Files
CapaKraken/packages/api/package.json
Hartmut 3222bec8a5 security: atomic compare-and-swap for TOTP replay window (#43, part 1)
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>
2026-04-17 09:11:50 +02:00

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"
}
}