fix and update

This commit is contained in:
lendry
2026-07-01 14:34:55 +03:00
parent 55deb5c152
commit 0c9b8e2629
6 changed files with 137 additions and 19 deletions

View File

@@ -1,13 +1,18 @@
import type { Request } from 'express';
import { firstValueFrom } from 'rxjs';
import { CoreGrpcService } from '../core-grpc.service';
import { resolveFrontendUrl, resolveOAuthIssuer } from './oauth-issuer';
import {
resolveFrontendUrl,
resolveOAuthIssuer,
resolveProjectDomainApiUrl,
resolveProjectDomainFrontendUrl
} from './oauth-issuer';
import {
isLocalDevBaseUrl,
isValidFedcmEndpointUrl,
normalizePublicBaseUrl,
preferCanonicalBase,
resolveFedcmWebIdentityOrigin,
resolvePublicApiBaseFromRequest,
resolvePublicFrontendBaseFromRequest
pickBestPublicBase,
resolveFedcmWebIdentityOrigin
} from './public-url';
export interface FedcmEndpoints {
@@ -39,17 +44,44 @@ function buildFedcmEndpointUrls(issuer: string, frontendUrl: string) {
};
}
export async function resolveFedcmEndpoints(core: CoreGrpcService, req?: Request): Promise<FedcmEndpoints> {
const storedIssuer = await resolveOAuthIssuer(core);
const storedFrontend = await resolveFrontendUrl(core);
// ВАЖНО для FedCM: configUrl должен быть стабильным независимо от того, с какого
// хоста пришёл запрос. well-known запрашивается браузером всегда с eTLD+1
// (например https://idpmvk.lpr/.well-known/web-identity), а discover.json — с
// поддомена (https://sso.idpmvk.lpr/idp-api/...). Оба обязаны вернуть ОДИН и тот
// же configUrl, иначе браузер отвергнет провайдера. Поэтому берём канонический
// публичный URL из настроек, а не из текущего хоста запроса.
const issuer = preferCanonicalBase(storedIssuer, resolvePublicApiBaseFromRequest(req));
const frontendUrl = preferCanonicalBase(storedFrontend, resolvePublicFrontendBaseFromRequest(req));
async function resolveCanonicalFedcmIssuer(core: CoreGrpcService): Promise<string> {
const stored = await resolveOAuthIssuer(core);
const fromProject = await resolveProjectDomainApiUrl(core);
const issuer = pickBestPublicBase(
[stored, fromProject],
stored
);
if (isValidFedcmEndpointUrl(issuer)) {
return issuer;
}
if (fromProject && isValidFedcmEndpointUrl(fromProject)) {
return fromProject;
}
return issuer;
}
async function resolveCanonicalFedcmFrontend(core: CoreGrpcService): Promise<string> {
const stored = await resolveFrontendUrl(core);
const fromProject = await resolveProjectDomainFrontendUrl(core);
const frontend = pickBestPublicBase(
[stored, fromProject],
stored
);
if (isValidFedcmEndpointUrl(frontend) && !isLocalDevBaseUrl(frontend)) {
return frontend;
}
if (fromProject && isValidFedcmEndpointUrl(fromProject)) {
return fromProject;
}
return frontend;
}
export async function resolveFedcmEndpoints(core: CoreGrpcService, _req?: Request): Promise<FedcmEndpoints> {
// FedCM: web-identity (idpmvk.lpr) и config.json (api.idpmvk.lpr) ОБЯЗАНЫ
// возвращать одинаковые login_url / accounts_endpoint / configUrl.
// Хост запроса разный — никогда не выводим URL из req.headers.host.
const issuer = await resolveCanonicalFedcmIssuer(core);
const frontendUrl = await resolveCanonicalFedcmFrontend(core);
let projectName = 'MVK ID';
try {