Skip to main content
Version: 🚧 Canary

🔐 Authentication Service

Testing Status

The Authentication Service provides a complete authentication system for identity registration, login, logout, and token management with JWT-based security and cookie support.


🚀 Quickstart

When using cookie authentication, install cookie-parser (and its TypeScript declarations):

npm install cookie-parser
npm install -D @types/cookie-parser
import express from 'express';
import cookieParser from 'cookie-parser';
import {services, middlewares, types, drivers} from '@nodeblocks/backend-sdk';

const {withMongo, createGoogleOAuthDriver, createTwitterOAuthDriver, createLineOAuthDriver} = drivers;
const connectToDatabase = withMongo('mongodb://localhost:27017/?authSource=admin', 'dev', 'user', 'password');

express()
// Required before any routes that use cookie authentication
.use(cookieParser())
.use(
services.authService(
{
...(await connectToDatabase('identities')),
...(await connectToDatabase('refreshtokens')),
...(await connectToDatabase('onetimetokens')),
...(await connectToDatabase('invitations')),
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
maxFailedLoginAttempts: 5,
authMode: 'cookie',
accessTokenSignOptions: {expiresIn: '15m'},
refreshTokenSignOptions: {expiresIn: '2d'},
onetimeTokenSignOptions: {expiresIn: '5m'},
isMfaEnabled: false, // Enable multi-factor authentication
mfaCodeLength: 6, // Length of MFA codes (default: 6)
mfaCodeEmailConfig: {
// Required if isMfaEnabled is true
sender: 'noreply@example.com',
emailConfig: {
subject: 'Your MFA Code',
bodyTemplate: 'Your verification code is: ${code}',
},
},
verifyEmailConfig: {
enabled: true,
emailConfig: {
bodyTemplate: 'Hello ${email}',
subject: 'Welcome to our app',
urlTemplate: 'https://example.com/verify-email?token=${token}',
},
sender: 'noreply@example.com',
},
invitation: {
enabled: true,
emailConfig: {
bodyTemplate: '<h1>You\'re invited!</h1><p>Click <a href="${url}">here</a> to accept the invitation.</p>',
subject: "You're invited to join our organization",
urlTemplate: 'https://yourapp.com/invitations/accept?token=${token}&email=${email}',
sender: 'invites@yourapp.com',
},
target: 'invitation',
},
},
{
mailService: {
sendMail: async (mailData: types.MailData) => {
console.log(mailData);
return true;
},
},
googleOAuthDriver: createGoogleOAuthDriver(
process.env.GOOGLE_CLIENT_ID!,
process.env.GOOGLE_CLIENT_SECRET!,
'https://example.com/auth/oauth/google/callback',
),
twitterOAuthDriver: createTwitterOAuthDriver(
process.env.TWITTER_CONSUMER_KEY!,
process.env.TWITTER_CONSUMER_SECRET!,
'https://example.com/auth/oauth/twitter/callback',
process.env.SESSION_SECRET!,
),
lineOAuthDriver: createLineOAuthDriver(
process.env.LINE_CHANNEL_ID!,
process.env.LINE_CHANNEL_SECRET!,
'https://example.com/auth/oauth/line/callback',
),
},
),
)
.use(middlewares.nodeBlocksErrorMiddleware())
.listen(8089, () => console.log('Server running'));

🗄️ Datastore

CollectionRequiredDescription
identitiesIdentity accounts used by auth flows
refreshtokensRefresh tokens used by auth flows
invitationsOptional — invitation create/list/get/delete
onetimetokensOptional — MFA / one-time token flows

📋 Endpoint Summary

MethodPathDescription
Authentication Endpoints
POST/auth/registerRegister a new identity account
POST/auth/loginAuthenticate identity and receive tokens (returns MFA token if MFA enabled)
POST/auth/mfa/verifyVerify MFA code and complete authentication
POST/auth/mfa/resendResend MFA code for verification
POST/auth/ott/loginAuthenticate using one-time token (magic link)
POST/auth/logoutLogout and invalidate tokens
Email Verification Endpoints
POST/auth/:identityId/send-verification-emailSend email verification to identity
POST/auth/confirm-emailConfirm email with verification token
Email Management Endpoints
PATCH/auth/:identityId/change-emailInitiate email change process
POST/auth/confirm-new-emailConfirm new email address
Password Management Endpoints
POST/auth/send-reset-password-link-emailSend password reset email
POST/auth/reset-passwordComplete password reset process
PATCH/auth/:identityId/change-passwordChange user password
Account Management Endpoints
POST/auth/activateActivate user account
POST/auth/deactivateDeactivate user account
Token Management Endpoints
POST/auth/token/refreshRefresh access token using refresh token
POST/auth/token/checkValidate access token
DELETE/auth/:identityId/refresh-tokensDelete refresh tokens for identity
Invitation Endpoints
POST/invitationsCreate a new invitation
GET/invitationsList invitations with optional filtering
GET/invitations/:invitationIdGet invitation by ID
DELETE/invitations/:invitationIdDelete invitation
OAuth Endpoints
GET/auth/oauth/googleInitiate Google OAuth flow
GET/auth/oauth/google/callbackProcess Google OAuth callback
GET/auth/oauth/twitterInitiate Twitter OAuth flow
GET/auth/oauth/twitter/callbackProcess Twitter OAuth callback
GET/auth/oauth/lineInitiate LINE OAuth flow
GET/auth/oauth/line/callbackProcess LINE OAuth callback

🗄️ Entity Schema

The authentication service manages user identities with the following schema:

Identity Entity

{
"id": "string",
"email": "string",
"password": "string",
"attempts": "number",
"locked": "boolean",
"emailVerified": "boolean",
"deactivatedAt": "string | null",
"createdAt": "string",
"updatedAt": "string",
"typeId": "string",
"provider": "string",
"providerId": "string"
}

Field Details

FieldTypeAuto-GeneratedRequiredDescription
idstringUnique identifier (UUID)
emailstring⚠️Identity's email address (optional for some OAuth)
passwordstringHashed password
attemptsnumberFailed login attempts counter
lockedbooleanAccount lock status
emailVerifiedbooleanWhether the identity email has been verified
deactivatedAtstring or nullAccount deactivation timestamp, or null when active
createdAtstringCreation timestamp
updatedAtstringLast update timestamp
typeIdstringIdentity role identifier (e.g., "100" for admin)
providerstring⚠️OAuth provider identifier (e.g., "google", "twitter", "line")
providerIdstring⚠️Provider-specific user ID for OAuth identities

