Skip to content

Authentication

Sessions, refresh-token rotation, password sign-in, forgot password, and plug-and-play Google OAuth.

HttpOnly cookie + CSRF double-submit. The session cookie is pulse_session, max-age 30 days. CSRF token is exposed via pulse_csrf (readable cookie) and must echo back in the X-CSRF-Token header for state-changing requests.

Long-lived refresh tokens rotate on every use. Refresh-token families are revoked on detected reuse (a classic compromised-token signal). If a user is suddenly bounced to /login, the family was revoked — they re-authenticate.

Standard email + password. Passwords are stored as bcrypt hashes with cost 12.

/forgot → email link → /reset?token=.... Links are valid for 1 hour, one-time use. Falls back to dev-log mode if SMTP isn’t configured.

Plug-and-play. Set:

GOOGLE_OAUTH_CLIENT_ID=your-client-id
GOOGLE_OAUTH_CLIENT_SECRET=your-secret
# optional, defaults to ${PUBLIC_BASE_URL}/api/v1/auth/google/callback
GOOGLE_OAUTH_REDIRECT_URL=https://pulse.example.com/api/v1/auth/google/callback

…and restart the API. A Continue with Google button appears on the login page automatically.

Behaviour:

  • New Google user — provisioned with the verified email and display name, no password, gets a personal organization automatically.
  • Returning Google user — looked up by oauth_provider + oauth_subject, logged in.
  • Existing password user signing in with Google for the first time (email matches) — the Google identity is linked to the existing account; their existing org membership is preserved.

When either env var is missing, the feature is invisible: no button, callback endpoint returns 404. No DB toggle to maintain — env presence is the switch.

Register the redirect URL in Google Cloud Console → APIs & Services → Credentials. It must match exactly.