Skip to content

feat(auth): sign in via cloud login page with short-lived desktop login codes (GTM-93)#1222

Draft
benceruleanlu wants to merge 1 commit into
mainfrom
benceruleanlu/gtm-93-desktop-login-code
Draft

feat(auth): sign in via cloud login page with short-lived desktop login codes (GTM-93)#1222
benceruleanlu wants to merge 1 commit into
mainfrom
benceruleanlu/gtm-93-desktop-login-code

Conversation

@benceruleanlu

@benceruleanlu benceruleanlu commented Jul 2, 2026

Copy link
Copy Markdown
Member

What

Desktop half of GTM-93 macOS web→desktop identity stitching: sign-in now runs through the real cloud.comfy.org login page with a short-lived, PKCE-bound desktop login code — no loopback callback, no credentials over localhost.

New src/main/auth/desktopLoginCode/ module, attempted first from the existing handleFirebasePopup intercept:

  1. Mint verifier/challenge, POST /api/auth/desktop-login-codes (installation_id = getDeviceId() machine hash, included only when telemetry consent is granted; the auth handoff works without it).
  2. Open the system browser at /cloud/login?desktop_login_code=dlc_… (only the opaque code — never installation_id — transits the URL), reusing the copy-link banner.
  3. Poll /exchange (interval + jitter, abortable singleton, one final attempt at deadline) until the signed-in browser session redeems the code with explicit user approval.
  4. REST accounts:signInWithCustomToken + accounts:lookup (main process has no Firebase SDK), assemble the persisted user via the same assemblePersistedUser contract as the OAuth path, then the unchanged IndexedDB inject + bindSignedInUser + focus restore.
  5. Telemetry: sign_in_started {flow: 'desktop_login_code'} (only once the browser actually opens), comfy.desktop.identity.login_attributed {via: 'desktop_login_code'} on success, sign_in_failed with error bucket otherwise.

Hard fallback: if code creation fails (old backend, network, timeout) — or the deployment targets the dev Firebase project through a non-loopback origin — the legacy loopback bridge runs unchanged. Login can never get worse than today.

Why

Windows stitches web→desktop by stamping a download token into the installer; macOS DMGs are notarized and can't be stamped. Logging in on the real cloud page in the user's own browser lets the web posthog.identify(uid) merge top-of-funnel anon activity into the Firebase uid, while the backend emits comfy.cloud.identity.login_attributed (uid ↔ installation_id) at redeem — the login-time twin of the Windows download_attributed event. Bonus: passkeys/password-manager autofill/email+password all work, since the login UI is the real cloud page rather than the bridge's provider redirect.

Supersedes #1150: same goal, but the browser never POSTs to a localhost server — the desktop pulls a one-time Firebase custom token with code + PKCE verifier (the token-over-loopback concern from that review is gone), so the fixed port 9876, CORS/PNA headers, and callback validation all disappear from this path.

Notes

  • Refactor: oauth.ts's persisted-user assembly extracted into exported assemblePersistedUser (byte-identical output; legacy path delegates) so both sign-in paths share the User.toJSON()/stsTokenManager contract that IndexedDB rehydration depends on.
  • Supersession safety: re-clicking Sign in aborts the previous flow at every await point (including the post-exchange tail) and closes any stale legacy bridge; a superseded flow never injects, steals focus, or tears down the newer flow's banner.
  • Watch for merge conflicts with fix(telemetry): installation_id is always the machine id (per-install id → install_id) #1159 (installation_id naming) — this PR uses getDeviceId() (the machine hash) for installation_id, matching that PR's direction.

Testing

83 tests in src/main/auth (46 new): PKCE vectors, origin resolution, client status classification (pending/complete/terminal/retryable/timeout), custom-token REST chain + persisted-user contract, orchestrator (fallback-on-create-failure, consent gating, no installation_id in URLs, poll pending→complete, final-attempt-at-deadline, supersession/abort races, dev-env guard, telemetry ordering). Full suite green; typecheck/lint clean.

Landing order

  1. Cloud backend: https://github.com/Comfy-Org/cloud/pull/4736 (endpoints + IAM signBlob for custom-token minting)
  2. Frontend: feat(cloud): redeem desktop login codes for web-to-desktop identity stitching (GTM-93) ComfyUI_frontend#13418 (redeem + approval UI)
  3. This PR (activates the flow; safe to merge early only because of the hard fallback, but sequencing avoids a window where users hit fallback unnecessarily)

GTM-93 · Supersedes #1150

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e2eb5b1d-55e8-4717-8e0a-1812891526e0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch benceruleanlu/gtm-93-desktop-login-code
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch benceruleanlu/gtm-93-desktop-login-code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant