- GET /auth/totp/setup returns the pending secret and otpauth URL (created on first call, reused on refresh) for the console to render as a QR code. - Enabling TOTP issues 8 one-time recovery codes (argon2id hashes in admin_recovery_code); login accepts recoveryCode in place of totpCode, disable accepts either, and recovery_codes regenerates with the password. - Passkeys via @simplewebauthn/server: register/list/rename/delete under the console session, public login options/verify that reuse the login rate limit and session cookies. Challenges are one-time rows in webauthn_challenge; RP ID and origins come from WEBAUTHN_RP_ID / WEBAUTHN_ORIGINS, falling back to the request host. Signature counter regressions are rejected. SessionInfo gains passkeyEnabled. - --role rotate-master-key re-encrypts the secret table from SECRET_MASTER_KEY to SECRET_MASTER_KEY_NEW one row per transaction, skips rows already on the new key (resumable, swap keys to roll back), logs progress and audits secret.master_key_rotate. Secrets now record the master key fingerprint in kdf_params.kid. - Runbook: recovery codes, passkey configuration, rotation steps and rollback. Co-Authored-By: Claude Opus 5.5 <[email protected]>
51 lines
1.5 KiB
JSON
51 lines
1.5 KiB
JSON
{
|
|
"name": "@umt/web",
|
|
"version": "0.2.0",
|
|
"private": true,
|
|
"type": "module",
|
|
"scripts": {
|
|
"dev": "react-router dev --host 0.0.0.0 --port 5180",
|
|
"build": "react-router build",
|
|
"preview": "vite preview --host 0.0.0.0 --port 5180",
|
|
"typecheck": "react-router typegen && tsc -p tsconfig.json",
|
|
"test": "vitest run",
|
|
"gen:tokens": "deno run -A scripts/gen-design-tokens.mjs",
|
|
"check:tokens": "deno run -A scripts/gen-design-tokens.mjs --check && sh scripts/check-design-tokens.sh"
|
|
},
|
|
"dependencies": {
|
|
"@fontsource-variable/inter-tight": "^5.2.7",
|
|
"@fontsource-variable/space-grotesk": "^5.2.10",
|
|
"@react-router/node": "7.12.0",
|
|
"@simplewebauthn/browser": "^13.3.0",
|
|
"@tanstack/react-query": "^5.90.21",
|
|
"@umt/contracts": "workspace:*",
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"date-fns": "^4.1.0",
|
|
"isbot": "^5.1.31",
|
|
"lucide-react": "^0.576.0",
|
|
"next-themes": "^0.4.6",
|
|
"qr-code-styling": "^1.9.2",
|
|
"radix-ui": "^1.4.3",
|
|
"react": "^19.2.4",
|
|
"react-day-picker": "^10.0.1",
|
|
"react-dom": "^19.2.4",
|
|
"react-router": "7.12.0",
|
|
"recharts": "^3.10.1",
|
|
"sonner": "^2.0.7",
|
|
"tailwind-merge": "^3.5.0",
|
|
"zod": "^4.3.6"
|
|
},
|
|
"devDependencies": {
|
|
"@react-router/dev": "7.12.0",
|
|
"@tailwindcss/vite": "^4.1.13",
|
|
"@types/react": "^19.2.7",
|
|
"@types/react-dom": "^19.2.3",
|
|
"shadcn": "^3.8.5",
|
|
"tailwindcss": "^4.1.13",
|
|
"tw-animate-css": "^1.4.0",
|
|
"vite": "^7.1.7",
|
|
"vite-tsconfig-paths": "^5.1.4"
|
|
}
|
|
}
|