Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions src/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import './i18n';
import { QueryClientProvider } from '@tanstack/react-query';
import { queryClient } from './lib/queryClient';
import './index.css';
import { getLegacyRedirectUrl } from './utils/legacyHostRedirect';

const legacyRedirectUrl = getLegacyRedirectUrl(globalThis?.location);
if (legacyRedirectUrl) {
globalThis.location.replace(legacyRedirectUrl);
}

// Show [DEV] in the browser tab when running locally.
const isLocalHost = ['localhost', '127.0.0.1', '0.0.0.0'].includes(globalThis?.location?.hostname);
Expand All @@ -27,17 +33,19 @@ if (import.meta.env.DEV && typeof navigator !== 'undefined' && 'serviceWorker' i
}
}

ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<BrowserRouter
future={{
v7_startTransition: true,
v7_relativeSplatPath: true,
}}
>
<App />
</BrowserRouter>
</QueryClientProvider>
</React.StrictMode>,
);
if (!legacyRedirectUrl) {
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<BrowserRouter
future={{
v7_startTransition: true,
v7_relativeSplatPath: true,
}}
>
<App />
</BrowserRouter>
</QueryClientProvider>
</React.StrictMode>,
);
}
9 changes: 9 additions & 0 deletions src/utils/legacyHostRedirect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const LEGACY_HOSTS = ['winbit-6579c.web.app', 'winbit-6579c.firebaseapp.com'];
const CURRENT_ORIGIN = 'https://app.winbit.com.ar';

// `/__/` is reserved by Firebase Hosting (Google sign-in handler); never redirect it.
export const getLegacyRedirectUrl = ({ hostname, pathname = '/', search = '', hash = '' } = {}) => {
if (!LEGACY_HOSTS.includes(hostname)) return null;
if (pathname.startsWith('/__/')) return null;
return `${CURRENT_ORIGIN}${pathname}${search}${hash}`;
};
42 changes: 42 additions & 0 deletions src/utils/legacyHostRedirect.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { describe, it, expect } from 'vitest';
import { getLegacyRedirectUrl } from './legacyHostRedirect';

describe('getLegacyRedirectUrl', () => {
it('redirects the legacy web.app host to the current domain', () => {
expect(getLegacyRedirectUrl({ hostname: 'winbit-6579c.web.app', pathname: '/' })).toBe(
'https://app.winbit.com.ar/',
);
});

it('redirects the legacy firebaseapp.com host', () => {
expect(
getLegacyRedirectUrl({ hostname: 'winbit-6579c.firebaseapp.com', pathname: '/login' }),
).toBe('https://app.winbit.com.ar/login');
});

it('preserves path, query string and hash', () => {
expect(
getLegacyRedirectUrl({
hostname: 'winbit-6579c.web.app',
pathname: '/history',
search: '?tab=2',
hash: '#top',
}),
).toBe('https://app.winbit.com.ar/history?tab=2#top');
});

it('never redirects the Firebase reserved /__/ paths', () => {
expect(
getLegacyRedirectUrl({
hostname: 'winbit-6579c.firebaseapp.com',
pathname: '/__/auth/handler',
}),
).toBeNull();
});

it('does not redirect the current domain or local hosts', () => {
expect(getLegacyRedirectUrl({ hostname: 'app.winbit.com.ar', pathname: '/' })).toBeNull();
expect(getLegacyRedirectUrl({ hostname: 'localhost', pathname: '/' })).toBeNull();
expect(getLegacyRedirectUrl()).toBeNull();
});
});
Loading