@cosmicdrift/kumiko-bundled-features 0.352.0 → 0.354.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/agent-tools/agent-doc-lint.d.ts +2 -0
- package/dist/agent-tools/agent-doc-lint.js +61 -1
- package/dist/agent-tools/agent-manifest.d.ts +1 -0
- package/dist/agent-tools/agent-manifest.js +17 -5
- package/dist/agent-tools/feature.js +7 -2
- package/dist/agent-tools/index.d.ts +1 -1
- package/dist/agent-tools/index.js +1 -1
- package/dist/agent-tools/manifest-deny-qns.d.ts +3 -0
- package/dist/agent-tools/manifest-deny-qns.js +17 -0
- package/dist/agent-tools/tool-catalog.d.ts +2 -1
- package/dist/agent-tools/tool-catalog.js +4 -1
- package/dist/agent-tools/tool-dispatch.js +1 -1
- package/dist/audit/handlers/list.query.js +13 -8
- package/dist/auth-email-password/handlers/change-password.write.js +1 -0
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +2 -2
- package/dist/auth-email-password/handlers/invite-accept.write.js +2 -2
- package/dist/auth-email-password/handlers/invite-create.write.js +17 -0
- package/dist/auth-email-password/handlers/invite-signup-complete.write.js +4 -1
- package/dist/auth-email-password/handlers/login.write.js +1 -0
- package/dist/auth-email-password/handlers/reset-password.write.js +1 -0
- package/dist/auth-email-password/handlers/signup-confirm.write.js +6 -4
- package/dist/auth-email-password/handlers/signup-request.write.js +51 -77
- package/dist/auth-email-password/handlers/token-request-handler.js +1 -0
- package/dist/auth-email-password/handlers/verify-email.write.js +1 -0
- package/dist/auth-email-password/index.d.ts +2 -0
- package/dist/auth-email-password/index.js +2 -0
- package/dist/auth-email-password/seeding.d.ts +2 -0
- package/dist/auth-email-password/seeding.js +30 -8
- package/dist/auth-email-password/signup-activation.d.ts +24 -0
- package/dist/auth-email-password/signup-activation.js +41 -0
- package/dist/auth-email-password/signup-token-store.d.ts +5 -0
- package/dist/auth-email-password/signup-token-store.js +8 -3
- package/dist/auth-email-password/web/auth-gate.d.ts +2 -2
- package/dist/auth-email-password/web/auth-gate.js +5 -5
- package/dist/auth-email-password/web/auth-redirect.d.ts +1 -0
- package/dist/auth-email-password/web/auth-redirect.js +14 -0
- package/dist/auth-email-password/web/login-screen.js +2 -2
- package/dist/auth-email-password/web/user-menu.js +1 -1
- package/dist/auth-mfa/feature.js +5 -0
- package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +1 -0
- package/dist/auth-mfa/handlers/verify.write.js +1 -0
- package/dist/auth-mfa/schema/user-mfa.d.ts +6 -0
- package/dist/auth-mfa/screens.js +2 -2
- package/dist/auth-mfa/web/mfa-recovery-codes-reveal.js +1 -1
- package/dist/auth-mfa/web/mfa-setup-preauth-screen.d.ts +1 -1
- package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +3 -3
- package/dist/auth-mfa/web/mfa-verify-screen.d.ts +1 -1
- package/dist/auth-mfa/web/mfa-verify-screen.js +1 -1
- package/dist/billing-foundation/billing-info-query.d.ts +5 -2
- package/dist/billing-foundation/checkout-core.d.ts +7 -0
- package/dist/billing-foundation/checkout-core.js +7 -2
- package/dist/billing-foundation/entities.d.ts +8 -0
- package/dist/billing-foundation/handlers/start-plan-checkout.write.js +7 -1
- package/dist/billing-foundation/projection.d.ts +8 -0
- package/dist/cap-counter/entity.d.ts +1 -0
- package/dist/cap-overview/access.js +2 -9
- package/dist/cap-overview/handlers/tenant-caps-list.query.js +2 -2
- package/dist/cap-overview/handlers/tenant-options.query.js +4 -5
- package/dist/channel-in-app/in-app-channel.js +1 -1
- package/dist/channel-in-app/tables.js +4 -2
- package/dist/compliance-profiles/schema/profile-selection.d.ts +10 -8
- package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +2 -4
- package/dist/config/handlers/values.query.d.ts +3 -1
- package/dist/config/handlers/values.query.js +7 -2
- package/dist/config/table.d.ts +6 -0
- package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +1 -0
- package/dist/crypto-shredding/handlers/forget-subject.write.js +110 -61
- package/dist/custom-fields/entity.d.ts +4 -0
- package/dist/data-retention/schema/tenant-retention-override.d.ts +4 -0
- package/dist/delivery/db/queries/address-opt-outs.d.ts +3 -1
- package/dist/delivery/db/queries/address-opt-outs.js +12 -7
- package/dist/delivery/delivery-service.js +60 -12
- package/dist/delivery/public-names.js +1 -1
- package/dist/delivery/tables.d.ts +6 -0
- package/dist/delivery/unsubscribe.js +66 -14
- package/dist/document-ingest-foundation/entity.d.ts +4 -0
- package/dist/feature-toggles/feature.js +2 -3
- package/dist/feature-toggles/toggle-runtime.d.ts +5 -1
- package/dist/feature-toggles/toggle-runtime.js +30 -6
- package/dist/feature-toggles/toggle-sync-signal.d.ts +3 -2
- package/dist/feature-toggles/toggle-sync-signal.js +29 -10
- package/dist/file-derivatives/handlers/public-variant.query.d.ts +1 -0
- package/dist/file-derivatives/handlers/public-variant.query.js +7 -1
- package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +5 -0
- package/dist/files-tenant-data/hooks.js +61 -24
- package/dist/folders/entity.d.ts +8 -0
- package/dist/folders/feature.js +2 -10
- package/dist/folders/handlers/delete-folder.write.js +31 -4
- package/dist/form-draft/db/queries/cleanup.d.ts +1 -1
- package/dist/form-draft/db/queries/cleanup.js +4 -3
- package/dist/form-draft/entity.d.ts +2 -0
- package/dist/form-draft/handlers/cleanup.job.d.ts +5 -1
- package/dist/form-draft/handlers/cleanup.job.js +11 -5
- package/dist/foundation-shared/index.d.ts +1 -1
- package/dist/foundation-shared/index.js +1 -1
- package/dist/foundation-shared/mail-host-policy.d.ts +4 -0
- package/dist/foundation-shared/mail-host-policy.js +13 -4
- package/dist/inbound-mail-foundation/entities.d.ts +25 -0
- package/dist/inbound-mail-foundation/projection.d.ts +20 -0
- package/dist/inbound-provider-imap/feature.js +2 -0
- package/dist/inbound-provider-imap/imap-client.js +3 -4
- package/dist/jobs/constants.d.ts +1 -0
- package/dist/jobs/constants.js +1 -0
- package/dist/jobs/db/queries/retention.d.ts +1 -0
- package/dist/jobs/db/queries/retention.js +5 -0
- package/dist/jobs/db/queries/stale-run-sweep.d.ts +2 -0
- package/dist/jobs/db/queries/stale-run-sweep.js +13 -2
- package/dist/jobs/feature.js +7 -1
- package/dist/jobs/handlers/list.query.d.ts +2 -1
- package/dist/jobs/handlers/list.query.js +40 -15
- package/dist/jobs/handlers/tenant-failures.query.js +1 -1
- package/dist/jobs/handlers/tenant-runs.query.d.ts +17 -0
- package/dist/jobs/handlers/tenant-runs.query.js +72 -0
- package/dist/jobs/i18n.js +1 -0
- package/dist/jobs/index.d.ts +2 -0
- package/dist/jobs/index.js +1 -0
- package/dist/jobs/job-run-logger.d.ts +2 -2
- package/dist/jobs/job-run-logger.js +98 -9
- package/dist/jobs/job-run-table.d.ts +6 -0
- package/dist/jobs/tenant-job-failure-table.js +15 -2
- package/dist/jobs/tenant-job-run-table.d.ts +4 -0
- package/dist/jobs/tenant-job-run-table.js +34 -0
- package/dist/ledger/entity.d.ts +24 -8
- package/dist/ledger/entity.js +17 -5
- package/dist/ledger/feature.js +3 -0
- package/dist/ledger/handlers/confirm-schedule-period.write.js +9 -3
- package/dist/ledger/handlers/create-transaction.write.js +1 -0
- package/dist/ledger/handlers/reverse-transaction.write.js +1 -0
- package/dist/ledger/schedule-subject-pair.d.ts +2 -0
- package/dist/ledger/schedule-subject-pair.js +24 -0
- package/dist/ledger/schemas.js +8 -2
- package/dist/mail-transport-smtp/feature.d.ts +3 -4
- package/dist/mail-transport-smtp/feature.js +4 -13
- package/dist/managed-pages/feature.js +28 -10
- package/dist/managed-pages/table.d.ts +12 -0
- package/dist/notes-history/entity.d.ts +12 -0
- package/dist/notes-history/entity.js +4 -0
- package/dist/notes-history/feature.js +2 -10
- package/dist/personal-access-tokens/handlers/create.write.js +1 -0
- package/dist/personal-access-tokens/schema/api-token.d.ts +6 -0
- package/dist/personal-access-tokens/screens.js +14 -3
- package/dist/secrets/table.d.ts +1 -0
- package/dist/seo/feature.js +28 -6
- package/dist/sessions/feature.d.ts +1 -0
- package/dist/sessions/feature.js +9 -8
- package/dist/sessions/handlers/detail.query.d.ts +1 -1
- package/dist/sessions/handlers/detail.query.js +2 -2
- package/dist/sessions/handlers/list.query.d.ts +1 -1
- package/dist/sessions/handlers/list.query.js +5 -3
- package/dist/sessions/schema/user-session.d.ts +4 -0
- package/dist/sessions/screens.d.ts +2 -2
- package/dist/sessions/screens.js +6 -7
- package/dist/shared/assert-no-where-rule-in-ownership-write.d.ts +2 -0
- package/dist/shared/assert-no-where-rule-in-ownership-write.js +18 -0
- package/dist/shared/encrypt-for-direct-write.js +10 -2
- package/dist/shared/index.d.ts +4 -3
- package/dist/shared/index.js +4 -3
- package/dist/shared/parent-visibility.d.ts +2 -1
- package/dist/shared/parent-visibility.js +21 -0
- package/dist/shared/rate-limited-text-response.d.ts +2 -0
- package/dist/shared/rate-limited-text-response.js +9 -0
- package/dist/shared/row-bound-grant.js +16 -2
- package/dist/shared/session-locale-field.d.ts +1 -0
- package/dist/shared/session-locale-field.js +6 -0
- package/dist/tags/entity.d.ts +9 -0
- package/dist/tags/feature.js +2 -10
- package/dist/template-resolver/api.d.ts +2 -2
- package/dist/template-resolver/handlers/list.query.d.ts +2 -0
- package/dist/template-resolver/handlers/list.query.js +2 -2
- package/dist/template-resolver/table.d.ts +48 -30
- package/dist/template-resolver/user-content-table.d.ts +34 -20
- package/dist/tenant/decrypt-tenant-names.d.ts +3 -0
- package/dist/tenant/decrypt-tenant-names.js +10 -0
- package/dist/tenant/feature.js +7 -1
- package/dist/tenant/handlers/me.query.js +5 -1
- package/dist/tenant/handlers/memberships.query.js +3 -2
- package/dist/tenant/handlers/tenant-directory.query.js +9 -3
- package/dist/tenant/handlers/toggle-enabled.write.js +2 -0
- package/dist/tenant/handlers/update-member-roles.write.js +1 -0
- package/dist/tenant/index.d.ts +1 -0
- package/dist/tenant/index.js +1 -0
- package/dist/tenant/invitation-table.d.ts +54 -8
- package/dist/tenant/invitation-table.js +6 -1
- package/dist/tenant/invited-membership.d.ts +8 -6
- package/dist/tenant/invited-membership.js +28 -7
- package/dist/tenant/membership-table.d.ts +4 -0
- package/dist/tenant/schema/tenant.d.ts +18 -10
- package/dist/tenant/schema/tenant.js +4 -6
- package/dist/tenant/screens.js +1 -1
- package/dist/tenant-handover/move-entity-graph.js +11 -18
- package/dist/tenant-handover/transfer-graph.d.ts +2 -21
- package/dist/tenant-handover/transfer-graph.js +8 -75
- package/dist/tenant-lifecycle/boot-checks.d.ts +1 -0
- package/dist/tenant-lifecycle/boot-checks.js +13 -0
- package/dist/tenant-lifecycle/constants.d.ts +3 -0
- package/dist/tenant-lifecycle/constants.js +5 -0
- package/dist/tenant-lifecycle/events.d.ts +5 -0
- package/dist/tenant-lifecycle/events.js +5 -0
- package/dist/tenant-lifecycle/feature.js +6 -3
- package/dist/tenant-lifecycle/run-tenant-destroy.d.ts +10 -5
- package/dist/tenant-lifecycle/run-tenant-destroy.js +59 -17
- package/dist/tenant-lifecycle/stages.d.ts +8 -1
- package/dist/tenant-lifecycle/stages.js +33 -4
- package/dist/tenant-lifecycle/testing.d.ts +8 -0
- package/dist/tenant-lifecycle/testing.js +42 -0
- package/dist/tier-engine/entity.d.ts +2 -0
- package/dist/tier-engine/handlers/set-tenant-tier.write.js +1 -0
- package/dist/tier-engine/tier-resolver.d.ts +2 -0
- package/dist/user/handlers/detail.query.js +2 -0
- package/dist/user/handlers/list.query.js +6 -2
- package/dist/user/handlers/update.write.js +1 -0
- package/dist/user/schema/user.d.ts +22 -8
- package/dist/user/seeding.d.ts +1 -0
- package/dist/user/seeding.js +20 -0
- package/dist/user-data-rights/boot-checks.js +5 -0
- package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +2 -2
- package/dist/user-data-rights/handlers/request-deletion.write.js +1 -0
- package/dist/user-data-rights/index.d.ts +1 -0
- package/dist/user-data-rights/index.js +1 -0
- package/dist/user-data-rights/schema/download-attempt.d.ts +14 -0
- package/dist/user-data-rights/schema/download-attempt.js +17 -9
- package/dist/user-data-rights/schema/download-token.d.ts +8 -0
- package/dist/user-data-rights/schema/export-job.d.ts +16 -8
- package/dist/user-profile/handlers/change-email.write.js +8 -2
- package/dist/waitlist/entity.d.ts +22 -6
- package/dist/workflow-runner/event-trigger.d.ts +1 -0
- package/dist/workflow-runner/event-trigger.js +63 -15
- package/dist/workflow-runner/handlers/resume-run.write.js +8 -2
- package/dist/workflow-runner/runner.d.ts +2 -1
- package/dist/workflow-runner/runner.js +5 -1
- package/package.json +35 -10
- package/src/agent-tools/changes.json +12 -0
- package/src/audit/changes.json +6 -0
- package/src/auth-email-password/changes.json +24 -0
- package/src/auth-mfa/changes.json +7 -0
- package/src/billing-foundation/changes.json +6 -0
- package/src/channel-in-app/changes.json +8 -1
- package/src/crypto-shredding/changes.json +12 -0
- package/src/delivery/changes.json +6 -0
- package/src/files/changes.json +24 -0
- package/src/files-tenant-data/changes.json +5 -0
- package/src/folders/changes.json +6 -0
- package/src/form-draft/changes.json +7 -1
- package/src/inbound-provider-imap/changes.json +6 -0
- package/src/jobs/changes.json +30 -0
- package/src/ledger/changes.json +23 -0
- package/src/managed-pages/changes.json +6 -0
- package/src/notes-history/changes.json +13 -0
- package/src/seo/changes.json +5 -0
- package/src/template-resolver/changes.json +5 -0
- package/src/tenant/changes.json +19 -0
- package/src/tenant-handover/changes.json +12 -0
- package/src/tenant-lifecycle/changes.json +22 -0
- package/src/tier-engine/changes.json +5 -0
- package/src/user/changes.json +15 -0
- package/src/user-data-rights/changes.json +6 -0
- package/src/workflow-runner/changes.json +5 -0
- package/dist/shared/has-where-rule.d.ts +0 -2
- package/dist/shared/has-where-rule.js +0 -10
|
@@ -114,7 +114,7 @@ export function MfaSetupPreauthScreen({ preauthSetupToken, accountLabel, title,
|
|
|
114
114
|
}
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
|
-
onSuccess?.();
|
|
117
|
+
onSuccess?.(res.data.landingPath);
|
|
118
118
|
}
|
|
119
119
|
catch {
|
|
120
120
|
setError("setup_failed");
|
|
@@ -129,7 +129,7 @@ export function MfaSetupPreauthScreen({ preauthSetupToken, accountLabel, title,
|
|
|
129
129
|
};
|
|
130
130
|
return (_jsxs(AuthCard, { title: title ?? t("auth.mfa.setup.title"), subtitle: subtitle ?? t("auth.mfa.setup.subtitle"), children: [error !== null ? (_jsx(Banner, { variant: "error", children: error === "too_many_attempts" && retryAfterSeconds !== null
|
|
131
131
|
? t("auth.mfa.errors.tooManyAttemptsWithSeconds", { seconds: retryAfterSeconds })
|
|
132
|
-
: t(reasonToKey(error)) })) : null, !setup && (
|
|
132
|
+
: t(reasonToKey(error)) })) : null, !setup && (_jsxs(Section, { testId: "mfa-setup-preauth-intro", children: [_jsx("span", { className: "text-sm text-muted-foreground", children: t("auth.mfa.setup.intro") }), _jsx("div", { className: "flex justify-end", children: _jsx(Button, { variant: "primary", onClick: () => void startSetup(), loading: busy, disabled: busy, children: t("auth.mfa.setup.start") }) })] })), setup && (_jsx(Form, { onSubmit: onSubmit, children: _jsxs(Section, { testId: "mfa-setup-preauth-setup", children: [_jsxs("div", { className: "flex flex-col items-center gap-2 text-center", children: [_jsx("span", { className: "text-sm font-semibold", children: t("auth.mfa.enable.scanTitle") }), _jsx("div", { className: "h-40 w-40",
|
|
133
133
|
// biome-ignore lint/security/noDangerouslySetInnerHtml: qrcode-generated SVG, no user input
|
|
134
|
-
dangerouslySetInnerHTML: { __html: setup.qrSvg } }), _jsx("span", { className: "text-xs text-muted-foreground", children: t("auth.mfa.enable.manualEntry") }), _jsx("code", { className: "inline-block break-all rounded bg-muted px-3 py-2 font-mono text-sm", children: setup.secretParam })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("span", { className: "text-sm font-semibold", children: t("auth.mfa.enable.recoveryTitle") }), _jsx("span", { className: "text-xs text-muted-foreground", children: t("auth.mfa.enable.recoveryHint") }), _jsx("code", { className: "block whitespace-pre-wrap break-all rounded bg-muted px-3 py-2 font-mono text-sm", children: setup.recoveryCodes.join("\n") }), _jsx(Field, { id: "mfa-setup-preauth-ack", label: t("auth.mfa.enable.acknowledge"), children: _jsx(Input, { kind: "boolean", id: "mfa-setup-preauth-ack", name: "mfa-setup-preauth-ack", value: acknowledged, onChange: setAcknowledged }) })] }), _jsx(Field, { id: "mfa-setup-preauth-code", label: t("auth.mfa.enable.code"), required: true, children: _jsx(Input, { kind: "text", id: "mfa-setup-preauth-code", name: "mfa-setup-preauth-code", value: code, onChange: setCode, disabled: busy || !acknowledged, autoComplete: "one-time-code" }) })] }) })), onCancel ? (_jsx("div", { className: "flex justify-center", children: _jsx(Button, { type: "button", variant: "secondary", onClick: onCancel, disabled: busy, children: t("auth.mfa.verify.backToLogin") }) })) : null] }));
|
|
134
|
+
dangerouslySetInnerHTML: { __html: setup.qrSvg } }), _jsx("span", { className: "text-xs text-muted-foreground", children: t("auth.mfa.enable.manualEntry") }), _jsx("code", { className: "inline-block break-all rounded bg-muted px-3 py-2 font-mono text-sm", children: setup.secretParam })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("span", { className: "text-sm font-semibold", children: t("auth.mfa.enable.recoveryTitle") }), _jsx("span", { className: "text-xs text-muted-foreground", children: t("auth.mfa.enable.recoveryHint") }), _jsx("code", { className: "block whitespace-pre-wrap break-all rounded bg-muted px-3 py-2 font-mono text-sm", children: setup.recoveryCodes.join("\n") }), _jsx(Field, { id: "mfa-setup-preauth-ack", label: t("auth.mfa.enable.acknowledge"), children: _jsx(Input, { kind: "boolean", id: "mfa-setup-preauth-ack", name: "mfa-setup-preauth-ack", value: acknowledged, onChange: setAcknowledged }) })] }), _jsx(Field, { id: "mfa-setup-preauth-code", label: t("auth.mfa.enable.code"), required: true, children: _jsx(Input, { kind: "text", id: "mfa-setup-preauth-code", name: "mfa-setup-preauth-code", value: code, onChange: setCode, disabled: busy || !acknowledged, autoComplete: "one-time-code" }) }), _jsx("div", { className: "flex justify-end", children: _jsx(Button, { type: "submit", variant: "primary", loading: busy, disabled: busy || !acknowledged || code.length !== 6, children: t("auth.mfa.setup.confirm") }) })] }) })), onCancel ? (_jsx("div", { className: "flex justify-center", children: _jsx(Button, { type: "button", variant: "secondary", onClick: onCancel, disabled: busy, children: t("auth.mfa.verify.backToLogin") }) })) : null] }));
|
|
135
135
|
}
|
|
@@ -7,7 +7,7 @@ export type MfaVerifyScreenProps = {
|
|
|
7
7
|
/** Called after the server confirms the code and the session state has
|
|
8
8
|
* refreshed. Optional — apps that swap this screen back out purely on
|
|
9
9
|
* session.status changing to "authenticated" don't need it. */
|
|
10
|
-
readonly onSuccess?: () => void;
|
|
10
|
+
readonly onSuccess?: (landingPath?: string) => void;
|
|
11
11
|
readonly onCancel?: () => void;
|
|
12
12
|
};
|
|
13
13
|
export declare function MfaVerifyScreen({ challengeToken, title, subtitle, submitLabel, onSuccess, onCancel, }: MfaVerifyScreenProps): ReactNode;
|
|
@@ -42,7 +42,7 @@ export function MfaVerifyScreen({ challengeToken, title, subtitle, submitLabel,
|
|
|
42
42
|
if (res.kind === "success") {
|
|
43
43
|
await session.refresh();
|
|
44
44
|
setSubmitting(false);
|
|
45
|
-
onSuccess?.();
|
|
45
|
+
onSuccess?.(res.data.landingPath);
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
setSubmitting(false);
|
|
@@ -9,12 +9,15 @@ export type BillingInfo<TTier extends string> = {
|
|
|
9
9
|
readonly tier: string;
|
|
10
10
|
readonly providerName: string;
|
|
11
11
|
} | null;
|
|
12
|
-
readonly prices:
|
|
12
|
+
readonly prices: TierPrices<TTier>;
|
|
13
|
+
};
|
|
14
|
+
export type TierPrices<TTier extends string> = {
|
|
15
|
+
readonly [K in TTier]?: string;
|
|
13
16
|
};
|
|
14
17
|
export type BillingInfoQueryDeps<TTier extends string> = {
|
|
15
18
|
readonly roles: readonly string[];
|
|
16
19
|
readonly resolveTier: (db: TenantDb, tenantId: TenantId) => Promise<TTier>;
|
|
17
|
-
readonly getBillingPrices: (ctx: HandlerContext) =>
|
|
20
|
+
readonly getBillingPrices: (ctx: HandlerContext) => TierPrices<TTier> | null;
|
|
18
21
|
};
|
|
19
22
|
export declare function createBillingInfoQueryConfig<TTier extends string>(deps: BillingInfoQueryDeps<TTier>): {
|
|
20
23
|
name: string;
|
|
@@ -80,6 +80,13 @@ export type OpenCheckoutOptions = {
|
|
|
80
80
|
readonly baseUrl?: string;
|
|
81
81
|
readonly catalog?: BillingPlanCatalog;
|
|
82
82
|
readonly now: () => Temporal.Instant;
|
|
83
|
+
/** The caller already ran `assertBillingEnabled` under its own handler name
|
|
84
|
+
* (before a costly provider lookup), so the gate is not repeated here. */
|
|
85
|
+
readonly billingEnabledChecked?: boolean;
|
|
86
|
+
/** The caller already ran `assertNoActiveSubscription` and passes its result
|
|
87
|
+
* (null = tenant has none); mode:"subscription" skips the second read and
|
|
88
|
+
* the providerCustomerId check reuses it. */
|
|
89
|
+
readonly checkedSubscription?: Awaited<ReturnType<typeof getSubscriptionForTenant>>;
|
|
83
90
|
};
|
|
84
91
|
export type OpenCheckoutInput = {
|
|
85
92
|
readonly providerName: string;
|
|
@@ -249,7 +249,9 @@ export async function assertCheckoutAllowed(ctx, options, input) {
|
|
|
249
249
|
// Checked before the redirect-origin hardening for every mode — a
|
|
250
250
|
// disabled provider must reject a mode:"payment" checkout just as much
|
|
251
251
|
// as a mode:"subscription" one.
|
|
252
|
-
|
|
252
|
+
if (options.billingEnabledChecked !== true) {
|
|
253
|
+
await assertBillingEnabled(ctx, plugin, "create-checkout-session");
|
|
254
|
+
}
|
|
253
255
|
assertRedirectOrigins([input.successUrl, input.cancelUrl], options.baseUrl);
|
|
254
256
|
const mode = input.mode ?? "subscription";
|
|
255
257
|
// Reused by the providerCustomerId check below to avoid a second lookup
|
|
@@ -257,7 +259,10 @@ export async function assertCheckoutAllowed(ctx, options, input) {
|
|
|
257
259
|
let ownSubscription;
|
|
258
260
|
if (mode === "subscription") {
|
|
259
261
|
assertSubscriptionPriceAllowed(plugin, options.catalog, input);
|
|
260
|
-
ownSubscription =
|
|
262
|
+
ownSubscription =
|
|
263
|
+
options.checkedSubscription !== undefined
|
|
264
|
+
? options.checkedSubscription
|
|
265
|
+
: await assertNoActiveSubscription(ctx, options.now());
|
|
261
266
|
}
|
|
262
267
|
else {
|
|
263
268
|
assertOneOffPriceAllowed(plugin, input);
|
|
@@ -3,6 +3,7 @@ export declare const subscriptionEntity: import("@cosmicdrift/kumiko-types/field
|
|
|
3
3
|
readonly type: "text";
|
|
4
4
|
readonly description?: string;
|
|
5
5
|
readonly maxLength?: number;
|
|
6
|
+
readonly minLength?: number;
|
|
6
7
|
readonly required?: boolean;
|
|
7
8
|
readonly searchable?: boolean;
|
|
8
9
|
readonly sortable?: boolean;
|
|
@@ -24,6 +25,7 @@ export declare const subscriptionEntity: import("@cosmicdrift/kumiko-types/field
|
|
|
24
25
|
readonly type: "text";
|
|
25
26
|
readonly description?: string;
|
|
26
27
|
readonly maxLength?: number;
|
|
28
|
+
readonly minLength?: number;
|
|
27
29
|
readonly required?: boolean;
|
|
28
30
|
readonly searchable?: boolean;
|
|
29
31
|
readonly sortable?: boolean;
|
|
@@ -45,6 +47,7 @@ export declare const subscriptionEntity: import("@cosmicdrift/kumiko-types/field
|
|
|
45
47
|
readonly type: "text";
|
|
46
48
|
readonly description?: string;
|
|
47
49
|
readonly maxLength?: number;
|
|
50
|
+
readonly minLength?: number;
|
|
48
51
|
readonly required?: boolean;
|
|
49
52
|
readonly searchable?: boolean;
|
|
50
53
|
readonly sortable?: boolean;
|
|
@@ -66,6 +69,7 @@ export declare const subscriptionEntity: import("@cosmicdrift/kumiko-types/field
|
|
|
66
69
|
readonly type: "text";
|
|
67
70
|
readonly description?: string;
|
|
68
71
|
readonly maxLength?: number;
|
|
72
|
+
readonly minLength?: number;
|
|
69
73
|
readonly required?: boolean;
|
|
70
74
|
readonly searchable?: boolean;
|
|
71
75
|
readonly sortable?: boolean;
|
|
@@ -87,6 +91,7 @@ export declare const subscriptionEntity: import("@cosmicdrift/kumiko-types/field
|
|
|
87
91
|
readonly type: "text";
|
|
88
92
|
readonly description?: string;
|
|
89
93
|
readonly maxLength?: number;
|
|
94
|
+
readonly minLength?: number;
|
|
90
95
|
readonly required?: boolean;
|
|
91
96
|
readonly searchable?: boolean;
|
|
92
97
|
readonly sortable?: boolean;
|
|
@@ -141,6 +146,7 @@ export declare const paymentEntity: import("@cosmicdrift/kumiko-types/fields").E
|
|
|
141
146
|
readonly type: "text";
|
|
142
147
|
readonly description?: string;
|
|
143
148
|
readonly maxLength?: number;
|
|
149
|
+
readonly minLength?: number;
|
|
144
150
|
readonly required?: boolean;
|
|
145
151
|
readonly searchable?: boolean;
|
|
146
152
|
readonly sortable?: boolean;
|
|
@@ -162,6 +168,7 @@ export declare const paymentEntity: import("@cosmicdrift/kumiko-types/fields").E
|
|
|
162
168
|
readonly type: "text";
|
|
163
169
|
readonly description?: string;
|
|
164
170
|
readonly maxLength?: number;
|
|
171
|
+
readonly minLength?: number;
|
|
165
172
|
readonly required?: boolean;
|
|
166
173
|
readonly searchable?: boolean;
|
|
167
174
|
readonly sortable?: boolean;
|
|
@@ -183,6 +190,7 @@ export declare const paymentEntity: import("@cosmicdrift/kumiko-types/fields").E
|
|
|
183
190
|
readonly type: "text";
|
|
184
191
|
readonly description?: string;
|
|
185
192
|
readonly maxLength?: number;
|
|
193
|
+
readonly minLength?: number;
|
|
186
194
|
readonly required?: boolean;
|
|
187
195
|
readonly searchable?: boolean;
|
|
188
196
|
readonly sortable?: boolean;
|
|
@@ -40,7 +40,13 @@ export function createStartPlanCheckoutHandler(options, catalog) {
|
|
|
40
40
|
? await prepareConsent(ctx, consumerProtection, payload.consent, "subscription")
|
|
41
41
|
: undefined;
|
|
42
42
|
const baseUrl = options.baseUrl ?? "";
|
|
43
|
-
const result = await openCheckout(ctx, {
|
|
43
|
+
const result = await openCheckout(ctx, {
|
|
44
|
+
baseUrl: options.baseUrl,
|
|
45
|
+
catalog,
|
|
46
|
+
now: options.now,
|
|
47
|
+
billingEnabledChecked: true,
|
|
48
|
+
checkedSubscription: existing,
|
|
49
|
+
}, {
|
|
44
50
|
providerName,
|
|
45
51
|
priceId: resolved.priceId,
|
|
46
52
|
successUrl: joinBaseUrl(baseUrl, catalog.successPath),
|
|
@@ -3,6 +3,7 @@ export declare const subscriptionsProjectionTable: import("@cosmicdrift/kumiko-f
|
|
|
3
3
|
readonly type: "text";
|
|
4
4
|
readonly description?: string;
|
|
5
5
|
readonly maxLength?: number;
|
|
6
|
+
readonly minLength?: number;
|
|
6
7
|
readonly required?: boolean;
|
|
7
8
|
readonly searchable?: boolean;
|
|
8
9
|
readonly sortable?: boolean;
|
|
@@ -24,6 +25,7 @@ export declare const subscriptionsProjectionTable: import("@cosmicdrift/kumiko-f
|
|
|
24
25
|
readonly type: "text";
|
|
25
26
|
readonly description?: string;
|
|
26
27
|
readonly maxLength?: number;
|
|
28
|
+
readonly minLength?: number;
|
|
27
29
|
readonly required?: boolean;
|
|
28
30
|
readonly searchable?: boolean;
|
|
29
31
|
readonly sortable?: boolean;
|
|
@@ -45,6 +47,7 @@ export declare const subscriptionsProjectionTable: import("@cosmicdrift/kumiko-f
|
|
|
45
47
|
readonly type: "text";
|
|
46
48
|
readonly description?: string;
|
|
47
49
|
readonly maxLength?: number;
|
|
50
|
+
readonly minLength?: number;
|
|
48
51
|
readonly required?: boolean;
|
|
49
52
|
readonly searchable?: boolean;
|
|
50
53
|
readonly sortable?: boolean;
|
|
@@ -66,6 +69,7 @@ export declare const subscriptionsProjectionTable: import("@cosmicdrift/kumiko-f
|
|
|
66
69
|
readonly type: "text";
|
|
67
70
|
readonly description?: string;
|
|
68
71
|
readonly maxLength?: number;
|
|
72
|
+
readonly minLength?: number;
|
|
69
73
|
readonly required?: boolean;
|
|
70
74
|
readonly searchable?: boolean;
|
|
71
75
|
readonly sortable?: boolean;
|
|
@@ -87,6 +91,7 @@ export declare const subscriptionsProjectionTable: import("@cosmicdrift/kumiko-f
|
|
|
87
91
|
readonly type: "text";
|
|
88
92
|
readonly description?: string;
|
|
89
93
|
readonly maxLength?: number;
|
|
94
|
+
readonly minLength?: number;
|
|
90
95
|
readonly required?: boolean;
|
|
91
96
|
readonly searchable?: boolean;
|
|
92
97
|
readonly sortable?: boolean;
|
|
@@ -140,6 +145,7 @@ export declare const paymentsProjectionTable: import("@cosmicdrift/kumiko-framew
|
|
|
140
145
|
readonly type: "text";
|
|
141
146
|
readonly description?: string;
|
|
142
147
|
readonly maxLength?: number;
|
|
148
|
+
readonly minLength?: number;
|
|
143
149
|
readonly required?: boolean;
|
|
144
150
|
readonly searchable?: boolean;
|
|
145
151
|
readonly sortable?: boolean;
|
|
@@ -161,6 +167,7 @@ export declare const paymentsProjectionTable: import("@cosmicdrift/kumiko-framew
|
|
|
161
167
|
readonly type: "text";
|
|
162
168
|
readonly description?: string;
|
|
163
169
|
readonly maxLength?: number;
|
|
170
|
+
readonly minLength?: number;
|
|
164
171
|
readonly required?: boolean;
|
|
165
172
|
readonly searchable?: boolean;
|
|
166
173
|
readonly sortable?: boolean;
|
|
@@ -182,6 +189,7 @@ export declare const paymentsProjectionTable: import("@cosmicdrift/kumiko-framew
|
|
|
182
189
|
readonly type: "text";
|
|
183
190
|
readonly description?: string;
|
|
184
191
|
readonly maxLength?: number;
|
|
192
|
+
readonly minLength?: number;
|
|
185
193
|
readonly required?: boolean;
|
|
186
194
|
readonly searchable?: boolean;
|
|
187
195
|
readonly sortable?: boolean;
|
|
@@ -3,6 +3,7 @@ export declare const capCounterEntity: import("@cosmicdrift/kumiko-types/fields"
|
|
|
3
3
|
readonly type: "text";
|
|
4
4
|
readonly description?: string;
|
|
5
5
|
readonly maxLength?: number;
|
|
6
|
+
readonly minLength?: number;
|
|
6
7
|
readonly required?: boolean;
|
|
7
8
|
readonly searchable?: boolean;
|
|
8
9
|
readonly sortable?: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { access } from "@cosmicdrift/kumiko-framework/engine";
|
|
1
|
+
import { access, BUILT_IN_MEMBERSHIP_ROLES } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
// Usage numbers are an operator concern by default; wider visibility is an
|
|
3
3
|
// explicit `usageVisibleTo` opt-in on createCapOverviewFeature. The my-caps
|
|
4
4
|
// screen and the query that fills its cards must carry the SAME rule, or the
|
|
@@ -7,14 +7,7 @@ export const DEFAULT_CAP_USAGE_ROLES = access.roles(...access.admin);
|
|
|
7
7
|
// Roles the engine itself knows (role-assignment.ts ranks). App-declared roles
|
|
8
8
|
// (assignableRole) only exist once the registry is composed, which is after
|
|
9
9
|
// this feature is defined, so they cannot be validated here.
|
|
10
|
-
const BUILT_IN_USAGE_VISIBLE_ROLES = new Set(
|
|
11
|
-
"User",
|
|
12
|
-
"Member",
|
|
13
|
-
"Editor",
|
|
14
|
-
"Admin",
|
|
15
|
-
"TenantAdmin",
|
|
16
|
-
"SystemAdmin",
|
|
17
|
-
]);
|
|
10
|
+
const BUILT_IN_USAGE_VISIBLE_ROLES = new Set(BUILT_IN_MEMBERSHIP_ROLES);
|
|
18
11
|
export function resolveCapUsageRoles(usageVisibleTo) {
|
|
19
12
|
if (usageVisibleTo === undefined)
|
|
20
13
|
return DEFAULT_CAP_USAGE_ROLES;
|
|
@@ -4,7 +4,7 @@ import { definePagedQueryHandler, MAX_LIST_LIMIT, } from "@cosmicdrift/kumiko-fr
|
|
|
4
4
|
import { InternalError, ValidationError } from "@cosmicdrift/kumiko-framework/errors";
|
|
5
5
|
import * as z from "zod";
|
|
6
6
|
import { subscriptionsProjectionTable } from "../../billing-foundation/index.js";
|
|
7
|
-
import { tenantTable } from "../../tenant/index.js";
|
|
7
|
+
import { decryptTenantNames, tenantTable } from "../../tenant/index.js";
|
|
8
8
|
import { tierAssignmentEntity } from "../../tier-engine/index.js";
|
|
9
9
|
import { capFieldName } from "../constants.js";
|
|
10
10
|
import { computeFraction } from "../usage-math.js";
|
|
@@ -115,7 +115,7 @@ export function createTenantCapsListQuery(caps, listCaps) {
|
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
const db = ctx.systemDb.acknowledgeCrossTenant("cap-overview:tenant-caps:list — SystemAdmin platform-wide tenant overview");
|
|
118
|
-
const tenants = await selectMany(db, tenantTable, {});
|
|
118
|
+
const tenants = await decryptTenantNames(await selectMany(db, tenantTable, {}), "cap-overview:tenant-caps:list");
|
|
119
119
|
const assignments = await selectMany(db, tierAssignmentTable, {});
|
|
120
120
|
const subscriptions = await selectMany(db, subscriptionsProjectionTable, {});
|
|
121
121
|
const assignmentByTenant = new Map(assignments.map((row) => [row.tenantId, row]));
|
|
@@ -2,7 +2,7 @@ import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
|
2
2
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
5
|
-
import { tenantTable } from "../../tenant/index.js";
|
|
5
|
+
import { decryptTenantNames, tenantTable } from "../../tenant/index.js";
|
|
6
6
|
export const tenantOptionsQuery = defineQueryHandler({
|
|
7
7
|
name: "tenant-options",
|
|
8
8
|
description: "Returns all tenants as id/name option pairs sorted by name; use it to populate the tenant picker of a platform-wide overview.",
|
|
@@ -15,9 +15,8 @@ export const tenantOptionsQuery = defineQueryHandler({
|
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
17
|
const db = ctx.systemDb.acknowledgeCrossTenant("cap-overview:tenant-options — SystemAdmin dashboard tenant-filter options");
|
|
18
|
-
const tenants = await selectMany(db, tenantTable, {},
|
|
19
|
-
|
|
20
|
-
});
|
|
21
|
-
return { rows: tenants.map((tenant) => ({ value: tenant.id, label: tenant.name })) };
|
|
18
|
+
const tenants = await decryptTenantNames(await selectMany(db, tenantTable, {}), "cap-overview:tenant-options");
|
|
19
|
+
const sorted = [...tenants].sort((a, b) => a.name.localeCompare(b.name));
|
|
20
|
+
return { rows: sorted.map((tenant) => ({ value: tenant.id, label: tenant.name })) };
|
|
22
21
|
},
|
|
23
22
|
});
|
|
@@ -18,7 +18,7 @@ export const inAppChannel = {
|
|
|
18
18
|
data: message.data ? JSON.stringify(message.data) : null,
|
|
19
19
|
});
|
|
20
20
|
if (ctx.sseBroker) {
|
|
21
|
-
ctx.sseBroker.pushToChannel(tenantChannel(ctx.tenantId), {
|
|
21
|
+
await ctx.sseBroker.pushToChannel(tenantChannel(ctx.tenantId), {
|
|
22
22
|
type: "channel-in-app:event:delivered",
|
|
23
23
|
data: {
|
|
24
24
|
id: row?.id,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { requireEntityTableMeta } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
|
-
import { boolean, instant, table as pgTable, serial, sql, text, uuid, } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import { boolean, index, instant, table as pgTable, serial, sql, text, uuid, } from "@cosmicdrift/kumiko-framework/db";
|
|
3
3
|
export const inAppMessagesTable = pgTable("in_app_messages", {
|
|
4
4
|
id: serial("id").primaryKey(),
|
|
5
5
|
tenantId: uuid("tenant_id").notNull(),
|
|
@@ -11,7 +11,9 @@ export const inAppMessagesTable = pgTable("in_app_messages", {
|
|
|
11
11
|
isRead: boolean("is_read").default(false).notNull(),
|
|
12
12
|
readAt: instant("read_at"),
|
|
13
13
|
createdAt: instant("created_at").default(sql `now()`).notNull(),
|
|
14
|
-
}
|
|
14
|
+
},
|
|
15
|
+
// Every inbox, unread-count, mark-all-read and userData export/delete read filters by tenant + user.
|
|
16
|
+
(t) => [index("in_app_messages_tenant_user_created_idx").on(t.tenantId, t.userId, t.createdAt)]);
|
|
15
17
|
// Derived from inAppMessagesTable (table() attaches the meta as a Symbol) so
|
|
16
18
|
// the two can't drift, instead of hand-duplicating the column list.
|
|
17
19
|
export const inAppMessagesTableMeta = requireEntityTableMeta(inAppMessagesTable, "inAppMessagesTable");
|
|
@@ -11,14 +11,15 @@ export declare const tenantComplianceProfileEntity: import("@cosmicdrift/kumiko-
|
|
|
11
11
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
12
12
|
readonly display?: "radio" | "dropdown";
|
|
13
13
|
readonly optionTones?: {
|
|
14
|
-
readonly "de-hr-dsgvo-hgb"?:
|
|
15
|
-
readonly "eu-dsgvo"?:
|
|
16
|
-
readonly "minimal-no-region"?:
|
|
17
|
-
readonly "swiss-dsg"?:
|
|
14
|
+
readonly "de-hr-dsgvo-hgb"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
15
|
+
readonly "eu-dsgvo"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
16
|
+
readonly "minimal-no-region"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
17
|
+
readonly "swiss-dsg"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
18
18
|
} | undefined;
|
|
19
19
|
readonly optionsQuery?: string;
|
|
20
20
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
21
21
|
readonly optionsAvailabilityQuery?: string;
|
|
22
|
+
readonly conditionalOptions?: readonly import("@cosmicdrift/kumiko-types/fields").SelectConditionalOptions<"de-hr-dsgvo-hgb" | "eu-dsgvo" | "minimal-no-region" | "swiss-dsg">[] | undefined;
|
|
22
23
|
} & import("@cosmicdrift/kumiko-types/fields").ResolvedPiiFlags & {
|
|
23
24
|
required: true;
|
|
24
25
|
};
|
|
@@ -52,14 +53,15 @@ export declare const tenantComplianceProfileTable: import("@cosmicdrift/kumiko-f
|
|
|
52
53
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
53
54
|
readonly display?: "radio" | "dropdown";
|
|
54
55
|
readonly optionTones?: {
|
|
55
|
-
readonly "de-hr-dsgvo-hgb"?:
|
|
56
|
-
readonly "eu-dsgvo"?:
|
|
57
|
-
readonly "minimal-no-region"?:
|
|
58
|
-
readonly "swiss-dsg"?:
|
|
56
|
+
readonly "de-hr-dsgvo-hgb"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
57
|
+
readonly "eu-dsgvo"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
58
|
+
readonly "minimal-no-region"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
59
|
+
readonly "swiss-dsg"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
59
60
|
} | undefined;
|
|
60
61
|
readonly optionsQuery?: string;
|
|
61
62
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
62
63
|
readonly optionsAvailabilityQuery?: string;
|
|
64
|
+
readonly conditionalOptions?: readonly import("@cosmicdrift/kumiko-types/fields").SelectConditionalOptions<"de-hr-dsgvo-hgb" | "eu-dsgvo" | "minimal-no-region" | "swiss-dsg">[] | undefined;
|
|
63
65
|
} & import("@cosmicdrift/kumiko-types/fields").ResolvedPiiFlags & {
|
|
64
66
|
required: true;
|
|
65
67
|
};
|
|
@@ -3,7 +3,7 @@ import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
import { tenantComplianceProfileTable } from "../../compliance-profiles/index.js";
|
|
6
|
-
import { tenantTable } from "../../tenant/index.js";
|
|
6
|
+
import { decryptTenantNames, tenantTable } from "../../tenant/index.js";
|
|
7
7
|
// SystemAdmin platform-wide counterpart to needs-profile (#2089).
|
|
8
8
|
//
|
|
9
9
|
// #2084 stopped needs-profile from nagging a TenantAdmin who can no longer
|
|
@@ -28,9 +28,7 @@ export const tenantsMissingProfileQuery = defineQueryHandler({
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
const db = ctx.systemDb.acknowledgeCrossTenant("platform operator scans every tenant for a missing compliance-profile selection");
|
|
31
|
-
const tenants = await db.selectMany(tenantTable, {
|
|
32
|
-
isEnabled: true,
|
|
33
|
-
});
|
|
31
|
+
const tenants = await decryptTenantNames(await db.selectMany(tenantTable, { isEnabled: true }), "compliance-profiles-ops:tenants-missing-profile");
|
|
34
32
|
const profileRows = await db.selectMany(tenantComplianceProfileTable, {});
|
|
35
33
|
const tenantIdsWithProfile = new Set(profileRows.map((row) => row.tenantId));
|
|
36
34
|
return {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type ConfigScope, type ConfigValueSource } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import * as z from "zod";
|
|
3
|
-
export declare const valuesQuery: import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"values", z.ZodObject<{
|
|
3
|
+
export declare const valuesQuery: import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"values", z.ZodObject<{
|
|
4
|
+
keys: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
5
|
+
}, z.core.$strip>, Record<string, {
|
|
4
6
|
value: string | number | boolean | undefined;
|
|
5
7
|
scope: ConfigScope;
|
|
6
8
|
source: ConfigValueSource;
|
|
@@ -5,8 +5,10 @@ import { MASKED, redactInheritedCascade, shouldRedactInherited } from "../read-r
|
|
|
5
5
|
import { hasConfigAccess } from "../write-helpers.js";
|
|
6
6
|
export const valuesQuery = defineQueryHandler({
|
|
7
7
|
name: "values",
|
|
8
|
-
description: "Returns the effective value, scope and winning source for every config key the caller may read, with encrypted and secret-backed values masked; use it to inspect the current settings.",
|
|
9
|
-
schema: z.object({
|
|
8
|
+
description: "Returns the effective value, scope and winning source for every config key the caller may read (optionally narrowed to `keys`), with encrypted and secret-backed values masked; use it to inspect the current settings.",
|
|
9
|
+
schema: z.object({
|
|
10
|
+
keys: z.array(z.string()).optional(),
|
|
11
|
+
}),
|
|
10
12
|
// Per-key read access enforced via hasConfigAccess inside the handler.
|
|
11
13
|
access: {
|
|
12
14
|
openToAll: {
|
|
@@ -26,7 +28,10 @@ export const valuesQuery = defineQueryHandler({
|
|
|
26
28
|
const allKeys = registry.getAllConfigKeys();
|
|
27
29
|
const keyDefs = new Map();
|
|
28
30
|
const filteredKeys = [];
|
|
31
|
+
const requestedKeys = query.payload.keys === undefined ? undefined : new Set(query.payload.keys);
|
|
29
32
|
for (const [qualifiedKey, keyDef] of allKeys) {
|
|
33
|
+
if (requestedKeys !== undefined && !requestedKeys.has(qualifiedKey))
|
|
34
|
+
continue;
|
|
30
35
|
if (!hasConfigAccess(keyDef.access.read, query.user.roles))
|
|
31
36
|
continue;
|
|
32
37
|
keyDefs.set(qualifiedKey, keyDef);
|
package/dist/config/table.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare const configValueEntity: import("@cosmicdrift/kumiko-types/fields
|
|
|
3
3
|
readonly type: "text";
|
|
4
4
|
readonly description?: string;
|
|
5
5
|
readonly maxLength?: number;
|
|
6
|
+
readonly minLength?: number;
|
|
6
7
|
readonly required?: boolean;
|
|
7
8
|
readonly searchable?: boolean;
|
|
8
9
|
readonly sortable?: boolean;
|
|
@@ -24,6 +25,7 @@ export declare const configValueEntity: import("@cosmicdrift/kumiko-types/fields
|
|
|
24
25
|
readonly type: "text";
|
|
25
26
|
readonly description?: string;
|
|
26
27
|
readonly maxLength?: number;
|
|
28
|
+
readonly minLength?: number;
|
|
27
29
|
readonly required?: boolean;
|
|
28
30
|
readonly searchable?: boolean;
|
|
29
31
|
readonly sortable?: boolean;
|
|
@@ -45,6 +47,7 @@ export declare const configValueEntity: import("@cosmicdrift/kumiko-types/fields
|
|
|
45
47
|
readonly type: "text";
|
|
46
48
|
readonly description?: string;
|
|
47
49
|
readonly maxLength?: number;
|
|
50
|
+
readonly minLength?: number;
|
|
48
51
|
readonly required?: boolean;
|
|
49
52
|
readonly searchable?: boolean;
|
|
50
53
|
readonly sortable?: boolean;
|
|
@@ -68,6 +71,7 @@ export declare const configValuesTable: import("@cosmicdrift/kumiko-framework/db
|
|
|
68
71
|
readonly type: "text";
|
|
69
72
|
readonly description?: string;
|
|
70
73
|
readonly maxLength?: number;
|
|
74
|
+
readonly minLength?: number;
|
|
71
75
|
readonly required?: boolean;
|
|
72
76
|
readonly searchable?: boolean;
|
|
73
77
|
readonly sortable?: boolean;
|
|
@@ -89,6 +93,7 @@ export declare const configValuesTable: import("@cosmicdrift/kumiko-framework/db
|
|
|
89
93
|
readonly type: "text";
|
|
90
94
|
readonly description?: string;
|
|
91
95
|
readonly maxLength?: number;
|
|
96
|
+
readonly minLength?: number;
|
|
92
97
|
readonly required?: boolean;
|
|
93
98
|
readonly searchable?: boolean;
|
|
94
99
|
readonly sortable?: boolean;
|
|
@@ -110,6 +115,7 @@ export declare const configValuesTable: import("@cosmicdrift/kumiko-framework/db
|
|
|
110
115
|
readonly type: "text";
|
|
111
116
|
readonly description?: string;
|
|
112
117
|
readonly maxLength?: number;
|
|
118
|
+
readonly minLength?: number;
|
|
113
119
|
readonly required?: boolean;
|
|
114
120
|
readonly searchable?: boolean;
|
|
115
121
|
readonly sortable?: boolean;
|
|
@@ -19,6 +19,7 @@ export declare const subjectForgottenSchema: z.ZodObject<{
|
|
|
19
19
|
subjectKey: z.ZodString;
|
|
20
20
|
reason: z.ZodString;
|
|
21
21
|
forgottenBy: z.ZodString;
|
|
22
|
+
cleanupError: z.ZodOptional<z.ZodString>;
|
|
22
23
|
}, z.core.$strip>;
|
|
23
24
|
export declare const subjectForgetDeniedSchema: z.ZodObject<{
|
|
24
25
|
subjectKeyDigest: z.ZodOptional<z.ZodString>;
|