Additional Field Details:

  • attempts: Tracks the number of consecutive failed login attempts for security purposes. After a certain threshold (configurable), the account will be automatically locked.

  • locked: Indicates whether the account is currently locked due to too many failed login attempts or administrative action. A locked account cannot be used for authentication until unlocked.

  • typeId: A string identifier that determines the identity's role and permissions in the system. Adjustable for each service. Common values might include:

    • "100": Administrator with full system access
    • "001": Standard user with basic permissions
    • "000": Guest user with lowest permissions
    • Additional custom roles can be defined as needed
  • email: For OAuth-based identities, email may not be provided by all providers (e.g., Twitter doesn't always provide email). For standard registration, email is required.

  • provider: Identifies the OAuth provider used to create this identity. Required for OAuth-based identities. Possible values: 'google', 'twitter', 'line'.

  • providerId: The unique identifier assigned by the OAuth provider to this user. Required for OAuth-based identities. Used in combination with provider to reliably identify and resolve OAuth identities across multiple logins.

Invitation Entity

The authentication service also manages invitations with the following schema:

{
"id": "string",
"email": "string",
"fromIdentityId": "string",
"orgId": "string",
"role": "string",
"status": "string",
"createdAt": "string",
"updatedAt": "string"
}

Invitation Field Details

FieldTypeAuto-GeneratedRequiredDescription
idstringUnique identifier (UUID)
emailstringEmail address of the invitee
fromIdentityIdstringID of the identity sending the invitation
orgIdstringID of the organization to invite to
rolestringRole for the invitee in the organization
statusstringInvitation status (e.g., "pending", "accepted")
createdAtstringCreation timestamp
updatedAtstringLast update timestamp

🔐 Authentication Headers

For protected endpoints, include the following headers:

Authorization: Bearer <access_token>
x-nb-fingerprint: <device_fingerprint>

⚠️ Important: The x-nb-fingerprint header is required for all authenticated requests if fingerprint was specified during authorization. Without it, requests will return 401 Unauthorized.


🔧 API Endpoints

1. Register Identity

Register a new identity account with email and password.

Request:

  • Method: POST
  • Path: /auth/register
  • Headers:
    • Content-Type: application/json
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
emailstring✅*Identity's email address
passwordstringIdentity's password
tokenstring✅*Invitation token

*Either email OR token is required, but not both.

Response Body:

FieldTypeDescription
No response body-Registration endpoint returns no response body on success

Validation:

  • Schema Validation: Enforced automatically (email and password or token and password required)
  • Route Validators: None

Example Request:

curl -X POST {{host}}/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword123"
}'

Example Request with Token (for existing users):

curl -X POST {{host}}/auth/register \
-H "Content-Type: application/json" \
-d '{
"token": "invitation-token",
"password": "securepassword123"
}'

Success Response:

HTTP/1.1 201 Created
Content-Type: application/json

Error Responses:

When email already exists:

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
"error": {
"message": "unable to register \"user@example.com\""
}
}

When request body is missing required fields:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'email'",
"request body must have required property 'token'",
"request body must match exactly one schema in oneOf"
]
}
}

2. Login Identity

Authenticate credentials and receive access and refresh tokens.

Request:

  • Method: POST
  • Path: /auth/login
  • Headers:
    • Content-Type: application/json
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
emailstringIdentity's email address
passwordstringIdentity's password
fingerprintstringDevice fingerprint for security

Response Body (bearer mode):

FieldTypeDescription
accessTokenstringJWT access token for API authentication
idstringIdentity's unique identifier
refreshTokenstringJWT refresh token for obtaining new access tokens

Response Body (cookie mode):

FieldTypeDescription
idstringIdentity's unique identifier

Validation:

  • Schema Validation: Enforced automatically (email, password required)
  • Route Validators: None

Example Request:

curl -X POST {{host}}/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword123",
"fingerprint": "device-fingerprint"
}'

Success Response (bearer mode — default):

HTTP/1.1 200 OK
Content-Type: application/json

{
"accessToken": "c911c0dd107f8d7e92c0608aa149d041:dee2...",
"id": "0b3839a6-92b4-4044-a13b-ed834a105646",
"refreshToken": "9f0cad0da1ceec15c01de729a2359236:2acc8ee1b57fd971473..."
}

Success Response (cookie mode — authMode: 'cookie'):

HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Credentials: true
Set-Cookie: accessToken=...; Path=/; HttpOnly; Secure; SameSite=Strict
Set-Cookie: refreshToken=...; Path=/; HttpOnly; Secure; SameSite=Strict

{
"id": "0b3839a6-92b4-4044-a13b-ed834a105646"
}

When authMode is 'cookie', tokens are set as cookies and the JSON body returns { id } only. Host apps must register cookie-parser.

Error Responses:

When credentials are invalid:

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
"error": {
"message": "wrong credentials provided"
}
}

3. Verify MFA Code

Verifies MFA code and completes authentication when MFA is enabled.

Request:

  • Method: POST
  • Path: /auth/mfa/verify
  • Headers:
    • Content-Type: application/json
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
tokenstringMFA challenge token received from login
codestringMFA verification code sent via email

Response Body:

FieldTypeDescription
accessTokenstringJWT access token for API authentication
idstringIdentity's unique identifier
refreshTokenstringJWT refresh token for obtaining new access tokens

Validation:

  • Schema Validation: Enforced automatically (token, code required)
  • Route Validators: None

Example Request:

curl -X POST {{host}}/auth/mfa/verify \
-H "Content-Type: application/json" \
-d '{
"token": "mfa-challenge-token",
"code": "123456"
}'

Success Response (bearer mode):

HTTP/1.1 200 OK
Content-Type: application/json

{
"accessToken": "c911c0dd107f8d7e92c0608aa149d041:dee2...",
"id": "0b3839a6-92b4-4044-a13b-ed834a105646",
"refreshToken": "9f0cad0da1ceec15c01de729a2359236:2acc8ee1b57fd971473..."
}

Success Response (cookie mode):

HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Credentials: true
Set-Cookie: accessToken=...; Path=/; HttpOnly; Secure; SameSite=Strict
Set-Cookie: refreshToken=...; Path=/; HttpOnly; Secure; SameSite=Strict

{
"id": "0b3839a6-92b4-4044-a13b-ed834a105646"
}

Error Responses:

When MFA code is invalid:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Invalid MFA code"
}
}

When token is invalid or expired:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Invalid or expired MFA token"
}
}

4. Resend MFA Code

Resends MFA verification code to the user's email address.

Request:

  • Method: POST
  • Path: /auth/mfa/resend
  • Headers:
    • Content-Type: application/json
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
tokenstringMFA challenge token received from login

Response Body:

FieldTypeDescription
tokenstringNew MFA challenge token (previous token is invalidated)

Validation:

  • Schema Validation: Enforced automatically (token required)
  • Route Validators: None

Example Request:

curl -X POST {{host}}/auth/mfa/resend \
-H "Content-Type: application/json" \
-d '{
"token": "mfa-challenge-token"
}'

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"token": "new-mfa-challenge-token"
}

Error Responses:

When token is invalid or expired:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Invalid or expired MFA token"
}
}

When identity is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Identity not found"
}
}

5. Logout Identity

Logout identity and invalidate refresh tokens.

Request:

  • Method: POST
  • Path: /auth/logout
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Request Body (bearer mode):

FieldTypeRequiredDescription
refreshTokenstringRefresh token to revoke

Request Body (cookie mode):

FieldTypeRequiredDescription
No request body-Refresh token is read from the refreshToken cookie

Response Body:

FieldTypeDescription
No response body-Logout endpoint returns no response body on success

Validation:

  • Schema Validation: Bearer mode requires refreshToken in the JSON body; cookie mode uses an empty body schema
  • Route Validators: Require authenticated request (isAuthenticated)

Example Request (bearer mode):

curl -X POST {{host}}/auth/logout \
-H "Authorization: Bearer <access-token>" \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "<refresh-token>"
}'

Example Request (cookie mode):

curl -X POST {{host}}/auth/logout \
-H "Cookie: accessToken=<access-token>; refreshToken=<refresh-token>"

Success Response:

HTTP/1.1 204 No Content

Error Responses:

When refresh token invalidation operation fails:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "failed to delete refresh token"
}
}

6. Login with One-Time Token

Authenticates user using a one-time token (magic link).

Request:

  • Method: POST
  • Path: /auth/ott/login
  • Headers:
    • Content-Type: application/json
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
tokenstringOne-time token for authentication

Response Body (bearer mode):

FieldTypeDescription
accessTokenstringJWT access token for API authentication
idstringIdentity's unique identifier
refreshTokenstringJWT refresh token for obtaining new access tokens

Response Body (cookie mode):

FieldTypeDescription
idstringIdentity's unique identifier

Validation:

  • Schema Validation: Enforced automatically (token required)
  • Route Validators: None

Example Request:

curl -X POST {{host}}/auth/ott/login \
-H "Content-Type: application/json" \
-d '{
"token": "one-time-token"
}'

