@burdenoff/microfe-auth 2026.917.2 → 2026.925.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* domain would send every other product's users to the wrong company's terms.
|
|
24
24
|
* Every product serves its marketing site at `www.<product-domain>` using the
|
|
25
25
|
* same `/terms` and `/privacy` route names (verified against fluidgrids.ai,
|
|
26
|
-
* burdenoff.com, bigconsole.com, planmagnet.com, adaptercloud.com,
|
|
26
|
+
* burdenoff.com, bigconsole.com, planmagnet.com, adaptercloud.com, botmanor.com and
|
|
27
27
|
* timecampus.com).
|
|
28
28
|
*/
|
|
29
29
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legalUrls.js","names":[],"sources":["../../../src/auth/utils/legalUrls.ts"],"sourcesContent":["/**\n * Public legal-document URLs for the signup consent copy.\n *\n * The signup form is shown to SIGNED-OUT visitors, so its \"Terms of Service\" and\n * \"Privacy Policy\" links must resolve to the public marketing site. They used to\n * be written as the app-relative paths `/legal/terms` and `/legal/privacy`, which\n * resolved against the app origin (e.g. `https://app.fluidgrids.ai/legal/terms`).\n * That route lives *inside* the shell's authenticated block, so a visitor who\n * clicked it was bounced to `/auth/login?returnTo=%2Flegal%2Fterms` and the shell\n * footer fired two FORBIDDEN queries on the way out:\n *\n * [Burdenoff backend error] You do not have permission to do that.\n * {code: FORBIDDEN, operationName: GetFooterContentPages}\n * {code: FORBIDDEN, operationName: GetFooterProduct}\n *\n * i.e. the consent links were unreadable for exactly the people being asked to\n * consent. The marketing site is also the authoritative home of the policy text\n * (rendered from the dated drafts in `fluidgrids-website/src/content/legal/`),\n * so linking there avoids maintaining a second copy that can drift.\n *\n * microfe-auth is mounted by every Burdenoff product shell, so the origin is\n * DERIVED from the current host rather than hardcoded — hardcoding one product's\n * domain would send every other product's users to the wrong company's terms.\n * Every product serves its marketing site at `www.<product-domain>` using the\n * same `/terms` and `/privacy` route names (verified against fluidgrids.ai,\n * burdenoff.com, bigconsole.com, planmagnet.com, adaptercloud.com,
|
|
1
|
+
{"version":3,"file":"legalUrls.js","names":[],"sources":["../../../src/auth/utils/legalUrls.ts"],"sourcesContent":["/**\n * Public legal-document URLs for the signup consent copy.\n *\n * The signup form is shown to SIGNED-OUT visitors, so its \"Terms of Service\" and\n * \"Privacy Policy\" links must resolve to the public marketing site. They used to\n * be written as the app-relative paths `/legal/terms` and `/legal/privacy`, which\n * resolved against the app origin (e.g. `https://app.fluidgrids.ai/legal/terms`).\n * That route lives *inside* the shell's authenticated block, so a visitor who\n * clicked it was bounced to `/auth/login?returnTo=%2Flegal%2Fterms` and the shell\n * footer fired two FORBIDDEN queries on the way out:\n *\n * [Burdenoff backend error] You do not have permission to do that.\n * {code: FORBIDDEN, operationName: GetFooterContentPages}\n * {code: FORBIDDEN, operationName: GetFooterProduct}\n *\n * i.e. the consent links were unreadable for exactly the people being asked to\n * consent. The marketing site is also the authoritative home of the policy text\n * (rendered from the dated drafts in `fluidgrids-website/src/content/legal/`),\n * so linking there avoids maintaining a second copy that can drift.\n *\n * microfe-auth is mounted by every Burdenoff product shell, so the origin is\n * DERIVED from the current host rather than hardcoded — hardcoding one product's\n * domain would send every other product's users to the wrong company's terms.\n * Every product serves its marketing site at `www.<product-domain>` using the\n * same `/terms` and `/privacy` route names (verified against fluidgrids.ai,\n * burdenoff.com, bigconsole.com, planmagnet.com, adaptercloud.com, botmanor.com and\n * timecampus.com).\n */\n\n/**\n * Shell subdomains that front a product's app surface. Stripping one of these\n * leaves the bare product domain whose `www.` host serves the marketing site.\n */\nconst APP_HOST_PREFIXES = [\n \"app.\",\n \"alphaapp.\",\n \"admin.\",\n \"alphaadmin.\",\n \"www.\",\n];\n\n/**\n * Resolve the public marketing origin for the product currently being served,\n * or `null` when it cannot be determined (local development, or a host with no\n * registrable domain). Exported for unit testing; prefer `resolveLegalUrl`.\n */\nexport function resolveMarketingOrigin(hostname?: string): string | null {\n const host = (\n hostname ?? (typeof window !== \"undefined\" ? window.location.hostname : \"\")\n )\n .toLowerCase()\n .trim();\n\n if (!host) return null;\n\n // Local development has no marketing site to link to. `0.0.0.0` and IPv6\n // literals (which `location.hostname` reports bracketed, e.g. \"[::1]\") are\n // included because a bare dotted-quad would otherwise survive the \"has a dot\"\n // check below and produce a nonsense origin like `https://www.0.0.0.0`.\n if (\n host === \"localhost\" ||\n host === \"127.0.0.1\" ||\n host === \"0.0.0.0\" ||\n host.startsWith(\"[\") ||\n host.endsWith(\".local.burdenoff.com\")\n ) {\n return null;\n }\n\n // Any other IPv4 literal is likewise not a registrable domain.\n if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(host)) return null;\n\n let domain = host;\n for (const prefix of APP_HOST_PREFIXES) {\n if (domain.startsWith(prefix)) {\n domain = domain.slice(prefix.length);\n break;\n }\n }\n\n // A bare hostname with no dot is not a registrable domain we can build on.\n if (!domain.includes(\".\")) return null;\n\n return `https://www.${domain}`;\n}\n\n/** Public legal pages, by the route name every product marketing site uses. */\nexport type LegalDocumentPath = \"/terms\" | \"/privacy\";\n\n/**\n * Absolute URL of a public legal document for the current product.\n *\n * Falls back to the bare path when the marketing origin cannot be resolved\n * (local development), which keeps the link valid-looking in dev without\n * inventing a production domain.\n */\nexport function resolveLegalUrl(path: LegalDocumentPath): string {\n const origin = resolveMarketingOrigin();\n return origin ? `${origin}${path}` : path;\n}\n"],"mappings":";AAiCA,IAAM,IAAoB;CACxB;CACA;CACA;CACA;CACA;CACD;AAOD,SAAgB,EAAuB,GAAkC;CACvE,IAAM,KACJ,MAAa,OAAO,SAAW,MAAc,OAAO,SAAS,WAAW,KAEvE,aAAa,CACb,MAAM;AAmBT,KAjBI,CAAC,KAOH,MAAS,eACT,MAAS,eACT,MAAS,aACT,EAAK,WAAW,IAAI,IACpB,EAAK,SAAS,uBAAuB,IAMnC,uBAAuB,KAAK,EAAK,CAAE,QAAO;CAE9C,IAAI,IAAS;AACb,MAAK,IAAM,KAAU,EACnB,KAAI,EAAO,WAAW,EAAO,EAAE;AAC7B,MAAS,EAAO,MAAM,EAAO,OAAO;AACpC;;AAOJ,QAFK,EAAO,SAAS,IAAI,GAElB,eAAe,MAFY;;AAepC,SAAgB,EAAgB,GAAiC;CAC/D,IAAM,IAAS,GAAwB;AACvC,QAAO,IAAS,GAAG,IAAS,MAAS"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/auth/utils/ssoOrigins.ts
|
|
2
|
-
var e = new Set(/* @__PURE__ */ "burdenoff.com,vibecontrols.com,fluidgrids.com,botlit.ai,bigconsole.com,gethealthybowl.com,headshotmarketing.com,timecampus.com,ggnomad.com,movethewheels.com,crewfoundry.com,planmagnet.com,eventfullymanaged.com,kadaikodi.com,assethandler.com,technospam.com,semanticfed.com,manufacturedops.com,theglobalfuel.com,housingvista.com,proserviceworld.com,mybodyshield.com,artistrybase.com,collabkin.com,brainyrich.com,theculturepost.com,comradecircle.com,cosmicintersection.com,govcitizenhub.com,intelwatchtower.com,ecoimpacthub.com,buildmyiq.com,fluidgrids.ai,atheletebridge.com,adaptercloud.com,coolandlovely.com,subscriberbot.com,labsofscience.com,hookmovies.com".split(","));
|
|
2
|
+
var e = new Set(/* @__PURE__ */ "burdenoff.com,vibecontrols.com,fluidgrids.com,botlit.ai,botmanor.com,bigconsole.com,gethealthybowl.com,headshotmarketing.com,timecampus.com,ggnomad.com,movethewheels.com,crewfoundry.com,planmagnet.com,eventfullymanaged.com,kadaikodi.com,assethandler.com,technospam.com,semanticfed.com,manufacturedops.com,theglobalfuel.com,housingvista.com,proserviceworld.com,mybodyshield.com,artistrybase.com,collabkin.com,brainyrich.com,theculturepost.com,comradecircle.com,cosmicintersection.com,govcitizenhub.com,intelwatchtower.com,ecoimpacthub.com,buildmyiq.com,fluidgrids.ai,atheletebridge.com,adaptercloud.com,coolandlovely.com,subscriberbot.com,labsofscience.com,hookmovies.com".split(","));
|
|
3
3
|
function t(t) {
|
|
4
4
|
if (t.hostname === "localhost" || t.hostname === "127.0.0.1" || t.hostname.endsWith(".local.burdenoff.com")) return !0;
|
|
5
5
|
if (t.protocol !== "https:") return !1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssoOrigins.js","names":[],"sources":["../../../src/auth/utils/ssoOrigins.ts"],"sourcesContent":["/**\n * Shared first-party SSO origin allow-list for the cross-domain auth pages\n * (SSOClearPage, SSODepositPage, SSORelayPage, SessionBridgePage).\n *\n * These four pages each used to hand-roll an identical copy of this domain set\n * plus its matching function, and they drifted independently — BOFF-4120 was\n * exactly that drift (SSOClearPage's copy was missing admin./alphaadmin., so an\n * admin logout returnTo was rejected on the bridge host and stranded the\n * operator on app.burdenoff.com). Keep the list + matching logic HERE only so\n * a new product domain or subdomain is added in one place. BOFF-4124.\n */\n\nconst ALLOWED_SSO_DOMAINS = new Set<string>([\n \"burdenoff.com\",\n \"vibecontrols.com\",\n \"fluidgrids.com\",\n \"botlit.ai\",\n \"bigconsole.com\",\n \"gethealthybowl.com\",\n \"headshotmarketing.com\",\n \"timecampus.com\",\n \"ggnomad.com\",\n \"movethewheels.com\",\n \"crewfoundry.com\",\n \"planmagnet.com\",\n \"eventfullymanaged.com\",\n \"kadaikodi.com\",\n \"assethandler.com\",\n \"technospam.com\",\n \"semanticfed.com\",\n \"manufacturedops.com\",\n \"theglobalfuel.com\",\n \"housingvista.com\",\n \"proserviceworld.com\",\n \"mybodyshield.com\",\n \"artistrybase.com\",\n \"collabkin.com\",\n \"brainyrich.com\",\n \"theculturepost.com\",\n \"comradecircle.com\",\n \"cosmicintersection.com\",\n \"govcitizenhub.com\",\n \"intelwatchtower.com\",\n \"ecoimpacthub.com\",\n \"buildmyiq.com\",\n \"fluidgrids.ai\",\n \"atheletebridge.com\",\n \"adaptercloud.com\",\n \"coolandlovely.com\",\n \"subscriberbot.com\",\n \"labsofscience.com\",\n \"hookmovies.com\",\n]);\n\n/**\n * True when `url` is a first-party Burdenoff shell origin permitted to take\n * part in the cross-domain SSO relay / clear / deposit / session-bridge flow:\n * - localhost / 127.0.0.1 (any port, local dev)\n * - *.local.burdenoff.com (local dev behind nginx)\n * - https://{\"\" | app. | alphaapp. | admin. | alphaadmin. | www.}<product-domain>\n * — note admin./alphaadmin. are included: the admin app shells\n * (admin.burdenoff.com / alphaadmin.burdenoff.com) are first-party origins\n * that relay through and return from the central bridge host.\n */\nexport function isAllowedSsoOrigin(url: URL): boolean {\n if (url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\") return true;\n if (url.hostname.endsWith(\".local.burdenoff.com\")) return true;\n if (url.protocol !== \"https:\") return false;\n for (const domain of ALLOWED_SSO_DOMAINS) {\n if (\n url.hostname === domain ||\n url.hostname === `app.${domain}` ||\n url.hostname === `alphaapp.${domain}` ||\n url.hostname === `admin.${domain}` ||\n url.hostname === `alphaadmin.${domain}` ||\n url.hostname === `www.${domain}`\n ) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * String-origin variant for postMessage origin checks (SessionBridgePage),\n * which receives a raw origin string rather than a parsed URL. Returns false on\n * an unparseable origin.\n */\nexport function isAllowedSsoOriginString(origin: string): boolean {\n try {\n return isAllowedSsoOrigin(new URL(origin));\n } catch {\n return false;\n }\n}\n"],"mappings":";AAYA,IAAM,IAAsB,IAAI,IAAY,
|
|
1
|
+
{"version":3,"file":"ssoOrigins.js","names":[],"sources":["../../../src/auth/utils/ssoOrigins.ts"],"sourcesContent":["/**\n * Shared first-party SSO origin allow-list for the cross-domain auth pages\n * (SSOClearPage, SSODepositPage, SSORelayPage, SessionBridgePage).\n *\n * These four pages each used to hand-roll an identical copy of this domain set\n * plus its matching function, and they drifted independently — BOFF-4120 was\n * exactly that drift (SSOClearPage's copy was missing admin./alphaadmin., so an\n * admin logout returnTo was rejected on the bridge host and stranded the\n * operator on app.burdenoff.com). Keep the list + matching logic HERE only so\n * a new product domain or subdomain is added in one place. BOFF-4124.\n */\n\nconst ALLOWED_SSO_DOMAINS = new Set<string>([\n \"burdenoff.com\",\n \"vibecontrols.com\",\n \"fluidgrids.com\",\n // BotManor (formerly Botlit): botmanor.com is the primary domain; botlit.ai\n // stays trusted while it redirects there, so in-flight relays still return.\n \"botlit.ai\",\n \"botmanor.com\",\n \"bigconsole.com\",\n \"gethealthybowl.com\",\n \"headshotmarketing.com\",\n \"timecampus.com\",\n \"ggnomad.com\",\n \"movethewheels.com\",\n \"crewfoundry.com\",\n \"planmagnet.com\",\n \"eventfullymanaged.com\",\n \"kadaikodi.com\",\n \"assethandler.com\",\n \"technospam.com\",\n \"semanticfed.com\",\n \"manufacturedops.com\",\n \"theglobalfuel.com\",\n \"housingvista.com\",\n \"proserviceworld.com\",\n \"mybodyshield.com\",\n \"artistrybase.com\",\n \"collabkin.com\",\n \"brainyrich.com\",\n \"theculturepost.com\",\n \"comradecircle.com\",\n \"cosmicintersection.com\",\n \"govcitizenhub.com\",\n \"intelwatchtower.com\",\n \"ecoimpacthub.com\",\n \"buildmyiq.com\",\n \"fluidgrids.ai\",\n \"atheletebridge.com\",\n \"adaptercloud.com\",\n \"coolandlovely.com\",\n \"subscriberbot.com\",\n \"labsofscience.com\",\n \"hookmovies.com\",\n]);\n\n/**\n * True when `url` is a first-party Burdenoff shell origin permitted to take\n * part in the cross-domain SSO relay / clear / deposit / session-bridge flow:\n * - localhost / 127.0.0.1 (any port, local dev)\n * - *.local.burdenoff.com (local dev behind nginx)\n * - https://{\"\" | app. | alphaapp. | admin. | alphaadmin. | www.}<product-domain>\n * — note admin./alphaadmin. are included: the admin app shells\n * (admin.burdenoff.com / alphaadmin.burdenoff.com) are first-party origins\n * that relay through and return from the central bridge host.\n */\nexport function isAllowedSsoOrigin(url: URL): boolean {\n if (url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\") return true;\n if (url.hostname.endsWith(\".local.burdenoff.com\")) return true;\n if (url.protocol !== \"https:\") return false;\n for (const domain of ALLOWED_SSO_DOMAINS) {\n if (\n url.hostname === domain ||\n url.hostname === `app.${domain}` ||\n url.hostname === `alphaapp.${domain}` ||\n url.hostname === `admin.${domain}` ||\n url.hostname === `alphaadmin.${domain}` ||\n url.hostname === `www.${domain}`\n ) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * String-origin variant for postMessage origin checks (SessionBridgePage),\n * which receives a raw origin string rather than a parsed URL. Returns false on\n * an unparseable origin.\n */\nexport function isAllowedSsoOriginString(origin: string): boolean {\n try {\n return isAllowedSsoOrigin(new URL(origin));\n } catch {\n return false;\n }\n}\n"],"mappings":";AAYA,IAAM,IAAsB,IAAI,IAAY,2rBA2C3C,CAAC;AAYF,SAAgB,EAAmB,GAAmB;AAEpD,KADI,EAAI,aAAa,eAAe,EAAI,aAAa,eACjD,EAAI,SAAS,SAAS,uBAAuB,CAAE,QAAO;AAC1D,KAAI,EAAI,aAAa,SAAU,QAAO;AACtC,MAAK,IAAM,KAAU,EACnB,KACE,EAAI,aAAa,KACjB,EAAI,aAAa,OAAO,OACxB,EAAI,aAAa,YAAY,OAC7B,EAAI,aAAa,SAAS,OAC1B,EAAI,aAAa,cAAc,OAC/B,EAAI,aAAa,OAAO,IAExB,QAAO;AAGX,QAAO;;AAQT,SAAgB,EAAyB,GAAyB;AAChE,KAAI;AACF,SAAO,EAAmB,IAAI,IAAI,EAAO,CAAC;SACpC;AACN,SAAO"}
|