User Registration & Email Verification
RESTHeart CloudFlow Overview
sequenceDiagram
participant C as Client
participant R as RESTHeart
participant M as MongoDB
participant E as Email
C->>R: POST /auth/register
Note over R: validate fields, zxcvbn score ≥ 3
R->>M: check email uniqueness
R->>M: create user (roles: $unauthenticated + verify token)
M-->>R: OK
R->>E: verification email
R-->>C: 201 Created
Note over C,E: user clicks link in email
C->>R: GET /auth/verify?email=…&token=…
R->>M: constant-time token compare + TTL check
R->>M: set roles → user, unset verify token
M-->>R: OK
R-->>C: 302 + JWT cookie → frontend app URL
Registration flow
POST /auth/register is the public signup endpoint. It creates a new user and a new tenant in a single atomic operation.
Request
POST /auth/register
Content-Type: application/json
{
"firstName": "Alice",
"lastName": "Rossi",
"teamName": "Acme",
"email": "alice@acme.com",
"password": "correct-horse-battery"
}
Server-side steps
-
Validate all required fields.
-
Enforce password strength via zxcvbn (score ≥
minimumPasswordStrength, default 3). -
Check email uniqueness —
409 Conflictif already registered. -
Generate a cryptographically random
verificationToken(256-bit) andverificationCreatedAttimestamp. -
Create the user document with
roles: ["$unauthenticated"]and the verification token. -
Create a
membershipdocument linking the user to the tenant asowner. -
Send a verification email containing a one-time link:
{baseAppUrl}/auth/verify?email=alice@acme.com&token=<verificationToken> -
Return
201 Created.
Response
{ "message": "Registration successful. Check your email to verify your address." }
Error responses
| Status | Reason |
|---|---|
|
Missing or invalid fields; password too weak |
|
Email already registered |
|
Note
|
Consents management:
The same interceptor pattern applies to |
Email verification
GET /auth/verify?email=…&token=… is sent as a link in the registration email.
Server-side steps
-
Extract
emailandtokenfrom the query string. -
Find the user by email.
-
Compare
tokenagainstverificationTokenusing constant-time comparison (timing-attack mitigation). -
Check that
verificationCreatedAtis within the TTL (verificationTokenTtlDays, default 7 days). -
Assign the system ACL role from
accountsConfig.default-role(default:user) — this replaces the$unauthenticatedrole assigned at registration.$unsetverificationToken and verificationCreatedAt. -
Issue a JWT access token + refresh cookie.
-
Redirect to
{frontendAppUrl}.
Expired token
If the token has expired, the endpoint returns 400 with a message inviting the user to request a new verification email from the login page.
|
Note
|
Re-sending a verification email is triggered by POST /auth/resend-verify (not yet implemented in v1 — users can contact support or attempt login which will prompt re-verification).
|