@gov-cy/govcy-express-services
Version:
An Express-based system that dynamically renders services using @gov-cy/govcy-frontend-renderer and posts data to a submission API.
106 lines (99 loc) • 5.8 kB
JavaScript
import { govcyApiRequest } from "../utils/govcyApiRequest.mjs";
import { logger } from "../utils/govcyLogger.mjs";
import { getEnvVariable, getEnvVariableBool } from "../utils/govcyEnvVariables.mjs";
import { getPageConfigData } from "../utils/govcyLoadConfigData.mjs";
import { handleMiddlewareError } from "../utils/govcyUtils.mjs";
import * as dataLayer from "../utils/govcyDataLayer.mjs";
// Helper to show error page or redirect (reuse your review handler logic)
function handleEligibilityError(res, errorPage,next) {
if (errorPage) {
return res.redirect(errorPage);
}
// fallback: show generic error
return handleMiddlewareError("Eligibility check failed", 403, next);
}
export function govcyServiceEligibilityHandler(checkForForm = false) {
return async (req, res, next) => {
try {
const service = req.serviceData;
// Extract siteId and pageUrl from request
let { siteId, pageUrl } = req.params;
// If `checkForForm` is set, check if page has no form and skip the eligibility check
if (checkForForm) {
// 🏠 Handle index page: If pageUrl is undefined (meaning the user accessed `/:siteId`), set a default value or handle accordingly
if (!pageUrl) pageUrl = "index";
// 🔍 Find the page by pageUrl
const page = getPageConfigData(service, pageUrl);
if (!page || !page.pageTemplate) return next(); // Defensive: skip if no template
// Deep copy pageTemplate to avoid modifying the original
const pageTemplateCopy = JSON.parse(JSON.stringify(page.pageTemplate));
// Check if any section contains a form element
const hasForm = pageTemplateCopy.sections?.some(section =>
section.elements?.some(el => el.element === "form")
);
if (!hasForm) {
// No form found, skip eligibility check
return next();
}
// else: continue with eligibility check
}
const eligibilityEndpoints = service?.site?.eligibilityAPIEndpoints || [];
const user = dataLayer.getUser(req.session); // Get the user from the session;
for (const endpoint of eligibilityEndpoints) {
// get the API endpoint URL, clientKey, serviceId from the environment variable (handle edge cases)
const url = getEnvVariable(endpoint?.url || "", false);
const clientKey = getEnvVariable(endpoint?.clientKey || "", false);
const serviceId = getEnvVariable(endpoint?.serviceId || "", false);
const dsfGtwApiKey = getEnvVariable(endpoint?.dsfgtwApiKey || "", "");
const cashingTimeoutMinutes = endpoint?.cashingTimeoutMinutes || 0; // Default to 0 if not set
const allowSelfSignedCerts = getEnvVariableBool("ALLOW_SELF_SIGNED_CERTIFICATES",false) ; // Default to false if not set
if (!url) {
return handleMiddlewareError("🚨 Service eligibility API endpoint URL is missing", 500, next);
}
if (!clientKey) {
return handleMiddlewareError("🚨 Service eligibility API clientKey is missing", 500, next);
}
if (!serviceId) {
return handleMiddlewareError("🚨 Service eligibility API serviceId is missing", 500, next);
}
const endpointKey = endpoint?.url || "defaultEndpoint";
const maxAgeMs = cashingTimeoutMinutes * 60 * 1000; // convert minutes to milliseconds
const params = endpoint?.params || {};
const method = (endpoint?.method || "GET").toLowerCase();
// Check if eligibility result is cached
let response = dataLayer.getSiteEligibilityResult(req.session, siteId, endpointKey, maxAgeMs);
if (!response) {
// Call the eligibility API
response = await govcyApiRequest(
method,
url,
params,
true,
user,
{
accept: "text/plain", // Set Accept header to text/plain
"client-key": clientKey, // Set the client key header
"service-id": serviceId, // Set the service ID header
...(dsfGtwApiKey !== '' && { "dsfgtw-api-key": dsfGtwApiKey }) // Use the DSF API GTW secret from environment variables
},
3,
allowSelfSignedCerts
);
// Cache the result
dataLayer.storeSiteEligibilityResult(req.session, siteId, endpointKey, response);
}
// If not eligible, handle error
if (!response.Succeeded) {
// Try to find a custom error page for this error code
const errorPage = endpoint.response?.errorResponse?.[String(response.ErrorCode)]?.page;
logger.info(`Eligibility check failed: ${response.ErrorMessage || response.ErrorCode}`);
return handleEligibilityError(res, errorPage, next);
}
}
// All checks passed
next();
} catch (err) {
return next(err); // Pass error to govcyHttpErrorHandler
}
};
}