Success Response (bearer mode):

HTTP/1.1 200 OK
Content-Type: application/json

{
"accessToken": "c911c0dd107f8d7e92c0608aa149d041:dee2...",
"id": "0b3839a6-92b4-4044-a13b-ed834a105646",
"refreshToken": "9f0cad0da1ceec15c01de729a2359236:2acc8ee1b57fd971473..."
}

Success Response (cookie mode):

HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Credentials: true
Set-Cookie: accessToken=...; Path=/; HttpOnly; Secure; SameSite=Strict
Set-Cookie: refreshToken=...; Path=/; HttpOnly; Secure; SameSite=Strict

{
"id": "0b3839a6-92b4-4044-a13b-ed834a105646"
}

Error Responses:

When token is rejected by the one-time-token flow:

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
"error": {
"message": "Token is incorrect for this operation"
}
}

7. Refresh Access Token

Refresh an access token using a valid refresh token.

Request:

  • Method: POST
  • Path: /auth/token/refresh
  • Headers:
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Not required

Request Body (bearer mode):

FieldTypeRequiredDescription
refreshTokenstringValid refresh token to use for renewal

Request Body (cookie mode):

FieldTypeRequiredDescription
No request body-Refresh token is read from the refreshToken cookie

Response Body (bearer mode):

FieldTypeDescription
accessTokenstringNew access token
refreshTokenstringNew refresh token

Response Body (cookie mode):

FieldTypeDescription
No response body-Tokens are set via Set-Cookie; response body is empty

Validation:

  • Schema Validation: Bearer mode requires refreshToken in the JSON body; cookie mode uses an empty body schema
  • Route Validators: None

Example Request (bearer mode):

curl -X POST {{host}}/auth/token/refresh \
-H "x-nb-fingerprint: <device-fingerprint>" \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "<refresh-token>"
}'

Example Request (cookie mode):

curl -X POST {{host}}/auth/token/refresh \
-H "x-nb-fingerprint: <device-fingerprint>" \
-H "Cookie: refreshToken=<refresh-token>"

Success Response (bearer mode):

HTTP/1.1 200 OK
Content-Type: application/json

{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Success Response (cookie mode):

HTTP/1.1 204 No Content
Set-Cookie: accessToken=...; Path=/; HttpOnly; Secure; SameSite=Strict
Set-Cookie: refreshToken=...; Path=/; HttpOnly; Secure; SameSite=Strict

Error Responses:

When refresh token is invalid:

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
"error": {
"message": "Invalid refresh token"
}
}

8. Delete Refresh Tokens

Delete refresh tokens for a specific identity (admin only or self).

Request:

  • Method: DELETE
  • Path: /auth/:identityId/refresh-tokens
  • Headers:
    • Authorization: Bearer <access-token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required
  • Path Parameters:
    • identityId: The ID of the identity whose refresh tokens to delete

Request Body:

FieldTypeRequiredDescription
No request body-No body required

Response Body:

FieldTypeDescription
No response body-Success returns 204 No Content

Validation:

  • Schema Validation: Enforced automatically (identityId path parameter required)
  • Route Validators: Require authenticated request, admin privileges or self-access

Example Request (admin):

curl -X DELETE {{host}}/auth/user123/refresh-tokens \
-H "Authorization: Bearer <admin-access-token>" \
-H "x-nb-fingerprint: <device-fingerprint>"

Example Request (self):

curl -X DELETE {{host}}/auth/current-user-id/refresh-tokens \
-H "Authorization: Bearer <access-token>" \
-H "x-nb-fingerprint: <device-fingerprint>"

Success Response:

HTTP/1.1 204 No Content

Error Responses:

When identity not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Identity not found"
}
}

9. Send Verification Email

Send an email verification link to a identity's email address.

Request:

  • Method: POST
  • Path: /auth/:identityId/send-verification-email
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required (admin or self access)

Path Parameters:

FieldTypeRequiredDescription
identityIdstringIdentity's unique identifier

Request Body:

FieldTypeRequiredDescription
fingerprintstringDevice fingerprint for security

Response Body:

FieldTypeDescription
No response body-Send verification email endpoint returns no response body on success

Validation:

  • Schema Validation: Enforced automatically
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or self

Example Request:

curl -X POST {{host}}/auth/identity-12345/send-verification-email \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"fingerprint": "device-fingerprint"
}'

Success Response:

HTTP/1.1 204 No Content
Content-Type: application/json

Error Responses:

When email verification is not enabled:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "verification email feature not enabled"
}
}

When mail service is missing:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "verification email feature requires a mail service to be provided"
}
}

When email configuration is missing:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "verifyEmailConfig requires emailConfig with fields bodyTemplate, subject, urlTemplate"
}
}

When the identity is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Identity not found"
}
}

When the identity has no email address:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Identity has no email address"
}
}

When one-time token generation fails:

HTTP/1.1 501 Not Implemented
Content-Type: application/json

{
"error": {
"message": "failed to generate onetime token"
}
}

When the email send operation returns a failure status:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "send verification email failed"
}
}

When email sending fails:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to send verification email"
}
}

10. Confirm Email

Confirm a identity's email address using a verification token.

Request:

  • Method: POST
  • Path: /auth/confirm-email
  • Headers:
    • Content-Type: application/json
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
tokenstringVerification token from email

Response Body:

FieldTypeDescription
No response body-Confirm email endpoint returns no response body on success

Validation:

  • Schema Validation: Enforced automatically (token required)
  • Route Validators: None

Example Request:

curl -X POST {{host}}/auth/confirm-email \
-H "Content-Type: application/json" \
-d '{
"token": "jwt-verification-token"
}'

Success Response:

HTTP/1.1 204 No Content
Content-Type: application/json

Error Responses:

When token is invalid:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Unable to verify token"
}
}

11. Create Invitation

Create a new invitation for an entity to join a service.

Request:

  • Method: POST
  • Path: /invitations
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required (admin access)

Request Body:

FieldTypeRequiredDescription
emailstringEmail address of the invitee
fromIdentityIdstringID of the identity sending the invitation
orgIdstringID of the organization to invite to
rolestringRole for the invitee in the organization

Response Body:

FieldTypeDescription
invitationIdstringUnique identifier of the created invitation

Validation:

  • Schema Validation: Enforced automatically (email, fromIdentityId required; no additional properties allowed)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role

Example Request:

curl -X POST {{host}}/invitations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"email": "newuser@example.com",
"fromIdentityId": "392157b1-dc7a-4935-a6f9-a2d333b910ea",
"orgId": "org123",
"role": "member"
}'

Success Response:

HTTP/1.1 201 Created
Content-Type: application/json

{
"invitationId": "62564a60-e720-4907-bb85-3afaa2729e0d"
}

Error Responses:

When request body is missing required fields:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'email'"
]
}
}

When request body is missing fromIdentityId:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'fromIdentityId'"
]
}
}

When email format is invalid:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"request body must match format \"email\""
]
}
}

When request contains extra properties:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"request body must NOT have additional properties"
]
}
}

When invitation email configuration is incomplete or disabled:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Invitation email configuration is incomplete or disabled"
}
}

12. List Invitations

Retrieve all invitations with optional filtering and pagination.

Request:

  • Method: GET
  • Path: /invitations
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required (admin access)

Query Parameters:

FieldTypeRequiredDescription
emailstringFilter by invitee email address
fromIdentityIdstringFilter by inviter identity ID
orgIdstringFilter by organization ID
rolestringFilter by role
pagenumberPage number for pagination (1-1000)
limitnumberNumber of items per page (1-50)

Response Body: JSON with paginated invitation list and metadata

Response Structure:

