3222bec8a5
The previous SELECT → compare → UPDATE sequence let two concurrent login requests with the same valid 6-digit code both observe a stale lastTotpAt, both pass the in-JS replay check, and both succeed. A stolen TOTP (shoulder- surf, phishing-proxy replay) was usable twice within its 30 s window. Replace the three callsites (login authorize, self-service enable, self- service verify) with a shared consumeTotpWindow() helper: a single updateMany() expresses "window unused" as a SQL WHERE clause, so Postgres' row lock serialises concurrent writers and whichever commits second sees count=0 and is treated as a replay. Backup codes (ticket part 2) are tracked as follow-up work. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
47 lines
1.4 KiB
JSON
47 lines
1.4 KiB
JSON
{
|
|
"name": "@capakraken/api",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"type": "module",
|
|
"exports": {
|
|
".": "./src/index.ts",
|
|
"./router": "./src/router/index.ts",
|
|
"./trpc": "./src/trpc.ts",
|
|
"./sse": "./src/sse/index.ts",
|
|
"./lib/audit": "./src/lib/audit.ts",
|
|
"./lib/reminder-scheduler": "./src/lib/reminder-scheduler.ts",
|
|
"./lib/logger": "./src/lib/logger.ts",
|
|
"./lib/runtime-security": "./src/lib/runtime-security.ts",
|
|
"./lib/totp-consume": "./src/lib/totp-consume.ts",
|
|
"./middleware/rate-limit": "./src/middleware/rate-limit.ts"
|
|
},
|
|
"scripts": {
|
|
"typecheck": "tsc --noEmit",
|
|
"test:unit": "vitest run",
|
|
"test:assistant-split": "node ./scripts/run-assistant-tool-split-regression.mjs"
|
|
},
|
|
"dependencies": {
|
|
"@capakraken/application": "workspace:*",
|
|
"@capakraken/db": "workspace:*",
|
|
"@capakraken/engine": "workspace:*",
|
|
"@capakraken/shared": "workspace:*",
|
|
"@capakraken/staffing": "workspace:*",
|
|
"@node-rs/argon2": "^2.0.2",
|
|
"@trpc/server": "^11.0.0",
|
|
"@types/nodemailer": "^7.0.11",
|
|
"ioredis": "^5.10.0",
|
|
"nodemailer": "^8.0.5",
|
|
"openai": "^6.27.0",
|
|
"otpauth": "^9.5.0",
|
|
"pino": "^10.3.1",
|
|
"zod": "^3.23.8"
|
|
},
|
|
"devDependencies": {
|
|
"@capakraken/tsconfig": "workspace:*",
|
|
"@types/node": "^22.10.2",
|
|
"typescript": "^5.6.3",
|
|
"vitest": "^2.1.8",
|
|
"@vitest/coverage-v8": "^2.1.9"
|
|
}
|
|
}
|