@aglyn/aglyn 1.0.0-beta.143
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.
- package/LICENSE +201 -0
- package/README.md +11 -0
- package/package.json +66 -0
- package/src/index.d.ts +25 -0
- package/src/index.js +26 -0
- package/src/index.js.map +1 -0
- package/src/lib/aglyn.d.ts +31 -0
- package/src/lib/aglyn.js +114 -0
- package/src/lib/aglyn.js.map +1 -0
- package/src/lib/app-utils/abuse-report.d.ts +193 -0
- package/src/lib/app-utils/abuse-report.js +321 -0
- package/src/lib/app-utils/abuse-report.js.map +1 -0
- package/src/lib/app-utils/accept-negotiation.d.ts +129 -0
- package/src/lib/app-utils/accept-negotiation.js +266 -0
- package/src/lib/app-utils/accept-negotiation.js.map +1 -0
- package/src/lib/app-utils/account-emails.d.ts +263 -0
- package/src/lib/app-utils/account-emails.js +264 -0
- package/src/lib/app-utils/account-emails.js.map +1 -0
- package/src/lib/app-utils/actions.d.ts +717 -0
- package/src/lib/app-utils/actions.js +1031 -0
- package/src/lib/app-utils/actions.js.map +1 -0
- package/src/lib/app-utils/activity-presenter.d.ts +152 -0
- package/src/lib/app-utils/activity-presenter.js +326 -0
- package/src/lib/app-utils/activity-presenter.js.map +1 -0
- package/src/lib/app-utils/advertising-tag-mounts.d.ts +133 -0
- package/src/lib/app-utils/advertising-tag-mounts.js +118 -0
- package/src/lib/app-utils/advertising-tag-mounts.js.map +1 -0
- package/src/lib/app-utils/advertising-tags.d.ts +307 -0
- package/src/lib/app-utils/advertising-tags.js +525 -0
- package/src/lib/app-utils/advertising-tags.js.map +1 -0
- package/src/lib/app-utils/agent-api-catalog.d.ts +94 -0
- package/src/lib/app-utils/agent-api-catalog.js +106 -0
- package/src/lib/app-utils/agent-api-catalog.js.map +1 -0
- package/src/lib/app-utils/agent-openapi.d.ts +103 -0
- package/src/lib/app-utils/agent-openapi.js +1128 -0
- package/src/lib/app-utils/agent-openapi.js.map +1 -0
- package/src/lib/app-utils/analytics-beacon.d.ts +154 -0
- package/src/lib/app-utils/analytics-beacon.js +152 -0
- package/src/lib/app-utils/analytics-beacon.js.map +1 -0
- package/src/lib/app-utils/analytics-environment.d.ts +133 -0
- package/src/lib/app-utils/analytics-environment.js +152 -0
- package/src/lib/app-utils/analytics-environment.js.map +1 -0
- package/src/lib/app-utils/analytics-events.d.ts +744 -0
- package/src/lib/app-utils/analytics-events.js +650 -0
- package/src/lib/app-utils/analytics-events.js.map +1 -0
- package/src/lib/app-utils/analytics-link-clicks.d.ts +102 -0
- package/src/lib/app-utils/analytics-link-clicks.js +267 -0
- package/src/lib/app-utils/analytics-link-clicks.js.map +1 -0
- package/src/lib/app-utils/analytics-path-key.d.ts +46 -0
- package/src/lib/app-utils/analytics-path-key.js +46 -0
- package/src/lib/app-utils/analytics-path-key.js.map +1 -0
- package/src/lib/app-utils/api-adapter.d.ts +47 -0
- package/src/lib/app-utils/api-adapter.js +367 -0
- package/src/lib/app-utils/api-adapter.js.map +1 -0
- package/src/lib/app-utils/api-idempotency.d.ts +169 -0
- package/src/lib/app-utils/api-idempotency.js +213 -0
- package/src/lib/app-utils/api-idempotency.js.map +1 -0
- package/src/lib/app-utils/api-plugins.d.ts +210 -0
- package/src/lib/app-utils/api-plugins.js +221 -0
- package/src/lib/app-utils/api-plugins.js.map +1 -0
- package/src/lib/app-utils/assist-credits.d.ts +482 -0
- package/src/lib/app-utils/assist-credits.js +509 -0
- package/src/lib/app-utils/assist-credits.js.map +1 -0
- package/src/lib/app-utils/attribution-attribute.d.ts +34 -0
- package/src/lib/app-utils/attribution-attribute.js +34 -0
- package/src/lib/app-utils/attribution-attribute.js.map +1 -0
- package/src/lib/app-utils/attribution-guard.d.ts +130 -0
- package/src/lib/app-utils/attribution-guard.js +410 -0
- package/src/lib/app-utils/attribution-guard.js.map +1 -0
- package/src/lib/app-utils/author-css.d.ts +123 -0
- package/src/lib/app-utils/author-css.js +275 -0
- package/src/lib/app-utils/author-css.js.map +1 -0
- package/src/lib/app-utils/author-html-markdown.d.ts +31 -0
- package/src/lib/app-utils/author-html-markdown.js +497 -0
- package/src/lib/app-utils/author-html-markdown.js.map +1 -0
- package/src/lib/app-utils/author-html.d.ts +135 -0
- package/src/lib/app-utils/author-html.js +1037 -0
- package/src/lib/app-utils/author-html.js.map +1 -0
- package/src/lib/app-utils/automation-placeholders.d.ts +72 -0
- package/src/lib/app-utils/automation-placeholders.js +207 -0
- package/src/lib/app-utils/automation-placeholders.js.map +1 -0
- package/src/lib/app-utils/bandwidth-cap.d.ts +183 -0
- package/src/lib/app-utils/bandwidth-cap.js +193 -0
- package/src/lib/app-utils/bandwidth-cap.js.map +1 -0
- package/src/lib/app-utils/binding-token-catalog.d.ts +82 -0
- package/src/lib/app-utils/binding-token-catalog.js +293 -0
- package/src/lib/app-utils/binding-token-catalog.js.map +1 -0
- package/src/lib/app-utils/binding-tokens.d.ts +157 -0
- package/src/lib/app-utils/binding-tokens.js +251 -0
- package/src/lib/app-utils/binding-tokens.js.map +1 -0
- package/src/lib/app-utils/breadcrumb-json-ld.d.ts +57 -0
- package/src/lib/app-utils/breadcrumb-json-ld.js +67 -0
- package/src/lib/app-utils/breadcrumb-json-ld.js.map +1 -0
- package/src/lib/app-utils/campaign-attribution.d.ts +117 -0
- package/src/lib/app-utils/campaign-attribution.js +162 -0
- package/src/lib/app-utils/campaign-attribution.js.map +1 -0
- package/src/lib/app-utils/campaign-forwarding.d.ts +220 -0
- package/src/lib/app-utils/campaign-forwarding.js +332 -0
- package/src/lib/app-utils/campaign-forwarding.js.map +1 -0
- package/src/lib/app-utils/campaign-membership.d.ts +109 -0
- package/src/lib/app-utils/campaign-membership.js +176 -0
- package/src/lib/app-utils/campaign-membership.js.map +1 -0
- package/src/lib/app-utils/campaign-touch.d.ts +206 -0
- package/src/lib/app-utils/campaign-touch.js +326 -0
- package/src/lib/app-utils/campaign-touch.js.map +1 -0
- package/src/lib/app-utils/child-contract-compose.d.ts +28 -0
- package/src/lib/app-utils/child-contract-compose.js +140 -0
- package/src/lib/app-utils/child-contract-compose.js.map +1 -0
- package/src/lib/app-utils/child-contract.d.ts +129 -0
- package/src/lib/app-utils/child-contract.js +153 -0
- package/src/lib/app-utils/child-contract.js.map +1 -0
- package/src/lib/app-utils/collection-delete.d.ts +113 -0
- package/src/lib/app-utils/collection-delete.js +120 -0
- package/src/lib/app-utils/collection-delete.js.map +1 -0
- package/src/lib/app-utils/collection-entries.d.ts +833 -0
- package/src/lib/app-utils/collection-entries.js +1285 -0
- package/src/lib/app-utils/collection-entries.js.map +1 -0
- package/src/lib/app-utils/collection-entry-date.d.ts +129 -0
- package/src/lib/app-utils/collection-entry-date.js +183 -0
- package/src/lib/app-utils/collection-entry-date.js.map +1 -0
- package/src/lib/app-utils/collection-kind.d.ts +55 -0
- package/src/lib/app-utils/collection-kind.js +69 -0
- package/src/lib/app-utils/collection-kind.js.map +1 -0
- package/src/lib/app-utils/collection-slug.d.ts +79 -0
- package/src/lib/app-utils/collection-slug.js +70 -0
- package/src/lib/app-utils/collection-slug.js.map +1 -0
- package/src/lib/app-utils/compose-layout-nodes.d.ts +147 -0
- package/src/lib/app-utils/compose-layout-nodes.js +261 -0
- package/src/lib/app-utils/compose-layout-nodes.js.map +1 -0
- package/src/lib/app-utils/compose-layout-props.d.ts +71 -0
- package/src/lib/app-utils/compose-layout-props.js +61 -0
- package/src/lib/app-utils/compose-layout-props.js.map +1 -0
- package/src/lib/app-utils/compose-reusable-components.d.ts +504 -0
- package/src/lib/app-utils/compose-reusable-components.js +1366 -0
- package/src/lib/app-utils/compose-reusable-components.js.map +1 -0
- package/src/lib/app-utils/compress.d.ts +35 -0
- package/src/lib/app-utils/compress.js +38 -0
- package/src/lib/app-utils/compress.js.map +1 -0
- package/src/lib/app-utils/consent-banner-ui.d.ts +226 -0
- package/src/lib/app-utils/consent-banner-ui.js +583 -0
- package/src/lib/app-utils/consent-banner-ui.js.map +1 -0
- package/src/lib/app-utils/consent-groups.d.ts +189 -0
- package/src/lib/app-utils/consent-groups.js +219 -0
- package/src/lib/app-utils/consent-groups.js.map +1 -0
- package/src/lib/app-utils/consent-preferences-dialog.d.ts +58 -0
- package/src/lib/app-utils/consent-preferences-dialog.js +106 -0
- package/src/lib/app-utils/consent-preferences-dialog.js.map +1 -0
- package/src/lib/app-utils/console-record-links.d.ts +163 -0
- package/src/lib/app-utils/console-record-links.js +178 -0
- package/src/lib/app-utils/console-record-links.js.map +1 -0
- package/src/lib/app-utils/console-routes.d.ts +658 -0
- package/src/lib/app-utils/console-routes.js +489 -0
- package/src/lib/app-utils/console-routes.js.map +1 -0
- package/src/lib/app-utils/console-widget-slot-context.d.ts +46 -0
- package/src/lib/app-utils/console-widget-slot-context.js +23 -0
- package/src/lib/app-utils/console-widget-slot-context.js.map +1 -0
- package/src/lib/app-utils/contact-custom-fields.d.ts +191 -0
- package/src/lib/app-utils/contact-custom-fields.js +349 -0
- package/src/lib/app-utils/contact-custom-fields.js.map +1 -0
- package/src/lib/app-utils/contact-holder.d.ts +52 -0
- package/src/lib/app-utils/contact-holder.js +98 -0
- package/src/lib/app-utils/contact-holder.js.map +1 -0
- package/src/lib/app-utils/contact-merge.d.ts +136 -0
- package/src/lib/app-utils/contact-merge.js +379 -0
- package/src/lib/app-utils/contact-merge.js.map +1 -0
- package/src/lib/app-utils/contacts.d.ts +554 -0
- package/src/lib/app-utils/contacts.js +401 -0
- package/src/lib/app-utils/contacts.js.map +1 -0
- package/src/lib/app-utils/content-author-profile.d.ts +68 -0
- package/src/lib/app-utils/content-author-profile.js +118 -0
- package/src/lib/app-utils/content-author-profile.js.map +1 -0
- package/src/lib/app-utils/content-authors.d.ts +662 -0
- package/src/lib/app-utils/content-authors.js +771 -0
- package/src/lib/app-utils/content-authors.js.map +1 -0
- package/src/lib/app-utils/content-schema-type.d.ts +81 -0
- package/src/lib/app-utils/content-schema-type.js +87 -0
- package/src/lib/app-utils/content-schema-type.js.map +1 -0
- package/src/lib/app-utils/contexts.d.ts +35 -0
- package/src/lib/app-utils/contexts.js +35 -0
- package/src/lib/app-utils/contexts.js.map +1 -0
- package/src/lib/app-utils/create-resource-uid.d.ts +18 -0
- package/src/lib/app-utils/create-resource-uid.js +23 -0
- package/src/lib/app-utils/create-resource-uid.js.map +1 -0
- package/src/lib/app-utils/crm-booking.d.ts +75 -0
- package/src/lib/app-utils/crm-booking.js +133 -0
- package/src/lib/app-utils/crm-booking.js.map +1 -0
- package/src/lib/app-utils/crm-csv.d.ts +232 -0
- package/src/lib/app-utils/crm-csv.js +432 -0
- package/src/lib/app-utils/crm-csv.js.map +1 -0
- package/src/lib/app-utils/crm-digest.d.ts +179 -0
- package/src/lib/app-utils/crm-digest.js +271 -0
- package/src/lib/app-utils/crm-digest.js.map +1 -0
- package/src/lib/app-utils/crm-email-templates.d.ts +172 -0
- package/src/lib/app-utils/crm-email-templates.js +382 -0
- package/src/lib/app-utils/crm-email-templates.js.map +1 -0
- package/src/lib/app-utils/crm-inbound.d.ts +245 -0
- package/src/lib/app-utils/crm-inbound.js +407 -0
- package/src/lib/app-utils/crm-inbound.js.map +1 -0
- package/src/lib/app-utils/crm-kinds.d.ts +73 -0
- package/src/lib/app-utils/crm-kinds.js +92 -0
- package/src/lib/app-utils/crm-kinds.js.map +1 -0
- package/src/lib/app-utils/crm-next-activity.d.ts +107 -0
- package/src/lib/app-utils/crm-next-activity.js +140 -0
- package/src/lib/app-utils/crm-next-activity.js.map +1 -0
- package/src/lib/app-utils/crm-reports.d.ts +479 -0
- package/src/lib/app-utils/crm-reports.js +680 -0
- package/src/lib/app-utils/crm-reports.js.map +1 -0
- package/src/lib/app-utils/crm-task-reminders.d.ts +129 -0
- package/src/lib/app-utils/crm-task-reminders.js +139 -0
- package/src/lib/app-utils/crm-task-reminders.js.map +1 -0
- package/src/lib/app-utils/crm.d.ts +1546 -0
- package/src/lib/app-utils/crm.js +1814 -0
- package/src/lib/app-utils/crm.js.map +1 -0
- package/src/lib/app-utils/csp-report.d.ts +84 -0
- package/src/lib/app-utils/csp-report.js +177 -0
- package/src/lib/app-utils/csp-report.js.map +1 -0
- package/src/lib/app-utils/csv-import.d.ts +192 -0
- package/src/lib/app-utils/csv-import.js +279 -0
- package/src/lib/app-utils/csv-import.js.map +1 -0
- package/src/lib/app-utils/dataset-csv.d.ts +109 -0
- package/src/lib/app-utils/dataset-csv.js +235 -0
- package/src/lib/app-utils/dataset-csv.js.map +1 -0
- package/src/lib/app-utils/dataset-models.d.ts +194 -0
- package/src/lib/app-utils/dataset-models.js +409 -0
- package/src/lib/app-utils/dataset-models.js.map +1 -0
- package/src/lib/app-utils/dataset-query.d.ts +57 -0
- package/src/lib/app-utils/dataset-query.js +126 -0
- package/src/lib/app-utils/dataset-query.js.map +1 -0
- package/src/lib/app-utils/datasets.d.ts +136 -0
- package/src/lib/app-utils/datasets.js +177 -0
- package/src/lib/app-utils/datasets.js.map +1 -0
- package/src/lib/app-utils/decompress.d.ts +36 -0
- package/src/lib/app-utils/decompress.js +32 -0
- package/src/lib/app-utils/decompress.js.map +1 -0
- package/src/lib/app-utils/dedicated-sending-domain.d.ts +47 -0
- package/src/lib/app-utils/dedicated-sending-domain.js +114 -0
- package/src/lib/app-utils/dedicated-sending-domain.js.map +1 -0
- package/src/lib/app-utils/deferred-image.d.ts +86 -0
- package/src/lib/app-utils/deferred-image.js +83 -0
- package/src/lib/app-utils/deferred-image.js.map +1 -0
- package/src/lib/app-utils/definition-canvas-tree.d.ts +61 -0
- package/src/lib/app-utils/definition-canvas-tree.js +126 -0
- package/src/lib/app-utils/definition-canvas-tree.js.map +1 -0
- package/src/lib/app-utils/deployment-shape.d.ts +167 -0
- package/src/lib/app-utils/deployment-shape.js +238 -0
- package/src/lib/app-utils/deployment-shape.js.map +1 -0
- package/src/lib/app-utils/detect-template-placeholders.d.ts +30 -0
- package/src/lib/app-utils/detect-template-placeholders.js +53 -0
- package/src/lib/app-utils/detect-template-placeholders.js.map +1 -0
- package/src/lib/app-utils/dmca-counter-notice.d.ts +185 -0
- package/src/lib/app-utils/dmca-counter-notice.js +277 -0
- package/src/lib/app-utils/dmca-counter-notice.js.map +1 -0
- package/src/lib/app-utils/docs-deflection.d.ts +156 -0
- package/src/lib/app-utils/docs-deflection.js +547 -0
- package/src/lib/app-utils/docs-deflection.js.map +1 -0
- package/src/lib/app-utils/docs-help.d.ts +57 -0
- package/src/lib/app-utils/docs-help.generated.d.ts +303 -0
- package/src/lib/app-utils/docs-help.generated.js +867 -0
- package/src/lib/app-utils/docs-help.generated.js.map +1 -0
- package/src/lib/app-utils/docs-help.js +46 -0
- package/src/lib/app-utils/docs-help.js.map +1 -0
- package/src/lib/app-utils/docs-index.generated.d.ts +29 -0
- package/src/lib/app-utils/docs-index.generated.js +8388 -0
- package/src/lib/app-utils/docs-index.generated.js.map +1 -0
- package/src/lib/app-utils/docs-retrieval.d.ts +67 -0
- package/src/lib/app-utils/docs-retrieval.js +188 -0
- package/src/lib/app-utils/docs-retrieval.js.map +1 -0
- package/src/lib/app-utils/document-landmark.d.ts +50 -0
- package/src/lib/app-utils/document-landmark.js +100 -0
- package/src/lib/app-utils/document-landmark.js.map +1 -0
- package/src/lib/app-utils/duplicate-resource.d.ts +101 -0
- package/src/lib/app-utils/duplicate-resource.js +206 -0
- package/src/lib/app-utils/duplicate-resource.js.map +1 -0
- package/src/lib/app-utils/dynamic-list-rule.d.ts +471 -0
- package/src/lib/app-utils/dynamic-list-rule.js +914 -0
- package/src/lib/app-utils/dynamic-list-rule.js.map +1 -0
- package/src/lib/app-utils/element-animation.d.ts +200 -0
- package/src/lib/app-utils/element-animation.js +233 -0
- package/src/lib/app-utils/element-animation.js.map +1 -0
- package/src/lib/app-utils/element-hidden-style.d.ts +46 -0
- package/src/lib/app-utils/element-hidden-style.js +48 -0
- package/src/lib/app-utils/element-hidden-style.js.map +1 -0
- package/src/lib/app-utils/element-ui.d.ts +243 -0
- package/src/lib/app-utils/element-ui.js +459 -0
- package/src/lib/app-utils/element-ui.js.map +1 -0
- package/src/lib/app-utils/email-starter-policy.d.ts +160 -0
- package/src/lib/app-utils/email-starter-policy.js +327 -0
- package/src/lib/app-utils/email-starter-policy.js.map +1 -0
- package/src/lib/app-utils/email-topics.d.ts +310 -0
- package/src/lib/app-utils/email-topics.js +336 -0
- package/src/lib/app-utils/email-topics.js.map +1 -0
- package/src/lib/app-utils/enabled-plugins-context.d.ts +100 -0
- package/src/lib/app-utils/enabled-plugins-context.js +113 -0
- package/src/lib/app-utils/enabled-plugins-context.js.map +1 -0
- package/src/lib/app-utils/ensure-canvas-root.d.ts +38 -0
- package/src/lib/app-utils/ensure-canvas-root.js +61 -0
- package/src/lib/app-utils/ensure-canvas-root.js.map +1 -0
- package/src/lib/app-utils/entity-picker-context.d.ts +199 -0
- package/src/lib/app-utils/entity-picker-context.js +93 -0
- package/src/lib/app-utils/entity-picker-context.js.map +1 -0
- package/src/lib/app-utils/error-beacon.d.ts +107 -0
- package/src/lib/app-utils/error-beacon.js +296 -0
- package/src/lib/app-utils/error-beacon.js.map +1 -0
- package/src/lib/app-utils/expand-repeatables.d.ts +172 -0
- package/src/lib/app-utils/expand-repeatables.js +299 -0
- package/src/lib/app-utils/expand-repeatables.js.map +1 -0
- package/src/lib/app-utils/foreign-script.d.ts +82 -0
- package/src/lib/app-utils/foreign-script.js +102 -0
- package/src/lib/app-utils/foreign-script.js.map +1 -0
- package/src/lib/app-utils/form-abuse-ceiling.d.ts +146 -0
- package/src/lib/app-utils/form-abuse-ceiling.js +158 -0
- package/src/lib/app-utils/form-abuse-ceiling.js.map +1 -0
- package/src/lib/app-utils/form-contract.d.ts +198 -0
- package/src/lib/app-utils/form-contract.js +282 -0
- package/src/lib/app-utils/form-contract.js.map +1 -0
- package/src/lib/app-utils/form-dataset-binding.d.ts +50 -0
- package/src/lib/app-utils/form-dataset-binding.js +74 -0
- package/src/lib/app-utils/form-dataset-binding.js.map +1 -0
- package/src/lib/app-utils/forms.d.ts +727 -0
- package/src/lib/app-utils/forms.js +777 -0
- package/src/lib/app-utils/forms.js.map +1 -0
- package/src/lib/app-utils/functions.d.ts +188 -0
- package/src/lib/app-utils/functions.js +529 -0
- package/src/lib/app-utils/functions.js.map +1 -0
- package/src/lib/app-utils/guarded-version-save.d.ts +91 -0
- package/src/lib/app-utils/guarded-version-save.js +131 -0
- package/src/lib/app-utils/guarded-version-save.js.map +1 -0
- package/src/lib/app-utils/health-report.d.ts +1766 -0
- package/src/lib/app-utils/health-report.js +2072 -0
- package/src/lib/app-utils/health-report.js.map +1 -0
- package/src/lib/app-utils/host-naming.d.ts +135 -0
- package/src/lib/app-utils/host-naming.js +188 -0
- package/src/lib/app-utils/host-naming.js.map +1 -0
- package/src/lib/app-utils/host-permissions.d.ts +76 -0
- package/src/lib/app-utils/host-permissions.js +119 -0
- package/src/lib/app-utils/host-permissions.js.map +1 -0
- package/src/lib/app-utils/host-tokens.d.ts +228 -0
- package/src/lib/app-utils/host-tokens.js +304 -0
- package/src/lib/app-utils/host-tokens.js.map +1 -0
- package/src/lib/app-utils/idp-profile.d.ts +83 -0
- package/src/lib/app-utils/idp-profile.js +268 -0
- package/src/lib/app-utils/idp-profile.js.map +1 -0
- package/src/lib/app-utils/image-upload-types.d.ts +49 -0
- package/src/lib/app-utils/image-upload-types.js +86 -0
- package/src/lib/app-utils/image-upload-types.js.map +1 -0
- package/src/lib/app-utils/index.d.ts +18 -0
- package/src/lib/app-utils/index.js +23 -0
- package/src/lib/app-utils/index.js.map +1 -0
- package/src/lib/app-utils/internal-traffic.d.ts +197 -0
- package/src/lib/app-utils/internal-traffic.js +288 -0
- package/src/lib/app-utils/internal-traffic.js.map +1 -0
- package/src/lib/app-utils/lineal-order.d.ts +62 -0
- package/src/lib/app-utils/lineal-order.js +65 -0
- package/src/lib/app-utils/lineal-order.js.map +1 -0
- package/src/lib/app-utils/link-references.d.ts +36 -0
- package/src/lib/app-utils/link-references.js +89 -0
- package/src/lib/app-utils/link-references.js.map +1 -0
- package/src/lib/app-utils/link-target-search-context.d.ts +123 -0
- package/src/lib/app-utils/link-target-search-context.js +221 -0
- package/src/lib/app-utils/link-target-search-context.js.map +1 -0
- package/src/lib/app-utils/list-assignment-policy.d.ts +169 -0
- package/src/lib/app-utils/list-assignment-policy.js +170 -0
- package/src/lib/app-utils/list-assignment-policy.js.map +1 -0
- package/src/lib/app-utils/list-import.d.ts +158 -0
- package/src/lib/app-utils/list-import.js +332 -0
- package/src/lib/app-utils/list-import.js.map +1 -0
- package/src/lib/app-utils/llms-txt.d.ts +104 -0
- package/src/lib/app-utils/llms-txt.js +144 -0
- package/src/lib/app-utils/llms-txt.js.map +1 -0
- package/src/lib/app-utils/local-storage-budget.d.ts +75 -0
- package/src/lib/app-utils/local-storage-budget.js +153 -0
- package/src/lib/app-utils/local-storage-budget.js.map +1 -0
- package/src/lib/app-utils/lockdown.d.ts +698 -0
- package/src/lib/app-utils/lockdown.js +929 -0
- package/src/lib/app-utils/lockdown.js.map +1 -0
- package/src/lib/app-utils/margin-utilization.d.ts +267 -0
- package/src/lib/app-utils/margin-utilization.js +351 -0
- package/src/lib/app-utils/margin-utilization.js.map +1 -0
- package/src/lib/app-utils/markdown-lite.d.ts +297 -0
- package/src/lib/app-utils/markdown-lite.js +705 -0
- package/src/lib/app-utils/markdown-lite.js.map +1 -0
- package/src/lib/app-utils/marketing-consent.d.ts +704 -0
- package/src/lib/app-utils/marketing-consent.js +783 -0
- package/src/lib/app-utils/marketing-consent.js.map +1 -0
- package/src/lib/app-utils/marketplace-listing-visibility.d.ts +120 -0
- package/src/lib/app-utils/marketplace-listing-visibility.js +139 -0
- package/src/lib/app-utils/marketplace-listing-visibility.js.map +1 -0
- package/src/lib/app-utils/marketplace-overrides.d.ts +271 -0
- package/src/lib/app-utils/marketplace-overrides.js +462 -0
- package/src/lib/app-utils/marketplace-overrides.js.map +1 -0
- package/src/lib/app-utils/marketplace-provenance.d.ts +150 -0
- package/src/lib/app-utils/marketplace-provenance.js +136 -0
- package/src/lib/app-utils/marketplace-provenance.js.map +1 -0
- package/src/lib/app-utils/marketplace-theme.d.ts +237 -0
- package/src/lib/app-utils/marketplace-theme.js +525 -0
- package/src/lib/app-utils/marketplace-theme.js.map +1 -0
- package/src/lib/app-utils/marketplace-update-state.d.ts +119 -0
- package/src/lib/app-utils/marketplace-update-state.js +132 -0
- package/src/lib/app-utils/marketplace-update-state.js.map +1 -0
- package/src/lib/app-utils/marketplace-verification.d.ts +95 -0
- package/src/lib/app-utils/marketplace-verification.js +81 -0
- package/src/lib/app-utils/marketplace-verification.js.map +1 -0
- package/src/lib/app-utils/measure-node-map.d.ts +76 -0
- package/src/lib/app-utils/measure-node-map.js +111 -0
- package/src/lib/app-utils/measure-node-map.js.map +1 -0
- package/src/lib/app-utils/media-alt.d.ts +55 -0
- package/src/lib/app-utils/media-alt.js +58 -0
- package/src/lib/app-utils/media-alt.js.map +1 -0
- package/src/lib/app-utils/media-asset-facts.d.ts +125 -0
- package/src/lib/app-utils/media-asset-facts.js +467 -0
- package/src/lib/app-utils/media-asset-facts.js.map +1 -0
- package/src/lib/app-utils/media-cdn-scope.d.ts +65 -0
- package/src/lib/app-utils/media-cdn-scope.js +75 -0
- package/src/lib/app-utils/media-cdn-scope.js.map +1 -0
- package/src/lib/app-utils/media-folders.d.ts +161 -0
- package/src/lib/app-utils/media-folders.js +230 -0
- package/src/lib/app-utils/media-folders.js.map +1 -0
- package/src/lib/app-utils/media-metadata.d.ts +277 -0
- package/src/lib/app-utils/media-metadata.js +388 -0
- package/src/lib/app-utils/media-metadata.js.map +1 -0
- package/src/lib/app-utils/media-picker-context.d.ts +93 -0
- package/src/lib/app-utils/media-picker-context.js +26 -0
- package/src/lib/app-utils/media-picker-context.js.map +1 -0
- package/src/lib/app-utils/media-quarantine.d.ts +247 -0
- package/src/lib/app-utils/media-quarantine.js +323 -0
- package/src/lib/app-utils/media-quarantine.js.map +1 -0
- package/src/lib/app-utils/media-ref.d.ts +661 -0
- package/src/lib/app-utils/media-ref.js +1055 -0
- package/src/lib/app-utils/media-ref.js.map +1 -0
- package/src/lib/app-utils/media-takedown-reach.d.ts +126 -0
- package/src/lib/app-utils/media-takedown-reach.js +143 -0
- package/src/lib/app-utils/media-takedown-reach.js.map +1 -0
- package/src/lib/app-utils/member-email-aliases.d.ts +180 -0
- package/src/lib/app-utils/member-email-aliases.js +217 -0
- package/src/lib/app-utils/member-email-aliases.js.map +1 -0
- package/src/lib/app-utils/merge-node-sx.d.ts +47 -0
- package/src/lib/app-utils/merge-node-sx.js +123 -0
- package/src/lib/app-utils/merge-node-sx.js.map +1 -0
- package/src/lib/app-utils/name-match.d.ts +155 -0
- package/src/lib/app-utils/name-match.js +175 -0
- package/src/lib/app-utils/name-match.js.map +1 -0
- package/src/lib/app-utils/name-search.d.ts +117 -0
- package/src/lib/app-utils/name-search.js +145 -0
- package/src/lib/app-utils/name-search.js.map +1 -0
- package/src/lib/app-utils/node-capabilities.d.ts +85 -0
- package/src/lib/app-utils/node-capabilities.js +88 -0
- package/src/lib/app-utils/node-capabilities.js.map +1 -0
- package/src/lib/app-utils/node-definition-sanitizer.d.ts +164 -0
- package/src/lib/app-utils/node-definition-sanitizer.js +402 -0
- package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -0
- package/src/lib/app-utils/node-identity.d.ts +47 -0
- package/src/lib/app-utils/node-identity.js +50 -0
- package/src/lib/app-utils/node-identity.js.map +1 -0
- package/src/lib/app-utils/node-interactions.d.ts +102 -0
- package/src/lib/app-utils/node-interactions.js +192 -0
- package/src/lib/app-utils/node-interactions.js.map +1 -0
- package/src/lib/app-utils/node-url-policy.d.ts +54 -0
- package/src/lib/app-utils/node-url-policy.js +72 -0
- package/src/lib/app-utils/node-url-policy.js.map +1 -0
- package/src/lib/app-utils/notifications.d.ts +71 -0
- package/src/lib/app-utils/notifications.js +101 -0
- package/src/lib/app-utils/notifications.js.map +1 -0
- package/src/lib/app-utils/onboarding-deep-link.d.ts +120 -0
- package/src/lib/app-utils/onboarding-deep-link.js +142 -0
- package/src/lib/app-utils/onboarding-deep-link.js.map +1 -0
- package/src/lib/app-utils/operator-identity.d.ts +207 -0
- package/src/lib/app-utils/operator-identity.js +186 -0
- package/src/lib/app-utils/operator-identity.js.map +1 -0
- package/src/lib/app-utils/org-billing-doc.d.ts +231 -0
- package/src/lib/app-utils/org-billing-doc.js +238 -0
- package/src/lib/app-utils/org-billing-doc.js.map +1 -0
- package/src/lib/app-utils/org-override-reason.d.ts +100 -0
- package/src/lib/app-utils/org-override-reason.js +116 -0
- package/src/lib/app-utils/org-override-reason.js.map +1 -0
- package/src/lib/app-utils/org-permissions.d.ts +194 -0
- package/src/lib/app-utils/org-permissions.js +357 -0
- package/src/lib/app-utils/org-permissions.js.map +1 -0
- package/src/lib/app-utils/org-roles.d.ts +72 -0
- package/src/lib/app-utils/org-roles.js +131 -0
- package/src/lib/app-utils/org-roles.js.map +1 -0
- package/src/lib/app-utils/organizations.d.ts +407 -0
- package/src/lib/app-utils/organizations.js +511 -0
- package/src/lib/app-utils/organizations.js.map +1 -0
- package/src/lib/app-utils/page-header-actions-context.d.ts +83 -0
- package/src/lib/app-utils/page-header-actions-context.js +58 -0
- package/src/lib/app-utils/page-header-actions-context.js.map +1 -0
- package/src/lib/app-utils/page-header-record-context.d.ts +80 -0
- package/src/lib/app-utils/page-header-record-context.js +64 -0
- package/src/lib/app-utils/page-header-record-context.js.map +1 -0
- package/src/lib/app-utils/page-markdown.d.ts +103 -0
- package/src/lib/app-utils/page-markdown.js +385 -0
- package/src/lib/app-utils/page-markdown.js.map +1 -0
- package/src/lib/app-utils/paid-media-source.d.ts +90 -0
- package/src/lib/app-utils/paid-media-source.js +184 -0
- package/src/lib/app-utils/paid-media-source.js.map +1 -0
- package/src/lib/app-utils/palette-sx.d.ts +34 -0
- package/src/lib/app-utils/palette-sx.js +150 -0
- package/src/lib/app-utils/palette-sx.js.map +1 -0
- package/src/lib/app-utils/password-policy.d.ts +47 -0
- package/src/lib/app-utils/password-policy.js +46 -0
- package/src/lib/app-utils/password-policy.js.map +1 -0
- package/src/lib/app-utils/payments-configured.d.ts +84 -0
- package/src/lib/app-utils/payments-configured.js +88 -0
- package/src/lib/app-utils/payments-configured.js.map +1 -0
- package/src/lib/app-utils/person-erasure.d.ts +126 -0
- package/src/lib/app-utils/person-erasure.js +121 -0
- package/src/lib/app-utils/person-erasure.js.map +1 -0
- package/src/lib/app-utils/person-key.d.ts +32 -0
- package/src/lib/app-utils/person-key.js +62 -0
- package/src/lib/app-utils/person-key.js.map +1 -0
- package/src/lib/app-utils/plan-entitlements.d.ts +2756 -0
- package/src/lib/app-utils/plan-entitlements.js +4085 -0
- package/src/lib/app-utils/plan-entitlements.js.map +1 -0
- package/src/lib/app-utils/platform-ad-conversions.d.ts +122 -0
- package/src/lib/app-utils/platform-ad-conversions.js +174 -0
- package/src/lib/app-utils/platform-ad-conversions.js.map +1 -0
- package/src/lib/app-utils/platform-advertising-tags.d.ts +139 -0
- package/src/lib/app-utils/platform-advertising-tags.js +203 -0
- package/src/lib/app-utils/platform-advertising-tags.js.map +1 -0
- package/src/lib/app-utils/platform-brand.d.ts +151 -0
- package/src/lib/app-utils/platform-brand.js +175 -0
- package/src/lib/app-utils/platform-brand.js.map +1 -0
- package/src/lib/app-utils/platform-consent-default.d.ts +142 -0
- package/src/lib/app-utils/platform-consent-default.js +295 -0
- package/src/lib/app-utils/platform-consent-default.js.map +1 -0
- package/src/lib/app-utils/platform-marketing-consent.d.ts +151 -0
- package/src/lib/app-utils/platform-marketing-consent.js +182 -0
- package/src/lib/app-utils/platform-marketing-consent.js.map +1 -0
- package/src/lib/app-utils/platform-marketing-host.d.ts +33 -0
- package/src/lib/app-utils/platform-marketing-host.js +97 -0
- package/src/lib/app-utils/platform-marketing-host.js.map +1 -0
- package/src/lib/app-utils/platform-visitor-consent.d.ts +252 -0
- package/src/lib/app-utils/platform-visitor-consent.js +533 -0
- package/src/lib/app-utils/platform-visitor-consent.js.map +1 -0
- package/src/lib/app-utils/plugin-api-cross-origin.d.ts +61 -0
- package/src/lib/app-utils/plugin-api-cross-origin.js +202 -0
- package/src/lib/app-utils/plugin-api-cross-origin.js.map +1 -0
- package/src/lib/app-utils/plugin-api-rate-limit.d.ts +192 -0
- package/src/lib/app-utils/plugin-api-rate-limit.js +270 -0
- package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -0
- package/src/lib/app-utils/plugin-artifact-path.d.ts +32 -0
- package/src/lib/app-utils/plugin-artifact-path.js +33 -0
- package/src/lib/app-utils/plugin-artifact-path.js.map +1 -0
- package/src/lib/app-utils/plugin-bundle-checks.d.ts +148 -0
- package/src/lib/app-utils/plugin-bundle-checks.js +989 -0
- package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -0
- package/src/lib/app-utils/plugin-manifest.d.ts +516 -0
- package/src/lib/app-utils/plugin-manifest.js +687 -0
- package/src/lib/app-utils/plugin-manifest.js.map +1 -0
- package/src/lib/app-utils/published-legal-pages.d.ts +71 -0
- package/src/lib/app-utils/published-legal-pages.js +90 -0
- package/src/lib/app-utils/published-legal-pages.js.map +1 -0
- package/src/lib/app-utils/publisher-agreement.d.ts +254 -0
- package/src/lib/app-utils/publisher-agreement.js +274 -0
- package/src/lib/app-utils/publisher-agreement.js.map +1 -0
- package/src/lib/app-utils/publisher-attestation.d.ts +99 -0
- package/src/lib/app-utils/publisher-attestation.js +158 -0
- package/src/lib/app-utils/publisher-attestation.js.map +1 -0
- package/src/lib/app-utils/recipient-email-render.d.ts +216 -0
- package/src/lib/app-utils/recipient-email-render.js +221 -0
- package/src/lib/app-utils/recipient-email-render.js.map +1 -0
- package/src/lib/app-utils/redispatch-caught-error.d.ts +38 -0
- package/src/lib/app-utils/redispatch-caught-error.js +46 -0
- package/src/lib/app-utils/redispatch-caught-error.js.map +1 -0
- package/src/lib/app-utils/registering-plugin.d.ts +19 -0
- package/src/lib/app-utils/registering-plugin.js +38 -0
- package/src/lib/app-utils/registering-plugin.js.map +1 -0
- package/src/lib/app-utils/release-flags.d.ts +283 -0
- package/src/lib/app-utils/release-flags.js +518 -0
- package/src/lib/app-utils/release-flags.js.map +1 -0
- package/src/lib/app-utils/repair-canvas-nodes.d.ts +130 -0
- package/src/lib/app-utils/repair-canvas-nodes.js +298 -0
- package/src/lib/app-utils/repair-canvas-nodes.js.map +1 -0
- package/src/lib/app-utils/repeat-infringer.d.ts +166 -0
- package/src/lib/app-utils/repeat-infringer.js +188 -0
- package/src/lib/app-utils/repeat-infringer.js.map +1 -0
- package/src/lib/app-utils/repeat-sources.d.ts +115 -0
- package/src/lib/app-utils/repeat-sources.js +86 -0
- package/src/lib/app-utils/repeat-sources.js.map +1 -0
- package/src/lib/app-utils/request-geo.d.ts +114 -0
- package/src/lib/app-utils/request-geo.js +247 -0
- package/src/lib/app-utils/request-geo.js.map +1 -0
- package/src/lib/app-utils/request-ip.d.ts +213 -0
- package/src/lib/app-utils/request-ip.js +344 -0
- package/src/lib/app-utils/request-ip.js.map +1 -0
- package/src/lib/app-utils/resolve-named-tokens.d.ts +26 -0
- package/src/lib/app-utils/resolve-named-tokens.js +59 -0
- package/src/lib/app-utils/resolve-named-tokens.js.map +1 -0
- package/src/lib/app-utils/responsive-typography-sx.d.ts +77 -0
- package/src/lib/app-utils/responsive-typography-sx.js +122 -0
- package/src/lib/app-utils/responsive-typography-sx.js.map +1 -0
- package/src/lib/app-utils/reusable-component-keys.d.ts +135 -0
- package/src/lib/app-utils/reusable-component-keys.js +140 -0
- package/src/lib/app-utils/reusable-component-keys.js.map +1 -0
- package/src/lib/app-utils/reusable-prop-values.d.ts +199 -0
- package/src/lib/app-utils/reusable-prop-values.js +494 -0
- package/src/lib/app-utils/reusable-prop-values.js.map +1 -0
- package/src/lib/app-utils/safe-json-ld.d.ts +29 -0
- package/src/lib/app-utils/safe-json-ld.js +37 -0
- package/src/lib/app-utils/safe-json-ld.js.map +1 -0
- package/src/lib/app-utils/sanitize-svg.d.ts +55 -0
- package/src/lib/app-utils/sanitize-svg.js +460 -0
- package/src/lib/app-utils/sanitize-svg.js.map +1 -0
- package/src/lib/app-utils/scheme-sx.d.ts +84 -0
- package/src/lib/app-utils/scheme-sx.js +148 -0
- package/src/lib/app-utils/scheme-sx.js.map +1 -0
- package/src/lib/app-utils/scope-tokens.d.ts +249 -0
- package/src/lib/app-utils/scope-tokens.js +331 -0
- package/src/lib/app-utils/scope-tokens.js.map +1 -0
- package/src/lib/app-utils/screen-link-context-value.d.ts +57 -0
- package/src/lib/app-utils/screen-link-context-value.js +43 -0
- package/src/lib/app-utils/screen-link-context-value.js.map +1 -0
- package/src/lib/app-utils/screen-link-context.d.ts +185 -0
- package/src/lib/app-utils/screen-link-context.js +304 -0
- package/src/lib/app-utils/screen-link-context.js.map +1 -0
- package/src/lib/app-utils/screen-link-value.d.ts +269 -0
- package/src/lib/app-utils/screen-link-value.js +384 -0
- package/src/lib/app-utils/screen-link-value.js.map +1 -0
- package/src/lib/app-utils/screen-route.d.ts +669 -0
- package/src/lib/app-utils/screen-route.js +751 -0
- package/src/lib/app-utils/screen-route.js.map +1 -0
- package/src/lib/app-utils/screen-seo-fields.d.ts +37 -0
- package/src/lib/app-utils/screen-seo-fields.js +42 -0
- package/src/lib/app-utils/screen-seo-fields.js.map +1 -0
- package/src/lib/app-utils/search-indexing.d.ts +162 -0
- package/src/lib/app-utils/search-indexing.js +207 -0
- package/src/lib/app-utils/search-indexing.js.map +1 -0
- package/src/lib/app-utils/seo-listing-fields.d.ts +70 -0
- package/src/lib/app-utils/seo-listing-fields.js +75 -0
- package/src/lib/app-utils/seo-listing-fields.js.map +1 -0
- package/src/lib/app-utils/seo-locale.d.ts +119 -0
- package/src/lib/app-utils/seo-locale.js +133 -0
- package/src/lib/app-utils/seo-locale.js.map +1 -0
- package/src/lib/app-utils/seo-title-variables.d.ts +149 -0
- package/src/lib/app-utils/seo-title-variables.js +190 -0
- package/src/lib/app-utils/seo-title-variables.js.map +1 -0
- package/src/lib/app-utils/seo-title.d.ts +70 -0
- package/src/lib/app-utils/seo-title.js +117 -0
- package/src/lib/app-utils/seo-title.js.map +1 -0
- package/src/lib/app-utils/server.d.ts +174 -0
- package/src/lib/app-utils/server.js +314 -0
- package/src/lib/app-utils/server.js.map +1 -0
- package/src/lib/app-utils/site-context.d.ts +106 -0
- package/src/lib/app-utils/site-context.js +100 -0
- package/src/lib/app-utils/site-context.js.map +1 -0
- package/src/lib/app-utils/sitemap.d.ts +117 -0
- package/src/lib/app-utils/sitemap.js +183 -0
- package/src/lib/app-utils/sitemap.js.map +1 -0
- package/src/lib/app-utils/social-image.d.ts +112 -0
- package/src/lib/app-utils/social-image.js +191 -0
- package/src/lib/app-utils/social-image.js.map +1 -0
- package/src/lib/app-utils/starter-templates.d.ts +99 -0
- package/src/lib/app-utils/starter-templates.js +579 -0
- package/src/lib/app-utils/starter-templates.js.map +1 -0
- package/src/lib/app-utils/stored-nodes.d.ts +120 -0
- package/src/lib/app-utils/stored-nodes.js +174 -0
- package/src/lib/app-utils/stored-nodes.js.map +1 -0
- package/src/lib/app-utils/strip-undefined.d.ts +59 -0
- package/src/lib/app-utils/strip-undefined.js +95 -0
- package/src/lib/app-utils/strip-undefined.js.map +1 -0
- package/src/lib/app-utils/stripe-deployment-mode.d.ts +47 -0
- package/src/lib/app-utils/stripe-deployment-mode.js +70 -0
- package/src/lib/app-utils/stripe-deployment-mode.js.map +1 -0
- package/src/lib/app-utils/support-tiers.d.ts +108 -0
- package/src/lib/app-utils/support-tiers.js +201 -0
- package/src/lib/app-utils/support-tiers.js.map +1 -0
- package/src/lib/app-utils/timezone-geo-hint.d.ts +36 -0
- package/src/lib/app-utils/timezone-geo-hint.js +180 -0
- package/src/lib/app-utils/timezone-geo-hint.js.map +1 -0
- package/src/lib/app-utils/upload-cors.d.ts +155 -0
- package/src/lib/app-utils/upload-cors.js +254 -0
- package/src/lib/app-utils/upload-cors.js.map +1 -0
- package/src/lib/app-utils/upload-inspection.d.ts +159 -0
- package/src/lib/app-utils/upload-inspection.js +539 -0
- package/src/lib/app-utils/upload-inspection.js.map +1 -0
- package/src/lib/app-utils/url-slug.d.ts +40 -0
- package/src/lib/app-utils/url-slug.js +42 -0
- package/src/lib/app-utils/url-slug.js.map +1 -0
- package/src/lib/app-utils/usage-budget.d.ts +429 -0
- package/src/lib/app-utils/usage-budget.js +421 -0
- package/src/lib/app-utils/usage-budget.js.map +1 -0
- package/src/lib/app-utils/variables.d.ts +96 -0
- package/src/lib/app-utils/variables.js +233 -0
- package/src/lib/app-utils/variables.js.map +1 -0
- package/src/lib/app-utils/video-asset-facts.d.ts +61 -0
- package/src/lib/app-utils/video-asset-facts.js +70 -0
- package/src/lib/app-utils/video-asset-facts.js.map +1 -0
- package/src/lib/app-utils/video-object.d.ts +89 -0
- package/src/lib/app-utils/video-object.js +245 -0
- package/src/lib/app-utils/video-object.js.map +1 -0
- package/src/lib/app-utils/visitor-consent.d.ts +757 -0
- package/src/lib/app-utils/visitor-consent.js +981 -0
- package/src/lib/app-utils/visitor-consent.js.map +1 -0
- package/src/lib/app-utils/visitor-record-ceiling.d.ts +223 -0
- package/src/lib/app-utils/visitor-record-ceiling.js +215 -0
- package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -0
- package/src/lib/app-utils/web-vitals-rum.d.ts +53 -0
- package/src/lib/app-utils/web-vitals-rum.js +278 -0
- package/src/lib/app-utils/web-vitals-rum.js.map +1 -0
- package/src/lib/app-utils/webhook-delivery.d.ts +324 -0
- package/src/lib/app-utils/webhook-delivery.js +413 -0
- package/src/lib/app-utils/webhook-delivery.js.map +1 -0
- package/src/lib/app-utils/where-used.d.ts +57 -0
- package/src/lib/app-utils/where-used.js +59 -0
- package/src/lib/app-utils/where-used.js.map +1 -0
- package/src/lib/app-utils/wistia-embed.d.ts +86 -0
- package/src/lib/app-utils/wistia-embed.js +119 -0
- package/src/lib/app-utils/wistia-embed.js.map +1 -0
- package/src/lib/app-utils/workflows.d.ts +136 -0
- package/src/lib/app-utils/workflows.js +346 -0
- package/src/lib/app-utils/workflows.js.map +1 -0
- package/src/lib/canvas-manager/canvas-manager-tree.d.ts +109 -0
- package/src/lib/canvas-manager/canvas-manager-tree.js +139 -0
- package/src/lib/canvas-manager/canvas-manager-tree.js.map +1 -0
- package/src/lib/canvas-manager/canvas-manager.d.ts +549 -0
- package/src/lib/canvas-manager/canvas-manager.js +1311 -0
- package/src/lib/canvas-manager/canvas-manager.js.map +1 -0
- package/src/lib/canvas-manager/index.d.ts +20 -0
- package/src/lib/canvas-manager/index.js +21 -0
- package/src/lib/canvas-manager/index.js.map +1 -0
- package/src/lib/canvas-manager/stores/index.d.ts +17 -0
- package/src/lib/canvas-manager/stores/index.js +18 -0
- package/src/lib/canvas-manager/stores/index.js.map +1 -0
- package/src/lib/canvas-manager/stores/node.store.d.ts +30 -0
- package/src/lib/canvas-manager/stores/node.store.js +45 -0
- package/src/lib/canvas-manager/stores/node.store.js.map +1 -0
- package/src/lib/components-manager/components-manager.d.ts +56 -0
- package/src/lib/components-manager/components-manager.js +191 -0
- package/src/lib/components-manager/components-manager.js.map +1 -0
- package/src/lib/components-manager/index.d.ts +18 -0
- package/src/lib/components-manager/index.js +19 -0
- package/src/lib/components-manager/index.js.map +1 -0
- package/src/lib/emit-manager/emit-manager.d.ts +56 -0
- package/src/lib/emit-manager/emit-manager.js +60 -0
- package/src/lib/emit-manager/emit-manager.js.map +1 -0
- package/src/lib/emit-manager/index.d.ts +18 -0
- package/src/lib/emit-manager/index.js +19 -0
- package/src/lib/emit-manager/index.js.map +1 -0
- package/src/lib/foundation/constants/_internal.d.ts +18 -0
- package/src/lib/foundation/constants/_internal.js +62 -0
- package/src/lib/foundation/constants/_internal.js.map +1 -0
- package/src/lib/foundation/constants/app.d.ts +23 -0
- package/src/lib/foundation/constants/app.js +25 -0
- package/src/lib/foundation/constants/app.js.map +1 -0
- package/src/lib/foundation/constants/canvas.d.ts +18 -0
- package/src/lib/foundation/constants/canvas.js +18 -0
- package/src/lib/foundation/constants/canvas.js.map +1 -0
- package/src/lib/foundation/constants/components.d.ts +54 -0
- package/src/lib/foundation/constants/components.js +61 -0
- package/src/lib/foundation/constants/components.js.map +1 -0
- package/src/lib/foundation/constants/shared.d.ts +50 -0
- package/src/lib/foundation/constants/shared.js +49 -0
- package/src/lib/foundation/constants/shared.js.map +1 -0
- package/src/lib/foundation/constants/symbol.d.ts +63 -0
- package/src/lib/foundation/constants/symbol.js +75 -0
- package/src/lib/foundation/constants/symbol.js.map +1 -0
- package/src/lib/foundation/definitions/components.types.d.ts +372 -0
- package/src/lib/foundation/definitions/components.types.js +180 -0
- package/src/lib/foundation/definitions/components.types.js.map +1 -0
- package/src/lib/foundation/definitions/contact.types.d.ts +73 -0
- package/src/lib/foundation/definitions/contact.types.js +107 -0
- package/src/lib/foundation/definitions/contact.types.js.map +1 -0
- package/src/lib/foundation/definitions/host-content-collections.d.ts +137 -0
- package/src/lib/foundation/definitions/host-content-collections.js +219 -0
- package/src/lib/foundation/definitions/host-content-collections.js.map +1 -0
- package/src/lib/foundation/definitions/org-billing.types.d.ts +1361 -0
- package/src/lib/foundation/definitions/org-billing.types.js +77 -0
- package/src/lib/foundation/definitions/org-billing.types.js.map +1 -0
- package/src/lib/foundation/definitions/organization.types.d.ts +307 -0
- package/src/lib/foundation/definitions/organization.types.js +42 -0
- package/src/lib/foundation/definitions/organization.types.js.map +1 -0
- package/src/lib/foundation/definitions/platform.types.d.ts +1326 -0
- package/src/lib/foundation/definitions/platform.types.js +124 -0
- package/src/lib/foundation/definitions/platform.types.js.map +1 -0
- package/src/lib/foundation/definitions/property-kinds.d.ts +189 -0
- package/src/lib/foundation/definitions/property-kinds.js +565 -0
- package/src/lib/foundation/definitions/property-kinds.js.map +1 -0
- package/src/lib/foundation/definitions/shared.d.ts +23 -0
- package/src/lib/foundation/definitions/shared.js +18 -0
- package/src/lib/foundation/definitions/shared.js.map +1 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +249 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.js +499 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -0
- package/src/lib/foundation/index.d.ts +32 -0
- package/src/lib/foundation/index.js +67 -0
- package/src/lib/foundation/index.js.map +1 -0
- package/src/lib/lifecycle.d.ts +24 -0
- package/src/lib/lifecycle.js +39 -0
- package/src/lib/lifecycle.js.map +1 -0
- package/src/lib/mst/common.d.ts +17 -0
- package/src/lib/mst/common.js +23 -0
- package/src/lib/mst/common.js.map +1 -0
- package/src/lib/mst/index.d.ts +19 -0
- package/src/lib/mst/index.js +20 -0
- package/src/lib/mst/index.js.map +1 -0
- package/src/lib/mst/json.d.ts +22 -0
- package/src/lib/mst/json.js +23 -0
- package/src/lib/mst/json.js.map +1 -0
- package/src/lib/mst/types.d.ts +20 -0
- package/src/lib/mst/types.js +18 -0
- package/src/lib/mst/types.js.map +1 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.d.ts +77 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.js +55 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.js.map +1 -0
- package/src/lib/plugin-manager/commerce-zone-props.d.ts +172 -0
- package/src/lib/plugin-manager/commerce-zone-props.js +31 -0
- package/src/lib/plugin-manager/commerce-zone-props.js.map +1 -0
- package/src/lib/plugin-manager/custom-fields.d.ts +60 -0
- package/src/lib/plugin-manager/custom-fields.js +39 -0
- package/src/lib/plugin-manager/custom-fields.js.map +1 -0
- package/src/lib/plugin-manager/editor-sessions.d.ts +109 -0
- package/src/lib/plugin-manager/editor-sessions.js +137 -0
- package/src/lib/plugin-manager/editor-sessions.js.map +1 -0
- package/src/lib/plugin-manager/enabled-plugins.d.ts +438 -0
- package/src/lib/plugin-manager/enabled-plugins.js +403 -0
- package/src/lib/plugin-manager/enabled-plugins.js.map +1 -0
- package/src/lib/plugin-manager/feature-plugins.d.ts +1314 -0
- package/src/lib/plugin-manager/feature-plugins.js +609 -0
- package/src/lib/plugin-manager/feature-plugins.js.map +1 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +11 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js +149 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -0
- package/src/lib/plugin-manager/index.d.ts +42 -0
- package/src/lib/plugin-manager/index.js +46 -0
- package/src/lib/plugin-manager/index.js.map +1 -0
- package/src/lib/plugin-manager/install-presets.d.ts +93 -0
- package/src/lib/plugin-manager/install-presets.js +86 -0
- package/src/lib/plugin-manager/install-presets.js.map +1 -0
- package/src/lib/plugin-manager/media-delivery-provider.d.ts +124 -0
- package/src/lib/plugin-manager/media-delivery-provider.js +53 -0
- package/src/lib/plugin-manager/media-delivery-provider.js.map +1 -0
- package/src/lib/plugin-manager/order-fulfilment.d.ts +142 -0
- package/src/lib/plugin-manager/order-fulfilment.js +104 -0
- package/src/lib/plugin-manager/order-fulfilment.js.map +1 -0
- package/src/lib/plugin-manager/plugin-activity-actions.d.ts +122 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js +140 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-bridge.d.ts +98 -0
- package/src/lib/plugin-manager/plugin-bridge.js +154 -0
- package/src/lib/plugin-manager/plugin-bridge.js.map +1 -0
- package/src/lib/plugin-manager/plugin-config.d.ts +148 -0
- package/src/lib/plugin-manager/plugin-config.js +228 -0
- package/src/lib/plugin-manager/plugin-config.js.map +1 -0
- package/src/lib/plugin-manager/plugin-console-crons.d.ts +139 -0
- package/src/lib/plugin-manager/plugin-console-crons.js +177 -0
- package/src/lib/plugin-manager/plugin-console-crons.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contact-capture.d.ts +220 -0
- package/src/lib/plugin-manager/plugin-contact-capture.js +89 -0
- package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contributions.d.ts +244 -0
- package/src/lib/plugin-manager/plugin-contributions.js +283 -0
- package/src/lib/plugin-manager/plugin-contributions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.d.ts +169 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.js +84 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entitlements.d.ts +181 -0
- package/src/lib/plugin-manager/plugin-entitlements.js +188 -0
- package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -0
- package/src/lib/plugin-manager/plugin-events.d.ts +145 -0
- package/src/lib/plugin-manager/plugin-events.js +79 -0
- package/src/lib/plugin-manager/plugin-events.js.map +1 -0
- package/src/lib/plugin-manager/plugin-figures.d.ts +251 -0
- package/src/lib/plugin-manager/plugin-figures.js +252 -0
- package/src/lib/plugin-manager/plugin-figures.js.map +1 -0
- package/src/lib/plugin-manager/plugin-host-collections.d.ts +146 -0
- package/src/lib/plugin-manager/plugin-host-collections.js +116 -0
- package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -0
- package/src/lib/plugin-manager/plugin-jobs.d.ts +130 -0
- package/src/lib/plugin-manager/plugin-jobs.js +182 -0
- package/src/lib/plugin-manager/plugin-jobs.js.map +1 -0
- package/src/lib/plugin-manager/plugin-loader.d.ts +86 -0
- package/src/lib/plugin-manager/plugin-loader.js +223 -0
- package/src/lib/plugin-manager/plugin-loader.js.map +1 -0
- package/src/lib/plugin-manager/plugin-manager.d.ts +95 -0
- package/src/lib/plugin-manager/plugin-manager.js +343 -0
- package/src/lib/plugin-manager/plugin-manager.js.map +1 -0
- package/src/lib/plugin-manager/plugin-metered-lines.d.ts +97 -0
- package/src/lib/plugin-manager/plugin-metered-lines.js +123 -0
- package/src/lib/plugin-manager/plugin-metered-lines.js.map +1 -0
- package/src/lib/plugin-manager/plugin-org-erasure.d.ts +52 -0
- package/src/lib/plugin-manager/plugin-org-erasure.js +100 -0
- package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-permissions.d.ts +69 -0
- package/src/lib/plugin-manager/plugin-permissions.js +77 -0
- package/src/lib/plugin-manager/plugin-permissions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-person-erasure.d.ts +58 -0
- package/src/lib/plugin-manager/plugin-person-erasure.js +109 -0
- package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-cards.d.ts +99 -0
- package/src/lib/plugin-manager/plugin-record-cards.js +59 -0
- package/src/lib/plugin-manager/plugin-record-cards.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-facts.d.ts +111 -0
- package/src/lib/plugin-manager/plugin-record-facts.js +51 -0
- package/src/lib/plugin-manager/plugin-record-facts.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-routes.d.ts +129 -0
- package/src/lib/plugin-manager/plugin-record-routes.js +93 -0
- package/src/lib/plugin-manager/plugin-record-routes.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-timeline.d.ts +147 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js +39 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +137 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.js +51 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -0
- package/src/lib/plugin-manager/plugin-services.d.ts +94 -0
- package/src/lib/plugin-manager/plugin-services.js +153 -0
- package/src/lib/plugin-manager/plugin-services.js.map +1 -0
- package/src/lib/plugin-manager/plugin-styles-ui.d.ts +71 -0
- package/src/lib/plugin-manager/plugin-styles-ui.js +80 -0
- package/src/lib/plugin-manager/plugin-styles-ui.js.map +1 -0
- package/src/lib/plugin-manager/plugin-styles.d.ts +176 -0
- package/src/lib/plugin-manager/plugin-styles.js +186 -0
- package/src/lib/plugin-manager/plugin-styles.js.map +1 -0
- package/src/lib/plugin-manager/plugin-subprocessors.d.ts +135 -0
- package/src/lib/plugin-manager/plugin-subprocessors.js +129 -0
- package/src/lib/plugin-manager/plugin-subprocessors.js.map +1 -0
- package/src/lib/plugin-manager/plugin-tax-profile.d.ts +84 -0
- package/src/lib/plugin-manager/plugin-tax-profile.js +39 -0
- package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -0
- package/src/lib/plugin-manager/plugin-user-erasure.d.ts +53 -0
- package/src/lib/plugin-manager/plugin-user-erasure.js +84 -0
- package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-zones.d.ts +121 -0
- package/src/lib/plugin-manager/plugin-zones.js +74 -0
- package/src/lib/plugin-manager/plugin-zones.js.map +1 -0
- package/src/lib/plugin-manager/realm-plugins.d.ts +112 -0
- package/src/lib/plugin-manager/realm-plugins.js +196 -0
- package/src/lib/plugin-manager/realm-plugins.js.map +1 -0
- package/src/lib/plugin-manager/realm-server.d.ts +54 -0
- package/src/lib/plugin-manager/realm-server.js +88 -0
- package/src/lib/plugin-manager/realm-server.js.map +1 -0
- package/src/lib/plugin-manager/record-zone-props.d.ts +126 -0
- package/src/lib/plugin-manager/record-zone-props.js +31 -0
- package/src/lib/plugin-manager/record-zone-props.js.map +1 -0
- package/src/lib/plugin-manager/site-page-hooks.d.ts +102 -0
- package/src/lib/plugin-manager/site-page-hooks.js +114 -0
- package/src/lib/plugin-manager/site-page-hooks.js.map +1 -0
- package/src/lib/plugin-manager/site-runtime.d.ts +57 -0
- package/src/lib/plugin-manager/site-runtime.js +25 -0
- package/src/lib/plugin-manager/site-runtime.js.map +1 -0
- package/src/lib/plugin-manager/usage-alert-contributors.d.ts +115 -0
- package/src/lib/plugin-manager/usage-alert-contributors.js +106 -0
- package/src/lib/plugin-manager/usage-alert-contributors.js.map +1 -0
- package/src/lib/types/ast.d.ts +199 -0
- package/src/lib/types/ast.js +20 -0
- package/src/lib/types/ast.js.map +1 -0
- package/src/lib/types/index.d.ts +20 -0
- package/src/lib/types/index.js +21 -0
- package/src/lib/types/index.js.map +1 -0
- package/src/lib/types/nodes.d.ts +608 -0
- package/src/lib/types/nodes.js +28 -0
- package/src/lib/types/nodes.js.map +1 -0
- package/src/lib/types/routing.d.ts +17 -0
- package/src/lib/types/routing.js +18 -0
- package/src/lib/types/routing.js.map +1 -0
- package/src/lib/types/screen.d.ts +23 -0
- package/src/lib/types/screen.js +18 -0
- package/src/lib/types/screen.js.map +1 -0
- package/src/lib/utils.d.ts +25 -0
- package/src/lib/utils.js +42 -0
- package/src/lib/utils.js.map +1 -0
- package/src/server.d.ts +37 -0
- package/src/server.js +55 -0
- package/src/server.js.map +1 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Several email addresses per account (AGL-2486) — GitHub's model, adopted
|
|
19
|
+
* verbatim because the answer to "how should a secondary address interact
|
|
20
|
+
* with an SSO domain claim?" was "do whatever github does to handle this".
|
|
21
|
+
*
|
|
22
|
+
* ## The one rule everything else here exists to serve
|
|
23
|
+
*
|
|
24
|
+
* **Adding an address to an account NEVER grants organization access.**
|
|
25
|
+
*
|
|
26
|
+
* On GitHub, org membership comes from an invitation or from SAML/SCIM
|
|
27
|
+
* provisioning by the IdP. Verified domains drive notification restrictions
|
|
28
|
+
* and badges; they do not auto-join anybody. SAML SSO links an *external
|
|
29
|
+
* identity* — the assertion the IdP makes at sign-in — to the account. It
|
|
30
|
+
* never matches on the domain of an address the user typed into a settings
|
|
31
|
+
* form.
|
|
32
|
+
*
|
|
33
|
+
* That distinction is load-bearing HERE in a way it is not on GitHub, because
|
|
34
|
+
* Aglyn has `/api/auth/sso-jit`, which just-in-time provisions org membership
|
|
35
|
+
* from a verified email's domain. If a secondary address could satisfy an
|
|
36
|
+
* `ssoDomains` lookup, then adding an address to your own account would JIT
|
|
37
|
+
* you into somebody else's organization — a privilege escalation delivered by
|
|
38
|
+
* a feature that looks like a convenience. So:
|
|
39
|
+
*
|
|
40
|
+
* - SSO domain routing and JIT provisioning read the identity **the IdP
|
|
41
|
+
* asserted at sign-in** (`decoded.email`, re-verified against the org's
|
|
42
|
+
* GCIP tenant). Never this collection.
|
|
43
|
+
* - Where a domain is consulted outside the SSO flow at all, it is derived
|
|
44
|
+
* from the **primary** address only — which is the Firebase Auth record's
|
|
45
|
+
* email, i.e. the same string the token carries.
|
|
46
|
+
* - A secondary address is a *sign-in identifier* and a *delivery address*.
|
|
47
|
+
* It is never an authorization input.
|
|
48
|
+
*
|
|
49
|
+
* `apps/console/specs/account-emails-never-reach-sso.spec.ts` is the negative
|
|
50
|
+
* proof, and it is written to FAIL if the guards are removed.
|
|
51
|
+
*
|
|
52
|
+
* ## Why the primary is special, and why it cannot always be moved
|
|
53
|
+
*
|
|
54
|
+
* The primary IS the Firebase Auth record's email. It is what
|
|
55
|
+
* `decoded.email` carries, so it is the input to
|
|
56
|
+
* `evaluateSsoDomainPolicy` at the session mint and to the invite-accept
|
|
57
|
+
* comparison. Re-designating it therefore CHANGES an authorization input —
|
|
58
|
+
* which is why {@link evaluatePrimaryChange} exists and why it refuses to
|
|
59
|
+
* move a primary off an SSO-governed domain. Without that refusal, this
|
|
60
|
+
* feature would hand every governed account a one-click way out of its own
|
|
61
|
+
* organization's sign-in policy. See the verdict docs below.
|
|
62
|
+
*
|
|
63
|
+
* ## This module is PURE
|
|
64
|
+
*
|
|
65
|
+
* No Firebase, no env, no I/O — every fact it decides on is passed in. That
|
|
66
|
+
* is deliberate and copied from `sso-domain-policy.ts`: a spec can drive
|
|
67
|
+
* every combination directly, and the console (which shows the user *why* a
|
|
68
|
+
* control is disabled) and the API route (which enforces it) can never
|
|
69
|
+
* disagree about what the policy says.
|
|
70
|
+
*/
|
|
71
|
+
/**
|
|
72
|
+
* How many addresses one account may hold, primary included.
|
|
73
|
+
*
|
|
74
|
+
* THE CAP IS NOT DECORATION. `users/{uid}/emails` is a new subcollection, and
|
|
75
|
+
* this repo has a recorded hole from shipping exactly one of those with no
|
|
76
|
+
* ceiling (AGL-2266: content entries, a free org minting unbounded Firestore
|
|
77
|
+
* documents from the browser). The rules deny client writes here outright —
|
|
78
|
+
* see the `emails` match block — so the browser cannot create these at all;
|
|
79
|
+
* this number is the server-side ceiling that stops the API route being the
|
|
80
|
+
* unbounded writer instead. Every add path counts before it writes.
|
|
81
|
+
*
|
|
82
|
+
* Five rather than GitHub's much larger allowance: each address costs a
|
|
83
|
+
* verification email, and the point of the feature is "my work address and my
|
|
84
|
+
* personal one", not address collecting.
|
|
85
|
+
*/
|
|
86
|
+
export declare const MAX_ACCOUNT_EMAILS = 5;
|
|
87
|
+
/** RFC 5321's practical ceiling; also what Firebase Auth accepts. */
|
|
88
|
+
export declare const ACCOUNT_EMAIL_MAX_LENGTH = 254;
|
|
89
|
+
/**
|
|
90
|
+
* The addresses this feature accepts.
|
|
91
|
+
*
|
|
92
|
+
* Deliberately NARROWER than RFC 5322, for a reason beyond tidiness: a
|
|
93
|
+
* normalized address is used verbatim as a Firestore **document id** (both
|
|
94
|
+
* `users/{uid}/emails/{address}` and `emailIdentityIndex/{address}`), so the
|
|
95
|
+
* pattern has to exclude every string a document id may not be:
|
|
96
|
+
*
|
|
97
|
+
* - no `/` — the one character a document id genuinely cannot contain;
|
|
98
|
+
* - no leading/trailing/doubled dot in the local part, so the id can never be
|
|
99
|
+
* `.` or `..`;
|
|
100
|
+
* - the required `@` means the id can never match Firestore's reserved
|
|
101
|
+
* `__.*__` form.
|
|
102
|
+
*
|
|
103
|
+
* A hash would also have worked and would have been unreadable in the
|
|
104
|
+
* console, in an export, and in a support conversation. The uniqueness index
|
|
105
|
+
* is a thing humans have to debug, so it stays legible.
|
|
106
|
+
*/
|
|
107
|
+
export declare const ACCOUNT_EMAIL_PATTERN: RegExp;
|
|
108
|
+
/**
|
|
109
|
+
* Trim, lower-case, validate. Returns null for anything this feature will not
|
|
110
|
+
* store — callers treat null as "reject", never as "store the raw input".
|
|
111
|
+
*
|
|
112
|
+
* **Lower-casing the LOCAL part is a deliberate, lossy choice.** RFC 5321 says
|
|
113
|
+
* the local part is the receiving server's business and may be
|
|
114
|
+
* case-sensitive; in practice no mainstream provider treats it that way, and
|
|
115
|
+
* Firebase Auth lower-cases it too. It has to happen here because uniqueness
|
|
116
|
+
* is the whole security property: if `Ada@acme.com` and `ada@acme.com` could
|
|
117
|
+
* both be verified, they would be two index entries for one mailbox and the
|
|
118
|
+
* sign-in identifier would be ambiguous — which is the account-takeover shape
|
|
119
|
+
* this feature has to avoid.
|
|
120
|
+
*
|
|
121
|
+
* What is NOT normalized away, on purpose: plus-addressing and dots in the
|
|
122
|
+
* local part. `a+b@x.com` and `a@x.com` are the same mailbox at Gmail and
|
|
123
|
+
* different mailboxes almost everywhere else, so collapsing them would refuse
|
|
124
|
+
* an address the user legitimately owns at every provider that is not Gmail.
|
|
125
|
+
* Two accounts CAN therefore hold `a@x.com` and `a+b@x.com` separately; that
|
|
126
|
+
* is correct, because delivery is what an address means here.
|
|
127
|
+
*/
|
|
128
|
+
export declare function normalizeAccountEmail(input: unknown): string | null;
|
|
129
|
+
/**
|
|
130
|
+
* The domain of an address, lower-cased; null when there isn't one.
|
|
131
|
+
*
|
|
132
|
+
* Same shape and same `lastIndexOf` as `domainOf` in `sso-domain-policy.ts`.
|
|
133
|
+
* It is duplicated rather than imported because that module is server-only
|
|
134
|
+
* (`@aglyn/tenant-data-admin`) and this one is imported by the console's
|
|
135
|
+
* client bundle — an nx boundary the lint enforces.
|
|
136
|
+
*
|
|
137
|
+
* WHERE THIS MAY BE USED: display, and the primary-change policy below.
|
|
138
|
+
* NOT for resolving an org, an IdP, or a membership. Those read the address
|
|
139
|
+
* the IdP asserted, and there is exactly one of those.
|
|
140
|
+
*/
|
|
141
|
+
export declare function accountEmailDomain(email: string | null | undefined): string | null;
|
|
142
|
+
/** One row of `users/{uid}/emails`. */
|
|
143
|
+
export interface AccountEmail {
|
|
144
|
+
/** Normalized address; mirrors the document id. */
|
|
145
|
+
address: string;
|
|
146
|
+
/**
|
|
147
|
+
* Proven by an emailed round-trip. An UNVERIFIED address does nothing at
|
|
148
|
+
* all: it is not a sign-in identifier, it receives no account mail beyond
|
|
149
|
+
* its own verification, it holds no claim on the address against another
|
|
150
|
+
* account, and it cannot be made primary.
|
|
151
|
+
*/
|
|
152
|
+
verified: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* Exactly one per account. The primary is the Firebase Auth record's email
|
|
155
|
+
* — receipts, account-critical mail, and every domain-derived decision read
|
|
156
|
+
* it and only it.
|
|
157
|
+
*/
|
|
158
|
+
primary: boolean;
|
|
159
|
+
}
|
|
160
|
+
/** Why a primary re-designation was refused. */
|
|
161
|
+
export type PrimaryChangeVerdict =
|
|
162
|
+
/** Allowed. */
|
|
163
|
+
'ok'
|
|
164
|
+
/** No such address on this account. */
|
|
165
|
+
| 'unknown-address'
|
|
166
|
+
/** The address exists but has not completed its round-trip. */
|
|
167
|
+
| 'unverified'
|
|
168
|
+
/** It is already the primary; a no-op, refused so the UI need not guess. */
|
|
169
|
+
| 'already-primary'
|
|
170
|
+
/**
|
|
171
|
+
* THE SECURITY REFUSAL. The CURRENT primary sits on a domain this
|
|
172
|
+
* deployment requires SSO for, and the requested primary does not.
|
|
173
|
+
*
|
|
174
|
+
* The primary is `decoded.email`. `evaluateSsoDomainPolicy` reads
|
|
175
|
+
* `decoded.email` at the session mint and refuses an account on a governed
|
|
176
|
+
* domain that did not come through the designated tenant. So an account
|
|
177
|
+
* governed by that policy could add a personal address, promote it, and
|
|
178
|
+
* walk straight out of the rule — with no IdP involved and nothing in the
|
|
179
|
+
* org's control plane recording it.
|
|
180
|
+
*
|
|
181
|
+
* Refused rather than merely flagged: the whole point of the policy is that
|
|
182
|
+
* the account cannot choose to be ungoverned.
|
|
183
|
+
*/
|
|
184
|
+
| 'sso-governed-escape'
|
|
185
|
+
/**
|
|
186
|
+
* The requested primary sits on a governed domain the account cannot
|
|
187
|
+
* satisfy — promoting it would make the NEXT session mint refuse them.
|
|
188
|
+
*
|
|
189
|
+
* This is self-lockout rather than escalation, so it is refused for the
|
|
190
|
+
* user's sake rather than the platform's: verifying a mailbox proves
|
|
191
|
+
* delivery, it does not put the account inside the org's IdP.
|
|
192
|
+
*/
|
|
193
|
+
| 'sso-governed-lockout';
|
|
194
|
+
export interface PrimaryChangeFacts {
|
|
195
|
+
/** The account's current primary, or null when it somehow has none. */
|
|
196
|
+
current: AccountEmail | null;
|
|
197
|
+
/** The row the caller asked to promote, or null when they named an unknown address. */
|
|
198
|
+
next: AccountEmail | null;
|
|
199
|
+
/**
|
|
200
|
+
* `ssoRequiredDomains()` — domain → the GCIP tenant id that domain must
|
|
201
|
+
* sign in through. Empty on a self-host install and on any deployment that
|
|
202
|
+
* has not configured the policy, which makes both refusals inert there.
|
|
203
|
+
*/
|
|
204
|
+
requiredDomains: Record<string, string>;
|
|
205
|
+
/**
|
|
206
|
+
* The tenant the account actually signed in through; null = project pool.
|
|
207
|
+
* Straight from `decoded.firebase?.tenant`, never inferred.
|
|
208
|
+
*/
|
|
209
|
+
tenantId: string | null;
|
|
210
|
+
/**
|
|
211
|
+
* Whether the enforcement switch (`AGLYN_SSO_DOMAIN_ENFORCEMENT`) is on.
|
|
212
|
+
*
|
|
213
|
+
* The LOCKOUT refusal is gated on it, because with the switch off promoting
|
|
214
|
+
* a governed address locks nobody out. The ESCAPE refusal is NOT gated on
|
|
215
|
+
* it — see {@link evaluatePrimaryChange}.
|
|
216
|
+
*/
|
|
217
|
+
enforcementEnabled: boolean;
|
|
218
|
+
}
|
|
219
|
+
export interface PrimaryChangeDecision {
|
|
220
|
+
allowed: boolean;
|
|
221
|
+
verdict: PrimaryChangeVerdict;
|
|
222
|
+
/** What the person is told. Null when allowed. */
|
|
223
|
+
message: string | null;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* May this account promote `next` to primary?
|
|
227
|
+
*
|
|
228
|
+
* Pure and total, so the console can grey out the control with the same
|
|
229
|
+
* verdict the API route refuses with.
|
|
230
|
+
*
|
|
231
|
+
* ## Why the ESCAPE refusal ignores the enforcement switch
|
|
232
|
+
*
|
|
233
|
+
* `ssoDomainRefusal` ships inert: it computes `refused` but returns null
|
|
234
|
+
* until `AGLYN_SSO_DOMAIN_ENFORCEMENT=on`, so the audit trail accumulates
|
|
235
|
+
* under the real rule before the rule bites. That is right for a gate that
|
|
236
|
+
* turns people away.
|
|
237
|
+
*
|
|
238
|
+
* It is exactly wrong for this one. A primary change is PERSISTENT: promote a
|
|
239
|
+
* personal address while the switch is off, and when the switch is later
|
|
240
|
+
* flipped the account is simply not on a governed domain any more. The
|
|
241
|
+
* escape would already have happened, silently, and the audit trail the
|
|
242
|
+
* inert period was supposed to build would record nothing — because from the
|
|
243
|
+
* policy's point of view there is no longer anything to record.
|
|
244
|
+
*
|
|
245
|
+
* So the escape is refused whenever the deployment has CONFIGURED governed
|
|
246
|
+
* domains, switch or no switch. A deployment that has configured none — every
|
|
247
|
+
* self-host install, and Aglyn itself until the domains are set — is
|
|
248
|
+
* unaffected, because `requiredDomains` is empty and `requiredTenantFor`
|
|
249
|
+
* returns null for everything.
|
|
250
|
+
*/
|
|
251
|
+
export declare function evaluatePrimaryChange(facts: PrimaryChangeFacts): PrimaryChangeDecision;
|
|
252
|
+
/**
|
|
253
|
+
* Whether an address may be removed.
|
|
254
|
+
*
|
|
255
|
+
* Two floors, both from GitHub: the primary is not removable (demote it
|
|
256
|
+
* first), and the LAST VERIFIED address is not removable — an account with no
|
|
257
|
+
* verified address has no way to receive a password reset, which is an
|
|
258
|
+
* account nobody can recover.
|
|
259
|
+
*/
|
|
260
|
+
export declare function canRemoveAccountEmail(address: string, emails: readonly AccountEmail[]): {
|
|
261
|
+
allowed: boolean;
|
|
262
|
+
message: string | null;
|
|
263
|
+
};
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ /**
|
|
17
|
+
* Several email addresses per account (AGL-2486) — GitHub's model, adopted
|
|
18
|
+
* verbatim because the answer to "how should a secondary address interact
|
|
19
|
+
* with an SSO domain claim?" was "do whatever github does to handle this".
|
|
20
|
+
*
|
|
21
|
+
* ## The one rule everything else here exists to serve
|
|
22
|
+
*
|
|
23
|
+
* **Adding an address to an account NEVER grants organization access.**
|
|
24
|
+
*
|
|
25
|
+
* On GitHub, org membership comes from an invitation or from SAML/SCIM
|
|
26
|
+
* provisioning by the IdP. Verified domains drive notification restrictions
|
|
27
|
+
* and badges; they do not auto-join anybody. SAML SSO links an *external
|
|
28
|
+
* identity* — the assertion the IdP makes at sign-in — to the account. It
|
|
29
|
+
* never matches on the domain of an address the user typed into a settings
|
|
30
|
+
* form.
|
|
31
|
+
*
|
|
32
|
+
* That distinction is load-bearing HERE in a way it is not on GitHub, because
|
|
33
|
+
* Aglyn has `/api/auth/sso-jit`, which just-in-time provisions org membership
|
|
34
|
+
* from a verified email's domain. If a secondary address could satisfy an
|
|
35
|
+
* `ssoDomains` lookup, then adding an address to your own account would JIT
|
|
36
|
+
* you into somebody else's organization — a privilege escalation delivered by
|
|
37
|
+
* a feature that looks like a convenience. So:
|
|
38
|
+
*
|
|
39
|
+
* - SSO domain routing and JIT provisioning read the identity **the IdP
|
|
40
|
+
* asserted at sign-in** (`decoded.email`, re-verified against the org's
|
|
41
|
+
* GCIP tenant). Never this collection.
|
|
42
|
+
* - Where a domain is consulted outside the SSO flow at all, it is derived
|
|
43
|
+
* from the **primary** address only — which is the Firebase Auth record's
|
|
44
|
+
* email, i.e. the same string the token carries.
|
|
45
|
+
* - A secondary address is a *sign-in identifier* and a *delivery address*.
|
|
46
|
+
* It is never an authorization input.
|
|
47
|
+
*
|
|
48
|
+
* `apps/console/specs/account-emails-never-reach-sso.spec.ts` is the negative
|
|
49
|
+
* proof, and it is written to FAIL if the guards are removed.
|
|
50
|
+
*
|
|
51
|
+
* ## Why the primary is special, and why it cannot always be moved
|
|
52
|
+
*
|
|
53
|
+
* The primary IS the Firebase Auth record's email. It is what
|
|
54
|
+
* `decoded.email` carries, so it is the input to
|
|
55
|
+
* `evaluateSsoDomainPolicy` at the session mint and to the invite-accept
|
|
56
|
+
* comparison. Re-designating it therefore CHANGES an authorization input —
|
|
57
|
+
* which is why {@link evaluatePrimaryChange} exists and why it refuses to
|
|
58
|
+
* move a primary off an SSO-governed domain. Without that refusal, this
|
|
59
|
+
* feature would hand every governed account a one-click way out of its own
|
|
60
|
+
* organization's sign-in policy. See the verdict docs below.
|
|
61
|
+
*
|
|
62
|
+
* ## This module is PURE
|
|
63
|
+
*
|
|
64
|
+
* No Firebase, no env, no I/O — every fact it decides on is passed in. That
|
|
65
|
+
* is deliberate and copied from `sso-domain-policy.ts`: a spec can drive
|
|
66
|
+
* every combination directly, and the console (which shows the user *why* a
|
|
67
|
+
* control is disabled) and the API route (which enforces it) can never
|
|
68
|
+
* disagree about what the policy says.
|
|
69
|
+
*/ /**
|
|
70
|
+
* How many addresses one account may hold, primary included.
|
|
71
|
+
*
|
|
72
|
+
* THE CAP IS NOT DECORATION. `users/{uid}/emails` is a new subcollection, and
|
|
73
|
+
* this repo has a recorded hole from shipping exactly one of those with no
|
|
74
|
+
* ceiling (AGL-2266: content entries, a free org minting unbounded Firestore
|
|
75
|
+
* documents from the browser). The rules deny client writes here outright —
|
|
76
|
+
* see the `emails` match block — so the browser cannot create these at all;
|
|
77
|
+
* this number is the server-side ceiling that stops the API route being the
|
|
78
|
+
* unbounded writer instead. Every add path counts before it writes.
|
|
79
|
+
*
|
|
80
|
+
* Five rather than GitHub's much larger allowance: each address costs a
|
|
81
|
+
* verification email, and the point of the feature is "my work address and my
|
|
82
|
+
* personal one", not address collecting.
|
|
83
|
+
*/ export const MAX_ACCOUNT_EMAILS = 5;
|
|
84
|
+
/** RFC 5321's practical ceiling; also what Firebase Auth accepts. */ export const ACCOUNT_EMAIL_MAX_LENGTH = 254;
|
|
85
|
+
/**
|
|
86
|
+
* The addresses this feature accepts.
|
|
87
|
+
*
|
|
88
|
+
* Deliberately NARROWER than RFC 5322, for a reason beyond tidiness: a
|
|
89
|
+
* normalized address is used verbatim as a Firestore **document id** (both
|
|
90
|
+
* `users/{uid}/emails/{address}` and `emailIdentityIndex/{address}`), so the
|
|
91
|
+
* pattern has to exclude every string a document id may not be:
|
|
92
|
+
*
|
|
93
|
+
* - no `/` — the one character a document id genuinely cannot contain;
|
|
94
|
+
* - no leading/trailing/doubled dot in the local part, so the id can never be
|
|
95
|
+
* `.` or `..`;
|
|
96
|
+
* - the required `@` means the id can never match Firestore's reserved
|
|
97
|
+
* `__.*__` form.
|
|
98
|
+
*
|
|
99
|
+
* A hash would also have worked and would have been unreadable in the
|
|
100
|
+
* console, in an export, and in a support conversation. The uniqueness index
|
|
101
|
+
* is a thing humans have to debug, so it stays legible.
|
|
102
|
+
*/ export const ACCOUNT_EMAIL_PATTERN = /^[a-z0-9!#$%&'*+=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+=?^_`{|}~-]+)*@[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/;
|
|
103
|
+
/**
|
|
104
|
+
* Trim, lower-case, validate. Returns null for anything this feature will not
|
|
105
|
+
* store — callers treat null as "reject", never as "store the raw input".
|
|
106
|
+
*
|
|
107
|
+
* **Lower-casing the LOCAL part is a deliberate, lossy choice.** RFC 5321 says
|
|
108
|
+
* the local part is the receiving server's business and may be
|
|
109
|
+
* case-sensitive; in practice no mainstream provider treats it that way, and
|
|
110
|
+
* Firebase Auth lower-cases it too. It has to happen here because uniqueness
|
|
111
|
+
* is the whole security property: if `Ada@acme.com` and `ada@acme.com` could
|
|
112
|
+
* both be verified, they would be two index entries for one mailbox and the
|
|
113
|
+
* sign-in identifier would be ambiguous — which is the account-takeover shape
|
|
114
|
+
* this feature has to avoid.
|
|
115
|
+
*
|
|
116
|
+
* What is NOT normalized away, on purpose: plus-addressing and dots in the
|
|
117
|
+
* local part. `a+b@x.com` and `a@x.com` are the same mailbox at Gmail and
|
|
118
|
+
* different mailboxes almost everywhere else, so collapsing them would refuse
|
|
119
|
+
* an address the user legitimately owns at every provider that is not Gmail.
|
|
120
|
+
* Two accounts CAN therefore hold `a@x.com` and `a+b@x.com` separately; that
|
|
121
|
+
* is correct, because delivery is what an address means here.
|
|
122
|
+
*/ export function normalizeAccountEmail(input) {
|
|
123
|
+
const raw = String(input != null ? input : '').trim().toLowerCase();
|
|
124
|
+
if (!raw || raw.length > ACCOUNT_EMAIL_MAX_LENGTH) return null;
|
|
125
|
+
if (!ACCOUNT_EMAIL_PATTERN.test(raw)) return null;
|
|
126
|
+
return raw;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The domain of an address, lower-cased; null when there isn't one.
|
|
130
|
+
*
|
|
131
|
+
* Same shape and same `lastIndexOf` as `domainOf` in `sso-domain-policy.ts`.
|
|
132
|
+
* It is duplicated rather than imported because that module is server-only
|
|
133
|
+
* (`@aglyn/tenant-data-admin`) and this one is imported by the console's
|
|
134
|
+
* client bundle — an nx boundary the lint enforces.
|
|
135
|
+
*
|
|
136
|
+
* WHERE THIS MAY BE USED: display, and the primary-change policy below.
|
|
137
|
+
* NOT for resolving an org, an IdP, or a membership. Those read the address
|
|
138
|
+
* the IdP asserted, and there is exactly one of those.
|
|
139
|
+
*/ export function accountEmailDomain(email) {
|
|
140
|
+
const address = String(email != null ? email : '').trim().toLowerCase();
|
|
141
|
+
const at = address.lastIndexOf('@');
|
|
142
|
+
if (at < 0 || at === address.length - 1) return null;
|
|
143
|
+
return address.slice(at + 1);
|
|
144
|
+
}
|
|
145
|
+
/** Exact-match lookup, never a suffix test — `notacme.com` ends with `acme.com`. */ function requiredTenantFor(domain, domains) {
|
|
146
|
+
var _domains_domain;
|
|
147
|
+
if (domain === null || domain === '') return null;
|
|
148
|
+
if (!Object.prototype.hasOwnProperty.call(domains, domain)) return null;
|
|
149
|
+
return (_domains_domain = domains[domain]) != null ? _domains_domain : null;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* May this account promote `next` to primary?
|
|
153
|
+
*
|
|
154
|
+
* Pure and total, so the console can grey out the control with the same
|
|
155
|
+
* verdict the API route refuses with.
|
|
156
|
+
*
|
|
157
|
+
* ## Why the ESCAPE refusal ignores the enforcement switch
|
|
158
|
+
*
|
|
159
|
+
* `ssoDomainRefusal` ships inert: it computes `refused` but returns null
|
|
160
|
+
* until `AGLYN_SSO_DOMAIN_ENFORCEMENT=on`, so the audit trail accumulates
|
|
161
|
+
* under the real rule before the rule bites. That is right for a gate that
|
|
162
|
+
* turns people away.
|
|
163
|
+
*
|
|
164
|
+
* It is exactly wrong for this one. A primary change is PERSISTENT: promote a
|
|
165
|
+
* personal address while the switch is off, and when the switch is later
|
|
166
|
+
* flipped the account is simply not on a governed domain any more. The
|
|
167
|
+
* escape would already have happened, silently, and the audit trail the
|
|
168
|
+
* inert period was supposed to build would record nothing — because from the
|
|
169
|
+
* policy's point of view there is no longer anything to record.
|
|
170
|
+
*
|
|
171
|
+
* So the escape is refused whenever the deployment has CONFIGURED governed
|
|
172
|
+
* domains, switch or no switch. A deployment that has configured none — every
|
|
173
|
+
* self-host install, and Aglyn itself until the domains are set — is
|
|
174
|
+
* unaffected, because `requiredDomains` is empty and `requiredTenantFor`
|
|
175
|
+
* returns null for everything.
|
|
176
|
+
*/ export function evaluatePrimaryChange(facts) {
|
|
177
|
+
const next = facts.next;
|
|
178
|
+
if (next === null || next === undefined) {
|
|
179
|
+
return {
|
|
180
|
+
allowed: false,
|
|
181
|
+
verdict: 'unknown-address',
|
|
182
|
+
message: 'That address is not on this account.'
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (next.verified !== true) {
|
|
186
|
+
return {
|
|
187
|
+
allowed: false,
|
|
188
|
+
verdict: 'unverified',
|
|
189
|
+
message: 'Confirm this address before making it your primary.'
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (next.primary === true) {
|
|
193
|
+
return {
|
|
194
|
+
allowed: false,
|
|
195
|
+
verdict: 'already-primary',
|
|
196
|
+
message: 'That address is already your primary.'
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const currentAddress = facts.current === null || facts.current === undefined ? null : facts.current.address;
|
|
200
|
+
const currentRequired = requiredTenantFor(accountEmailDomain(currentAddress), facts.requiredDomains);
|
|
201
|
+
const nextRequired = requiredTenantFor(accountEmailDomain(next.address), facts.requiredDomains);
|
|
202
|
+
// ESCAPE: leaving a governed domain for one the policy does not reach.
|
|
203
|
+
// Note this compares the REQUIREMENT, not the domain — moving between two
|
|
204
|
+
// domains that are both governed by the same tenant is not an escape.
|
|
205
|
+
if (currentRequired !== null && nextRequired !== currentRequired) {
|
|
206
|
+
return {
|
|
207
|
+
allowed: false,
|
|
208
|
+
verdict: 'sso-governed-escape',
|
|
209
|
+
message: 'Your organization requires single sign-on for this address, so it ' + 'has to stay your primary. Ask an administrator to change it for you.'
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
// LOCKOUT: moving ONTO a governed domain the account does not sign in
|
|
213
|
+
// through. Verifying a mailbox proves delivery; it does not put you inside
|
|
214
|
+
// the organization's identity provider.
|
|
215
|
+
if (facts.enforcementEnabled === true && nextRequired !== null && facts.tenantId !== nextRequired) {
|
|
216
|
+
return {
|
|
217
|
+
allowed: false,
|
|
218
|
+
verdict: 'sso-governed-lockout',
|
|
219
|
+
message: 'That address is on a domain that signs in through an identity ' + 'provider. Making it your primary would lock this account out, so ' + 'sign in through that provider instead.'
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
allowed: true,
|
|
224
|
+
verdict: 'ok',
|
|
225
|
+
message: null
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Whether an address may be removed.
|
|
230
|
+
*
|
|
231
|
+
* Two floors, both from GitHub: the primary is not removable (demote it
|
|
232
|
+
* first), and the LAST VERIFIED address is not removable — an account with no
|
|
233
|
+
* verified address has no way to receive a password reset, which is an
|
|
234
|
+
* account nobody can recover.
|
|
235
|
+
*/ export function canRemoveAccountEmail(address, emails) {
|
|
236
|
+
const row = emails.find((entry)=>entry.address === address);
|
|
237
|
+
if (row === undefined) {
|
|
238
|
+
return {
|
|
239
|
+
allowed: false,
|
|
240
|
+
message: 'That address is not on this account.'
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
if (row.primary === true) {
|
|
244
|
+
return {
|
|
245
|
+
allowed: false,
|
|
246
|
+
message: 'This is your primary address. Make another address primary first.'
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
if (row.verified === true) {
|
|
250
|
+
const otherVerified = emails.filter((entry)=>entry.verified === true && entry.address !== address);
|
|
251
|
+
if (otherVerified.length === 0) {
|
|
252
|
+
return {
|
|
253
|
+
allowed: false,
|
|
254
|
+
message: 'This is your only confirmed address — removing it would leave no ' + 'way to recover this account.'
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
allowed: true,
|
|
260
|
+
message: null
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
//# sourceMappingURL=account-emails.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/account-emails.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Several email addresses per account (AGL-2486) — GitHub's model, adopted\n * verbatim because the answer to \"how should a secondary address interact\n * with an SSO domain claim?\" was \"do whatever github does to handle this\".\n *\n * ## The one rule everything else here exists to serve\n *\n * **Adding an address to an account NEVER grants organization access.**\n *\n * On GitHub, org membership comes from an invitation or from SAML/SCIM\n * provisioning by the IdP. Verified domains drive notification restrictions\n * and badges; they do not auto-join anybody. SAML SSO links an *external\n * identity* — the assertion the IdP makes at sign-in — to the account. It\n * never matches on the domain of an address the user typed into a settings\n * form.\n *\n * That distinction is load-bearing HERE in a way it is not on GitHub, because\n * Aglyn has `/api/auth/sso-jit`, which just-in-time provisions org membership\n * from a verified email's domain. If a secondary address could satisfy an\n * `ssoDomains` lookup, then adding an address to your own account would JIT\n * you into somebody else's organization — a privilege escalation delivered by\n * a feature that looks like a convenience. So:\n *\n * - SSO domain routing and JIT provisioning read the identity **the IdP\n * asserted at sign-in** (`decoded.email`, re-verified against the org's\n * GCIP tenant). Never this collection.\n * - Where a domain is consulted outside the SSO flow at all, it is derived\n * from the **primary** address only — which is the Firebase Auth record's\n * email, i.e. the same string the token carries.\n * - A secondary address is a *sign-in identifier* and a *delivery address*.\n * It is never an authorization input.\n *\n * `apps/console/specs/account-emails-never-reach-sso.spec.ts` is the negative\n * proof, and it is written to FAIL if the guards are removed.\n *\n * ## Why the primary is special, and why it cannot always be moved\n *\n * The primary IS the Firebase Auth record's email. It is what\n * `decoded.email` carries, so it is the input to\n * `evaluateSsoDomainPolicy` at the session mint and to the invite-accept\n * comparison. Re-designating it therefore CHANGES an authorization input —\n * which is why {@link evaluatePrimaryChange} exists and why it refuses to\n * move a primary off an SSO-governed domain. Without that refusal, this\n * feature would hand every governed account a one-click way out of its own\n * organization's sign-in policy. See the verdict docs below.\n *\n * ## This module is PURE\n *\n * No Firebase, no env, no I/O — every fact it decides on is passed in. That\n * is deliberate and copied from `sso-domain-policy.ts`: a spec can drive\n * every combination directly, and the console (which shows the user *why* a\n * control is disabled) and the API route (which enforces it) can never\n * disagree about what the policy says.\n */\n\n/**\n * How many addresses one account may hold, primary included.\n *\n * THE CAP IS NOT DECORATION. `users/{uid}/emails` is a new subcollection, and\n * this repo has a recorded hole from shipping exactly one of those with no\n * ceiling (AGL-2266: content entries, a free org minting unbounded Firestore\n * documents from the browser). The rules deny client writes here outright —\n * see the `emails` match block — so the browser cannot create these at all;\n * this number is the server-side ceiling that stops the API route being the\n * unbounded writer instead. Every add path counts before it writes.\n *\n * Five rather than GitHub's much larger allowance: each address costs a\n * verification email, and the point of the feature is \"my work address and my\n * personal one\", not address collecting.\n */\nexport const MAX_ACCOUNT_EMAILS = 5\n\n/** RFC 5321's practical ceiling; also what Firebase Auth accepts. */\nexport const ACCOUNT_EMAIL_MAX_LENGTH = 254\n\n/**\n * The addresses this feature accepts.\n *\n * Deliberately NARROWER than RFC 5322, for a reason beyond tidiness: a\n * normalized address is used verbatim as a Firestore **document id** (both\n * `users/{uid}/emails/{address}` and `emailIdentityIndex/{address}`), so the\n * pattern has to exclude every string a document id may not be:\n *\n * - no `/` — the one character a document id genuinely cannot contain;\n * - no leading/trailing/doubled dot in the local part, so the id can never be\n * `.` or `..`;\n * - the required `@` means the id can never match Firestore's reserved\n * `__.*__` form.\n *\n * A hash would also have worked and would have been unreadable in the\n * console, in an export, and in a support conversation. The uniqueness index\n * is a thing humans have to debug, so it stays legible.\n */\nexport const ACCOUNT_EMAIL_PATTERN =\n /^[a-z0-9!#$%&'*+=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+=?^_`{|}~-]+)*@[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/\n\n/**\n * Trim, lower-case, validate. Returns null for anything this feature will not\n * store — callers treat null as \"reject\", never as \"store the raw input\".\n *\n * **Lower-casing the LOCAL part is a deliberate, lossy choice.** RFC 5321 says\n * the local part is the receiving server's business and may be\n * case-sensitive; in practice no mainstream provider treats it that way, and\n * Firebase Auth lower-cases it too. It has to happen here because uniqueness\n * is the whole security property: if `Ada@acme.com` and `ada@acme.com` could\n * both be verified, they would be two index entries for one mailbox and the\n * sign-in identifier would be ambiguous — which is the account-takeover shape\n * this feature has to avoid.\n *\n * What is NOT normalized away, on purpose: plus-addressing and dots in the\n * local part. `a+b@x.com` and `a@x.com` are the same mailbox at Gmail and\n * different mailboxes almost everywhere else, so collapsing them would refuse\n * an address the user legitimately owns at every provider that is not Gmail.\n * Two accounts CAN therefore hold `a@x.com` and `a+b@x.com` separately; that\n * is correct, because delivery is what an address means here.\n */\nexport function normalizeAccountEmail(input: unknown): string | null {\n const raw = String(input ?? '')\n .trim()\n .toLowerCase()\n if (!raw || raw.length > ACCOUNT_EMAIL_MAX_LENGTH) return null\n if (!ACCOUNT_EMAIL_PATTERN.test(raw)) return null\n return raw\n}\n\n/**\n * The domain of an address, lower-cased; null when there isn't one.\n *\n * Same shape and same `lastIndexOf` as `domainOf` in `sso-domain-policy.ts`.\n * It is duplicated rather than imported because that module is server-only\n * (`@aglyn/tenant-data-admin`) and this one is imported by the console's\n * client bundle — an nx boundary the lint enforces.\n *\n * WHERE THIS MAY BE USED: display, and the primary-change policy below.\n * NOT for resolving an org, an IdP, or a membership. Those read the address\n * the IdP asserted, and there is exactly one of those.\n */\nexport function accountEmailDomain(email: string | null | undefined): string | null {\n const address = String(email ?? '')\n .trim()\n .toLowerCase()\n const at = address.lastIndexOf('@')\n if (at < 0 || at === address.length - 1) return null\n return address.slice(at + 1)\n}\n\n/** One row of `users/{uid}/emails`. */\nexport interface AccountEmail {\n /** Normalized address; mirrors the document id. */\n address: string\n /**\n * Proven by an emailed round-trip. An UNVERIFIED address does nothing at\n * all: it is not a sign-in identifier, it receives no account mail beyond\n * its own verification, it holds no claim on the address against another\n * account, and it cannot be made primary.\n */\n verified: boolean\n /**\n * Exactly one per account. The primary is the Firebase Auth record's email\n * — receipts, account-critical mail, and every domain-derived decision read\n * it and only it.\n */\n primary: boolean\n}\n\n/** Why a primary re-designation was refused. */\nexport type PrimaryChangeVerdict =\n /** Allowed. */\n | 'ok'\n /** No such address on this account. */\n | 'unknown-address'\n /** The address exists but has not completed its round-trip. */\n | 'unverified'\n /** It is already the primary; a no-op, refused so the UI need not guess. */\n | 'already-primary'\n /**\n * THE SECURITY REFUSAL. The CURRENT primary sits on a domain this\n * deployment requires SSO for, and the requested primary does not.\n *\n * The primary is `decoded.email`. `evaluateSsoDomainPolicy` reads\n * `decoded.email` at the session mint and refuses an account on a governed\n * domain that did not come through the designated tenant. So an account\n * governed by that policy could add a personal address, promote it, and\n * walk straight out of the rule — with no IdP involved and nothing in the\n * org's control plane recording it.\n *\n * Refused rather than merely flagged: the whole point of the policy is that\n * the account cannot choose to be ungoverned.\n */\n | 'sso-governed-escape'\n /**\n * The requested primary sits on a governed domain the account cannot\n * satisfy — promoting it would make the NEXT session mint refuse them.\n *\n * This is self-lockout rather than escalation, so it is refused for the\n * user's sake rather than the platform's: verifying a mailbox proves\n * delivery, it does not put the account inside the org's IdP.\n */\n | 'sso-governed-lockout'\n\nexport interface PrimaryChangeFacts {\n /** The account's current primary, or null when it somehow has none. */\n current: AccountEmail | null\n /** The row the caller asked to promote, or null when they named an unknown address. */\n next: AccountEmail | null\n /**\n * `ssoRequiredDomains()` — domain → the GCIP tenant id that domain must\n * sign in through. Empty on a self-host install and on any deployment that\n * has not configured the policy, which makes both refusals inert there.\n */\n requiredDomains: Record<string, string>\n /**\n * The tenant the account actually signed in through; null = project pool.\n * Straight from `decoded.firebase?.tenant`, never inferred.\n */\n tenantId: string | null\n /**\n * Whether the enforcement switch (`AGLYN_SSO_DOMAIN_ENFORCEMENT`) is on.\n *\n * The LOCKOUT refusal is gated on it, because with the switch off promoting\n * a governed address locks nobody out. The ESCAPE refusal is NOT gated on\n * it — see {@link evaluatePrimaryChange}.\n */\n enforcementEnabled: boolean\n}\n\nexport interface PrimaryChangeDecision {\n allowed: boolean\n verdict: PrimaryChangeVerdict\n /** What the person is told. Null when allowed. */\n message: string | null\n}\n\n/** Exact-match lookup, never a suffix test — `notacme.com` ends with `acme.com`. */\nfunction requiredTenantFor(\n domain: string | null,\n domains: Record<string, string>,\n): string | null {\n if (domain === null || domain === '') return null\n if (!Object.prototype.hasOwnProperty.call(domains, domain)) return null\n return domains[domain] ?? null\n}\n\n/**\n * May this account promote `next` to primary?\n *\n * Pure and total, so the console can grey out the control with the same\n * verdict the API route refuses with.\n *\n * ## Why the ESCAPE refusal ignores the enforcement switch\n *\n * `ssoDomainRefusal` ships inert: it computes `refused` but returns null\n * until `AGLYN_SSO_DOMAIN_ENFORCEMENT=on`, so the audit trail accumulates\n * under the real rule before the rule bites. That is right for a gate that\n * turns people away.\n *\n * It is exactly wrong for this one. A primary change is PERSISTENT: promote a\n * personal address while the switch is off, and when the switch is later\n * flipped the account is simply not on a governed domain any more. The\n * escape would already have happened, silently, and the audit trail the\n * inert period was supposed to build would record nothing — because from the\n * policy's point of view there is no longer anything to record.\n *\n * So the escape is refused whenever the deployment has CONFIGURED governed\n * domains, switch or no switch. A deployment that has configured none — every\n * self-host install, and Aglyn itself until the domains are set — is\n * unaffected, because `requiredDomains` is empty and `requiredTenantFor`\n * returns null for everything.\n */\nexport function evaluatePrimaryChange(\n facts: PrimaryChangeFacts,\n): PrimaryChangeDecision {\n const next = facts.next\n if (next === null || next === undefined) {\n return {\n allowed: false,\n verdict: 'unknown-address',\n message: 'That address is not on this account.',\n }\n }\n if (next.verified !== true) {\n return {\n allowed: false,\n verdict: 'unverified',\n message: 'Confirm this address before making it your primary.',\n }\n }\n if (next.primary === true) {\n return {\n allowed: false,\n verdict: 'already-primary',\n message: 'That address is already your primary.',\n }\n }\n\n const currentAddress =\n facts.current === null || facts.current === undefined\n ? null\n : facts.current.address\n const currentRequired = requiredTenantFor(\n accountEmailDomain(currentAddress),\n facts.requiredDomains,\n )\n const nextRequired = requiredTenantFor(\n accountEmailDomain(next.address),\n facts.requiredDomains,\n )\n\n // ESCAPE: leaving a governed domain for one the policy does not reach.\n // Note this compares the REQUIREMENT, not the domain — moving between two\n // domains that are both governed by the same tenant is not an escape.\n if (currentRequired !== null && nextRequired !== currentRequired) {\n return {\n allowed: false,\n verdict: 'sso-governed-escape',\n message:\n 'Your organization requires single sign-on for this address, so it ' +\n 'has to stay your primary. Ask an administrator to change it for you.',\n }\n }\n\n // LOCKOUT: moving ONTO a governed domain the account does not sign in\n // through. Verifying a mailbox proves delivery; it does not put you inside\n // the organization's identity provider.\n if (\n facts.enforcementEnabled === true &&\n nextRequired !== null &&\n facts.tenantId !== nextRequired\n ) {\n return {\n allowed: false,\n verdict: 'sso-governed-lockout',\n message:\n 'That address is on a domain that signs in through an identity ' +\n 'provider. Making it your primary would lock this account out, so ' +\n 'sign in through that provider instead.',\n }\n }\n\n return { allowed: true, verdict: 'ok', message: null }\n}\n\n/**\n * Whether an address may be removed.\n *\n * Two floors, both from GitHub: the primary is not removable (demote it\n * first), and the LAST VERIFIED address is not removable — an account with no\n * verified address has no way to receive a password reset, which is an\n * account nobody can recover.\n */\nexport function canRemoveAccountEmail(\n address: string,\n emails: readonly AccountEmail[],\n): { allowed: boolean; message: string | null } {\n const row = emails.find((entry) => entry.address === address)\n if (row === undefined) {\n return { allowed: false, message: 'That address is not on this account.' }\n }\n if (row.primary === true) {\n return {\n allowed: false,\n message:\n 'This is your primary address. Make another address primary first.',\n }\n }\n if (row.verified === true) {\n const otherVerified = emails.filter(\n (entry) => entry.verified === true && entry.address !== address,\n )\n if (otherVerified.length === 0) {\n return {\n allowed: false,\n message:\n 'This is your only confirmed address — removing it would leave no ' +\n 'way to recover this account.',\n }\n }\n }\n return { allowed: true, message: null }\n}\n"],"names":["MAX_ACCOUNT_EMAILS","ACCOUNT_EMAIL_MAX_LENGTH","ACCOUNT_EMAIL_PATTERN","normalizeAccountEmail","input","raw","String","trim","toLowerCase","length","test","accountEmailDomain","email","address","at","lastIndexOf","slice","requiredTenantFor","domain","domains","Object","prototype","hasOwnProperty","call","evaluatePrimaryChange","facts","next","undefined","allowed","verdict","message","verified","primary","currentAddress","current","currentRequired","requiredDomains","nextRequired","enforcementEnabled","tenantId","canRemoveAccountEmail","emails","row","find","entry","otherVerified","filter"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqDC,GAED;;;;;;;;;;;;;;CAcC,GACD,OAAO,MAAMA,qBAAqB,EAAC;AAEnC,mEAAmE,GACnE,OAAO,MAAMC,2BAA2B,IAAG;AAE3C;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,MAAMC,wBACX,wIAAuI;AAEzI;;;;;;;;;;;;;;;;;;;CAmBC,GACD,OAAO,SAASC,sBAAsBC,KAAc;IAClD,MAAMC,MAAMC,OAAOF,gBAAAA,QAAS,IACzBG,IAAI,GACJC,WAAW;IACd,IAAI,CAACH,OAAOA,IAAII,MAAM,GAAGR,0BAA0B,OAAO;IAC1D,IAAI,CAACC,sBAAsBQ,IAAI,CAACL,MAAM,OAAO;IAC7C,OAAOA;AACT;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAASM,mBAAmBC,KAAgC;IACjE,MAAMC,UAAUP,OAAOM,gBAAAA,QAAS,IAC7BL,IAAI,GACJC,WAAW;IACd,MAAMM,KAAKD,QAAQE,WAAW,CAAC;IAC/B,IAAID,KAAK,KAAKA,OAAOD,QAAQJ,MAAM,GAAG,GAAG,OAAO;IAChD,OAAOI,QAAQG,KAAK,CAACF,KAAK;AAC5B;AAyFA,kFAAkF,GAClF,SAASG,kBACPC,MAAqB,EACrBC,OAA+B;QAIxBA;IAFP,IAAID,WAAW,QAAQA,WAAW,IAAI,OAAO;IAC7C,IAAI,CAACE,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACJ,SAASD,SAAS,OAAO;IACnE,QAAOC,kBAAAA,OAAO,CAACD,OAAO,YAAfC,kBAAmB;AAC5B;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;CAyBC,GACD,OAAO,SAASK,sBACdC,KAAyB;IAEzB,MAAMC,OAAOD,MAAMC,IAAI;IACvB,IAAIA,SAAS,QAAQA,SAASC,WAAW;QACvC,OAAO;YACLC,SAAS;YACTC,SAAS;YACTC,SAAS;QACX;IACF;IACA,IAAIJ,KAAKK,QAAQ,KAAK,MAAM;QAC1B,OAAO;YACLH,SAAS;YACTC,SAAS;YACTC,SAAS;QACX;IACF;IACA,IAAIJ,KAAKM,OAAO,KAAK,MAAM;QACzB,OAAO;YACLJ,SAAS;YACTC,SAAS;YACTC,SAAS;QACX;IACF;IAEA,MAAMG,iBACJR,MAAMS,OAAO,KAAK,QAAQT,MAAMS,OAAO,KAAKP,YACxC,OACAF,MAAMS,OAAO,CAACrB,OAAO;IAC3B,MAAMsB,kBAAkBlB,kBACtBN,mBAAmBsB,iBACnBR,MAAMW,eAAe;IAEvB,MAAMC,eAAepB,kBACnBN,mBAAmBe,KAAKb,OAAO,GAC/BY,MAAMW,eAAe;IAGvB,uEAAuE;IACvE,0EAA0E;IAC1E,sEAAsE;IACtE,IAAID,oBAAoB,QAAQE,iBAAiBF,iBAAiB;QAChE,OAAO;YACLP,SAAS;YACTC,SAAS;YACTC,SACE,uEACA;QACJ;IACF;IAEA,sEAAsE;IACtE,2EAA2E;IAC3E,wCAAwC;IACxC,IACEL,MAAMa,kBAAkB,KAAK,QAC7BD,iBAAiB,QACjBZ,MAAMc,QAAQ,KAAKF,cACnB;QACA,OAAO;YACLT,SAAS;YACTC,SAAS;YACTC,SACE,mEACA,sEACA;QACJ;IACF;IAEA,OAAO;QAAEF,SAAS;QAAMC,SAAS;QAAMC,SAAS;IAAK;AACvD;AAEA;;;;;;;CAOC,GACD,OAAO,SAASU,sBACd3B,OAAe,EACf4B,MAA+B;IAE/B,MAAMC,MAAMD,OAAOE,IAAI,CAAC,CAACC,QAAUA,MAAM/B,OAAO,KAAKA;IACrD,IAAI6B,QAAQf,WAAW;QACrB,OAAO;YAAEC,SAAS;YAAOE,SAAS;QAAuC;IAC3E;IACA,IAAIY,IAAIV,OAAO,KAAK,MAAM;QACxB,OAAO;YACLJ,SAAS;YACTE,SACE;QACJ;IACF;IACA,IAAIY,IAAIX,QAAQ,KAAK,MAAM;QACzB,MAAMc,gBAAgBJ,OAAOK,MAAM,CACjC,CAACF,QAAUA,MAAMb,QAAQ,KAAK,QAAQa,MAAM/B,OAAO,KAAKA;QAE1D,IAAIgC,cAAcpC,MAAM,KAAK,GAAG;YAC9B,OAAO;gBACLmB,SAAS;gBACTE,SACE,sEACA;YACJ;QACF;IACF;IACA,OAAO;QAAEF,SAAS;QAAME,SAAS;IAAK;AACxC"}
|