FieldTypeDescription
dataarrayArray of invitation objects
data[].emailstringEmail address of the invitee
data[].fromIdentityIdstringID of the identity sending the invitation
data[].orgIdstringID of the organization to invite to
data[].rolestringRole for the invitee in the organization
data[].statusstringInvitation status (e.g., "pending", "accepted")
data[].createdAtstringCreation timestamp
data[].idstringUnique invitation identifier
data[].updatedAtstringLast update timestamp
metadata.paginationobjectPagination information
metadata.pagination.pagenumberCurrent page number
metadata.pagination.limitnumberItems per page
metadata.pagination.totalnumberTotal number of invitations
metadata.pagination.totalPagesnumberTotal number of pages
metadata.pagination.hasNextbooleanWhether there are more pages
metadata.pagination.hasPrevbooleanWhether there are previous pages

Validation:

  • Schema Validation: Enforced automatically
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role

Example Request:

curl -X GET "{{host}}/invitations" \
-H "Authorization: Bearer <access-token>"

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"data": [
{
"email": "newuser@example.com",
"fromIdentityId": "392157b1-dc7a-4935-a6f9-a2d333b910ea",
"orgId": "org123",
"role": "member",
"status": "pending",
"createdAt": "2025-07-04T06:29:32.905Z",
"id": "62564a60-e720-4907-bb85-3afaa2729e0d",
"updatedAt": "2025-07-04T06:29:32.905Z"
}
],
"metadata": {
"pagination": {
"page": 1,
"limit": 10,
"total": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}
}

Empty Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"data": [],
"metadata": {
"pagination": {
"page": 1,
"limit": 10,
"total": 0,
"totalPages": 0,
"hasNext": false,
"hasPrev": false
}
}
}

13. Get Invitation by ID

Retrieve a specific invitation by its unique identifier.

Request:

  • Method: GET
  • Path: /invitations/:invitationId
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required (admin access)

Path Parameters:

FieldTypeRequiredDescription
invitationIdstringUnique invitation identifier

Validation:

  • Schema Validation: Enforced automatically
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role

Example Request:

curl -X GET {{host}}/invitations/62564a60-e720-4907-bb85-3afaa2729e0d \
-H "Authorization: Bearer <access-token>"

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"email": "newuser@example.com",
"fromIdentityId": "392157b1-dc7a-4935-a6f9-a2d333b910ea",
"orgId": "org123",
"role": "member",
"status": "pending",
"createdAt": "2025-07-04T06:29:32.905Z",
"id": "62564a60-e720-4907-bb85-3afaa2729e0d",
"updatedAt": "2025-07-04T06:29:32.905Z"
}

Error Responses:

When invitation is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Invitation not found"
}
}

14. Delete Invitation

Delete a specific invitation by its unique identifier.

Request:

  • Method: DELETE
  • Path: /invitations/:invitationId
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required (admin access)

Path Parameters:

FieldTypeRequiredDescription
invitationIdstringUnique invitation identifier

Validation:

  • Schema Validation: Enforced automatically
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role

Example Request:

curl -X DELETE {{host}}/invitations/62564a60-e720-4907-bb85-3afaa2729e0d \
-H "Authorization: Bearer <access-token>"

Success Response:

HTTP/1.1 204 No Content

Error Responses:

When invitation is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Invitation not found"
}
}

15. Change Email

Initiates the email change process for a user by sending a verification email to the new address.

Request:

  • Method: PATCH
  • Path: /auth/:identityId/change-email
  • Headers:
    • Content-Type: application/json
  • Authorization: Bearer token required (admin or self access)

Path Parameters:

FieldTypeRequiredDescription
identityIdstringIdentity's unique identifier

Request Body:

FieldTypeRequiredDescription
emailstringNew email address for the identity

Response Body:

FieldTypeDescription
No response body-Change email endpoint returns no response body on success

Validation:

  • Schema Validation: Enforced automatically (email required, must be valid email format)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or self

The outbound verification email uses verifyEmailConfig (sender and emailConfig) together with the third-argument mailService.

Example Request:

curl -X PATCH {{host}}/auth/identity-12345/change-email \
-H "Content-Type: application/json" \
-d '{
"email": "newemail@example.com"
}'

Success Response:

HTTP/1.1 204 No Content
Content-Type: application/json

Error Responses:

When email already exists:

HTTP/1.1 409 Conflict
Content-Type: application/json

{
"error": {
"message": "Email already in use"
}
}

When identity is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Identity not found"
}
}

16. Confirm New Email

Confirms a user's new email address using a one-time verification token.

Request:

  • Method: POST
  • Path: /auth/confirm-new-email
  • Headers:
    • Content-Type: application/json
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
tokenstringVerification token from email

Response Body:

FieldTypeDescription
No response body-Confirm new email endpoint returns no response body on success

Validation:

  • Schema Validation: Enforced automatically (token required)
  • Route Validators: None

Example Request:

curl -X POST {{host}}/auth/confirm-new-email \
-H "Content-Type: application/json" \
-d '{
"token": "jwt-verification-token"
}'

Success Response:

HTTP/1.1 204 No Content
Content-Type: application/json

Error Responses:

When token is invalid:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Invalid token"
}
}

Sends a password reset link email to a user based on their email address.

Request:

  • Method: POST
  • Path: /auth/send-reset-password-link-email
  • Headers:
    • Content-Type: application/json
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
emailstringEmail address for password reset

Response Body:

FieldTypeDescription
No response body-Send reset password link email endpoint returns no response body on success

Validation:

  • Schema Validation: Enforced automatically (email required, must be valid email format)
  • Route Validators: None

Example Request:

curl -X POST {{host}}/auth/send-reset-password-link-email \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com"
}'

Success Response:

HTTP/1.1 204 No Content
Content-Type: application/json

Error Responses:

When email is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Email not found"
}
}

18. Complete Password Reset

Completes the password reset process by validating the token and updating the user's password.

Request:

  • Method: POST
  • Path: /auth/reset-password
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <one-time-token>
  • Authorization: Bearer token required (one-time token)

Request Body:

FieldTypeRequiredDescription
passwordstringNew password (8-24 characters, must contain lowercase letter and number)

Response Body:

FieldTypeDescription
No response body-Complete password reset endpoint returns no response body on success

Validation:

  • Schema Validation: Enforced automatically (password required, must meet security requirements)
  • Route Validators: None

Example Request:

curl -X POST {{host}}/auth/reset-password \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <one-time-token>" \
-d '{
"password": "newSecurePassword123"
}'

Success Response:

HTTP/1.1 204 No Content
Content-Type: application/json

Error Responses:

When token is invalid:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Invalid token"
}
}

When password doesn't meet requirements:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"password must match pattern \"^(?=.*[a-z])(?=.*[0-9])[A-Za-z0-9.?/_-]{8,24}$\""
]
}
}

19. Change Password

Changes user password via PATCH /auth/:identityId/change-password.

Request:

  • Method: PATCH
  • Path: /auth/:identityId/change-password
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Path Parameters:

FieldTypeRequiredDescription
identityIdstringIdentity's unique identifier

Request Body:

FieldTypeRequiredDescription
passwordstringCurrent password for verification
newPasswordstringNew password (8-24 characters, must contain lowercase letter and number)

Response Body:

FieldTypeDescription
No response body-Change password endpoint returns no response body on success

Validation:

  • Schema Validation: Enforced automatically (password, newPassword required, newPassword must meet security requirements)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or self

Example Request:

curl -X PATCH {{host}}/auth/identity-12345/change-password \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"password": "oldPassword123",
"newPassword": "newSecurePassword123"
}'

Success Response:

HTTP/1.1 204 No Content
Content-Type: application/json

Error Responses:

When current password is incorrect:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Invalid input"
}
}

When new password doesn't meet requirements:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"newPassword must match pattern \"^(?=.*[a-z])(?=.*[0-9])[A-Za-z0-9.?/_-]{8,24}$\""
]
}
}

