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:
@@ -4,6 +4,10 @@
|
||||
// BASE_DOMAIN is read at build time; falls back to ulicraft.local.
|
||||
const BASE_DOMAIN = process.env.BASE_DOMAIN ?? "ulicraft.local";
|
||||
|
||||
// REGISTRATION_MODE (invite|open) is read at build time, same .env as Drasl's
|
||||
// render-config.sh. "invite" => the register form must collect an invite code.
|
||||
const REGISTRATION_MODE = process.env.REGISTRATION_MODE ?? "invite";
|
||||
|
||||
// Minecraft / pack facts, surfaced in a few places.
|
||||
const MC_VERSION = "1.21.1";
|
||||
|
||||
@@ -12,6 +16,11 @@ export const site = {
|
||||
baseDomain: BASE_DOMAIN,
|
||||
mcVersion: MC_VERSION,
|
||||
|
||||
// Register form behaviour, driven by REGISTRATION_MODE in .env.
|
||||
// true => show the invite-code field (Drasl RequireInvite = true)
|
||||
// false => open self-registration
|
||||
registrationRequiresInvite: REGISTRATION_MODE === "invite",
|
||||
|
||||
// Design knobs (replace the design's in-browser TweaksPanel). Baked at build.
|
||||
// mood: "grass" | "nether" | "end"
|
||||
// hero: "centered" | "split" | "spotlight"
|
||||
@@ -30,14 +39,24 @@ export const site = {
|
||||
// Drasl auth web UI + authlib-injector API root (public HTTPS).
|
||||
authUrl: `https://auth.${BASE_DOMAIN}`,
|
||||
authlibUrl: `https://auth.${BASE_DOMAIN}/authlib-injector`,
|
||||
// Drasl REST API v2 root — the /register form calls this from the browser.
|
||||
// Requires CORSAllowOrigins to include the apex in drasl config.toml.
|
||||
draslApiUrl: `https://auth.${BASE_DOMAIN}/drasl/api/v2`,
|
||||
|
||||
// packwiz modpack entrypoint (public HTTPS, pack. subdomain).
|
||||
packwizUrl: `https://pack.${BASE_DOMAIN}/pack.toml`,
|
||||
|
||||
// Static server-list panel (Status section). No fake live count — see plan
|
||||
// 09-landing.md option B.
|
||||
// NMSR avatar renderer root. Player heads come from OUR Drasl skins, not
|
||||
// Mojang/Crafatar — head URL is `${avatarUrl}/headiso/<uuid>?size=64`.
|
||||
avatarUrl: `https://avatar.${BASE_DOMAIN}`,
|
||||
|
||||
// Live server card (ServerCard.astro). `slots` is the SSG fallback cap shown
|
||||
// before/without JS; live count comes from mcstatus.io pinging the public
|
||||
// address. mcstatus.io sets Access-Control-Allow-Origin:* → direct browser
|
||||
// fetch, no proxy/key. Uptime Kuma stays the history + alerting backend.
|
||||
status: {
|
||||
slots: 10,
|
||||
statusApi: `https://api.mcstatus.io/v2/status/java/${BASE_DOMAIN}`,
|
||||
},
|
||||
|
||||
// Honest stat tiles. Keys (numbers/versions) are language-neutral; labels
|
||||
|
||||
Reference in New Issue
Block a user