Skip to main content
Version: 0.4.2 (Previous)

👤 User Service

Testing Status

The User Service provides a complete REST API for managing user entities with CRUD operations and user account locking/unlocking. It's built using the Nodeblocks functional composition approach and integrates seamlessly with MongoDB.


🚀 Quickstart

import express from 'express';
import { MongoClient } from 'mongodb';

import { middlewares, services } from '@nodeblocks/backend-sdk';

const { nodeBlocksErrorMiddleware } = middlewares;
const { userService } = services;

const client = new MongoClient('mongodb://localhost:27017').db('dev');

express()
.use(
userService(
{
users: client.collection('users'),
identity: client.collection('identity'),
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
user: {
typeIds: {
admin: '100',
guest: '000',
user: '001',
},
},
}
)
)
.use(nodeBlocksErrorMiddleware())
.listen(8089, () => console.log('Server running'));

📋 Endpoint Summary

MethodPathDescriptionAuthorization
POST/usersCreate a new userBearer token required
GET/users/:userIdRetrieve a user by IDBearer token required (admin/self)
GET/usersList/filter usersBearer token required (admin only)
PATCH/users/:userIdUpdate a userBearer token required (admin/self)
DELETE/users/:userIdDelete a userBearer token required (admin/self)
POST/users/:userId/lockLock a user accountBearer token required (admin only)
POST/users/:userId/unlockUnlock a user accountBearer token required (admin only)

🗄️ Entity Schema

The user entity combines base fields (auto-generated) with user-specific data:

{
"id": "string",
"createdAt": "string (datetime)",
"updatedAt": "string (datetime)",
"email": "string",
"name": "string",
"status": "string",
"isLocked": "boolean (optional)"
}

Field Details

FieldTypeAuto-GeneratedRequiredDescription
idstringUnique identifier (UUID)
createdAtdatetimeCreation timestamp
updatedAtdatetimeLast modification timestamp
emailstringUser's email address
namestringUser's display name
statusstringUser status (e.g., "active", "pending")
isLockedbooleanAccount lock status (only present after lock/unlock operations)

📝 Note: Auto-generated fields are set by the service and should not be included in create/update requests.

🔒 Lock Status: The isLocked field only appears in responses after a user has been locked or unlocked. New users and users that have never been locked/unlocked will not have this field in their response.


🔐 Authentication Headers

For all 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. Create User

Creates a new user with the provided information.

Request:

  • Method: POST
  • Path: /users
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Request Body:

FieldTypeRequiredDescription
emailstringUser's email address
namestringUser's display name
statusstringUser's status

Response Body:

FieldTypeDescription
idstringUnique user identifier
emailstringUser's email address
namestringUser's display name
statusstringUser's status
createdAtstringCreation timestamp
updatedAtstringLast update timestamp

Validation:

  • Schema Validation: Basic validation (email, name, status required as strings, no format validation)
  • Route Validators: verifyAuthentication(getBearerTokenInfo) - Validates bearer token authentication

Example Request:

curl -X POST {{host}}/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"email": "john.doe@example.com",
"name": "John Doe",
"status": "active"
}'

Success Response:

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

{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"email": "john.doe@example.com",
"name": "John Doe",
"status": "active",
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
}

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'",
"request body must have required property 'name'",
"request body must have required property 'status'"
]
}
}

When no authorization token is provided:

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

{
"error": {
"message": "token could not be verified"
}
}

When database insert operation fails to return an inserted ID:

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

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

When an unexpected error occurs (database connection issues, etc.):

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

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

2. Get User by ID

Retrieves a specific user by their unique ID.

Request:

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

URL Parameters:

ParameterTypeRequiredDescription
userIdstringUnique user identifier

Response Body:

FieldTypeDescription
idstringUnique user identifier
emailstringUser's email address
namestringUser's display name
statusstringUser's status
createdAtstringCreation timestamp
updatedAtstringLast update timestamp
isLockedbooleanAccount lock status (only present if user has been locked/unlocked)

Validation:

  • Schema Validation: None (GET request)
  • Route Validators:
    • verifyAuthentication(getBearerTokenInfo) - Validates bearer token authentication
    • validateUserProfileAccess(['admin', 'self'], getBearerTokenInfo) - Ensures user has admin role or is the target user

Example Request:

curl {{host}}/users/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2 \
-H "Authorization: Bearer your-access-token-here"

Success Response:

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

{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"email": "john.doe@example.com",
"name": "John Doe",
"status": "active",
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
}

Error Responses:

When no authorization token is provided:

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

{
"error": {
"message": "token could not be verified"
}
}

When the user is not authorized to access this resource:

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

{
"error": {
"message": "User is not authorized to access this user profile"
}
}

