Redirecting to fp/install and fp/auth on missing token
This commit is contained in:
parent
0189726503
commit
0ab0cc563e
|
|
@ -18,6 +18,7 @@ COPY server/index.js ./
|
|||
COPY server/fdk.js ./
|
||||
COPY server/postgresFdkStorage.js ./
|
||||
COPY server/config ./config
|
||||
# Includes protected and public platform routes such as routes/platformPublic.js.
|
||||
COPY server/routes ./routes
|
||||
COPY server/services ./services
|
||||
COPY --from=client-build /client/dist ./public
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ 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}`;
|
||||
|
|
@ -63,14 +65,57 @@ function buildFdkInstallUrl(companyId) {
|
|||
|
||||
function createBootstrapRedirectError() {
|
||||
const error = new Error('Redirecting to FDK auth bootstrap');
|
||||
error.code = 'FDK_AUTH_BOOTSTRAP_REDIRECT';
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ const path = require('path');
|
|||
|
||||
const businessesRoutes = require('./routes/businesses');
|
||||
const platformRoutes = require('./routes/platform');
|
||||
const platformPublicRoutes = require('./routes/platformPublic');
|
||||
const { fdkExtension, isFdkConfigured } = require('./fdk');
|
||||
|
||||
const app = express();
|
||||
|
|
@ -29,9 +30,11 @@ app.get('/api/health', (req, res) => res.json({
|
|||
}));
|
||||
|
||||
if (fdkExtension) {
|
||||
app.use('/api/platform', platformPublicRoutes);
|
||||
app.use(fdkExtension.fdkHandler);
|
||||
app.use('/api/platform', fdkExtension.platformApiRoutes, platformRoutes);
|
||||
} else {
|
||||
app.use('/api/platform', platformPublicRoutes);
|
||||
app.use('/api/platform', platformRoutes);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
const express = require('express');
|
||||
const { SESSION_COOKIE_NAME } = require('@gofynd/fdk-extension-javascript/express/constants');
|
||||
|
||||
const { fdkExtension, isFdkConfigured } = require('../fdk');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
function normalizeText(value) {
|
||||
return typeof value === 'string' ? value.trim() : '';
|
||||
}
|
||||
|
||||
function getCompanyId(req) {
|
||||
return normalizeText(
|
||||
req.get('x-company-id')
|
||||
|| req.query.company_id
|
||||
|| req.query.companyId
|
||||
|| ''
|
||||
);
|
||||
}
|
||||
|
||||
function getSessionCookieName(companyId) {
|
||||
return `${SESSION_COOKIE_NAME}_${companyId}`;
|
||||
}
|
||||
|
||||
function clearSessionCookie(res, companyId) {
|
||||
res.clearCookie(getSessionCookieName(companyId), {
|
||||
path: '/',
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: 'None',
|
||||
partitioned: true,
|
||||
});
|
||||
}
|
||||
|
||||
router.get('/session-status', async (req, res) => {
|
||||
const companyId = getCompanyId(req);
|
||||
|
||||
if (!isFdkConfigured || !fdkExtension) {
|
||||
return res.json({
|
||||
configured: false,
|
||||
authenticated: false,
|
||||
companyId,
|
||||
needsBootstrap: false,
|
||||
reason: 'fdk_not_configured',
|
||||
});
|
||||
}
|
||||
|
||||
if (!companyId) {
|
||||
return res.status(400).json({
|
||||
configured: true,
|
||||
authenticated: false,
|
||||
companyId: '',
|
||||
needsBootstrap: false,
|
||||
reason: 'missing_company_id',
|
||||
});
|
||||
}
|
||||
|
||||
const sessionCookieName = getSessionCookieName(companyId);
|
||||
const sessionId = normalizeText(req.signedCookies?.[sessionCookieName] || '');
|
||||
|
||||
if (!sessionId) {
|
||||
return res.json({
|
||||
configured: true,
|
||||
authenticated: false,
|
||||
companyId,
|
||||
needsBootstrap: true,
|
||||
reason: 'missing_session_cookie',
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const session = await fdkExtension.storage.get(sessionId);
|
||||
const authenticated = Boolean(
|
||||
session
|
||||
&& normalizeText(String(session.company_id || '')) === companyId
|
||||
&& normalizeText(session.access_token || '')
|
||||
);
|
||||
|
||||
if (!authenticated) {
|
||||
clearSessionCookie(res, companyId);
|
||||
}
|
||||
|
||||
return res.json({
|
||||
configured: true,
|
||||
authenticated,
|
||||
companyId,
|
||||
needsBootstrap: !authenticated,
|
||||
reason: authenticated ? 'ok' : 'missing_or_invalid_session',
|
||||
});
|
||||
} catch (error) {
|
||||
return res.status(503).json({
|
||||
configured: true,
|
||||
authenticated: false,
|
||||
companyId,
|
||||
needsBootstrap: false,
|
||||
reason: 'session_status_error',
|
||||
error: error.message || 'Failed to inspect FDK session',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Loading…
Reference in New Issue
Block a user