auth: add POST /auth/lockdown to trigger the distress lockdown
exposes the duress lockdown as an endpoint (needs the distress password in the body, rate-limited) so it can be tripped from a shortcut/webhook, not only by typing the distress password at the login form. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,7 @@ import { forgotPasswordHandler } from './forgot-password';
|
||||
import { resetPasswordHandler } from './reset-password';
|
||||
import { bootstrapHandler } from './bootstrap';
|
||||
import { usersMe } from './users-me';
|
||||
import { lockdownHandler } from './lockdown';
|
||||
import { passkeyRouter } from './passkey-router';
|
||||
|
||||
export const authRouter = createRouter();
|
||||
@@ -34,6 +35,8 @@ authRouter.post('/signin', signinRateLimiter, signinHandler);
|
||||
authRouter.post('/signout', userMiddleware, signoutHandler);
|
||||
// Explicit "revoke the current token" alias (same effect as signout: blacklists this JWT).
|
||||
authRouter.post('/blacklist-token', userMiddleware, signoutHandler);
|
||||
// Trigger the duress lockdown programmatically (needs the distress password in the body).
|
||||
authRouter.post('/lockdown', signinRateLimiter, lockdownHandler);
|
||||
authRouter.post('/signup', signupRateLimiter, signupHandler);
|
||||
authRouter.post('/bootstrap', signupRateLimiter, bootstrapHandler);
|
||||
authRouter.post('/verify', verifyHandler);
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { Handler } from 'hono';
|
||||
import * as errors from '@@/custom-errors';
|
||||
import { triggerLockdown } from './distress';
|
||||
|
||||
const { DISTRESS_PASSWORD } = process.env;
|
||||
|
||||
// Trigger the duress lockdown programmatically — same effect as entering the distress password at
|
||||
// login. Requires the distress password in the body so only its holder can trip it (rate-limited at
|
||||
// the route). Once tripped, all logins and existing sessions are refused until the server restarts.
|
||||
export const lockdownHandler: Handler = async (ctx) => {
|
||||
const { password } = ctx.get('body') as { password?: string };
|
||||
if (!DISTRESS_PASSWORD || password !== DISTRESS_PASSWORD) throw errors.UNAUTHORIZED();
|
||||
triggerLockdown();
|
||||
return ctx.json({ ok: true });
|
||||
};
|
||||
Reference in New Issue
Block a user