chore: improve cors

This commit is contained in:
DarkSky
2026-02-24 00:51:08 +08:00
parent 744c78abbb
commit e617740974
2 changed files with 44 additions and 17 deletions

View File

@@ -6,6 +6,8 @@ import { TelemetryDeduper } from './deduper';
import { Ga4Client } from './ga4-client'; import { Ga4Client } from './ga4-client';
import { TelemetryAck, TelemetryBatch } from './types'; import { TelemetryAck, TelemetryBatch } from './types';
const TELEMETRY_ROUTE_PATTERN = /\/api\/telemetry(?:\/|$)/;
@Injectable() @Injectable()
export class TelemetryService { export class TelemetryService {
private readonly logger = new Logger(TelemetryService.name); private readonly logger = new Logger(TelemetryService.name);
@@ -71,6 +73,13 @@ export class TelemetryService {
return false; return false;
} }
getAllowedOrigins(routePath?: string): string[] {
if (routePath && TELEMETRY_ROUTE_PATTERN.test(routePath)) {
return [...this.allowedOrigins];
}
return [];
}
async collectBatch(batch: TelemetryBatch): Promise<TelemetryAck> { async collectBatch(batch: TelemetryBatch): Promise<TelemetryAck> {
if (!batch || batch.schemaVersion !== 1 || !Array.isArray(batch.events)) { if (!batch || batch.schemaVersion !== 1 || !Array.isArray(batch.events)) {
return { return {

View File

@@ -18,9 +18,11 @@ import {
} from './base'; } from './base';
import { SocketIoAdapter } from './base/websocket'; import { SocketIoAdapter } from './base/websocket';
import { AuthGuard } from './core/auth'; import { AuthGuard } from './core/auth';
import { TelemetryService } from './core/telemetry/service';
import { serverTimingAndCache } from './middleware/timing'; import { serverTimingAndCache } from './middleware/timing';
const OneMB = 1024 * 1024; const OneMB = 1024 * 1024;
export async function run() { export async function run() {
const { AppModule } = await import('./app.module'); const { AppModule } = await import('./app.module');
@@ -37,17 +39,32 @@ export async function run() {
app.useLogger(logger); app.useLogger(logger);
const config = app.get(Config); const config = app.get(Config);
const url = app.get(URLHelper); const url = app.get(URLHelper);
let telemetry: TelemetryService | null = null;
try {
telemetry = app.get(TelemetryService, { strict: false });
} catch {
telemetry = null;
}
const allowedOrigins = buildCorsAllowedOrigins(url); const defaultAllowedOrigins = buildCorsAllowedOrigins(url);
app.enableCors({ app.enableCors((req, callback) => {
origin: (origin, callback) => { const requestPath = req.path ?? req.url ?? '';
const appendedOrigins = telemetry?.getAllowedOrigins(requestPath) ?? [];
const finalAllowedOrigins = appendedOrigins.length
? new Set([...defaultAllowedOrigins, ...appendedOrigins])
: defaultAllowedOrigins;
callback(null, {
origin: (origin, originCallback) => {
corsOriginCallback( corsOriginCallback(
origin, origin,
allowedOrigins, finalAllowedOrigins,
blockedOrigin => blockedOrigin =>
logger.warn(`Blocked CORS request from origin: ${blockedOrigin}`), logger.warn(`Blocked CORS request from origin: ${blockedOrigin}`, {
callback requestPath,
}),
originCallback
); );
}, },
credentials: true, credentials: true,
@@ -57,6 +74,7 @@ export async function run() {
maxAge: 86400, maxAge: 86400,
optionsSuccessStatus: 204, optionsSuccessStatus: 204,
}); });
});
if (config.server.path) { if (config.server.path) {
app.setGlobalPrefix(config.server.path); app.setGlobalPrefix(config.server.path);