Skip to main content
ClientNest365ClientNest365

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:

  1. The browser loads portal.yourfirm.com/portal/<32-byte-token> (or clientnest365.com/portal/<token> if no custom domain).
  2. The server hashes the token, looks up the matching client, creates a signed session cookie, and consumes the token.
  3. The browser redirects to portal.yourfirm.com/portal/c/<client-slug> (the client's permanent portal URL).
  4. 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:

  1. Open /app/clients/<client>
  2. Click Resend invite in the top-right action menu
  3. Confirm the email address (you can update it here if needed)
  4. 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.