When no user exists with the provided ID:

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

{
"error": {
"message": "User profile not found"
}
}

When an unexpected error occurs (database connection issues, etc.):

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

{
"error": {
"message": "Failed to get user"
}
}

3. List Users

Retrieves a list of users with optional filtering and pagination.

Request:

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

Query Parameters:

ParameterTypeRequiredDescription
emailstringFilter users by email address
namestringFilter users by display name
statusstringFilter users by status
pagenumberPage number
limitnumberItems per page

Response Body:

FieldTypeDescription
idstringUnique user identifier
emailstringUser's email address
namestringUser's display name
statusstringUser's status
createdAtstringCreation timestamp
updatedAtstringLast update timestamp
isLockedbooleanAccount lock status (only present if user has been locked/unlocked)

Validation:

  • Schema Validation: Query parameter validation for email, name, status (strings), page and limit (integers with min/max constraints)
  • Route Validators:
    • verifyAuthentication(getBearerTokenInfo) - Validates bearer token authentication
    • validateUserProfileAccess(['admin'], getBearerTokenInfo) - Ensures user has admin role

Example Requests:

List all users:

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

Filter active users:

curl "{{host}}/users?status=active" \
-H "Authorization: Bearer <access-token>"

Filter by email:

curl "{{host}}/users?email=john.doe@example.com" \
-H "Authorization: Bearer <access-token>"

Filter by name:

curl "{{host}}/users?name=John" \
-H "Authorization: Bearer <access-token>"

Combine filters:

curl "{{host}}/users?status=active&name=John&page=1&limit=20" \
-H "Authorization: Bearer <access-token>"

Success Response:

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

[
{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"email": "john.doe@example.com",
"name": "John Doe",
"status": "active",
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
},
{
"id": "8fec096b-1bc7-5bfe-c827-3600e8fe2790",
"email": "jane.smith@example.com",
"name": "Jane Smith",
"status": "pending",
"createdAt": "2024-05-29T10:15:33.441Z",
"updatedAt": "2024-05-29T10:15:33.441Z",
"isLocked": true
}
]

Error Responses:

When an unexpected error occurs (database connection issues, invalid filter syntax, etc.):

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

{
"error": {
"message": "Failed to find users"
}
}

4. Update User

Updates an existing user with partial data.

Request:

  • Method: PATCH
  • Path: /users/:userId
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required (admin/self)

URL Parameters:

ParameterTypeRequiredDescription
userIdstringUnique user identifier

Request Body (required, all fields optional):

FieldTypeRequiredDescription
emailstringUser's email address
namestringUser's display name
statusstringUser's status

Note: While all fields in the request body are optional, the request body itself is required and cannot be empty. Sending an empty body will result in a 400 error.

Response Body:

FieldTypeDescription
idstringUnique user identifier
emailstringUpdated user's email address
namestringUpdated user's display name
statusstringUpdated user's status
createdAtstringCreation timestamp
updatedAtstringLast update timestamp

Validation:

  • Schema Validation: Basic validation (only name and status fields allowed, all optional)
  • Route Validators:
    • verifyAuthentication(getBearerTokenInfo) - Validates bearer token authentication
    • validateUserProfileAccess(['admin', 'self'], getBearerTokenInfo) - Ensures user has admin role or is the target user

Example Request:

curl -X PATCH {{host}}/users/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{"status": "inactive"}'

Success Response:

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

{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"email": "john.doe@example.com",
"name": "John Doe",
"status": "inactive",
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T14:22:15.789Z"
}

Error Responses:

When request body is empty or missing:

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

{
"error": {
"message": "Request body is required"
}
}

When no user exists with the provided ID:

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

{
"error": {
"message": "User profile not found"
}
}

When the update operation doesn't modify any data (no changes detected):

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

{
"error": {
"message": "Failed to update user"
}
}

When an unexpected error occurs (database connection issues, etc.):

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

{
"error": {
"message": "Failed to update user"
}
}

5. Delete User

Permanently deletes a user from the system.

Request:

  • Method: DELETE
  • Path: /users/:userId
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required (admin/self)

URL Parameters:

ParameterTypeRequiredDescription
userIdstringUnique user identifier

Response Body:

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

Validation:

  • Schema Validation: None (DELETE request)
  • Route Validators:
    • verifyAuthentication(getBearerTokenInfo) - Validates bearer token authentication
    • validateUserProfileAccess(['admin', 'self'], getBearerTokenInfo) - Ensures user has admin role or is the target user

Example Request:

curl -X DELETE {{host}}/users/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2 \
-H "Authorization: Bearer <access-token>"

Success Response:

HTTP/1.1 204 No Content

Error Responses:

