feat(web-ui): CMaNGOS web management interface - #44
Conversation
… all cores, open v-serialization question
…S AsHexStr Session-1 assumption (little-endian reversed hex) was wrong: AccountMgr stores BN_bn2hex(v)/BN_bn2hex(s) — big-endian, uppercase, unpadded — and realmd parses with BN_hex2bn. A little-endian row would be undetectable until a retail client failed to log in. x computation (LE salt || LE h1, digest read big-endian) confirmed correct against SRP6.cpp. Known vector ADMIN/ADMIN verified independently with Python hashlib/pow: 28AE3C33...157BB. Salt now emitted uppercase to match BN_bn2hex. 7 bun tests pass.
…register-flow reference notes
…resolution - server/database/schema.ts: faithful descriptors for realmd.account, realmlist, uptime, characters (DDL verified upstream 2026-08-26); descriptors only, no migrations ever - server/database/config.ts: pure resolveCmangosConfig — derives <core>realmd/<core>characters, errors name the exact NUXT_* vars - server/database/client.ts: lazy mysql2 pools cached on globalThis - drizzle-orm 0.45.2 + mysql2 3.24.2; 8 new unit tests (17 total pass)
- server/utils/auth.ts: SRP6a auth adapter (create + verify credentials), BN_hex2bn-tolerant comparison, legacy-sha_pass_hash seam documented - server/utils/validation.ts: registration input validation, uppercases username per CMaNGOS convention, rules from WoWSimpleRegistration ref - test/auth.test.ts + test/validation.test.ts: 13 new tests, all pass (49 total across 4 suites) Phase 1 steps 6 (partial) and 5-adjacent: adapter + validation ready; next: POST /api/auth/register endpoint, then login/logout/me, then server status, then BlizzLike shell.
…ealed-cookie sessions - POST /api/auth/register: validate, check duplicate username, compute SRP6 credentials, INSERT into realmd.account via Drizzle - POST /api/auth/login: verify SRP6 v against submitted password, open sealed cookie session (h3 useSession), reject locked accounts - POST /api/auth/logout: clear session cookie - GET /api/auth/me: return session identity without DB read - server/utils/session.ts: thin wrapper over h3 useSession with config-driven password, maxAge, httpOnly/Lax/secure cookie attributes - schema.ts: document joindate as DB-owned, remove .defaultNow() drift - srp6.ts: defensive copy before crypto.subtle.digest (SharedArrayBuffer guard) - bun-types devDependency + tsconfig files for stricter type checking - test type annotations tightened All 49 tests pass. Build completes. Live DB round-trip untested on dev box (no docker/mysql); must be verified on homelab.
…s, known type issues
Phase 1 backend — complete (sessions 3–5)The whole server-side surface of Phase 1 is now on this branch:
Testing: 49 bun unit tests green (srp6, config, auth, validation); Nuxt build green. Two known type-only issues, queued for the next session: Remaining for Phase 1: the BlizzLike frontend shell (layout, palette, register/login/status pages). |
… CmangosCore - schema.ts: mirror DDL DEFAULT NOW() via .default(sql`NOW()`) so the insert type treats joindate as optional (Drizzle omits it at runtime; MariaDB applies its own default). Descriptors-only invariant kept. - tsconfig.json: opt into bun-types (Nuxt's generated config sets types: []), fixing bun:test resolution in test files. - auth.test.ts: type the test.each param as CmangosCore. vue-tsc --noEmit clean, 49/49 tests pass, build green.
… status Design system recreated from scratch in pure CSS (no Blizzard assets, no copied code/values — celguar/spp-classics visual reference only). App shell with auth-aware header, useAuth composable, ServerStatus widget (30s client poll, offline reason from details block), landing/login/register pages with per-field server errors. NOTE: build/vue-tsc verification of these files is PENDING (session cut short) — queued as first task of session 7, see PLAN.md.
|
Phase 1 complete — user side, read-mostly, backend + frontend shell. This batch (3 commits,
Verification (dev box, no DB): Still untested, as flagged before: every DB round-trip against live MariaDB (register INSERT, login verify, status queries). No docker/mysql on this box — the first homelab run must exercise register → login → status end to end. The dedicated least-privilege DB user (SELECT broadly, INSERT/UPDATE only on Decisions taken on your behalf, full list in PLAN.md (session 6): single-realm assumption (first Phase 1 done. Remaining per PLAN.md: Phase 2 (self-service), Phase 3 (admin — blocked on #27), Phase 4 (packaging: Dockerfile, compose profile, least-privilege provisioning, docs page after #43 merges). |
The "Create account" nav link reuses the hero .btn style (gold background), but .site-nav a / a:hover / a.router-link-active overrode its text color with --mist / --gold-bright — mist-on-gold, illegible. Scope the nav rules with :not(.btn) so buttons keep their own colors, per review of PR Byloth#44. No !important.
|
Review fix pushed (49db4e9): the .site-nav color rules are now scoped :not(.btn) — the nav Create account button keeps its own dark-on-gold colors and typography again, and hover/active states come from .btn itself. No !important used. Verified: 49/49 tests, vue-tsc clean, build green, production SSR smoke renders the header correctly. |
Work in progress — Nuxt 4.5.2 scaffold, SRP6 auth foundation, and action plan for the full web UI.
See issue #6 for context and PLAN.md in this branch for the roadmap.