👤 User Service
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
Method | Path | Description | Authorization |
---|---|---|---|
POST | /users | Create a new user | Bearer token required |
GET | /users/:userId | Retrieve a user by ID | Bearer token required (admin/self) |
GET | /users | List/filter users | Bearer token required (admin only) |
PATCH | /users/:userId | Update a user | Bearer token required (admin/self) |
DELETE | /users/:userId | Delete a user | Bearer token required (admin/self) |
POST | /users/:userId/lock | Lock a user account | Bearer token required (admin only) |
POST | /users/:userId/unlock | Unlock a user account | Bearer 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
Field | Type | Auto-Generated | Required | Description |
---|---|---|---|---|
id | string | ✅ | ✅ | Unique identifier (UUID) |
createdAt | datetime | ✅ | ✅ | Creation timestamp |
updatedAt | datetime | ✅ | ✅ | Last modification timestamp |
email | string | ❌ | ✅ | User's email address |
name | string | ❌ | ✅ | User's display name |
status | string | ❌ | ✅ | User status (e.g., "active", "pending") |
isLocked | boolean | ❌ | ❌ | Account 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:
Field | Type | Required | Description |
---|---|---|---|
email | string | ✅ | User's email address |
name | string | ✅ | User's display name |
status | string | ✅ | User's status |
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique user identifier |
email | string | User's email address |
name | string | User's display name |
status | string | User's status |
createdAt | string | Creation timestamp |
updatedAt | string | Last 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:
Parameter | Type | Required | Description |
---|---|---|---|
userId | string | ✅ | Unique user identifier |
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique user identifier |
email | string | User's email address |
name | string | User's display name |
status | string | User's status |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
isLocked | boolean | Account lock status (only present if user has been locked/unlocked) |
Validation:
- Schema Validation: None (GET request)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Validates bearer token authenticationvalidateUserProfileAccess(['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:
Parameter | Type | Required | Description |
---|---|---|---|
email | string | ❌ | Filter users by email address |
name | string | ❌ | Filter users by display name |
status | string | ❌ | Filter users by status |
page | number | ❌ | Page number |
limit | number | ❌ | Items per page |
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique user identifier |
email | string | User's email address |
name | string | User's display name |
status | string | User's status |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
isLocked | boolean | Account 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 authenticationvalidateUserProfileAccess(['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:
Parameter | Type | Required | Description |
---|---|---|---|
userId | string | ✅ | Unique user identifier |
Request Body (required, all fields optional):
Field | Type | Required | Description |
---|---|---|---|
email | string | ❌ | User's email address |
name | string | ❌ | User's display name |
status | string | ❌ | User'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:
Field | Type | Description |
---|---|---|
id | string | Unique user identifier |
email | string | Updated user's email address |
name | string | Updated user's display name |
status | string | Updated user's status |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Validation:
- Schema Validation: Basic validation (only name and status fields allowed, all optional)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Validates bearer token authenticationvalidateUserProfileAccess(['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:
Parameter | Type | Required | Description |
---|---|---|---|
userId | string | ✅ | Unique user identifier |
Response Body:
Field | Type | Description |
---|---|---|
No response body | - | Delete endpoint returns no response body on success |
Validation:
- Schema Validation: None (DELETE request)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Validates bearer token authenticationvalidateUserProfileAccess(['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:
Parameter | Type | Required | Description |
---|---|---|---|
userId | string | ✅ | Unique user identifier |
Response Body:
Field | Type | Description |
---|---|---|
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 authenticationvalidateUserProfileAccess(['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:
Parameter | Type | Required | Description |
---|---|---|---|
userId | string | ✅ | Unique user identifier |
Response Body:
Field | Type | Description |
---|---|---|
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 authenticationvalidateUserProfileAccess(['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 encryptionauthSignSecret
: 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"
- Type:
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"
- Type:
user
: Regular user type identifier- Type:
string
- Description: Custom identifier for regular users
- Use Case: Standard user access permissions
- Example:
"user"
,"member"
,"customer"
- Type:
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
Status | Error Message | Description |
---|---|---|
400 | Validation Error | Invalid request body format or missing required fields |
400 | Failed to create user | Database insert operation failed to return an inserted ID |
400 | Failed to update user | Update operation doesn't modify any data (no changes detected) |
401 | token could not be verified | Missing or invalid authorization token |
403 | User is not authorized to access this user profile | User lacks required permissions (admin/self access) |
403 | User is not authorized to access this resource | User lacks required permissions (admin access) |
404 | User profile not found | User doesn't exist for GET/PATCH operations |
404 | User not found | User doesn't exist for DELETE/lock/unlock operations |
500 | Failed to create user | Database connection issues or unexpected failures during creation |
500 | Failed to get user | Database connection issues or unexpected failures during retrieval |
500 | Failed to find users | Database connection issues, invalid filter syntax, or unexpected failures during listing |
500 | Failed to update user | Database connection issues or unexpected failures during update |
500 | Failed to delete user | Database connection issues or unexpected failures during deletion |
500 | Failed to lock user | Database connection issues or unexpected failures during account locking |
500 | Failed to unlock user | Database 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'"
]
}
}
🔗 Related Documentation
- Error Handling - Understanding error patterns
- Schema Component - Data validation concepts
- Custom Service Tutorial - Build your own services