Users

Base URL: /api/users · Port 3001 in development.

All endpoints in this group require an authenticated admin unless noted. changeMyPwd is the only exception — it is available to any authenticated role.

Role values: "admin" | "distributor"


POST /api/users/create

Auth required: Yes — admin only

Creates a new user account. The user is created with a default hashed password and is_active = false. An activation email is sent so they can set their own password via PATCH /api/auth/changePwd.

Request body

FieldTypeRequiredDescription
namestringFull name of the user
emailstringValid email address (must be unique)
rolestring"admin" or "distributor"
{
  "name": "John Doe",
  "email": "john@pakag.com",
  "role": "distributor"
}

Response 201

{
  "id": 5,
  "name": "John Doe",
  "email": "john@pakag.com",
  "role": "distributor",
  "is_active": false
}

Errors

StatusMessageCondition
400"name is required and must be a non-empty string"Missing or empty name
400"email is required and must be a valid email address"Missing or invalid email
400"role is required and must be one of: admin, distributor"Invalid or missing role
401"Authorization header is missing"No token
403"You do not have permission to access this resource"Caller is not admin
409"A user with this email already exists"Duplicate email
500"Internal server error"Unhandled exception

Side effect: Inserts user row with bcrypt-hashed default password. Sends an activation email with a one-time token link (expires in 7 days).


GET /api/users/list

Auth required: Yes — admin only

Returns a paginated list of users, optionally filtered by role and/or active status.

Query parameters

ParamTypeDefaultDescription
rolestringFilter by "admin" or "distributor"
is_activestringFilter by "true" or "false"
pagenumber1Page number
limitnumber20Results per page (1–100)

Response 200

{
  "users": [
    {
      "id": 1,
      "name": "Admin User",
      "email": "admin@pakag.com",
      "role": "admin",
      "is_active": true,
      "created_at": "2024-01-01T00:00:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20
}

Errors

StatusMessageCondition
400"role must be one of: admin, distributor"Invalid role value
400"is_active must be 'true' or 'false'"Invalid boolean string
401"Authorization header is missing"No token
403"You do not have permission to access this resource"Caller is not admin
500"Internal server error"Unhandled exception

GET /api/users/getById

Auth required: Yes — admin only

Returns the full profile of a single user by ID.

Query parameters

ParamTypeRequiredDescription
idnumberUser ID (positive integer)

Response 200

{
  "id": 3,
  "name": "Jane Smith",
  "email": "jane@pakag.com",
  "role": "distributor",
  "is_active": true,
  "created_at": "2024-01-15T10:00:00.000Z",
  "updated_at": "2024-03-01T08:30:00.000Z"
}

Errors

StatusMessageCondition
400"id is required"Missing id query param
400"id must be a positive integer"Non-integer or negative value
401"Authorization header is missing"No token
403"You do not have permission to access this resource"Caller is not admin
404"User not found"No user with that ID
500"Internal server error"Unhandled exception

PATCH /api/users/update

Auth required: Yes — admin only

Partially updates one or more fields of an existing user. At least one field (besides id) must be provided.

Request body

FieldTypeRequiredDescription
idnumberID of the user to update
namestringNew full name
emailstringNew email (must be unique)
rolestring"admin" or "distributor"
is_activebooleanActivate or deactivate the account
{
  "id": 3,
  "name": "Jane Doe",
  "is_active": false
}

Response 200

{
  "id": 3,
  "name": "Jane Doe",
  "email": "jane@pakag.com",
  "role": "distributor",
  "is_active": false
}

Errors

StatusMessageCondition
400"id must be a positive integer"Missing or invalid ID
400"name must be a non-empty string"Invalid name
400"email must be a valid email address"Invalid email
400"is_active must be a boolean"Non-boolean value
400"role must be one of: admin, distributor"Invalid role
400"at least one field must be provided to update"Empty update body
401"Authorization header is missing"No token
403"You do not have permission to access this resource"Caller is not admin
404"User not found"No user with that ID
409"This email is already in use by another user"Duplicate email
500"Internal server error"Unhandled exception

DELETE /api/users/remove

Auth required: Yes — admin only

Permanently deletes a user. A user cannot delete themselves.

Query parameters

ParamTypeRequiredDescription
idnumberUser ID to delete

Response 204 — No content.

Errors

StatusMessageCondition
400"id is required"Missing query param
400"id must be a positive integer"Non-integer value
401"Authorization header is missing"No token
403"You do not have permission to access this resource"Caller is not admin
404"User not found"No user with that ID
409"User cannot be deleted because it has related records"User has DB foreign key references
500"Internal server error"Unhandled exception

Side effect: Deletes the user row. Refresh, reset, and activation tokens linked to the user are removed by DB cascade.


PATCH /api/users/changeMyPwd

Auth required: Yes — admin or distributor (Bearer token)

Allows any authenticated user to change their own password.

Request body

FieldTypeRequiredDescription
current_passwordstringCurrent plaintext password
new_passwordstringNew password (min 6 characters)
{
  "current_password": "oldSecret",
  "new_password": "newSecret123"
}

Response 200

{ "message": "Password updated successfully" }

Errors

StatusMessageCondition
400"current_password is required"Missing current password
400"new_password must be at least 6 characters"Too-short new password
401"Authorization header is missing"No token
401"Invalid credentials"Current password doesn’t match
500"Internal server error"Unhandled exception