u
This commit is contained in:
@@ -11,6 +11,7 @@ import env from '../config/env.js';
|
||||
import { authMiddleware } from './middleware/auth.js';
|
||||
import { ensureConnection } from '../db/store.js';
|
||||
import { closeAll as closeAllSse } from './sse.js';
|
||||
import { closeAllManagers } from '../services/conversationManager.js';
|
||||
import { getOrCreateCert } from '../util/cert.js';
|
||||
import v1Router from '../v1/index.js';
|
||||
|
||||
@@ -47,6 +48,16 @@ let startedAt;
|
||||
function corsMiddleware(req, res, next) {
|
||||
const origin = req.headers.origin;
|
||||
|
||||
if (req.path.startsWith('/api/public') || req.path.startsWith('/public')) {
|
||||
res.setHeader('Access-Control-Allow-Origin', origin || '*');
|
||||
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET,OPTIONS');
|
||||
if (req.method === 'OPTIONS') {
|
||||
return res.sendStatus(204);
|
||||
}
|
||||
return next();
|
||||
}
|
||||
|
||||
if (origin && env.corsOrigins.includes(origin)) {
|
||||
res.setHeader('Access-Control-Allow-Origin', origin);
|
||||
res.setHeader('Vary', 'Origin');
|
||||
@@ -66,8 +77,8 @@ async function createApi() {
|
||||
const app = express();
|
||||
|
||||
app.use((req, res, next) => {
|
||||
// Do not attach no-store to SSE endpoint
|
||||
if (req.path !== '/api/events') {
|
||||
// Do not attach no-store to SSE or public endpoints
|
||||
if (req.path !== '/api/events' && !req.path.startsWith('/api/public') && !req.path.startsWith('/public')) {
|
||||
res.setHeader('Cache-Control', 'no-store');
|
||||
}
|
||||
next();
|
||||
@@ -89,14 +100,20 @@ async function createApi() {
|
||||
app.use('/v1', v1Router);
|
||||
app.use('/api/v1', v1Router);
|
||||
|
||||
app.use((err, _req, res, next) => {
|
||||
app.use((_req, res) => {
|
||||
res.status(404).json({ error: 'Not found' });
|
||||
});
|
||||
|
||||
app.use((err, _req, res, _next) => {
|
||||
if (err.type === 'entity.too.large') {
|
||||
return res.status(413).json({ error: 'Payload too large' });
|
||||
}
|
||||
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
|
||||
return res.status(400).json({ error: 'Invalid JSON body' });
|
||||
}
|
||||
next(err);
|
||||
console.error('Unhandled API error:', err);
|
||||
const status = typeof err.status === 'number' && err.status >= 400 && err.status < 600 ? err.status : 500;
|
||||
res.status(status).json({ error: err.message || 'Internal server error' });
|
||||
});
|
||||
|
||||
return app;
|
||||
@@ -174,6 +191,7 @@ export async function stopApi() {
|
||||
// Long-lived SSE (and keep-alive) sockets otherwise block server.close()
|
||||
// forever — node --watch hangs on "Waiting for graceful termination...".
|
||||
closeAllSse();
|
||||
closeAllManagers();
|
||||
const closers = [];
|
||||
if (server) {
|
||||
const s = server;
|
||||
|
||||
Reference in New Issue
Block a user