Skip to content

Refactor share-auth flow into reducer + driver pattern#426

Open
valentinpalkovic wants to merge 1 commit intovalentin/viral-sharing-2from
valentin/viral-sharing-6-digit
Open

Refactor share-auth flow into reducer + driver pattern#426
valentinpalkovic wants to merge 1 commit intovalentin/viral-sharing-2from
valentin/viral-sharing-6-digit

Conversation

@valentinpalkovic
Copy link
Copy Markdown
Contributor

Summary

Refactors the share popover's authentication flow so the UI state and the OAuth state machine no longer share a single tangled component. The popover now drives a typed reducer for screen transitions, and OAuth itself lives behind a small pluggable driver interface with two implementations: device-code (verification code in a new tab + polled token) and authorization-code (popup with redirect back to the addon).

The driver-level split means the rest of the addon never sees the difference — the popover, manager redirect handler, and Authentication screen all consume the same SignInDriver interface and resume from the same snapshot shape across remounts. This makes it cheap to switch flows for experiments or rollback without touching call sites.

What changed

  • New typed reducer (shareReducer) owns the popover screen + share-request lifecycle, with a single START_UPLOAD action covering all four ways an upload can begin (initial publish, repeat publish, post-auth, and signed-in auto-skip).
  • New SignInDriver interface with two implementations:
    • device-code — open verification URL in a new tab, poll the token endpoint, no popup window.
    • authorization-code — open a popup, accept the OAuth redirect on this window, exchange the code for a token.
  • useShareAuth hook owns the driver lifecycle (start, resume, cancel, snapshot persistence) and translates driver outcomes into reducer actions.
  • The OAuth redirect handler in manager no longer instantiates a driver at module load — it's gated by an exported boolean constant that mirrors the configured flow.
  • Adds a dedicated Verifying screen for the device-code flow showing the user code as digit chips with a pulsing "waiting for verification…" indicator.
  • Snapshot-based resume: if the addon remounts mid-sign-in (panel close/reopen, manager reload), the driver picks up where it left off as long as the persisted snapshot's flow still matches the configured one.
  • Test coverage for both drivers, the reducer, the hook, the redirect handler, and the Authentication / Verify screens.

Toggling the OAuth flow

There is a single switch that controls which OAuth flow the addon uses. To change it, edit the constant in src/utils/signInDriver.ts:

export const OAUTH_FLOW: OAuthFlow = 'device-code';

Set it to either:

  • 'device-code' — current default. The addon opens the verification URL in a new browser tab, the user signs in on Chromatic, and the addon polls the token endpoint until a token is issued or the device code expires. No popup, no redirect, no special manager handling.
  • 'authorization-code' — the addon opens a popup window pointed at Chromatic's authorization URL, Chromatic redirects back to the addon's manager URL with a code + state, the manager forwards the grant to the popover via postMessage, and the driver exchanges the code for a token.

The same constant also drives handlesOAuthRedirect, an exported boolean the manager checks before installing its OAuth redirect listener — so flipping the switch automatically wires up (or removes) the redirect handler without any further code changes. Snapshots stored in session storage from a previous flow are dropped on mount when they don't match the active flow, so a switch never strands a user mid-sign-in.

Test plan

  • Verify share popover sign-in works end-to-end with OAUTH_FLOW = 'device-code': verification screen renders with the digit chips, opens the correct URL in a new tab, polls and completes upload after the user authorizes on Chromatic.
  • Verify share popover sign-in works end-to-end with OAUTH_FLOW = 'authorization-code': popup opens, redirect lands back on the manager, popover transitions to uploading after postMessage.
  • Close the popover mid-verification and reopen it — the verifying screen should resume against the same device code (device-code flow only; auth-code popup cannot resume after the popup closes).
  • Trigger the auth-error path (expired token from the API): popover should drop back to the sign-in screen and clear the access token without showing a generic error.
  • Cancel an in-flight upload from the uploading screen — share is canceled, telemetry fires share-canceled.
  • Sign in via the standalone Authentication screen (project setup flow), not just the share popover — verification screen, popup handling, and project-creation handoff should all still work for both flows.
  • Run yarn vitest run, yarn lint, and tsc --noEmit — all green.

🤖 Generated with Claude Code

Move share-popover state into a typed reducer and split the OAuth
sign-in into pluggable drivers (device-code, authorization-code) behind
a single SignInDriver interface. Adds the verifying screen, snapshot-
based resume across remounts, and a toggle so we can swap OAuth flows
without touching call sites.
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