docs: update documentation to OKF v0.1 format

This commit is contained in:
OpenVelo Agent
2026-07-21 21:19:36 +00:00
parent cd97e40030
commit ad40b3b820
2 changed files with 31 additions and 18 deletions
+30 -17
View File
@@ -1,7 +1,7 @@
---
type: api
title: Auth Endpoints
description: Login, refresh, logout, public self-registration, CSRF, and first-admin registration.
description: Login, refresh, logout, public self-registration, CSRF, first-admin registration, and registration throttling.
tags: [api, auth, login, register, refresh, csrf]
timestamp: 2026-07-21T18:28:00Z
---
@@ -51,18 +51,27 @@ The refresh token is set as an `HttpOnly` cookie via `setRefreshCookie(res, sess
| 400 | `WEAK_PASSWORD` | Argon2 policy rejects the password. |
| 403 | `REGISTRATIONS_DISABLED`| `setting.registrationsEnabled !== 'true'`. |
| 409 | `USERNAME_TAKEN` | A user with that username already exists. |
| 429 | `RATE_LIMITED` | `RegistrationRateLimitService` blocked the IP. |
| 429 | `RATE_LIMITED` | The per-IP registration limiter has reached 10 attempts in the rolling 60-second window. |
## Wiring
* `AuthService.registerPlayer(dto, ip)` runs inside a single
`DataSource.transaction`:
1. `RegistrationRateLimitService.isAllowed(ip)` check.
* `AuthService.registerPlayer(dto, ip)` runs inside a single `DataSource.transaction`:
1. `RegistrationRateLimitService.tryConsume(ip)` permits at most 10 attempts per IP in a rolling 60-second window.
2. `SettingsService.get(SETTINGS_KEYS.REGISTRATIONS_ENABLED, 'false')` check.
3. Username uniqueness lookup → `USERNAME_TAKEN` on collision.
4. Argon2id hash + insert `UserEntity({ role: 'player', status: 'enabled' })`.
5. `RegistrationRateLimitService.record(ip)`.
6. `mintSession(manager, user)` → access JWT + refresh row.
5. `mintSession(manager, user)` → access JWT + refresh row.
* `AuthService.registerFirstAdmin(username, password, ip)` uses the same limiter before checking whether an administrator already exists.
* The limiter is an in-memory Nest provider in `backend/src/common/services/registration-rate-limit.service.ts`; counters are process-local and reset when the API process restarts.
# Key Files
| File | Responsibility |
|------|----------------|
| `backend/src/modules/auth/auth.service.ts` | Validates registration policy, applies the limiter, creates users, and mints sessions. |
| `backend/src/common/services/registration-rate-limit.service.ts` | Tracks timestamps and enforces the 10-per-minute per-IP limit. |
| `backend/src/modules/auth/auth.controller.ts` | Exposes public registration and authentication routes. |
| `backend/src/modules/auth/dto/auth.dto.ts` | Validates registration request fields. |
# Frontend consumer
@@ -70,18 +79,22 @@ The refresh token is set as an `HttpOnly` cookie via `setRefreshCookie(res, sess
`register()`. Both:
1. Call `ensureCsrf()``GET /api/v1/auth/csrf` to materialise the `csrf`
cookie if it isn't set yet (failures are swallowed because the
`CsrfMiddleware` will mint the cookie on the next response anyway).
cookie if it isn't set yet.
2. `POST` with `{ withCredentials: true, observe: 'response' }`.
3. Return a discriminated union:
* `{ ok: true, accessToken, expiresIn, user }` on success.
* `{ ok: false, status, code, message }` on failure, built by the
private `mapAuthError()` helper from the standard
[error envelope](/api/rest-overview.md).
3. Return success or the standard [error envelope](/api/rest-overview.md).
The `LandingComponent` (`frontend/src/app/features/landing/landing.component.ts`)
consumes both methods and maps the `code` to user-facing copy via
`buildLoginFailureMessage` (see [Landing Page](/guides/landing-page.md)).
The `LandingComponent` consumes both methods and maps failures to user-facing
copy (see [Landing Page](/guides/landing-page.md)).
# Examples
## Tester flow: registration rate limit
1. Enable registrations in the admin settings.
2. Open the public registration form from the landing page.
3. Submit attempts from the same client IP.
4. The first 10 attempts are processed normally; the 11th within 60 seconds returns HTTP `429` with code `RATE_LIMITED`.
5. After the rolling window expires, a new attempt is accepted if other requirements pass.
# See also
+1 -1
View File
@@ -11,7 +11,7 @@ scoreboard, an event window with a public countdown, theming, and admin
controls.
The docs below are organized by purpose so agents can pull just the slice
they need. Last regenerated 2026-07-21T18:45:54Z.
they need. Last regenerated 2026-07-21T21:18:00Z.
# Architecture