# Sign in with Discord on web and make share links origin-aware \(\#182\) · dara/icarus

[View on GitCafe](https://git.cafe/dara/icarus/commit/b32d08655c49fa9372d1353ac8b9019cd31a5c13)

Repository: [dara/icarus](https://git.cafe/dara/icarus)

Visibility: public

Requested revision: b32d08655c49fa9372d1353ac8b9019cd31a5c13

Requested commit: b32d08655c49fa9372d1353ac8b9019cd31a5c13

Commit: b32d08655c49fa9372d1353ac8b9019cd31a5c13

Tree: 5c4a02cfda4eb4e18be11263a90e75fc27b5f86c

Author: Dara Adedeji

Committer: GitHub

## Message

```
Sign in with Discord on web and make share links origin-aware (#182)

* Make Discord sign-in and share links work on the web beta

Discord sign-in on web asked Supabase to return to icarus://auth/callback,
which a browser cannot open. On web the redirect is now the root of the
page's own origin, and the callback check accepts a URI that lands on this
build's redirect with a sign-in result. The page URL is published at startup
when it is an auth callback or a share link (app_links on web only echoed
it), and after the handler runs the sign-in parameters are removed from the
address bar so a refresh does not replay a spent code. detectSessionInUri
stays false: Supabase's detector would treat a ?code= share link as a
sign-in and bypass authProvider's loading and error states.

Share links were fixed to icarusstrats.com. They now take an origin: native
builds keep production, web uses the page origin, so the beta hands out beta
links. The recognizer accepts production plus the current origin. Uri.base
is read only in currentShareOrigin() and currentAuthRedirectUri(); the
format helpers stay pure.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Keep a pending share code across the web Discord sign-in

On web, Discord sign-in navigates the tab away and back, which restarts the
app and dropped a share code opened while signed out. The pending code now
lives in a PendingShareCodeStore: the tab's sessionStorage on web (memory if
the browser refuses storage), memory on native. The controller restores it
when created, so the auth-ready listener redeems it once the returning
session is ready. It is cleared once redeemed, or after a failed redemption
the user was told about, so a revoked link does not replay its failure on
every reload.

Docs list the real Pages host, icarus-web-a50.pages.dev, in the Supabase
redirect allowlist.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Reject injected auth tokens, scope share-code clears, redact share codes

A link to the auth redirect carrying access_token/refresh_token (query or
fragment) was treated as a sign-in and handed to getSessionFromUrl, which
imports token payloads even in PKCE mode. Anyone could craft one and sign
the victim into the attacker's account, on web and through icarus:// on
desktop alike. classifyAuthCallbackUri now accepts only a PKCE code or an
error; token-bearing or undecodable links are rejected, logged redacted,
never sent to Supabase, and on web scrubbed from the address bar. We only
use the PKCE flow, so no genuine callback carries tokens.

A redeem attempt that failed late cleared whatever code was pending, even a
newer one. Each held code now has a generation, and an attempt clears only
its own.

Deep-link and launch-argument logs printed share codes in full. They go
through redactDeepLinkUri, which hides the /share/<code> path, ?code=,
?token=, and sign-in secrets, and never throws on undecodable escapes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Harden link parsing: any-case token names, total redaction and share parsing

Token parameter names are compared in lowercase, so ACCESS_TOKEN= is
rejected like access_token= and scrubbed from the address bar.

redactDeepLinkUri no longer throws on a path that does not decode (e.g.
icarus://share/%FF?token=secret): it logs <unparseable link> instead, so one
bad startup argument cannot abort the loop over the rest. Launch arguments
shaped like links are always redacted, or logged as the placeholder when
they do not parse; plain file paths stay readable.

isIcarusShareUri and extractIcarusShareCode treat an undecodable path or
query as "not a share link" instead of throwing. On web isIcarusShareUri
runs on Uri.base before runApp, so a crafted /share/%FF URL could otherwise
stop the beta from starting.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
```

## Parents

- [ee96bb57fa9375d0c8bf767983c8ce479ead89ba](https://git.cafe/dara/icarus/commit/ee96bb57fa9375d0c8bf767983c8ce479ead89ba?format=markdown)

[Source at this commit](https://git.cafe/dara/icarus/tree/b32d08655c49fa9372d1353ac8b9019cd31a5c13?format=markdown)
