码桶
发现社区成员的开源项目
logout.js1.7 KB
import { jwtVerify } from 'jose';
import { logAudit } from './_audit.js';
export async function onRequestPost(context) {
const { request, env } = context;
const serverPassword = env.APP_PASSWORD;
if (!serverPassword) {
return new Response(JSON.stringify({ error: 'Server not configured.' }), {
status: 400, headers: { 'Content-Type': 'application/json' }
});
}
const kv = env.CF_DNS_KV;
const secret = new TextEncoder().encode(serverPassword);
// The user is already authenticated via the middleware (Bearer token).
// Extract username from context set by middleware.
const user = context.data.user;
const username = user ? user.username : 'unknown';
// Read refresh token from request body to revoke it
let refreshToken = null;
try {
const body = await request.json();
refreshToken = body.refreshToken;
} catch {
// Body may be empty or malformed -- that's okay, we still log out
}
if (refreshToken && kv) {
try {
const { payload } = await jwtVerify(refreshToken, secret);
if (payload.type === 'refresh' && payload.jti) {
// Store revocation with TTL of 7 days (matching refresh token lifetime)
const SEVEN_DAYS = 7 * 24 * 60 * 60;
await kv.put(`REVOKED_RT:${payload.jti}`, 'revoked', {
expirationTtl: SEVEN_DAYS
});
}
} catch {
// Refresh token may be invalid or expired -- ignore, still log out
}
}
await logAudit(kv, username, 'auth.logout', 'Logged out');
return new Response(JSON.stringify({ success: true }), {
headers: { 'Content-Type': 'application/json' }
});
}