- Updated all package.json name fields and dependency references - Updated all TypeScript/JavaScript imports - Updated .woodpecker/publish.yml filters and registry paths - Updated tools/install.sh scope default - Updated .npmrc registry paths (worktree + host) - Enhanced update-checker.ts with checkForAllUpdates() multi-package support - Updated CLI update command to show table of all packages - Added KNOWN_PACKAGES, formatAllPackagesTable, getInstallAllCommand - Marked checkForUpdate() with @deprecated JSDoc Closes #391
69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
import { toNodeHandler } from 'better-auth/node';
|
|
import type { Auth } from '@mosaicstack/auth';
|
|
import type { NestFastifyApplication } from '@nestjs/platform-fastify';
|
|
import { AUTH } from './auth.tokens.js';
|
|
|
|
export function mountAuthHandler(app: NestFastifyApplication): void {
|
|
const auth = app.get<Auth>(AUTH);
|
|
const nodeHandler = toNodeHandler(auth);
|
|
const corsOrigin = process.env['GATEWAY_CORS_ORIGIN'] ?? 'http://localhost:3000';
|
|
|
|
const fastify = app.getHttpAdapter().getInstance();
|
|
|
|
// BetterAuth is mounted at the raw HTTP level via Fastify's onRequest hook,
|
|
// bypassing NestJS middleware (including CORS). We must set CORS headers
|
|
// manually on the raw response before handing off to BetterAuth.
|
|
fastify.addHook(
|
|
'onRequest',
|
|
(
|
|
req: { raw: IncomingMessage; url: string; method: string },
|
|
reply: { raw: ServerResponse; hijack: () => void },
|
|
done: () => void,
|
|
) => {
|
|
if (!req.url.startsWith('/api/auth/')) {
|
|
done();
|
|
return;
|
|
}
|
|
|
|
const origin = req.raw.headers.origin;
|
|
const allowed = corsOrigin.split(',').map((o) => o.trim());
|
|
|
|
if (origin && allowed.includes(origin)) {
|
|
reply.raw.setHeader('Access-Control-Allow-Origin', origin);
|
|
reply.raw.setHeader('Access-Control-Allow-Credentials', 'true');
|
|
reply.raw.setHeader(
|
|
'Access-Control-Allow-Methods',
|
|
'GET, POST, PUT, PATCH, DELETE, OPTIONS',
|
|
);
|
|
reply.raw.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Cookie');
|
|
}
|
|
|
|
// Handle preflight
|
|
if (req.method === 'OPTIONS') {
|
|
reply.hijack();
|
|
reply.raw.writeHead(204);
|
|
reply.raw.end();
|
|
return;
|
|
}
|
|
|
|
reply.hijack();
|
|
nodeHandler(req.raw as IncomingMessage, reply.raw as ServerResponse)
|
|
.then(() => {
|
|
if (!reply.raw.writableEnded) {
|
|
reply.raw.end();
|
|
}
|
|
})
|
|
.catch((err: unknown) => {
|
|
if (!reply.raw.headersSent) {
|
|
reply.raw.writeHead(500, { 'Content-Type': 'application/json' });
|
|
}
|
|
if (!reply.raw.writableEnded) {
|
|
reply.raw.end(JSON.stringify({ error: 'Internal auth error' }));
|
|
}
|
|
console.error('[AUTH] Handler error:', err);
|
|
});
|
|
},
|
|
);
|
|
}
|