Implemented partnerui

This commit is contained in:
2026-10-23 00:58:47 +02:00
parent 9ed210613e
commit 8f58e15f0f
27 changed files with 11416 additions and 983 deletions
@@ -0,0 +1,164 @@
import { getTenant } from './api';
import { ActivityStatus, Tenant } from '../types';
import { setActivationPending } from './userSyncService';
export interface TenantLockoutResult {
isActive: boolean;
tenant: Tenant | null;
errorMessage?: string;
statusCode?: number;
}
let cachedTenantLockout: {
key: string;
result: TenantLockoutResult;
timestamp: number;
} | null = null;
const LOCKOUT_CACHE_TTL_MS = 60 * 1000;
export function clearTenantLockoutCache(): void {
cachedTenantLockout = null;
}
export function isStatusActive(status: any): boolean {
if (status === undefined || status === null || status === '') {
return false;
}
if (status === ActivityStatus.Active || status === 1 || status === '1') {
return true;
}
if (typeof status === 'string' && status.trim().toLowerCase() === 'active') {
return true;
}
if (status === true) {
return true;
}
return false;
}
export function getStatusLabel(status: any): string {
if (status === ActivityStatus.Active || status === 1 || String(status).toLowerCase() === 'active') {
return 'Active';
}
if (status === ActivityStatus.Inactive || status === 2 || String(status).toLowerCase() === 'inactive') {
return 'Inactive';
}
if (status === ActivityStatus.Disabled || status === 3 || String(status).toLowerCase() === 'disabled') {
return 'Disabled';
}
if (String(status).toLowerCase() === 'suspended') {
return 'Suspended';
}
if (status === 0 || String(status).toLowerCase() === 'pending') {
return 'Pending';
}
if (status !== undefined && status !== null && status !== '') {
return String(status);
}
return 'Not Specified';
}
export async function verifyTenantLockout(
tenantId?: number | string | null,
tenantClaim?: string | null,
forceRefresh = false
): Promise<TenantLockoutResult> {
const primaryId =
tenantId !== undefined && tenantId !== null && tenantId !== ''
? tenantId
: tenantClaim !== undefined && tenantClaim !== null && tenantClaim !== ''
? tenantClaim
: null;
if (primaryId === null || primaryId === undefined || primaryId === '') {
const errorMsg =
'Tenant identification claims (tenant / tenant_id) not found in credentials. Access is restricted.';
setActivationPending(true, errorMsg);
return {
isActive: false,
tenant: null,
errorMessage: errorMsg,
};
}
const cacheKey = String(primaryId).trim().toLowerCase();
if (!forceRefresh && cachedTenantLockout && cachedTenantLockout.key === cacheKey) {
if (
cachedTenantLockout.result.isActive &&
Date.now() - cachedTenantLockout.timestamp < LOCKOUT_CACHE_TTL_MS
) {
return cachedTenantLockout.result;
}
}
let tenantRes: Tenant | null = null;
let lastError: any = null;
try {
tenantRes = await getTenant(primaryId);
} catch (err: any) {
lastError = err;
tenantRes = null;
}
if (!tenantRes && tenantClaim && String(tenantClaim) !== String(primaryId)) {
try {
tenantRes = await getTenant(tenantClaim);
lastError = null;
} catch (err: any) {
lastError = err;
tenantRes = null;
}
}
if (!tenantRes || (typeof tenantRes === 'object' && Object.keys(tenantRes).length === 0)) {
const serverMsg =
lastError?.response?.data?.detail ||
lastError?.response?.data?.message ||
lastError?.message ||
'No tenant record returned';
const errorMsg = `Tenant record could not be retrieved (${serverMsg}). Account is locked out.`;
setActivationPending(true, errorMsg);
return {
isActive: false,
tenant: null,
errorMessage: errorMsg,
statusCode: lastError?.response?.status,
};
}
const tenantObj: Tenant = (tenantRes as any)?.data || (tenantRes as any)?.result || tenantRes;
const rawStatus =
(tenantObj as any)?.status ??
(tenantObj as any)?.Status ??
(tenantObj as any)?.activityStatus ??
(tenantObj as any)?.ActivityStatus;
const active = isStatusActive(rawStatus);
if (!active) {
const statusLabel = getStatusLabel(rawStatus);
const tenantName = tenantObj?.name || String(primaryId);
const errorMsg = `Tenant account "${tenantName}" is not Active (Status: ${statusLabel}). Account is locked out.`;
setActivationPending(true, errorMsg);
return {
isActive: false,
tenant: tenantObj,
errorMessage: errorMsg,
};
}
const successResult: TenantLockoutResult = {
isActive: true,
tenant: tenantObj,
};
cachedTenantLockout = {
key: cacheKey,
result: successResult,
timestamp: Date.now(),
};
return successResult;
}