20. Activate Account

Activates a user account via POST /auth/activate.

Request:

  • Method: POST
  • Path: /auth/activate
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
  • Authorization: Bearer token required (admin access)

Request Body:

FieldTypeRequiredDescription
identityIdstringIdentity's unique identifier for activation

Response Body:

FieldTypeDescription
No response body-Activate account endpoint returns no response body on success

Validation:

  • Schema Validation: Enforced automatically (identityId required)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role

Example Request:

curl -X POST {{host}}/auth/activate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"identityId": "identity-12345"
}'

Success Response:

HTTP/1.1 204 No Content
Content-Type: application/json

Error Responses:

When identity is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Identity not found"
}
}

When email is not verified:

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
"error": {
"message": "Email must be verified before activation"
}
}

21. Deactivate Account

Deactivates a user identity via POST /auth/deactivate.

Request:

  • Method: POST
  • Path: /auth/deactivate
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
  • Authorization: Bearer token required (admin or self access)

Request Body:

FieldTypeRequiredDescription
identityIdstringIdentity's unique identifier for deactivation

Response Body:

FieldTypeDescription
No response body-Deactivate account endpoint returns no response body on success

Validation:

  • Schema Validation: Enforced automatically (identityId required)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or self

Example Request:

curl -X POST {{host}}/auth/deactivate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"identityId": "identity-12345"
}'

Success Response:

HTTP/1.1 204 No Content
Content-Type: application/json

Error Responses:

When identity is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Identity not found"
}
}

When email is not verified:

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
"error": {
"message": "Email must be verified before deactivation"
}
}

When token is missing:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Missing token header"
}
}

When email sending fails:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Failed to send email"
}
}

22. Check Token

Validates an access token and returns its status.

Request:

  • Method: POST
  • Path: /auth/token/check
  • Headers:
    • Content-Type: application/json
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
tokenstringToken to validate
targetstringOptional target context for validation

Response Body:

FieldTypeDescription
identityIdstringIdentity ID if token is valid

Validation:

  • Schema Validation: Enforced automatically (token required)
  • Route Validators: None

Example Request:

curl -X POST {{host}}/auth/token/check \
-H "Content-Type: application/json" \
-d '{
"token": "jwt-token-to-validate",
"target": "optional-target-context"
}'

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"identityId": "811ff0a3-a26f-447b-b68a-dd83ea4000b9"
}

Error Responses:

When token is invalid:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Unable to verify token"
}
}

23. Initiate Google OAuth

Initiates the Google OAuth authentication flow by redirecting users to Google's authorization page. This flow can be used for both user login and signup, automatically creating new accounts for first-time users or authenticating existing users.

Request:

  • Method: GET
  • Path: /auth/oauth/google
  • Headers: None required
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
No request body-No body required. Uses query parameters for configuration.

Query Parameters:

FieldTypeRequiredDescription
fpstringDevice fingerprint for security
purposestringOAuth purpose: oauth-login or oauth-signup
redirectUrlstringURL to redirect after OAuth completion
typeIdstringIdentity type ID (required for signup)

Response:

  • Status: 302 Found
  • Headers: Location header with Google OAuth URL

Response Body:

FieldTypeDescription
No response body-OAuth initiation endpoint returns no response body on success

Example Request:

# OAuth Login
curl -v "{{host}}/auth/oauth/google?fp=device-fingerprint&purpose=oauth-login&redirectUrl=http://localhost/oauth/callback"

# OAuth Signup
curl -v "{{host}}/auth/oauth/google?fp=device-fingerprint&purpose=oauth-signup&redirectUrl=http://localhost/oauth/callback&typeId=001"

Success Response:

HTTP/1.1 302 Found
Location: https://accounts.google.com/o/oauth2/v2/auth?prompt=consent&response_type=code&redirect_uri=...&scope=email%20profile&state=...&client_id=...

Error Responses:

When required parameters are missing:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"query parameter 'fp' is required",
"query parameter 'purpose' is required",
"query parameter 'redirectUrl' is required"
]
}
}

When purpose has invalid value:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"query parameter 'purpose' must be equal to one of the allowed values"
]
}
}

24. Google OAuth Callback

Processes the Google OAuth callback and completes the authentication flow. After successful processing, the user is redirected to the redirectUrl that was specified in the initial OAuth request, with authentication tokens (either an onetime token or access token)

Request:

  • Method: GET
  • Path: /auth/oauth/google/callback
  • Headers: None required
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
No request body-No body required. Uses query parameters for OAuth callback processing.

Query Parameters:

FieldTypeRequiredDescription
codestringOne-time authorization code from Google (consumed by Passport.js for token exchange)
statestringSigned JWT containing OAuth flow context (purpose, redirectUrl, typeId, fingerprint, userAgent)

Response:

  • Status: 302 Found (redirect to final destination)
  • Headers: Location header with final redirect URL

Response Body:

FieldTypeDescription
No response body-OAuth callback endpoint returns no response body on success

Validation:

  • Schema Validation: None
  • Route Validators: None

Example Request:

curl -v "{{host}}/auth/oauth/google/callback?code=AUTH_CODE&state=STATE_TOKEN"

Success Response:

HTTP/1.1 302 Found
Location: http://localhost:3000/oauth/callback?token=JWT_TOKEN

Error Responses:

When OAuth state is invalid or expired:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Invalid onetime token"
}
}

When typeId is missing for signup:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "typeId is required"
}
}

When identity creation fails:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Failed to create identity"
}
}

When identity is not found (login only):

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "No identity found for the given google account."
}
}

When email already exists (signup only):

HTTP/1.1 409 Conflict
Content-Type: application/json

{
"error": {
"message": "Email already in use"
}
}

When database operation fails:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": {
"message": "Error finding or creating identity"
}
}

25. Initiate Twitter OAuth

Initiates the Twitter OAuth authentication flow by redirecting users to Twitter's authorization page. This flow can be used for both user login and signup, automatically creating new accounts for first-time users or authenticating existing users.

Request:

  • Method: GET
  • Path: /auth/oauth/twitter
  • Headers: None required
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
No request body-No body required. Uses query parameters for configuration.

Query Parameters:

FieldTypeRequiredDescription
purposestringOAuth purpose: oauth-login or oauth-signup
redirectUrlstringURL to redirect after OAuth completion
typeIdstringIdentity type ID (required for signup)

Note: Unlike Google and LINE OAuth, Twitter OAuth does not require an fp fingerprint query parameter.

Response:

  • Status: 302 Found
  • Headers: Location header with Twitter OAuth URL

Response Body:

FieldTypeDescription
No response body-OAuth initiation endpoint returns no response body on success

Example Request:

# OAuth Login
curl -v "{{host}}/auth/oauth/twitter?purpose=oauth-login&redirectUrl=http://localhost/oauth/callback"

# OAuth Signup
curl -v "{{host}}/auth/oauth/twitter?purpose=oauth-signup&redirectUrl=http://localhost/oauth/callback&typeId=001"

Success Response:

HTTP/1.1 302 Found
Location: https://api.twitter.com/oauth/authenticate?oauth_token=...

Error Responses:

When required parameters are missing:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"query parameter 'purpose' is required",
"query parameter 'redirectUrl' is required"
]
}
}

26. Twitter OAuth Callback

Processes the Twitter OAuth callback and completes the authentication flow. After successful processing, the user is redirected to the redirectUrl that was specified in the initial OAuth request, with authentication tokens.

Request:

  • Method: GET
  • Path: /auth/oauth/twitter/callback
  • Headers: None required
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
No request body-No body required. Uses query parameters for OAuth callback processing.

Query Parameters:

