web: a dead invite link redirects signed-in members to the chat (#598)
An existing member clicking a stale invite (an old link in a chat message, email, or the one-time setup link they already used) got "This invite has been used or is no longer valid. Ask for a new one." — an error about an invite they don't need. Check for a live session first and go to the chat; liveSession's definitive-403 rule keeps the honest error for tokens from a reset instance, and the native add-chat embed keeps the join flow.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2 files changed,
+12
−0
changelog/2026-07-10-expired-link-goes-home.md+4 −0web/static/join.js+8 −0
diff --git a/changelog/2026-07-10-expired-link-goes-home.md b/changelog/2026-07-10-expired-link-goes-home.md| new file mode 100644 |
| index 0000000..60f53be |
| --- /dev/null |
| +++ b/changelog/2026-07-10-expired-link-goes-home.md |
| @@ -0,0 +1,4 @@ |
| +🤖 Clicking an old invite link when you're already signed in on this device |
| +now takes you straight to your chats. Before, it showed "this invite has been |
| +used" — an error you couldn't do anything with, about an invite you didn't |
| +need. |
diff --git a/web/static/join.js b/web/static/join.js| index 70e147b..21ad2bb 100644 |
| --- a/web/static/join.js |
| +++ b/web/static/join.js |
| @@ -77,6 +77,14 @@ async function start() { |
| return showError("Couldn't reach the server. Try again."); |
| } |
| if (!info.ok) { |
| + // A dead link in an existing member's hands is just a stale bookmark — |
| + // they're already in, so go to the chat instead of an error card telling |
| + // them to ask for an invite they don't need. liveSession (not a raw |
| + // localStorage read) so a token from a reset instance still falls through |
| + // to the honest error. Embed keeps the error: the native add-chat webview |
| + // owns navigation, and its shell expects a join, not a redirect. |
| + const existing = window.__lchatEmbed ? null : await liveSession(); |
| + if (existing) return location.replace("/"); |
| return showError("This invite has been used or is no longer valid. Ask for a new one."); |
| } |