From 84253012c1588dbbea86e10ec722ca21aed4ad2d Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Mon, 24 Aug 2026 14:14:30 +0400 Subject: [PATCH] fix(auth): route admin/customer Telegram QR login to the shared auth origin AUTH_API_URL was wired to ApiConfigService.getBaseUrl() (the per-tenant content origin, e.g. api.gorbushka.market), so admin/customer QR-login session creation POSTed to a host with no /users/sessions route. Auth is a single shared cross-tenant service (like payment's qr.vitanova.network), not tenant-scoped - confirmed against the pre-tenant-refactor state (commit a59ffbca) where every brand's environment file carried the identical fixed authApiUrl, and against a live POST to users.vitanova.network:456/users/sessions. Restores authApiUrl as a fixed constant in both environment files and wires AUTH_API_URL/MARKETPLACES_AUTH_CONFIG.apiUrl to it, mirroring the existing qrApiUrl/provideMarketplacesPayment pattern. Also provides MARKETPLACES_AUTH_CONFIG.marketplaceDomain via TenantResolverService's existing getBaseDomain() so the X-Marketplace-Domain header stays normalized instead of falling back to raw, unnormalized location.hostname (it was never provided before, so that fallback was always in effect). No package edits, no path/method/body change, no QR/Telegram flow change. tenantApiTemplate/tenantApiBaseUrls/ApiConfigService/ TenantResolverService untouched - still drive content-API resolution only. Known remaining blocker (server-side, tracked in vitanovaPackages BACKEND-TODO.md): users.vitanova.network:456 CORS-rejects the admin.gorbushka.market origin outright (403 on preflight, no allow headers) while novo.market gets a full grant - this fix alone will not make browser login work on gorbushka domains until that origin allowlist is updated. --- src/app/app.config.ts | 27 ++++++++++++++-------- src/environments/environment.production.ts | 1 + src/environments/environment.ts | 1 + 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 5cdbe2f..00fc11a 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -8,12 +8,11 @@ import { apiErrorInterceptor } from './core/interceptors/api-error.interceptor'; import { apiBaseUrlInterceptor } from './interceptors/api-base-url.interceptor'; import { apiHeadersInterceptor } from './interceptors/api-headers.interceptor'; import { mockDataInterceptor } from './interceptors/mock-data.interceptor'; -import { adminAuthHeadersInterceptor, Ed25519VerificationService, NoopEd25519VerificationService, AUTH_API_URL, TELEGRAM_BOT_USERNAME } from '@marketplaces/auth'; +import { adminAuthHeadersInterceptor, Ed25519VerificationService, NoopEd25519VerificationService, AUTH_API_URL, TELEGRAM_BOT_USERNAME, MARKETPLACES_AUTH_CONFIG, MarketplacesAuthConfig } from '@marketplaces/auth'; import { provideMarketplacesPayment } from '@marketplaces/payment'; import { provideServiceWorker } from '@angular/service-worker'; import { MediaRepository } from './core/media/media-repository'; import { MockMediaRepository } from './core/media/mock-media-repository.service'; -import { ApiConfigService } from './core/config/api-config.service'; import { TenantResolverService } from './core/config/tenant-resolver.service'; import { environment } from '../environments/environment'; import { MOCK_GATEWAY_PROVIDERS } from './mock-gateway.providers'; @@ -31,12 +30,22 @@ export const appConfig: ApplicationConfig = { // other interceptor has run, and normalizes whatever actually came back. withInterceptors([mockDataInterceptor, apiBaseUrlInterceptor, apiHeadersInterceptor, adminAuthHeadersInterceptor, cacheInterceptor, apiErrorInterceptor]) ), - { - provide: AUTH_API_URL, - useFactory: (apiConfig: ApiConfigService) => apiConfig.getBaseUrl(), - deps: [ApiConfigService] - }, + // authApiUrl ('https://users.vitanova.network:456') is a single shared + // cross-tenant service, same shape as qrApiUrl below - NOT the per-tenant + // apiConfig.getBaseUrl(). That was the bug: AUTH_API_URL used to read the + // tenant content origin (api.{baseDomain}), which has no /users/sessions + // endpoint. Confirmed against the pre-split reference build (novo.market) + // and a live POST against users.vitanova.network:456/users/sessions. + { provide: AUTH_API_URL, useValue: environment.authApiUrl }, { provide: TELEGRAM_BOT_USERNAME, useValue: environment.telegramBot }, + { + provide: MARKETPLACES_AUTH_CONFIG, + useFactory: (tenantResolver: TenantResolverService): MarketplacesAuthConfig => ({ + apiUrl: environment.authApiUrl, + marketplaceDomain: () => tenantResolver.getBaseDomain(), + }), + deps: [TenantResolverService] + }, // useFactory, not useClass: @marketplaces/auth ships plain tsc output, not // Angular Package Format, so it carries no baked-in Ivy DI metadata for // this class. useClass forces Angular to JIT-compile it at runtime, which @@ -49,8 +58,8 @@ export const appConfig: ApplicationConfig = { // apiUrl: environment.qrApiUrl ('https://qr.vitanova.network/api') is the // same "central payment service" the legacy /qr and // /card/{partnerId}/{orderId} endpoints already used (api.service.ts) - - // one service shared across every tenant, unlike the per-tenant - // AUTH_API_URL above. Stripped the trailing /api here: the package's own + // one service shared across every tenant - same shape as AUTH_API_URL + // above. Stripped the trailing /api here: the package's own // default paymentsPath is '/api/v1/payments', so passing qrApiUrl // unchanged would double it to .../api/api/v1/payments. Confirmed by // reading the package's baseUrl() directly (apiUrl + paymentsPath, diff --git a/src/environments/environment.production.ts b/src/environments/environment.production.ts index 15857c2..779cd66 100644 --- a/src/environments/environment.production.ts +++ b/src/environments/environment.production.ts @@ -11,6 +11,7 @@ export const environment = { theme: 'dexar', apiUrl: '/api', qrApiUrl: 'https://qr.vitanova.network/api', + authApiUrl: 'https://users.vitanova.network:456', logo: '/icons/icon-192x192.png', contactEmail: 'info@dexarmarket.ru', supportEmail: 'info@dexarmarket.ru', diff --git a/src/environments/environment.ts b/src/environments/environment.ts index d561417..b7cee51 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -12,6 +12,7 @@ export const environment = { theme: 'dexar', apiUrl: '/api', qrApiUrl: 'https://qr.vitanova.network/api', + authApiUrl: 'https://users.vitanova.network:456', logo: '/icons/icon-192x192.png', contactEmail: 'info@dexarmarket.ru', supportEmail: 'info@dexarmarket.ru',