Skip to main content

Authentication

Admin login with Discord, the signed-in admin's profile, logout, and the session cleanup job.

Project-scoped login (/auth/authorize), backend-to-backend session API (/auth/token, /auth/validate, /auth/logout, /auth/token/refresh), and system-admin Discord OAuth (/auth/admin/*). Use /auth/authorize when you need to force a fresh Discord consent (step-up auth) or to stay on the pre-SSO flow.

Initiate system admin Discord OAuth2 login

GET/api/auth/admin/discord

Returns a Discord authorization URL. The admin opens the URL, authenticates with Discord, and is redirected to the admin callback endpoint.

A CLI (mcid-cli) can instead receive the result itself: pass a loopback redirect_uri plus a PKCE S256 code_challenge (RFC 8252 / RFC 7636). After Discord, MCID redirects to that URL with ?code=&state= (or ?error=&state=), and the CLI exchanges the code at POST /auth/admin/token.

Authentication: None, this endpoint is public.

Parameters

NameInTypeRequiredDescription
redirect_uriquerystringnoCLI login only: the loopback URL (http, 127.0.0.1 / localhost / [::1], explicit port) MCID redirects to with ?code=&state= (or ?error=&state=) once Discord is done.
code_challengequerystringnoCLI login only: PKCE challenge, BASE64URL(SHA256(code_verifier)) (RFC 7636).
code_challenge_methodquerystringnoCLI login only: must be S256.

Responses

StatusDescriptionBody
200Discord authorization URL.any
400Invalid CLI login parameters (non-loopback redirect_uri, missing or malformed PKCE challenge).

Open in Swagger (opens in a new tab)

Log out of the admin dashboard

POST/api/auth/admin/logout

Invalidates the current admin session and clears the admin_session httpOnly cookie. Accepts the token via Authorization: Bearer or the admin_session cookie, same as other admin routes.

Authentication: Admin session token (Authorization: Bearer <token>)

Responses

StatusDescriptionBody
200Logout successful.SuccessResponseDto
401Missing, invalid, or expired session token.

Open in Swagger (opens in a new tab)

Get current system admin profile

GET/api/auth/admin/me

Returns the profile of the authenticated system admin based on their Bearer session token or the admin_session httpOnly cookie set after Discord OAuth2 login. Also returns root and the effective access level per admin resource (permissions), which the admin panel uses to decide what to show. Any valid admin session succeeds, including one whose member holds no access yet. Useful for verifying a token is still valid and retrieving up-to-date profile data.

Authentication: Admin session token (Authorization: Bearer <token>)

Responses

StatusDescriptionBody
200Authenticated admin profile.AdminMeResponseDto
401Missing, invalid, or expired session token.

Open in Swagger (opens in a new tab)

Exchange a CLI login code for an admin session

POST/api/auth/admin/token

Second half of the CLI admin login (mcid-cli). Exchanges the one-time code MCID redirected to the CLI with, plus the PKCE codeVerifier whose S256 challenge started the login, for a 24-hour admin session token. A code works once and expires quickly; every failure returns the same 401.

Authentication: None, this endpoint is public.

Request body (JSON, required): AdminCliTokenDto schema.

Responses

StatusDescriptionBody
200Admin session issued.AdminCliTokenResponseDto
401Unknown, used or expired code, or a code_verifier that does not match.

Open in Swagger (opens in a new tab)

Cleanup expired sessions (maintenance)

POST/api/auth/cleanup

Removes expired sessions. Should be called by a scheduled job.

Authentication: None, this endpoint is public.

Responses

StatusDescriptionBody
200Cleanup completed.SuccessResponseDto

Open in Swagger (opens in a new tab)

Schemas

AdminCliTokenDto schema

FieldTypeRequiredDescription
codestringyesThe one-time code from the CLI login redirect
codeVerifierstringyesThe PKCE code_verifier whose S256 challenge started the login (RFC 7636)

AdminCliTokenResponseDto schema

FieldTypeRequiredDescription
expiresAtstring (date-time)yesWhen the session expires
tokenstringyesAdmin session token (Bearer), valid 24 hours

AdminMeResponseDto schema

FieldTypeRequiredDescription
avatarstring or nullnoDiscord avatar hash or full CDN URL
displayNamestring or nullnoDiscord guild nickname (rewritten on every sync)
emailstring or nullnoEmail address from Discord (requires email OAuth scope)
globalNamestring or nullnoDiscord global display name
idstringyesMember ID (Discord snowflake)
isSystemAdminbooleanyesWhether the member has the system admin flag set
permissionsmap of "none" or "read" or "write" or "manage"yesThe effective access level per admin resource. The admin panel builds its navigation from this; the API enforces it on every request.
preferredNamestring or nullnoAdmin-set display-name override (via PATCH /api/admin/profile); takes precedence over displayName in the UI when present
rootbooleanyesTrue when the member holds a root role. Root has manage on every resource.
sessionExpiresAtstring (date-time)yesISO 8601 timestamp when the current session expires
usernamestringyesDiscord username

SuccessResponseDto schema

FieldTypeRequiredDescription
successbooleanyesOperation success status

Source: apps/api/openapi.json.