Skip to content

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

Merged
benceruleanlu merged 14 commits into
mainfrom
benceruleanlu/gtm-93-desktop-login-code
Jul 16, 2026
Merged

feat(auth): sign in via cloud login page with short-lived desktop login codes (GTM-93)#1222
benceruleanlu merged 14 commits into
mainfrom
benceruleanlu/gtm-93-desktop-login-code

Conversation

@benceruleanlu

@benceruleanlu benceruleanlu commented Jul 2, 2026

Copy link
Copy Markdown
Member

Review, don't merge until corresponding FE PRs are backported and live on cloud.

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

90 tests in src/main/auth (53 new): PKCE vectors, production-pinned/dev-only origin resolution, client status/body-timeout 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, same-path and cross-flow 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

GTM-93 identity dependency (July 15 update)

This PR owns authentication and Firebase persistence injection; it is not the final PostHog identity authority. In the corrected stack, Frontend #13687 reports the post-reload Firebase state and Desktop #1272 identifies only after all live hosted windows agree. The legacy bindSignedInUser call becomes a compatibility no-op under #1272.

Do not release this PR until Frontend #13687 is deployed and Desktop #1272 is included in the same Desktop release. Deploy Router #34 afterward. The #1272 + #1222 synthetic stack is covered by GTM-277.

See GTM-93 for review and deployment order.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a PKCE-based desktop login code sign-in flow, REST clients for code creation and exchange, custom-token persistence, origin resolution, abortable orchestration, and Firebase bridge integration.

Changes

Desktop Login Code Sign-In

Layer / File(s) Summary
PKCE and origin foundations
src/main/auth/desktopLoginCode/pkce.ts, src/main/auth/desktopLoginCode/origins.ts, src/main/auth/desktopLoginCode/*.test.ts
Adds PKCE helpers and resolves trusted loopback or production cloud origins.
Desktop login code HTTP client
src/main/auth/desktopLoginCode/client.ts, src/main/auth/desktopLoginCode/client.test.ts, src/main/auth/desktopLoginCode/testHelpers.ts
Adds typed requests, timeout and cancellation handling, payload validation, error classification, and HTTP-boundary tests.
Custom-token sign-in and persistence
src/main/auth/desktopLoginCode/customTokenSignIn.ts, src/main/auth/firebaseBridge/oauth.ts, src/main/auth/desktopLoginCode/customTokenSignIn.test.ts
Adds identity-toolkit sign-in, account lookup, persisted-user construction, and persistence helpers.
Desktop login orchestration
src/main/auth/desktopLoginCode/index.ts, src/main/auth/desktopLoginCode/index.test.ts
Creates and opens login codes, polls exchange status, completes sign-in, handles retries and deadlines, and reports telemetry.
Abortable Firebase flow control
src/main/auth/firebaseBridge/flowControl.ts
Adds abort-aware promise and sleep helpers.
Firebase bridge integration
src/main/auth/firebaseBridge/index.ts, src/main/auth/firebaseBridge/flowState.ts, src/main/auth/firebaseBridge/flowShared.ts, src/main/auth/firebaseBridge/index.test.ts
Runs the desktop flow before the legacy bridge, coordinates active attempts and banner ownership, and stops stale flows.
Parent window restoration
src/main/auth/firebaseBridge/restoreParentWindow.ts, src/main/auth/firebaseBridge/restoreParentWindow.test.ts
Adds guarded restore, show, and focus behavior for the optional parent window.

Sequence Diagram(s)

sequenceDiagram
    participant Renderer as ComfyContents
    participant Bridge as handleFirebasePopup
    participant Flow as signInViaDesktopLoginCode
    participant Client as DesktopLoginCodeClient
    participant Cloud as Cloud Login Page
    participant Identity as Identity Toolkit

    Renderer->>Bridge: intercepted auth URL
    Bridge->>Flow: start desktop login code flow
    Flow->>Client: createDesktopLoginCode(request)
    Client-->>Flow: grant
    Flow->>Cloud: open login URL with opaque code
    loop poll until redemption
        Flow->>Client: exchangeDesktopLoginCode(code, verifier)
        Client-->>Flow: pending or custom token
    end
    Flow->>Identity: signInWithCustomToken(custom token)
    Identity-->>Flow: ID and refresh tokens
    Flow->>Identity: lookupAccount(ID token)
    Identity-->>Flow: account details
    Flow-->>Renderer: bind user, inject state, restore window
Loading

Possibly related PRs

Suggested reviewers: kosinkadink, deepme987, maanilverma

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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.

…t timings

Review follow-ups on the desktop-login-code flow:
- signInWithCustomToken/lookupAccount now go through the same
  timeout-guarded postJson as the login-code endpoints, so a hung
  identitytoolkit call fails the flow instead of stalling it forever
  with the banner up and no sign_in_failed.
- createDesktopLoginCode rejects grants with expires_in or
  poll_interval <= 0 (tight-poll spin / instant expiry) while the
  legacy-bridge fallback is still available.
@benceruleanlu
benceruleanlu marked this pull request as ready for review July 6, 2026 02:06
@benceruleanlu
benceruleanlu marked this pull request as draft July 6, 2026 02:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/auth/firebaseBridge/oauth.ts (1)

172-191: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Extract shared providerUserInfoPersistedProviderData[] mapping.

This map (Lines 172-191) is near-identical to the one added in customTokenSignIn.ts's buildPersistedUserFromCustomToken (Lines 96-103 there), differing only in the provider-id fallback (providerId param vs. hardcoded 'firebase'). Since assemblePersistedUser was just centralized as "single source of truth" for this contract, consider pulling the mapping into a shared helper alongside it (e.g. mapProviderUserInfo(list, fallbackProviderId, fallbackUid)) so the two sign-in paths can't silently diverge.

♻️ Suggested shared helper
+export function mapProviderUserInfo(
+  list: ProviderUserInfo[] | undefined,
+  fallbackProviderId: string,
+  fallbackUid: string,
+): PersistedProviderData[] {
+  return (list ?? []).map((p) => ({
+    providerId: p.providerId ?? fallbackProviderId,
+    uid: p.rawId ?? fallbackUid,
+    displayName: p.displayName ?? null,
+    email: p.email ?? null,
+    phoneNumber: null,
+    photoURL: p.photoUrl ?? null,
+  }))
+}

Then in buildPersistedUser:

-  const providerData: PersistedProviderData[] =
-    resp.providerUserInfo && resp.providerUserInfo.length > 0
-      ? resp.providerUserInfo.map((p) => ({...}))
-      : [{...}]
+  const providerData: PersistedProviderData[] =
+    resp.providerUserInfo && resp.providerUserInfo.length > 0
+      ? mapProviderUserInfo(resp.providerUserInfo, providerId, resp.localId)
+      : [{ providerId, uid: resp.federatedId ?? resp.rawId ?? resp.localId, ... }]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/auth/firebaseBridge/oauth.ts` around lines 172 - 191, The
`providerUserInfo` to `PersistedProviderData[]` conversion in
`buildPersistedUser` duplicates the mapping already used in
`buildPersistedUserFromCustomToken`, so the two sign-in paths can drift. Extract
this logic into a shared helper near `assemblePersistedUser` (for example, a
mapper that accepts the provider list plus fallback providerId and uid values),
then update both `oauth.ts` and `customTokenSignIn.ts` to use it. Keep the
existing fallback behavior intact, including the `providerId` parameter here and
the hardcoded `'firebase'` case there.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/auth/desktopLoginCode/client.ts`:
- Around line 96-179: There is duplicated status-classification logic in
createDesktopLoginCode and exchangeDesktopLoginCode where retryable is computed
inline, which should be centralized to avoid divergence. Extract the shared 5xx
retryability check into a small helper or shared utility near
DesktopLoginCodeError handling, and keep the 404 featureMissing branch in
createDesktopLoginCode as the only special case. Use the existing
createDesktopLoginCode and exchangeDesktopLoginCode symbols to update both call
sites consistently.
- Around line 164-179: The exchange parsing in desktopLoginCode/client.ts treats
an unexpected HTTP 200 payload as terminal, which can break the poll loop on a
transient malformed response. Update the DesktopLoginCodeError thrown in the
response handling logic after resp.json() to mark this specific “unexpected
payload” path as retryable, while keeping the explicit pending/complete cases
and the 403/404 terminal cases unchanged.

In `@src/main/auth/desktopLoginCode/customTokenSignIn.test.ts`:
- Around line 117-131: Add a test case in customTokenSignIn.test.ts for a
malformed expiresIn value so the fallback path is covered. Extend the existing
buildPersistedUserFromCustomToken coverage by using a non-numeric expiresIn in
the token input and asserting the resulting user still gets sensible defaults,
matching the new guard logic in customTokenSignIn.ts. Keep the test alongside
the current sparse-lookup case so the behavior of
buildPersistedUserFromCustomToken remains locked in.

In `@src/main/auth/desktopLoginCode/customTokenSignIn.ts`:
- Around line 38-81: Both signInWithCustomToken and lookupAccount duplicate the
same non-OK response handling pattern, so extract that logic into a shared
helper near these functions and use it for both postJson calls. Keep the helper
responsible for checking resp.ok, reading resp.text() with a fallback, and
throwing the formatted error so the status/message format stays consistent and
won’t diverge between signInWithCustomToken and lookupAccount.
- Around line 92-94: Guard the token expiration calculation in customTokenSignIn
by validating signIn.expiresIn before using it, since Number(signIn.expiresIn ||
'3600') can produce NaN for truthy non-numeric strings and break expirationTime.
Update the logic around expiresInSec and the related expirationTime assignment
to reject or replace invalid values with the default 3600, and keep the check
localized in customTokenSignIn so the session timing remains safe.

In `@src/main/auth/desktopLoginCode/index.ts`:
- Around line 234-239: The parent-window restore/show/focus logic is duplicated
between desktopLoginCode’s handling block and handleFirebasePopup in
firebaseBridge, so extract it into a shared helper and reuse it from both call
sites. Add a small utility like restoreParentWindow that accepts the
BrowserWindow, guards against missing/destroyed windows, restores if minimized,
then shows and focuses it, and replace the inline blocks in
desktopLoginCode/index.ts and firebaseBridge/index.ts with that helper to keep
behavior synchronized.

In `@src/main/auth/desktopLoginCode/origins.ts`:
- Around line 6-10: The isLoopbackHostname helper only matches localhost and the
compressed IPv6 loopback forms, so update it to also recognize fully expanded
IPv6 loopback hostnames such as 0:0:0:0:0:0:0:1. Adjust the normalization/check
logic in isLoopbackHostname in origins.ts so any equivalent loopback
representation is treated as loopback before falling back to the IPv4 127.*
check.

---

Outside diff comments:
In `@src/main/auth/firebaseBridge/oauth.ts`:
- Around line 172-191: The `providerUserInfo` to `PersistedProviderData[]`
conversion in `buildPersistedUser` duplicates the mapping already used in
`buildPersistedUserFromCustomToken`, so the two sign-in paths can drift. Extract
this logic into a shared helper near `assemblePersistedUser` (for example, a
mapper that accepts the provider list plus fallback providerId and uid values),
then update both `oauth.ts` and `customTokenSignIn.ts` to use it. Keep the
existing fallback behavior intact, including the `providerId` parameter here and
the hardcoded `'firebase'` case there.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e6fbdcb3-c4cf-4a1d-97f7-d95055a69517

📥 Commits

Reviewing files that changed from the base of the PR and between 5394475 and 6ce111b.

📒 Files selected for processing (12)
  • src/main/auth/desktopLoginCode/client.test.ts
  • src/main/auth/desktopLoginCode/client.ts
  • src/main/auth/desktopLoginCode/customTokenSignIn.test.ts
  • src/main/auth/desktopLoginCode/customTokenSignIn.ts
  • src/main/auth/desktopLoginCode/index.test.ts
  • src/main/auth/desktopLoginCode/index.ts
  • src/main/auth/desktopLoginCode/origins.test.ts
  • src/main/auth/desktopLoginCode/origins.ts
  • src/main/auth/desktopLoginCode/pkce.test.ts
  • src/main/auth/desktopLoginCode/pkce.ts
  • src/main/auth/firebaseBridge/index.ts
  • src/main/auth/firebaseBridge/oauth.ts

Comment thread src/main/auth/desktopLoginCode/client.ts
Comment thread src/main/auth/desktopLoginCode/client.ts Outdated
Comment thread src/main/auth/desktopLoginCode/customTokenSignIn.test.ts Outdated
Comment thread src/main/auth/desktopLoginCode/customTokenSignIn.ts
Comment thread src/main/auth/desktopLoginCode/customTokenSignIn.ts
Comment thread src/main/auth/desktopLoginCode/index.ts Outdated
Comment thread src/main/auth/desktopLoginCode/origins.ts
@benceruleanlu
benceruleanlu marked this pull request as ready for review July 10, 2026 02:22
pull Bot pushed a commit to Mu-L/ComfyUI_frontend that referenced this pull request Jul 10, 2026
…titching (GTM-93) (Comfy-Org#13418)

## What

Browser half of GTM-93 macOS web→desktop identity stitching: when the
desktop app opens the system browser at cloud login with
`?desktop_login_code=dlc_…`, the frontend redeems that code against the
cloud backend once a Firebase session exists — after **explicit user
approval**.

Reworked on top of the preserved-query `stripAfterCapture` capability
(Comfy-Org#13465):

- The `DESKTOP_LOGIN` namespace opts into strip-on-capture: the code is
stashed and removed from the URL **before any navigation completes**, so
it never reaches history, `previousFullPath`, later guards, or telemetry
— the hand-rolled URL scrubbing this PR previously carried (raw-string
parser + three strip sites) is gone.
- `desktopLoginRedemption.ts` is a plain module with a single export,
`installDesktopLoginRedemption(router)`, installed once in `router.ts`'s
cloud block (replaces six per-view/composable trigger sites). Redemption
reads the code only from the stash: per-code state (approval + 2-attempt
transient budget, so a second code gets its own approval and budget),
approval dialog, `POST /api/auth/desktop-login-codes/redeem` with the
raw Firebase ID token (backend route is Firebase-JWT-only), 10s fetch
timeout.
- Triggers: `router.afterEach` (the cloud auth guard settles Firebase
init before navigations complete) plus a lazy watcher on
`authStore.currentUser` for sessions that appear without a navigation
(OAuth-resume error branch, dialog sign-in). One bounded in-page retry
(5s) guarantees an approved sign-in always ends in a success or failure
toast.
- Terminal rejections (400/403/404/409/410) drop the code with an error
toast; transient failures (401/5xx/timeout/network) retry once; budget
exhaustion now surfaces a failure toast instead of dying silently.

## Why

Windows stitches web→desktop at download time via installer stamping;
macOS DMGs can't be stamped, so we stitch at login. The browser is where
both halves meet: the existing `posthog.identify(uid)` merges the web
anon person into the Firebase uid, and the backend emits
`comfy.cloud.identity.login_attributed` (uid ↔ installation_id) at
redeem. The desktop app polls the backend and receives a one-time custom
token — no auth material posted to a desktop loopback server (the
concern that stalled Comfy-Org#12983, which this supersedes).

## Security

- **Approval dialog before redeem** — redemption mints the desktop a
sign-in token for *your* account, so a lured click must not be enough
(device-code phishing mitigation). Cancel clears the stash and does
nothing.
- Only the opaque single-use code ever appears in a URL; the tracker
strips it on first sight, pre-navigation, and it is never logged.

## Testing

Vitest, driven through a real router (createRouter/createMemoryHistory,
no vue-router mocks) and the real preserved-query manager: capture/stash
lifecycle, approval gate (no fetch before approve; decline/dismiss
clears; per-code approval), Bearer/body shape, terminal-vs-transient
statuses, timeout abort, bounded in-page retry + failure toast on budget
exhaustion, per-code regressions (second code after
success/decline/exhaustion redeems independently), auth-watcher trigger
(session appearing without navigation), unauthenticated no-op, trigger
coalescing. Typecheck/lint/format clean.

Types are hand-written with a `TODO(@comfyorg/ingest-types)` — the
generated types land automatically once the cloud PR merges and the
type-gen workflow runs.

## Landing order

1. Cloud backend: Comfy-Org/cloud#4736 (until it
ships, redemption never triggers — this PR is inert)
2. Comfy-Org#13465 preserved-query strip-on-capture (base of this PR)
3. Comfy-Org#13466 global-prompt FIFO queue (runtime dependency: the approval
confirm must settle even if another prompt is open)
4. **This PR**
5. Desktop (activates the flow):
Comfy-Org/Comfy-Desktop#1222

GTM-93 · Supersedes Comfy-Org#12983

---------

Co-authored-by: AustinMroz <austin@comfy.org>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/auth/desktopLoginCode/client.ts (1)

64-66: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Treat HTTP 429 as retryable. isRetryableStatus() only covers 5xx responses, so a rate-limited exchange call is marked terminal and the poll loop stops instead of backing off.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/auth/desktopLoginCode/client.ts` around lines 64 - 66, Update
isRetryableStatus() to also return true for HTTP status 429, while preserving
retry behavior for all 5xx responses and terminal behavior for other statuses.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/main/auth/desktopLoginCode/client.ts`:
- Around line 64-66: Update isRetryableStatus() to also return true for HTTP
status 429, while preserving retry behavior for all 5xx responses and terminal
behavior for other statuses.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6f25228f-e407-483c-9224-5ddcbf969d6e

📥 Commits

Reviewing files that changed from the base of the PR and between f1f574e and 34c1d94.

📒 Files selected for processing (7)
  • src/main/auth/desktopLoginCode/client.test.ts
  • src/main/auth/desktopLoginCode/client.ts
  • src/main/auth/desktopLoginCode/customTokenSignIn.test.ts
  • src/main/auth/desktopLoginCode/index.test.ts
  • src/main/auth/desktopLoginCode/testHelpers.ts
  • src/main/auth/firebaseBridge/index.test.ts
  • src/main/auth/firebaseBridge/index.ts
💤 Files with no reviewable changes (1)
  • src/main/auth/desktopLoginCode/index.test.ts

@deepme987 deepme987 assigned benceruleanlu and unassigned deepme987 Jul 14, 2026
@benceruleanlu

Copy link
Copy Markdown
Member Author

Considering just rebasing this on top of #1272

@benceruleanlu

Copy link
Copy Markdown
Member Author

Review takes too long for the ideal scenario above.

@benceruleanlu
benceruleanlu merged commit a3c5979 into main Jul 16, 2026
12 checks passed
@benceruleanlu
benceruleanlu deleted the benceruleanlu/gtm-93-desktop-login-code branch July 16, 2026 02:18
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants