[GTM-277] Carry website anonymous ID through Desktop auth#1272
[GTM-277] Carry website anonymous ID through Desktop auth#1272benceruleanlu wants to merge 11 commits into
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughChangesTelemetry identity and Firebase consensus
Sequence Diagram(s)sequenceDiagram
participant HostedView
participant PreloadBridge
participant TelemetryIPC
participant FirebaseAuthIdentity
participant MainTelemetry
HostedView->>PreloadBridge: reportFirebaseAuthState(state)
PreloadBridge->>TelemetryIPC: send telemetry:firebaseAuthState
TelemetryIPC->>FirebaseAuthIdentity: validate trusted frame and auth state
FirebaseAuthIdentity->>MainTelemetry: apply Firebase user or anonymous consensus
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify 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. Comment |
6dbccca to
b035ca3
Compare
9508995 to
47544b2
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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/lib/cloudUrl.ts`:
- Around line 34-36: Replace the historical explanation above the cloud URL
handling with a concise present-tense description of the behavior: remove both
the legacy identity name and property name when supplied by stale callers. Keep
the implementation unchanged.
In `@src/main/lib/telemetry.ts`:
- Around line 611-628: Update the deferred handling around
capturePersonProperties() and capture() so each returns an admission result
indicating whether the write was accepted. Clear
pendingPersonSet/pendingPersonSetOnce only after capturePersonProperties()
succeeds; clear pendingDownloadTokenAttribution and invoke
attribution.onAttributed() only after capture() succeeds, otherwise retain the
deferred state for retry.
- Around line 802-808: Update unbindUserId() to clear pendingPersonSet and
pendingPersonSetOnce before checking boundUserId, ensuring deferred-login logout
cannot retain values for the next UID. Preserve the existing early return after
clearing both buffers, and add coverage for logout while UID binding is
deferred.
In `@src/preload/comfyPreload.ts`:
- Around line 87-100: Extract the duplicated ipcRenderer.send try/catch into a
shared safeTelemetrySend helper near the bridge or Telemetry declaration,
preserving the existing ignored-error behavior. Update bindUserId and
unbindUserId to call the helper, and reuse it for capture if it has the same
telemetry-send pattern.
🪄 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: 11f8f461-05fe-438d-8bd0-ee5b679b6760
📒 Files selected for processing (22)
packages/comfyui-desktop-bridge-types/comfyDesktopBridge.d.tspackages/comfyui-desktop-bridge-types/package.jsonsrc/main/index.tssrc/main/lib/anonymousIdentity.test.tssrc/main/lib/anonymousIdentity.tssrc/main/lib/cloudUrl.test.tssrc/main/lib/cloudUrl.tssrc/main/lib/deviceId.test.tssrc/main/lib/deviceId.tssrc/main/lib/experiments.test.tssrc/main/lib/ipc/registerTelemetryHandlers.test.tssrc/main/lib/ipc/registerTelemetryHandlers.tssrc/main/lib/ipc/sessionActions/launch.tssrc/main/lib/opaqueIdentifier.tssrc/main/lib/telemetry.test.tssrc/main/lib/telemetry.tssrc/main/lib/trustedCloudUrl.test.tssrc/main/lib/trustedCloudUrl.tssrc/preload/api.tssrc/preload/comfyPreload.tssrc/types/comfyDesktopBridge.tssrc/types/ipc.ts
💤 Files with no reviewable changes (1)
- src/preload/api.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 47544b25df
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
47544b2 to
5d32ba2
Compare
53af77a to
75d8b29
Compare
75d8b29 to
02ace26
Compare
|
Took over per GTM-93. Three additive commits on top of 02ace26, all red-green tested (144 tests green locally, typecheck+eslint via hooks):
Also verified at this head: buffer clearing on signed-out consensus (cross-account leak), experiments/flags keyed to installationId with no person creation, and the full identity contract (no aliases, personless pre-login, reserve-before-merge rotation) — no violations found. Flagged, not fixed: inbound UID validation (registerTelemetryHandlers → normalizeOpaqueIdentifier) doesn't apply the illegal-ID check to F itself. Low risk (trusted cloud frames only, Firebase UIDs are alphanumeric) — fine as a follow-up. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8b05b95234
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/lib/telemetry.ts (1)
847-869: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winDo not consume volume-guard budget for rejected SDK writes.
The rate-limit stamp and session count are committed before
client.capture()succeeds, so repeated SDK failures can leave retained one-shots permanently capped—quite the retry trap. Commit or roll back guard accounting on failure.🤖 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/lib/telemetry.ts` around lines 847 - 869, The capture function currently commits rate-limit and session-count accounting before client.capture succeeds. Move the _eventsCapturedThisProcess increment and corresponding _checkRateLimit commitment into the successful SDK-write path, or explicitly roll both back in the catch block, so rejected writes do not consume volume-guard budget while preserving existing early rejection behavior.
🤖 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 `@scripts/installer.nsh`:
- Around line 263-267: Update the pending-website-anonymous-id carrier handling
around SetShellVarContext current so elevated /ALLUSERS installs do not read or
delete the file in the administrator’s profile. Persist the carrier through the
unelevated interactive user context, or skip this carrier path for that install
mode, while preserving cleanup for the intended user profile.
In `@src/main/index.ts`:
- Around line 1416-1418: Update the comments at src/main/index.ts:1416-1418 to
state that startup removes the compatibility marker regardless of guard state;
at src/main/lib/deviceId.ts:90-92 to describe the marker as compatibility-only
and cleared at boot; at src/main/lib/deviceId.ts:170-172 to simply describe the
helper as removing the compatibility marker; and at
src/main/lib/deviceId.ts:208-216 to explain marker precedence and deferred
cleanup without release-history references.
In `@src/main/lib/cloudUrl.test.ts`:
- Line 40: In the test covering withCloudDistributionUtm, extract the repeated
“not a url” literal into an input variable and use that variable both as the
function argument and expected assertion value, matching the adjacent non-cloud
URLs test structure.
In `@src/main/lib/firebaseAuthIdentity.ts`:
- Around line 142-148: Update the anonymous conflict handling around
anonymousEpochIsUnmergeable and markAnonymousEpochUnmergeable in
src/main/lib/firebaseAuthIdentity.ts:142-148 to fail closed when persistence
fails by durably rotating the epoch or suspending capture/binding; do not rely
on the in-memory taint surviving a restart. Add coverage in
src/main/lib/firebaseAuthIdentity.test.ts:530-547 that simulates restart after
the marker write failure and verifies the prior epoch cannot bind.
- Around line 152-156: Update the signed-in user flow around
applyFirebaseUserConsensus to validate userId with the existing PostHog
illegal-ID guard before assigning requestedUserId or binding consensus. Return
without binding when the guard rejects the UID, while preserving the current
clearUnmergeableEpoch behavior for valid IDs.
In `@src/main/lib/ipc/registerTelemetryHandlers.ts`:
- Around line 46-48: The signed-in telemetry normalization path must reject
Firebase UIDs that match the existing illegal PostHog distinct-ID validator. In
src/main/lib/ipc/registerTelemetryHandlers.ts lines 46-48, apply that validator
after normalizeOpaqueIdentifier and return null for matching values; in
src/main/lib/ipc/registerTelemetryHandlers.test.ts lines 204-223, add coverage
asserting every reserved value is rejected in a signed-in payload.
In `@src/main/lib/telemetry.ts`:
- Around line 635-637: Update applyFirebaseUserConsensus to reject Firebase UIDs
flagged by isIllegalPostHogDistinctId() before rotating the anonymous ID, while
retaining the existing normalizeOpaqueIdentifier validation. Add coverage for
illegal values such as “anonymous” and “0”, ensuring they leave the current
distinct ID unchanged.
In `@src/renderer/src/lib/rendererBootstrap.ts`:
- Line 386: Remove the orphaned “Person-property upserts…” comment from the
callback near getDeviceId(), or move it beside the actual
registerTelemetryProperties calls. Ensure the comment no longer implies that
this callback performs person-property upserts.
- Around line 375-376: Reword the comment near registerCohortContext to
distinguish its unconditional registration from conditional Datadog effects:
clarify that Datadog context writes and setUser only apply when
isDatadogInitialized is true, while PostHog person properties continue routing
through main.
---
Outside diff comments:
In `@src/main/lib/telemetry.ts`:
- Around line 847-869: The capture function currently commits rate-limit and
session-count accounting before client.capture succeeds. Move the
_eventsCapturedThisProcess increment and corresponding _checkRateLimit
commitment into the successful SDK-write path, or explicitly roll both back in
the catch block, so rejected writes do not consume volume-guard budget while
preserving existing early rejection behavior.
🪄 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: a98f8659-2c8f-4280-a725-fd93812bd7a2
📒 Files selected for processing (36)
packages/comfyui-desktop-bridge-types/comfyDesktopBridge.d.tspackages/comfyui-desktop-bridge-types/package.jsonscripts/installer.nshsrc/main/auth/firebaseBridge/index.tssrc/main/host/attach.tssrc/main/host/createHostWindow.tssrc/main/index.tssrc/main/lib/anonymousIdentity.test.tssrc/main/lib/anonymousIdentity.tssrc/main/lib/cloudCapacity.tssrc/main/lib/cloudUrl.test.tssrc/main/lib/cloudUrl.tssrc/main/lib/deviceId.test.tssrc/main/lib/deviceId.tssrc/main/lib/downloadAttribution.test.tssrc/main/lib/downloadAttribution.tssrc/main/lib/experiments.test.tssrc/main/lib/experiments.tssrc/main/lib/firebaseAuthIdentity.test.tssrc/main/lib/firebaseAuthIdentity.tssrc/main/lib/ipc/registerTelemetryHandlers.test.tssrc/main/lib/ipc/registerTelemetryHandlers.tssrc/main/lib/ipc/sessionActions/launch.tssrc/main/lib/opaqueIdentifier.tssrc/main/lib/telemetry.test.tssrc/main/lib/telemetry.tssrc/main/lib/trustedCloudUrl.test.tssrc/main/lib/trustedCloudUrl.tssrc/main/lib/userTier.test.tssrc/main/lib/websiteAnonymousIdentity.test.tssrc/main/lib/websiteAnonymousIdentity.tssrc/preload/api.tssrc/preload/comfyPreload.tssrc/renderer/src/lib/rendererBootstrap.tssrc/types/comfyDesktopBridge.tssrc/types/ipc.ts
💤 Files with no reviewable changes (3)
- src/main/lib/downloadAttribution.test.ts
- src/main/lib/downloadAttribution.ts
- src/preload/api.ts
…ropped (GTM-277) A capture dropped by the SDK or the volume guards previously still cleared pendingSessionStart, pendingFirstLaunch, and the queued person-prop buffers, losing the one-shot payload forever (first_launch's on-disk guard is burned at boot). capture() now reports admission and the deferred buffers are only cleared on success, so the next flush trigger retries them exactly once.
PostHog ingestion refuses to merge distinct IDs like 'undefined', 'anonymous', or '[object Object]'. A carrier or persisted file holding one would pool unrelated installs into a shared bucket and silently strand the pre-login history at identify time. Reject them at carrier decode (treated as no carrier: cleared, fall back to D) and at persisted-ID read/write (boot regenerates a mergeable random D).
…sus (GTM-277) A main-frame load failure without a did-fail-provisional-load previously left mainFrameNavigationsInFlight stuck, pinning the reporter to pending and blocking the user consensus that triggers the anonymous-to-Firebase identify. Handle did-fail-load with dedup against provisional failures, restore the retained document state on settle, and compare reporter frames by processId/routingId so an equivalent main-frame wrapper object is not rejected as a different frame.
…y guards (GTM-277) bindUserId is real again: interactive sign-ins verified by the main process (OAuth loopback, desktop login code) bind through applyFirebaseUserConsensus, so hosted bundles without the consensus bridge still stitch; consensus supersedes the bind and same-UID rebinds stay no-ops (GTM-93 decision 8). Firebase UIDs are rejected when PostHog would refuse to merge them — at the IPC boundary and before the consensus bind burns an anonymous-ID rotation. When the conflict-taint marker cannot persist, the epoch is durably replaced instead so a restart cannot resurrect a conflicted anonymous ID. isIllegalPostHogDistinctId moves to opaqueIdentifier (pure module).
…-277) Per-machine installs run customInstall in an elevated process that may be a different Windows account (over-the-shoulder UAC, SYSTEM for silent IT deploys), so per-user shell folders resolve to that account's profile. The carrier would land where the real user never reads it — or worse, where the admin's own Desktop adopts another user's website identity. Skip the block when $installMode is "all"; Desktop falls back to its generated ID.
8b05b95 to
7215d66
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/lib/telemetry.ts`:
- Around line 1045-1046: The privacy claims in telemetry.ts at lines 1045-1046
and cloudCapacity.ts at lines 7-8 should be scoped to the evaluation request
payload: state that the payload contains only the installation-stable evaluation
key and flag key, without claiming those are the only data reaching the
endpoint.
🪄 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: 078c2dd1-32e0-4105-9635-5ccbe48ca2aa
📒 Files selected for processing (36)
packages/comfyui-desktop-bridge-types/comfyDesktopBridge.d.tspackages/comfyui-desktop-bridge-types/package.jsonscripts/installer.nshsrc/main/auth/firebaseBridge/index.tssrc/main/host/attach.tssrc/main/host/createHostWindow.tssrc/main/index.tssrc/main/lib/anonymousIdentity.test.tssrc/main/lib/anonymousIdentity.tssrc/main/lib/cloudCapacity.tssrc/main/lib/cloudUrl.test.tssrc/main/lib/cloudUrl.tssrc/main/lib/deviceId.test.tssrc/main/lib/deviceId.tssrc/main/lib/downloadAttribution.test.tssrc/main/lib/downloadAttribution.tssrc/main/lib/experiments.test.tssrc/main/lib/experiments.tssrc/main/lib/firebaseAuthIdentity.test.tssrc/main/lib/firebaseAuthIdentity.tssrc/main/lib/ipc/registerTelemetryHandlers.test.tssrc/main/lib/ipc/registerTelemetryHandlers.tssrc/main/lib/ipc/sessionActions/launch.tssrc/main/lib/opaqueIdentifier.tssrc/main/lib/telemetry.test.tssrc/main/lib/telemetry.tssrc/main/lib/trustedCloudUrl.test.tssrc/main/lib/trustedCloudUrl.tssrc/main/lib/userTier.test.tssrc/main/lib/websiteAnonymousIdentity.test.tssrc/main/lib/websiteAnonymousIdentity.tssrc/preload/api.tssrc/preload/comfyPreload.tssrc/renderer/src/lib/rendererBootstrap.tssrc/types/comfyDesktopBridge.tssrc/types/ipc.ts
💤 Files with no reviewable changes (3)
- src/main/lib/downloadAttribution.ts
- src/main/lib/downloadAttribution.test.ts
- src/preload/api.ts
| * consent. The only data leaving the device is the installation-stable | ||
| * evaluation key and the flag key; no person properties are sent. |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Scope the feature-flag privacy claim to request payload fields.
GeoIP remains enabled, so the endpoint receives network metadata beyond the evaluation and flag keys.
src/main/lib/telemetry.ts#L1045-L1046: say the evaluation request payload contains only the stable key and flag key.src/main/lib/cloudCapacity.ts#L7-L8: use the same payload-scoped wording.
📍 Affects 2 files
src/main/lib/telemetry.ts#L1045-L1046(this comment)src/main/lib/cloudCapacity.ts#L7-L8
🤖 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/lib/telemetry.ts` around lines 1045 - 1046, The privacy claims in
telemetry.ts at lines 1045-1046 and cloudCapacity.ts at lines 7-8 should be
scoped to the evaluation request payload: state that the payload contains only
the installation-stable evaluation key and flag key, without claiming those are
the only data reaching the endpoint.
Delete comments that restated callee docblocks or another module's behavior, and replace the W/D single-letter identity shorthand with plain terms everywhere outside telemetry.ts, which defines it.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
scripts/installer.nsh (1)
270-308: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueIndent the block for readability.
The commands inside this
${If}block aren't indented. A little indentation goes a long way to keep confusion at bay, and makes the code as neat as a pin, I say!🤖 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 `@scripts/installer.nsh` around lines 270 - 308, Indent all commands within the `${If} $R3 >= 2` block, including its nested `${AndIf}`, comment, directory creation, file-writing operations, and `${EndIf}`, without changing the installer logic.
🤖 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 `@scripts/installer.nsh`:
- Around line 270-308: Indent all commands within the `${If} $R3 >= 2` block,
including its nested `${AndIf}`, comment, directory creation, file-writing
operations, and `${EndIf}`, without changing the installer logic.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 6be240d7-6c56-4441-b190-46488b1bda5b
📒 Files selected for processing (9)
scripts/installer.nshsrc/main/index.tssrc/main/lib/anonymousIdentity.test.tssrc/main/lib/anonymousIdentity.tssrc/main/lib/cloudUrl.tssrc/main/lib/telemetry.test.tssrc/main/lib/telemetry.tssrc/main/lib/websiteAnonymousIdentity.test.tssrc/main/lib/websiteAnonymousIdentity.ts
💤 Files with no reviewable changes (1)
- src/main/lib/cloudUrl.ts
|
Did a deep pass on this (identity model + trust boundary + consensus state machine + the installer carrier). Really solid work — the two things that could have sunk it both hold up:
Also 👍 on moving off the deprecated alias path onto One thing to reconcile before mergeThe description says the #1222 conflict was resolved by routing It's safe (the OAuth UID is main-authoritative, not renderer-supplied, so no spoof/merge). But there's an asymmetry worth a decision:
Should-fix (your call, none blocking)
Confirm-intent (all fail safe, toward anonymous)An Net: no blocking security or merge bug. Reconcile the description/precedence item and the rest is polish. Nice architecture. |
deepme987
left a comment
There was a problem hiding this comment.
adding preemptive approval if you're blocked on this. Posting [agent] review table
- Add opaqueIdentifier.test.ts covering the full PostHog-illegal-ID vocabulary and normalizeOpaqueIdentifier edge cases; consumers keep one representative case each proving they consult the shared check. - Table-ify bucketError and the deployment-tagging tests with it.each. - Extract a setupTelemetry() helper replacing the repeated env/init/consent/bind boilerplate across telemetry.test.ts describe blocks, removing the cross-block consent-state coupling. - Merge websiteAnonymousIdentity.test.ts into anonymousIdentity.test.ts (byte-identical fs mock harness) and chain the two retained-document cancel scenarios in firebaseAuthIdentity.test.ts.
The filename carrier now holds the PostHog $device_id verbatim instead of
an unpadded base64url envelope. posthog-js device IDs are 36-char lowercase
hyphenated UUIDs, which are already filename-safe, so the encoding bought
nothing for the only producer we have; the Router gates emission on the
same UUID shape Desktop validates.
The fixed-length payload also lets the installer extract exactly 36 chars
after the 26-char prefix and ignore everything after them, so browser
duplicate-download names ("… (1).exe") keep their carrier instead of
silently losing attribution.
The persisted-ID file envelope keeps base64url but its version tag is
renamed b64id1_ so phid1_ refers only to the filename-carrier grammar.
|
I'm fixing this one later, it has a very funny backstory. Bridge type has two hand-synced copies — comfyPreload imports the local type, #13687 consumes the published .d.ts, nothing keeps them in sync. Generate the package .d.ts in CI (or import the package type) so a future edit can't ship a lie to the frontend. |
…dedup map Three review findings, each validated against the code before fixing: - A transient split write failure (persist(W) fails, the random D minted in the same boot persists) permanently outranked the retained carrier on the next startup. When W is valid but unpersistable, fall back to an ephemeral ID for this process — matching getOrCreateAnonymousDistinctId's own failed-persist behavior — so the carrier retries next boot. - A present-but-undecodable identity file fell through to carrier adoption. The app's own writer is atomic, so such a file always means external interference and never a fresh install: fail closed, drop the carrier, and regenerate D. - provisionalFailureTerminals only drained via paired did-fail-load echoes, which Electron never emits for canceled (ERR_ABORTED) loads, so entries accumulated for the view's lifetime — and a stale entry could swallow a later genuine terminal with the same key, leaving the reporter pending. Flush the map at every main-frame commit; the new test locks the post-commit terminal settling (verified to fail without the fix). Also documents the installation_id caveat: many call sites still override the machine-hash default with the per-install record id; #1159 redirects those overrides to install_id and should rebase over this branch.
|
@deepme987 Thanks for the deep pass. Should-fix items are addressed in 92fb15e:
Heads-up since your pass: the carrier switched from base64url to the raw |
…13687) ## Summary Reports each hosted Cloud renderer's declarative Firebase auth state to Desktop. Desktop remains the sole owner of PostHog identity and arbitrates all live `WebContents` before changing the process-global person. Linear: [GTM-278](https://linear.app/comfyorg/issue/GTM-278) · Parent: [GTM-93](https://linear.app/comfyorg/issue/GTM-93) ## Changes - reports `pending` as soon as host auth synchronization starts - waits for Firebase initialization, then reports `signed_out` or `signed_in` with the Firebase UID - reports restored sessions, logout, and direct account switches through the same declarative state contract - makes repeated same-UID Firebase updates a no-op - adds the optional `reportFirebaseAuthState` contract to the Desktop bridge types - keeps host bridge failures from interrupting renderer startup or Firebase auth ## Ownership and privacy - the frontend never calls PostHog `identify`, `alias`, bind, or unbind APIs - browser PostHog provider behavior is unchanged - the auth-state message is local to Desktop; Desktop Comfy-Org#1272 applies its own telemetry-consent gate before any PostHog identify or emission - `enable_telemetry` controls only the frontend `HostTelemetrySink` (renderer event forwarding), so this observer deliberately does not share that rollout flag - no canonical `comfy_user_id`, `/api/user` lookup, Cloud API dependency, Redis state, token redemption, or website transport change is added ## Review and rollout order Review [Comfy-Desktop Comfy-Org#1272](Comfy-Org/Comfy-Desktop#1272) first because it defines the trusted state-reporting API and consensus policy. Deploy this frontend first: the method is optional and therefore a no-op on older Desktop builds. Then release Desktop Comfy-Org#1272, and only afterward deploy [comfy-router #34](Comfy-Org/comfy-router#34). Auth [Comfy-Desktop Comfy-Org#1222](Comfy-Org/Comfy-Desktop#1222) must not become an identity authority; with Desktop Comfy-Org#1272 its legacy imperative bind is inert and the post-reload Firebase report is the source of truth. ## Testing - `pnpm test:unit src/platform/telemetry/hostUserIdSync.test.ts src/platform/telemetry/providers/cloud/PostHogTelemetryProvider.test.ts` — 53 tests passed - `pnpm typecheck` - targeted Oxlint and ESLint - targeted `oxfmt --check` - `pnpm knip` - pre-commit typecheck/lint/format hooks - pre-push `knip` - `git diff --check` No user-facing UI changes.
Summary
Carries the website's anonymous PostHog identity into a fresh Windows Desktop install, keeps every pre-auth Desktop event anonymous, and identifies the Firebase UID only after all live hosted Cloud views agree on the user.
Linear: GTM-277 · Parent: GTM-93
Identity contract
$device_idisW.Comfy-Desktop-Setup-phid1_<W>.exe, carryingWverbatim; the Router only emits the carrier whenWis a 36-character lowercase hyphenated UUID (posthog-js's$device_idformat, version/variant nibbles not pinned).… (1).exe) keep their carrier. Before any telemetry capture, Desktop validates the exact lowercase-UUID shape, then durably seeds its anonymous-ID store with exactW.D. Missing, malformed, or unpersistable carriers fall back to persisted/generated randomD.WorDwith$process_person_profile: false. Pre-auth person properties remain in memory.identify(F, { $anon_distinct_id: W_or_D, $set, $set_once }), and it runs only after auth consensus.Dbefore identify, then adopts it on logout, account switch, or the next process.Auth consensus
pending,signed_out, orsigned_in(F)state through the optionalreportFirebaseAuthStateDesktop bridge method.Dbefore any later identify so conflicting users can never merge through the same anonymous ID.isLoadingMainFrame()is still true.bindUserId/unbindUserIdbridge methods are removed. Deprecated main-process compatibility exports are no-ops, so Desktop auth #1222 cannot bypass consensus during integration.Integration with Desktop auth #1222
The current #1272 and #1222 heads have one expected textual conflict in
src/main/auth/firebaseBridge/index.ts: #1222 refactors the login flow while this PR removes the old native imperative identity bind. Rebase #1272 after #1222 and resolve that line by keeping authentication/injection from #1222 while leavingflowShared.bindSignedInUserrouted only to the deprecated no-op compatibility hook. The synthetic resolved stack passes typecheck and 185 focused tests; onlyapplyFirebaseUserConsensusmay identify.Removed
download_tokenevent properties, andcomfy.desktop.identity.download_attributedevent.installation_idas an event/person property only.Review order
Deployment order
W.Older Desktop releases safely ignore the new filename suffix, but cannot complete the deterministic website-to-Desktop join.
Verification
pnpm run typecheckpnpm run lintpnpm run buildpnpm run test— 198 files passed; 2,978 tests passed, 1 skippedgit diff --checkNo user-facing UI changes.