Define the invitation policy before sending email
Decide who may invite, which roles they may grant, and whether invitation acceptance consumes a seat. A workspace administrator should not be able to grant authority beyond their own delegated power. Keep organization rules, purchased capacity, and the proposed membership separate.
An invitation record should identify tenant, intended recipient, proposed role, inviter, creation time, expiry, status, and policy version. Distinguish pending, accepted, revoked, and expired states. Delivery state belongs in a separate record because an undelivered email does not necessarily invalidate the invitation.
Generate single-purpose credentials and protect their lifecycle
Generate a high-entropy random secret and store a verifier rather than plaintext where practical. Bind the verifier to the invitation record, not merely to an email address. Return safe public metadata only after a valid token is presented, and rate-limit unsuccessful lookups.
Keep invitation links out of logs, analytics, and third-party page resources. Apply an appropriate referrer policy on the acceptance screen. Expiry must be checked by the server; a browser countdown is only explanatory. Treat a resent invitation as a deliberate credential lifecycle decision, invalidating the old secret if replacement is the policy.
Verify who is accepting and show the actual workspace
Require a signed-in account with a verified address that satisfies the invitation recipient policy. Do not silently attach a forwarded invitation to whichever account happens to be logged in. Show the intended organization and role, and provide a safe switch-account path.
A domain invitation, email-specific invitation, and open team link grant different authority. Implement them as separate policies rather than gradually weakening one token handler. Restrict return navigation to approved local destinations so acceptance cannot become an open redirect.
Accept once inside an authorized transaction
Recheck current invitation status, expiry, tenant status, role existence, and recipient eligibility. Create the membership, consume or release any reserved seat, and mark the invitation accepted atomically. Enforce membership uniqueness in the database.
Two simultaneous acceptance requests should converge on one membership. An already accepted token may return a safe confirmation for the same authenticated recipient, but must not grant a second identity access. If capacity changed since creation, return an actionable outcome without consuming the token prematurely.
Handle changing roles, ownership, and capacity explicitly
Define whether an inviter losing authority invalidates pending invitations, and re-evaluate that rule at acceptance. If a role changes materially, require review or issue a replacement invitation instead of silently upgrading the recipient.
Seat reservations can prevent promises that cannot be fulfilled later, but they need expiry and reconciliation. Alternatively, allocate capacity at acceptance and explain that invitation issuance does not guarantee a seat. Never count both the pending invitation and the final membership as permanent usage.
Send asynchronously and keep recovery understandable
Commit the invitation and durable email intent together. Retry temporary delivery failures without generating duplicate membership grants. Give administrators a scoped screen to inspect pending invites, resend, revoke, and identify failed delivery.
Keep acceptance idempotent even when email is delivered several times. A link preview or email scanner must not accept an invitation through a GET request. Require an intentional, authenticated confirmation mutation before membership changes.
Test the lifecycle beyond the happy path
Test forwarding, a wrong logged-in account, duplicate acceptance, expiry at the commit boundary, revoked invitations, removed roles, suspended tenants, full capacity, and repeated resends. Verify that neither failure responses nor logs expose other organizations.
Record safe invitation IDs, actor, tenant, policy, role, and outcome in the audit trail. Monitor old pending invitations and delivery failures. Keep the acceptance page accessible with clear errors and a recovery action that does not require guessing what happened.
Build a more dependable Next.js application
Endurance Softwares helps teams design, build, test, and operate production-ready Next.js platforms.
