mirror of
https://github.com/velocitatem/cvfs.git
synced 2026-05-31 08:43:37 +00:00
Middleware runs in Edge Runtime (no Node.js built-ins), so use
globalThis.crypto.subtle for HMAC verification. Route handler uses
`import { createHmac } from 'crypto'` without the node: prefix
which webpack cannot resolve during Next.js build.
https://claude.ai/code/session_01CdisLhbC2kVt2hxfJ7TNPf
30 lines
1.3 KiB
TypeScript
30 lines
1.3 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
|
|
const SECRET = process.env.SESSION_SECRET ?? 'dev-secret-change-in-production';
|
|
|
|
async function verifySession(token: string): Promise<boolean> {
|
|
const lastDot = token.lastIndexOf('.');
|
|
if (lastDot === -1) return false;
|
|
const payload = token.slice(0, lastDot);
|
|
const sigHex = token.slice(lastDot + 1);
|
|
try {
|
|
const key = await globalThis.crypto.subtle.importKey(
|
|
'raw', new TextEncoder().encode(SECRET),
|
|
{ name: 'HMAC', hash: 'SHA-256' }, false, ['verify'],
|
|
);
|
|
const sigBytes = new Uint8Array((sigHex.match(/.{1,2}/g) ?? []).map(b => parseInt(b, 16)));
|
|
return await globalThis.crypto.subtle.verify('HMAC', key, sigBytes, new TextEncoder().encode(payload));
|
|
} catch { return false; }
|
|
}
|
|
|
|
export async function middleware(req: NextRequest) {
|
|
if (!req.nextUrl.pathname.startsWith('/dashboard')) return NextResponse.next();
|
|
const session = req.cookies.get('session')?.value;
|
|
const oidc = req.cookies.get('oidc_token')?.value;
|
|
if (oidc) return NextResponse.next();
|
|
if (session && await verifySession(session)) return NextResponse.next();
|
|
return NextResponse.redirect(new URL('/login', req.url));
|
|
}
|
|
|
|
export const config = { matcher: ['/dashboard/:path*'] };
|