fix and update
This commit is contained in:
@@ -3,11 +3,8 @@ import { firstValueFrom } from 'rxjs';
|
||||
import { CoreGrpcService } from '../core-grpc.service';
|
||||
import { resolveFrontendUrl, resolveOAuthIssuer } from './oauth-issuer';
|
||||
import {
|
||||
hostsMatch,
|
||||
normalizePublicBaseUrl,
|
||||
preferBrowserReachableBase,
|
||||
readRequestHost,
|
||||
readRequestProto,
|
||||
preferCanonicalBase,
|
||||
resolvePublicApiBaseFromRequest,
|
||||
resolvePublicFrontendBaseFromRequest
|
||||
} from './public-url';
|
||||
@@ -47,76 +44,17 @@ function buildFedcmEndpointUrls(issuer: string, frontendUrl: string) {
|
||||
};
|
||||
}
|
||||
|
||||
function resolveSameOriginFrontend(storedFrontend: string, req?: Request): string {
|
||||
const fromRequest = resolvePublicFrontendBaseFromRequest(req);
|
||||
const preferred = preferBrowserReachableBase(storedFrontend, fromRequest);
|
||||
if (preferred !== storedFrontend) {
|
||||
return preferred;
|
||||
}
|
||||
|
||||
const host = readRequestHost(req);
|
||||
if (!host) {
|
||||
return storedFrontend;
|
||||
}
|
||||
|
||||
const requestOrigin = normalizePublicBaseUrl(`${readRequestProto(req)}://${host}`);
|
||||
|
||||
try {
|
||||
const frontendUrl = new URL(storedFrontend);
|
||||
const requestUrl = new URL(requestOrigin);
|
||||
|
||||
if (hostsMatch(frontendUrl.hostname, requestUrl.hostname)) {
|
||||
return requestOrigin;
|
||||
}
|
||||
} catch {
|
||||
return storedFrontend;
|
||||
}
|
||||
|
||||
return storedFrontend;
|
||||
}
|
||||
|
||||
export function resolveSameOriginIssuer(storedIssuer: string, storedFrontend: string, req?: Request): string {
|
||||
const fromRequest = resolvePublicApiBaseFromRequest(req);
|
||||
const preferred = preferBrowserReachableBase(storedIssuer, fromRequest);
|
||||
if (preferred !== storedIssuer) {
|
||||
return preferred;
|
||||
}
|
||||
|
||||
const host = readRequestHost(req);
|
||||
if (!host) {
|
||||
return storedIssuer;
|
||||
}
|
||||
|
||||
const requestOrigin = normalizePublicBaseUrl(`${readRequestProto(req)}://${host}`);
|
||||
const sameOriginApi = `${requestOrigin}/idp-api`;
|
||||
|
||||
try {
|
||||
const issuerUrl = new URL(storedIssuer);
|
||||
const frontendUrl = new URL(storedFrontend);
|
||||
const requestUrl = new URL(requestOrigin);
|
||||
|
||||
const hostMatches =
|
||||
hostsMatch(issuerUrl.hostname, requestUrl.hostname) || hostsMatch(frontendUrl.hostname, requestUrl.hostname);
|
||||
|
||||
if (!hostMatches) {
|
||||
return storedIssuer;
|
||||
}
|
||||
|
||||
if (normalizePublicBaseUrl(storedIssuer) !== sameOriginApi) {
|
||||
return sameOriginApi;
|
||||
}
|
||||
} catch {
|
||||
return fromRequest ?? storedIssuer;
|
||||
}
|
||||
|
||||
return storedIssuer;
|
||||
}
|
||||
|
||||
export async function resolveFedcmEndpoints(core: CoreGrpcService, req?: Request): Promise<FedcmEndpoints> {
|
||||
const storedIssuer = await resolveOAuthIssuer(core);
|
||||
const storedFrontend = await resolveFrontendUrl(core);
|
||||
const frontendUrl = resolveSameOriginFrontend(storedFrontend, req);
|
||||
const issuer = resolveSameOriginIssuer(storedIssuer, storedFrontend, req);
|
||||
// ВАЖНО для 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));
|
||||
let projectName = 'MVK ID';
|
||||
|
||||
try {
|
||||
|
||||
@@ -94,6 +94,25 @@ export function resolvePublicFrontendBaseFromRequest(req?: Request): string | nu
|
||||
return resolvePublicOriginFromRequest(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает канонический публичный base-URL для FedCM.
|
||||
*
|
||||
* FedCM требует, чтобы well-known файл (всегда запрашивается с eTLD+1, например
|
||||
* idpmvk.lpr) и discover.json (запрашивается с поддомена sso.idpmvk.lpr)
|
||||
* возвращали ОДИН и тот же configUrl. Поэтому здесь приоритет всегда у значения
|
||||
* из настроек (PUBLIC_API_URL / PUBLIC_FRONTEND_URL), а на хост запроса
|
||||
* переключаемся только если в настройках указан внутренний Docker-хост.
|
||||
*/
|
||||
export function preferCanonicalBase(stored: string, fromRequest: string | null) {
|
||||
if (stored && isBrowserReachableBaseUrl(stored)) {
|
||||
return normalizePublicBaseUrl(stored);
|
||||
}
|
||||
if (fromRequest && isBrowserReachableBaseUrl(fromRequest)) {
|
||||
return normalizePublicBaseUrl(fromRequest);
|
||||
}
|
||||
return normalizePublicBaseUrl(stored);
|
||||
}
|
||||
|
||||
export function preferBrowserReachableBase(stored: string, fromRequest: string | null) {
|
||||
if (fromRequest && isBrowserReachableBaseUrl(fromRequest)) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user