Clients and invitations
How magic-link client access works
What clients see when they receive a magic-link invite, how the session lifecycle works, and how to reissue links if a client loses access.
Audience: owner · 4 min read · Last reviewed
Magic-link auth is how clients access their portal. No password to create, no password to lose. Click the link in the email, you're in.
What the client sees
When you tick Send magic-link invite now on a new client, the client receives an email from noreply@clientnest365.com (or your custom-domain sender if configured). The subject line reads:
Your private portal at [Your Firm Name]
The body carries your firm name, the welcome message you set in Settings → Branding, and a single button: Open your portal. That button is the magic link.
When they click:
- The browser loads
portal.yourfirm.com/portal/<32-byte-token>(orclientnest365.com/portal/<token>if no custom domain). - The server hashes the token, looks up the matching client, creates a signed session cookie, and consumes the token.
- The browser redirects to
portal.yourfirm.com/portal/c/<client-slug>(the client's permanent portal URL). - The client lands in their portal with full access.
No password. No "create an account" form. No "verify your email" step.
Session lifecycle
The session cookie is HttpOnly, Secure, SameSite=Lax, and HMAC-signed. Default lifetime is 30 days from issue.
When the session expires, the next portal visit redirects to a "session expired" page that offers to email a fresh magic link to the same address. The client clicks Send me a new link, gets the email, clicks, and they're back in.
The client never has to remember anything. The portal sends them what they need each time.
What "one-time use" means
Each magic-link token can be consumed exactly once. After the first click:
- The token is invalidated in the database
- A second click of the same URL hits a "this link has been used" page
- The page offers to email a fresh link
This protects against email forwarding attacks: if the client forwards the email to a colleague (or if the email is intercepted), only one of them can use it.
If the client clicks the link, opens the portal, then closes the browser tab, the session cookie persists. They can re-open the portal URL (portal.yourfirm.com/portal/c/<slug>) without clicking the original email again. The one-time-use rule is for the token, not the session.
When to reissue a link
You'll need to reissue when:
- The client says they didn't receive the email. First check the spam folder. If still missing, go to
/app/clients/<client>, click Send new invite. - The token expired before they clicked. Default token TTL is 24 hours. After that, reissue.
- The session expired and they want back in. They can self-serve via the "session expired" page, or you can send a fresh link from the client detail page.
- They lost access to the email account. This is the hardest case. The new link goes to a new email address; update the client's primary email first.
To reissue from the agency side:
- Open
/app/clients/<client> - Click Resend invite in the top-right action menu
- Confirm the email address (you can update it here if needed)
- The new link replaces the old one (the old token, if unused, is invalidated)
What clients should NOT do
These are worth communicating to clients during onboarding:
- Don't forward the invite email to colleagues. If multiple people at the client need access, ask the firm to add them as additional client contacts. Each gets their own magic link.
- Don't bookmark the magic-link URL itself. It's one-time use. Bookmark the portal URL after logging in:
portal.yourfirm.com/portal/c/<client-slug>. - Don't share the portal URL with screenshots that include the URL bar. The portal URL is not sensitive by itself (no token), but it's still per-client information.
Audit log
Every magic-link issue, click, and session creation is logged. The log captures:
- Timestamp
- Source IP
- User-agent
- Token hash (not the token itself, which is never stored unhashed)
- Client and matter the token was for
You can view the audit log per client at /app/clients/<client>/activity. It's especially useful for fee disputes ("the client claims they never received the engagement letter; here's the timestamp of their portal open the day after we sent it").
Security notes
The implementation is standard but worth knowing:
- Tokens are 32 bytes of cryptographically secure randomness (
crypto.randomBytes(32)in Node.js) - Database stores SHA-256 hashes of tokens, not the raw tokens
- Tokens have a 24-hour TTL on first-issue, 15-minute TTL on session-renewal links
- Rate-limit: 5 invites per hour per source IP, to prevent enumeration attacks
- HTTPS-only cookies; never readable from JavaScript (HttpOnly)
- Sessions can be revoked from the agency side:
/app/clients/<client>→ Revoke all sessions
If your firm has compliance requirements that magic links don't meet (e.g., regulated healthcare or banking), let us know via contact. For most service-business contexts, the magic-link model is appropriate and well-supported.