feat: add sign-in flow for crossOriginIsolated contexts, take two#3338
feat: add sign-in flow for crossOriginIsolated contexts, take two#3338velzie wants to merge 8 commits into
Conversation
|
@ProgrammerIn-wonderland @velzie what was the issue that caused this to be reverted earlier? |
|
the function which listened on onmessage for the iframe in the non cross origin codepath was called with empty parameters on accident |
There was a problem hiding this comment.
Pull request overview
Adds a fallback sign-in mechanism for crossOriginIsolated contexts by routing the auth token through backend long-polling + Redis pub/sub fanout instead of relying solely on postMessage between opener/popup.
Changes:
- Frontend:
puter.auth.signIn()now includes asignin_sessionand polls/login/waitincrossOriginIsolatedmode. - GUI: popup sign-in path posts the token to
/login/setwhencross_origin_isolated=true, and common post-auth behaviors were refactored intopostAuthActions(). - Backend: introduces
/login/waitand/login/set, adds anEventClient.off()API, and extendsBroadcastServicewith Redis pub/sub-based intra-cluster fanout.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/puter-js/src/modules/Auth.js | Adds COI-specific sign-in session + backend polling; adjusts popup handling. |
| src/gui/src/initgui.js | Extracts post-auth flows and adds COI popup token handoff via /login/set. |
| src/backend/services/broadcast/BroadcastService.ts | Adds Redis pub/sub fanout layer and source-loop prevention for replicated events. |
| src/backend/controllers/auth/AuthController.ts | Adds /login/wait and /login/set endpoints for token rendezvous. |
| src/backend/clients/event/types.ts | Adds typed pubsub.login.* event key. |
| src/backend/clients/event/EventClient.ts | Adds off() to unregister event listeners. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if ( window.crossOriginIsolated ) { | ||
| (async () => { | ||
| while (true) { | ||
| try { | ||
| const result = await fetch(`${this.APIOrigin}/login/wait`, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify({ session: signinsession }), | ||
| }); | ||
|
|
||
| if ( result.ok ) { | ||
| const { auth_token } = await result.json(); | ||
| if (settled) return; | ||
| settled = true; | ||
| cleanup(); | ||
| puter.setAuthToken(auth_token); | ||
| resolve({ success: true, token: auth_token }); | ||
| return ''; | ||
| } | ||
| } catch {} | ||
| await new Promise(r => setTimeout(r, 1000)); | ||
| } | ||
| })(); |
| const popup = openAuthPopup(url); | ||
| if ( !window.crossOriginIsolated ) { | ||
| // cannot watch in isolated mode | ||
| watchPopup(popup); | ||
| } |
There was a problem hiding this comment.
annoyingly enough you can't even check the closed status of cross origin isolated windows so this was intentional
| if (isolated) { | ||
| let data = await window.getUserAppToken(new URL(window.openerOrigin).origin); | ||
| await fetch(`${window.api_origin}/login/set`, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify({ | ||
| auth_token: data.token, | ||
| session: session, | ||
| }), | ||
| }) | ||
| window.close(); | ||
| window.open('', '_self').close(); | ||
| } else { |
| const { resolve, promise } = Promise.withResolvers<void>(); | ||
|
|
||
| let token: string | null = null; | ||
| const listener = (_key: string, value: { authtoken: string }) => { | ||
| token = value.authtoken; | ||
| resolve(); | ||
| }; | ||
| this.clients.event.on(`pubsub.login.${session}`, listener); | ||
|
|
||
| const timeout = new Promise<void>((resolve) => | ||
| setTimeout(resolve, 10000), | ||
| ); | ||
| await Promise.race([promise, timeout]); | ||
| if (!token) { | ||
| throw new HttpError(408, 'Request timeout.', { | ||
| legacyCode: 'request_timeout', | ||
| }); | ||
| } | ||
| this.clients.event.off(`pubsub.login.${session}`, listener); | ||
|
|
|
should be resolved |
Salazareo
left a comment
There was a problem hiding this comment.
if couple copilot flags are resolved then I think this looks good
No description provided.