feat(landing): self-serve registration page via Drasl API (B1)
Add a static /register page (en/es/eu) that calls the Drasl REST API v2 directly from the browser: register -> login -> optional skin upload, all in the pixel design. Guests never touch Drasl's own web UI. Drasl config gains the pieces this needs: - CORSAllowOrigins scoped to the apex (the API has no CORS until set; never "*"). - [RateLimit] for the now public-facing anonymous POST /users. - [RegistrationNewPlayer] with RequireInvite driven by a new REGISTRATION_MODE (invite|open) .env flag. REGISTRATION_MODE has two consumers from one key: render-config.sh derives the TOML boolean for Drasl (drasl is TOML-only, no env), and the landing build reads it to show/hide the invite-code field. render-config.sh halts on any value other than invite/open. Security verified against drasl source: anonymous POST /users cannot set privileged fields (isAdmin/isLocked/chosenUuid/maxPlayerCount are gated on callerIsAdmin in CreateUser), so browser-direct registration is safe. Docs: plan/16-landing-registration.md captures the design + the B1 vs fork decision; build-order, deploy, and the deploy skill wire REGISTRATION_MODE and the landing-rebuild requirement (www/ is gitignored, not updated by a git pull). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# render-config.sh — turn *.tmpl files into real configs via envsubst.
|
||||
# Substitutes ONLY ${BASE_DOMAIN} so literal $-syntax that belongs to the target
|
||||
# file (caddy, toml) is left untouched.
|
||||
# Substitutes ONLY a small whitelist so literal $-syntax that belongs to the
|
||||
# target file (caddy, toml) is left untouched.
|
||||
# Halts on any unset var or missing template (cautious: no half-rendered output).
|
||||
set -euo pipefail
|
||||
|
||||
@@ -10,9 +10,19 @@ cd "$(dirname "$0")/.." # repo root
|
||||
[ -f .env ] && { set -a; . ./.env; set +a; }
|
||||
: "${BASE_DOMAIN:?BASE_DOMAIN unset (set in .env)}"
|
||||
|
||||
# REGISTRATION_MODE (invite|open) -> Drasl RequireInvite boolean. drasl is
|
||||
# TOML-only with no env support, so we derive the literal here and substitute it.
|
||||
: "${REGISTRATION_MODE:=invite}"
|
||||
case "$REGISTRATION_MODE" in
|
||||
invite) REGISTRATION_REQUIRE_INVITE=true ;;
|
||||
open) REGISTRATION_REQUIRE_INVITE=false ;;
|
||||
*) echo "REGISTRATION_MODE must be 'invite' or 'open' (got '$REGISTRATION_MODE')" >&2; exit 1 ;;
|
||||
esac
|
||||
export REGISTRATION_REQUIRE_INVITE
|
||||
|
||||
render() { # $1=template $2=output
|
||||
[ -f "$1" ] || { echo "missing template: $1" >&2; exit 1; }
|
||||
envsubst '${BASE_DOMAIN}' < "$1" > "$2"
|
||||
envsubst '${BASE_DOMAIN} ${REGISTRATION_REQUIRE_INVITE}' < "$1" > "$2"
|
||||
echo "rendered $2"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user