Endpoint
Request body
The user’s username
The user’s password (will be compared against the bcrypt hash)
Response
HTTP status code (200 for success, 401 for authentication failure)
JSON stringified response object
Success response object
Example request
cURL
Example success response
Error responses
User not found
Returned when no user exists with the provided username.Invalid password
Returned when the password does not match the stored hash.Authentication flow
- Client sends username and password to
/api/user/login - Server looks up user by username in the database (source:
server/api/user/login.ts:16-18) - If user not found, returns 401 error
- Server compares provided password with stored bcrypt hash (source:
server/api/user/login.ts:27) - If password invalid, returns 401 error
- Server generates JWT token with user data (source:
server/api/user/login.ts:36) - Token contains:
userId,username,userTypeand expires in 1 hour - Client receives token and should include it in subsequent API requests
Using the JWT token
After successful login, include the JWT token in theAuthorization header for protected endpoints:
Token details
- Signing algorithm: HS256 (HMAC with SHA-256)
- Expiration: 1 hour from issue time
- Payload includes: userId, username, userType
- Implementation: Source code at
server/api/user/login.ts:35-36
Security notes
- Passwords are never returned in responses
- Password verification uses bcrypt’s constant-time comparison
- Failed login attempts return generic 401 errors to prevent username enumeration
- Tokens expire after 1 hour and must be refreshed