@cosmicdrift/kumiko-bundled-features 0.362.0 → 0.364.0
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/admin-shell/feature.d.ts +3 -0
- package/dist/admin-shell/feature.js +6 -1
- package/dist/agent-tools/agent-manifest.js +2 -1
- package/dist/agent-tools/filter-ops.d.ts +1 -1
- package/dist/agent-tools/filter-ops.js +1 -3
- package/dist/agent-tools/tool-dispatch.js +2 -1
- package/dist/audit/handlers/list.query.js +9 -5
- package/dist/auth-email-password/bootstrap.d.ts +8 -5
- package/dist/auth-email-password/bootstrap.js +12 -4
- package/dist/auth-email-password/email-rate-limits.d.ts +4 -0
- package/dist/auth-email-password/email-rate-limits.js +13 -0
- package/dist/auth-email-password/email-templates.d.ts +4 -26
- package/dist/auth-email-password/email-templates.js +9 -101
- package/dist/auth-email-password/feature.js +24 -6
- package/dist/auth-email-password/handlers/change-password.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/change-password.write.js +6 -2
- package/dist/auth-email-password/handlers/confirm-account-unlock.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/invite-accept.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
- package/dist/auth-email-password/handlers/invite-create.write.js +4 -4
- package/dist/auth-email-password/handlers/invite-signup-complete.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/logout.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/logout.write.js +6 -2
- package/dist/auth-email-password/handlers/request-account-unlock.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/request-account-unlock.write.js +2 -4
- package/dist/auth-email-password/handlers/request-email-verification.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/request-email-verification.write.js +2 -4
- package/dist/auth-email-password/handlers/request-password-reset.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/request-password-reset.write.js +2 -4
- package/dist/auth-email-password/handlers/reset-password.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/signup-confirm.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/signup-confirm.write.js +3 -4
- package/dist/auth-email-password/handlers/signup-request.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/signup-request.write.js +2 -1
- package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/token-request-handler.d.ts +2 -3
- package/dist/auth-email-password/handlers/token-request-handler.js +2 -2
- package/dist/auth-email-password/handlers/verify-email.write.d.ts +1 -1
- package/dist/auth-email-password/index.d.ts +2 -2
- package/dist/auth-email-password/index.js +1 -1
- package/dist/auth-email-password/magic-link-mail.d.ts +3 -2
- package/dist/auth-email-password/magic-link-mail.js +19 -14
- package/dist/auth-email-password/mail-notifications.d.ts +32 -0
- package/dist/auth-email-password/mail-notifications.js +116 -0
- package/dist/auth-email-password/signup-activation.d.ts +1 -1
- package/dist/auth-email-password/signup-activation.js +2 -3
- package/dist/auth-email-password/web/auth-gate.js +16 -4
- package/dist/auth-foundation/types.js +2 -8
- package/dist/auth-mfa/feature.js +4 -4
- package/dist/auth-mfa/handlers/disable.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/enable-confirm-preauth.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/enable-confirm.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/enable-start-preauth.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/enable-start.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/regenerate-recovery.write.d.ts +1 -1
- package/dist/auth-mfa/handlers/verify.write.d.ts +1 -1
- package/dist/auth-mfa/hmac-token-codec.js +4 -4
- package/dist/auth-mfa/mfa-challenge-token.js +3 -3
- package/dist/auth-mfa/mfa-preauth-setup-token.js +3 -3
- package/dist/auth-mfa/mfa-setup-token.js +8 -8
- package/dist/billing-foundation/constants.d.ts +3 -3
- package/dist/billing-foundation/constants.js +5 -4
- package/dist/billing-foundation/consumer-protection/confirmation-mail.d.ts +32 -14
- package/dist/billing-foundation/consumer-protection/confirmation-mail.js +74 -32
- package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +3 -0
- package/dist/billing-foundation/consumer-protection/consent-gate.js +21 -2
- package/dist/billing-foundation/consumer-protection/issue-confirmation.js +3 -3
- package/dist/billing-foundation/consumer-protection/mail-notifications.d.ts +8 -0
- package/dist/billing-foundation/consumer-protection/mail-notifications.js +95 -0
- package/dist/billing-foundation/consumer-protection/register-consent.js +2 -0
- package/dist/billing-foundation/consumer-protection/register-termination.js +11 -1
- package/dist/billing-foundation/consumer-protection/termination-mail.d.ts +25 -13
- package/dist/billing-foundation/consumer-protection/termination-mail.js +11 -23
- package/dist/billing-foundation/consumer-protection/termination-notify.js +2 -2
- package/dist/billing-foundation/consumer-protection/termination-pages.js +1 -3
- package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +6 -0
- package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +34 -0
- package/dist/billing-foundation/consumer-protection/termination-record.d.ts +2 -0
- package/dist/billing-foundation/consumer-protection/termination-record.js +7 -1
- package/dist/billing-foundation/consumer-protection/termination-request.js +31 -21
- package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
- package/dist/billing-foundation/consumer-protection/termination-texts.js +6 -0
- package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +10 -0
- package/dist/billing-foundation/consumer-protection/withdrawal-period.js +26 -0
- package/dist/billing-foundation/handlers/create-checkout-session.write.js +11 -5
- package/dist/billing-foundation/handlers/process-event.write.js +12 -8
- package/dist/billing-foundation/handlers/process-payment-event.write.js +1 -1
- package/dist/billing-foundation/i18n.js +3 -0
- package/dist/billing-foundation/subscription-tier-sync.d.ts +7 -1
- package/dist/billing-foundation/subscription-tier-sync.js +16 -9
- package/dist/billing-foundation/types.d.ts +7 -2
- package/dist/cap-counter/calendar-cap-usage-reservation.js +2 -0
- package/dist/cap-counter/enforce-cap.d.ts +18 -1
- package/dist/cap-counter/enforce-cap.js +49 -6
- package/dist/cap-counter/index.d.ts +1 -1
- package/dist/cap-counter/index.js +1 -1
- package/dist/cap-counter/with-cap-enforcement.d.ts +2 -0
- package/dist/cap-overview/handlers/tenant-caps-list.query.js +2 -1
- package/dist/cap-overview/web/cap-usage-cell.js +5 -4
- package/dist/channel-email/email-channel.d.ts +2 -2
- package/dist/channel-email/email-channel.js +101 -26
- package/dist/channel-email/feature.js +3 -3
- package/dist/channel-email/index.d.ts +1 -1
- package/dist/channel-email/index.js +1 -1
- package/dist/channel-email/pii-guard.js +10 -0
- package/dist/channel-email/smtp-transport.js +13 -0
- package/dist/channel-email/types.d.ts +8 -0
- package/dist/channel-in-app/handlers/mark-all-read.write.d.ts +1 -1
- package/dist/channel-in-app/handlers/mark-read.write.d.ts +1 -1
- package/dist/compliance-profiles/handlers/set-profile.write.d.ts +1 -1
- package/dist/config/handlers/reset.write.d.ts +1 -1
- package/dist/config/handlers/set.write.d.ts +1 -1
- package/dist/config/handlers/set.write.js +3 -4
- package/dist/config/resolver.d.ts +1 -0
- package/dist/config/resolver.js +11 -14
- package/dist/config/write-helpers.d.ts +2 -0
- package/dist/config/write-helpers.js +19 -0
- package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +1 -1
- package/dist/crypto-shredding/handlers/forget-subject.write.js +29 -19
- package/dist/custom-fields/handlers/update-tenant-field.write.js +0 -1
- package/dist/custom-fields/lib/value-schema.js +10 -11
- package/dist/custom-fields/wire-user-data-rights.js +7 -6
- package/dist/data-retention/index.d.ts +1 -0
- package/dist/data-retention/index.js +1 -0
- package/dist/data-retention/run-retention-cleanup.js +6 -6
- package/dist/delivery/attachment-ref.d.ts +41 -0
- package/dist/delivery/attachment-ref.js +78 -0
- package/dist/delivery/channel-context.d.ts +8 -4
- package/dist/delivery/channel-context.js +94 -2
- package/dist/delivery/constants.d.ts +1 -0
- package/dist/delivery/constants.js +1 -0
- package/dist/delivery/delivery-service.d.ts +4 -1
- package/dist/delivery/delivery-service.js +38 -32
- package/dist/delivery/feature.js +1 -1
- package/dist/delivery/handlers/resubscribe-address.write.d.ts +1 -1
- package/dist/delivery/handlers/resubscribe-user.write.d.ts +1 -1
- package/dist/delivery/handlers/set-preference.write.d.ts +1 -1
- package/dist/delivery/handlers/unsubscribe-address.write.d.ts +1 -1
- package/dist/delivery/handlers/unsubscribe-user.write.d.ts +1 -1
- package/dist/delivery/index.d.ts +5 -2
- package/dist/delivery/index.js +4 -1
- package/dist/delivery/jobs.js +66 -14
- package/dist/delivery/notify-factory.js +4 -1
- package/dist/delivery/testing.d.ts +4 -1
- package/dist/delivery/types.d.ts +26 -14
- package/dist/delivery/unsubscribe.js +4 -1
- package/dist/derivatives-sharp/render.js +1 -18
- package/dist/document-ingest-foundation/pages.js +4 -4
- package/dist/feature-toggles/handlers/set.write.d.ts +1 -1
- package/dist/feature-toggles/toggle-sync-signal.js +4 -4
- package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
- package/dist/file-foundation/index.d.ts +1 -0
- package/dist/file-foundation/index.js +1 -0
- package/dist/file-foundation/read-file-ref-content.d.ts +27 -0
- package/dist/file-foundation/read-file-ref-content.js +51 -0
- package/dist/files-tenant-data/hooks.js +4 -0
- package/dist/folders/web/folder-manager.js +3 -2
- package/dist/form-draft/db/queries/cleanup.js +4 -4
- package/dist/form-draft/db/queries/draft-count.js +2 -2
- package/dist/form-draft/db/queries/owned-file-refs.js +2 -2
- package/dist/form-draft/handlers/discard.write.d.ts +1 -1
- package/dist/form-draft/handlers/save.write.d.ts +1 -1
- package/dist/form-draft/release-file-refs.js +3 -2
- package/dist/inbound-mail-foundation/handlers/connect-account.write.js +1 -1
- package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +6 -6
- package/dist/inbound-mail-foundation/handlers/scope-visibility.d.ts +1 -1
- package/dist/inbound-mail-foundation/oauth-access-token.js +8 -3
- package/dist/inbound-mail-foundation/oauth-state.js +7 -7
- package/dist/inbound-mail-foundation/types.js +4 -4
- package/dist/inbound-mail-foundation/watch-supervisor.js +24 -13
- package/dist/inbound-provider-imap/imap-client.js +4 -3
- package/dist/jobs/db/queries/stale-run-sweep.d.ts +1 -1
- package/dist/jobs/db/queries/stale-run-sweep.js +12 -5
- package/dist/jobs/feature.js +5 -3
- package/dist/jobs/handlers/list.query.js +3 -1
- package/dist/jobs/handlers/retry.write.d.ts +1 -1
- package/dist/jobs/handlers/stale-run-sweep.job.d.ts +1 -1
- package/dist/jobs/handlers/stale-run-sweep.job.js +2 -2
- package/dist/jobs/handlers/trigger.write.d.ts +1 -1
- package/dist/jobs/job-run-logger.js +32 -10
- package/dist/jobs/tenant-job-run-table.js +3 -2
- package/dist/ledger/entity.js +3 -1
- package/dist/ledger/recurring.js +1 -3
- package/dist/managed-pages/branding.d.ts +2 -0
- package/dist/managed-pages/branding.js +24 -2
- package/dist/managed-pages/feature.js +1 -0
- package/dist/managed-pages/handlers/set.write.d.ts +1 -1
- package/dist/managed-pages/i18n.js +1 -0
- package/dist/managed-pages/screens/branding-screen.js +8 -1
- package/dist/page-render/branding.d.ts +1 -0
- package/dist/page-render/branding.js +1 -0
- package/dist/page-render/markdown.js +1 -1
- package/dist/personal-access-tokens/feature.js +1 -1
- package/dist/personal-access-tokens/handlers/create.write.d.ts +1 -1
- package/dist/personal-access-tokens/handlers/list.query.js +2 -1
- package/dist/personal-access-tokens/handlers/revoke.write.d.ts +1 -1
- package/dist/personal-access-tokens/revoke-for-user.js +2 -1
- package/dist/renderer-foundation/api.d.ts +13 -13
- package/dist/renderer-foundation/api.js +1 -1
- package/dist/renderer-foundation/constants.js +2 -4
- package/dist/renderer-foundation/feature.js +7 -7
- package/dist/renderer-foundation/index.d.ts +2 -1
- package/dist/renderer-foundation/index.js +1 -0
- package/dist/renderer-foundation/types.d.ts +94 -32
- package/dist/renderer-pdf/feature.js +7 -1
- package/dist/renderer-pdf/render-table-pdf.d.ts +27 -33
- package/dist/renderer-pdf/render-table-pdf.js +95 -34
- package/dist/secrets/feature.js +4 -3
- package/dist/secrets/handlers/delete.write.d.ts +1 -1
- package/dist/secrets/handlers/set.write.d.ts +1 -1
- package/dist/secrets/secrets-context.js +15 -3
- package/dist/sessions/db/queries/cleanup.js +2 -2
- package/dist/sessions/feature.js +1 -1
- package/dist/sessions/handlers/list.query.js +2 -1
- package/dist/sessions/handlers/revoke-all-for-user.write.d.ts +1 -1
- package/dist/sessions/handlers/revoke-all-others.write.d.ts +1 -1
- package/dist/sessions/handlers/revoke.write.d.ts +1 -1
- package/dist/shared/attachment-file-name.d.ts +3 -0
- package/dist/shared/attachment-file-name.js +35 -0
- package/dist/shared/chunked-entity-migration.d.ts +1 -0
- package/dist/shared/chunked-entity-migration.js +1 -1
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +3 -0
- package/dist/shared/is-tenant-db.js +1 -1
- package/dist/shared/mail-template-body.d.ts +7 -0
- package/dist/shared/mail-template-body.js +27 -0
- package/dist/shared/sharp-input-limits.d.ts +6 -0
- package/dist/shared/sharp-input-limits.js +22 -0
- package/dist/shared/signup-handover.js +2 -2
- package/dist/subscription-stripe/plugin-methods.js +18 -8
- package/dist/subscription-stripe/verify-webhook.d.ts +1 -1
- package/dist/tags/handlers/assign-tag.write.js +3 -1
- package/dist/tags/web/tag-chip.js +2 -0
- package/dist/template-resolver/api.d.ts +30 -2
- package/dist/template-resolver/api.js +42 -6
- package/dist/template-resolver/compile-document-body.d.ts +12 -0
- package/dist/template-resolver/compile-document-body.js +205 -0
- package/dist/template-resolver/constants.d.ts +13 -4
- package/dist/template-resolver/constants.js +32 -10
- package/dist/template-resolver/document-sanitizer.d.ts +32 -0
- package/dist/template-resolver/document-sanitizer.js +201 -0
- package/dist/template-resolver/document-schema.d.ts +21 -0
- package/dist/template-resolver/document-schema.js +316 -0
- package/dist/template-resolver/feature.d.ts +20 -0
- package/dist/template-resolver/feature.js +53 -6
- package/dist/template-resolver/handlers/bundle-import.d.ts +20 -0
- package/dist/template-resolver/handlers/bundle-import.js +147 -0
- package/dist/template-resolver/handlers/collection-set.write.d.ts +1 -1
- package/dist/template-resolver/handlers/collection-set.write.js +25 -2
- package/dist/template-resolver/handlers/copy-locale.write.d.ts +19 -0
- package/dist/template-resolver/handlers/copy-locale.write.js +134 -0
- package/dist/template-resolver/handlers/diff-to-system.query.d.ts +22 -0
- package/dist/template-resolver/handlers/diff-to-system.query.js +30 -0
- package/dist/template-resolver/handlers/discard-draft.write.d.ts +13 -0
- package/dist/template-resolver/handlers/discard-draft.write.js +37 -0
- package/dist/template-resolver/handlers/export-bundle.query.d.ts +35 -0
- package/dist/template-resolver/handlers/export-bundle.query.js +118 -0
- package/dist/template-resolver/handlers/find-by-id.query.d.ts +2 -0
- package/dist/template-resolver/handlers/find-by-id.query.js +9 -6
- package/dist/template-resolver/handlers/import-bundle-system.write.d.ts +39 -0
- package/dist/template-resolver/handlers/import-bundle-system.write.js +36 -0
- package/dist/template-resolver/handlers/import-bundle.write.d.ts +40 -0
- package/dist/template-resolver/handlers/import-bundle.write.js +19 -0
- package/dist/template-resolver/handlers/layout-source.query.d.ts +31 -0
- package/dist/template-resolver/handlers/layout-source.query.js +87 -0
- package/dist/template-resolver/handlers/list.query.d.ts +4 -1
- package/dist/template-resolver/handlers/list.query.js +9 -8
- package/dist/template-resolver/handlers/override-diff.d.ts +20 -0
- package/dist/template-resolver/handlers/override-diff.js +41 -0
- package/dist/template-resolver/handlers/overview.query.d.ts +65 -0
- package/dist/template-resolver/handlers/overview.query.js +205 -0
- package/dist/template-resolver/handlers/preview.query.d.ts +12 -0
- package/dist/template-resolver/handlers/preview.query.js +24 -0
- package/dist/template-resolver/handlers/reset-to-system.write.d.ts +8 -0
- package/dist/template-resolver/handlers/reset-to-system.write.js +50 -0
- package/dist/template-resolver/handlers/resource-link-pdf.write.d.ts +8 -0
- package/dist/template-resolver/handlers/resource-link-pdf.write.js +32 -0
- package/dist/template-resolver/handlers/resource-remove.write.d.ts +9 -0
- package/dist/template-resolver/handlers/resource-remove.write.js +44 -0
- package/dist/template-resolver/handlers/resource-shared.d.ts +9 -0
- package/dist/template-resolver/handlers/resource-shared.js +14 -0
- package/dist/template-resolver/handlers/resource-upload.write.d.ts +13 -0
- package/dist/template-resolver/handlers/resource-upload.write.js +98 -0
- package/dist/template-resolver/handlers/send-test.write.d.ts +13 -0
- package/dist/template-resolver/handlers/send-test.write.js +108 -0
- package/dist/template-resolver/handlers/set.write.d.ts +5 -2
- package/dist/template-resolver/handlers/set.write.js +25 -3
- package/dist/template-resolver/handlers/shared.d.ts +9 -5
- package/dist/template-resolver/handlers/shared.js +6 -2
- package/dist/template-resolver/handlers/template-gates.d.ts +36 -0
- package/dist/template-resolver/handlers/template-gates.js +142 -0
- package/dist/template-resolver/handlers/template-write.d.ts +45 -0
- package/dist/template-resolver/handlers/template-write.js +141 -0
- package/dist/template-resolver/handlers/tenant-overrides.query.d.ts +49 -0
- package/dist/template-resolver/handlers/tenant-overrides.query.js +112 -0
- package/dist/template-resolver/handlers/toggle-status.write.d.ts +27 -2
- package/dist/template-resolver/handlers/toggle-status.write.js +47 -15
- package/dist/template-resolver/handlers/upsert-system.write.d.ts +5 -8
- package/dist/template-resolver/handlers/upsert-system.write.js +14 -59
- package/dist/template-resolver/handlers/upsert-tenant.write.d.ts +5 -8
- package/dist/template-resolver/handlers/upsert-tenant.write.js +11 -62
- package/dist/template-resolver/handlers/usage.query.d.ts +17 -0
- package/dist/template-resolver/handlers/usage.query.js +24 -0
- package/dist/template-resolver/handlers/validate.query.d.ts +74 -0
- package/dist/template-resolver/handlers/validate.query.js +80 -0
- package/dist/template-resolver/index.d.ts +19 -1
- package/dist/template-resolver/index.js +17 -1
- package/dist/template-resolver/layout-appearance.d.ts +10 -0
- package/dist/template-resolver/layout-appearance.js +26 -0
- package/dist/template-resolver/layout-regions.d.ts +23 -0
- package/dist/template-resolver/layout-regions.js +125 -0
- package/dist/template-resolver/linked-resources.d.ts +17 -0
- package/dist/template-resolver/linked-resources.js +75 -0
- package/dist/template-resolver/pdf-constants.d.ts +7 -0
- package/dist/template-resolver/pdf-constants.js +8 -0
- package/dist/template-resolver/preview-display-html.d.ts +7 -0
- package/dist/template-resolver/preview-display-html.js +27 -0
- package/dist/template-resolver/print-document.d.ts +1 -0
- package/dist/template-resolver/print-document.js +55 -0
- package/dist/template-resolver/qualified-names.d.ts +34 -0
- package/dist/template-resolver/qualified-names.js +34 -0
- package/dist/template-resolver/record-mapping.d.ts +2 -0
- package/dist/template-resolver/record-mapping.js +21 -0
- package/dist/template-resolver/resource-image.d.ts +15 -0
- package/dist/template-resolver/resource-image.js +34 -0
- package/dist/template-resolver/seeding.d.ts +14 -1
- package/dist/template-resolver/seeding.js +125 -18
- package/dist/template-resolver/store-template-resource.d.ts +64 -0
- package/dist/template-resolver/store-template-resource.js +264 -0
- package/dist/template-resolver/table.d.ts +150 -8
- package/dist/template-resolver/table.js +20 -2
- package/dist/template-resolver/template-bundle.d.ts +36 -0
- package/dist/template-resolver/template-bundle.js +60 -0
- package/dist/template-resolver/template-diff.d.ts +7 -0
- package/dist/template-resolver/template-diff.js +68 -0
- package/dist/template-resolver/template-draft.d.ts +51 -0
- package/dist/template-resolver/template-draft.js +72 -0
- package/dist/template-resolver/template-meta.d.ts +85 -0
- package/dist/template-resolver/template-meta.js +145 -0
- package/dist/template-resolver/template-preview.d.ts +103 -0
- package/dist/template-resolver/template-preview.js +418 -0
- package/dist/template-resolver/template-resources.d.ts +19 -0
- package/dist/template-resolver/template-resources.js +73 -0
- package/dist/template-resolver/template-usage.d.ts +16 -0
- package/dist/template-resolver/template-usage.js +35 -0
- package/dist/template-resolver/template-validation.d.ts +22 -0
- package/dist/template-resolver/template-validation.js +173 -0
- package/dist/template-resolver/testing.js +5 -5
- package/dist/template-resolver/user-content-table.d.ts +14 -8
- package/dist/template-resolver/web/client-plugin.d.ts +1 -0
- package/dist/template-resolver/web/client-plugin.js +12 -7
- package/dist/template-resolver/web/document-editor-extensions.d.ts +18 -0
- package/dist/template-resolver/web/document-editor-extensions.js +145 -0
- package/dist/template-resolver/web/document-editor.d.ts +4 -0
- package/dist/template-resolver/web/document-editor.js +17 -0
- package/dist/template-resolver/web/document-tiptap-editor.d.ts +3 -0
- package/dist/template-resolver/web/document-tiptap-editor.js +492 -0
- package/dist/template-resolver/web/document-toolbar-blocks.d.ts +41 -0
- package/dist/template-resolver/web/document-toolbar-blocks.js +19 -0
- package/dist/template-resolver/web/editor-handle.d.ts +3 -0
- package/dist/template-resolver/web/editor-handle.js +24 -0
- package/dist/template-resolver/web/i18n.js +91 -0
- package/dist/template-resolver/web/index.d.ts +5 -0
- package/dist/template-resolver/web/index.js +5 -0
- package/dist/template-resolver/web/placeholder-line-editor-lazy.d.ts +4 -0
- package/dist/template-resolver/web/placeholder-line-editor-lazy.js +16 -0
- package/dist/template-resolver/web/placeholder-line-editor.d.ts +17 -0
- package/dist/template-resolver/web/placeholder-line-editor.js +94 -0
- package/dist/template-resolver/web/placeholder-text.d.ts +4 -0
- package/dist/template-resolver/web/placeholder-text.js +34 -0
- package/dist/template-resolver/web/use-stable-by-key.d.ts +1 -0
- package/dist/template-resolver/web/use-stable-by-key.js +13 -0
- package/dist/tenant/handlers/add-member.write.d.ts +1 -1
- package/dist/tenant/handlers/cancel-invitation.write.d.ts +1 -1
- package/dist/tenant/handlers/create.write.d.ts +1 -1
- package/dist/tenant/handlers/remove-member.write.d.ts +1 -1
- package/dist/tenant/handlers/team-list.query.js +3 -2
- package/dist/tenant/handlers/toggle-enabled.write.d.ts +2 -2
- package/dist/tenant/handlers/update-member-roles.write.d.ts +1 -1
- package/dist/tenant/handlers/update.write.d.ts +1 -1
- package/dist/tenant/seeding.js +31 -6
- package/dist/tenant-handover/handlers/claim.write.d.ts +1 -1
- package/dist/tenant-lifecycle/handlers/cancel-destruction.write.d.ts +2 -2
- package/dist/tenant-lifecycle/handlers/cancel-destruction.write.js +2 -1
- package/dist/tenant-lifecycle/handlers/request-destruction.write.d.ts +1 -1
- package/dist/tier-engine/feature.js +9 -3
- package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +1 -1
- package/dist/user/db/queries/stream-tenant-backfill.js +4 -4
- package/dist/user/handlers/create.write.d.ts +1 -1
- package/dist/user/handlers/detail.query.js +2 -1
- package/dist/user/handlers/update.write.d.ts +1 -1
- package/dist/user/resolve-display-names.js +5 -9
- package/dist/user/seeding.js +20 -1
- package/dist/user-data-rights/db/queries/forget-cleanup.d.ts +2 -2
- package/dist/user-data-rights/email-templates.d.ts +1 -29
- package/dist/user-data-rights/email-templates.js +5 -106
- package/dist/user-data-rights/feature.js +53 -35
- package/dist/user-data-rights/handlers/cancel-deletion.write.d.ts +2 -2
- package/dist/user-data-rights/handlers/cancel-deletion.write.js +2 -1
- package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/lift-restriction.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/request-deletion.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/request-deletion.write.js +5 -7
- package/dist/user-data-rights/handlers/request-export.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/restrict-account.write.d.ts +1 -1
- package/dist/user-data-rights/handlers/run-forget-cleanup.write.d.ts +1 -1
- package/dist/user-data-rights/lib/default-mailers.d.ts +15 -7
- package/dist/user-data-rights/lib/default-mailers.js +100 -48
- package/dist/user-data-rights/lib/update-user-lifecycle.js +1 -1
- package/dist/user-data-rights/mail-notifications.d.ts +13 -0
- package/dist/user-data-rights/mail-notifications.js +118 -0
- package/dist/user-data-rights/web/privacy-center-screen.js +2 -1
- package/dist/user-profile/handlers/change-email.write.d.ts +1 -1
- package/dist/user-profile/web/profile-screen.js +2 -1
- package/dist/waitlist/feature.js +10 -0
- package/dist/waitlist/handlers/invite.write.d.ts +1 -1
- package/dist/waitlist/handlers/reject.write.d.ts +1 -1
- package/dist/waitlist/handlers/submit.write.d.ts +1 -1
- package/dist/waitlist/handlers/submit.write.js +3 -4
- package/dist/waitlist/mail.d.ts +19 -6
- package/dist/waitlist/mail.js +50 -14
- package/dist/waitlist/options.js +1 -1
- package/dist/workflow-runner/event-trigger.js +2 -2
- package/dist/workflow-runner/handlers/resume-run.write.js +7 -2
- package/package.json +37 -17
- package/src/admin-shell/changes.json +6 -0
- package/src/audit/changes.json +6 -0
- package/src/auth-email-password/changes.json +51 -0
- package/src/billing-foundation/changes.json +43 -0
- package/src/cap-counter/changes.json +6 -0
- package/src/channel-email/changes.json +19 -0
- package/src/config/changes.json +6 -0
- package/src/crypto-shredding/changes.json +6 -0
- package/src/custom-fields/changes.json +6 -0
- package/src/data-retention/changes.json +6 -0
- package/src/delivery/changes.json +66 -0
- package/src/file-foundation/changes.json +6 -0
- package/src/files-tenant-data/changes.json +6 -0
- package/src/inbound-mail-foundation/changes.json +6 -0
- package/src/jobs/changes.json +19 -0
- package/src/ledger/changes.json +7 -0
- package/src/managed-pages/changes.json +6 -0
- package/src/renderer-foundation/changes.json +39 -0
- package/src/renderer-pdf/changes.json +12 -0
- package/src/secrets/changes.json +6 -0
- package/src/shared/changes.json +6 -0
- package/src/subscription-stripe/changes.json +6 -0
- package/src/template-resolver/changes.json +186 -0
- package/src/tier-engine/changes.json +6 -0
- package/src/user/changes.json +6 -0
- package/src/user-data-rights/changes.json +13 -0
- package/src/user-profile/changes.json +1 -1
- package/src/waitlist/changes.json +7 -0
- package/src/workflow-runner/changes.json +6 -0
- package/dist/renderer-simple/feature.d.ts +0 -10
- package/dist/renderer-simple/feature.js +0 -42
- package/dist/renderer-simple/index.d.ts +0 -3
- package/dist/renderer-simple/index.js +0 -2
- package/dist/renderer-simple/mail-blocks.d.ts +0 -21
- package/dist/renderer-simple/mail-blocks.js +0 -107
- package/dist/renderer-simple/resolve-variables.d.ts +0 -7
- package/dist/renderer-simple/resolve-variables.js +0 -47
- package/dist/renderer-simple/simple-renderer.d.ts +0 -24
- package/dist/renderer-simple/simple-renderer.js +0 -200
- package/src/renderer-simple/changes.json +0 -27
|
@@ -12,6 +12,9 @@ export type CreateAdminShellOptions = {
|
|
|
12
12
|
* Requires cap-overview mounted. Default false — apps that don't mount cap-overview
|
|
13
13
|
* must not get a nav entry pointing at a screen that doesn't exist. */
|
|
14
14
|
readonly includeCapOverview?: boolean;
|
|
15
|
+
/** Tenant nav → document-designer:nav:templates, platform nav → document-designer:nav:platform-templates.
|
|
16
|
+
* Requires document-designer mounted (a separate package, so no import here). Default false. */
|
|
17
|
+
readonly includeDocumentDesigner?: boolean;
|
|
15
18
|
/** When false, only overview screens + nav are registered — app owns r.workspace(). Default true. */
|
|
16
19
|
readonly registerWorkspaces?: boolean;
|
|
17
20
|
/** Metric list the overview panels are built from — pass the SAME list to
|
|
@@ -11,10 +11,11 @@ export function createAdminShellFeature(options = {}) {
|
|
|
11
11
|
const platformWsId = options.workspaceIds?.platform ?? DEFAULT_PLATFORM_WORKSPACE_ID;
|
|
12
12
|
const includeTierAdmin = options.includeTierAdmin ?? true;
|
|
13
13
|
const includeCapOverview = options.includeCapOverview ?? false;
|
|
14
|
+
const includeDocumentDesigner = options.includeDocumentDesigner ?? false;
|
|
14
15
|
const registerWorkspaces = options.registerWorkspaces ?? true;
|
|
15
16
|
const metrics = options.metrics ?? DEFAULT_METRICS;
|
|
16
17
|
return defineFeature(ADMIN_SHELL_FEATURE, (r) => {
|
|
17
|
-
r.describe("Registers tenant-admin and platform-admin workspaces with provider nav into owner-feature screens (`tenant:screen:members`, `audit:screen:audit-log`, `tenant:screen:tenant-list`, `jobs:screen:job-runs`, optional `tier-engine:screen:tier-admin`, optional `cap-overview:screen:my-caps`/`cap-overview:screen:tenant-cap-list`) and the two overview dashboards, built from the metrics list (`metrics` option, default DEFAULT_METRICS). Mount after user, tenant, audit, jobs, metrics and metrics-system; pass `workspaceIds` to match app URL conventions (e.g. Studio `d`/`s`, PublicStatus `admin`/`sysadmin`). Client: `adminShellClient()`, `tenantClient()`, `auditClient()`, `jobsClient()`, optional `tierEngineClient()`.");
|
|
18
|
+
r.describe("Registers tenant-admin and platform-admin workspaces with provider nav into owner-feature screens (`tenant:screen:members`, `audit:screen:audit-log`, `tenant:screen:tenant-list`, `jobs:screen:job-runs`, optional `tier-engine:screen:tier-admin`, optional `cap-overview:screen:my-caps`/`cap-overview:screen:tenant-cap-list`, optional `document-designer` template navs) and the two overview dashboards, built from the metrics list (`metrics` option, default DEFAULT_METRICS). Mount after user, tenant, audit, jobs, metrics and metrics-system; pass `workspaceIds` to match app URL conventions (e.g. Studio `d`/`s`, PublicStatus `admin`/`sysadmin`). Client: `adminShellClient()`, `tenantClient()`, `auditClient()`, `jobsClient()`, optional `tierEngineClient()`.");
|
|
18
19
|
r.uiHints({
|
|
19
20
|
displayLabel: "Admin Shell",
|
|
20
21
|
category: "operations",
|
|
@@ -30,18 +31,22 @@ export function createAdminShellFeature(options = {}) {
|
|
|
30
31
|
r.requires("tier-engine");
|
|
31
32
|
if (includeCapOverview)
|
|
32
33
|
r.requires("cap-overview");
|
|
34
|
+
if (includeDocumentDesigner)
|
|
35
|
+
r.requires("document-designer");
|
|
33
36
|
r.translations({ keys: ADMIN_SHELL_I18N });
|
|
34
37
|
const tenantNav = [
|
|
35
38
|
"admin-shell:nav:tenant-overview",
|
|
36
39
|
"tenant:nav:members",
|
|
37
40
|
"audit:nav:audit-log",
|
|
38
41
|
...(includeCapOverview ? ["admin-shell:nav:my-caps"] : []),
|
|
42
|
+
...(includeDocumentDesigner ? ["document-designer:nav:templates"] : []),
|
|
39
43
|
];
|
|
40
44
|
const platformNav = [
|
|
41
45
|
"admin-shell:nav:platform-overview",
|
|
42
46
|
"admin-shell:nav:tenants",
|
|
43
47
|
...(includeCapOverview ? ["admin-shell:nav:tenant-caps"] : []),
|
|
44
48
|
"jobs:nav:job-runs",
|
|
49
|
+
...(includeDocumentDesigner ? ["document-designer:nav:platform-templates"] : []),
|
|
45
50
|
...(includeTierAdmin ? ["admin-shell:nav:tier-admin"] : []),
|
|
46
51
|
];
|
|
47
52
|
r.screen({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { hasAccess, isAgentVisibleScreen, resolveAgentExposure, SYSTEM_ONLY_JSON_SCHEMA_KEY, } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import { translationValueOtherText } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
3
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
3
4
|
import * as z from "zod";
|
|
4
5
|
import { recordManifestDenyQns } from "./manifest-deny-qns.js";
|
|
5
6
|
/** The manifest surfaces one string per locale — a plural entry reads as its
|
|
@@ -124,7 +125,7 @@ export function systemOnlyPropertyNames(jsonSchema) {
|
|
|
124
125
|
if (typeof properties !== "object" || properties === null)
|
|
125
126
|
return [];
|
|
126
127
|
return Object.entries(properties)
|
|
127
|
-
.filter(([, property]) => property[SYSTEM_ONLY_JSON_SCHEMA_KEY] === true)
|
|
128
|
+
.filter(([, property]) => isPlainObject(property) && property[SYSTEM_ONLY_JSON_SCHEMA_KEY] === true)
|
|
128
129
|
.map(([name]) => name);
|
|
129
130
|
}
|
|
130
131
|
function withoutSystemOnlyProperties(jsonSchema) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const FILTER_OPS: readonly ["eq", "ne", "lt", "gt", "lte", "gte", "in"];
|
|
2
|
-
export
|
|
2
|
+
export { isPlainObject as isRecord } from "@cosmicdrift/kumiko-types/type-guards";
|
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
export const FILTER_OPS = ["eq", "ne", "lt", "gt", "lte", "gte", "in"];
|
|
2
|
-
export
|
|
3
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
-
}
|
|
2
|
+
export { isPlainObject as isRecord } from "@cosmicdrift/kumiko-types/type-guards";
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { runAsDirectCallEntry } from "@cosmicdrift/kumiko-framework/internal/request-context";
|
|
2
|
+
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
3
|
import { FILTER_OPS, isRecord } from "./filter-ops.js";
|
|
3
4
|
const SEARCH_RESULT_LIMIT = 10;
|
|
4
5
|
const DEFAULT_LIST_LIMIT = 10;
|
|
5
6
|
const MAX_LIST_LIMIT = 200;
|
|
6
7
|
function isFilterOp(value) {
|
|
7
|
-
return
|
|
8
|
+
return isOneOf(FILTER_OPS, value);
|
|
8
9
|
}
|
|
9
10
|
function buildSearchPayload(toolName, toolInput) {
|
|
10
11
|
const query = toolInput["query"];
|
|
@@ -88,11 +88,15 @@ export const listQuery = defineQueryHandler({
|
|
|
88
88
|
aggregateType: scopeFilter.aggregateType ?? p.aggregateType,
|
|
89
89
|
}, direction);
|
|
90
90
|
const rows = await selectMany(ctx.db, eventsTable, where, {
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
// The id cursor only resumes an id-ordered listing. created_at comes from the
|
|
92
|
+
// transaction start and can run against insert order, so ordering by it would let
|
|
93
|
+
// a page boundary skip rows; only the type sort leaves id order (and is one page).
|
|
94
|
+
orderBy: p.sort === "type"
|
|
95
|
+
? [
|
|
96
|
+
{ col: "type", direction },
|
|
97
|
+
{ col: "id", direction },
|
|
98
|
+
]
|
|
99
|
+
: [{ col: "id", direction }],
|
|
96
100
|
limit: p.limit,
|
|
97
101
|
});
|
|
98
102
|
const serialised = rows.map((r) => ({
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { makeDispatchSystemWrite, type
|
|
1
|
+
import { makeDispatchSystemWrite, type RoleDispatchArgs } from "@cosmicdrift/kumiko-framework/api";
|
|
2
2
|
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
3
|
-
import { type TenantId, type WriteResult } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
+
import { type Registry, type TenantId, type WriteResult } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
4
|
import type { Dispatcher } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
5
|
+
import type { EnvelopeCipher } from "@cosmicdrift/kumiko-framework/secrets";
|
|
5
6
|
import type { Redis } from "ioredis";
|
|
6
7
|
import type { GLOBAL_ROLE_OPTIONS } from "../user/constants.js";
|
|
7
8
|
type GlobalRole = (typeof GLOBAL_ROLE_OPTIONS)[number];
|
|
@@ -18,9 +19,7 @@ export type BootstrapSeedDeps = {
|
|
|
18
19
|
/** Writes as the system user with the given tenant roles in the seeded
|
|
19
20
|
* tenant; use it when the app gates tenant data on its own roles rather
|
|
20
21
|
* than SystemAdmin. */
|
|
21
|
-
readonly dispatchWriteAs: (args:
|
|
22
|
-
readonly roles: readonly string[];
|
|
23
|
-
}) => Promise<WriteResult>;
|
|
22
|
+
readonly dispatchWriteAs: (args: Omit<RoleDispatchArgs, "tenantId">) => Promise<WriteResult>;
|
|
24
23
|
};
|
|
25
24
|
export type BootstrapConfigValue = string | number | boolean;
|
|
26
25
|
export type BootstrapTenant = {
|
|
@@ -54,6 +53,10 @@ export type BootstrapDeps = {
|
|
|
54
53
|
readonly db: DbConnection;
|
|
55
54
|
readonly redis: Redis;
|
|
56
55
|
readonly dispatcher: Dispatcher;
|
|
56
|
+
/** With these, a rerun can compare `encrypted`/`piiEncrypted` config keys by
|
|
57
|
+
* their decrypted value; without them such keys are rewritten on every run. */
|
|
58
|
+
readonly registry?: Registry;
|
|
59
|
+
readonly configCipher?: EnvelopeCipher;
|
|
57
60
|
};
|
|
58
61
|
export type BootstrapTenantOutcome = "created" | "exists";
|
|
59
62
|
export type BootstrapInviteOutcome = "invited" | "resent" | "pending" | "active" | "cancelled" | "role-mismatch";
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
// exactly as for any other writer. Nobody gets a role before accepting: the
|
|
5
5
|
// invitation row holds membership role + global roles until the invitee
|
|
6
6
|
// accepts through the regular invite-accept routes.
|
|
7
|
-
import { makeDispatchSystemWrite, } from "@cosmicdrift/kumiko-framework/api";
|
|
7
|
+
import { makeDispatchSystemWrite, makeDispatchWriteAs, } from "@cosmicdrift/kumiko-framework/api";
|
|
8
8
|
import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
9
9
|
import { ConfigScopes, createSystemUser, } from "@cosmicdrift/kumiko-framework/engine";
|
|
10
10
|
import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
|
|
11
11
|
// kumiko-lint-ignore cross-feature-import bootstrap sets per-tenant config through the config feature's write handler
|
|
12
12
|
import { ConfigHandlers } from "../config/constants.js";
|
|
13
13
|
// kumiko-lint-ignore cross-feature-import bootstrap compares against the stored config row to stay idempotent
|
|
14
|
-
import { findConfigRow } from "../config/write-helpers.js";
|
|
14
|
+
import { configRowHoldsValue, findConfigRow } from "../config/write-helpers.js";
|
|
15
15
|
// kumiko-lint-ignore cross-feature-import bootstrap provisions tenant + invitation rows owned by the tenant feature
|
|
16
16
|
import { TenantHandlers } from "../tenant/constants.js";
|
|
17
17
|
// kumiko-lint-ignore cross-feature-import bootstrap provisions tenant + invitation rows owned by the tenant feature
|
|
@@ -78,8 +78,10 @@ async function applyTenantConfig(deps, tenant) {
|
|
|
78
78
|
const applied = [];
|
|
79
79
|
for (const [key, value] of Object.entries(tenant.config ?? {})) {
|
|
80
80
|
const existing = await findConfigRow(deps.db, key, tenant.id, null);
|
|
81
|
-
|
|
81
|
+
const serialized = JSON.stringify(value);
|
|
82
|
+
if (await configRowHoldsValue(existing, deps.registry?.getConfigKey(key), deps.configCipher, key, serialized)) {
|
|
82
83
|
continue;
|
|
84
|
+
}
|
|
83
85
|
const result = await deps.dispatcher.write(ConfigHandlers.set, { key, value, scope: ConfigScopes.tenant },
|
|
84
86
|
// SystemAdmin on top of the system role: keys with the default tenant
|
|
85
87
|
// write access (admin roles) reject a bare system user, system-only keys
|
|
@@ -125,6 +127,11 @@ async function decideInvite(deps, invite) {
|
|
|
125
127
|
}
|
|
126
128
|
if (invitation.status === INVITATION_STATUS.accepted)
|
|
127
129
|
return "active";
|
|
130
|
+
// The plan dropped a global role (e.g. an admin moved to tenants[].invites):
|
|
131
|
+
// the stored invitation would still grant it on accept, so it is re-issued.
|
|
132
|
+
if (storedGlobalRoles.some((role) => !invite.globalRoles.some((planned) => planned === role))) {
|
|
133
|
+
return "resent";
|
|
134
|
+
}
|
|
128
135
|
if (await hasLiveInviteToken(deps.redis, invitation.id))
|
|
129
136
|
return "pending";
|
|
130
137
|
return "resent";
|
|
@@ -135,6 +142,7 @@ function isMailingOutcome(outcome) {
|
|
|
135
142
|
export async function bootstrapTenants(deps, plan) {
|
|
136
143
|
const plannedInvites = planInvites(plan);
|
|
137
144
|
const dispatchSystemWrite = makeDispatchSystemWrite(deps.dispatcher);
|
|
145
|
+
const dispatchWriteAsRoles = makeDispatchWriteAs(deps.dispatcher);
|
|
138
146
|
const tenants = [];
|
|
139
147
|
for (const tenant of plan.tenants) {
|
|
140
148
|
const outcome = await ensureTenant(deps, tenant);
|
|
@@ -144,7 +152,7 @@ export async function bootstrapTenants(deps, plan) {
|
|
|
144
152
|
tenantId: tenant.id,
|
|
145
153
|
db: deps.db,
|
|
146
154
|
dispatchSystemWrite,
|
|
147
|
-
dispatchWriteAs: (
|
|
155
|
+
dispatchWriteAs: (args) => dispatchWriteAsRoles({ ...args, tenantId: tenant.id }),
|
|
148
156
|
});
|
|
149
157
|
}
|
|
150
158
|
const configApplied = await applyTenantConfig(deps, tenant);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PayloadRateLimitOption } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
export declare const AUTH_EMAIL_RATE_LIMIT_WINDOW_SECONDS: number;
|
|
3
|
+
export declare const AUTH_EMAIL_RATE_LIMIT_MAX_REQUESTS = 3;
|
|
4
|
+
export declare const AUTH_EMAIL_PAYLOAD_RATE_LIMITS: readonly PayloadRateLimitOption[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// The bucket counts across all IPs, so a long window would let an attacker who
|
|
2
|
+
// knows an address lock its owner out of recovery/signup for the whole window.
|
|
3
|
+
// A short one still throttles mail bombing but clears within minutes.
|
|
4
|
+
export const AUTH_EMAIL_RATE_LIMIT_WINDOW_SECONDS = 15 * 60;
|
|
5
|
+
export const AUTH_EMAIL_RATE_LIMIT_MAX_REQUESTS = 3;
|
|
6
|
+
export const AUTH_EMAIL_PAYLOAD_RATE_LIMITS = [
|
|
7
|
+
{
|
|
8
|
+
per: { payloadField: "email" },
|
|
9
|
+
limit: AUTH_EMAIL_RATE_LIMIT_MAX_REQUESTS,
|
|
10
|
+
windowSeconds: AUTH_EMAIL_RATE_LIMIT_WINDOW_SECONDS,
|
|
11
|
+
normalize: "email",
|
|
12
|
+
},
|
|
13
|
+
];
|
|
@@ -1,35 +1,13 @@
|
|
|
1
1
|
export type AuthMailLocale = string;
|
|
2
2
|
export declare const AUTH_MAIL_EN: Readonly<Record<string, string>>;
|
|
3
|
-
export type
|
|
4
|
-
readonly url: string;
|
|
3
|
+
export type TokenMailTiming = {
|
|
5
4
|
readonly expiresAt: string;
|
|
6
|
-
readonly locale?: AuthMailLocale;
|
|
7
|
-
/** Optional app name for subject + intro. Default from auth.mail.appNameDefault. */
|
|
8
|
-
readonly appName?: string;
|
|
9
5
|
/** ISO instant the token was issued; the validity duration is measured from it. Default: now. */
|
|
10
6
|
readonly issuedAt?: string;
|
|
11
7
|
/** IANA zone the expiry time is shown in. Default "UTC"; an invalid zone falls back to "UTC". */
|
|
12
8
|
readonly timeZone?: string;
|
|
13
9
|
};
|
|
14
|
-
export
|
|
15
|
-
readonly
|
|
10
|
+
export declare function tokenMailExpiry(args: TokenMailTiming, locale: string): {
|
|
11
|
+
readonly validFor: string;
|
|
12
|
+
readonly validUntil: string;
|
|
16
13
|
};
|
|
17
|
-
export type AuthMailSection = {
|
|
18
|
-
readonly text: string;
|
|
19
|
-
} | {
|
|
20
|
-
readonly button: {
|
|
21
|
-
readonly label: string;
|
|
22
|
-
readonly url: string;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
export type AuthMailContent = {
|
|
26
|
-
readonly subject: string;
|
|
27
|
-
readonly header: string;
|
|
28
|
-
readonly sections: readonly AuthMailSection[];
|
|
29
|
-
readonly footer: string;
|
|
30
|
-
};
|
|
31
|
-
export declare function renderResetPasswordEmail(args: RenderTokenContentArgs): AuthMailContent;
|
|
32
|
-
export declare function renderUnlockAccountEmail(args: RenderTokenContentArgs): AuthMailContent;
|
|
33
|
-
export declare function renderVerifyEmail(args: RenderTokenContentArgs): AuthMailContent;
|
|
34
|
-
export declare function renderActivationEmail(args: RenderTokenContentArgs): AuthMailContent;
|
|
35
|
-
export declare function renderInviteEmail(args: RenderInviteEmailArgs): AuthMailContent;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// renderer-simple turns it into HTML. Apps wanting their own branding swap the
|
|
5
|
-
// renderer; these templates are deliberately plain so the renderer (and the
|
|
6
|
-
// operator reading the mailer log) can rely on them.
|
|
1
|
+
// English texts and expiry formatting for the transactional auth mails. The
|
|
2
|
+
// mail bodies are built from these keys into stored templates (see
|
|
3
|
+
// mail-notifications.ts).
|
|
7
4
|
//
|
|
8
5
|
// English ships here. Other languages register via @cosmicdrift/kumiko-locale-*
|
|
9
6
|
// (localeDe() / localeEs() call registerMailTranslations).
|
|
10
|
-
import {
|
|
7
|
+
import { registerMailTranslations } from "@cosmicdrift/kumiko-framework/i18n";
|
|
11
8
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
12
9
|
export const AUTH_MAIL_EN = {
|
|
13
10
|
"auth.mail.appNameDefault": "Account",
|
|
@@ -43,96 +40,6 @@ export const AUTH_MAIL_EN = {
|
|
|
43
40
|
"auth.mail.unlock.ignore": "If you didn't trigger this lock, you can ignore this email — the lock expires on its own.",
|
|
44
41
|
};
|
|
45
42
|
registerMailTranslations("en", AUTH_MAIL_EN);
|
|
46
|
-
function tokenMailContent(spec) {
|
|
47
|
-
return {
|
|
48
|
-
subject: spec.subject,
|
|
49
|
-
header: spec.header,
|
|
50
|
-
sections: [
|
|
51
|
-
{ text: spec.greeting },
|
|
52
|
-
{ text: spec.intro },
|
|
53
|
-
{ button: { label: spec.buttonLabel, url: spec.buttonUrl } },
|
|
54
|
-
{ text: spec.expiry },
|
|
55
|
-
],
|
|
56
|
-
footer: spec.ignore,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
function t(locale, key, params) {
|
|
60
|
-
return mailT(locale, key, params);
|
|
61
|
-
}
|
|
62
|
-
function appNameFor(args) {
|
|
63
|
-
const locale = args.locale ?? "en";
|
|
64
|
-
return args.appName ?? t(locale, "auth.mail.appNameDefault");
|
|
65
|
-
}
|
|
66
|
-
export function renderResetPasswordEmail(args) {
|
|
67
|
-
const locale = args.locale ?? "en";
|
|
68
|
-
const app = appNameFor(args);
|
|
69
|
-
return tokenMailContent({
|
|
70
|
-
subject: t(locale, "auth.mail.reset.subject", { app }),
|
|
71
|
-
header: t(locale, "auth.mail.reset.button"),
|
|
72
|
-
greeting: t(locale, "auth.mail.reset.greeting"),
|
|
73
|
-
intro: t(locale, "auth.mail.reset.intro", { app }),
|
|
74
|
-
buttonLabel: t(locale, "auth.mail.reset.button"),
|
|
75
|
-
buttonUrl: args.url,
|
|
76
|
-
expiry: t(locale, "auth.mail.reset.expiry", expiryParams(args, locale)),
|
|
77
|
-
ignore: t(locale, "auth.mail.reset.ignore"),
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
export function renderUnlockAccountEmail(args) {
|
|
81
|
-
const locale = args.locale ?? "en";
|
|
82
|
-
const app = appNameFor(args);
|
|
83
|
-
return tokenMailContent({
|
|
84
|
-
subject: t(locale, "auth.mail.unlock.subject", { app }),
|
|
85
|
-
header: t(locale, "auth.mail.unlock.button"),
|
|
86
|
-
greeting: t(locale, "auth.mail.unlock.greeting"),
|
|
87
|
-
intro: t(locale, "auth.mail.unlock.intro", { app }),
|
|
88
|
-
buttonLabel: t(locale, "auth.mail.unlock.button"),
|
|
89
|
-
buttonUrl: args.url,
|
|
90
|
-
expiry: t(locale, "auth.mail.unlock.expiry", expiryParams(args, locale)),
|
|
91
|
-
ignore: t(locale, "auth.mail.unlock.ignore"),
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
export function renderVerifyEmail(args) {
|
|
95
|
-
const locale = args.locale ?? "en";
|
|
96
|
-
const app = appNameFor(args);
|
|
97
|
-
return tokenMailContent({
|
|
98
|
-
subject: t(locale, "auth.mail.verify.subject", { app }),
|
|
99
|
-
header: t(locale, "auth.mail.verify.button"),
|
|
100
|
-
greeting: t(locale, "auth.mail.verify.greeting"),
|
|
101
|
-
intro: t(locale, "auth.mail.verify.intro", { app }),
|
|
102
|
-
buttonLabel: t(locale, "auth.mail.verify.button"),
|
|
103
|
-
buttonUrl: args.url,
|
|
104
|
-
expiry: t(locale, "auth.mail.verify.expiry", expiryParams(args, locale)),
|
|
105
|
-
ignore: t(locale, "auth.mail.verify.ignore"),
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
export function renderActivationEmail(args) {
|
|
109
|
-
const locale = args.locale ?? "en";
|
|
110
|
-
const app = appNameFor(args);
|
|
111
|
-
return tokenMailContent({
|
|
112
|
-
subject: t(locale, "auth.mail.activation.subject", { app }),
|
|
113
|
-
header: t(locale, "auth.mail.activation.button"),
|
|
114
|
-
greeting: t(locale, "auth.mail.activation.greeting"),
|
|
115
|
-
intro: t(locale, "auth.mail.activation.intro", { app }),
|
|
116
|
-
buttonLabel: t(locale, "auth.mail.activation.button"),
|
|
117
|
-
buttonUrl: args.url,
|
|
118
|
-
expiry: t(locale, "auth.mail.activation.expiry", expiryParams(args, locale)),
|
|
119
|
-
ignore: t(locale, "auth.mail.activation.ignore"),
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
export function renderInviteEmail(args) {
|
|
123
|
-
const locale = args.locale ?? "en";
|
|
124
|
-
const app = args.appName ?? "Workspace";
|
|
125
|
-
return tokenMailContent({
|
|
126
|
-
subject: t(locale, "auth.mail.invite.subject", { app }),
|
|
127
|
-
header: t(locale, "auth.mail.invite.button"),
|
|
128
|
-
greeting: t(locale, "auth.mail.invite.greeting"),
|
|
129
|
-
intro: t(locale, "auth.mail.invite.intro", { app, role: args.role }),
|
|
130
|
-
buttonLabel: t(locale, "auth.mail.invite.button"),
|
|
131
|
-
buttonUrl: args.url,
|
|
132
|
-
expiry: t(locale, "auth.mail.invite.expiry", expiryParams(args, locale)),
|
|
133
|
-
ignore: t(locale, "auth.mail.invite.ignore"),
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
43
|
const MS_PER_MINUTE = 60_000;
|
|
137
44
|
const MS_PER_HOUR = 60 * MS_PER_MINUTE;
|
|
138
45
|
const MS_PER_DAY = 24 * MS_PER_HOUR;
|
|
@@ -185,16 +92,17 @@ function formatWhen(expiresAt, locale, timeZone) {
|
|
|
185
92
|
}
|
|
186
93
|
}
|
|
187
94
|
}
|
|
188
|
-
|
|
95
|
+
// Formatted as text here because the stored template only knows plain variables.
|
|
96
|
+
export function tokenMailExpiry(args, locale) {
|
|
189
97
|
try {
|
|
190
98
|
const expiresAt = Temporal.Instant.from(args.expiresAt);
|
|
191
99
|
const issuedAt = args.issuedAt ? Temporal.Instant.from(args.issuedAt) : Temporal.Now.instant();
|
|
192
100
|
return {
|
|
193
|
-
|
|
194
|
-
|
|
101
|
+
validFor: formatDuration(expiresAt.epochMilliseconds - issuedAt.epochMilliseconds, locale),
|
|
102
|
+
validUntil: formatWhen(expiresAt, locale, args.timeZone ?? "UTC"),
|
|
195
103
|
};
|
|
196
104
|
}
|
|
197
105
|
catch {
|
|
198
|
-
return {
|
|
106
|
+
return { validFor: args.expiresAt, validUntil: args.expiresAt };
|
|
199
107
|
}
|
|
200
108
|
}
|
|
@@ -19,6 +19,7 @@ import { createSignupConfirmHandler } from "./handlers/signup-confirm.write.js";
|
|
|
19
19
|
import { createSignupRequestHandler, } from "./handlers/signup-request.write.js";
|
|
20
20
|
import { createSwitchTenantMfaGateHandler } from "./handlers/switch-tenant-mfa-gate.write.js";
|
|
21
21
|
import { createVerifyEmailHandler } from "./handlers/verify-email.write.js";
|
|
22
|
+
import { AUTH_MAIL_VARIABLES, authMailLocalizedTemplate, INVITE_MAIL_VARIABLES, sendsMagicLinkMail, } from "./mail-notifications.js";
|
|
22
23
|
/**
|
|
23
24
|
* Env-vars contract for the `auth-email-password` feature.
|
|
24
25
|
*
|
|
@@ -85,14 +86,31 @@ export function createAuthEmailPasswordFeature(opts = {}) {
|
|
|
85
86
|
// All five magic-link flows (reset/verify/signup/invite/unlock) dispatch
|
|
86
87
|
// via ctx.notify → delivery must be mounted. Fail closed at boot instead
|
|
87
88
|
// of silently dropping the mail.
|
|
88
|
-
if (opts
|
|
89
|
-
opts.emailVerification ||
|
|
90
|
-
opts.signup ||
|
|
91
|
-
opts.invite ||
|
|
92
|
-
opts.accountUnlock) {
|
|
89
|
+
if (sendsMagicLinkMail(opts))
|
|
93
90
|
r.requires("delivery");
|
|
94
|
-
}
|
|
95
91
|
r.envSchema(authEmailPasswordEnvSchema);
|
|
92
|
+
// Declared unconditionally: apps also issue the activation link from their
|
|
93
|
+
// own flows (issueSignupActivation) without enabling the signup option.
|
|
94
|
+
r.notification("password-reset", {
|
|
95
|
+
variables: AUTH_MAIL_VARIABLES,
|
|
96
|
+
localizedTemplate: authMailLocalizedTemplate("passwordReset"),
|
|
97
|
+
});
|
|
98
|
+
r.notification("account-unlock", {
|
|
99
|
+
variables: AUTH_MAIL_VARIABLES,
|
|
100
|
+
localizedTemplate: authMailLocalizedTemplate("accountUnlock"),
|
|
101
|
+
});
|
|
102
|
+
r.notification("email-verification", {
|
|
103
|
+
variables: AUTH_MAIL_VARIABLES,
|
|
104
|
+
localizedTemplate: authMailLocalizedTemplate("emailVerification"),
|
|
105
|
+
});
|
|
106
|
+
r.notification("signup-activation", {
|
|
107
|
+
variables: AUTH_MAIL_VARIABLES,
|
|
108
|
+
localizedTemplate: authMailLocalizedTemplate("signupActivation"),
|
|
109
|
+
});
|
|
110
|
+
r.notification("invite", {
|
|
111
|
+
variables: INVITE_MAIL_VARIABLES,
|
|
112
|
+
localizedTemplate: authMailLocalizedTemplate("invite"),
|
|
113
|
+
});
|
|
96
114
|
const handlers = {
|
|
97
115
|
login: r.writeHandler(createLoginHandler({
|
|
98
116
|
strictEmailVerification: strictVerification,
|
|
@@ -4,4 +4,4 @@ export declare const changePasswordWrite: import("@cosmicdrift/kumiko-types/defi
|
|
|
4
4
|
newPassword: z.ZodString;
|
|
5
5
|
}, z.core.$strip>, {
|
|
6
6
|
kind: string;
|
|
7
|
-
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
7
|
+
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createSystemUser, defineWriteHandler, SYSTEM_TENANT_ID, } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { hashPassword, verifyPassword } from "../../shared/index.js";
|
|
4
4
|
import { UserHandlers, UserQueries } from "../../user/index.js";
|
|
@@ -14,7 +14,11 @@ export const changePasswordWrite = defineWriteHandler({
|
|
|
14
14
|
oldPassword: z.string().min(1),
|
|
15
15
|
newPassword: passwordSchema,
|
|
16
16
|
}),
|
|
17
|
-
access: {
|
|
17
|
+
access: {
|
|
18
|
+
openToAll: {
|
|
19
|
+
reason: "Self-service: acts only on event.user.id and re-checks the caller's current password; invited members hold only an app role, so a fixed role list would lock them out.",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
18
22
|
escapeHatch: {
|
|
19
23
|
grants: ["systemIdentity"],
|
|
20
24
|
reason: "Reads the caller's own passwordHash (privileged-only field) via ctx.queryAs(SYSTEM, ...) " +
|
|
@@ -6,4 +6,4 @@ export declare function createConfirmAccountUnlockHandler(opts: ConfirmAccountUn
|
|
|
6
6
|
token: z.ZodString;
|
|
7
7
|
}, z.core.$strip>, {
|
|
8
8
|
kind: "account-unlocked";
|
|
9
|
-
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
9
|
+
}, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -18,4 +18,4 @@ export declare function createInviteAcceptWithLoginHandler(opts?: InviteAcceptWi
|
|
|
18
18
|
token: z.ZodString;
|
|
19
19
|
email: z.ZodEmail;
|
|
20
20
|
password: z.ZodString;
|
|
21
|
-
}, z.core.$strip>, InviteAcceptWithLoginData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
21
|
+
}, z.core.$strip>, InviteAcceptWithLoginData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -8,4 +8,4 @@ export type InviteAcceptData = {
|
|
|
8
8
|
};
|
|
9
9
|
export declare function createInviteAcceptHandler(): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"invite-accept", z.ZodObject<{
|
|
10
10
|
token: z.ZodString;
|
|
11
|
-
}, z.core.$strip>, InviteAcceptData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
11
|
+
}, z.core.$strip>, InviteAcceptData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -33,12 +33,12 @@ export type InviteCreateOptions = {
|
|
|
33
33
|
export declare function createInviteCreateHandler(opts: InviteCreateOptions): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"invite-create", z.ZodObject<{
|
|
34
34
|
email: z.ZodEmail;
|
|
35
35
|
role: z.ZodString;
|
|
36
|
-
}, z.core.$strip>, InviteCreateData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
36
|
+
}, z.core.$strip>, InviteCreateData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
37
37
|
export declare function createSystemInviteCreateHandler(opts: InviteCreateOptions): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"system-invite-create", z.ZodObject<{
|
|
38
38
|
email: z.ZodEmail;
|
|
39
39
|
role: z.ZodString;
|
|
40
40
|
globalRoles: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
41
41
|
SystemAdmin: "SystemAdmin";
|
|
42
42
|
}>>>;
|
|
43
|
-
}, z.core.$strip>, InviteCreateData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
43
|
+
}, z.core.$strip>, InviteCreateData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
44
44
|
export {};
|
|
@@ -33,11 +33,10 @@ import { GLOBAL_ROLE_OPTIONS } from "../../user/constants.js";
|
|
|
33
33
|
// kumiko-lint-ignore cross-feature-import invitee lookup by email reads the user row
|
|
34
34
|
import { userTable } from "../../user/schema/user.js";
|
|
35
35
|
import { AUTH_INVITE_DEFAULT_TTL_MINUTES } from "../constants.js";
|
|
36
|
-
import { renderInviteEmail } from "../email-templates.js";
|
|
37
36
|
import { inviteAlreadyAccepted } from "../errors.js";
|
|
38
37
|
import { invalidateExistingInviteToken, storeInviteToken } from "../invite-token-store.js";
|
|
39
38
|
import { dispatchMagicLinkMail, resolveHandlerMailLocale } from "../magic-link-mail.js";
|
|
40
|
-
|
|
39
|
+
import { AuthMailNotificationTypes } from "../mail-notifications.js";
|
|
41
40
|
const InviteCreateSchema = z.object({
|
|
42
41
|
email: z.email(),
|
|
43
42
|
role: z.string().min(1).max(50),
|
|
@@ -137,8 +136,8 @@ async function issueInvitation(opts, ttlSeconds, request, inviter, ctx, refuseAc
|
|
|
137
136
|
const locale = resolveHandlerMailLocale(ctx, opts.locale);
|
|
138
137
|
await dispatchMagicLinkMail(ctx.notify, {
|
|
139
138
|
handlerName: "invite-create",
|
|
140
|
-
notificationType:
|
|
141
|
-
|
|
139
|
+
notificationType: AuthMailNotificationTypes.invite,
|
|
140
|
+
fallbackAppName: "Workspace",
|
|
142
141
|
}, {
|
|
143
142
|
email,
|
|
144
143
|
appUrl: opts.appUrl,
|
|
@@ -146,6 +145,7 @@ async function issueInvitation(opts, ttlSeconds, request, inviter, ctx, refuseAc
|
|
|
146
145
|
expiresAt: expiresAt.toString(),
|
|
147
146
|
issuedAt: issuedAt.toString(),
|
|
148
147
|
timeZone: ctx.tz.user,
|
|
148
|
+
role: request.role,
|
|
149
149
|
...(opts.appName !== undefined && { appName: opts.appName }),
|
|
150
150
|
locale,
|
|
151
151
|
});
|
|
@@ -13,4 +13,4 @@ export type InviteSignupCompleteOptions = Pick<LoginHandlerOptions, "mfaStatusCh
|
|
|
13
13
|
export declare function createInviteSignupCompleteHandler(opts?: InviteSignupCompleteOptions): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"invite-signup-complete", z.ZodObject<{
|
|
14
14
|
token: z.ZodString;
|
|
15
15
|
password: z.ZodString;
|
|
16
|
-
}, z.core.$strip>, InviteSignupCompleteData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
16
|
+
}, z.core.$strip>, InviteSignupCompleteData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -74,5 +74,5 @@ export declare function gateBuildSession(ctx: HandlerContext, userId: string, te
|
|
|
74
74
|
export declare function createLoginHandler(opts?: LoginHandlerOptions): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"login", z.ZodObject<{
|
|
75
75
|
email: z.ZodEmail;
|
|
76
76
|
password: z.ZodString;
|
|
77
|
-
}, z.core.$strip>, LoginResult, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
77
|
+
}, z.core.$strip>, LoginResult, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
78
78
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
-
export declare const logoutWrite: import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"logout", z.ZodObject<{}, z.core.$strip>, unknown, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
2
|
+
export declare const logoutWrite: import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"logout", z.ZodObject<{}, z.core.$strip>, unknown, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineWriteHandler, stepsPipeline } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
// Logout — JWT is stateless, so server-side we only return OK. A future
|
|
4
4
|
// revocation list / session table can land here without changing the
|
|
@@ -6,7 +6,11 @@ import * as z from "zod";
|
|
|
6
6
|
export const logoutWrite = defineWriteHandler({
|
|
7
7
|
name: "logout",
|
|
8
8
|
schema: z.object({}),
|
|
9
|
-
access: {
|
|
9
|
+
access: {
|
|
10
|
+
openToAll: {
|
|
11
|
+
reason: "Self-service: touches no data, any signed-in member must be able to sign out regardless of which role they hold.",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
10
14
|
description: "Acknowledges a sign-out for the authenticated caller so the client can discard its token; the JWT is stateless, so no server-side session state changes here.",
|
|
11
15
|
perform: stepsPipeline(({ r }) => [
|
|
12
16
|
r.step.return({ isSuccess: true, data: { kind: "logged-out" } }),
|
|
@@ -3,4 +3,4 @@ export type RequestAccountUnlockOptions = TokenRequestOptions;
|
|
|
3
3
|
export type RequestUnlockData = TokenRequestData<"unlock-requested">;
|
|
4
4
|
export declare function createRequestAccountUnlockHandler(opts: RequestAccountUnlockOptions): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"request-account-unlock", import("zod").ZodObject<{
|
|
5
5
|
email: import("zod").ZodEmail;
|
|
6
|
-
}, import("zod/v4/core").$strip>, TokenRequestData<"unlock-requested">, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
6
|
+
}, import("zod/v4/core").$strip>, TokenRequestData<"unlock-requested">, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { AUTH_UNLOCK_DEFAULT_TTL_MINUTES, AuthErrors } from "../constants.js";
|
|
2
|
-
import {
|
|
2
|
+
import { AuthMailNotificationTypes } from "../mail-notifications.js";
|
|
3
3
|
import { signUnlockToken } from "../unlock-token.js";
|
|
4
4
|
import { createTokenRequestHandler, } from "./token-request-handler.js";
|
|
5
|
-
const UNLOCK_NOTIFICATION_TYPE = "auth-email-password:account-unlock";
|
|
6
5
|
// @wrapper-known semantic-alias
|
|
7
6
|
export function createRequestAccountUnlockHandler(opts) {
|
|
8
7
|
return createTokenRequestHandler({
|
|
@@ -18,7 +17,6 @@ export function createRequestAccountUnlockHandler(opts) {
|
|
|
18
17
|
// locked right now. Confirming just clears the (possibly already
|
|
19
18
|
// empty) lockout state — harmless no-op if they weren't locked.
|
|
20
19
|
extraSilentSkip: () => false,
|
|
21
|
-
notificationType:
|
|
22
|
-
renderContent: renderUnlockAccountEmail,
|
|
20
|
+
notificationType: AuthMailNotificationTypes.accountUnlock,
|
|
23
21
|
}, opts);
|
|
24
22
|
}
|
|
@@ -3,4 +3,4 @@ export type RequestEmailVerificationOptions = TokenRequestOptions;
|
|
|
3
3
|
export type RequestVerificationData = TokenRequestData<"verification-requested">;
|
|
4
4
|
export declare function createRequestEmailVerificationHandler(opts: RequestEmailVerificationOptions): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"request-email-verification", import("zod").ZodObject<{
|
|
5
5
|
email: import("zod").ZodEmail;
|
|
6
|
-
}, import("zod/v4/core").$strip>, TokenRequestData<"verification-requested">, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
6
|
+
}, import("zod/v4/core").$strip>, TokenRequestData<"verification-requested">, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|