141 lines
4.1 KiB
JavaScript
141 lines
4.1 KiB
JavaScript
import apiClient from '../api/client';
|
|
import { normalizeChannelsPayload } from './businessProfile';
|
|
import { getRuntimeApplicationId, getRuntimeCompanyId } from './runtimeContext';
|
|
|
|
const FDK_BOOTSTRAP_ATTEMPT_PREFIX = 'sms_fdk_bootstrap_attempt';
|
|
const FDK_BOOTSTRAP_TTL_MS = 2 * 60 * 1000;
|
|
const FDK_BOOTSTRAP_REDIRECT_CODE = 'FDK_AUTH_BOOTSTRAP_REDIRECT';
|
|
const FDK_SESSION_UNAVAILABLE_CODE = 'FDK_SESSION_UNAVAILABLE';
|
|
|
|
function getBootstrapStorageKey(companyId) {
|
|
return `${FDK_BOOTSTRAP_ATTEMPT_PREFIX}:${companyId}`;
|
|
}
|
|
|
|
function readBootstrapAttempt(companyId) {
|
|
if (!companyId || typeof sessionStorage === 'undefined') return 0;
|
|
|
|
try {
|
|
return Number(sessionStorage.getItem(getBootstrapStorageKey(companyId)) || 0);
|
|
} catch {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
function writeBootstrapAttempt(companyId) {
|
|
if (!companyId || typeof sessionStorage === 'undefined') return;
|
|
|
|
try {
|
|
sessionStorage.setItem(getBootstrapStorageKey(companyId), String(Date.now()));
|
|
} catch {
|
|
// Ignore storage failures and still attempt bootstrap redirect.
|
|
}
|
|
}
|
|
|
|
function clearBootstrapAttempt(companyId) {
|
|
if (!companyId || typeof sessionStorage === 'undefined') return;
|
|
|
|
try {
|
|
sessionStorage.removeItem(getBootstrapStorageKey(companyId));
|
|
} catch {
|
|
// Ignore storage failures.
|
|
}
|
|
}
|
|
|
|
function shouldBootstrapSession(companyId) {
|
|
const lastAttempt = readBootstrapAttempt(companyId);
|
|
if (!lastAttempt) return true;
|
|
return (Date.now() - lastAttempt) > FDK_BOOTSTRAP_TTL_MS;
|
|
}
|
|
|
|
function buildFdkInstallUrl(companyId) {
|
|
if (!companyId || typeof window === 'undefined') return '';
|
|
|
|
const search = new URLSearchParams({
|
|
company_id: companyId,
|
|
redirect_path: window.location.href,
|
|
});
|
|
const applicationId = getRuntimeApplicationId();
|
|
|
|
if (applicationId) {
|
|
search.set('application_id', applicationId);
|
|
}
|
|
|
|
return `/fp/install?${search.toString()}`;
|
|
}
|
|
|
|
function createBootstrapRedirectError() {
|
|
const error = new Error('Redirecting to FDK auth bootstrap');
|
|
error.code = FDK_BOOTSTRAP_REDIRECT_CODE;
|
|
return error;
|
|
}
|
|
|
|
function createSessionUnavailableError(message = 'FDK session is unavailable') {
|
|
const error = new Error(message);
|
|
error.code = FDK_SESSION_UNAVAILABLE_CODE;
|
|
return error;
|
|
}
|
|
|
|
function shouldAttemptBootstrap(sessionStatus = {}) {
|
|
return Boolean(sessionStatus?.configured) && Boolean(sessionStatus?.needsBootstrap);
|
|
}
|
|
|
|
async function getSessionStatus() {
|
|
const response = await apiClient.get('/api/platform/session-status');
|
|
return response?.data || {};
|
|
}
|
|
|
|
async function ensureFdkPlatformSession(companyId) {
|
|
if (!companyId) {
|
|
throw createSessionUnavailableError('Missing company id for FDK session bootstrap');
|
|
}
|
|
|
|
const sessionStatus = await getSessionStatus();
|
|
if (sessionStatus?.authenticated) {
|
|
clearBootstrapAttempt(companyId);
|
|
return sessionStatus;
|
|
}
|
|
|
|
if (shouldAttemptBootstrap(sessionStatus) && shouldBootstrapSession(companyId)) {
|
|
const installUrl = buildFdkInstallUrl(companyId);
|
|
if (installUrl && typeof window !== 'undefined') {
|
|
writeBootstrapAttempt(companyId);
|
|
window.location.replace(installUrl);
|
|
throw createBootstrapRedirectError();
|
|
}
|
|
}
|
|
|
|
throw createSessionUnavailableError(
|
|
sessionStatus?.reason
|
|
? `FDK session unavailable: ${sessionStatus.reason}`
|
|
: 'FDK session is unavailable'
|
|
);
|
|
}
|
|
|
|
export async function fetchActiveSalesChannels() {
|
|
const companyId = getRuntimeCompanyId();
|
|
|
|
try {
|
|
await ensureFdkPlatformSession(companyId);
|
|
const response = await apiClient.get('/api/platform/sales-channels');
|
|
clearBootstrapAttempt(companyId);
|
|
return normalizeChannelsPayload(
|
|
response?.data?.salesChannels
|
|
|| response?.data?.channels
|
|
|| response?.data?.items
|
|
|| []
|
|
);
|
|
} catch (error) {
|
|
const status = error?.response?.status;
|
|
if (status === 401 && companyId && shouldBootstrapSession(companyId)) {
|
|
const installUrl = buildFdkInstallUrl(companyId);
|
|
if (installUrl && typeof window !== 'undefined') {
|
|
writeBootstrapAttempt(companyId);
|
|
window.location.replace(installUrl);
|
|
throw createBootstrapRedirectError();
|
|
}
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
}
|