fix(19): CR-04 scope login lockout to username, add TTL auto-expiry + admin-reset unlock
This commit is contained in:
@@ -35,6 +35,7 @@ import {
|
||||
CredentialValidationError,
|
||||
} from '../broker/credentialSync.js';
|
||||
import { hashPassword } from '../auth/localCredentials.js';
|
||||
import { resetLoginAttempts } from './localAuth.js';
|
||||
import { COLOR_PALETTE } from '../auth/user.js';
|
||||
// Side-effect import: brings in the ContextVariableMap augmentation for c.get('user')
|
||||
import '../auth/devBypass.js';
|
||||
@@ -220,9 +221,10 @@ adminRouter.post(
|
||||
const { newPassword } = c.req.valid('json');
|
||||
// T-19-06: NEVER log newPassword or the request body
|
||||
|
||||
// Verify the target user has a local_credentials row (404 if not)
|
||||
// Verify the target user has a local_credentials row (404 if not).
|
||||
// Also read the username so we can clear any login lockout for it (CR-04).
|
||||
const [credRow] = await db
|
||||
.select({ id: localCredentials.id })
|
||||
.select({ id: localCredentials.id, username: localCredentials.username })
|
||||
.from(localCredentials)
|
||||
.where(eq(localCredentials.userId, targetId))
|
||||
.limit(1);
|
||||
@@ -237,6 +239,11 @@ adminRouter.post(
|
||||
.set({ passwordHash: hashPassword(newPassword) })
|
||||
.where(eq(localCredentials.userId, targetId));
|
||||
|
||||
// CR-04: an admin password reset must immediately clear any rate-limit / lockout
|
||||
// state for this username, so a locked-out member regains access at once rather than
|
||||
// waiting for the TTL. The lockout is keyed on username (not member id).
|
||||
resetLoginAttempts(credRow.username);
|
||||
|
||||
return c.json({ ok: true }, 200);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
|
||||
Reference in New Issue
Block a user