import { environment } from '../environments/environment'; // Is the practice's WordPress SITE CONFIGURED for https? - Spencer, 2026-08-15: // *"https needs to be forced in this app... and needs to be part of the onboarding process for a new org."* // // THIS IS NOT THE SAME QUESTION AS `window.isSecureContext`, AND CONFUSING THEM MAKES THE STEP USELESS. // The server-side gate in `class-akashere-secure-transport.php` already refuses to render the portal over // http - so by the time this code runs, THIS request is always secure and `isSecureContext` is always // true. Reading it here would produce a checklist item that can never fail. // // THE STATE THIS EXISTS TO CATCH is the one the gate cannot: a site that answers on BOTH schemes, // which is the ordinary case because almost nobody configures the redirect. The admin types https, sees a // working portal and a green checklist; WordPress goes on generating http links from its stored Site // Address, so every patient who follows one gets the refusal notice. **The practice's own setup looks // finished and their patients cannot get in.** export type SiteTransportFacts = { /** WordPress "Site Address" (`home`) - what patient-facing links are built from. */ homeSecure?: boolean; /** WordPress "WordPress Address" (`siteurl`) - where wp-admin and the login form live. */ siteUrlSecure?: boolean; }; /** * `true` / `false` / `undefined`, and the third one is load-bearing. * * An unmeasurable site must NOT coalesce to `false`: telling a practice their site is insecure * because we could not find out is a false accusation, and on a REQUIRED step it would also wedge * onboarding permanently for anyone running the app outside WordPress. Nor to `true`, which is the * silent pass this card exists to close. **The caller drops the step entirely when it cannot be * measured** - the only answer that asserts nothing in either direction. * * That is safe precisely BECAUSE the protection is not this step: the server-side gate still refuses * to serve PHI over http whatever the checklist says. This step exists to stop a practice completing * setup while their patients are locked out, not to be the boundary itself. */ export function siteTransportSecure(facts: SiteTransportFacts | undefined): boolean | undefined { if (!facts) return undefined; const { homeSecure, siteUrlSecure } = facts; if (typeof homeSecure !== 'boolean' || typeof siteUrlSecure !== 'boolean') return undefined; // BOTH, not either. The Site Address is what patients follow; the WordPress Address is where the // login form posts. A practice with one of the two on http still has a door open in clear text. return homeSecure && siteUrlSecure; } /** * Which of the two settings is wrong, for copy that names the setting instead of saying "something". * Returns `undefined` when nothing is wrong or nothing could be measured. */ export function insecureSiteSettings( facts: SiteTransportFacts | undefined, ): ('Site Address' | 'WordPress Address')[] | undefined { if (siteTransportSecure(facts) !== false) return undefined; const wrong: ('Site Address' | 'WordPress Address')[] = []; if (!facts?.homeSecure) wrong.push('Site Address'); if (!facts?.siteUrlSecure) wrong.push('WordPress Address'); return wrong; } /** Reads what the plugin localized onto every mount. Absent the app is not running inside WordPress. */ export function readSiteTransportSecure(): boolean | undefined { return siteTransportSecure(environment.wpData?.siteTransport as SiteTransportFacts | undefined); }