From dce16af5a5aa2498a1930e66d9cf66c50fe83228 Mon Sep 17 00:00:00 2001 From: lendry Date: Wed, 1 Jul 2026 12:05:34 +0300 Subject: [PATCH] fix and update --- .../src/controllers/well-known.controller.ts | 5 ++-- apps/api-gateway/src/lib/fedcm-cors.ts | 27 ++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/apps/api-gateway/src/controllers/well-known.controller.ts b/apps/api-gateway/src/controllers/well-known.controller.ts index 9439da3..68b96d6 100644 --- a/apps/api-gateway/src/controllers/well-known.controller.ts +++ b/apps/api-gateway/src/controllers/well-known.controller.ts @@ -3,7 +3,6 @@ import { ApiOperation, ApiTags } from '@nestjs/swagger'; import type { Request, Response } from 'express'; import { CoreGrpcService } from '../core-grpc.service'; import { buildFedcmWebIdentityManifest, resolveFedcmEndpoints } from '../lib/fedcm-config'; -import { assertFedcmWebIdentityRequest } from '../lib/fedcm-cors'; import { buildOpenIdConfiguration, resolveOAuthIssuer } from '../lib/oauth-issuer'; @ApiTags('OpenID Connect') @@ -17,9 +16,11 @@ export class WellKnownController { description: 'Манифест Federated Credential Management API, указывающий на конфигурацию провайдера.' }) async webIdentity(@Req() req: Request, @Res({ passthrough: true }) res: Response) { - assertFedcmWebIdentityRequest(req); + // Публичный discovery-манифест: без Sec-Fetch-Dest проверки (браузер FedCM шлёт + // webidentity или empty; ручной заход с document не должен ломать One Tap). res.setHeader('Content-Type', 'application/json; charset=utf-8'); res.setHeader('Cache-Control', 'public, max-age=300'); + res.setHeader('Access-Control-Allow-Origin', '*'); const endpoints = await resolveFedcmEndpoints(this.core, req); return buildFedcmWebIdentityManifest(endpoints); } diff --git a/apps/api-gateway/src/lib/fedcm-cors.ts b/apps/api-gateway/src/lib/fedcm-cors.ts index fc03658..2aa8cfa 100644 --- a/apps/api-gateway/src/lib/fedcm-cors.ts +++ b/apps/api-gateway/src/lib/fedcm-cors.ts @@ -33,9 +33,34 @@ export function applyFedcmPreflightHeaders(res: Response, origin?: string) { res.setHeader('Access-Control-Max-Age', '86400'); } +/** + * FedCM-запросы должны иметь Sec-Fetch-Dest: webidentity (или empty, если прокси + * не пробрасывает заголовок). Блокируем только явно «не-FedCM» dest (document, + * script, image…) — иначе well-known/config отдают 400 и One Tap ломается. + */ +const BLOCKED_FEDCM_FETCH_DEST = new Set([ + 'document', + 'embed', + 'frame', + 'iframe', + 'object', + 'script', + 'style', + 'image', + 'font', + 'audio', + 'video', + 'track', + 'worker', + 'serviceworker', + 'sharedworker', + 'manifest', + 'xslt' +]); + export function assertFedcmWebIdentityRequest(req: Request) { const dest = String(req.headers['sec-fetch-dest'] ?? '').toLowerCase(); - if (dest && dest !== 'webidentity') { + if (dest && BLOCKED_FEDCM_FETCH_DEST.has(dest)) { throw new BadRequestException('Недопустимый Sec-Fetch-Dest для FedCM'); } }