NeXuS

Auth Service API

The Auth Service handles user registration, login, JWT token management, and session handling. It runs on port 6000 at https://auth.sebhosting.com.

Rate Limiting

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"
}

Endpoints

POST /auth/register

Create 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:

POST /auth/login

Authenticate 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:

Errors:

POST /auth/refresh

Exchange 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:

GET /auth/me

Get 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"
}

POST /auth/logout

Logout 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"
}

Security Details

Database Schema

CREATE 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()
);