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:
{
"username": "admin",
"password": "your-secure-password"
}| Field | Rules |
|---|---|
username | Required, minimum 3 characters |
password | Required, minimum 8 characters |
Response (201):
{
"ok": true,
"data": {
"username": "admin",
"createdAt": "2024-01-01T00:00:00.000Z"
}
}Error responses:
| Status | When |
|---|---|
| 405 | Not POST |
| 409 | Admin already initialized |
| 400 | Username < 3 chars or password < 8 chars |
Login
POST /api/auth/login
Authenticate with the admin credentials and receive a session token.
Request:
{
"username": "admin",
"password": "your-secure-password"
}Response (200):
{
"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-hexError responses:
| Status | When |
|---|---|
| 401 | Missing username/password |
| 401 | Admin not initialized |
| 401 | Invalid 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):
{
"ok": true,
"data": {
"setupRequired": true,
"authenticated": false,
"username": null
}
}Response (admin exists, not authenticated):
{
"ok": true,
"data": {
"setupRequired": false,
"authenticated": false,
"username": null
}
}Response (authenticated):
{
"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):
{
"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