fix remote HMAC: match tenant domain only, not shared adminUrl

k.montzar.ir on Gholaktala adminUrl was selecting tenant app.gholaktala.ir. HMAC now uses primary domain (and its subdomain), not admin/app/node URLs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-09 22:07:40 +03:30
co-authored by Cursor
parent 3f0dfe448c
commit 82e74f86f0
3 changed files with 42 additions and 16 deletions
+13 -5
View File
@@ -62,14 +62,17 @@ function isSubdomainOf(host: string, parent: string): boolean {
return child === root || child.endsWith('.' + root);
}
export type TenantHostMatchMode = 'full' | 'hmac';
/**
* Same identity as GET /get_user?domain= — primary domain, then aliases,
* then app/admin URLs. nodeServer is last and only if unique (many versions
* share one API host like new.gholaktala.ir).
* full: get_user — دامنه، alias، app/admin/node.
* hmac: فقط دامنهٔ اصلی نسخه (و ساب‌دامنهٔ همان). adminUrl مشترک
* (k.montzar.ir روی نسخهٔ app.gholaktala.ir) هویت نیست.
*/
export function scoreTenantHost(
tenant: TenantHostFields,
hostRaw: string,
mode: TenantHostMatchMode = 'full',
): number {
const host = normalizeTenantHost(hostRaw);
if (!host) return 0;
@@ -77,6 +80,11 @@ export function scoreTenantHost(
hostsEqual(normalizeTenantHost(raw), host);
if (eq(tenant.domain)) return 100;
if (mode === 'hmac') {
if (tenant.domain && isSubdomainOf(host, tenant.domain)) return 75;
return 0;
}
for (const alias of readHostList(tenant.domains)) {
if (eq(alias)) return 90;
}
@@ -102,16 +110,16 @@ export function scoreTenantHost(
export function findTenantForHost<T extends TenantHostFields>(
tenants: T[],
host: string,
mode: TenantHostMatchMode = 'full',
): T | undefined {
const scored = tenants
.map((row) => ({ row, score: scoreTenantHost(row, host) }))
.map((row) => ({ row, score: scoreTenantHost(row, host, mode) }))
.filter((item) => item.score > 0)
.sort((a, b) => b.score - a.score);
if (!scored.length) return undefined;
const best = scored[0].score;
const tied = scored.filter((item) => item.score === best);
// nodeServer مشترک یا دو نسخه با امتیاز مساوی — حدس نزن
if (tied.length !== 1) return undefined;
return tied[0].row;
}