Add WebAuthn support for admin login and kiosk mode
This commit is contained in:
@@ -11,8 +11,16 @@ type SessionPayload = {
|
||||
exp: number;
|
||||
};
|
||||
|
||||
type AdminMfaPayload = {
|
||||
uid: number;
|
||||
purpose: "admin-mfa";
|
||||
exp: number;
|
||||
};
|
||||
|
||||
export const SESSION_COOKIE = "moped_session";
|
||||
export const ADMIN_MFA_COOKIE = "moped_admin_mfa";
|
||||
const SESSION_TTL_SECONDS = 60 * 60 * 24 * 30;
|
||||
const ADMIN_MFA_TTL_SECONDS = 60 * 5;
|
||||
|
||||
function getSecretKey() {
|
||||
return new TextEncoder().encode(getAuthSecret());
|
||||
@@ -43,6 +51,41 @@ export async function clearSessionCookie() {
|
||||
(await cookies()).delete(SESSION_COOKIE);
|
||||
}
|
||||
|
||||
export async function setPendingAdminMfaCookie(userId: number) {
|
||||
const token = await new SignJWT({ uid: userId, purpose: "admin-mfa" })
|
||||
.setProtectedHeader({ alg: "HS256" })
|
||||
.setIssuedAt()
|
||||
.setExpirationTime(`${ADMIN_MFA_TTL_SECONDS}s`)
|
||||
.sign(getSecretKey());
|
||||
const cookieStore = await cookies();
|
||||
cookieStore.set(ADMIN_MFA_COOKIE, token, {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
sameSite: "lax",
|
||||
maxAge: ADMIN_MFA_TTL_SECONDS,
|
||||
path: "/",
|
||||
priority: "high",
|
||||
});
|
||||
}
|
||||
|
||||
export async function getPendingAdminMfaUserId() {
|
||||
const token = (await cookies()).get(ADMIN_MFA_COOKIE)?.value;
|
||||
if (!token) return null;
|
||||
try {
|
||||
const result = await jwtVerify(token, getSecretKey());
|
||||
const payload = result.payload as unknown as AdminMfaPayload;
|
||||
return Number.isSafeInteger(payload.uid) && payload.uid > 0 && payload.purpose === "admin-mfa"
|
||||
? payload.uid
|
||||
: null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function clearPendingAdminMfaCookie() {
|
||||
(await cookies()).delete(ADMIN_MFA_COOKIE);
|
||||
}
|
||||
|
||||
export async function getSessionUser(): Promise<SessionUser | null> {
|
||||
const token = (await cookies()).get(SESSION_COOKIE)?.value;
|
||||
if (!token) return null;
|
||||
|
||||
Reference in New Issue
Block a user