Invitations that fix themselves

If someone signs in without going through the invite link, the app finds their pending invitation by verified email and applies it automatically.

What it is

A repair pass that runs on every app load for a user who has no account attached. It looks up pending, unexpired invitations matching any of the user's verified email addresses, cross-checks the invitation's account against the inviter's current account, then applies role, crew and approved status, marks the invitation accepted, and stamps the person onto any work that was assigned to their email before they existed.

Also called: signed up but still pending · invite didn't take · stuck invitation · auto-accept invite

See it
Invitations that fix themselves
New lead 2
Marlin Hoover
$18k
Delia Yoder
$46k
Contacted 2
Sutter Kline
$59k
Ronan Petsch
$51k
Ivy Brubaker
$56k
Estimate 3
Ivy Brubaker
$40k
Gideon Alt
$51k
Sold 2
Marlin Hoover
$75k
Delia Yoder
$20k
Sutter Kline
$67k
A team list where a row flips from 'Invited' to their real role after the person's first sign-in, with no admin action. Logic in src/app/api/me/route.ts. Sample data — no customer information appears here.
How it works
  1. 1Runs only for a signed-in user whose identity has no account attached.
  2. 2Requires a VERIFIED email address — an unverified address is a claim, not proof.
  3. 3Matching is case-insensitive, because a stored mixed-case address wouldn't match a lowercased list.
  4. 4The invitation's account is cross-verified against the inviter's current account; a mismatch prefers the inviter's value and logs loudly.
  5. 5Role, crew and approved status are written to the user's identity; the invitation is marked accepted; a crew-scoped invitee is bridged into the crew roster with an explicit account id.
  6. 6Deferred assignments are resolved: estimates, leads and opportunities assigned to that email get the new user's id stamped on them.
Why we built it

The comment lists the two ways the happy path breaks: the auth provider 'recognizes the email and bounces to /sign-in instead of /sign-up', where no invite handler exists and 'the token is dropped on the floor'; or the person 'navigates to the tenant directly (bookmark, manual typing) and just signs in — they never see the invite link.' In both cases the user ends up signed in as the least-privileged role with every API call refusing them, while still appearing under Pending Invitations to the admin who invited them. The account cross-check is a separate incident: a mis-stamped invitation 'caused a new user to land on [the wrong tenant] when they were actually invited to [another] — a serious cross-tenant data exposure.' The verification gate is stated as the safety property: 'Without that gate, anyone could add an unverified email matching a pending invite to their Clerk account and silently claim the invite.'

The problem
  • Users who signed in off the invite path were stranded with no account and no access.
  • Admins saw people as 'pending' who had in fact already signed up.
  • Work assigned to someone by email before they had an account stayed unassigned after they joined.
Sound familiar?
What you get
Most stuck invitations resolve themselves on the user's next page load.
Work assigned by email is waiting for the person the moment they sign in.
Only verified addresses can claim an invitation.

See it on your own jobs

Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.

or keep browsing features →