Files
pfm/PostFundManagement.ConsoleUI/src/services/tenantLockoutService.ts
T
2026-09-26 10:28:43 +02:00

155 lines
4.6 KiB
TypeScript

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;
}
/**
* Checks whether a given status value corresponds to ActivityStatus.Active (1)
*/
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;
}
/**
* Formats a human-readable status label from numeric or string status
*/
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';
}
/**
* Calls the GetTenant endpoint for the provided tenant identifier.
*
* Rules:
* - If nothing is returned (empty response, 404, or failure) OR
* - There is a response object and its Status is not Active
* Then lockout is triggered and the existing lockout modal is shown.
*/
export async function verifyTenantLockout(
tenantId?: number | string | null,
tenantClaim?: string | null
): 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,
};
}
let tenantRes: Tenant | null = null;
let lastError: any = null;
try {
tenantRes = await getTenant(primaryId);
} catch (err: any) {
lastError = err;
tenantRes = null;
}
// If primary identifier returned nothing, and tenantClaim provides a different candidate, attempt fallback
if (!tenantRes && tenantClaim && String(tenantClaim) !== String(primaryId)) {
try {
tenantRes = await getTenant(tenantClaim);
lastError = null;
} catch (err: any) {
lastError = err;
tenantRes = null;
}
}
// Condition 1: If nothing is returned
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,
};
}
// Handle wrapped response structures: { data: { ... } } or { result: { ... } }
const tenantObj: Tenant = (tenantRes as any)?.data || (tenantRes as any)?.result || tenantRes;
// Condition 2: If there is a response object and its Status is not Active
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,
};
}
// Success: Response object returned and Status is Active
return {
isActive: true,
tenant: tenantObj,
};
}