Login
Authenticate a user with email and password credentials.Endpoint
Authenticate user and receive JWT tokens
Request Body
User’s email address (must be valid email format)
User’s password (ASCII characters only)
Response
On success, returns status200 OK with JWT tokens set as HTTP-only cookies:
jwt-access - Access token cookie (expires per JWT_ACCESS_EXP_MIN)jwt-refresh - Refresh token cookie (expires per JWT_REFRESH_EXP_MIN)Error Responses
400 Bad Request
Invalid email format or missing required fields
401 Unauthorized
Incorrect email or password
User Signup
Create a new user account with email and password.Endpoint
Register a new user account
Request Body
User’s first name
User’s last name
User’s email address (must be unique and valid email format)
User’s phone number (must be in E.164 format, e.g., +14155552671)
User’s password (ASCII characters only, will be hashed with bcrypt)
Response
On success, returns status201 Created with JWT tokens set as HTTP-only cookies:
jwt-access - Access token cookiejwt-refresh - Refresh token cookieError Responses
400 Bad Request
Validation errors (invalid email, phone number format, email/phone already exists, or password too long)
Get Current User
Retrieve information about the currently authenticated user.Endpoint
Get current authenticated user details
Authentication Required
This endpoint requires a valid access token in thejwt-access cookie.
Response
Returns status200 OK if authenticated.
Logout
Log out the current user by clearing their JWT tokens.Endpoint
Logout from current device
Authentication Required
This endpoint requires a valid access token in thejwt-access cookie.
Response
Clears bothjwt-access and jwt-refresh cookies by setting them to expired.
Logout All Devices
Invalidate all refresh tokens across all devices by incrementing the user’s JWT refresh version.Endpoint
Logout from all devices and invalidate all refresh tokens
Authentication Required
This endpoint requires a valid access token in thejwt-access cookie.
Response
Increments the user’sjwt_refresh_version in the database, invalidating all existing refresh tokens. Clears both jwt-access and jwt-refresh cookies for the current session.
Error Responses
400 Bad Request
Error incrementing refresh version
JWT Token Structure
Access and refresh tokens are signed using HS256 algorithm and contain the following claims:Common Claims (Both Tokens)
Subject - User ID (UUID v7 format)
Expiration time (Unix timestamp)
Optional Employee Claims
If the user is associated with a merchant as an employee:Merchant ID the employee belongs to
Employee ID
Location ID where the employee works
Employee role (e.g., “owner”, “manager”, “staff”)
Refresh Token Only
Current refresh token version (incremented on logout all devices)
Token Configuration
Token expiration times are configured via environment variables:JWT_ACCESS_EXP_MIN- Access token expiration in minutesJWT_REFRESH_EXP_MIN- Refresh token expiration in minutesJWT_ACCESS_SECRET- Secret key for signing access tokensJWT_REFRESH_SECRET- Secret key for signing refresh tokens
Implementation Notes
Password Security
- Passwords are hashed using bcrypt with cost factor 14
- Original passwords are never stored
- Password comparison is constant-time to prevent timing attacks
Token Storage
Tokens are stored in HTTP-only cookies with the following properties:- HttpOnly: Prevents JavaScript access (XSS protection)
- SameSite: Lax mode (CSRF protection)
- Domain:
.reservations.local(subdomain support) - Secure: false in development, true in production (HTTPS only)
- Path:
/(available site-wide)
Cookie Names
- Access token:
jwt-access - Refresh token:
jwt-refresh