FieldTypeRequiredDescription
oauth_tokenstringOAuth token from Twitter
oauth_verifierstringOAuth verifier from Twitter

Response:

  • Status: 302 Found (redirect to final destination)
  • Headers: Location header with final redirect URL

Response Body:

FieldTypeDescription
No response body-OAuth callback endpoint returns no response body on success

Validation:

  • Schema Validation: None
  • Route Validators: None

Example Request:

curl -v "{{host}}/auth/oauth/twitter/callback?oauth_token=OAUTH_TOKEN&oauth_verifier=OAUTH_VERIFIER"

Success Response:

HTTP/1.1 302 Found
Location: http://localhost:3000/oauth/callback?token=JWT_TOKEN

Error Responses:

When OAuth token is invalid or expired:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Invalid OAuth token"
}
}

When typeId is missing for signup:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "typeId is required"
}
}

When identity creation fails:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Failed to create identity"
}
}

When identity is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "No identity found for the given twitter account."
}
}

27. Initiate LINE OAuth

Initiates the LINE OAuth authentication flow by redirecting users to LINE's authorization page. This flow can be used for both user login and signup, automatically creating new accounts for first-time users or authenticating existing users.

Request:

  • Method: GET
  • Path: /auth/oauth/line
  • Headers: None required
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
No request body-No body required. Uses query parameters for OAuth initiation.

Query Parameters:

FieldTypeRequiredDescription
fpstringDevice fingerprint for security
purposestringOAuth purpose: oauth-login or oauth-signup
redirectUrlstringURL to redirect after authentication
typeIdstringIdentity type identifier for new users (required for signup)

Response:

  • Status: 302 Found (redirect to LINE authorization page)
  • Headers: Location header with LINE OAuth URL

Response Body:

FieldTypeDescription
No response body-OAuth initiation endpoint redirects to LINE authorization page

Validation:

  • Schema Validation: None
  • Route Validators: None

Example Request:

curl -X GET "{{host}}/auth/oauth/line?fp=device-fingerprint&purpose=oauth-signup&redirectUrl=https://example.com/auth/callback&typeId=regular"

Success Response:

HTTP/1.1 302 Found
Location: https://access.line.me/oauth2/v2.1/authorize?...

Error Responses:

When redirectUrl is missing:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "redirectUrl is required"
}
}

When typeId is missing:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "typeId is required"
}
}

28. LINE OAuth Callback

Processes the LINE OAuth callback and completes the authentication flow. After successful processing, the user is redirected to the redirectUrl that was specified in the initial OAuth request, with authentication tokens.

Request:

  • Method: GET
  • Path: /auth/oauth/line/callback
  • Headers: None required
  • Authorization: None required

Request Body:

FieldTypeRequiredDescription
No request body-No body required. Uses query parameters for OAuth callback processing.

Query Parameters:

FieldTypeRequiredDescription
codestringAuthorization code from LINE
statestringState parameter for CSRF protection

Response:

  • Status: 302 Found (redirect to final destination)
  • Headers: Location header with final redirect URL

Response Body:

FieldTypeDescription
No response body-OAuth callback endpoint returns no response body on success

Validation:

  • Schema Validation: None
  • Route Validators: None

Example Request:

# Automatically called by LINE after authorization:
GET {{host}}/auth/oauth/line/callback?code=AUTHORIZATION_CODE&state=STATE_STRING

Success Response:

HTTP/1.1 302 Found
Location: https://example.com/auth/callback?token=ACCESS_TOKEN

Error Responses:

When LINE authorization fails:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "LINE authorization failed"
}
}

When typeId is missing:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "typeId is required"
}
}

When identity creation fails:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Identity creation failed"
}
}

When identity is not found:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "No identity found for the given LINE account."
}
}

🔒 Security Features

Account Protection

  • Failed Login Attempts: Tracks failed login attempts
  • Account Locking: Automatically locks accounts after 5 failed attempts (configurable)
  • Password Hashing: Passwords are securely hashed
  • Token Security: JWT tokens include device fingerprinting and IP validation

Token Management

  • Access Tokens: Short-lived tokens for API access
  • Refresh Tokens: Long-lived tokens for token renewal
  • Token Verification: Validates domain, fingerprint, IP, and user agent
  • Secure Cookies: HTTP-only, secure cookies for token storage

Authentication Methods

Bearer Token Authentication

// Use in Authorization header
Authorization: Bearer <access-token>
import cookieParser from 'cookie-parser';

express()
// Register cookie-parser before the authentication and protected services
.use(cookieParser())
.use(
services.authService(dataStores, {
authMode: 'cookie',
authSecrets,
}),
);

The SDK reads tokens from req.cookies but does not configure cookie parsing. Install and register cookie-parser in the host Express app before mounting any service that uses cookie authentication.


⚙️ Configuration Options

Service Configuration

interface AuthenticationServiceConfiguration {
authSecrets: {
authEncSecret: string; // JWT encryption secret
authSignSecret: string; // JWT signing secret
};
maxFailedLoginAttempts?: number; // Default: 5
isMfaEnabled?: boolean; // Enable multi-factor authentication (default: false)
mfaCodeLength?: number; // Length of MFA codes (default: 6)
authMode?: 'bearer' | 'cookie'; // Default: bearer behavior when unset
checkIp?: boolean; // Optional IP binding for tokens
cookieOpts?: {
domain?: string;
httpOnly?: boolean;
path?: string;
sameSite?: 'strict' | 'lax' | 'none';
secure?: boolean;
};
jwtOpts?: {
jwtSignOptions?: SignOptions;
stateful?: boolean;
};
accessTokenSignOptions?: {expiresIn: string | number} & SignOptions; // Default: { expiresIn: '15m' }
refreshTokenSignOptions?: {expiresIn: string | number} & SignOptions; // Default: { expiresIn: '2d' }
onetimeTokenSignOptions?: {expiresIn: string | number} & SignOptions; // Default: { expiresIn: '5m' } (also used for MFA)
identity?: {
typeIds?: {
admin: string; // Admin user type identifier
guest: string; // Guest user type identifier
regular: string; // Regular user type identifier
};
};
mfaCodeEmailConfig?: {
// Required if isMfaEnabled is true
sender: string; // Sender email address
emailConfig: {
subject: string; // Email subject line
bodyTemplate: string; // Email body template with ${code} placeholder
};
};
verifyEmailConfig?: {
enabled: boolean; // Enable email verification feature
emailConfig?: {
bodyTemplate: string; // Email body template with ${email} and ${token} placeholders
subject: string; // Email subject line
urlTemplate: string; // URL template with ${token} placeholder
};
sender?: string; // Sender email address
};
sendResetPasswordEmailConfig?: {
emailConfig: {
bodyTemplate: string; // Email body template for password reset
subject: string; // Email subject for password reset
urlTemplate: string; // URL template with ${token} placeholder
};
sender: string; // Sender email address for password reset emails
};
resetPasswordSuccessConfig?: {
emailConfig: {
bodyTemplate: string; // Email body template for successful password reset
subject: string; // Email subject for successful password reset
urlTemplate: string; // URL template for success confirmation
};
sender: string; // Sender email address for success notifications
};
changePasswordConfig?: {
emailConfig: {
bodyTemplate: string; // Email body template for password change notification
subject: string; // Email subject for password change
urlTemplate: string; // URL template for change confirmation
};
sender: string; // Sender email address for password change notifications
};
deactivateIdentityEmailConfig?: {
emailConfig: {
bodyTemplate: string; // Email body template for account deactivation
subject: string; // Email subject for deactivation
urlTemplate: string; // URL template for deactivation confirmation
};
sender: string; // Sender email address for deactivation emails
};
invitation?: {
enabled: boolean; // Enable invitation feature
emailConfig?: {
bodyTemplate: string; // Email body template with ${email} and ${token} placeholders
subject: string; // Email subject line
urlTemplate: string; // URL template with ${token} placeholder
sender: string; // Sender email address
};
target?: string; // Token target for invitation validation
status?: {
pending?: string; // Status identifier for pending invitations
accepted?: string; // Status identifier for accepted invitations
};
};
}

