@wildo-ai/saas-models 1.1.2 → 1.1.3
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/dist/esm/applications/applications-context.schemas.d.ts +14 -10
- package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
- package/dist/esm/applications/applications.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/applications/applications.shared.resources-config.schemas.js +4 -3
- package/dist/esm/applications/applications.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/billing-configuration.shared.schemas.d.ts +0 -4
- package/dist/esm/billing/billing-configuration.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-configuration.shared.schemas.js +59 -17
- package/dist/esm/billing/billing-configuration.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-enums.shared.schemas.d.ts +77 -21
- package/dist/esm/billing/billing-enums.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-enums.shared.schemas.js +85 -23
- package/dist/esm/billing/billing-enums.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-types.shared.schemas.d.ts +3 -3
- package/dist/esm/billing/price.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/price.shared.schemas.js +7 -1
- package/dist/esm/billing/price.shared.schemas.js.map +1 -1
- package/dist/esm/billing/product-behavior-policy.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product-behavior-policy.shared.schemas.js +52 -11
- package/dist/esm/billing/product-behavior-policy.shared.schemas.js.map +1 -1
- package/dist/esm/billing/product-definition.shared.schemas.d.ts +2 -2
- package/dist/esm/billing/product.shared.resources-config.schemas.d.ts +2 -2
- package/dist/esm/billing/product.shared.schemas.d.ts +2 -2
- package/dist/esm/billing/product.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product.shared.schemas.js +7 -3
- package/dist/esm/billing/product.shared.schemas.js.map +1 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.js +15 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/usage-record.shared.schemas.d.ts +7 -3
- package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/usage-record.shared.schemas.js +22 -3
- package/dist/esm/billing/usage-record.shared.schemas.js.map +1 -1
- package/dist/esm/companion/provider-discovery.shared.schemas.d.ts +69 -2
- package/dist/esm/companion/provider-discovery.shared.schemas.d.ts.map +1 -1
- package/dist/esm/companion/provider-discovery.shared.schemas.js +20 -1
- package/dist/esm/companion/provider-discovery.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.d.ts +85 -0
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.d.ts.map +1 -0
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.js +157 -0
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.js.map +1 -0
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.d.ts +23 -0
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.js +56 -0
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts +480 -20
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js +547 -23
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js.map +1 -1
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js +82 -3
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts +31 -30
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js +98 -3
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/privacy.shared.schemas.d.ts +17 -0
- package/dist/esm/compliance/privacy/privacy.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/privacy.shared.schemas.js +27 -4
- package/dist/esm/compliance/privacy/privacy.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts +82 -29
- package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.js +95 -29
- package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-export.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-export.shared.schemas.js +12 -5
- package/dist/esm/compliance/privacy/subject-export.shared.schemas.js.map +1 -1
- package/dist/esm/config/analytics-value-moments.shared.schemas.d.ts +21 -0
- package/dist/esm/config/analytics-value-moments.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/analytics-value-moments.shared.schemas.js +20 -0
- package/dist/esm/config/analytics-value-moments.shared.schemas.js.map +1 -1
- package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts +7 -5
- package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/auth-config-resolution.shared.utils.d.ts +8 -1
- package/dist/esm/config/auth-config-resolution.shared.utils.d.ts.map +1 -1
- package/dist/esm/config/auth-config-resolution.shared.utils.js +29 -0
- package/dist/esm/config/auth-config-resolution.shared.utils.js.map +1 -1
- package/dist/esm/config/entity-identity-config.shared.schemas.d.ts +95 -17
- package/dist/esm/config/entity-identity-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/entity-identity-config.shared.schemas.js +86 -8
- package/dist/esm/config/entity-identity-config.shared.schemas.js.map +1 -1
- package/dist/esm/config/frontend/chart-definition.shared.schemas.d.ts +12 -12
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts +28 -0
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts.map +1 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js +28 -0
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts +45 -12
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts +103 -58
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.js +176 -15
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts +15 -3
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js +32 -5
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
- package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts +83 -7
- package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.d.ts +59 -0
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.d.ts.map +1 -0
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.js +61 -0
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.js.map +1 -0
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.d.ts +97 -0
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.d.ts.map +1 -0
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.js +41 -0
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.js.map +1 -0
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.d.ts +148 -2
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.js +56 -1
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts +5 -28
- package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-capability.shared.schemas.js +4 -2
- package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.d.ts +18 -8
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.js +9 -4
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.d.ts +338 -0
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.d.ts.map +1 -0
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.js +332 -0
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.js.map +1 -0
- package/dist/esm/external-providers/provider-metadata.shared.schemas.d.ts +178 -9
- package/dist/esm/external-providers/provider-metadata.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-metadata.shared.schemas.js +181 -9
- package/dist/esm/external-providers/provider-metadata.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-protocol.shared.schemas.d.ts +7 -5
- package/dist/esm/external-providers/provider-protocol.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-protocol.shared.schemas.js +7 -5
- package/dist/esm/external-providers/provider-protocol.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.d.ts +40 -0
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.d.ts.map +1 -0
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.js +80 -0
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.js.map +1 -0
- package/dist/esm/features/core-feature-definitions.shared.d.ts.map +1 -1
- package/dist/esm/features/core-feature-definitions.shared.js +7 -1
- package/dist/esm/features/core-feature-definitions.shared.js.map +1 -1
- package/dist/esm/features/feature-builders.shared.d.ts +32 -0
- package/dist/esm/features/feature-builders.shared.d.ts.map +1 -1
- package/dist/esm/features/feature-builders.shared.js +32 -0
- package/dist/esm/features/feature-builders.shared.js.map +1 -1
- package/dist/esm/files/file-upload-grant.shared.schemas.d.ts +14 -2
- package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -1
- package/dist/esm/files/file-upload-grant.shared.schemas.js +44 -5
- package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -1
- package/dist/esm/files/files.shared.schemas.d.ts +15 -8
- package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
- package/dist/esm/files/files.shared.schemas.js +15 -8
- package/dist/esm/files/files.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/actors.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/actors.shared.schemas.js +3 -2
- package/dist/esm/flows-actors/actors.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/agents.shared.schemas.d.ts +54 -5
- package/dist/esm/flows-actors/agents.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/agents.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/apps-blueprint/apps-blueprint.shared.schemas.d.ts +6 -6
- package/dist/esm/flows-actors/deliberation.shared.schemas.d.ts +0 -3
- package/dist/esm/flows-actors/deliberation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/deliberation.shared.schemas.js +0 -5
- package/dist/esm/flows-actors/deliberation.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts +14 -0
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js +40 -3
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.d.ts +19 -0
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.js +33 -0
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.d.ts +14 -9
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.js +14 -9
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.schemas.js +3 -2
- package/dist/esm/flows-actors/flows-actors.system.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows.shared.schemas.js +3 -2
- package/dist/esm/flows-actors/flows.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.d.ts +128 -0
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.d.ts.map +1 -0
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.js +142 -0
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.js.map +1 -0
- package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.d.ts +0 -3
- package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.js +1 -4
- package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.d.ts +0 -16
- package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.js +1 -17
- package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/decisions.meta-workflows.shared.schemas.d.ts +3 -3
- package/dist/esm/flows-actors/meta-workflows/decisions.meta-workflows.shared.schemas.js +3 -3
- package/dist/esm/flows-actors/meta-workflows/decisions.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.d.ts +2 -8
- package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.js +4 -15
- package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.utils.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.utils.js +1 -0
- package/dist/esm/guidance/guidance-state.shared.utils.js.map +1 -1
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts +8 -0
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/progression-state.shared.schemas.d.ts +46 -0
- package/dist/esm/guidance/progression-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/progression-state.shared.schemas.js +49 -0
- package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts +320 -50
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js +137 -36
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
- package/dist/esm/index.d.ts +9 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +9 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/notifications/email/email-template-registry.shared.schemas.d.ts +11 -2
- package/dist/esm/notifications/email/email-template-registry.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-template-registry.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/email/email-template.shared.enums.d.ts +15 -0
- package/dist/esm/notifications/email/email-template.shared.enums.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-template.shared.enums.js +15 -0
- package/dist/esm/notifications/email/email-template.shared.enums.js.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.d.ts +1 -0
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.js +19 -0
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.d.ts +30 -0
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.js +65 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/notification-badges.core.definitions.d.ts +6 -4
- package/dist/esm/notifications/notification-badges.core.definitions.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.core.definitions.js +6 -4
- package/dist/esm/notifications/notification-badges.core.definitions.js.map +1 -1
- package/dist/esm/notifications/notification-badges.schemas.d.ts +167 -5
- package/dist/esm/notifications/notification-badges.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.schemas.js +191 -6
- package/dist/esm/notifications/notification-badges.schemas.js.map +1 -1
- package/dist/esm/notifications/notifications.shared.schemas.d.ts +107 -0
- package/dist/esm/notifications/notifications.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notifications.shared.schemas.js +149 -1
- package/dist/esm/notifications/notifications.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.schemas.js +22 -1
- package/dist/esm/organizations/organization-notifications.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.schemas.d.ts +26 -0
- package/dist/esm/organizations/organization-preferences.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.schemas.js +25 -0
- package/dist/esm/organizations/organization-preferences.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.schemas.d.ts +25 -0
- package/dist/esm/organizations/organization-profile.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.schemas.js +42 -17
- package/dist/esm/organizations/organization-profile.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.shared.d.ts +3 -2
- package/dist/esm/organizations/organization-unit-narrowing.shared.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.shared.js +9 -2
- package/dist/esm/organizations/organization-unit-narrowing.shared.js.map +1 -1
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.js +18 -3
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/public-runtime/index.d.ts +49 -2
- package/dist/esm/public-runtime/index.d.ts.map +1 -1
- package/dist/esm/public-runtime/index.js +48 -1
- package/dist/esm/public-runtime/index.js.map +1 -1
- package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts +6 -5
- package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/queue/jobs.shared.resources-config.schemas.js +6 -5
- package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/queue/jobs.shared.schemas.d.ts +16 -3
- package/dist/esm/queue/jobs.shared.schemas.d.ts.map +1 -1
- package/dist/esm/queue/jobs.shared.schemas.js +16 -3
- package/dist/esm/queue/jobs.shared.schemas.js.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-documentation.d.ts +137 -0
- package/dist/esm/requests/manual-controllers-routes-documentation.d.ts.map +1 -0
- package/dist/esm/requests/manual-controllers-routes-documentation.js +1201 -0
- package/dist/esm/requests/manual-controllers-routes-documentation.js.map +1 -0
- package/dist/esm/requests/manual-controllers-routes-urls.d.ts +67 -0
- package/dist/esm/requests/manual-controllers-routes-urls.d.ts.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-urls.js +78 -0
- package/dist/esm/requests/manual-controllers-routes-urls.js.map +1 -1
- package/dist/esm/requests/rate-limits.shared.schemas.d.ts +11 -1
- package/dist/esm/requests/rate-limits.shared.schemas.d.ts.map +1 -1
- package/dist/esm/requests/rate-limits.shared.schemas.js +11 -1
- package/dist/esm/requests/rate-limits.shared.schemas.js.map +1 -1
- package/dist/esm/requests/websocket.shared.schemas.d.ts +27 -4
- package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
- package/dist/esm/requests/websocket.shared.schemas.js +35 -0
- package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources-config.shared.factory.d.ts +1 -0
- package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
- package/dist/esm/resources/resources-config.shared.factory.js +105 -20
- package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
- package/dist/esm/resources/resources-config.shared.schemas.d.ts +254 -72
- package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources-config.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources-registry.shared.core.definitions.d.ts.map +1 -1
- package/dist/esm/resources/resources-registry.shared.core.definitions.js +97 -5
- package/dist/esm/resources/resources-registry.shared.core.definitions.js.map +1 -1
- package/dist/esm/resources/resources-relationships.shared.factory.d.ts.map +1 -1
- package/dist/esm/resources/resources-relationships.shared.factory.js +15 -0
- package/dist/esm/resources/resources-relationships.shared.factory.js.map +1 -1
- package/dist/esm/resources/resources.shared.core.definitions.d.ts +37 -0
- package/dist/esm/resources/resources.shared.core.definitions.d.ts.map +1 -1
- package/dist/esm/resources/resources.shared.core.definitions.js +51 -0
- package/dist/esm/resources/resources.shared.core.definitions.js.map +1 -1
- package/dist/esm/resources/resources.shared.schemas.d.ts +11 -2
- package/dist/esm/resources/resources.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources.shared.schemas.js +34 -3
- package/dist/esm/resources/resources.shared.schemas.js.map +1 -1
- package/dist/esm/resources/utils/field-value-disclosure.utils.d.ts +51 -0
- package/dist/esm/resources/utils/field-value-disclosure.utils.d.ts.map +1 -0
- package/dist/esm/resources/utils/field-value-disclosure.utils.js +53 -0
- package/dist/esm/resources/utils/field-value-disclosure.utils.js.map +1 -0
- package/dist/esm/resources/utils/resources-summary.utils.d.ts +16 -2
- package/dist/esm/resources/utils/resources-summary.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-summary.utils.js +19 -5
- package/dist/esm/resources/utils/resources-summary.utils.js.map +1 -1
- package/dist/esm/resources/utils/shared-persistence-collection.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/shared-persistence-collection.utils.js +11 -0
- package/dist/esm/resources/utils/shared-persistence-collection.utils.js.map +1 -1
- package/dist/esm/runtime/domain-module.shared.definitions.d.ts +25 -0
- package/dist/esm/runtime/domain-module.shared.definitions.d.ts.map +1 -1
- package/dist/esm/runtime/domain-module.shared.definitions.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.d.ts +1 -0
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.js +38 -0
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.d.ts +1 -0
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.js +38 -0
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.d.ts +4 -11
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.js +0 -1
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.schemas.d.ts +84 -5
- package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.schemas.js +83 -3
- package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/registration.shared.dto.schemas.d.ts +1 -0
- package/dist/esm/security/authentications/registration.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/registration.shared.dto.schemas.js +11 -0
- package/dist/esm/security/authentications/registration.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.d.ts +15 -0
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.js +21 -4
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts +61 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.js +208 -6
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.d.ts +37 -27
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.js +134 -12
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.d.ts +0 -6
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.js +17 -8
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js +27 -0
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts +52 -7
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js +45 -8
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.d.ts +31 -0
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.js +198 -0
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.js.map +1 -0
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.d.ts +31 -0
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.js +191 -0
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.js.map +1 -0
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.d.ts +250 -0
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.js +486 -0
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.js.map +1 -0
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.d.ts +4 -1
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.js +29 -0
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.d.ts +4 -1
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.js +29 -0
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts +6 -0
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js +31 -0
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts +13 -0
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js +24 -3
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts +4 -4
- package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts +4 -4
- package/dist/esm/users/user-self.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-self.shared.resources-config.schemas.js +33 -3
- package/dist/esm/users/user-self.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/users.shared.resources-config.schemas.d.ts +17 -1
- package/dist/esm/users/users.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/users.shared.resources-config.schemas.js +136 -5
- package/dist/esm/users/users.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/users.shared.schemas.d.ts +43 -12
- package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/users.shared.schemas.js +38 -7
- package/dist/esm/users/users.shared.schemas.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +4 -4
|
@@ -54,6 +54,17 @@ export const UserRegisterApiDtoSchema = z.object({
|
|
|
54
54
|
password: z.string().min(1).optional(),
|
|
55
55
|
/** W6.2: Org name when orgNameSource is 'ask'. */
|
|
56
56
|
organizationName: z.string().min(1).max(200).optional(),
|
|
57
|
+
/**
|
|
58
|
+
* How the registrant will authenticate afterwards (#463). Absent ⇒ PASSWORD, so a client that
|
|
59
|
+
* predates password-less signup keeps working unchanged.
|
|
60
|
+
*
|
|
61
|
+
* Typed as the whole `AuthMethod` vocabulary rather than a narrowed subset, deliberately: the set
|
|
62
|
+
* a given application accepts is `registration.allowedMethods`, which is per user type and
|
|
63
|
+
* authored, and duplicating a narrower list here would be a second place for it to drift. A method
|
|
64
|
+
* this application does not allow is refused by the service with the allowed set in the message,
|
|
65
|
+
* which is a better answer than a schema rejection that cannot say what IS allowed.
|
|
66
|
+
*/
|
|
67
|
+
method: z.enum(AuthMethod).optional(),
|
|
57
68
|
});
|
|
58
69
|
// ═══════════════════════════════════════════════════════════════
|
|
59
70
|
// Invitation Acceptance DTOs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration.shared.dto.schemas.js","sourceRoot":"","sources":["../../../../../src/security/authentications/registration.shared.dto.schemas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,kEAAkE;AAClE,8BAA8B;AAC9B,kEAAkE;AAElE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC;QACtC,IAAI,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,KAAK,EAAE;KAC1D,CAAC;IACF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC;QAC5C,IAAI,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,UAAU,EAAE;KAC/D,CAAC;IACF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC;QAC3C,IAAI,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,WAAW,EAAE;KAChE,CAAC;IACF,mFAAmF;IACnF,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QACpD,IAAI,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,YAAY,EAAE;KACjE,CAAC,CAAC,QAAQ,EAAE;IACb,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC;QAChD,IAAI,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,YAAY,EAAE;KACjE,CAAC,CAAC,QAAQ,EAAE;IACb,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC;QACvD,IAAI,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,YAAY,EAAE;KACjE,CAAC,CAAC,QAAQ,EAAE;CACd,CAAC,CAAC;AAKH;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE;IAC9B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACtC,kDAAkD;IAClD,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;CACxD,CAAC,CAAC;AAKH,kEAAkE;AAClE,6BAA6B;AAC7B,kEAAkE;AAElE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,8FAA8F;IAC9F,mFAAmF;IACnF,+FAA+F;IAC/F,+FAA+F;IAC/F,wFAAwF;IACxF,0FAA0F;IAC1F,6FAA6F;IAC7F,6FAA6F;IAC7F,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;QACxD,IAAI,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,UAAU,EAAE;KAC/D,CAAC;IACF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;QACvD,IAAI,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,WAAW,EAAE;KAChE,CAAC;IACF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC;QACzC,IAAI,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,YAAY,EAAE;KACjE,CAAC,CAAC,QAAQ,EAAE;IACb,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC;QAChD,IAAI,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,YAAY,EAAE;KACjE,CAAC,CAAC,QAAQ,EAAE;CACd,CAAC,CAAC;AAIH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG;IAClD,UAAU,CAAC,QAAQ;IACnB,UAAU,CAAC,UAAU;IACrB,UAAU,CAAC,OAAO;CACV,CAAC;AAWX;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,8EAA8E;IAC9E,gFAAgF;IAChF,yDAAyD;IACzD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAC1C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC,QAAQ,EAAE;CAC1E,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,CAAC,MAAM,CAAC;IACvD,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;CAChD,CAAC,CAAC;AAIH,kEAAkE;AAClE,6BAA6B;AAC7B,kEAAkE;AAElE;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE;CAC/B,CAAC,CAAC","sourcesContent":["/**\n * User Registration — Shared DTO Schemas\n *\n * Single source of truth for user registration validation.\n * Used by both frontend (AutomatedForm component) and backend (req.body parsing).\n */\n\nimport { z } from 'zod';\nimport { AutocompleteFieldIdentifier } from '@wildo-ai/zod-decorators';\nimport { AuthMethod } from './authentication.shared.schemas';\n\n// ═══════════════════════════════════════════════════════════════\n// Registration Form + API DTO\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * POST /auth/register — registration form fields.\n * Used as:\n * - Frontend: AutomatedForm schema (all 5 fields rendered)\n * - Backend: req.body parsing (minus confirmPassword)\n *\n * confirmPassword is a frontend-only field for client-side match validation.\n * The .refine() for password match is applied at the component level\n * (not here) because the error message needs i18n.\n * The .isPassword() decorator tells FormField to render password inputs.\n */\nexport const UserRegisterFormDtoSchema = z.object({\n email: z.email().toLowerCase().stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.EMAIL },\n }),\n firstName: z.string().min(1).max(50).stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.GIVEN_NAME },\n }),\n lastName: z.string().min(1).max(50).stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.FAMILY_NAME },\n }),\n /** W6.2: Org name when orgNameSource is 'ask'. Conditionally shown on frontend. */\n organizationName: z.string().min(1).max(200).stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.ORGANIZATION },\n }).optional(),\n password: z.string().min(1).isPassword().stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.NEW_PASSWORD },\n }).optional(),\n confirmPassword: z.string().min(1).isPassword().stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.NEW_PASSWORD },\n }).optional(),\n});\n\n\nexport type UserRegisterFormDto = z.infer<typeof UserRegisterFormDtoSchema>;\n\n/**\n * POST /auth/register — API contract (what goes over the wire).\n * Backend uses this for req.body parsing.\n * confirmPassword is NOT sent to the backend.\n */\nexport const UserRegisterApiDtoSchema = z.object({\n email: z.email().toLowerCase(),\n firstName: z.string().min(1).max(50),\n lastName: z.string().min(1).max(50),\n password: z.string().min(1).optional(),\n /** W6.2: Org name when orgNameSource is 'ask'. */\n organizationName: z.string().min(1).max(200).optional(),\n});\n\n\nexport type UserRegisterApiDto = z.infer<typeof UserRegisterApiDtoSchema>;\n\n// ═══════════════════════════════════════════════════════════════\n// Invitation Acceptance DTOs\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * POST /auth/invitation/accept — public invitation-acceptance form fields.\n *\n * The invitation token identifies the target invitation. Name/password fields are optional\n * because an existing invited user may only need to confirm the invitation, while a new\n * invited user can provide profile/password data in the same flow.\n *\n * confirmPassword is frontend-only and excluded from the API DTO.\n */\nexport const UserInvitationFormDtoSchema = z.object({\n // Required, mirroring registration: the invitee establishes their identity at acceptance, and\n // the profile seed keys on non-empty first+last (UserProfileSchema requires both).\n // `.regex(/\\S/)` rejects a WHITESPACE-ONLY name client-side — which `.min(1)` alone would PASS\n // (\" \" has length 2), then the frontend `normalizeText`/`.trim()` collapses it to `undefined`\n // and the required API DTO 400s AFTER the form said the field was valid. It is a CHECK,\n // deliberately NOT a `.trim()` TRANSFORM: a transform ahead of `.stringUI()` disrupts the\n // decorator's introspection surface (`getFieldUIEditConfig`). Trailing/leading whitespace is\n // normalized at the authoritative boundary (`UserInvitationApiDtoSchema`, `.trim().min(1)`).\n firstName: z.string().min(1).max(50).regex(/\\S/).stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.GIVEN_NAME },\n }),\n lastName: z.string().min(1).max(50).regex(/\\S/).stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.FAMILY_NAME },\n }),\n password: z.string().isPassword().stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.NEW_PASSWORD },\n }).optional(),\n confirmPassword: z.string().isPassword().stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.NEW_PASSWORD },\n }).optional(),\n});\n\nexport type UserInvitationFormDto = z.infer<typeof UserInvitationFormDtoSchema>;\n\n/**\n * The first-factor credential the invitee chooses to establish at acceptance.\n *\n * The invitation-accept endpoint supports exactly three establishment paths (SSO-managed\n * invitees are routed to the IdP's enterprise-authorize flow, NOT this endpoint):\n * - `PASSWORD` — set a password now. When both `credentialMethod` and\n * `password` are omitted, intentionally activate with no local credential;\n * another configured authentication method can establish later sessions.\n * - `MAGIC_LINK` — activate with no local credential; a magic link is emailed and the\n * session is established when the invitee clicks it.\n * - `PASSKEY` — enroll a NEW WebAuthn credential at accept; the invitation token bootstraps\n * the session and the passkey is registered as the go-forward credential.\n */\nexport const INVITATION_ACCEPT_CREDENTIAL_METHODS = [\n AuthMethod.PASSWORD,\n AuthMethod.MAGIC_LINK,\n AuthMethod.PASSKEY,\n] as const;\n\n/**\n * The subset of {@link AuthMethod} an invitee may establish at accept time. Enterprise-SSO / social-\n * OAuth invitees are routed to the IdP authorize flow, NOT the accept endpoint, so those members are\n * intentionally absent. Single source of truth for BOTH the request DTO (`credentialMethod` enum) and\n * the backend `AcceptInvitationParams.credentialMethod` — so the service signature can never drift\n * wider than the wire contract it is fed from.\n */\nexport type InvitationAcceptCredentialMethod = (typeof INVITATION_ACCEPT_CREDENTIAL_METHODS)[number];\n\n/**\n * POST /auth/invitation/accept — API contract.\n *\n * `credentialMethod` is optional by design. When absent, a provided `password`\n * establishes a password credential; without one, acceptance activates the\n * membership without a local credential. `MAGIC_LINK` and `PASSKEY` are\n * explicit because they initiate method-specific work.\n */\nexport const UserInvitationApiDtoSchema = z.object({\n invitationToken: z.string().min(1),\n // Required (min 1), mirroring registration — see UserInvitationFormDtoSchema.\n // `.trim()` before `.min(1)` fail-closes a whitespace-only name at the boundary\n // (a direct API caller can't seed a blank profile name).\n firstName: z.string().trim().min(1).max(50),\n lastName: z.string().trim().min(1).max(50),\n password: z.string().optional(),\n credentialMethod: z.enum(INVITATION_ACCEPT_CREDENTIAL_METHODS).optional(),\n});\n\nexport type UserInvitationApiDto = z.infer<typeof UserInvitationApiDtoSchema>;\n\n/**\n * POST /auth/invitation/reject — API contract.\n */\nexport const UserInvitationRejectApiDtoSchema = z.object({\n invitationToken: z.string().min(1),\n rejectionReason: z.string().max(500).optional(),\n});\n\nexport type UserInvitationRejectApiDto = z.infer<typeof UserInvitationRejectApiDtoSchema>;\n\n// ═══════════════════════════════════════════════════════════════\n// Email Verification API DTO\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * POST /auth/verify-email — API contract.\n * Token and email are extracted from URL query parameters on the frontend.\n * Email is required for defense-in-depth constant-time comparison against token metadata.\n */\nexport const EmailVerifyDtoSchema = z.object({\n token: z.string().min(1),\n email: z.email().toLowerCase(),\n});\n\nexport type EmailVerifyDto = z.infer<typeof EmailVerifyDtoSchema>;\n"]}
|
|
1
|
+
{"version":3,"file":"registration.shared.dto.schemas.js","sourceRoot":"","sources":["../../../../../src/security/authentications/registration.shared.dto.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Registration — Shared DTO Schemas\n *\n * Single source of truth for user registration validation.\n * Used by both frontend (AutomatedForm component) and backend (req.body parsing).\n */\n\nimport { z } from 'zod';\nimport { AutocompleteFieldIdentifier } from '@wildo-ai/zod-decorators';\nimport { AuthMethod } from './authentication.shared.schemas';\n\n// ═══════════════════════════════════════════════════════════════\n// Registration Form + API DTO\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * POST /auth/register — registration form fields.\n * Used as:\n * - Frontend: AutomatedForm schema (all 5 fields rendered)\n * - Backend: req.body parsing (minus confirmPassword)\n *\n * confirmPassword is a frontend-only field for client-side match validation.\n * The .refine() for password match is applied at the component level\n * (not here) because the error message needs i18n.\n * The .isPassword() decorator tells FormField to render password inputs.\n */\nexport const UserRegisterFormDtoSchema = z.object({\n email: z.email().toLowerCase().stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.EMAIL },\n }),\n firstName: z.string().min(1).max(50).stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.GIVEN_NAME },\n }),\n lastName: z.string().min(1).max(50).stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.FAMILY_NAME },\n }),\n /** W6.2: Org name when orgNameSource is 'ask'. Conditionally shown on frontend. */\n organizationName: z.string().min(1).max(200).stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.ORGANIZATION },\n }).optional(),\n password: z.string().min(1).isPassword().stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.NEW_PASSWORD },\n }).optional(),\n confirmPassword: z.string().min(1).isPassword().stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.NEW_PASSWORD },\n }).optional(),\n});\n\n\nexport type UserRegisterFormDto = z.infer<typeof UserRegisterFormDtoSchema>;\n\n/**\n * POST /auth/register — API contract (what goes over the wire).\n * Backend uses this for req.body parsing.\n * confirmPassword is NOT sent to the backend.\n */\nexport const UserRegisterApiDtoSchema = z.object({\n email: z.email().toLowerCase(),\n firstName: z.string().min(1).max(50),\n lastName: z.string().min(1).max(50),\n password: z.string().min(1).optional(),\n /** W6.2: Org name when orgNameSource is 'ask'. */\n organizationName: z.string().min(1).max(200).optional(),\n /**\n * How the registrant will authenticate afterwards (#463). Absent ⇒ PASSWORD, so a client that\n * predates password-less signup keeps working unchanged.\n *\n * Typed as the whole `AuthMethod` vocabulary rather than a narrowed subset, deliberately: the set\n * a given application accepts is `registration.allowedMethods`, which is per user type and\n * authored, and duplicating a narrower list here would be a second place for it to drift. A method\n * this application does not allow is refused by the service with the allowed set in the message,\n * which is a better answer than a schema rejection that cannot say what IS allowed.\n */\n method: z.enum(AuthMethod).optional(),\n});\n\n\nexport type UserRegisterApiDto = z.infer<typeof UserRegisterApiDtoSchema>;\n\n// ═══════════════════════════════════════════════════════════════\n// Invitation Acceptance DTOs\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * POST /auth/invitation/accept — public invitation-acceptance form fields.\n *\n * The invitation token identifies the target invitation. Name/password fields are optional\n * because an existing invited user may only need to confirm the invitation, while a new\n * invited user can provide profile/password data in the same flow.\n *\n * confirmPassword is frontend-only and excluded from the API DTO.\n */\nexport const UserInvitationFormDtoSchema = z.object({\n // Required, mirroring registration: the invitee establishes their identity at acceptance, and\n // the profile seed keys on non-empty first+last (UserProfileSchema requires both).\n // `.regex(/\\S/)` rejects a WHITESPACE-ONLY name client-side — which `.min(1)` alone would PASS\n // (\" \" has length 2), then the frontend `normalizeText`/`.trim()` collapses it to `undefined`\n // and the required API DTO 400s AFTER the form said the field was valid. It is a CHECK,\n // deliberately NOT a `.trim()` TRANSFORM: a transform ahead of `.stringUI()` disrupts the\n // decorator's introspection surface (`getFieldUIEditConfig`). Trailing/leading whitespace is\n // normalized at the authoritative boundary (`UserInvitationApiDtoSchema`, `.trim().min(1)`).\n firstName: z.string().min(1).max(50).regex(/\\S/).stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.GIVEN_NAME },\n }),\n lastName: z.string().min(1).max(50).regex(/\\S/).stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.FAMILY_NAME },\n }),\n password: z.string().isPassword().stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.NEW_PASSWORD },\n }).optional(),\n confirmPassword: z.string().isPassword().stringUI({\n edit: { autoComplete: AutocompleteFieldIdentifier.NEW_PASSWORD },\n }).optional(),\n});\n\nexport type UserInvitationFormDto = z.infer<typeof UserInvitationFormDtoSchema>;\n\n/**\n * The first-factor credential the invitee chooses to establish at acceptance.\n *\n * The invitation-accept endpoint supports exactly three establishment paths (SSO-managed\n * invitees are routed to the IdP's enterprise-authorize flow, NOT this endpoint):\n * - `PASSWORD` — set a password now. When both `credentialMethod` and\n * `password` are omitted, intentionally activate with no local credential;\n * another configured authentication method can establish later sessions.\n * - `MAGIC_LINK` — activate with no local credential; a magic link is emailed and the\n * session is established when the invitee clicks it.\n * - `PASSKEY` — enroll a NEW WebAuthn credential at accept; the invitation token bootstraps\n * the session and the passkey is registered as the go-forward credential.\n */\nexport const INVITATION_ACCEPT_CREDENTIAL_METHODS = [\n AuthMethod.PASSWORD,\n AuthMethod.MAGIC_LINK,\n AuthMethod.PASSKEY,\n] as const;\n\n/**\n * The subset of {@link AuthMethod} an invitee may establish at accept time. Enterprise-SSO / social-\n * OAuth invitees are routed to the IdP authorize flow, NOT the accept endpoint, so those members are\n * intentionally absent. Single source of truth for BOTH the request DTO (`credentialMethod` enum) and\n * the backend `AcceptInvitationParams.credentialMethod` — so the service signature can never drift\n * wider than the wire contract it is fed from.\n */\nexport type InvitationAcceptCredentialMethod = (typeof INVITATION_ACCEPT_CREDENTIAL_METHODS)[number];\n\n/**\n * POST /auth/invitation/accept — API contract.\n *\n * `credentialMethod` is optional by design. When absent, a provided `password`\n * establishes a password credential; without one, acceptance activates the\n * membership without a local credential. `MAGIC_LINK` and `PASSKEY` are\n * explicit because they initiate method-specific work.\n */\nexport const UserInvitationApiDtoSchema = z.object({\n invitationToken: z.string().min(1),\n // Required (min 1), mirroring registration — see UserInvitationFormDtoSchema.\n // `.trim()` before `.min(1)` fail-closes a whitespace-only name at the boundary\n // (a direct API caller can't seed a blank profile name).\n firstName: z.string().trim().min(1).max(50),\n lastName: z.string().trim().min(1).max(50),\n password: z.string().optional(),\n credentialMethod: z.enum(INVITATION_ACCEPT_CREDENTIAL_METHODS).optional(),\n});\n\nexport type UserInvitationApiDto = z.infer<typeof UserInvitationApiDtoSchema>;\n\n/**\n * POST /auth/invitation/reject — API contract.\n */\nexport const UserInvitationRejectApiDtoSchema = z.object({\n invitationToken: z.string().min(1),\n rejectionReason: z.string().max(500).optional(),\n});\n\nexport type UserInvitationRejectApiDto = z.infer<typeof UserInvitationRejectApiDtoSchema>;\n\n// ═══════════════════════════════════════════════════════════════\n// Email Verification API DTO\n// ═══════════════════════════════════════════════════════════════\n\n/**\n * POST /auth/verify-email — API contract.\n * Token and email are extracted from URL query parameters on the frontend.\n * Email is required for defense-in-depth constant-time comparison against token metadata.\n */\nexport const EmailVerifyDtoSchema = z.object({\n token: z.string().min(1),\n email: z.email().toLowerCase(),\n});\n\nexport type EmailVerifyDto = z.infer<typeof EmailVerifyDtoSchema>;\n"]}
|
|
@@ -30,6 +30,21 @@ export declare const ScimAttributeMappingSchema: z.ZodObject<{
|
|
|
30
30
|
displayName: z.ZodDefault<z.ZodString>;
|
|
31
31
|
}, z.core.$strip>;
|
|
32
32
|
export type ScimAttributeMapping = z.infer<typeof ScimAttributeMappingSchema>;
|
|
33
|
+
/**
|
|
34
|
+
* The API-relative base an external identity provider pushes SCIM traffic to.
|
|
35
|
+
*
|
|
36
|
+
* ONE named source for a path that four different surfaces need to agree on: the virtual
|
|
37
|
+
* `scimEndpointUrl` below, the SCIM controller's own mount, the specification that documents the
|
|
38
|
+
* field, and the customer documentation that tells an administrator what to paste into their IdP.
|
|
39
|
+
* Before this existed the documentation's worked example was `https://api.example.com/api/v1/scim/v2`
|
|
40
|
+
* — a real path under a host that does not exist, which an administrator cannot tell from a value
|
|
41
|
+
* they are meant to use.
|
|
42
|
+
*
|
|
43
|
+
* Built from {@link MAIN_API_BASE_PATH}, so a mount change moves every consumer with it rather than
|
|
44
|
+
* stranding a literal. That is not hypothetical here: this field replaced a dead custom
|
|
45
|
+
* implementation that hardcoded `/api/scim/v2` and was simply wrong for missing the version prefix.
|
|
46
|
+
*/
|
|
47
|
+
export declare const SCIM_SERVICE_BASE_PATH: string;
|
|
33
48
|
export declare const ScimProvisioningConfigBaseSchema: z.ZodObject<{
|
|
34
49
|
_id: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<z.ZodString>>;
|
|
35
50
|
autoCreateUsers: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<z.ZodDefault<z.ZodBoolean>>>;
|
package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scim-provisioning-config.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../../src/security/authentications/scim/scim-provisioning-config.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,0BAA0B;;;;;iBAKrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAa9E,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;iBAsJ3C,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,eAAO,MAAM,4CAA4C;;;;;;;;;;;;;;;;;;;;;kBAMvD,CAAC"}
|
|
1
|
+
{"version":3,"file":"scim-provisioning-config.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../../src/security/authentications/scim/scim-provisioning-config.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,0BAA0B;;;;;iBAKrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAa9E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAwC,CAAC;AAE9E,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;iBAsJ3C,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,eAAO,MAAM,4CAA4C;;;;;;;;;;;;;;;;;;;;;kBAMvD,CAAC"}
|
|
@@ -13,7 +13,7 @@ import { AUTH_SCOPE_VARIANTS } from '../authentication.shared.schemas.js';
|
|
|
13
13
|
import { declarePolymorphicSchemas } from '../../../resources/utils/resource-polymorphism.schemas.js';
|
|
14
14
|
import { CoreResourceType } from '../../../resources/resources.shared.core.definitions.js';
|
|
15
15
|
import { MAIN_API_BASE_PATH } from '../../../requests/manual-controllers-routes-urls.js';
|
|
16
|
-
import {
|
|
16
|
+
import { resolveVerifiedDomains } from '../sso/sso-config.shared.schemas.js';
|
|
17
17
|
import { ScimOrganizationUnitMappingEntrySchema } from './scim-organization-unit-mapping.shared.js';
|
|
18
18
|
/**
|
|
19
19
|
* Maps a Wildo profile field to a PATH into the inbound SCIM User JSON. Each value is a
|
|
@@ -44,6 +44,21 @@ const SCIM_SCOPE_FK_TO_SSO_CONFIG = [
|
|
|
44
44
|
['organizationId', CoreResourceType.ORGANIZATION_SSO_CONFIG],
|
|
45
45
|
['applicationId', CoreResourceType.APPLICATION_SSO_CONFIG],
|
|
46
46
|
];
|
|
47
|
+
/**
|
|
48
|
+
* The API-relative base an external identity provider pushes SCIM traffic to.
|
|
49
|
+
*
|
|
50
|
+
* ONE named source for a path that four different surfaces need to agree on: the virtual
|
|
51
|
+
* `scimEndpointUrl` below, the SCIM controller's own mount, the specification that documents the
|
|
52
|
+
* field, and the customer documentation that tells an administrator what to paste into their IdP.
|
|
53
|
+
* Before this existed the documentation's worked example was `https://api.example.com/api/v1/scim/v2`
|
|
54
|
+
* — a real path under a host that does not exist, which an administrator cannot tell from a value
|
|
55
|
+
* they are meant to use.
|
|
56
|
+
*
|
|
57
|
+
* Built from {@link MAIN_API_BASE_PATH}, so a mount change moves every consumer with it rather than
|
|
58
|
+
* stranding a literal. That is not hypothetical here: this field replaced a dead custom
|
|
59
|
+
* implementation that hardcoded `/api/scim/v2` and was simply wrong for missing the version prefix.
|
|
60
|
+
*/
|
|
61
|
+
export const SCIM_SERVICE_BASE_PATH = `${MAIN_API_BASE_PATH}/scim/v2`;
|
|
47
62
|
export const ScimProvisioningConfigBaseSchema = z.object({
|
|
48
63
|
_id: z.string().min(1).isPrimaryKey().isSummaryField(),
|
|
49
64
|
// NOTE: there is deliberately NO `scimEnabled` field. Whether SCIM is AVAILABLE for an org is a
|
|
@@ -127,7 +142,7 @@ export const ScimProvisioningConfigBaseSchema = z.object({
|
|
|
127
142
|
* separates tenants by bearer token, not by path.
|
|
128
143
|
*/
|
|
129
144
|
scimEndpointUrl: z.string().optional().isVirtual({
|
|
130
|
-
calculate: () =>
|
|
145
|
+
calculate: () => SCIM_SERVICE_BASE_PATH,
|
|
131
146
|
}),
|
|
132
147
|
/**
|
|
133
148
|
* The email domains SCIM provisioning will accept, mirroring the gate actually enforced at
|
|
@@ -169,8 +184,10 @@ export const ScimProvisioningConfigBaseSchema = z.object({
|
|
|
169
184
|
const domains = rowsByScopeId.get(scopeId)?.['domains'];
|
|
170
185
|
if (!domains)
|
|
171
186
|
return undefined;
|
|
172
|
-
|
|
173
|
-
|
|
187
|
+
// The one derivation (#457), not a sixth hand-written join. `undefined` above is still
|
|
188
|
+
// DISTINCT from the `[]` this can return — see the field's docstring; the helper answers
|
|
189
|
+
// "which are verified", and only the caller knows whether the config was readable at all.
|
|
190
|
+
return resolveVerifiedDomains(domains);
|
|
174
191
|
}
|
|
175
192
|
catch (error) {
|
|
176
193
|
utils?.logger?.warn?.(`[scimProvisioningConfig.allowedDomains] SSO config read failed for ${scope.fk}=${scopeId}; reporting undetermined`, error);
|
package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scim-provisioning-config.shared.schemas.js","sourceRoot":"","sources":["../../../../../../src/security/authentications/scim/scim-provisioning-config.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SCIM Provisioning Config Schema (Shared) — Polymorphic\n *\n * SCIM provisioning settings: auto-create, auto-deactivate, attribute mapping.\n * Independent from SSO JIT provisioning (SsoConfig.provisioning) — SCIM is a\n * separate provisioning channel triggered by IdP push.\n * Scope FK (organizationId / applicationId) is injected by the polymorphism engine.\n *\n * @see auth-data-model-audit.md §2G\n */\n\nimport { z } from 'zod';\nimport { AUTH_SCOPE_VARIANTS } from '../authentication.shared.schemas';\nimport { declarePolymorphicSchemas } from '../../../resources/utils/resource-polymorphism.schemas';\nimport { CoreResourceType } from '../../../resources/resources.shared.core.definitions';\nimport { MAIN_API_BASE_PATH } from '../../../requests/manual-controllers-routes-urls';\nimport { DomainVerificationStatus } from '../sso/sso-config.shared.schemas';\nimport { ScimOrganizationUnitMappingEntrySchema } from './scim-organization-unit-mapping.shared';\n\n/**\n * Maps a Wildo profile field to a PATH into the inbound SCIM User JSON. Each value is a\n * path expression resolved against the SCIM body at push time by the backend\n * `resolveScimAttributePath` — the row's authoritative source for how a directory's payload\n * shape translates to Wildo's `{email, firstName, lastName, displayName}` (Okta, Azure AD, etc.\n * differ). The defaults reproduce the framework's built-in mapping exactly, so an org that never\n * customises this behaves identically to the hardcoded normalisation it replaces.\n *\n * Supported path grammar (what `resolveScimAttributePath` understands):\n * - dotted traversal — `name.givenName`\n * - array index — `emails[0].value`\n * - array filter — `emails[primary eq true].value` (first element whose `primary` equals `true`;\n * also `emails[type eq \"work\"].value`) — the SCIM-style selector the spec examples use.\n */\nexport const ScimAttributeMappingSchema = z.object({\n email: z.string().default('emails[0].value'),\n firstName: z.string().default('name.givenName'),\n lastName: z.string().default('name.familyName'),\n displayName: z.string().default('displayName'),\n});\nexport type ScimAttributeMapping = z.infer<typeof ScimAttributeMappingSchema>;\n\n/**\n * The scope FKs the polymorphism engine injects onto the two variants. Declared here\n * (rather than read off a variant schema) because this BASE schema's virtual fields run\n * for both variants and must discover which scope the row belongs to at read time.\n */\nconst SCIM_SCOPE_FK_TO_SSO_CONFIG: ReadonlyArray<readonly [fk: string, ssoResourceType: CoreResourceType]> = [\n ['organizationId', CoreResourceType.ORGANIZATION_SSO_CONFIG],\n ['applicationId', CoreResourceType.APPLICATION_SSO_CONFIG],\n] as const;\n\n\nexport const ScimProvisioningConfigBaseSchema = z.object({\n _id: z.string().min(1).isPrimaryKey().isSummaryField(),\n\n // NOTE: there is deliberately NO `scimEnabled` field. Whether SCIM is AVAILABLE for an org is a\n // per-ORG-TYPE decision at `organizationTypes[type].scimProvisioning.enabled` in the app config —\n // the authority the app-global MOUNT gate and the SCIM controller auth gate\n // (`isScimProvisioningEnabledForOrg`) consult. NB: the invitation `managementMode` resolver and\n // the invite-accept credential block key instead on per-org ACTIVE management (the\n // DIRECTORY_PROVISIONING feature + a live SCIM token — see `isOrgActivelyDirectoryManaged` /\n // AUTH-23), so a SCIM-capable type does not by itself forbid local credentials. A per-scope\n // `scimEnabled` on this row would duplicate the type-level authority, could silently drift from\n // it, and was read by nothing. This row governs only WHAT HAPPENS to users once SCIM is on.\n // `.isAuditEvidence()` on the four below — every one decides what the DIRECTORY is allowed to do\n // to member accounts and with what standing. `defaultRole` in particular is a role GRANT: SCIM\n // provisions through an internal execution context, so it is NOT bounded by any caller's role\n // ceiling (see `defaultUnitRole`'s note below) — configuring it IS granting the role, which is\n // exactly the class of change an auditor must be able to reconstruct with before/after values.\n // `autoDeactivateUsers` is the deprovisioning switch; flipping it off silently strands access.\n // None of these is personal data — they are flags and role names — so recording their values\n // does not conflict with the minimisation rule that keeps user-identifying fields unmarked.\n // assurance-control: WILDO.IDENTITY.DIRECTORY_PROVISIONING — the switches that create accounts and\n // deprovision access.\n autoCreateUsers: z.boolean().default(true).isSummaryField().isAuditEvidence(),\n autoVerifyEmail: z.boolean().default(true),\n autoDeactivateUsers: z.boolean().default(true).isAuditEvidence(),\n defaultRole: z.string().optional().isAuditEvidence(),\n attributeMapping: ScimAttributeMappingSchema.optional(),\n\n /**\n * Declared bindings from the directory's `department` value to an ORGANIZATION UNIT.\n *\n * assurance-control: WILDO.IDENTITY.DIRECTORY_PROVISIONING — the directory becomes the authority\n * for which unit a member belongs to.\n *\n * Explicit and unit-id-addressed on purpose. Since units are an authorization axis, resolving a\n * flat directory string to the wrong node in the tree grants the wrong DATA — and `code` is unique\n * only among siblings while `name` is freeform, so a search-based match is genuinely ambiguous.\n * Nothing here guesses: a value with no declared binding is ignored, and no unit is ever created.\n *\n * ⚠️ **Declaring this makes SCIM AUTHORITATIVE over the member's unit assignments.** Every push\n * replaces the member's assignments with exactly what the directory says, so leaving a department\n * actually revokes its access — and assignments made BY HAND in the application are removed too.\n * An organization that wants manual unit assignments should leave this empty. Reconciliation only\n * runs when this list is non-empty AND {@link ScimProvisioningConfigBaseSchema.shape.defaultUnitRole}\n * is set, so an organization that never opted in can never have assignments deleted by a push.\n */\n // `.isAuditEvidence()` — declaring a binding makes SCIM AUTHORITATIVE over unit assignments\n // (see the warning above), so the mapping list is an authorization surface, not preferences.\n organizationUnitMapping: z.array(ScimOrganizationUnitMappingEntrySchema).optional().isAuditEvidence(),\n\n /**\n * The role every SCIM-created unit assignment carries.\n *\n * Deliberately SEPARATE from {@link ScimProvisioningConfigBaseSchema.shape.defaultRole}, which is the\n * ORGANIZATION-wide role. A unit grant and an organization grant are different authority over\n * different row sets; one field meaning both would merge two scopes that the whole narrowing model\n * exists to keep apart.\n *\n * ⚠️ SCIM provisions through an internal execution context, so this value is NOT bounded by a\n * caller's role ceiling — exactly as `defaultRole` is not. The gate is the write to THIS row, which\n * is organization-admin-gated. Treat configuring it as granting the role.\n */\n // `.isAuditEvidence()` — a role grant on a DIFFERENT authority axis than `defaultRole`, and the\n // JSDoc above says it plainly: treat configuring it as granting the role.\n defaultUnitRole: z.string().optional().isAuditEvidence(),\n\n /**\n * The API-relative path an external IdP pushes SCIM traffic to, e.g. `/api/v1/scim/v2`.\n *\n * VIRTUAL (computed per read, never persisted, never accepted on write) because it is\n * derived deployment routing — not tenant data. Storing it would let a row drift from the\n * route the server actually mounts, which is precisely the class of lie this field replaces:\n * it supersedes a dead custom-implementation that injected a hardcoded `/api/scim/v2`,\n * **missing the `/api/v1` mount prefix and therefore simply wrong**. Built from\n * {@link MAIN_API_BASE_PATH} — the documented single source of truth for the prefix — so a\n * future mount change moves this field with it instead of stranding a literal.\n *\n * PATH, not an absolute URL: the host lives in `runtime.endPoints.main_backend_api.publicUrl`,\n * reachable only through `AppConfigService`, whose DI symbol lives in `saas-backend-lib` —\n * unreachable from this shared package without inverting the dependency direction. `publicUrl`\n * is also optional, so an absolute form would frequently resolve to nothing. Callers that need\n * the absolute endpoint compose it against their own API base (the frontend already knows it).\n *\n * Identical on both scope variants: the SCIM controller mounts ONE app-global router and\n * separates tenants by bearer token, not by path.\n */\n scimEndpointUrl: z.string().optional().isVirtual({\n calculate: () => `${MAIN_API_BASE_PATH}/scim/v2`,\n }),\n\n /**\n * The email domains SCIM provisioning will accept, mirroring the gate actually enforced at\n * push time — `EnterpriseUserProvisioningBackendService.provisionEnterpriseUser` rejects an IdP profile\n * whose email domain is absent from this list.\n *\n * VIRTUAL and read live from the scope's SSO config rather than stored here: the domains are\n * OWNED by `SsoConfig.domains` (verified via DNS there), so persisting a copy on this row\n * would denormalize a security-relevant allow-list and let it go stale against the owner —\n * exactly the drift `forwardedLabel` exists to avoid. Same predicate as the enforcement path\n * (`SCIMControllerBackendService._getProvisioningConfig`): a domain counts only once DNS\n * verification has actually passed, so `verifiedDomains` is filtered by\n * `domainVerificationStatus`. Deliberately NOT the looser `verifiedDomains || ssoEnabledDomains`\n * union used by domain→org lookup — widening this list would widen a security gate.\n *\n * `[]` and `undefined` are DISTINCT and both meaningful:\n * - `[]` — the SSO config exists and has no verified domain ⇒ **unrestricted** (the enforcement\n * check is skipped entirely when the list is empty). This is the honest reading of the value.\n * - `undefined` — the SSO config could not be read ⇒ **undetermined**. Degrading to `[]` here\n * would render an unread config as \"unrestricted\", overstating what we know.\n *\n * Fail-safe: never throws — this is a display mirror, not the enforcement point.\n */\n allowedDomains: z.array(z.string()).optional().isVirtual({\n dependencies: SCIM_SCOPE_FK_TO_SSO_CONFIG.map(([fk]) => fk),\n calculate: async ({ currentObject, utils }) => {\n const row = currentObject as Record<string, unknown> | undefined;\n\n const scope = SCIM_SCOPE_FK_TO_SSO_CONFIG\n .map(([fk, ssoResourceType]) => ({ fk, ssoResourceType, value: row?.[fk] }))\n .find(({ value }) => value !== null && value !== undefined && String(value).length > 0);\n if (!scope) return undefined;\n\n const scopeId = String(scope.value);\n const ssoRepository = utils?.repositories?.getRepository?.(scope.ssoResourceType);\n if (!ssoRepository || typeof ssoRepository.findFieldValuesByJoinField !== 'function') return undefined;\n\n try {\n const rowsByScopeId: Map<string, Record<string, unknown>> =\n await ssoRepository.findFieldValuesByJoinField(scope.fk, [scopeId], ['domains']);\n const domains = rowsByScopeId.get(scopeId)?.['domains'] as\n | { verifiedDomains?: string[]; domainVerificationStatus?: Record<string, string> }\n | undefined;\n if (!domains) return undefined;\n\n const verificationStatus = domains.domainVerificationStatus ?? {};\n return (domains.verifiedDomains ?? []).filter(\n (domain) => verificationStatus[domain] === DomainVerificationStatus.VERIFIED,\n );\n } catch (error) {\n utils?.logger?.warn?.(\n `[scimProvisioningConfig.allowedDomains] SSO config read failed for ${scope.fk}=${scopeId}; reporting undetermined`,\n error,\n );\n return undefined;\n }\n },\n }),\n\n createdAt: z.date().default(() => new Date()).excludeFromCreate().excludeFromUpdate(),\n updatedAt: z.date().default(() => new Date()).excludeFromCreate().excludeFromUpdate(),\n});\n\nexport type ScimProvisioningConfigBase = z.infer<typeof ScimProvisioningConfigBaseSchema>;\n\nexport const scimProvisioningConfigPolymorphicDeclaration = declarePolymorphicSchemas({\n baseResourceType: 'scimProvisioningConfig',\n baseFieldIdentifier: 'scimProvisioningConfigId',\n baseEnumKey: 'SCIM_PROVISIONING_CONFIG',\n baseSchema: ScimProvisioningConfigBaseSchema,\n variants: AUTH_SCOPE_VARIANTS,\n});\n"]}
|
|
1
|
+
{"version":3,"file":"scim-provisioning-config.shared.schemas.js","sourceRoot":"","sources":["../../../../../../src/security/authentications/scim/scim-provisioning-config.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SCIM Provisioning Config Schema (Shared) — Polymorphic\n *\n * SCIM provisioning settings: auto-create, auto-deactivate, attribute mapping.\n * Independent from SSO JIT provisioning (SsoConfig.provisioning) — SCIM is a\n * separate provisioning channel triggered by IdP push.\n * Scope FK (organizationId / applicationId) is injected by the polymorphism engine.\n *\n * @see auth-data-model-audit.md §2G\n */\n\nimport { z } from 'zod';\nimport { AUTH_SCOPE_VARIANTS } from '../authentication.shared.schemas';\nimport { declarePolymorphicSchemas } from '../../../resources/utils/resource-polymorphism.schemas';\nimport { CoreResourceType } from '../../../resources/resources.shared.core.definitions';\nimport { MAIN_API_BASE_PATH } from '../../../requests/manual-controllers-routes-urls';\nimport { resolveVerifiedDomains } from '../sso/sso-config.shared.schemas';\nimport { ScimOrganizationUnitMappingEntrySchema } from './scim-organization-unit-mapping.shared';\n\n/**\n * Maps a Wildo profile field to a PATH into the inbound SCIM User JSON. Each value is a\n * path expression resolved against the SCIM body at push time by the backend\n * `resolveScimAttributePath` — the row's authoritative source for how a directory's payload\n * shape translates to Wildo's `{email, firstName, lastName, displayName}` (Okta, Azure AD, etc.\n * differ). The defaults reproduce the framework's built-in mapping exactly, so an org that never\n * customises this behaves identically to the hardcoded normalisation it replaces.\n *\n * Supported path grammar (what `resolveScimAttributePath` understands):\n * - dotted traversal — `name.givenName`\n * - array index — `emails[0].value`\n * - array filter — `emails[primary eq true].value` (first element whose `primary` equals `true`;\n * also `emails[type eq \"work\"].value`) — the SCIM-style selector the spec examples use.\n */\nexport const ScimAttributeMappingSchema = z.object({\n email: z.string().default('emails[0].value'),\n firstName: z.string().default('name.givenName'),\n lastName: z.string().default('name.familyName'),\n displayName: z.string().default('displayName'),\n});\nexport type ScimAttributeMapping = z.infer<typeof ScimAttributeMappingSchema>;\n\n/**\n * The scope FKs the polymorphism engine injects onto the two variants. Declared here\n * (rather than read off a variant schema) because this BASE schema's virtual fields run\n * for both variants and must discover which scope the row belongs to at read time.\n */\nconst SCIM_SCOPE_FK_TO_SSO_CONFIG: ReadonlyArray<readonly [fk: string, ssoResourceType: CoreResourceType]> = [\n ['organizationId', CoreResourceType.ORGANIZATION_SSO_CONFIG],\n ['applicationId', CoreResourceType.APPLICATION_SSO_CONFIG],\n] as const;\n\n\n/**\n * The API-relative base an external identity provider pushes SCIM traffic to.\n *\n * ONE named source for a path that four different surfaces need to agree on: the virtual\n * `scimEndpointUrl` below, the SCIM controller's own mount, the specification that documents the\n * field, and the customer documentation that tells an administrator what to paste into their IdP.\n * Before this existed the documentation's worked example was `https://api.example.com/api/v1/scim/v2`\n * — a real path under a host that does not exist, which an administrator cannot tell from a value\n * they are meant to use.\n *\n * Built from {@link MAIN_API_BASE_PATH}, so a mount change moves every consumer with it rather than\n * stranding a literal. That is not hypothetical here: this field replaced a dead custom\n * implementation that hardcoded `/api/scim/v2` and was simply wrong for missing the version prefix.\n */\nexport const SCIM_SERVICE_BASE_PATH: string = `${MAIN_API_BASE_PATH}/scim/v2`;\n\nexport const ScimProvisioningConfigBaseSchema = z.object({\n _id: z.string().min(1).isPrimaryKey().isSummaryField(),\n\n // NOTE: there is deliberately NO `scimEnabled` field. Whether SCIM is AVAILABLE for an org is a\n // per-ORG-TYPE decision at `organizationTypes[type].scimProvisioning.enabled` in the app config —\n // the authority the app-global MOUNT gate and the SCIM controller auth gate\n // (`isScimProvisioningEnabledForOrg`) consult. NB: the invitation `managementMode` resolver and\n // the invite-accept credential block key instead on per-org ACTIVE management (the\n // DIRECTORY_PROVISIONING feature + a live SCIM token — see `isOrgActivelyDirectoryManaged` /\n // AUTH-23), so a SCIM-capable type does not by itself forbid local credentials. A per-scope\n // `scimEnabled` on this row would duplicate the type-level authority, could silently drift from\n // it, and was read by nothing. This row governs only WHAT HAPPENS to users once SCIM is on.\n // `.isAuditEvidence()` on the four below — every one decides what the DIRECTORY is allowed to do\n // to member accounts and with what standing. `defaultRole` in particular is a role GRANT: SCIM\n // provisions through an internal execution context, so it is NOT bounded by any caller's role\n // ceiling (see `defaultUnitRole`'s note below) — configuring it IS granting the role, which is\n // exactly the class of change an auditor must be able to reconstruct with before/after values.\n // `autoDeactivateUsers` is the deprovisioning switch; flipping it off silently strands access.\n // None of these is personal data — they are flags and role names — so recording their values\n // does not conflict with the minimisation rule that keeps user-identifying fields unmarked.\n // assurance-control: WILDO.IDENTITY.DIRECTORY_PROVISIONING — the switches that create accounts and\n // deprovision access.\n autoCreateUsers: z.boolean().default(true).isSummaryField().isAuditEvidence(),\n autoVerifyEmail: z.boolean().default(true),\n autoDeactivateUsers: z.boolean().default(true).isAuditEvidence(),\n defaultRole: z.string().optional().isAuditEvidence(),\n attributeMapping: ScimAttributeMappingSchema.optional(),\n\n /**\n * Declared bindings from the directory's `department` value to an ORGANIZATION UNIT.\n *\n * assurance-control: WILDO.IDENTITY.DIRECTORY_PROVISIONING — the directory becomes the authority\n * for which unit a member belongs to.\n *\n * Explicit and unit-id-addressed on purpose. Since units are an authorization axis, resolving a\n * flat directory string to the wrong node in the tree grants the wrong DATA — and `code` is unique\n * only among siblings while `name` is freeform, so a search-based match is genuinely ambiguous.\n * Nothing here guesses: a value with no declared binding is ignored, and no unit is ever created.\n *\n * ⚠️ **Declaring this makes SCIM AUTHORITATIVE over the member's unit assignments.** Every push\n * replaces the member's assignments with exactly what the directory says, so leaving a department\n * actually revokes its access — and assignments made BY HAND in the application are removed too.\n * An organization that wants manual unit assignments should leave this empty. Reconciliation only\n * runs when this list is non-empty AND {@link ScimProvisioningConfigBaseSchema.shape.defaultUnitRole}\n * is set, so an organization that never opted in can never have assignments deleted by a push.\n */\n // `.isAuditEvidence()` — declaring a binding makes SCIM AUTHORITATIVE over unit assignments\n // (see the warning above), so the mapping list is an authorization surface, not preferences.\n organizationUnitMapping: z.array(ScimOrganizationUnitMappingEntrySchema).optional().isAuditEvidence(),\n\n /**\n * The role every SCIM-created unit assignment carries.\n *\n * Deliberately SEPARATE from {@link ScimProvisioningConfigBaseSchema.shape.defaultRole}, which is the\n * ORGANIZATION-wide role. A unit grant and an organization grant are different authority over\n * different row sets; one field meaning both would merge two scopes that the whole narrowing model\n * exists to keep apart.\n *\n * ⚠️ SCIM provisions through an internal execution context, so this value is NOT bounded by a\n * caller's role ceiling — exactly as `defaultRole` is not. The gate is the write to THIS row, which\n * is organization-admin-gated. Treat configuring it as granting the role.\n */\n // `.isAuditEvidence()` — a role grant on a DIFFERENT authority axis than `defaultRole`, and the\n // JSDoc above says it plainly: treat configuring it as granting the role.\n defaultUnitRole: z.string().optional().isAuditEvidence(),\n\n /**\n * The API-relative path an external IdP pushes SCIM traffic to, e.g. `/api/v1/scim/v2`.\n *\n * VIRTUAL (computed per read, never persisted, never accepted on write) because it is\n * derived deployment routing — not tenant data. Storing it would let a row drift from the\n * route the server actually mounts, which is precisely the class of lie this field replaces:\n * it supersedes a dead custom-implementation that injected a hardcoded `/api/scim/v2`,\n * **missing the `/api/v1` mount prefix and therefore simply wrong**. Built from\n * {@link MAIN_API_BASE_PATH} — the documented single source of truth for the prefix — so a\n * future mount change moves this field with it instead of stranding a literal.\n *\n * PATH, not an absolute URL: the host lives in `runtime.endPoints.main_backend_api.publicUrl`,\n * reachable only through `AppConfigService`, whose DI symbol lives in `saas-backend-lib` —\n * unreachable from this shared package without inverting the dependency direction. `publicUrl`\n * is also optional, so an absolute form would frequently resolve to nothing. Callers that need\n * the absolute endpoint compose it against their own API base (the frontend already knows it).\n *\n * Identical on both scope variants: the SCIM controller mounts ONE app-global router and\n * separates tenants by bearer token, not by path.\n */\n scimEndpointUrl: z.string().optional().isVirtual({\n calculate: () => SCIM_SERVICE_BASE_PATH,\n }),\n\n /**\n * The email domains SCIM provisioning will accept, mirroring the gate actually enforced at\n * push time — `EnterpriseUserProvisioningBackendService.provisionEnterpriseUser` rejects an IdP profile\n * whose email domain is absent from this list.\n *\n * VIRTUAL and read live from the scope's SSO config rather than stored here: the domains are\n * OWNED by `SsoConfig.domains` (verified via DNS there), so persisting a copy on this row\n * would denormalize a security-relevant allow-list and let it go stale against the owner —\n * exactly the drift `forwardedLabel` exists to avoid. Same predicate as the enforcement path\n * (`SCIMControllerBackendService._getProvisioningConfig`): a domain counts only once DNS\n * verification has actually passed, so `verifiedDomains` is filtered by\n * `domainVerificationStatus`. Deliberately NOT the looser `verifiedDomains || ssoEnabledDomains`\n * union used by domain→org lookup — widening this list would widen a security gate.\n *\n * `[]` and `undefined` are DISTINCT and both meaningful:\n * - `[]` — the SSO config exists and has no verified domain ⇒ **unrestricted** (the enforcement\n * check is skipped entirely when the list is empty). This is the honest reading of the value.\n * - `undefined` — the SSO config could not be read ⇒ **undetermined**. Degrading to `[]` here\n * would render an unread config as \"unrestricted\", overstating what we know.\n *\n * Fail-safe: never throws — this is a display mirror, not the enforcement point.\n */\n allowedDomains: z.array(z.string()).optional().isVirtual({\n dependencies: SCIM_SCOPE_FK_TO_SSO_CONFIG.map(([fk]) => fk),\n calculate: async ({ currentObject, utils }) => {\n const row = currentObject as Record<string, unknown> | undefined;\n\n const scope = SCIM_SCOPE_FK_TO_SSO_CONFIG\n .map(([fk, ssoResourceType]) => ({ fk, ssoResourceType, value: row?.[fk] }))\n .find(({ value }) => value !== null && value !== undefined && String(value).length > 0);\n if (!scope) return undefined;\n\n const scopeId = String(scope.value);\n const ssoRepository = utils?.repositories?.getRepository?.(scope.ssoResourceType);\n if (!ssoRepository || typeof ssoRepository.findFieldValuesByJoinField !== 'function') return undefined;\n\n try {\n const rowsByScopeId: Map<string, Record<string, unknown>> =\n await ssoRepository.findFieldValuesByJoinField(scope.fk, [scopeId], ['domains']);\n const domains = rowsByScopeId.get(scopeId)?.['domains'] as\n | { verifiedDomains?: string[]; domainVerificationStatus?: Record<string, string> }\n | undefined;\n if (!domains) return undefined;\n\n // The one derivation (#457), not a sixth hand-written join. `undefined` above is still\n // DISTINCT from the `[]` this can return — see the field's docstring; the helper answers\n // \"which are verified\", and only the caller knows whether the config was readable at all.\n return resolveVerifiedDomains(domains);\n } catch (error) {\n utils?.logger?.warn?.(\n `[scimProvisioningConfig.allowedDomains] SSO config read failed for ${scope.fk}=${scopeId}; reporting undetermined`,\n error,\n );\n return undefined;\n }\n },\n }),\n\n createdAt: z.date().default(() => new Date()).excludeFromCreate().excludeFromUpdate(),\n updatedAt: z.date().default(() => new Date()).excludeFromCreate().excludeFromUpdate(),\n});\n\nexport type ScimProvisioningConfigBase = z.infer<typeof ScimProvisioningConfigBaseSchema>;\n\nexport const scimProvisioningConfigPolymorphicDeclaration = declarePolymorphicSchemas({\n baseResourceType: 'scimProvisioningConfig',\n baseFieldIdentifier: 'scimProvisioningConfigId',\n baseEnumKey: 'SCIM_PROVISIONING_CONFIG',\n baseSchema: ScimProvisioningConfigBaseSchema,\n variants: AUTH_SCOPE_VARIANTS,\n});\n"]}
|
package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts
CHANGED
|
@@ -5,6 +5,66 @@
|
|
|
5
5
|
* Spread into the registry factory map:
|
|
6
6
|
* ...ssoConfigPolymorphicFactories
|
|
7
7
|
*/
|
|
8
|
+
import { z } from 'zod';
|
|
8
9
|
import { CoreResourceOperation } from '../../../resources/resources.shared.core.definitions';
|
|
9
|
-
export declare
|
|
10
|
+
export declare enum SsoConfig_Operations {
|
|
11
|
+
CLAIM_DOMAIN = "claimDomain",
|
|
12
|
+
VERIFY_DOMAIN = "verifyDomain",
|
|
13
|
+
REVOKE_DOMAIN = "revokeDomain"
|
|
14
|
+
}
|
|
15
|
+
export declare const SsoConfig_ClaimDomainRequestDto: z.ZodObject<{
|
|
16
|
+
domain: z.ZodString;
|
|
17
|
+
}, z.core.$strict>;
|
|
18
|
+
export declare const SsoConfig_VerifyDomainRequestDto: z.ZodObject<{
|
|
19
|
+
domain: z.ZodString;
|
|
20
|
+
}, z.core.$strict>;
|
|
21
|
+
export declare const SsoConfig_RevokeDomainRequestDto: z.ZodObject<{
|
|
22
|
+
domain: z.ZodString;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
/**
|
|
25
|
+
* The claim response is the ONLY disclosure of the challenge nonce.
|
|
26
|
+
*
|
|
27
|
+
* `domainVerificationTokens` is `.isBackendOnly()`, so no READ of the config ever returns it — an
|
|
28
|
+
* operator who loses this response claims again, which mints a new nonce and invalidates the old
|
|
29
|
+
* one. `.isEphemeral()` marks `dnsRecordValue` as a revealed-once secret, the same contract the
|
|
30
|
+
* SCIM token mint uses for its one-time plaintext.
|
|
31
|
+
*/
|
|
32
|
+
export declare const SsoConfig_ClaimDomainResponseDto: z.ZodObject<{
|
|
33
|
+
domain: z.ZodString;
|
|
34
|
+
status: z.ZodEnum<{
|
|
35
|
+
readonly PENDING: "pending";
|
|
36
|
+
readonly VERIFIED: "verified";
|
|
37
|
+
readonly FAILED: "failed";
|
|
38
|
+
readonly EXPIRED: "expired";
|
|
39
|
+
}>;
|
|
40
|
+
/** The DNS name the TXT record goes on: `_wildo-verification.<domain>`. */
|
|
41
|
+
dnsName: z.ZodString;
|
|
42
|
+
/** The exact TXT value to publish. Revealed once. */
|
|
43
|
+
dnsRecordValue: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<z.ZodString>;
|
|
44
|
+
}, z.core.$strict>;
|
|
45
|
+
export declare const SsoConfig_VerifyDomainResponseDto: z.ZodObject<{
|
|
46
|
+
domain: z.ZodString;
|
|
47
|
+
status: z.ZodEnum<{
|
|
48
|
+
readonly PENDING: "pending";
|
|
49
|
+
readonly VERIFIED: "verified";
|
|
50
|
+
readonly FAILED: "failed";
|
|
51
|
+
readonly EXPIRED: "expired";
|
|
52
|
+
}>;
|
|
53
|
+
dnsName: z.ZodString;
|
|
54
|
+
/**
|
|
55
|
+
* Every TXT record found at `dnsName`, so a failed check is diagnosable without a second tool.
|
|
56
|
+
* These are public DNS records of a domain the caller is claiming to own — echoing them discloses
|
|
57
|
+
* nothing the caller could not resolve themselves.
|
|
58
|
+
*/
|
|
59
|
+
dnsRecordsFound: z.ZodArray<z.ZodString>;
|
|
60
|
+
}, z.core.$strict>;
|
|
61
|
+
export declare const SsoConfig_RevokeDomainResponseDto: z.ZodObject<{
|
|
62
|
+
domain: z.ZodString;
|
|
63
|
+
/** True once the domain holds no claim, no status and no nonce in this scope. */
|
|
64
|
+
revoked: z.ZodBoolean;
|
|
65
|
+
}, z.core.$strict>;
|
|
66
|
+
export type SsoConfig_ClaimDomainResponse = z.infer<typeof SsoConfig_ClaimDomainResponseDto>;
|
|
67
|
+
export type SsoConfig_VerifyDomainResponse = z.infer<typeof SsoConfig_VerifyDomainResponseDto>;
|
|
68
|
+
export type SsoConfig_RevokeDomainResponse = z.infer<typeof SsoConfig_RevokeDomainResponseDto>;
|
|
69
|
+
export declare const ssoConfigPolymorphicFactories: Record<string, import("../../..").ResourceConfiguration_InitializationFactory<typeof SsoConfig_Operations, CoreResourceOperation.READ | CoreResourceOperation.UPDATE | CoreResourceOperation.DELETE | CoreResourceOperation.CREATE | CoreResourceOperation.LIST, any>>;
|
|
10
70
|
//# sourceMappingURL=sso-config.shared.resources-config.schemas.d.ts.map
|
package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sso-config.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../../../src/security/authentications/sso/sso-config.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,qBAAqB,EAAoB,MAAM,sDAAsD,CAAC;
|
|
1
|
+
{"version":3,"file":"sso-config.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../../../src/security/authentications/sso/sso-config.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAoB,MAAM,sDAAsD,CAAC;AAsB/G,oBAAY,oBAAoB;IAC9B,YAAY,gBAAgB;IAC5B,aAAa,iBAAiB;IAC9B,aAAa,iBAAiB;CAC/B;AAiBD,eAAO,MAAM,+BAA+B;;kBAE1C,CAAC;AAEH,eAAO,MAAM,gCAAgC;;kBAE3C,CAAC;AAEH,eAAO,MAAM,gCAAgC;;kBAE3C,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,gCAAgC;;;;;;;;IAG3C,2EAA2E;;IAE3E,qDAAqD;;kBAErD,CAAC;AAEH,eAAO,MAAM,iCAAiC;;;;;;;;;IAI5C;;;;OAIG;;kBAEH,CAAC;AAEH,eAAO,MAAM,iCAAiC;;IAE5C,iFAAiF;;kBAEjF,CAAC;AAEH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAC7F,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAC/F,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAI/F,eAAO,MAAM,6BAA6B,wQAyOzC,CAAC"}
|
|
@@ -5,15 +5,88 @@
|
|
|
5
5
|
* Spread into the registry factory map:
|
|
6
6
|
* ...ssoConfigPolymorphicFactories
|
|
7
7
|
*/
|
|
8
|
+
import { z } from 'zod';
|
|
8
9
|
import { CoreResourceOperation, CoreResourceType } from '../../../resources/resources.shared.core.definitions.js';
|
|
9
10
|
import { ResourceOperationRiskLevel, ResourceOperationVariantType, } from '../../../resources/resources.shared.schemas.js';
|
|
10
11
|
import { createPolymorphicResourceConfigurations } from '../../../resources/utils/resource-polymorphism.factory.js';
|
|
11
12
|
import { ResourceSystemAccessMode } from '../../../resources/resources-config.shared.schemas.js';
|
|
12
13
|
import { CORE_ORG_ROLES, CORE_APP_ROLES } from '../../authorizations/roles.shared.schemas.js';
|
|
13
|
-
import { ssoConfigPolymorphicDeclaration } from './sso-config.shared.schemas.js';
|
|
14
|
+
import { DomainVerificationStatus, ssoConfigPolymorphicDeclaration } from './sso-config.shared.schemas.js';
|
|
15
|
+
// ── Domain-ownership operations ──────────────────────────────────────
|
|
16
|
+
//
|
|
17
|
+
// Enterprise domain routing sends every `@customer.com` sign-in to that customer's identity
|
|
18
|
+
// provider. Reaching the VERIFIED state used to require an out-of-band database write, which made
|
|
19
|
+
// enterprise onboarding a support ticket forever (#424). These three operations are the door.
|
|
20
|
+
//
|
|
21
|
+
// They are entity-level operations on a resource that is a ONE-to-ONE COMPOSITION under its scope,
|
|
22
|
+
// so the URL builder omits the id segment and the scope in the path selects the row:
|
|
23
|
+
// PUT /organizations/{organizationId}/sso-configs/claim-domain
|
|
24
|
+
// PUT /organizations/{organizationId}/sso-configs/verify-domain
|
|
25
|
+
// PUT /organizations/{organizationId}/sso-configs/revoke-domain
|
|
26
|
+
export var SsoConfig_Operations;
|
|
27
|
+
(function (SsoConfig_Operations) {
|
|
28
|
+
SsoConfig_Operations["CLAIM_DOMAIN"] = "claimDomain";
|
|
29
|
+
SsoConfig_Operations["VERIFY_DOMAIN"] = "verifyDomain";
|
|
30
|
+
SsoConfig_Operations["REVOKE_DOMAIN"] = "revokeDomain";
|
|
31
|
+
})(SsoConfig_Operations || (SsoConfig_Operations = {}));
|
|
32
|
+
/**
|
|
33
|
+
* A DNS hostname, syntactically. Two labels minimum — a single label is not a domain anyone can
|
|
34
|
+
* publish a TXT record under, and accepting one would mint a challenge that can never be answered.
|
|
35
|
+
*
|
|
36
|
+
* Case is NOT normalised here. The backend lowercases before every read and every write, because
|
|
37
|
+
* that is where the stored map keys are decided; doing it in two places would make the request
|
|
38
|
+
* contract look like the authority when it is not.
|
|
39
|
+
*/
|
|
40
|
+
const SSO_DOMAIN_PATTERN = /^(?!-)[A-Za-z0-9-]{1,63}(?<!-)(\.(?!-)[A-Za-z0-9-]{1,63}(?<!-))+$/;
|
|
41
|
+
const SsoConfig_DomainSelector = z.string()
|
|
42
|
+
.min(4)
|
|
43
|
+
.max(253)
|
|
44
|
+
.regex(SSO_DOMAIN_PATTERN, 'Provide a DNS hostname with at least two labels, e.g. "customer.com".');
|
|
45
|
+
export const SsoConfig_ClaimDomainRequestDto = z.strictObject({
|
|
46
|
+
domain: SsoConfig_DomainSelector,
|
|
47
|
+
});
|
|
48
|
+
export const SsoConfig_VerifyDomainRequestDto = z.strictObject({
|
|
49
|
+
domain: SsoConfig_DomainSelector,
|
|
50
|
+
});
|
|
51
|
+
export const SsoConfig_RevokeDomainRequestDto = z.strictObject({
|
|
52
|
+
domain: SsoConfig_DomainSelector,
|
|
53
|
+
});
|
|
54
|
+
/**
|
|
55
|
+
* The claim response is the ONLY disclosure of the challenge nonce.
|
|
56
|
+
*
|
|
57
|
+
* `domainVerificationTokens` is `.isBackendOnly()`, so no READ of the config ever returns it — an
|
|
58
|
+
* operator who loses this response claims again, which mints a new nonce and invalidates the old
|
|
59
|
+
* one. `.isEphemeral()` marks `dnsRecordValue` as a revealed-once secret, the same contract the
|
|
60
|
+
* SCIM token mint uses for its one-time plaintext.
|
|
61
|
+
*/
|
|
62
|
+
export const SsoConfig_ClaimDomainResponseDto = z.strictObject({
|
|
63
|
+
domain: z.string(),
|
|
64
|
+
status: z.enum(DomainVerificationStatus),
|
|
65
|
+
/** The DNS name the TXT record goes on: `_wildo-verification.<domain>`. */
|
|
66
|
+
dnsName: z.string(),
|
|
67
|
+
/** The exact TXT value to publish. Revealed once. */
|
|
68
|
+
dnsRecordValue: z.string().isEphemeral(),
|
|
69
|
+
});
|
|
70
|
+
export const SsoConfig_VerifyDomainResponseDto = z.strictObject({
|
|
71
|
+
domain: z.string(),
|
|
72
|
+
status: z.enum(DomainVerificationStatus),
|
|
73
|
+
dnsName: z.string(),
|
|
74
|
+
/**
|
|
75
|
+
* Every TXT record found at `dnsName`, so a failed check is diagnosable without a second tool.
|
|
76
|
+
* These are public DNS records of a domain the caller is claiming to own — echoing them discloses
|
|
77
|
+
* nothing the caller could not resolve themselves.
|
|
78
|
+
*/
|
|
79
|
+
dnsRecordsFound: z.array(z.string()),
|
|
80
|
+
});
|
|
81
|
+
export const SsoConfig_RevokeDomainResponseDto = z.strictObject({
|
|
82
|
+
domain: z.string(),
|
|
83
|
+
/** True once the domain holds no claim, no status and no nonce in this scope. */
|
|
84
|
+
revoked: z.boolean(),
|
|
85
|
+
});
|
|
14
86
|
// ── Polymorphic Factory ──────────────────────────────────────────────
|
|
15
87
|
export const ssoConfigPolymorphicFactories = createPolymorphicResourceConfigurations(ssoConfigPolymorphicDeclaration, {
|
|
16
88
|
isSystemResource: true,
|
|
89
|
+
customOperation: SsoConfig_Operations,
|
|
17
90
|
// The auth runtime loads the org SSO config via `readAsSystem` during login,
|
|
18
91
|
// before the user's roles/membership are established (READ). When the row is
|
|
19
92
|
// absent — a provisioned / migrated / pre-seed org that bypassed the
|
|
@@ -22,11 +95,24 @@ export const ssoConfigPolymorphicFactories = createPolymorphicResourceConfigurat
|
|
|
22
95
|
// `AuthOrganizationConfigurationService.loadSSOConfig`. Both are system-context
|
|
23
96
|
// (the logging-in user is not the config's admin owner), so the resource opts
|
|
24
97
|
// BOTH verbs in.
|
|
98
|
+
//
|
|
99
|
+
// `list` is the DOMAIN-EXCLUSIVITY probe and nothing else (#424). At most one scope may hold a
|
|
100
|
+
// domain VERIFIED, or a `@customer.com` sign-in routes non-deterministically to whichever
|
|
101
|
+
// config the lookup happens to reach first. Answering "does another scope already hold this
|
|
102
|
+
// domain" is unavoidably a cross-scope read, and the two candidates that avoid this grant are
|
|
103
|
+
// both worse:
|
|
104
|
+
// - `AuthOrganizationConfigurationService.getAllOrganizationIds()` enumerates an IN-MEMORY
|
|
105
|
+
// CACHE of scopes whose config has been loaded, so it under-reports on a cold process. An
|
|
106
|
+
// exclusivity check built on it answers "nobody else holds it" from an incomplete
|
|
107
|
+
// population — the negative-result failure that produces a confident wrong answer;
|
|
108
|
+
// - reaching the repository directly bypasses the `systemAccessPolicy` opt-in AND the
|
|
109
|
+
// `SYSTEM_CONTEXT_*` audit event, which is a bigger grant wearing a smaller name.
|
|
25
110
|
systemAccessPolicy: {
|
|
26
111
|
read: ResourceSystemAccessMode.ALLOWED,
|
|
27
112
|
create: ResourceSystemAccessMode.ALLOWED,
|
|
113
|
+
list: ResourceSystemAccessMode.ALLOWED,
|
|
28
114
|
},
|
|
29
|
-
coreOperations: [CoreResourceOperation.READ, CoreResourceOperation.CREATE, CoreResourceOperation.UPDATE, CoreResourceOperation.DELETE],
|
|
115
|
+
coreOperations: [CoreResourceOperation.READ, CoreResourceOperation.LIST, CoreResourceOperation.CREATE, CoreResourceOperation.UPDATE, CoreResourceOperation.DELETE],
|
|
30
116
|
operationsConfiguration: {
|
|
31
117
|
[CoreResourceOperation.READ]: {
|
|
32
118
|
variants: [{
|
|
@@ -61,13 +147,36 @@ export const ssoConfigPolymorphicFactories = createPolymorphicResourceConfigurat
|
|
|
61
147
|
riskLevel: ResourceOperationRiskLevel.HIGH,
|
|
62
148
|
}],
|
|
63
149
|
},
|
|
150
|
+
// Internal-only (INTERNAL_CALL, NO HTTP route): the ONE caller is the domain-exclusivity
|
|
151
|
+
// probe described on `systemAccessPolicy.list` above, reached through
|
|
152
|
+
// `SystemAccessService.listAsSystem`. It must NOT be REPOSITORY_ONLY for the same reason the
|
|
153
|
+
// CREATE and UPDATE below are not: `listAsSystem` resolves the verb through
|
|
154
|
+
// `getServiceOperationPathDefault`, which honours INTERNAL_CALL / API_CALL and rejects
|
|
155
|
+
// REPOSITORY_ONLY. There is deliberately no API_CALL variant — one tenant enumerating every
|
|
156
|
+
// other tenant's SSO policy is the opposite of what this resource is for, and the probe that
|
|
157
|
+
// needs the enumeration answers a single yes/no question and returns no row to a caller.
|
|
158
|
+
// Admin tier / HIGH.
|
|
159
|
+
[CoreResourceOperation.LIST]: {
|
|
160
|
+
variants: [{
|
|
161
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
162
|
+
isDefault: true,
|
|
163
|
+
polymorphicRole: {
|
|
164
|
+
[CoreResourceType.ORGANIZATIONS]: [CORE_ORG_ROLES.ORG_ADMIN],
|
|
165
|
+
[CoreResourceType.APPLICATION]: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
166
|
+
},
|
|
167
|
+
riskLevel: ResourceOperationRiskLevel.HIGH,
|
|
168
|
+
}],
|
|
169
|
+
},
|
|
64
170
|
// Internal-only (INTERNAL_CALL, NO HTTP route): admin policy edits reach this
|
|
65
171
|
// through the config service path — `AuthOrganizationConfigurationService.saveSSOConfig`
|
|
66
172
|
// dispatches the write via `ServicesRegistryHandler.update` with the ADMIN's EC,
|
|
67
|
-
// preserving admin audit attribution.
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
173
|
+
// preserving admin audit attribution. The comment here used to say the path was
|
|
174
|
+
// "correct-but-dormant" because `DomainVerificationBackendService` had no public operation
|
|
175
|
+
// wired to it, and warned against "simplifying" the variant on the theory that nothing calls
|
|
176
|
+
// it. That warning was right and is now moot: the domain workflow it was holding the door
|
|
177
|
+
// open for exists (`claimDomain` / `verifyDomain` / `revokeDomain` below), and
|
|
178
|
+
// `initiateDomainVerification` / `verifyDomainOwnership` still reach this INTERNAL_CALL path
|
|
179
|
+
// for callers that hold no operation.
|
|
71
180
|
// Must NOT be REPOSITORY_ONLY: `.update()` resolves the op via
|
|
72
181
|
// `getServiceOperationPathDefault`, which honours INTERNAL_CALL / API_CALL but NOT
|
|
73
182
|
// REPOSITORY_ONLY — a repository-only UPDATE throws
|
|
@@ -108,6 +217,99 @@ export const ssoConfigPolymorphicFactories = createPolymorphicResourceConfigurat
|
|
|
108
217
|
riskLevel: ResourceOperationRiskLevel.HIGH,
|
|
109
218
|
}],
|
|
110
219
|
},
|
|
220
|
+
/*
|
|
221
|
+
* ─── The three domain-ownership doors (#424) ────────────────────────────────────────────
|
|
222
|
+
*
|
|
223
|
+
* ## Why the tenant's own admin, and NOT a platform operator
|
|
224
|
+
*
|
|
225
|
+
* None of the three declares `admitsCrossTenantPlatformAdministration`, and that is a
|
|
226
|
+
* decision rather than an omission. A platform operator crossing into a tenant is justified
|
|
227
|
+
* when the tenant CANNOT act for itself — `organizationMembers.grantOwnership` repairs a
|
|
228
|
+
* tenant with no owner. Domain ownership is the opposite shape: the party who must prove it
|
|
229
|
+
* is the party who controls the DNS, and the operator controls neither the DNS nor the
|
|
230
|
+
* business relationship. A crossing here would let a platform administrator hand one tenant
|
|
231
|
+
* routing control over every sign-in at a domain, with the tenant's own admins unable to see
|
|
232
|
+
* why. The ambient reach `.claude/rules/administrative-continuity-floors.md` forbids is
|
|
233
|
+
* exactly this.
|
|
234
|
+
*
|
|
235
|
+
* ## Why each is UPDATE-like
|
|
236
|
+
*
|
|
237
|
+
* All three mutate `domains` on the scope's single config row, so they borrow UPDATE and get
|
|
238
|
+
* a PUT that carries a body. The domain travels in the BODY, never in the URL: a domain name
|
|
239
|
+
* is a customer identity, and a GET would write it into every access log between the operator
|
|
240
|
+
* and the server.
|
|
241
|
+
*
|
|
242
|
+
* ## Where the work happens
|
|
243
|
+
*
|
|
244
|
+
* Each is implemented as a PREFIX that returns the new `domains` object, which the core
|
|
245
|
+
* UPDATE persists — the organization-units MOVE/ARCHIVE shape. Deliberately NOT `OVERRIDE_ALL`:
|
|
246
|
+
* that mode returns before the framework's post-operation lane and would therefore emit NO
|
|
247
|
+
* `RESOURCE_OPERATION_PERFORMED` audit event, which is the one control that makes a
|
|
248
|
+
* privileged configuration change with cross-tenant reach accountable. See
|
|
249
|
+
* `sso-config-domain-verification.custom-impl.backend.service.ts`.
|
|
250
|
+
*
|
|
251
|
+
* ## What the trail carries
|
|
252
|
+
*
|
|
253
|
+
* All three sit at or above `AUTOMATIC_AUDIT_RISK_FLOOR`, so no `auditableEvent` declaration
|
|
254
|
+
* is needed. `domains.verifiedDomains`, `domains.ssoEnabledDomains` and
|
|
255
|
+
* `domains.domainVerificationStatus` are `.isAuditEvidence()`, so the row carries the
|
|
256
|
+
* before/after of the claimed set and the status map — i.e. WHICH domain moved, and to what.
|
|
257
|
+
* `domains.domainVerificationTokens` is not marked and must never be: it is the challenge
|
|
258
|
+
* nonce, and the ledger it would land in cannot be scrubbed.
|
|
259
|
+
*
|
|
260
|
+
* assurance-control: WILDO.IDENTITY.SESSION_ASSURANCE — a verified domain decides which
|
|
261
|
+
* identity provider authenticates every principal at that domain.
|
|
262
|
+
* assurance-control: WILDO.AUDIT.EVIDENCE_INTEGRITY — the domain-ownership trail.
|
|
263
|
+
*/
|
|
264
|
+
[SsoConfig_Operations.CLAIM_DOMAIN]: {
|
|
265
|
+
variants: [{
|
|
266
|
+
variantType: ResourceOperationVariantType.API_CALL,
|
|
267
|
+
isDefault: true,
|
|
268
|
+
polymorphicRole: {
|
|
269
|
+
[CoreResourceType.ORGANIZATIONS]: [CORE_ORG_ROLES.ORG_ADMIN],
|
|
270
|
+
[CoreResourceType.APPLICATION]: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
271
|
+
},
|
|
272
|
+
// HIGH, not CRITICAL: a claim grants NOTHING. It records `pending` and mints a nonce, and
|
|
273
|
+
// every routing reader gates on `verified`. The step that confers authority is VERIFY.
|
|
274
|
+
riskLevel: ResourceOperationRiskLevel.HIGH,
|
|
275
|
+
resourceOperationLike: CoreResourceOperation.UPDATE,
|
|
276
|
+
requestDto: SsoConfig_ClaimDomainRequestDto,
|
|
277
|
+
customResponseDto: SsoConfig_ClaimDomainResponseDto,
|
|
278
|
+
}],
|
|
279
|
+
},
|
|
280
|
+
[SsoConfig_Operations.VERIFY_DOMAIN]: {
|
|
281
|
+
variants: [{
|
|
282
|
+
variantType: ResourceOperationVariantType.API_CALL,
|
|
283
|
+
isDefault: true,
|
|
284
|
+
polymorphicRole: {
|
|
285
|
+
[CoreResourceType.ORGANIZATIONS]: [CORE_ORG_ROLES.ORG_ADMIN],
|
|
286
|
+
[CoreResourceType.APPLICATION]: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
287
|
+
},
|
|
288
|
+
// CRITICAL: this is the transition that hands a tenant SSO routing control over EVERY
|
|
289
|
+
// person who signs in with an address at the domain — including people who are not that
|
|
290
|
+
// tenant's members.
|
|
291
|
+
riskLevel: ResourceOperationRiskLevel.CRITICAL,
|
|
292
|
+
resourceOperationLike: CoreResourceOperation.UPDATE,
|
|
293
|
+
requestDto: SsoConfig_VerifyDomainRequestDto,
|
|
294
|
+
customResponseDto: SsoConfig_VerifyDomainResponseDto,
|
|
295
|
+
}],
|
|
296
|
+
},
|
|
297
|
+
[SsoConfig_Operations.REVOKE_DOMAIN]: {
|
|
298
|
+
variants: [{
|
|
299
|
+
variantType: ResourceOperationVariantType.API_CALL,
|
|
300
|
+
isDefault: true,
|
|
301
|
+
polymorphicRole: {
|
|
302
|
+
[CoreResourceType.ORGANIZATIONS]: [CORE_ORG_ROLES.ORG_ADMIN],
|
|
303
|
+
[CoreResourceType.APPLICATION]: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
304
|
+
},
|
|
305
|
+
// CRITICAL for the same reason as VERIFY, from the other side: revocation is what makes a
|
|
306
|
+
// domain claimable by a different scope, so it is the hinge of every hand-over.
|
|
307
|
+
riskLevel: ResourceOperationRiskLevel.CRITICAL,
|
|
308
|
+
resourceOperationLike: CoreResourceOperation.UPDATE,
|
|
309
|
+
requestDto: SsoConfig_RevokeDomainRequestDto,
|
|
310
|
+
customResponseDto: SsoConfig_RevokeDomainResponseDto,
|
|
311
|
+
}],
|
|
312
|
+
},
|
|
111
313
|
},
|
|
112
314
|
});
|
|
113
315
|
//# sourceMappingURL=sso-config.shared.resources-config.schemas.js.map
|