The Auth Service handles user registration, login, JWT token management, and session handling. It runs on port 6000 at https://auth.sebhosting.com.
All /auth/* endpoints are rate-limited to 20 requests per 15 minutes per IP address. Exceeding this limit returns:
{
"error": "Too many attempts, try again later"
}
/auth/registerCreate a new user account. The first registered user automatically receives the admin role; subsequent users get viewer.
Request:
{
"username": "seb",
"email": "seb@example.com",
"password": "securepassword123"
}
Response (201):
{
"message": "Account created",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "seb",
"email": "seb@example.com",
"role": "admin"
}
}
Errors:
400 β Missing fields or password under 8 characters409 β Username or email already taken/auth/loginAuthenticate and receive a JWT access token. A refresh token is set as an httpOnly cookie.
Request:
{
"email": "seb@example.com",
"password": "securepassword123"
}
Response (200):
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "seb",
"email": "seb@example.com",
"role": "admin"
}
}
Cookies set:
refresh_token β httpOnly, secure, sameSite=strict, 7-day expiryErrors:
400 β Missing email or password401 β Invalid credentials/auth/refreshExchange a refresh token cookie for a new access token. Implements token rotation β the old refresh token is invalidated and a new one is issued.
Request: No body required. The refresh token is read from the refresh_token cookie.
Response (200):
{
"accessToken": "eyJhbGciOiJIUzI1NiIs..."
}
Errors:
401 β No refresh token, expired, or revoked/auth/meGet the current authenticated userβs profile. Requires a valid access token.
Headers:
Authorization: Bearer <access_token>
Response (200):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "seb",
"email": "seb@example.com",
"role": "admin",
"lastLogin": "2026-02-14T06:19:07.261Z"
}
/auth/logoutLogout the current user. Revokes all refresh tokens for the user and clears the refresh token cookie.
Headers:
Authorization: Bearer <access_token>
Response (200):
{
"message": "Logged out"
}
httpOnly, secure, and sameSite=stricthttps://nexus.sebhosting.com and http://localhost:3000CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(20) NOT NULL DEFAULT 'viewer',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
last_login TIMESTAMPTZ,
is_active BOOLEAN NOT NULL DEFAULT true
);
CREATE TABLE refresh_tokens (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
token_hash VARCHAR(255) NOT NULL,
expires_at TIMESTAMPTZ NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);