fix(drasl): correct admin key + CORS placement in config template

Two config keys were silently ignored by drasl (logged as "unknown config
option"), so neither took effect in production:

- `DefaultAdminUsernames` is not a drasl option; the correct top-level key is
  `DefaultAdmins`. With the wrong key, the `admin` user never got promoted —
  admin-only API routes (e.g. GET /players for the registered-players roster)
  returned 403.
- `CORSAllowOrigins` sat after the `[RegistrationNewPlayer]` table header, so
  TOML parsed it as `RegistrationNewPlayer.CORSAllowOrigins` (ignored → no CORS
  headers → landing register/account browser calls blocked). Moved it top-level,
  before any [Section], with a comment warning against re-nesting.

Verified against drasl master configuration.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 18:34:48 +02:00
parent a138bbfd72
commit 97347693b6

View File

@@ -10,7 +10,7 @@
BaseURL = "https://auth.${BASE_DOMAIN}" BaseURL = "https://auth.${BASE_DOMAIN}"
Domain = "auth.${BASE_DOMAIN}" Domain = "auth.${BASE_DOMAIN}"
ListenAddress = "0.0.0.0:25585" # internal; Caddy reverse-proxies to it ListenAddress = "0.0.0.0:25585" # internal; Caddy reverse-proxies to it
DefaultAdminUsernames = ["admin"] DefaultAdmins = ["admin"]
# Password login: admin + guests register a username/password on the web UI. # Password login: admin + guests register a username/password on the web UI.
AllowPasswordLogin = true AllowPasswordLogin = true
@@ -22,6 +22,15 @@ SignPublicKeys = false
# Free-text owner label shown in the web UI (a string, not a table). # Free-text owner label shown in the web UI (a string, not a table).
ApplicationOwner = "Ulicraft" ApplicationOwner = "Ulicraft"
# CORS: the landing register/account form (served from the apex) calls the
# Drasl API from the browser. Without this the API has NO CORS headers and the
# browser blocks every cross-origin call. Scope to the apex only — never "*",
# which would let any site script the auth API. Echo backfills AllowMethods
# (incl. PATCH/DELETE) and reflects requested headers (Content-Type/Authorization).
# MUST stay top-level (before any [Section]) — under a table it parses as
# <table>.CORSAllowOrigins and drasl ignores it (silent: no CORS headers).
CORSAllowOrigins = ["https://${BASE_DOMAIN}"]
# New-account registration (username+password). RequireInvite is derived from # New-account registration (username+password). RequireInvite is derived from
# REGISTRATION_MODE in .env by render-config.sh: invite -> true, open -> false. # REGISTRATION_MODE in .env by render-config.sh: invite -> true, open -> false.
# When true, non-admin callers (web UI + landing register form) must supply a # When true, non-admin callers (web UI + landing register form) must supply a
@@ -31,13 +40,6 @@ ApplicationOwner = "Ulicraft"
Allow = true Allow = true
RequireInvite = ${REGISTRATION_REQUIRE_INVITE} RequireInvite = ${REGISTRATION_REQUIRE_INVITE}
# CORS: the landing register/account form (served from the apex) calls the
# Drasl API from the browser. Without this the API has NO CORS headers and the
# browser blocks every cross-origin call. Scope to the apex only — never "*",
# which would let any site script the auth API. Echo backfills AllowMethods
# (incl. PATCH/DELETE) and reflects requested headers (Content-Type/Authorization).
CORSAllowOrigins = ["https://${BASE_DOMAIN}"]
# Rate limit the now public-facing API (anonymous POST /users etc). Token # Rate limit the now public-facing API (anonymous POST /users etc). Token
# bucket; admins are exempt. Conservative for a 4-10 player server. # bucket; admins are exempt. Conservative for a 4-10 player server.
[RateLimit] [RateLimit]