diff --git a/server/landing.ts b/server/landing.ts index 9b1401f..e133fd0 100644 --- a/server/landing.ts +++ b/server/landing.ts @@ -339,24 +339,39 @@ export function renderSpaceDashboard(space: string, modules: ModuleInfo[]): stri import '/shell.js'; document.querySelector('rstack-app-switcher')?.setModules(${moduleListJSON}); + // Check session in localStorage OR cross-subdomain cookie + function _hasSession() { + try { + var raw = localStorage.getItem('encryptid_session'); + 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 - try { - var raw = localStorage.getItem('encryptid_session'); - var loggedIn = raw && JSON.parse(raw)?.accessToken; - if (loggedIn) { - var dest = window.__rspaceNavUrl - ? window.__rspaceNavUrl('${escapeAttr(space)}', 'rspace') - : '/${escapeAttr(space)}/rspace'; - window.location.replace(dest); - } else if ('${escapeAttr(space)}' !== 'demo') { - // Don't show other users' space dashboards to logged-out visitors - var host = window.location.host.split(':')[0]; - if (host.endsWith('.rspace.online') || host === 'rspace.online') { - window.location.replace('https://rspace.online/'); - } + var loggedIn = _hasSession(); + if (loggedIn) { + var dest = window.__rspaceNavUrl + ? window.__rspaceNavUrl('${escapeAttr(space)}', 'rspace') + : '/${escapeAttr(space)}/rspace'; + window.location.replace(dest); + } else if ('${escapeAttr(space)}' !== 'demo') { + var host = window.location.host.split(':')[0]; + if (host.endsWith('.rspace.online') || host === 'rspace.online') { + window.location.replace('https://rspace.online/'); } - } catch(e) {} + } // Fix up dashboard links to be subdomain-aware if (window.__rspaceNavUrl) { diff --git a/server/shell.ts b/server/shell.ts index 3892309..9201888 100644 --- a/server/shell.ts +++ b/server/shell.ts @@ -627,6 +627,28 @@ export function renderShell(opts: ShellOptions): string { if (raw) session = JSON.parse(raw); } 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; // Permissioned spaces: only need a valid session