refactor(forms): enable approved Form A placements by default
This commit is contained in:
41 files changed
+862
-523
No files matched your search
@@ -14,7 +14,7 @@ interface Props {
|
||||
const { lang = 'en', logicalForm = 'general' } = Astro.props;
|
||||
const text = formMessages(lang);
|
||||
const title = Astro.props.title ?? text.contactHeading;
|
||||
const config = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE, import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED);
|
||||
const config = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE);
|
||||
const mode = formModeForRuntime(config);
|
||||
const mockResult = resolveMockFormResult(import.meta.env.PUBLIC_AIA_FORMS_MOCK_RESULT);
|
||||
---
|
||||
|
||||
@@ -10,7 +10,7 @@ interface Props {
|
||||
|
||||
const { lang = 'en', variant = 'full', submitText } = Astro.props;
|
||||
const text = formMessages(lang).formAPreview;
|
||||
const config = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE, import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED);
|
||||
const config = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE);
|
||||
const mode = formModeForRuntime(config);
|
||||
const enabled = formAPreviewEnabled(import.meta.env.PUBLIC_AIA_FORM_A_PREVIEW, import.meta.env.PUBLIC_ALLOW_INDEXING, mode);
|
||||
const prefix = `form-a-${variant}`;
|
||||
|
||||
@@ -8,18 +8,12 @@ const { lang = 'en', showBackground = false, route = '' } = Astro.props;
|
||||
const text = formMessages(lang);
|
||||
const title = Astro.props.title ?? text.heading;
|
||||
const logicalForm: LogicalForm = Astro.props.logicalForm ?? (Astro.props.title === 'Physician & Insurer Referrals' ? 'referral' : 'service');
|
||||
const config = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE, import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED);
|
||||
const config = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE);
|
||||
const mode = formModeForRuntime(config);
|
||||
const mockResult = resolveMockFormResult(import.meta.env.PUBLIC_AIA_FORMS_MOCK_RESULT);
|
||||
const formAIframe = logicalForm === 'service'
|
||||
? resolveFormAIframe({
|
||||
rawMode: import.meta.env.PUBLIC_AIA_FORMS_MODE,
|
||||
liveApproved: import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED,
|
||||
isolatedTestApproved: import.meta.env.PUBLIC_AIA_FORMS_ISOLATED_TEST_APPROVED,
|
||||
consultationTestApproved: import.meta.env.PUBLIC_AIA_FORMS_CONSULTATION_TEST_APPROVED,
|
||||
productionApproved: import.meta.env.PUBLIC_AIA_FORM_A_PRODUCTION_APPROVED,
|
||||
environmentRole: import.meta.env.PUBLIC_AIA_FORMS_ENVIRONMENT,
|
||||
allowIndexing: import.meta.env.PUBLIC_ALLOW_INDEXING,
|
||||
route,
|
||||
locale: lang,
|
||||
})
|
||||
|
||||
@@ -27,7 +27,6 @@ const headingId = `${idBase}-heading`;
|
||||
aria-label={hideHeading ? config.title : undefined}
|
||||
data-jotform-form-a
|
||||
data-form-mode={config.mode}
|
||||
data-form-environment={config.environmentRole}
|
||||
data-logical-form={config.context === 'consultation' ? 'service' : 'general'}
|
||||
data-form-context={config.context}
|
||||
data-jotform-source="approved-form-a"
|
||||
|
||||
@@ -122,24 +122,18 @@ const serviceCopy = serviceInquiryCopy[service][lang];
|
||||
const drawerId = `service-inquiry-${lang}-${service}`;
|
||||
const titleId = `${drawerId}-title`;
|
||||
const noteId = `${drawerId}-note`;
|
||||
const config = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE, import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED);
|
||||
const config = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE);
|
||||
const mode = formModeForRuntime(config);
|
||||
const mockResult = resolveMockFormResult(import.meta.env.PUBLIC_AIA_FORMS_MOCK_RESULT);
|
||||
const formAIframe = resolveFormAIframe({
|
||||
rawMode: import.meta.env.PUBLIC_AIA_FORMS_MODE,
|
||||
liveApproved: import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED,
|
||||
isolatedTestApproved: import.meta.env.PUBLIC_AIA_FORMS_ISOLATED_TEST_APPROVED,
|
||||
consultationTestApproved: import.meta.env.PUBLIC_AIA_FORMS_CONSULTATION_TEST_APPROVED,
|
||||
productionApproved: import.meta.env.PUBLIC_AIA_FORM_A_PRODUCTION_APPROVED,
|
||||
environmentRole: import.meta.env.PUBLIC_AIA_FORMS_ENVIRONMENT,
|
||||
allowIndexing: import.meta.env.PUBLIC_ALLOW_INDEXING,
|
||||
route,
|
||||
locale: lang,
|
||||
});
|
||||
const consultationTestEnabled = formAIframe.enabled && formAIframe.context === 'consultation';
|
||||
const consultationEnabled = formAIframe.enabled && formAIframe.context === 'consultation';
|
||||
---
|
||||
|
||||
{consultationTestEnabled && formAIframe.url && <>
|
||||
{consultationEnabled && formAIframe.url && <>
|
||||
<noscript>
|
||||
<p class="service-inquiry-drawer__noscript">
|
||||
{copy.noScript} <a href={formAIframe.url} target="_blank" rel="noopener noreferrer">{copy.hostedLink}</a>
|
||||
@@ -151,7 +145,7 @@ const consultationTestEnabled = formAIframe.enabled && formAIframe.context === '
|
||||
id={drawerId}
|
||||
class="service-inquiry-drawer"
|
||||
data-service-inquiry-drawer
|
||||
data-consultation-test={consultationTestEnabled ? 'true' : undefined}
|
||||
data-consultation-enabled={consultationEnabled ? 'true' : undefined}
|
||||
data-service={service}
|
||||
aria-labelledby={titleId}
|
||||
>
|
||||
@@ -162,12 +156,12 @@ const consultationTestEnabled = formAIframe.enabled && formAIframe.context === '
|
||||
</button>
|
||||
|
||||
<header class="service-inquiry-drawer__intro">
|
||||
<h2 id={titleId} data-service-inquiry-title tabindex="-1">{consultationTestEnabled ? serviceCopy.heading : serviceName}</h2>
|
||||
<p>{consultationTestEnabled ? serviceCopy.introduction : copy.legacyStatus}</p>
|
||||
{consultationTestEnabled && <p class="service-inquiry-drawer__privacy">{copy.privacy}</p>}
|
||||
<h2 id={titleId} data-service-inquiry-title tabindex="-1">{consultationEnabled ? serviceCopy.heading : serviceName}</h2>
|
||||
<p>{consultationEnabled ? serviceCopy.introduction : copy.legacyStatus}</p>
|
||||
{consultationEnabled && <p class="service-inquiry-drawer__privacy">{copy.privacy}</p>}
|
||||
</header>
|
||||
|
||||
{consultationTestEnabled
|
||||
{consultationEnabled
|
||||
? <div class="service-inquiry-drawer__iframe">
|
||||
<p data-service-inquiry-completed hidden role="status" aria-live="polite" aria-atomic="true">
|
||||
{lang === 'es' ? '¡Gracias! Hemos recibido su mensaje.' : 'Thank you! Your message has been received.'}
|
||||
|
||||
@@ -12,7 +12,7 @@ interface Props {
|
||||
const { sourcePage, title, intro, buttonText } = Astro.props;
|
||||
const phone = import.meta.env.PUBLIC_AIA_PHONE || '480-687-7099';
|
||||
const tel = phone.replace(/[^0-9+]/g, '');
|
||||
const formConfig = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE, import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED);
|
||||
const formConfig = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE);
|
||||
const formPreview = formAPreviewEnabled(import.meta.env.PUBLIC_AIA_FORM_A_PREVIEW, import.meta.env.PUBLIC_ALLOW_INDEXING, formModeForRuntime(formConfig));
|
||||
const campaignRoute = sourcePage === 'general'
|
||||
? '/lp/aba-therapy'
|
||||
@@ -24,12 +24,6 @@ const campaignRoute = sourcePage === 'general'
|
||||
const iframeDescription = 'Use this form to request a conversation. An AIA team member can explain the next steps for your family.';
|
||||
const formAIframe = resolveFormAIframe({
|
||||
rawMode: import.meta.env.PUBLIC_AIA_FORMS_MODE,
|
||||
liveApproved: import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED,
|
||||
isolatedTestApproved: import.meta.env.PUBLIC_AIA_FORMS_ISOLATED_TEST_APPROVED,
|
||||
consultationTestApproved: import.meta.env.PUBLIC_AIA_FORMS_CONSULTATION_TEST_APPROVED,
|
||||
productionApproved: import.meta.env.PUBLIC_AIA_FORM_A_PRODUCTION_APPROVED,
|
||||
environmentRole: import.meta.env.PUBLIC_AIA_FORMS_ENVIRONMENT,
|
||||
allowIndexing: import.meta.env.PUBLIC_ALLOW_INDEXING,
|
||||
route: campaignRoute,
|
||||
locale: 'en',
|
||||
});
|
||||
|
||||
@@ -4,12 +4,6 @@ import { resolveFormAIframe } from '../../utils/form-integration';
|
||||
|
||||
const formAIframe = resolveFormAIframe({
|
||||
rawMode: import.meta.env.PUBLIC_AIA_FORMS_MODE,
|
||||
liveApproved: import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED,
|
||||
isolatedTestApproved: import.meta.env.PUBLIC_AIA_FORMS_ISOLATED_TEST_APPROVED,
|
||||
consultationTestApproved: import.meta.env.PUBLIC_AIA_FORMS_CONSULTATION_TEST_APPROVED,
|
||||
productionApproved: import.meta.env.PUBLIC_AIA_FORM_A_PRODUCTION_APPROVED,
|
||||
environmentRole: import.meta.env.PUBLIC_AIA_FORMS_ENVIRONMENT,
|
||||
allowIndexing: import.meta.env.PUBLIC_ALLOW_INDEXING,
|
||||
route: '/lp/early-intervention',
|
||||
locale: 'en',
|
||||
});
|
||||
|
||||
@@ -12,17 +12,11 @@ interface Props {
|
||||
|
||||
const { title, lang } = Astro.props;
|
||||
const text = formMessages(lang);
|
||||
const formConfig = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE, import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED);
|
||||
const formConfig = resolveFormMode(import.meta.env.PUBLIC_AIA_FORMS_MODE);
|
||||
const formPreview = formAPreviewEnabled(import.meta.env.PUBLIC_AIA_FORM_A_PREVIEW, import.meta.env.PUBLIC_ALLOW_INDEXING, formModeForRuntime(formConfig));
|
||||
const route = lang === 'es' ? '/es/contact' : '/contact';
|
||||
const formAIframe = resolveFormAIframe({
|
||||
rawMode: import.meta.env.PUBLIC_AIA_FORMS_MODE,
|
||||
liveApproved: import.meta.env.PUBLIC_AIA_FORMS_LIVE_APPROVED,
|
||||
isolatedTestApproved: import.meta.env.PUBLIC_AIA_FORMS_ISOLATED_TEST_APPROVED,
|
||||
consultationTestApproved: import.meta.env.PUBLIC_AIA_FORMS_CONSULTATION_TEST_APPROVED,
|
||||
productionApproved: import.meta.env.PUBLIC_AIA_FORM_A_PRODUCTION_APPROVED,
|
||||
environmentRole: import.meta.env.PUBLIC_AIA_FORMS_ENVIRONMENT,
|
||||
allowIndexing: import.meta.env.PUBLIC_ALLOW_INDEXING,
|
||||
route,
|
||||
locale: lang,
|
||||
});
|
||||
|
||||
@@ -5,7 +5,6 @@ import Button from '../Button.astro';
|
||||
const payload = readPortalInput({
|
||||
approved: import.meta.env.AIA_PORTAL_LOCAL_PREVIEW_APPROVED,
|
||||
indexing: import.meta.env.PUBLIC_ALLOW_INDEXING,
|
||||
environment: import.meta.env.PUBLIC_AIA_FORMS_ENVIRONMENT,
|
||||
file: import.meta.env.AIA_PORTAL_CIPHERTEXT_FILE,
|
||||
});
|
||||
const serialized = payload ? JSON.stringify(payload).replaceAll('<', '\\u003c') : 'null';
|
||||
|
||||
@@ -18,7 +18,7 @@ export function initializeServiceInquiryDrawers() {
|
||||
document.querySelectorAll<HTMLDialogElement>('[data-service-inquiry-drawer]').forEach((dialog) => {
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
const authorized = dialog.dataset.consultationTest === 'true';
|
||||
const authorized = dialog.dataset.consultationEnabled === 'true';
|
||||
const closeButton = dialog.querySelector<HTMLButtonElement>('[data-service-inquiry-close]');
|
||||
const triggers = [...document.querySelectorAll<HTMLAnchorElement>('[data-service-inquiry-trigger]')]
|
||||
.filter((anchor) => anchor.dataset.serviceInquiryTrigger === dialog.dataset.service);
|
||||
@@ -121,8 +121,8 @@ export function initializeServiceInquiryDrawers() {
|
||||
observer?.observe(document.documentElement);
|
||||
checkScroll();
|
||||
}
|
||||
} else if (!suppressed()) {
|
||||
// Retain the existing inactive/mock demonstration timer outside test mode.
|
||||
} else if (dialog.querySelector('[data-form-mode="mock"]') && !suppressed()) {
|
||||
// Retain the existing synthetic demonstration timer only in mock mode.
|
||||
timer = window.setTimeout(() => open(), 10000);
|
||||
}
|
||||
addEventListener('storage', (event) => { if (event.key === suppressionKey && suppressed()) stopAuto(); }, { signal });
|
||||
|
||||
@@ -1,47 +1,32 @@
|
||||
export type FormMode = 'off' | 'mock' | 'isolated-test' | 'live';
|
||||
export type FormMode = 'live' | 'off' | 'mock';
|
||||
export type LogicalForm = 'general' | 'service' | 'referral';
|
||||
export type MockFormResult = 'success' | 'failed' | 'unavailable';
|
||||
|
||||
export interface FormModeConfig {
|
||||
mode: FormMode;
|
||||
reason: 'default-off' | 'mock' | 'isolated-test' | 'live-approved' | 'invalid-mode' | 'live-not-approved';
|
||||
reason: 'default-live' | 'live' | 'off' | 'mock';
|
||||
}
|
||||
|
||||
export function resolveFormMode(rawMode: string | undefined, liveApproved: string | undefined): FormModeConfig {
|
||||
export function resolveFormMode(rawMode: string | undefined): FormModeConfig {
|
||||
const mode = rawMode?.trim().toLowerCase();
|
||||
if (!mode) return { mode: 'off', reason: 'default-off' };
|
||||
if (mode === 'mock') return { mode: 'mock', reason: 'mock' };
|
||||
if (mode === 'isolated-test') return { mode: 'isolated-test', reason: 'isolated-test' };
|
||||
if (mode !== 'live') return { mode: 'off', reason: 'invalid-mode' };
|
||||
if (liveApproved?.trim().toLowerCase() !== 'true') return { mode: 'off', reason: 'live-not-approved' };
|
||||
return { mode: 'live', reason: 'live-approved' };
|
||||
if (!mode) return { mode: 'live', reason: 'default-live' };
|
||||
if (mode === 'live' || mode === 'off' || mode === 'mock') return { mode, reason: mode };
|
||||
throw new Error('Invalid PUBLIC_AIA_FORMS_MODE. Remove the obsolete setting (including isolated-test) or choose live, off, or mock.');
|
||||
}
|
||||
|
||||
/** Native fixtures never become live; only the bounded Form A adapter can. */
|
||||
export function formModeForRuntime(config: FormModeConfig): 'off' | 'mock' {
|
||||
// The isolated iframe adapter has its own fixed Form A route allowlist.
|
||||
// Keep all other lead-form surfaces and every live setting fail-closed.
|
||||
return config.mode === 'mock' ? 'mock' : 'off';
|
||||
}
|
||||
|
||||
export type FormAIframeReason =
|
||||
| 'enabled'
|
||||
| 'mode-not-authorized'
|
||||
| 'isolated-test-not-approved'
|
||||
| 'consultation-test-not-approved'
|
||||
| 'live-approval-not-disabled'
|
||||
| 'production-approval-not-granted'
|
||||
| 'invalid-environment-role'
|
||||
| 'indexing-enabled'
|
||||
| 'route-not-authorized'
|
||||
| 'locale-not-authorized';
|
||||
export type FormAIframeReason = 'enabled' | 'mode-not-authorized' | 'route-not-authorized' | 'locale-not-authorized';
|
||||
|
||||
export interface FormAIframeConfig {
|
||||
enabled: boolean;
|
||||
reason: FormAIframeReason;
|
||||
route: FormAIframeRoute | string;
|
||||
locale: 'en' | 'es' | string;
|
||||
mode?: 'isolated-test' | 'live';
|
||||
environmentRole?: 'isolated-test' | 'production';
|
||||
mode?: 'live';
|
||||
context?: FormAIframeContext;
|
||||
url?: string;
|
||||
title?: string;
|
||||
@@ -51,25 +36,13 @@ export interface FormAIframeConfig {
|
||||
|
||||
export interface ResolveFormAIframeOptions {
|
||||
rawMode: string | undefined;
|
||||
liveApproved: string | undefined;
|
||||
isolatedTestApproved: string | undefined;
|
||||
consultationTestApproved: string | undefined;
|
||||
productionApproved: string | undefined;
|
||||
environmentRole: string | undefined;
|
||||
allowIndexing: string | undefined;
|
||||
route: string;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The owner-approved Form A identifier is deliberately only made into an
|
||||
* iframe URL after every explicit isolated-test or production gate has
|
||||
* passed. It is never enabled by an API URL, hostname, or publication flag.
|
||||
*/
|
||||
/** Fixed owner-approved identity. Never accept visitor-supplied destinations. */
|
||||
export const formAIframeOrigin = 'https://form.jotform.com' as const;
|
||||
export const formAIframeId = '262946078314059' as const;
|
||||
const isolatedTestEnvironmentRole = 'isolated-test';
|
||||
const productionEnvironmentRole = 'production';
|
||||
|
||||
export type FormAIframeContext = 'contact' | 'landing' | 'consultation';
|
||||
export type FormAIframeRoute =
|
||||
@@ -96,13 +69,7 @@ export interface FormAIframePlacement {
|
||||
context: FormAIframeContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the complete fixed allowlist for the Form A adapter in both
|
||||
* explicitly approved modes.
|
||||
* Campaign placements are an owner-approved override of their earlier
|
||||
* logical Form B mapping. The shared compact landing presentation uses the
|
||||
* same fixed `landing` context; no route may supply its own context or URL.
|
||||
*/
|
||||
/** Complete owner-approved registry, independent of indexing or hostname. */
|
||||
export const formAIframePlacements: ReadonlyArray<FormAIframePlacement> = [
|
||||
{ route: '/contact', locale: 'en', context: 'contact' },
|
||||
{ route: '/es/contact', locale: 'es', context: 'contact' },
|
||||
@@ -111,15 +78,6 @@ export const formAIframePlacements: ReadonlyArray<FormAIframePlacement> = [
|
||||
{ route: '/lp/aba-ahcccs', locale: 'en', context: 'landing' },
|
||||
{ route: '/lp/aba-private-pay', locale: 'en', context: 'landing' },
|
||||
{ route: '/lp/early-intervention', locale: 'en', context: 'landing' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Consultation placements are a separate, non-production allowlist. They
|
||||
* cannot be activated by the production approval gate, even when every
|
||||
* production value is true. Service drawers defer assigning their iframe src
|
||||
* until the authorized drawer opens.
|
||||
*/
|
||||
export const formAConsultationTestPlacements: ReadonlyArray<FormAIframePlacement> = [
|
||||
{ route: '/client-consultation', locale: 'en', context: 'consultation' },
|
||||
{ route: '/es/client-consultation', locale: 'es', context: 'consultation' },
|
||||
{ route: '/schedule-consultation', locale: 'en', context: 'consultation' },
|
||||
@@ -131,8 +89,6 @@ export const formAConsultationTestPlacements: ReadonlyArray<FormAIframePlacement
|
||||
{ route: '/es/learner-social-club', locale: 'es', context: 'consultation' },
|
||||
];
|
||||
|
||||
const isTrue = (value: string | undefined) => value?.trim().toLowerCase() === 'true';
|
||||
|
||||
function formAIframeCopy(locale: 'en' | 'es', context: FormAIframeContext) {
|
||||
const consultation = context === 'consultation';
|
||||
return locale === 'es'
|
||||
@@ -150,17 +106,16 @@ function formAIframeCopy(locale: 'en' | 'es', context: FormAIframeContext) {
|
||||
|
||||
/** Builds a fixed, allowlisted URL; it accepts neither visitor data nor URL parameters. */
|
||||
export function buildFormAIframeUrl(locale: 'en' | 'es', context: FormAIframeContext): string {
|
||||
if (!['en', 'es'].includes(locale) || !['contact', 'landing', 'consultation'].includes(context)) {
|
||||
throw new Error('Unsupported Form A locale or context');
|
||||
}
|
||||
const url = new URL(`/${formAIframeId}`, formAIframeOrigin);
|
||||
url.searchParams.set('formContext', context);
|
||||
url.searchParams.set('language', locale);
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the real Form A iframe only through one of two explicit gates:
|
||||
* a non-indexing isolated test, or a separately approved production build.
|
||||
* No API URL, hostname, indexing setting, or form ID can activate it alone.
|
||||
*/
|
||||
/** Enables Form A only for a fixed route/locale pairing in live mode. */
|
||||
export function resolveFormAIframe(options: ResolveFormAIframeOptions): FormAIframeConfig {
|
||||
const disabled = (reason: Exclude<FormAIframeReason, 'enabled'>): FormAIframeConfig => ({
|
||||
enabled: false,
|
||||
@@ -168,45 +123,17 @@ export function resolveFormAIframe(options: ResolveFormAIframeOptions): FormAIfr
|
||||
route: options.route,
|
||||
locale: options.locale,
|
||||
});
|
||||
const config = resolveFormMode(options.rawMode, options.liveApproved);
|
||||
const environmentRole = options.environmentRole?.trim().toLowerCase();
|
||||
let mode: 'isolated-test' | 'live';
|
||||
let approvedEnvironment: 'isolated-test' | 'production';
|
||||
|
||||
if (config.mode === 'isolated-test') {
|
||||
if (options.liveApproved?.trim().toLowerCase() !== 'false') return disabled('live-approval-not-disabled');
|
||||
if (!isTrue(options.isolatedTestApproved)) return disabled('isolated-test-not-approved');
|
||||
if (environmentRole !== isolatedTestEnvironmentRole) return disabled('invalid-environment-role');
|
||||
if (isTrue(options.allowIndexing)) return disabled('indexing-enabled');
|
||||
mode = 'isolated-test';
|
||||
approvedEnvironment = 'isolated-test';
|
||||
} else if (config.mode === 'live') {
|
||||
if (!isTrue(options.productionApproved)) return disabled('production-approval-not-granted');
|
||||
if (environmentRole !== productionEnvironmentRole) return disabled('invalid-environment-role');
|
||||
mode = 'live';
|
||||
approvedEnvironment = 'production';
|
||||
} else {
|
||||
return disabled('mode-not-authorized');
|
||||
}
|
||||
|
||||
const standardPlacement = formAIframePlacements.find((candidate) => candidate.route === options.route);
|
||||
const consultationPlacement = formAConsultationTestPlacements.find((candidate) => candidate.route === options.route);
|
||||
const placement = mode === 'isolated-test'
|
||||
? standardPlacement ?? consultationPlacement
|
||||
: standardPlacement;
|
||||
if (resolveFormMode(options.rawMode).mode !== 'live') return disabled('mode-not-authorized');
|
||||
const placement = formAIframePlacements.find((candidate) => candidate.route === options.route);
|
||||
if (!placement) return disabled('route-not-authorized');
|
||||
if (options.locale !== placement.locale) return disabled('locale-not-authorized');
|
||||
if (placement.context === 'consultation' && (options.allowIndexing !== 'false' || !isTrue(options.consultationTestApproved))) {
|
||||
return disabled('consultation-test-not-approved');
|
||||
}
|
||||
|
||||
return {
|
||||
enabled: true,
|
||||
reason: 'enabled',
|
||||
route: options.route,
|
||||
locale: placement.locale,
|
||||
mode,
|
||||
environmentRole: approvedEnvironment,
|
||||
mode: 'live',
|
||||
context: placement.context,
|
||||
url: buildFormAIframeUrl(placement.locale, placement.context),
|
||||
...formAIframeCopy(placement.locale, placement.context),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Build-only reader; never imported by a browser script.
|
||||
import fs from 'node:fs';
|
||||
import { validatePortalPayload } from './portal-crypto.mjs';
|
||||
export function readPortalInput({ approved, indexing, environment, file }) {
|
||||
if (approved !== 'true' || indexing !== 'false' || environment !== 'isolated-test' || !file) return undefined;
|
||||
export function readPortalInput({ approved, indexing, file }) {
|
||||
if (approved !== 'true' || indexing !== 'false' || !file) return undefined;
|
||||
try {
|
||||
if (fs.statSync(file).size > 12_000_000) return undefined;
|
||||
return validatePortalPayload(JSON.parse(fs.readFileSync(file, 'utf8')));
|
||||
|
||||
Reference in new issue
Block a user