chat / public /oauth-callback.html
incognitolm
Account Handling
ad573c0
Raw
History Blame
3.5 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Signing in…</title>
<style>
body { background: #0d0e11; color: #e8eaf0; font-family: system-ui, sans-serif;
display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }
.box { text-align: center; }
.spinner { width: 32px; height: 32px; border: 3px solid rgba(229,200,70,0.2);
border-top-color: #e5c846; border-radius: 50%; animation: spin 0.8s linear infinite;
margin: 0 auto 16px; }
@keyframes spin { to { transform: rotate(360deg); } }
</style>
</head>
<body>
<div class="box">
<div class="spinner"></div>
<p id="msg">Completing sign-in…</p>
</div>
<script>
// ── Extract tokens from URL hash (Supabase implicit flow) or search params ──
function getTokens() {
const hash = new URLSearchParams(location.hash.replace('#', ''));
const search = new URLSearchParams(location.search);
return {
access_token: hash.get('access_token') || search.get('access_token'),
refresh_token: hash.get('refresh_token') || search.get('refresh_token'),
error: hash.get('error') || search.get('error'),
error_desc: hash.get('error_description') || search.get('error_description'),
};
}
const tokens = getTokens();
const msgEl = document.getElementById('msg');
if (tokens.error) {
msgEl.textContent = 'Sign-in error: ' + (tokens.error_desc || tokens.error);
} else if (tokens.access_token) {
// ── Primary path: write to localStorage so the main tab picks it up
// via a 'storage' event listener β€” works even when window.opener is null
// (strict popup policies, mobile browsers, etc.).
const payload = JSON.stringify({
access_token: tokens.access_token,
refresh_token: tokens.refresh_token || '',
});
localStorage.setItem('ipai_oauth_pending', payload);
// ── Also try postMessage to opener for fastest possible handoff ──────
if (window.opener && !window.opener.closed) {
try {
window.opener.postMessage({
type: 'oauth:callback',
access_token: tokens.access_token,
refresh_token: tokens.refresh_token,
}, location.origin);
} catch (_) { /* cross-origin opener β€” storage event is enough */ }
}
msgEl.textContent = 'Sign-in complete! Closing…';
// Give localStorage a moment to propagate, then try to close the popup.
setTimeout(() => {
try { window.close(); } catch (_) { /* ignore */ }
}, 300);
} else {
msgEl.textContent = 'No token received. You can close this window.';
}
</script>
<!-- Cloudflare Turnstile -->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<div id="turnstile-overlay" style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.6);z-index:9999;">
<div style="background:#0d0e11;padding:18px;border-radius:10px;text-align:center;max-width:420px;width:90%;">
<div style="color:#d7d7d7;margin-bottom:12px;">Please verify you are human to continue.</div>
<div class="cf-turnstile" data-sitekey="0x4AAAAAAC1ZXKIhZ9Kdz8j9" data-callback="onTurnstileSuccess"></div>
</div>
</div>
<script type="module" src="/js/turnstile.js"></script>
</body>
</html>