Users
User Managementβ
The user endpoints manage user accounts in the Ambrosia POS system.
The role field differs between create and update:
POST /usersreceives theUsermodel, where the role is sent in therolefield (UUID of an existing role).PUT /users/{id}receivesUpdateUserRequest, where the role is sent in theroleIdfield.
GET /usersβ
Retrieves all users in the system.
Authorization: None (public in this version).
cURL Example:
curl -X GET "http://127.0.0.1:9154/users"
Response Body (Success - 200 OK):
[
{
"id": "e911705c-e1b4-4997-ab02-ef7460491ac0",
"name": "cooluser1",
"pin": "****",
"refreshToken": "****",
"role": "Waiter",
"roleId": "e7349203-1bdf-4d8a-8a83-0f5dccb23e1b",
"email": null,
"phone": null,
"isAdmin": false
}
]
isAdmin is always false in this listinggetUsers() never assigns isAdmin, so the field falls back to the model default (false) regardless of whether the user is an administrator. Use GET /users/{id} to get the real value β that query does select it.
Response Body (Empty list - 200 OK):
"No users found"
GET /users/{id}β
Retrieves a specific user by their ID.
Authorization: None (public in this version).
Path Parameters:
id(string): ID of the user to retrieve.
cURL Example:
curl -X GET "http://127.0.0.1:9154/users/76ee1086-b945-4170-b2e6-9fbeb95ae0be"
Response Body (Success - 200 OK):
{
"id": "76ee1086-b945-4170-b2e6-9fbeb95ae0be",
"name": "admin",
"pin": "****",
"refreshToken": null,
"role": "Admin",
"roleId": null,
"email": "admin@ambrosia.com",
"phone": null,
"isAdmin": true
}
Unlike GET /users, which always masks the token as "****", getUserById() returns the raw refresh_token column value: null when the user has no active session, but the real, unmasked token when they do. Since the endpoint also requires no authentication, anyone who knows a user ID can obtain the refresh token of an open session. Treat this as a known server-side security flaw, not intended behaviour.
isAdmin is reliable hereUnlike GET /users, this query does select r.isAdmin, so the value reflects the real state of the role.
roleId is always null hereThe GET_USER_BY_ID query selects r.role and r.isAdmin but not u.role_id, so roleId is never populated in this response. Use GET /users if you need the role UUID.
GET /users/meβ
Retrieves the currently authenticated user together with their permissions.
Authorization: requires a valid accessToken and the refreshToken cookie. If the latter is missing, it responds 401 { "error": "Refresh token no encontrado" }.
cURL Example:
curl -X GET "http://127.0.0.1:9154/users/me" \
-H "Cookie: accessToken=$ACCESS_TOKEN" \
-H "Cookie: refreshToken=$REFRESH_TOKEN"
Response Body (Success - 200 OK):
{
"user": {
"userId": "76ee1086-b945-4170-b2e6-9fbeb95ae0be",
"name": "admin",
"role": "Admin",
"roleId": "Admin",
"isAdmin": true,
"email": null,
"phone": null
},
"perms": [
{ "id": "perm-uuid", "name": "orders_read", "description": "Read orders", "enabled": true }
]
}
roleId repeats the role nameThe handler builds the response with roleId = userInfo.role, assigning the role name to the roleId field instead of the UUID (which is available as userInfo.roleId). That is why role and roleId return the same value. This is a known server bug β do not rely on roleId from this endpoint.
POST /usersβ
Creates a new user in the system.
Authorization: users_create
Request Body:
{
"name": "string",
"pin": "string (minimum 4 characters)",
"role": "UUID of an existing role",
"email": "string (optional)",
"phone": "string (optional)",
"isAdmin": false
}
cURL Example:
curl -X POST "http://127.0.0.1:9154/users" \
-H "Cookie: accessToken=$ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "newuser",
"pin": "1234",
"role": "262006ea-8782-4b08-ac3b-b3f13270fec3"
}'
Response Body (Success - 201 Created):
{
"id": "new-user-uuid",
"message": "User added successfully"
}
Response Body (Duplicate name - 409 Conflict):
{
"message": "User name already exists"
}
PUT /users/{id}β
Updates an existing user. All fields are optional (but at least one must be provided).
Authorization: users_update
Path Parameters:
id(string): ID of the user to update.
Request Body:
{
"name": "string",
"pin": "string",
"roleId": "UUID (role ID)",
"email": "string",
"phone": "string",
"refreshToken": "string"
}
cURL Example:
curl -X PUT "http://127.0.0.1:9154/users/76ee1086-b945-4170-b2e6-9fbeb95ae0be" \
-H "Cookie: accessToken=$ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "updateduser",
"pin": "5678",
"roleId": "262006ea-8782-4b08-ac3b-b3f13270fec3"
}'
Response Body (Success - 200 OK):
{
"id": "76ee1086-b945-4170-b2e6-9fbeb95ae0be",
"message": "User updated successfully"
}
DELETE /users/{id}β
Deletes a user from the system.
Authorization: users_delete
Path Parameters:
id(string): ID of the user to delete.
cURL Example:
curl -X DELETE "http://127.0.0.1:9154/users/76ee1086-b945-4170-b2e6-9fbeb95ae0be" \
-H "Cookie: accessToken=$ACCESS_TOKEN"
Response: 204 No Content (no body).
Response Body (409 Conflict): when trying to delete the last user or the last administrator.
{
"message": "Cannot delete the last user"
}
Notesβ
GET /usersandGET /users/{id}are public (no authentication) in this version.- User IDs are UUIDs generated automatically.
- The PIN is stored hashed and returned masked as
"****"; minimum 4 characters.
Remember: on create the role goes in the role field; on update it goes in roleId. See the note at the top of the page.