feat: show "invitation expired" message for late team-invite acceptances#1642
Open
giladresisi wants to merge 1 commit into
Open
feat: show "invitation expired" message for late team-invite acceptances#1642giladresisi wants to merge 1 commit into
giladresisi wants to merge 1 commit into
Conversation
When a user accepted a team invitation after the 1-hour link expiry, they were silently not added to the inviting org and dropped on the pricing page with no explanation. Surface an "invitation expired" toast across every acceptance path. - proxy: already-logged-in invitees redirect to the landing page with ?invitation=expired instead of the (query-stripping) "/" hop - register/login/oauth: a single-use `org` invite cookie is handled by AuthService.consumeOrgInviteCookie, which flags expiry via a short-lived `invitation` cookie (so it survives the email-activation detour) and then always clears the `org` cookie so a consumed/expired token can't leak to the next user who signs in on the same browser - frontend: InvitationMessage shows the toast from the query param or the cookie, once, then clears both Tested locally (temporarily lowering the invite expiry to 1 minute): - register (brand-new account) — expired invite shows the toast - activation flow (LOCAL + email provider) — toast survives the register -> email -> activate round-trip and shows after landing - login (existing, logged-out invitee) — expired invite shows the toast - cookie reuse — after the first auth event the `org` cookie is cleared, so logging in as a different user afterwards (e.g. the inviting org owner) no longer shows the toast Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Contribution-checker quality warning Heuristics that flagged:
If this is a genuine contribution, please add detail to your PR description and tighten the diff scope before reviewers look at it. |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Team invitation links expire 1 hour after they're sent. The email even says so — but in practice many users skim past that wording and click the link later. When they do, they're silently not added to the inviting org: no error, no explanation. They just land in their own (often free) workspace / on the pricing page and assume the invite or the product is broken.
What this does
Surfaces a clear "invitation expired" toast whenever a late acceptance fails to join the inviting org, so the user understands what happened and can ask for a fresh invite — across every way an invite can be accepted.
How
The challenge is that an invite can be accepted through several different flows, which land the user in the app via different mechanisms:
?invitation=expired.orgcookie. A newAuthService.consumeOrgInviteCookiehelper handles it in one place: if the token was expired/invalid it sets a short-lived, non-httpOnlyinvitationcookie (a cookie rather than a redirect param, because the brand-new-account flow detours through an email-activation step before the user ever reaches the app), and it always clears theorgcookie so a consumed token is single-use.InvitationMessagecomponent (mounted once in the app layout) shows the toast from either the query param or the cookie, exactly once, then clears both.Single-use / no cross-user leak
Because the
orgcookie is cleared as soon as any auth event consumes it, the expired signal only ever affects the actual late invitee. A subsequent login on the same browser by a different user (e.g. the inviting org owner) no longer re-triggers the toast.Testing
Verified locally (temporarily lowering the invite expiry to 1 minute):
orgcookie is cleared, so logging in as a different user afterwards (e.g. the inviting org owner) does not show the toastNotes
🤖 Generated with Claude Code