From 018972650388994a048bba650e29f0610c4c4c04 Mon Sep 17 00:00:00 2001 From: Ritul Date: Tue, 31 Mar 2026 16:06:21 +0530 Subject: [PATCH] Routing to fp/install --- client/src/utils/fyndSalesChannels.js | 97 +++++++++++++++++++++++++-- server/routes/platform.js | 1 - 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/client/src/utils/fyndSalesChannels.js b/client/src/utils/fyndSalesChannels.js index 0a04fbc..969de15 100644 --- a/client/src/utils/fyndSalesChannels.js +++ b/client/src/utils/fyndSalesChannels.js @@ -1,12 +1,95 @@ 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; + +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_AUTH_BOOTSTRAP_REDIRECT'; + return error; +} export async function fetchActiveSalesChannels() { - const response = await apiClient.get('/api/platform/sales-channels'); - return normalizeChannelsPayload( - response?.data?.salesChannels - || response?.data?.channels - || response?.data?.items - || [] - ); + const companyId = getRuntimeCompanyId(); + + try { + 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; + } } diff --git a/server/routes/platform.js b/server/routes/platform.js index 50380f7..bd53327 100644 --- a/server/routes/platform.js +++ b/server/routes/platform.js @@ -150,7 +150,6 @@ router.get('/sales-channels', async (req, res) => { if (!req.platformClient) { return res.status(503).json({ error: 'Platform client is unavailable for sales-channel fetch' }); } - console.log("req.platformClient", req.platformClient); const applications = await listAllApplications(req.platformClient); const channels = [];