Auth Routes
POST /auth/login
Authenticates a user using a username and password, then issues JWT tokens for session management.
This endpoint is protected by rate limiting. After 10 failed login attempts within a 15-minute window (configurable in the backend), further attempts are temporarily blocked.
The request body must be sent as JSON and include the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
| username | string | Yes | The user’s username |
| password | string | Yes | The user’s plain-text password |
{
"username": "exampleUser",
"password": "securePassword123"
}
200 OK
Returned when the user is authenticated successfully.
{
"accessToken": "<jwt-access-token>",
"user": {
"id": "string",
"username": "string",
"profile_image": "string | null",
"registered": "string",
"age_verified": "number",
"slug": "string",
"roles": [/* See model for reference */],
"permissions": [/* See model for reference */],
}
}
Models used
User Model
Role Model
Permission Model
400 Bad Request
Returned when required request parameters are missing.
{
"data": "Required parameters missing",
"code": 400
}
Models used
Response Model
401 Unauthorized
Returned when the username does not exist or the password is incorrect.
{
"data": "Invalid credentials",
"code": 401
}
Models used
Response Model
429 Too Many Requests
Returned when too many failed login attempts are made within a short period of time. The client is temporarily blocked from making further login requests.
{
"data": "Too many requests.",
"code": 429
}
Models used
Response Model
POST /auth/register
Registers a new user account using a username and password.
This endpoint is protected by rate limiting. After 10 register attempts within a 1-hour window (configurable in the backend), further attempts are temporarily blocked.
The request body must be sent as JSON and include the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
| username | string | Yes | Desired username |
| password | string | Yes | Plain-text account password |
During registration, the backend validates both the username and password against rules defined in the backend configuration. The username must be a string that falls within the allowed length range and matches the permitted character set, ensuring only valid characters are accepted. The password is also validated to confirm it is a string and meets the configured length requirements. If any of these checks fail, the registration request is rejected with a validation error.
{
"username": "new_user",
"password": "strongPassword123"
}
201 Created
Returned when the user account is created successfully.
{
"data": "User created successfully",
"code": 201
}
Models used
Response Model
400 Bad Request
Returned when required request parameters are missing.
{
"data": "Required parameters missing",
"code": 400
}
Models used
Response Model
409 Conflict
Returned when the requested username is already in use.
{
"data": "Username already taken",
"code": 409
}
Models used
Response Model
422 Unprocessable Entity
Returned when the username or password does not meet validation requirements.
{
"data": "Invalid username",
"code": 422
}
{
"data": "Invalid password",
"code": 422
}
Models used
Response Model
429 Too Many Requests
Returned when too many failed register attempts are made within a short period of time. The client is temporarily blocked from making further register requests.
{
"data": "Too many requests.",
"code": 429
}
Models used
Response Model
500 Internal Server Error
Returned when an internal error occurs during user creation or role assignment.
{
"data": "User creation failed",
"code": 500
}
{
"data": "No default role set",
"code": 500
}
Models used
Response Model
GET /auth/me
Validates the current user session using a refresh token and returns the authenticated user context along with a newly issued access token.
This endpoint uses the refresh token stored in cookies.
| Cookie Name | Required | Description |
|---|---|---|
| refreshToken | Yes | Refresh token used to validate user |
200 OK
Returned when the user is authenticated successfully and the session is valid.
{
"accessToken": "<jwt-access-token>",
"user": {
"id": "string",
"username": "string",
"profile_image": "string | null",
"registered": "string",
"age_verified": "number",
"slug": "string",
"roles": [/* See model for reference */],
"permissions": [/* See model for reference */],
"settings": { /* User-specific settings */ }
}
}
Models used
User Model
Role Model
Permission Model
401 Unauthorized
Returned when the refresh token is missing, invalid, or does not resolve to a user.
{
"data": "Unauthorized",
"code": 401
}
Models used
Response Model
POST /auth/logout
Logs out the currently authenticated user by invalidating the refresh token and clearing the authentication cookie.
This endpoint uses the refresh token stored in cookies.
| Cookie Name | Required | Description |
|---|---|---|
| refreshToken | Yes | Refresh token used to identify user |
200 OK
Returned when the user is logged out successfully.
{
"data": "Logged out",
"code": 200
}
Models used
Response Model
401 Unauthorized
Returned when the refresh token is missing or invalid.
{
"data": "Unauthorized",
"code": 401
}
Models used
Response Model
— Locks —
POST /admin/lock
Creates or validates a lock for a specific route and resource to prevent concurrent modifications.
This endpoint requires authentication via the refresh token stored in cookies and the appropriate permission.
- Required permission:
manage-locks
| Cookie Name | Required | Description |
|---|---|---|
| refreshToken | Yes | Refresh token used to identify user |
The request body must be sent as JSON and include the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
| route | string | Yes | Base route to lock (e.g. volume) |
| id | string | Yes | Resource identifier to lock |
The full lock identifier is constructed internally using the provided route and id. |
{
"route": "volume",
"id": "1234"
}
200 OK
Returned when the lock is successfully created or already owned by the requesting user.
{
"data": "Success",
"code": 200
}
Models used
Response Model
400 Bad Request
Returned when required parameters are missing.
{
"data": "Missing parameters",
"code": 400
}
Models used
Response Model
404 Not Found
Returned when the authenticated user cannot be resolved.
{
"data": "Not found",
"code": 404
}
Models used
Response Model
409 Conflict
Returned when a lock already exists for the specified route and resource and is owned by another user.
{
"data": "Conflict",
"code": 409
}
Models used
Response Model
500 Internal Server Error
Returned when the lock could not be created due to an internal error.
{
"data": "Internal server error",
"code": 500
}
Models used
Response Model
DELETE /admin/remove-lock
Removes an existing lock from a specific resource. This endpoint is restricted to authenticated users with the appropriate permission and ensures that only the owner of a lock can remove it.
This endpoint requires authentication via a refresh token stored in cookies and the required permission.
| Cookie Name | Required | Description |
|---|---|---|
| refreshToken | Yes | Refresh token used to authenticate |
Required Permission: manage-locks
| Field | Type | Required | Description |
|---|---|---|---|
| route | string | Yes | Base route of the locked resource |
| id | string | Yes | Identifier of the locked resource |
The full lock identifier is constructed internally using the provided route and id.
200 OK
Returned when the lock is successfully removed.
{
"data": "Success",
"code": 200
}
Models used
Response Model
400 Bad Request
Returned when required parameters are missing.
{
"data": "Missing parameters",
"code": 400
}
Models used
Response Model
403 Forbidden
Returned when the lock exists but does not belong to the authenticated user.
{
"data": "Forbidden",
"code": 403
}
Models used
Response Model
404 Not Found
Returned when the user or lock cannot be found.
{
"data": "Not found",
"code": 404
}
Models used
Response Model
500 Internal Server Error
Returned when an unexpected error occurs while removing the lock.
{
"data": "Internal server error",
"code": 500
}
Models used
Response Model