Add 2FA, email + password reset, and batch-7 pages

Auth (hand-built on the auth core):
- 2FA: User model gains two_factor_secret/recovery_codes/confirmed_at (+ idempotent
  MariaDB migration). authorize() requires a valid TOTP code when 2FA is confirmed
  (secret decrypted via Laravel APP_KEY, fail-closed). Two-step login (precheckLogin
  reveals the code field). /settings/2fa enable/confirm/disable flow.
- Password reset: nodemailer email service; PasswordReset model + migration;
  /forgot (request, generic response) + /reset (token sha256 + 1h TTL, sets argon2id
  hash). Login links to forgot.

Batch 7 (parallel agents): /admin/commandocentrum (RCON controls + emulator_errors),
social write actions (friend request + guild forum new thread), /help/[category],
/badges (public). env: APP_KEY, APP_URL, SMTP_*. Nav extended.

Verified: tsc exit 0, vitest 48/48, next build exit 0 (64 page routes).
This commit is contained in:
Simo committed 2026-06-28 14:25:19 +02:00
1 parent 486ce51559
commit e668fa85ec
24 files changed
+1223 -34

No files matched your search

+27 -4
View File
@@ -25,7 +25,10 @@ importers:
version: 16.2.9([email protected]([email protected]))([email protected])
next-auth:
specifier: 5.0.0-beta.31
version: 5.0.0-beta.31([email protected]([email protected]([email protected]))([email protected]))([email protected])
version: 5.0.0-beta.31([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected])
nodemailer:
specifier: ^6.9.0
version: 6.10.1
otplib:
specifier: ^12.0.1
version: 12.0.1
@@ -42,6 +45,9 @@ importers:
'@types/node':
specifier: ^22.10.0
version: 22.20.0
'@types/nodemailer':
specifier: ^6.4.0
version: 6.4.24
'@types/react':
specifier: ^19.2.0
version: 19.2.17
@@ -1240,6 +1246,9 @@ packages:
'@types/[email protected]':
resolution: {integrity: sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==}
'@types/[email protected]':
resolution: {integrity: sha512-Ww4u0rT9wQNXh4JiQaIwx3QWdcOFXzOjQA2zc+jtFYNmQiT4mIUqcDin51bDFdkzKubFnQCZNK7FIHlPKQ/q9w==}
'@types/[email protected]':
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
peerDependencies:
@@ -1694,6 +1703,10 @@ packages:
sass:
optional: true
[email protected]:
resolution: {integrity: sha512-Z+iLaBGVaSjbIzQ4pX6XV41HrooLsQ10ZWPUehGmuantvzWoDVBnmsdUcOIDM1t+yPor5pDhVlDESgOMEGxhHA==}
engines: {node: '>=6.0.0'}
[email protected]:
resolution: {integrity: sha512-iwemM91xz8nryHti2yTmg5fhyEMVOkOXwHNqbvcATjyajb5oQxCQzrNOA6uElRHuMhQQTKUyFKV9y/CNyg25BQ==}
@@ -2011,13 +2024,15 @@ packages:
snapshots:
'@auth/[email protected]':
'@auth/[email protected]([email protected])':
dependencies:
'@panva/hkdf': 1.2.1
jose: 6.2.3
oauth4webapi: 3.8.6
preact: 10.24.3
preact-render-to-string: 6.5.11([email protected])
optionalDependencies:
nodemailer: 6.10.1
'@drizzle-team/[email protected]': {}
@@ -2730,6 +2745,10 @@ snapshots:
dependencies:
undici-types: 7.18.2
'@types/[email protected]':
dependencies:
'@types/node': 22.20.0
'@types/[email protected](@types/[email protected])':
dependencies:
'@types/react': 19.2.17
@@ -3136,11 +3155,13 @@ snapshots:
[email protected]: {}
[email protected]([email protected]([email protected]([email protected]))([email protected]))([email protected]):
[email protected]([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected]):
dependencies:
'@auth/core': 0.41.2
'@auth/core': 0.41.2([email protected])
next: 16.2.9([email protected]([email protected]))([email protected])
react: 19.2.7
optionalDependencies:
nodemailer: 6.10.1
[email protected]([email protected]([email protected]))([email protected]):
dependencies:
@@ -3166,6 +3187,8 @@ snapshots:
- '@babel/core'
- babel-plugin-macros
[email protected]: {}
[email protected]: {}
[email protected]: {}