Files

35 lines
1.3 KiB
TypeScript

import { timingSafeEqual } from 'node:crypto';
import type { NextRequest } from 'next/server';
export const LEARNING_ENGINE_TOKEN_ENV = 'LEARNING_ENGINE_TOKEN';
export const LEGACY_LEARNING_ENGINE_TOKEN_ENV = 'MAKELORE_RUNTIME_TOKEN';
/**
* Server-to-server credential for the private Learning Engine API.
*
* LEARNING_ENGINE_TOKEN is the canonical deployment name shared with Works
* Square. MAKELORE_RUNTIME_TOKEN remains a migration alias so existing private
* deployments can rotate without downtime.
*/
export function configuredLearningRuntimeToken(): string | undefined {
return (
process.env[LEARNING_ENGINE_TOKEN_ENV]?.trim() ||
process.env[LEGACY_LEARNING_ENGINE_TOKEN_ENV]?.trim() ||
undefined
);
}
export function authorizeLearningRuntime(request: NextRequest): boolean {
const expected = configuredLearningRuntimeToken();
const header = request.headers.get('authorization') || '';
const received = header.startsWith('Bearer ') ? header.slice(7).trim() : '';
if (!expected || !received) return false;
const expectedBytes = Buffer.from(expected);
const receivedBytes = Buffer.from(received);
return expectedBytes.length === receivedBytes.length && timingSafeEqual(expectedBytes, receivedBytes);
}
export function runtimeUnauthorized(): Response {
return Response.json({ error: 'unauthorized' }, { status: 401 });
}