When no user exists with the provided ID:

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

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

When an unexpected error occurs (database connection issues, etc.):

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

{
"error": {
"message": "Failed to delete user"
}
}

6. Lock User Account

Locks a user account by setting isLocked to true.

Request:

  • Method: POST
  • Path: /users/:userId/lock
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required (admin only)

URL Parameters:

ParameterTypeRequiredDescription
userIdstringUnique user identifier

Response Body:

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

Validation:

  • Schema Validation: None (no request body)
  • Route Validators:
    • verifyAuthentication(getBearerTokenInfo) - Validates bearer token authentication
    • validateUserProfileAccess(['admin'], getBearerTokenInfo) - Ensures user has admin role

Example Request:

curl -X POST {{host}}/users/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/lock \
-H "Authorization: Bearer <access-token>"

Success Response:

HTTP/1.1 204 No Content

Error Responses:

When no user exists with the provided ID:

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

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

When an unexpected error occurs (database connection issues, etc.):

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

{
"error": {
"message": "Failed to lock user"
}
}

7. Unlock User Account

Unlocks a user account by setting isLocked to false.

Request:

  • Method: POST
  • Path: /users/:userId/unlock
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required (admin only)

URL Parameters:

ParameterTypeRequiredDescription
userIdstringUnique user identifier

Response Body:

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

Validation:

  • Schema Validation: None (no request body)
  • Route Validators:
    • verifyAuthentication(getBearerTokenInfo) - Validates bearer token authentication
    • validateUserProfileAccess(['admin'], getBearerTokenInfo) - Ensures user has admin role

Example Request:

curl -X POST {{host}}/users/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/unlock

Success Response:

HTTP/1.1 204 No Content

Error Responses:

When no user exists with the provided ID:

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

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

When an unexpected error occurs (database connection issues, etc.):

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

{
"error": {
"message": "Failed to unlock user"
}
}

⚙️ Configuration Options

Service Configuration

interface UserServiceConfiguration {
authSecrets: {
authEncSecret: string; // JWT encryption secret
authSignSecret: string; // JWT signing secret
};
user?: {
typeIds?: {
admin: string; // Admin user type identifier
guest: string; // Guest user type identifier
user: string; // Regular user type identifier
};
};
}

Configuration Details

The user service configuration is organized into logical groups for security and user type management.

🔐 Security Settings

authSecrets - JWT token security secrets

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

👥 User Type Settings

user.typeIds - User type identifier configuration

  • Type: { admin?: string; guest?: string; user?: string }
  • Description: Custom user type identifiers for role-based access control
  • Default: undefined (uses default type validation)
  • Child Properties:
    • admin: Admin user type identifier
      • Type: string
      • Description: Custom identifier for admin users
      • Use Case: Role-based access control for administrative operations
      • Example: "admin", "administrator", "superuser"
    • guest: Guest user type identifier
      • Type: string
      • Description: Custom identifier for guest users
      • Use Case: Limited access for unauthenticated or temporary users
      • Example: "guest", "visitor", "anonymous"
    • user: Regular user type identifier
      • Type: string
      • Description: Custom identifier for regular users
      • Use Case: Standard user access permissions
      • Example: "user", "member", "customer"

Example Configuration

const userConfig = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET || 'your-enc-secret',
authSignSecret: process.env.AUTH_SIGN_SECRET || 'your-sign-secret'
},
user: {
typeIds: {
admin: '100',
guest: '000',
user: '001'
}
}
};

🚨 Error Handling

All user service errors return JSON format with appropriate HTTP status codes:

Common Error Codes

StatusError MessageDescription
400Validation ErrorInvalid request body format or missing required fields
400Failed to create userDatabase insert operation failed to return an inserted ID
400Failed to update userUpdate operation doesn't modify any data (no changes detected)
401token could not be verifiedMissing or invalid authorization token
403User is not authorized to access this user profileUser lacks required permissions (admin/self access)
403User is not authorized to access this resourceUser lacks required permissions (admin access)
404User profile not foundUser doesn't exist for GET/PATCH operations
404User not foundUser doesn't exist for DELETE/lock/unlock operations
500Failed to create userDatabase connection issues or unexpected failures during creation
500Failed to get userDatabase connection issues or unexpected failures during retrieval
500Failed to find usersDatabase connection issues, invalid filter syntax, or unexpected failures during listing
500Failed to update userDatabase connection issues or unexpected failures during update
500Failed to delete userDatabase connection issues or unexpected failures during deletion
500Failed to lock userDatabase connection issues or unexpected failures during account locking
500Failed to unlock userDatabase connection issues or unexpected failures during account unlocking

Error Response Format

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

Validation Errors include additional details:

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