🛣️ Authentication Routes
Authentication routes provide pre-configured HTTP endpoints for user authentication and authorization operations in NodeBlocks applications. These routes combine blocks (pure business logic functions), handlers, validators, and middleware to create complete API endpoints for login, registration, token management, and email verification.
🎯 Overview
Authentication routes are designed to:
- Provide complete API endpoints for user authentication operations
- Combine blocks and handlers with validators for secure operations
- Include authentication and authorization checks
- Support functional composition patterns
- Handle logging and error management automatically
📋 Route Structure
Each authentication route follows a consistent pattern:
- HTTP Method: Defines the operation type (GET, POST, PATCH, DELETE)
- Path: Specifies the endpoint URL with parameters
- Handler: Composed function chain using blocks and handlers
- Validators: Authentication and authorization checks
🔧 Available Authentication Routes
registerCredentialsRoute
Registers new user credentials with optional invitation processing.
Purpose: Handles user registration with support for invitation acceptance
Route Details:
- Method:
POST - Path:
/auth/register - Authentication: Not required
Handlers:
- With invitation token:
buildCheckInvitationTokenPayload,checkToken,getInvitationIdFromTokenInfo,getInvitationById,isPendingInvitation,registerCredentials,buildAcceptInvitationPayload,updateInvitation - Without token:
registerCredentials - Finally:
registerTerminator
Validators: None
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.registerCredentialsRoute);
Note: For invitation-specific functionality, see Invitation Blocks.
loginWithCredentialsRoute
User authentication via credentials with optional MFA support.
Purpose: Handles user login with credential validation and optional multi-factor authentication
Route Details:
- Method:
POST - Path:
/auth/login - Authentication: Not required
Authentication Flow:
When MFA is Disabled (default):
- Validates credentials → Creates access token → Creates refresh token → Sets response cookie → Returns login response
When MFA is Enabled (isMfaEnabled: true):
- Validates credentials → Creates MFA code → Creates MFA token → Sends MFA code via email → Returns MFA token
Handlers/Blocks (MFA Enabled):
loginWithCredentials: Validates user credentialscreateMfaCode: Generates secure numeric MFA codecreateMfaToken: Creates and stores MFA challenge tokensendMfaCode: Sends MFA code via email
Handlers (MFA Disabled):
loginWithCredentials: Validates user credentialscreateAccessToken: Generates JWT access tokencreateRefreshToken: Generates JWT refresh tokensetResponseCookie: Sets HTTP-only refresh token cookie
Validators: None
Request Body (MFA Disabled):
{
"email": "user@example.com",
"password": "securePassword123",
"fingerprint": "device-fingerprint"
}
Response (MFA Disabled):
{
"id": "identity-uuid",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response (MFA Enabled):
{
"token": "encrypted-mfa-challenge-token"
}
Key Features (MFA):
- Configurable MFA code length (default: 6 digits)
- Configurable MFA token expiration (default: 10 minutes)
- Template-based email customization
- Conditional flow based on
isMfaEnabledconfiguration - Automatic MFA code generation and delivery
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.loginWithCredentialsRoute);
// Configure MFA in authentication service:
const authService = createAuthenticationService({
// ... other config
isMfaEnabled: true,
mfaCodeLength: 6,
mfaTokenExpireTime: '10m',
mfaCodeEmailConfig: {
sender: 'noreply@example.com',
emailConfig: {
subject: 'Your MFA Code',
bodyTemplate: 'Your verification code is: ${code}'
}
}
});
MFA Flow:
- User submits credentials
- System validates credentials
- If MFA enabled:
- Generate MFA code
- Create MFA challenge token
- Send code via email
- Return MFA token to client
- Client must submit MFA code with token (separate endpoint)
- If MFA disabled:
- Generate access and refresh tokens
- Return tokens directly
resendMfaCodeRoute
Resends MFA code via POST /auth/mfa/resend for users who need a new verification code.
Purpose: Generates and sends a new MFA code while invalidating the previous one
Route Details:
- Method:
POST - Path:
/auth/mfa/resend - Authentication: Not required (uses MFA token)
Handlers/Blocks:
getMfaChallengeTokenTarget: Gets MFA challenge target constantgetFingerprint: Extracts device fingerprint from headerscheckOneTimeToken: Verifies and decrypts MFA tokenassertValidOneTimeTokenExists: Validates token exists in databaseinvalidateOneTimeToken: Marks old token as usedgetIdentityById: Retrieves user identity from tokencreateMfaCode: Generates new secure numeric MFA codecreateMfaToken: Creates and stores new MFA challenge tokensendMfaCode: Sends new MFA code via email
Validators: None
Request Body:
{
"token": "encrypted-mfa-challenge-token"
}
Response (Success):
{
"token": "new-encrypted-mfa-challenge-token"
}
Error Responses:
- 400 Bad Request: Invalid request body or token format
- 401 Unauthorized: MFA token expired or invalid
- 403 Forbidden: Token already used or wrong target
- 404 Not Found: MFA token not found or identity not found
- 500 Internal Server Error: Unexpected error during code regeneration or email sending
Handler Process:
- Extract MFA challenge target constant
- Get device fingerprint from request headers
- Verify and decrypt MFA token
- Validate token exists in database and hasn't been used
- Invalidate old MFA token (security measure)
- Retrieve user identity from token data
- Generate new secure MFA code
- Create and store new MFA challenge token
- Send new MFA code via email
- Return new MFA token to client
Key Features:
- Invalidates previous MFA token for security
- Generates completely new MFA code (not reusing old one)
- Issues new MFA token with fresh expiration
- Maintains same MFA workflow security
- Prevents abuse through token invalidation
- Configurable code length and token expiration
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.resendMfaCodeRoute);
// Typical resend flow:
// 1. User logs in (POST /auth/login) → receives MFA token
// 2. User requests resend (POST /auth/mfa/resend) → receives new MFA token
// 3. User receives new MFA code via email
// 4. User submits verification (POST /auth/mfa/verify) with new token and code
MFA Resend Flow:
Client Server
| |
| POST /auth/login |
|------------------------>|
| | - Validate credentials
| | - Generate MFA code
| | - Send code via email
| { token: "old-tkn" } | - Store code in token
|<------------------------|
| |
| User didn't receive |
| email or code expired |
| |
| POST /auth/mfa/resend |
| { token: "old-tkn" } |
|------------------------>|
| | - Verify old token
| | - Invalidate old token
| | - Generate NEW code
| | - Send NEW code email
| { token: "new-tkn" } | - Store in NEW token
|<------------------------|
| |
| User receives new code |
| via email: "654321" |
| |
| POST /auth/mfa/verify |
| { token: "new-tkn", |
| code: "654321" } |
|------------------------>|
| | - Verify token validity
| | - Compare codes
| | - Generate auth tokens
| { accessToken, ... } | - Invalidate MFA token
|<------------------------|
Use Cases:
- User didn't receive initial MFA code email
- Email delivery delayed or failed
- User accidentally deleted email
- MFA code expired before user could enter it
- User lost access to email temporarily
Notes:
- Old MFA token is invalidated immediately upon resend
- New MFA code is different from the old one for security
- Token expiration timer resets with new token
- User can only verify with the new token after resend
- Email template and sender configurable via service options
verifyMfaCodeRoute
Verifies MFA code and completes authentication flow.
Purpose: Validates user-submitted MFA code against stored code and issues authentication tokens
Route Details:
- Method:
POST - Path:
/auth/mfa/verify - Authentication: Not required (uses MFA token)
Handlers/Blocks:
getMfaChallengeTokenTarget: Gets MFA challenge target constantgetFingerprint: Extracts device fingerprint from headerscheckOneTimeToken: Verifies and decrypts MFA tokenassertValidOneTimeTokenExists: Validates token exists in databaseinvalidateOneTimeToken: Marks token as usedverifyMfaCode: Compares user code with stored codegetIdentityById: Retrieves user identitycreateAccessToken: Generates JWT access tokencreateRefreshToken: Generates JWT refresh tokensetResponseCookie: Sets HTTP-only refresh token cookie
Validators: None
Request Body:
{
"token": "encrypted-mfa-challenge-token",
"code": "123456"
}
Response (Success):
{
"id": "identity-uuid",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Error Responses:
- 400 Bad Request: Invalid MFA code provided
- 401 Unauthorized: MFA token expired or invalid
- 404 Not Found: MFA token not found
- 500 Internal Server Error: Unexpected error during verification
Handler Process:
- Extract MFA challenge target constant
- Get device fingerprint from request headers
- Verify and decrypt MFA token
- Validate token exists in database and hasn't been used
- Invalidate token (one-time use)
- Compare user-provided code with stored code
- Retrieve user identity
- Generate access and refresh tokens
- Set refresh token cookie
- Return authentication tokens
Key Features:
- One-time token usage (invalidated after verification)
- Secure code comparison
- Complete MFA workflow
- Returns same token structure as standard login
- Automatic token invalidation prevents reuse
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.verifyMfaCodeRoute);
// Complete MFA flow:
// 1. User logs in (POST /auth/login) → receives MFA token
// 2. User receives MFA code via email
// 3. User submits verification (POST /auth/mfa/verify)
// 4. System validates and returns access/refresh tokens
MFA Verification Flow:
Client Server
| |
| POST /auth/login |
|------------------------>|
| | - Validate credentials
| | - Generate MFA code
| | - Send code via email
| { token: "..." } | - Store code in token
|<------------------------|
| |
| User receives code |
| via email: "123456" |
| |
| POST /auth/mfa/verify |
| { token, code } |
|------------------------>|
| | - Verify token validity
| | - Compare codes
| | - Generate auth tokens
| { accessToken, ... } | - Invalidate MFA token
|<------------------------|
logoutRoute
Logs out user by invalidating their session and clearing tokens.
Purpose: Handles user logout and session cleanup
Route Details:
- Method:
POST - Path:
/auth/logout - Authentication: Required (Bearer token)
Handlers: logout, logoutTerminator
Validators: isAuthenticated
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.logoutRoute);
refreshTokenRoute
Refreshes access token using a valid refresh token.
Purpose: Generates new access token from refresh token
Route Details:
- Method:
POST - Path:
/auth/token/refresh - Authentication: Not required
Handlers: refreshToken
Validators: None
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.refreshTokenRoute);
checkTokenRoute
Validates an access token and returns its status.
Purpose: Validates token authenticity and status
Route Details:
- Method:
POST - Path:
/auth/token/check - Authentication: Not required
Blocks: checkToken - Validates token using pure business logic
Validators: None
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.checkTokenRoute);
deleteRefreshTokensRoute
Deletes refresh tokens for a specific identity via DELETE /auth/:identityId/refresh-tokens.
Purpose: Removes refresh tokens for identity management and security
Route Details:
- Method:
DELETE - Path:
/auth/:identityId/refresh-tokens - Authentication: Required (Bearer token)
Blocks: softDeleteRefreshTokens - Soft-deletes refresh tokens for identity
Validators: isAuthenticated, some(checkIdentityType(['admin']), isSelf(['params', 'requestBody', 'identityId']))
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.deleteRefreshTokensRoute);
loginWithOnetimeTokenRoute
One-time token authentication for passwordless secure login.
Purpose: Validates one-time token and completes passwordless authentication flow
Route Details:
- Method:
POST - Path:
/auth/ott/login - Authentication: Not required (uses one-time token)
Handlers:
loginWithOnetimeToken: Validates token and retrieves identityinvalidateOneTimeToken: Marks token as used (one-time use)createAccessToken: Generates JWT access tokencreateRefreshToken: Generates JWT refresh tokensetResponseCookie: Sets HTTP-only refresh token cookie
Validators: None
Request Body:
{
"token": "encrypted-onetime-authentication-token"
}
Response (Success):
{
"id": "identity-uuid",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Error Responses:
- 403 Forbidden: Token is incorrect for this operation, invalid target, or already used
- 404 Not Found: Identity not found
- 500 Internal Server Error: Unexpected error during authentication
Handler Process:
- Validate one-time token exists in database
- Decrypt and verify JWT token structure
- Verify token type is
'onetime' - Verify token target is
'login' - Retrieve identity from token data
- Invalidate token (one-time use)
- Generate access and refresh tokens
- Set refresh token cookie
- Return authentication tokens
Key Features:
- Passwordless authentication via magic link
- One-time token usage (automatically invalidated)
- Secure token validation with type and target checks
- Returns same token structure as standard login
- Identity lookup from token data
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.loginWithOnetimeTokenRoute);
// Typical magic link flow:
// 1. Generate one-time token with target: 'login' and identityId
// 2. Send magic link email with token
// 3. User clicks link → client submits POST /auth/ott/login with token
// 4. System validates and returns authentication tokens
Magic Link Flow:
User Server
| |
| Request magic link |
| (separate endpoint) |
|------------------------>|
| | - Generate OTT token
| | - Store token in DB
| Magic link email | - Send email
|<------------------------|
| |
| Click link in email |
| |
| POST /auth/ott/login |
| { token } |
|------------------------>|
| | - Validate token
| | - Get identity
| | - Invalidate token
| { accessToken, ... } | - Generate auth tokens
|<------------------------|
generateOnetimeTokenRoute
Generates a new one-time token for authentication purposes.
Purpose: Creates OTT for authentication (admin only)
Route Details:
- Method:
POST - Path:
/auth/ott/generate - Authentication: Required (Bearer token)
Handlers: generateOnetimeToken
Validators: isAuthenticated, checkIdentityType(['admin'])
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.generateOnetimeTokenRoute);
restoreOnetimeTokenRoute
Restores a previously invalidated one-time token.
Purpose: Re-enables invalidated OTT (admin only)
Route Details:
- Method:
POST - Path:
/auth/ott/restore - Authentication: Required (Bearer token)
Handlers: restoreOnetimeToken
Validators: isAuthenticated, checkIdentityType(['admin'])
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.restoreOnetimeTokenRoute);
invalidateOnetimeTokenRoute
Invalidates an existing one-time token.
Purpose: Disables active OTT (admin only)
Route Details:
- Method:
POST - Path:
/auth/ott/invalidate - Authentication: Required (Bearer token)
Handlers: invalidateOnetimeToken
Validators: isAuthenticated, checkIdentityType(['admin'])
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.invalidateOnetimeTokenRoute);
sendVerificationEmailRoute
Sends verification emails to users.
Purpose: Triggers email verification process
Route Details:
- Method:
POST - Path:
/auth/:identityId/send-verification-email - Authentication: Required (Bearer token)
Handlers: sendVerificationEmail, sendVerificationEmailTerminator
Validators: isAuthenticated, some(checkIdentityType(['admin']), isSelf(['params', 'requestParams', 'identityId']))
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.sendVerificationEmailRoute);
confirmEmailRoute
Confirms user email addresses using verification tokens.
Purpose: Processes email verification tokens
Route Details:
- Method:
POST - Path:
/auth/confirm-email - Authentication: Not required
Handlers: buildCheckConfirmEmailTokenPayload, checkToken, confirmEmail, confirmEmailTerminator
Validators: None
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.confirmEmailRoute);
changeEmailRoute
Initiates the email change process for a user by sending a verification email to the new address.
Purpose: Handles email change initiation with token generation and email sending
Route Details:
- Method:
PATCH - Path:
/auth/:identityId/change-email - Authentication: Required (Bearer token)
Blocks:
assertIdentityExists- Verifies identity existscheckEmailIsUniqueInIdentities- Validates email uniquenessgetFingerprint- Extracts request fingerprintbuildTokenVerification- Builds security contextgenerateOneTimeToken- Generates secure tokenstoreOneTimeToken- Stores token in databasesendEmail- Sends verification emailnormalizeEmptyBody- Normalizes response
Validators: isAuthenticated, some(checkIdentityType(['admin']), isSelf(['params', 'requestParams', 'identityId']))
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.changeEmailRoute);
confirmNewEmailRoute
Confirms a user's new email address using a one-time verification token.
Purpose: Processes email change confirmation with token validation
Route Details:
- Method:
POST - Path:
/auth/confirm-new-email - Authentication: Not required
Blocks:
getFingerprint- Extracts request fingerprintbuildTokenVerification- Builds security contextcheckOneTimeToken- Validates tokenassertValidOneTimeTokenExists- Verifies token existsinvalidateOneTimeToken- Marks token as usedcheckEmailIsUniqueInIdentities- Validates email uniquenessisEmail- Validates email formatbuildUpdateIdentityEmailAndEmailVerifiedPayload- Builds update payloadupdateIdentity- Updates user identitynormalizeEmptyBody- Normalizes response
Validators: None
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.confirmNewEmailRoute);
sendResetPasswordLinkEmailRoute
Sends a password reset link email to a user based on their email address.
Purpose: Handles password reset email generation and sending
Route Details:
- Method:
POST - Path:
/auth/send-reset-password-link-email - Authentication: Not required
Blocks:
getIdentityIdByEmail- Retrieves identity by emailgetFingerprint- Extracts request fingerprintbuildTokenVerification- Builds security contextgenerateOneTimeToken- Generates secure tokenstoreOneTimeToken- Stores token in databasesendEmail- Sends password reset emailnormalizeEmptyBody- Normalizes response
Validators: None
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Register route with Express app
app.use('/api', routes.sendResetPasswordLinkEmailRoute);
changePasswordRoute
Changes user password via PATCH /auth/:identityId/change-password.
Purpose: Handles password change with current password verification and new password hashing
Route Details:
- Method:
PATCH - Path:
/auth/:identityId/change-password - Authentication: Required (Bearer token)
Blocks:
getIdentityById- Retrieves the identity by IDcompareStringAgainstHash- Verifies the current passwordhash- Hashes the new passwordbuildUpdateIdentityPasswordPayload- Builds the update payloadupdateIdentity- Updates the identity password in the databasesendEmail- Sends a notification emailnormalizeEmptyBody- Normalizes the response bodyorThrow- Throws mapped errors or returns the normalized identity
Validators: isAuthenticated, some(checkIdentityType(['admin']), isSelf(['params', 'requestParams', 'identityId']))
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Use in feature composition:
export const changePasswordFeature = compose(changePasswordSchema, changePasswordRoute);
// Register route with Express app
app.use('/api', routes.changePasswordRoute);
activateRoute
Activates a user account via POST /auth/activate.
Purpose: Handles account activation with email verification and identity status update
Route Details:
- Method:
POST - Path:
/auth/activate - Authentication: Required (Bearer token)
Blocks:
getIdentityById- Retrieves identity by IDisEmailVerified- Checks if email is verifiedbuildUpdateIdentityActivatedPayload- Builds activation payloadupdateIdentity- Updates identity as activatednormalizeEmptyBody- Normalizes response bodyorThrow- Throws mapped errors or returns 204 No Content
Validators: isAuthenticated, checkIdentityType(['admin'])
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Use in feature composition:
export const activateFeature = compose(activateSchema, activateRoute);
// Register route with Express app
app.use('/api', routes.activateRoute);
deactivateRoute
Deactivates a user identity via POST /auth/deactivate.
Purpose: Handles account deactivation with email verification, identity status update, and token invalidation
Route Details:
- Method:
POST - Path:
/auth/deactivate - Authentication: Required (Bearer token)
Blocks:
getIdentityById- Retrieves identity by IDisEmailVerified- Checks if email is verifiedbuildUpdateIdentityDeactivatedPayload- Builds deactivation payloadupdateIdentity- Updates identity as deactivatedsoftDeleteRefreshTokens- Soft-deletes refresh tokens for identityextractTokenFromAuthorizationHeader- Extracts Bearer token from requestcheckToken- Validates access token and user permissionssendEmail- Sends deactivation notification emailnormalizeEmptyBody- Normalizes response bodyorThrow- Throws mapped errors or returns 204 No Content
Validators: isAuthenticated, some(checkIdentityType(['admin']), isSelf(['params', 'requestParams', 'identityId']))
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Use in feature composition:
export const deactivateFeature = compose(deactivateSchema, routes.deactivateRoute);
// Register route with Express app
app.use('/api', routes.deactivateRoute);
completePasswordResetRoute
Completes the password reset process by validating the token and updating the user's password.
Purpose: Handles password reset completion with token validation and password update
Route Details:
- Method:
POST - Path:
/auth/reset-password - Authentication: Not required
Blocks:
getResetPasswordTokenTarget- Gets reset password token targetgetFingerprint- Extracts request fingerprintbuildTokenVerification- Builds security contextextractTokenFromAuthorizationHeader- Extracts Bearer token from requestcheckOneTimeToken- Validates one-time tokenassertValidOneTimeTokenExists- Verifies token exists in databaseinvalidateOneTimeToken- Marks token as usedhash- Hashes the new passwordbuildUpdateIdentityPasswordPayload- Builds password update payloadupdateIdentity- Updates user identity with new passwordgetIdentityById- Retrieves updated identitysendEmail- Sends password reset success emailnormalizeEmptyBody- Normalizes response bodyorThrow- Throws mapped errors or returns 204 No Content
Validators: None
Usage:
import { routes } from '@nodeblocks/backend-sdk';
// Route registration:
app.use('/api', routes.completePasswordResetRoute);
// POST /auth/reset-password
// Headers:
// Authorization: Bearer <one-time-token>
// Request body:
// {
// "password": "newStrongPassword123"
// }
// Response: 204 No Content (success)