Configuration Details

The authentication service configuration is organized into logical groups for security, cookies, JWT settings, invitations and email verification. getMergedAuthConfig deep-merges the supplied configuration with service defaults, including verifyEmailConfig.enabled: false.

🔐 Security Settings

authSecrets - JWT token security secrets

  • Type: { authEncSecret: string; authSignSecret: string }
  • Description: Secret keys for JWT encryption and signing
  • Default: { authEncSecret: '', authSignSecret: '' }
  • Required: Yes (for production)
  • Child Properties:
    • authEncSecret: Secret key for JWT payload encryption
    • authSignSecret: Secret key for JWT signature verification

maxFailedLoginAttempts - Account lockout threshold

  • Type: number
  • Description: Maximum failed login attempts before account lockout
  • Default: 5
  • Behavior: Locks account after threshold is exceeded, requires manual unlock

🔐 Multi-Factor Authentication (MFA) Settings

isMfaEnabled - Enable MFA for login

  • Type: boolean
  • Description: Enables multi-factor authentication for user login
  • Default: false
  • Behavior: When enabled, users must verify a code sent via email after credentials validation
  • Requirements: Requires mfaCodeEmailConfig to be configured
  • Use Case: Enhanced security for sensitive applications

mfaCodeLength - Length of MFA verification codes

  • Type: number
  • Description: Number of digits in generated MFA codes
  • Default: 6
  • Format: Numeric string with leading zeros (e.g., "012345")
  • Security: Longer codes provide more security but are less user-friendly

onetimeTokenSignOptions (also used for MFA challenge tokens)

  • Type: SignOptions with required expiresIn
  • Description: Time window for MFA challenge tokens and other one-time tokens
  • Default: { expiresIn: '5m' }
  • Security: Short expiration reduces attack window

mfaCodeEmailConfig - MFA code email configuration

  • Type: { sender: string; emailConfig: { subject: string; bodyTemplate: string } }
  • Description: Email configuration for delivering MFA codes
  • Required: Yes, when isMfaEnabled is true
  • Child Properties:
    • sender: Sender email address
      • Type: string
      • Description: Email address shown as sender for MFA code emails
      • Example: 'noreply@example.com'
    • emailConfig: Email template configuration
      • Type: { subject: string; bodyTemplate: string }
      • Child Properties:
        • subject: Email subject line
          • Type: string
          • Example: 'Your MFA Code'
        • bodyTemplate: Email body template
          • Type: string
          • Description: HTML/text template with ${code} placeholder for MFA code
          • Example: 'Your verification code is: ${code}'

MFA Flow:

  1. User submits credentials via /auth/login
  2. System validates credentials
  3. If MFA enabled:
    • Generates secure numeric MFA code
    • Creates time-limited MFA challenge token
    • Sends code via email
    • Returns MFA token to client
    • Client must submit code via /auth/mfa/verify endpoint with token and code
    • System verifies code and returns access/refresh tokens
  4. If MFA disabled:
    • Generates and returns access/refresh tokens immediately

authMode - Authentication transport mode

  • Type: 'bearer' | 'cookie'
  • Default: bearer behavior when unset
  • Description: When 'cookie', login/MFA set tokens as cookies and protected routes read the access token from cookies. Presence of cookieOpts alone does not enable cookie mode.
  • Requirements: Host apps using cookie mode must register cookie-parser

checkIp - Bind tokens to client IP

  • Type: boolean
  • Default: undefined in configuration; token validation is effectively enabled by default (checkIp ?? true)
  • Description: Controls IP checks during user-token validation. Set to false to disable IP binding checks.

cookieOpts - HTTP cookie attribute overrides (does not activate cookie auth by itself)

  • Type: { domain?: string; httpOnly?: boolean; path?: string; sameSite?: 'strict' | 'lax' | 'none'; secure?: boolean }
  • Description: Overrides Set-Cookie attributes for access/refresh token cookies when cookie mode is used
  • Default: safe defaults (httpOnly, secure, sameSite: 'strict', path: '/'); maxAge is derived from sign-option expiresIn values
  • Child Properties:
    • domain: Cookie domain scope
    • httpOnly: Prefer true so JS cannot read tokens
    • path: Cookie path scope (default '/')
    • sameSite: 'strict' | 'lax' | 'none'
    • secure: Prefer true in production (required with sameSite: 'none')

🔑 JWT Settings

jwtOpts - JWT token generation and validation options

  • Type: { jwtSignOptions?: SignOptions; stateful?: boolean }
  • Description: Legacy configuration field retained in the service type. The current service implementation does not read this field; use the dedicated token sign-option fields below for supported JWT configuration.
  • Default: undefined

⏰ Token Sign Options

accessTokenSignOptions - Access token JWT options

  • Type: SignOptions with required expiresIn
  • Description: Short-lived token for API access
  • Default: { expiresIn: '15m' }
  • Example: { expiresIn: '30m' }

refreshTokenSignOptions - Refresh token JWT options

  • Type: SignOptions with required expiresIn
  • Description: Long-lived token for obtaining new access tokens
  • Default: { expiresIn: '2d' }
  • Example: { expiresIn: '7d' }

onetimeTokenSignOptions - One-time / MFA challenge token JWT options

  • Type: SignOptions with required expiresIn
  • Description: Temporary token for password reset, email verification, MFA challenges
  • Default: { expiresIn: '5m' }
  • Example: { expiresIn: '10m' }

📧 Email Verification Settings

verifyEmailConfig - Email verification configuration

  • Type: { enabled: boolean; emailConfig?: EmailConfig; sender?: string }
  • Description: Controls email verification feature and email templates. Actual email delivery uses the third-argument mailService driver (not a field on this config object).
  • Default: merged configuration with enabled: false
  • Child Properties:
    • enabled: Enable email verification feature
      • Type: boolean
      • Description: Master switch for email verification functionality
      • Default: false
      • Required: Yes (when using email verification)
    • emailConfig: Email template configuration
      • Type: { bodyTemplate: string; subject: string; urlTemplate: string }
      • Description: Templates for verification emails
      • Required: Yes (when enabled)
      • Child Properties:
        • bodyTemplate: HTML email body template
          • Type: string
          • Description: HTML template for email body with ${url}, ${email} and ${token} placeholders. Will use urlTemplate value for url
          • Example: "Hello ${email}, click <a href="${url}">here</a> to verify your email."
        • subject: Email subject line
          • Type: string
          • Description: Subject line for verification emails
          • Example: "Verify your email address"
        • urlTemplate: URL template for verification link
          • Type: string
          • Description: URL template with ${email} and ${token} placeholders
          • Example: "https://yourapp.com/verify?token=${token}"
    • sender: Sender email address
      • Type: string
      • Description: Email address that verification emails will be sent from
      • Required: No (optional)
      • Example: "noreply@yourapp.com"

🔐 Password Reset Email Settings

sendResetPasswordEmailConfig - Password reset email configuration

  • Type: { emailConfig: EmailConfig; sender: string }
  • Description: Controls password reset email templates and sender
  • Default: Predefined template with bodyTemplate: 'Reset your password by clicking ${url}'
  • Child Properties:
    • emailConfig: Email template configuration
      • Type: { bodyTemplate: string; subject: string; urlTemplate: string }
      • Description: Templates for password reset emails
      • Required: Yes
      • Child Properties:
        • bodyTemplate: Email body template
          • Type: string
          • Description: HTML template with ${url} placeholder
          • Example: 'Reset your password by clicking ${url}'
        • subject: Email subject line
          • Type: string
          • Description: Subject for password reset emails
          • Example: 'Reset your password'
        • urlTemplate: URL template
          • Type: string
          • Description: URL template with ${token} placeholder
          • Example: 'https://yourapp.com/reset-password?token=${token}'
    • sender: Sender email address
      • Type: string
      • Description: Email address that password reset emails will be sent from
      • Required: Yes
      • Example: "noreply@yourapp.com"

resetPasswordSuccessConfig - Password reset success email configuration

  • Type: { emailConfig: EmailConfig; sender: string }
  • Description: Controls password reset success notification templates
  • Default: Predefined template with bodyTemplate: 'Your password has been reset'
  • Child Properties:
    • emailConfig: Email template configuration (same structure as above)
    • sender: Sender email address for success notifications

changePasswordConfig - Password change notification configuration

  • Type: { emailConfig: EmailConfig; sender: string }
  • Description: Controls password change notification templates
  • Default: Predefined template with bodyTemplate: 'Your password has been changed'
  • Child Properties:
    • emailConfig: Email template configuration (same structure as above)
    • sender: Sender email address for password change notifications

deactivateIdentityEmailConfig - Account deactivation email configuration

  • Type: { emailConfig: EmailConfig; sender: string }
  • Description: Controls account deactivation notification templates
  • Default: No service default; provide this configuration when account-deactivation emails are required
  • Child Properties:
    • emailConfig: Email template configuration (same structure as above)
    • sender: Sender email address for deactivation notifications

Service Options (3rd argument)

interface AuthServiceOptions {
mailService?: MailService; // Mail service implementation
googleOAuthDriver?: GoogleOAuthDriver; // Google OAuth driver instance
twitterOAuthDriver?: TwitterOAuthDriver; // Twitter OAuth driver instance
lineOAuthDriver?: LineOAuthDriver; // LINE OAuth driver instance
}

Provide these via the third argument to authService(dataStores, config, options).

📨 Invitation Settings

invitation - Invitation management configuration

  • Type: { enabled: boolean; emailConfig?: InvitationEmailConfig; target?: string }
  • Description: Controls invitation feature and email templates
  • Default: undefined (invitation feature disabled)
  • Child Properties:
    • enabled: Enable invitation feature
      • Type: boolean
      • Description: Master switch for invitation functionality
      • Default: false
      • Required: Yes (when using invitation feature)
    • emailConfig: Invitation email template configuration
      • Type: { bodyTemplate: string; subject: string; urlTemplate: string; sender: string }
      • Description: Templates for invitation emails
      • Required: No — provide it when invitation emails should be sent; its nested fields are required when supplied.
      • Child Properties:
        • bodyTemplate: HTML email body template
          • Type: string
          • Description: HTML template for email body with ${url}, ${token} and ${email} placeholders. Will use urlTemplate value for url
          • Example: "<h1>You're invited!</h1><p>Click <a href='${url}'>here</a> to accept the invitation.</p>"
        • subject: Email subject line
          • Type: string
          • Description: Subject line for invitation emails
          • Example: "You're invited to join our organization"
        • urlTemplate: URL template for invitation link
          • Type: string
          • Description: URL template with ${token} and ${email} placeholders
          • Example: "https://yourapp.com/invitations/accept?token=${token}&email=${email}"
        • sender: Sender email address
          • Type: string
          • Description: Email address that invitation emails will be sent from
          • Required: Yes (when enabled)
          • Example: "invites@yourapp.com"
    • target: Token target for invitation validation
      • Type: string
      • Description: Target identifier for invitation token validation
      • Default: "invitation"
      • Required: No
      • Example: "invitation"
    • status: Invitation status configuration
      • Type: { pending?: string; accepted?: string }
      • Description: Custom status identifiers for invitation states
      • Default: undefined (uses default status values)
      • Child Properties:
        • pending: Status identifier for pending invitations
          • Type: string
          • Description: Custom identifier for pending invitation status
          • Example: "pending"
        • accepted: Status identifier for accepted invitations
          • Type: string
          • Description: Custom identifier for accepted invitation status
          • Example: "accepted"

Example Configuration

const authConfig = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET || 'your-enc-secret',
authSignSecret: process.env.AUTH_SIGN_SECRET || 'your-sign-secret',
},
maxFailedLoginAttempts: 3,
authMode: 'bearer', // or 'cookie'
checkIp: false,
cookieOpts: {
secure: true,
httpOnly: true,
sameSite: 'strict',
path: '/',
},
accessTokenSignOptions: {expiresIn: '1h'},
refreshTokenSignOptions: {expiresIn: '7d'},
onetimeTokenSignOptions: {expiresIn: '30m'},
verifyEmailConfig: {
enabled: true,
emailConfig: {
bodyTemplate: 'Hello ${email}, click <a href="${url}">here</a> to verify your email address.',
subject: 'Verify your email address',
urlTemplate: 'https://yourapp.com/verify?token=${token}',
},
sender: 'noreply@yourapp.com',
},
invitation: {
enabled: true,
emailConfig: {
bodyTemplate: '<h1>You\'re invited!</h1><p>Click <a href="${url}">here</a> to accept the invitation.</p>',
subject: "You're invited to join our organization",
urlTemplate: 'https://yourapp.com/invitations/accept?token=${token}&email=${email}',
sender: 'invites@yourapp.com',
},
target: 'invitation',
},
sendResetPasswordEmailConfig: {
emailConfig: {
bodyTemplate: 'Reset your password by clicking ${url}',
subject: 'Reset your password',
urlTemplate: 'https://yourapp.com/reset-password?token=${token}',
},
sender: 'noreply@yourapp.com',
},
resetPasswordSuccessConfig: {
emailConfig: {
bodyTemplate: 'Your password has been reset successfully',
subject: 'Password reset successful',
urlTemplate: 'https://yourapp.com/auth/callback/reset-password-success',
},
sender: 'noreply@yourapp.com',
},
changePasswordConfig: {
emailConfig: {
bodyTemplate: 'Your password has been changed successfully',
subject: 'Password change successful',
urlTemplate: 'https://yourapp.com/auth/callback/change-password-success',
},
sender: 'noreply@yourapp.com',
},
deactivateIdentityEmailConfig: {
emailConfig: {
bodyTemplate: 'Your account has been deactivated',
subject: 'Account deactivated',
urlTemplate: 'https://yourapp.com/account-deactivated',
},
sender: 'noreply@yourapp.com',
},
};

🚨 Error Handling

All authentication errors return JSON format with appropriate HTTP status codes:

Common Error Codes

StatusError MessageDescription
400Validation ErrorInvalid request body format
400verification email feature not enabledEmail verification not configured
400verification email feature requires a mail service to be providedMail service not configured
400verifyEmailConfig requires emailConfig with fields bodyTemplate, subject, urlTemplateMissing email configuration
400Unable to verify tokenInvalid verification token
401wrong credentials providedInvalid email/password
401This account is lockedAccount locked due to failed attempts
401Token is not valid access tokenInvalid or expired token
401Token fails security checkToken security validation failed
401Unable to detect access tokenMissing access token
403token does not contain expected dataToken validation failed
403Identity is not authorized to access this resourceIdentity lacks required permissions (admin access)
404Identity not foundIdentity does not exist
404Invitation not foundInvitation does not exist
409Email already verified or no changes madeEmail already verified
422unable to register "<email>"Email already exists
500unable to generate access tokenToken generation failed
500unable to generate refresh tokenRefresh token generation failed
500Failed to send verification emailEmail sending process failed
500Invitation email configuration is incomplete or disabledInvitation email configuration or mail service is unavailable

Error Response Format

{
"error": {
"message": "Error message description",
"data": ["Additional error details"]
}
}