fix(auth): check cross-subdomain cookie in access gate and dashboard redirects
The access gate and space dashboard redirect scripts checked only localStorage, which is per-origin. When navigating between subdomains (e.g. demo → jeff), the session wasn't found. Now both scripts also check the eid_token cross-subdomain cookie and sync it to localStorage. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5f25ae02e1
commit
3655632e0f
|
|
@ -339,24 +339,39 @@ export function renderSpaceDashboard(space: string, modules: ModuleInfo[]): stri
|
||||||
import '/shell.js';
|
import '/shell.js';
|
||||||
document.querySelector('rstack-app-switcher')?.setModules(${moduleListJSON});
|
document.querySelector('rstack-app-switcher')?.setModules(${moduleListJSON});
|
||||||
|
|
||||||
// Logged-in users: redirect to rSpace canvas instead of showing the grid
|
// Check session in localStorage OR cross-subdomain cookie
|
||||||
// Non-demo spaces: redirect logged-out visitors to the main domain landing
|
function _hasSession() {
|
||||||
try {
|
try {
|
||||||
var raw = localStorage.getItem('encryptid_session');
|
var raw = localStorage.getItem('encryptid_session');
|
||||||
var loggedIn = raw && JSON.parse(raw)?.accessToken;
|
if (raw && JSON.parse(raw)?.accessToken) return true;
|
||||||
|
} catch(e) {}
|
||||||
|
try {
|
||||||
|
var m = document.cookie.match(/(?:^|; )eid_token=([^;]*)/);
|
||||||
|
if (!m) return false;
|
||||||
|
var tok = decodeURIComponent(m[1]);
|
||||||
|
var parts = tok.split('.');
|
||||||
|
if (parts.length < 2) return false;
|
||||||
|
var b64 = parts[1].replace(/-/g,'+').replace(/_/g,'/');
|
||||||
|
var pad = '='.repeat((4 - b64.length % 4) % 4);
|
||||||
|
var payload = JSON.parse(atob(b64 + pad));
|
||||||
|
return payload.exp && Math.floor(Date.now()/1000) < payload.exp;
|
||||||
|
} catch(e) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logged-in users: redirect to rSpace canvas instead of showing the grid
|
||||||
|
// Non-demo spaces: redirect logged-out visitors to the main domain landing
|
||||||
|
var loggedIn = _hasSession();
|
||||||
if (loggedIn) {
|
if (loggedIn) {
|
||||||
var dest = window.__rspaceNavUrl
|
var dest = window.__rspaceNavUrl
|
||||||
? window.__rspaceNavUrl('${escapeAttr(space)}', 'rspace')
|
? window.__rspaceNavUrl('${escapeAttr(space)}', 'rspace')
|
||||||
: '/${escapeAttr(space)}/rspace';
|
: '/${escapeAttr(space)}/rspace';
|
||||||
window.location.replace(dest);
|
window.location.replace(dest);
|
||||||
} else if ('${escapeAttr(space)}' !== 'demo') {
|
} else if ('${escapeAttr(space)}' !== 'demo') {
|
||||||
// Don't show other users' space dashboards to logged-out visitors
|
|
||||||
var host = window.location.host.split(':')[0];
|
var host = window.location.host.split(':')[0];
|
||||||
if (host.endsWith('.rspace.online') || host === 'rspace.online') {
|
if (host.endsWith('.rspace.online') || host === 'rspace.online') {
|
||||||
window.location.replace('https://rspace.online/');
|
window.location.replace('https://rspace.online/');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(e) {}
|
|
||||||
|
|
||||||
// Fix up dashboard links to be subdomain-aware
|
// Fix up dashboard links to be subdomain-aware
|
||||||
if (window.__rspaceNavUrl) {
|
if (window.__rspaceNavUrl) {
|
||||||
|
|
|
||||||
|
|
@ -627,6 +627,28 @@ export function renderShell(opts: ShellOptions): string {
|
||||||
if (raw) session = JSON.parse(raw);
|
if (raw) session = JSON.parse(raw);
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
|
|
||||||
|
// Also check cross-subdomain cookie (localStorage is per-origin)
|
||||||
|
if (!session || !session.accessToken) {
|
||||||
|
try {
|
||||||
|
var m = document.cookie.match(/(?:^|; )eid_token=([^;]*)/);
|
||||||
|
if (m) {
|
||||||
|
var tok = decodeURIComponent(m[1]);
|
||||||
|
var parts = tok.split('.');
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
var b64 = parts[1].replace(/-/g,'+').replace(/_/g,'/');
|
||||||
|
var pad = '='.repeat((4 - b64.length % 4) % 4);
|
||||||
|
var payload = JSON.parse(atob(b64 + pad));
|
||||||
|
if (payload.exp && Math.floor(Date.now()/1000) < payload.exp) {
|
||||||
|
session = { accessToken: tok, claims: payload };
|
||||||
|
// Sync to localStorage so downstream code sees it
|
||||||
|
localStorage.setItem('encryptid_session', JSON.stringify(session));
|
||||||
|
if (payload.username) localStorage.setItem('rspace-username', payload.username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
|
||||||
var hasToken = session && session.accessToken;
|
var hasToken = session && session.accessToken;
|
||||||
|
|
||||||
// Permissioned spaces: only need a valid session
|
// Permissioned spaces: only need a valid session
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue