import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import './index.css';
import { supabase, INITIAL_URL_HASH, INITIAL_URL_SEARCH } from './services/supabase.ts';
const rawHash = INITIAL_URL_HASH || (typeof window !== 'undefined' ? window.location.hash : '');
const rawSearch = INITIAL_URL_SEARCH || (typeof window !== 'undefined' ? window.location.search : '');
const cleanHash = rawHash.startsWith('#') ? rawHash.substring(1) : rawHash;
const hashParams = new URLSearchParams(cleanHash);
const searchParams = new URLSearchParams(rawSearch);
const authType = searchParams.get('type') || hashParams.get('type') || '';
const isEmailFlow =
authType === 'recovery' ||
authType === 'signup' ||
authType === 'email' ||
authType === 'invite' ||
authType === 'magiclink';
const hasAuthParams =
typeof window !== 'undefined' &&
!isEmailFlow &&
(hashParams.has('access_token') ||
searchParams.has('code') ||
searchParams.has('error') ||
hashParams.has('error') ||
searchParams.has('error_description') ||
hashParams.has('error_description'));
const isSameTabRedirect = (() => {
try {
if (typeof window !== 'undefined' && sessionStorage.getItem('supabase_oauth_same_tab') === '1') {
sessionStorage.removeItem('supabase_oauth_same_tab');
return true;
}
} catch (e) {}
return false;
})();
// Check if this window was opened as a Supabase OAuth popup callback
// Note: Navigating through accounts.google.com sends Cross-Origin-Opener-Policy headers
// which can set window.opener = null and clear window.name = '' in modern browsers.
const isPopup =
typeof window !== 'undefined' &&
hasAuthParams &&
!isSameTabRedirect &&
((window.opener && window.opener !== window) ||
window.name === 'supabase_google_oauth' ||
window.self === window.top);
if (isPopup && hasAuthParams) {
// Render a minimal loader in the popup instead of mounting the entire application UI
const rootEl = document.getElementById('root');
if (rootEl) {
rootEl.innerHTML = `
تمت المصادقة بنجاح
جاري تحديث الجلسة والعودة للتطبيق...
`;
}
const notifyOpenerAndClose = async (payload: { type: string; code?: string | null; session?: any; error?: string }) => {
// 1. Direct postMessage to opener (if not severed by COOP)
try {
if (window.opener && !window.opener.closed) {
window.opener.postMessage(payload, '*');
}
} catch (e) {
console.warn('postMessage to opener error:', e);
}
// 2. BroadcastChannel (for same-partition contexts)
try {
if (typeof BroadcastChannel !== 'undefined') {
const bc = new BroadcastChannel('supabase_google_oauth_channel');
bc.postMessage(payload);
setTimeout(() => {
try {
bc.close();
} catch (e) {}
}, 300);
}
} catch (e) {}
// 3. localStorage event bridge (for same-partition contexts)
try {
localStorage.setItem(
'supabase_google_oauth_result',
JSON.stringify({ ...payload, ts: Date.now() })
);
} catch (e) {}
// 4. Server-side relay (bridges cross-origin iframe storage partitioning & COOP severed opener)
try {
if (
payload.type === 'SUPABASE_AUTH_SUCCESS' &&
(payload.code || (payload.session?.access_token && payload.session?.refresh_token))
) {
await fetch('/api/oauth-relay', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'complete',
code: payload.code || null,
session:
payload.session?.access_token && payload.session?.refresh_token
? {
access_token: payload.session.access_token,
refresh_token: payload.session.refresh_token,
}
: null,
}),
});
} else if (payload.type === 'SUPABASE_AUTH_ERROR') {
await fetch('/api/oauth-relay', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'error',
error: payload.error || 'Authentication failed',
}),
});
}
} catch (e) {
console.warn('Server oauth-relay error:', e);
}
setTimeout(() => {
try {
window.close();
} catch (e) {}
// Fallback UI if browser prevents closing a COOP-severed window automatically
setTimeout(() => {
if (rootEl) {
rootEl.innerHTML = `
✓
تم تسجيل الدخول بنجاح
تم ربط جلستك في نافذة التطبيق بنجاح. يمكنك إغلاق هذه النافذة الآن.
`;
}
}, 600);
}, 250);
};
// 1. Direct extraction for PKCE code or implicit tokens
const code = searchParams.get('code');
const accessToken = hashParams.get('access_token');
const refreshToken = hashParams.get('refresh_token');
const errorDescription =
searchParams.get('error_description') ||
hashParams.get('error_description') ||
searchParams.get('error') ||
hashParams.get('error');
if (errorDescription) {
notifyOpenerAndClose({ type: 'SUPABASE_AUTH_ERROR', error: errorDescription });
} else if (code) {
notifyOpenerAndClose({
type: 'SUPABASE_AUTH_SUCCESS',
code,
});
} else if (accessToken && refreshToken) {
notifyOpenerAndClose({
type: 'SUPABASE_AUTH_SUCCESS',
session: {
access_token: accessToken,
refresh_token: refreshToken,
},
});
} else {
supabase.auth
.getSession()
.then(({ data, error }) => {
if (data?.session) {
notifyOpenerAndClose({ type: 'SUPABASE_AUTH_SUCCESS', session: data.session });
} else if (error) {
notifyOpenerAndClose({ type: 'SUPABASE_AUTH_ERROR', error: error.message });
} else {
notifyOpenerAndClose({ type: 'SUPABASE_AUTH_SUCCESS' });
}
})
.catch(() => {
notifyOpenerAndClose({ type: 'SUPABASE_AUTH_SUCCESS' });
});
}
} else {
// Main app window: render normal React application
createRoot(document.getElementById('root')!).render(
,
);
}