Skip to content

Authentication

Dotnify uses a simple Bearer token authentication system. Sessions are stored in Redis with a 7-day TTL.

Setup

POST /api/auth/setup

Create the admin account. This endpoint is only available when no admin exists yet. After the admin is created, this endpoint returns 409 Conflict.

Request:

json
{
  "username": "admin",
  "password": "your-secure-password"
}
FieldRules
usernameRequired, minimum 3 characters
passwordRequired, minimum 8 characters

Response (201):

json
{
  "ok": true,
  "data": {
    "username": "admin",
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
}

Error responses:

StatusWhen
405Not POST
409Admin already initialized
400Username < 3 chars or password < 8 chars

Login

POST /api/auth/login

Authenticate with the admin credentials and receive a session token.

Request:

json
{
  "username": "admin",
  "password": "your-secure-password"
}

Response (200):

json
{
  "ok": true,
  "data": {
    "token": "a1b2c3d4...64-char-hex",
    "username": "admin"
  }
}

The token should be sent as a Bearer token in subsequent requests:

Authorization: Bearer a1b2c3d4...64-char-hex

Error responses:

StatusWhen
401Missing username/password
401Admin not initialized
401Invalid credentials

Check Status

GET /api/auth/me

Check the current authentication state. This is a public endpoint — it does not require a Bearer token, but will use one if provided to determine the auth status.

Response (no admin yet):

json
{
  "ok": true,
  "data": {
    "setupRequired": true,
    "authenticated": false,
    "username": null
  }
}

Response (admin exists, not authenticated):

json
{
  "ok": true,
  "data": {
    "setupRequired": false,
    "authenticated": false,
    "username": null
  }
}

Response (authenticated):

json
{
  "ok": true,
  "data": {
    "setupRequired": false,
    "authenticated": true,
    "username": "admin"
  }
}

Logout

POST /api/auth/logout

Invalidate the current session token in Redis. This endpoint is idempotent — calling it without a token still returns success.

Headers:

Authorization: Bearer <token>

Response (200):

json
{
  "ok": true,
  "data": {
    "loggedOut": true
  }
}

Session Details

  • Token format: 64-character hex string (32 random bytes)
  • TTL: 7 days (604,800 seconds) from creation
  • Storage: Redis key dotnify:session:<token>
  • Password hashing: scrypt with 16-byte salt and 64-byte key length
  • Verification: timing-safe comparison to prevent timing attacks