@cosmicdrift/kumiko-bundled-features 0.391.0 → 0.392.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 +47 -30
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +2 -2
- package/dist/auth-email-password/handlers/invite-signup-complete.write.js +2 -2
- package/dist/cap-overview/handlers/caps-usage.query.js +1 -0
- package/dist/cap-overview/handlers/tenant-caps-list.query.js +3 -2
- package/dist/cap-overview/i18n.js +4 -0
- package/dist/cap-overview/types.d.ts +3 -1
- package/dist/cap-overview/web/cap-amount-format.d.ts +3 -0
- package/dist/cap-overview/web/cap-amount-format.js +30 -0
- package/dist/cap-overview/web/cap-cards-panel.js +63 -23
- package/dist/cap-overview/web/cap-usage-bar.js +9 -4
- package/dist/cap-overview/web/cap-usage-cell.js +4 -2
- package/dist/cap-overview/web/usage-math.d.ts +1 -0
- package/dist/cap-overview/web/usage-math.js +4 -1
- package/dist/channel-email/app-transport.d.ts +14 -0
- package/dist/channel-email/app-transport.js +20 -0
- package/dist/channel-email/feature.js +6 -0
- package/dist/channel-email/index.d.ts +1 -0
- package/dist/channel-email/index.js +1 -0
- package/dist/channel-email/smtp-transport.js +2 -19
- package/dist/compliance-profiles/schema/profile-selection.d.ts +8 -8
- package/dist/foundation-shared/index.d.ts +1 -0
- package/dist/foundation-shared/index.js +1 -0
- package/dist/foundation-shared/mail-display-name.d.ts +1 -0
- package/dist/foundation-shared/mail-display-name.js +18 -0
- package/dist/inbound-mail-foundation/account-record.d.ts +13 -0
- package/dist/inbound-mail-foundation/account-record.js +27 -0
- package/dist/inbound-mail-foundation/feature.js +1 -1
- package/dist/inbound-mail-foundation/i18n.js +17 -0
- package/dist/inbound-mail-foundation/index.d.ts +3 -1
- package/dist/inbound-mail-foundation/index.js +3 -1
- package/dist/inbound-mail-foundation/outbound-mail.d.ts +28 -0
- package/dist/inbound-mail-foundation/outbound-mail.js +52 -0
- package/dist/inbound-mail-foundation/probe.js +5 -28
- package/dist/inbound-mail-foundation/screens.d.ts +2 -0
- package/dist/inbound-mail-foundation/screens.js +14 -0
- package/dist/inbound-mail-foundation/send-from-account.d.ts +31 -0
- package/dist/inbound-mail-foundation/send-from-account.js +87 -0
- package/dist/inbound-mail-foundation/types.d.ts +4 -0
- package/dist/inbound-mail-foundation/watch-supervisor.js +10 -8
- package/dist/inbound-provider-imap/connect-mailbox.d.ts +13 -0
- package/dist/inbound-provider-imap/connect-mailbox.js +124 -0
- package/dist/inbound-provider-imap/constants.d.ts +41 -0
- package/dist/inbound-provider-imap/constants.js +39 -0
- package/dist/inbound-provider-imap/credential-document.d.ts +6 -0
- package/dist/inbound-provider-imap/credential-document.js +31 -1
- package/dist/inbound-provider-imap/feature.d.ts +1 -1
- package/dist/inbound-provider-imap/feature.js +13 -22
- package/dist/inbound-provider-imap/i18n.d.ts +3 -0
- package/dist/inbound-provider-imap/i18n.js +45 -0
- package/dist/inbound-provider-imap/imap-client.d.ts +1 -0
- package/dist/inbound-provider-imap/imap-client.js +1 -1
- package/dist/inbound-provider-imap/screens.d.ts +2 -0
- package/dist/inbound-provider-imap/screens.js +39 -0
- package/dist/inbound-provider-imap/send-mail.d.ts +2 -0
- package/dist/inbound-provider-imap/send-mail.js +48 -0
- package/dist/inbound-provider-imap/sent-folder.d.ts +8 -0
- package/dist/inbound-provider-imap/sent-folder.js +40 -0
- package/dist/inbound-provider-imap/smtp-client.d.ts +35 -0
- package/dist/inbound-provider-imap/smtp-client.js +106 -0
- package/dist/ledger/entity.d.ts +8 -8
- package/dist/mail-foundation/i18n.d.ts +9 -1
- package/dist/mail-foundation/i18n.js +9 -1
- package/dist/mail-foundation/probe.js +32 -16
- package/dist/readiness/built-in-probes.d.ts +2 -1
- package/dist/readiness/built-in-probes.js +12 -1
- package/dist/readiness/constants.d.ts +5 -0
- package/dist/readiness/constants.js +1 -0
- package/dist/readiness/i18n.js +7 -1
- package/dist/readiness/index.d.ts +1 -1
- package/dist/readiness/index.js +1 -1
- package/dist/readiness/schema/probe-run.d.ts +8 -8
- package/dist/readiness/screens.d.ts +3 -0
- package/dist/readiness/screens.js +25 -2
- package/dist/readiness/visible-results.d.ts +2 -1
- package/dist/template-resolver/table.d.ts +36 -36
- package/dist/template-resolver/user-content-table.d.ts +26 -26
- package/dist/tenant/invitation-table.d.ts +8 -8
- package/dist/tenant/schema/tenant.d.ts +10 -10
- package/dist/tier-engine/entity.d.ts +3 -3
- package/dist/tier-engine/feature.js +8 -4
- package/dist/tier-engine/tier-resolver.d.ts +3 -3
- package/dist/user/schema/user.d.ts +8 -8
- package/dist/user-data-rights/handlers/download-by-token.query.js +3 -3
- package/dist/user-data-rights/schema/download-token.js +5 -3
- package/dist/user-data-rights/schema/export-job.d.ts +8 -8
- package/dist/user-data-rights/token-helpers.d.ts +1 -2
- package/dist/user-data-rights/token-helpers.js +5 -4
- package/dist/waitlist/entity.d.ts +8 -8
- package/package.json +11 -11
- package/src/admin-shell/changes.json +6 -0
- package/src/cap-overview/changes.json +12 -0
- package/src/channel-email/changes.json +6 -0
- package/src/foundation-shared/changes.json +6 -0
- package/src/inbound-mail-foundation/changes.json +18 -0
- package/src/inbound-provider-imap/changes.json +12 -0
- package/src/mail-foundation/changes.json +6 -0
- package/src/readiness/changes.json +30 -0
- package/src/tier-engine/changes.json +6 -0
- package/src/workflow-runner/changes.json +6 -0
|
@@ -15,15 +15,15 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
15
15
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
16
16
|
readonly display?: "radio" | "dropdown";
|
|
17
17
|
readonly optionTones?: {
|
|
18
|
-
readonly "ai-prompt"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
19
|
-
readonly "document-pdf"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
20
|
-
readonly "image-snapshot"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
21
|
-
readonly mail?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
22
|
-
readonly "mail-layout"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
23
|
-
readonly notification?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
24
|
-
readonly "pdf-layout"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
25
|
-
readonly snippet?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
26
|
-
readonly "text-block"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
18
|
+
readonly "ai-prompt"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
19
|
+
readonly "document-pdf"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
20
|
+
readonly "image-snapshot"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
21
|
+
readonly mail?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
22
|
+
readonly "mail-layout"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
23
|
+
readonly notification?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
24
|
+
readonly "pdf-layout"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
25
|
+
readonly snippet?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
26
|
+
readonly "text-block"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
27
27
|
} | undefined;
|
|
28
28
|
readonly optionsQuery?: string;
|
|
29
29
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -56,10 +56,10 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
56
56
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
57
57
|
readonly display?: "radio" | "dropdown";
|
|
58
58
|
readonly optionTones?: {
|
|
59
|
-
readonly html?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
60
|
-
readonly markdown?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
61
|
-
readonly mjml?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
62
|
-
readonly plain?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
59
|
+
readonly html?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
60
|
+
readonly markdown?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
61
|
+
readonly mjml?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
62
|
+
readonly plain?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
63
63
|
} | undefined;
|
|
64
64
|
readonly optionsQuery?: string;
|
|
65
65
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -89,8 +89,8 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
89
89
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
90
90
|
readonly display?: "radio" | "dropdown";
|
|
91
91
|
readonly optionTones?: {
|
|
92
|
-
readonly system?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
93
|
-
readonly tenant?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
92
|
+
readonly system?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
93
|
+
readonly tenant?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
94
94
|
} | undefined;
|
|
95
95
|
readonly optionsQuery?: string;
|
|
96
96
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -114,9 +114,9 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
114
114
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
115
115
|
readonly display?: "radio" | "dropdown";
|
|
116
116
|
readonly optionTones?: {
|
|
117
|
-
readonly active?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
118
|
-
readonly archived?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
119
|
-
readonly draft?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
117
|
+
readonly active?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
118
|
+
readonly archived?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
119
|
+
readonly draft?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
120
120
|
} | undefined;
|
|
121
121
|
readonly optionsQuery?: string;
|
|
122
122
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -179,15 +179,15 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
|
|
|
179
179
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
180
180
|
readonly display?: "radio" | "dropdown";
|
|
181
181
|
readonly optionTones?: {
|
|
182
|
-
readonly "ai-prompt"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
183
|
-
readonly "document-pdf"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
184
|
-
readonly "image-snapshot"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
185
|
-
readonly mail?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
186
|
-
readonly "mail-layout"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
187
|
-
readonly notification?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
188
|
-
readonly "pdf-layout"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
189
|
-
readonly snippet?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
190
|
-
readonly "text-block"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
182
|
+
readonly "ai-prompt"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
183
|
+
readonly "document-pdf"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
184
|
+
readonly "image-snapshot"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
185
|
+
readonly mail?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
186
|
+
readonly "mail-layout"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
187
|
+
readonly notification?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
188
|
+
readonly "pdf-layout"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
189
|
+
readonly snippet?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
190
|
+
readonly "text-block"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
191
191
|
} | undefined;
|
|
192
192
|
readonly optionsQuery?: string;
|
|
193
193
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -220,10 +220,10 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
|
|
|
220
220
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
221
221
|
readonly display?: "radio" | "dropdown";
|
|
222
222
|
readonly optionTones?: {
|
|
223
|
-
readonly html?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
224
|
-
readonly markdown?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
225
|
-
readonly mjml?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
226
|
-
readonly plain?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
223
|
+
readonly html?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
224
|
+
readonly markdown?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
225
|
+
readonly mjml?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
226
|
+
readonly plain?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
227
227
|
} | undefined;
|
|
228
228
|
readonly optionsQuery?: string;
|
|
229
229
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -253,8 +253,8 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
|
|
|
253
253
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
254
254
|
readonly display?: "radio" | "dropdown";
|
|
255
255
|
readonly optionTones?: {
|
|
256
|
-
readonly system?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
257
|
-
readonly tenant?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
256
|
+
readonly system?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
257
|
+
readonly tenant?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
258
258
|
} | undefined;
|
|
259
259
|
readonly optionsQuery?: string;
|
|
260
260
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -278,9 +278,9 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
|
|
|
278
278
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
279
279
|
readonly display?: "radio" | "dropdown";
|
|
280
280
|
readonly optionTones?: {
|
|
281
|
-
readonly active?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
282
|
-
readonly archived?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
283
|
-
readonly draft?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
281
|
+
readonly active?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
282
|
+
readonly archived?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
283
|
+
readonly draft?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
284
284
|
} | undefined;
|
|
285
285
|
readonly optionsQuery?: string;
|
|
286
286
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -18,15 +18,15 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
18
18
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
19
19
|
readonly display?: "radio" | "dropdown";
|
|
20
20
|
readonly optionTones?: {
|
|
21
|
-
readonly "ai-prompt"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
22
|
-
readonly "document-pdf"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
23
|
-
readonly "image-snapshot"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
24
|
-
readonly mail?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
25
|
-
readonly "mail-layout"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
26
|
-
readonly notification?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
27
|
-
readonly "pdf-layout"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
28
|
-
readonly snippet?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
29
|
-
readonly "text-block"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
21
|
+
readonly "ai-prompt"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
22
|
+
readonly "document-pdf"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
23
|
+
readonly "image-snapshot"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
24
|
+
readonly mail?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
25
|
+
readonly "mail-layout"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
26
|
+
readonly notification?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
27
|
+
readonly "pdf-layout"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
28
|
+
readonly snippet?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
29
|
+
readonly "text-block"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
30
30
|
} | undefined;
|
|
31
31
|
readonly optionsQuery?: string;
|
|
32
32
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -59,10 +59,10 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
59
59
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
60
60
|
readonly display?: "radio" | "dropdown";
|
|
61
61
|
readonly optionTones?: {
|
|
62
|
-
readonly html?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
63
|
-
readonly markdown?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
64
|
-
readonly mjml?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
65
|
-
readonly plain?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
62
|
+
readonly html?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
63
|
+
readonly markdown?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
64
|
+
readonly mjml?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
65
|
+
readonly plain?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
66
66
|
} | undefined;
|
|
67
67
|
readonly optionsQuery?: string;
|
|
68
68
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -91,15 +91,15 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
|
|
|
91
91
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
92
92
|
readonly display?: "radio" | "dropdown";
|
|
93
93
|
readonly optionTones?: {
|
|
94
|
-
readonly "ai-prompt"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
95
|
-
readonly "document-pdf"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
96
|
-
readonly "image-snapshot"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
97
|
-
readonly mail?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
98
|
-
readonly "mail-layout"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
99
|
-
readonly notification?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
100
|
-
readonly "pdf-layout"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
101
|
-
readonly snippet?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
102
|
-
readonly "text-block"?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
94
|
+
readonly "ai-prompt"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
95
|
+
readonly "document-pdf"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
96
|
+
readonly "image-snapshot"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
97
|
+
readonly mail?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
98
|
+
readonly "mail-layout"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
99
|
+
readonly notification?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
100
|
+
readonly "pdf-layout"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
101
|
+
readonly snippet?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
102
|
+
readonly "text-block"?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
103
103
|
} | undefined;
|
|
104
104
|
readonly optionsQuery?: string;
|
|
105
105
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -132,10 +132,10 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
|
|
|
132
132
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
133
133
|
readonly display?: "radio" | "dropdown";
|
|
134
134
|
readonly optionTones?: {
|
|
135
|
-
readonly html?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
136
|
-
readonly markdown?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
137
|
-
readonly mjml?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
138
|
-
readonly plain?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
135
|
+
readonly html?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
136
|
+
readonly markdown?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
137
|
+
readonly mjml?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
138
|
+
readonly plain?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
139
139
|
} | undefined;
|
|
140
140
|
readonly optionsQuery?: string;
|
|
141
141
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -26,10 +26,10 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
|
|
|
26
26
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
27
27
|
readonly display?: "radio" | "dropdown";
|
|
28
28
|
readonly optionTones?: {
|
|
29
|
-
readonly accepted?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
30
|
-
readonly cancelled?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
31
|
-
readonly expired?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
32
|
-
readonly pending?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
29
|
+
readonly accepted?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
30
|
+
readonly cancelled?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
31
|
+
readonly expired?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
32
|
+
readonly pending?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
33
33
|
} | undefined;
|
|
34
34
|
readonly optionsQuery?: string;
|
|
35
35
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -96,10 +96,10 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
|
|
|
96
96
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
97
97
|
readonly display?: "radio" | "dropdown";
|
|
98
98
|
readonly optionTones?: {
|
|
99
|
-
readonly accepted?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
100
|
-
readonly cancelled?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
101
|
-
readonly expired?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
102
|
-
readonly pending?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
99
|
+
readonly accepted?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
100
|
+
readonly cancelled?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
101
|
+
readonly expired?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
102
|
+
readonly pending?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
103
103
|
} | undefined;
|
|
104
104
|
readonly optionsQuery?: string;
|
|
105
105
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -23,11 +23,11 @@ export declare const tenantEntity: import("@cosmicdrift/kumiko-types/fields").En
|
|
|
23
23
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
24
24
|
readonly display?: "radio" | "dropdown";
|
|
25
25
|
readonly optionTones?: {
|
|
26
|
-
readonly active?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
27
|
-
readonly destroyFailed?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
28
|
-
readonly destroyRequested?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
29
|
-
readonly destroyed?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
30
|
-
readonly destroying?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
26
|
+
readonly active?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
27
|
+
readonly destroyFailed?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
28
|
+
readonly destroyRequested?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
29
|
+
readonly destroyed?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
30
|
+
readonly destroying?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
31
31
|
} | undefined;
|
|
32
32
|
readonly optionsQuery?: string;
|
|
33
33
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -123,11 +123,11 @@ export declare const tenantTable: import("@cosmicdrift/kumiko-framework/db").Ent
|
|
|
123
123
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
124
124
|
readonly display?: "radio" | "dropdown";
|
|
125
125
|
readonly optionTones?: {
|
|
126
|
-
readonly active?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
127
|
-
readonly destroyFailed?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
128
|
-
readonly destroyRequested?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
129
|
-
readonly destroyed?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
130
|
-
readonly destroying?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
126
|
+
readonly active?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
127
|
+
readonly destroyFailed?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
128
|
+
readonly destroyRequested?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
129
|
+
readonly destroyed?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
130
|
+
readonly destroying?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
131
131
|
} | undefined;
|
|
132
132
|
readonly optionsQuery?: string;
|
|
133
133
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -15,9 +15,9 @@ export declare const tierAssignmentEntity: import("@cosmicdrift/kumiko-types/fie
|
|
|
15
15
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
16
16
|
readonly display?: "radio" | "dropdown";
|
|
17
17
|
readonly optionTones?: {
|
|
18
|
-
readonly billing?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
19
|
-
readonly default?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
20
|
-
readonly manual?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
18
|
+
readonly billing?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
19
|
+
readonly default?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
20
|
+
readonly manual?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
21
21
|
} | undefined;
|
|
22
22
|
readonly optionsQuery?: string;
|
|
23
23
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
import { buildEntityTable, createEventStoreExecutor, createTenantDb, fetchOne, selectMany, } from "@cosmicdrift/kumiko-framework/db";
|
|
43
43
|
import { defineEntityCreateHandler, defineEntityListHandler, defineEntityUpdateHandler, defineFeature, defineQueryHandler, HookPhases, SYSTEM_TENANT_ID, TENANT_TIER_RESOLVER_EXT, } from "@cosmicdrift/kumiko-framework/engine";
|
|
44
44
|
import { getUnscopedAggregateStreamMaxVersion } from "@cosmicdrift/kumiko-framework/event-store";
|
|
45
|
+
import { systemScopedRunner } from "@cosmicdrift/kumiko-framework/internal/row-level-security";
|
|
45
46
|
import { createFallbackLogger } from "@cosmicdrift/kumiko-framework/logging";
|
|
46
47
|
import { CACHE_SYNC_TOPICS, isTierAssignmentSyncMessage, } from "@cosmicdrift/kumiko-framework/redis";
|
|
47
48
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
@@ -381,6 +382,9 @@ export function createTierEngineFeature(opts = {}) {
|
|
|
381
382
|
// post-stack-setup, calls build(deps), wires effectiveFeatures.
|
|
382
383
|
const plugin = {
|
|
383
384
|
build: async (deps) => {
|
|
385
|
+
// Preloads and bus-driven reloads run outside any request scope and read every
|
|
386
|
+
// tenant's rows; the enforcing pool would return zero rows and lock paying tenants out.
|
|
387
|
+
const systemDb = systemScopedRunner(deps.db, "tier cache preloads and reloads assignments and tenant creation times of all tenants");
|
|
384
388
|
// Always-on set: all non-toggleable features in the registry. Canonical
|
|
385
389
|
// Kumiko pattern (matches the feature-toggles resolver): only features
|
|
386
390
|
// that explicitly register `r.toggleable()` are tier-cuttable.
|
|
@@ -394,7 +398,7 @@ export function createTierEngineFeature(opts = {}) {
|
|
|
394
398
|
computedAlwaysOn.add(feature.name);
|
|
395
399
|
}
|
|
396
400
|
alwaysOnHolder.set = computedAlwaysOn;
|
|
397
|
-
const rows = await selectMany(
|
|
401
|
+
const rows = await selectMany(systemDb, tierAssignmentTable);
|
|
398
402
|
for (const row of rows) {
|
|
399
403
|
cache.set(row.tenantId, mergeAlwaysOn(computedAlwaysOn, featuresForTier(tierMap, row.tier)));
|
|
400
404
|
}
|
|
@@ -402,7 +406,7 @@ export function createTierEngineFeature(opts = {}) {
|
|
|
402
406
|
// to the default tier, which would lock paying tenants out meanwhile.
|
|
403
407
|
const reloadTenant = async (tenantId) => {
|
|
404
408
|
const ticket = takeTicket(tenantId);
|
|
405
|
-
const row = await fetchOne(
|
|
409
|
+
const row = await fetchOne(systemDb, tierAssignmentTable, { tenantId });
|
|
406
410
|
// skip: a newer write or reload for this tenant started meanwhile and owns the entry
|
|
407
411
|
if (latestTicket.get(tenantId) !== ticket)
|
|
408
412
|
return;
|
|
@@ -416,7 +420,7 @@ export function createTierEngineFeature(opts = {}) {
|
|
|
416
420
|
const reloadAllTenants = async () => {
|
|
417
421
|
ticketCounter += 1;
|
|
418
422
|
const startedAtTicket = ticketCounter;
|
|
419
|
-
const current = await selectMany(
|
|
423
|
+
const current = await selectMany(systemDb, tierAssignmentTable);
|
|
420
424
|
const loaded = new Map();
|
|
421
425
|
for (const row of current) {
|
|
422
426
|
loaded.set(row.tenantId, mergeAlwaysOn(computedAlwaysOn, featuresForTier(tierMap, row.tier)));
|
|
@@ -491,7 +495,7 @@ export function createTierEngineFeature(opts = {}) {
|
|
|
491
495
|
return false;
|
|
492
496
|
let startedMsPromise = startedMemo.get(tenantId);
|
|
493
497
|
if (startedMsPromise === undefined) {
|
|
494
|
-
startedMsPromise = fetchOne(
|
|
498
|
+
startedMsPromise = fetchOne(systemDb, tenantTable, {
|
|
495
499
|
id: tenantId,
|
|
496
500
|
}).then((row) => row?.insertedAt?.epochMilliseconds);
|
|
497
501
|
// Evict on rejection too — a transient DB error must not poison
|
|
@@ -22,9 +22,9 @@ export declare function createTierResolver<TTier extends string, TCaps>(deps: Ti
|
|
|
22
22
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
23
23
|
readonly display?: "radio" | "dropdown";
|
|
24
24
|
readonly optionTones?: {
|
|
25
|
-
readonly billing?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
26
|
-
readonly default?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
27
|
-
readonly manual?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
25
|
+
readonly billing?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
26
|
+
readonly default?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
27
|
+
readonly manual?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
28
28
|
} | undefined;
|
|
29
29
|
readonly optionsQuery?: string;
|
|
30
30
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -69,10 +69,10 @@ export declare const userEntity: import("@cosmicdrift/kumiko-types/fields").Enti
|
|
|
69
69
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
70
70
|
readonly display?: "radio" | "dropdown";
|
|
71
71
|
readonly optionTones?: {
|
|
72
|
-
readonly active?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
73
|
-
readonly deleted?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
74
|
-
readonly deletionRequested?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
75
|
-
readonly restricted?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
72
|
+
readonly active?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
73
|
+
readonly deleted?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
74
|
+
readonly deletionRequested?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
75
|
+
readonly restricted?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
76
76
|
} | undefined;
|
|
77
77
|
readonly optionsQuery?: string;
|
|
78
78
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -142,10 +142,10 @@ export declare const userTable: import("@cosmicdrift/kumiko-framework/db").Entit
|
|
|
142
142
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
143
143
|
readonly display?: "radio" | "dropdown";
|
|
144
144
|
readonly optionTones?: {
|
|
145
|
-
readonly active?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
146
|
-
readonly deleted?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
147
|
-
readonly deletionRequested?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
148
|
-
readonly restricted?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
145
|
+
readonly active?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
146
|
+
readonly deleted?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
147
|
+
readonly deletionRequested?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
148
|
+
readonly restricted?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
149
149
|
} | undefined;
|
|
150
150
|
readonly optionsQuery?: string;
|
|
151
151
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
// 7. Return {url, expiresAt}
|
|
14
14
|
//
|
|
15
15
|
// **Security:**
|
|
16
|
-
// -
|
|
17
|
-
//
|
|
18
|
-
//
|
|
16
|
+
// - The hash is matched by a DB equality lookup, not a constant-time comparison. With
|
|
17
|
+
// 256 bits of token randomness a timing leak reveals at most hash prefixes, never
|
|
18
|
+
// a preimage.
|
|
19
19
|
// - Invalid tokens return 404 without leaking existence, using the same code path
|
|
20
20
|
// as a token that was not found.
|
|
21
21
|
// - The token is tenant-agnostic: UUID + SHA256 makes it globally unique, so no
|
|
@@ -12,7 +12,10 @@ import { createBigIntField, createEntity, createTextField, createTimestampField,
|
|
|
12
12
|
// 3. Plain token remains in worker memory + is passed via
|
|
13
13
|
// RunExportJobsResult to the notification flow. NEVER plain in DB.
|
|
14
14
|
// 4. The download endpoint hashes the incoming token + looks up the
|
|
15
|
-
//
|
|
15
|
+
// row by tokenHash equality. This is a plain DB lookup,
|
|
16
|
+
// not a constant-time comparison: the token carries 256 bits of
|
|
17
|
+
// randomness, so a timing leak can reveal at most hash prefixes,
|
|
18
|
+
// never a preimage.
|
|
16
19
|
//
|
|
17
20
|
// **Multi-use within TTL**: Token is not "consumed" on download.
|
|
18
21
|
// Multiple downloads until expiresAt are allowed — better UX for connection
|
|
@@ -39,8 +42,7 @@ export const exportDownloadTokenEntity = createEntity({
|
|
|
39
42
|
personal: false,
|
|
40
43
|
reason: "technical_reference",
|
|
41
44
|
}),
|
|
42
|
-
// **Hash
|
|
43
|
-
// via konstanter-Zeit-Vergleich.
|
|
45
|
+
// **Hash, never plain.** SHA256 hex (64 chars), looked up by equality.
|
|
44
46
|
tokenHash: createTextField({
|
|
45
47
|
required: true,
|
|
46
48
|
maxLength: 64,
|
|
@@ -31,10 +31,10 @@ export declare const exportJobEntity: import("@cosmicdrift/kumiko-types/fields")
|
|
|
31
31
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
32
32
|
readonly display?: "radio" | "dropdown";
|
|
33
33
|
readonly optionTones?: {
|
|
34
|
-
readonly done?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
35
|
-
readonly failed?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
36
|
-
readonly pending?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
37
|
-
readonly running?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
34
|
+
readonly done?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
35
|
+
readonly failed?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
36
|
+
readonly pending?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
37
|
+
readonly running?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
38
38
|
} | undefined;
|
|
39
39
|
readonly optionsQuery?: string;
|
|
40
40
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -141,10 +141,10 @@ export declare const exportJobsTable: import("@cosmicdrift/kumiko-framework/db")
|
|
|
141
141
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
142
142
|
readonly display?: "radio" | "dropdown";
|
|
143
143
|
readonly optionTones?: {
|
|
144
|
-
readonly done?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
145
|
-
readonly failed?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
146
|
-
readonly pending?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
147
|
-
readonly running?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
144
|
+
readonly done?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
145
|
+
readonly failed?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
146
|
+
readonly pending?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
147
|
+
readonly running?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
148
148
|
} | undefined;
|
|
149
149
|
readonly optionsQuery?: string;
|
|
150
150
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -12,7 +12,6 @@ export declare function generateDownloadToken(): Promise<{
|
|
|
12
12
|
/**
|
|
13
13
|
* Hashes a plain token into its database representation. In the verification path,
|
|
14
14
|
* the download endpoint hashes the incoming token and looks up the hash in the
|
|
15
|
-
* database
|
|
16
|
-
* performs it via `crypto.subtle` or a secure comparison helper.
|
|
15
|
+
* database (no constant-time comparison, see the header comment).
|
|
17
16
|
*/
|
|
18
17
|
export declare function hashDownloadToken(plain: string): Promise<string>;
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
// (SHA256 hex).
|
|
6
6
|
// 2. The database stores ONLY the hash. The plain token remains in worker memory.
|
|
7
7
|
// 3. The notification step sends the plain token to the user by email.
|
|
8
|
-
// 4. The download endpoint hashes the incoming token and
|
|
9
|
-
//
|
|
8
|
+
// 4. The download endpoint hashes the incoming token and looks up the row
|
|
9
|
+
// by tokenHash. No constant-time comparison is needed: the token has
|
|
10
|
+
// 256 bits of randomness, so a timing leak reveals at most hash prefixes, never
|
|
11
|
+
// a preimage.
|
|
10
12
|
//
|
|
11
13
|
// **Multi-use within TTL:** The token is NOT "consumed" on download, so the user
|
|
12
14
|
// can download repeatedly until expiresAt. This matches Google-Takeout (7d) and
|
|
@@ -31,8 +33,7 @@ export async function generateDownloadToken() {
|
|
|
31
33
|
/**
|
|
32
34
|
* Hashes a plain token into its database representation. In the verification path,
|
|
33
35
|
* the download endpoint hashes the incoming token and looks up the hash in the
|
|
34
|
-
* database
|
|
35
|
-
* performs it via `crypto.subtle` or a secure comparison helper.
|
|
36
|
+
* database (no constant-time comparison, see the header comment).
|
|
36
37
|
*/
|
|
37
38
|
export async function hashDownloadToken(plain) {
|
|
38
39
|
const encoded = new TextEncoder().encode(plain);
|
|
@@ -30,10 +30,10 @@ export declare const waitlistEntryEntity: import("@cosmicdrift/kumiko-types/fiel
|
|
|
30
30
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
31
31
|
readonly display?: "radio" | "dropdown";
|
|
32
32
|
readonly optionTones?: {
|
|
33
|
-
readonly invited?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
34
|
-
readonly pending?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
35
|
-
readonly provisioned?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
36
|
-
readonly rejected?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
33
|
+
readonly invited?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
34
|
+
readonly pending?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
35
|
+
readonly provisioned?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
36
|
+
readonly rejected?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
37
37
|
} | undefined;
|
|
38
38
|
readonly optionsQuery?: string;
|
|
39
39
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
@@ -125,10 +125,10 @@ export declare const waitlistEntryTable: import("@cosmicdrift/kumiko-framework/d
|
|
|
125
125
|
readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
|
|
126
126
|
readonly display?: "radio" | "dropdown";
|
|
127
127
|
readonly optionTones?: {
|
|
128
|
-
readonly invited?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
129
|
-
readonly pending?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
130
|
-
readonly provisioned?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
131
|
-
readonly rejected?: "bad" | "neutral" | "ok" | "warn" | undefined;
|
|
128
|
+
readonly invited?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
129
|
+
readonly pending?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
130
|
+
readonly provisioned?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
131
|
+
readonly rejected?: "accent" | "bad" | "critical" | "neutral" | "ok" | "warn" | undefined;
|
|
132
132
|
} | undefined;
|
|
133
133
|
readonly optionsQuery?: string;
|
|
134
134
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-bundled-features",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.392.0",
|
|
4
4
|
"description": "Built-in features — tenant, user, auth, delivery. The stuff you'd rewrite anyway, already typed.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -558,9 +558,9 @@
|
|
|
558
558
|
}
|
|
559
559
|
},
|
|
560
560
|
"dependencies": {
|
|
561
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
562
|
-
"@cosmicdrift/kumiko-renderer": "0.
|
|
563
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
561
|
+
"@cosmicdrift/kumiko-framework": "0.392.0",
|
|
562
|
+
"@cosmicdrift/kumiko-renderer": "0.392.0",
|
|
563
|
+
"@cosmicdrift/kumiko-types": "0.392.0",
|
|
564
564
|
"@mollie/api-client": "^4.5.0",
|
|
565
565
|
"@node-rs/argon2": "^2.0.2",
|
|
566
566
|
"@tiptap/core": "^3.31.3",
|
|
@@ -1142,17 +1142,17 @@
|
|
|
1142
1142
|
],
|
|
1143
1143
|
"devDependencies": {
|
|
1144
1144
|
"@testing-library/user-event": "^14.6.1",
|
|
1145
|
-
"@cosmicdrift/kumiko-locale-de": "0.
|
|
1146
|
-
"@cosmicdrift/kumiko-locale-es": "0.
|
|
1147
|
-
"@cosmicdrift/kumiko-locale-fr": "0.
|
|
1148
|
-
"@cosmicdrift/kumiko-locale-it": "0.
|
|
1149
|
-
"@cosmicdrift/kumiko-renderer-mail-html": "0.
|
|
1145
|
+
"@cosmicdrift/kumiko-locale-de": "0.392.0",
|
|
1146
|
+
"@cosmicdrift/kumiko-locale-es": "0.392.0",
|
|
1147
|
+
"@cosmicdrift/kumiko-locale-fr": "0.392.0",
|
|
1148
|
+
"@cosmicdrift/kumiko-locale-it": "0.392.0",
|
|
1149
|
+
"@cosmicdrift/kumiko-renderer-mail-html": "0.392.0",
|
|
1150
1150
|
"jsqr": "^1.4.0",
|
|
1151
1151
|
"unpdf": "^1.8.1",
|
|
1152
|
-
"@cosmicdrift/kumiko-testing": "0.
|
|
1152
|
+
"@cosmicdrift/kumiko-testing": "0.392.0"
|
|
1153
1153
|
},
|
|
1154
1154
|
"peerDependencies": {
|
|
1155
|
-
"@cosmicdrift/kumiko-testing": "0.
|
|
1155
|
+
"@cosmicdrift/kumiko-testing": "0.392.0"
|
|
1156
1156
|
},
|
|
1157
1157
|
"peerDependenciesMeta": {
|
|
1158
1158
|
"@cosmicdrift/kumiko-testing": {
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.392.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "includeTenantOverview turns the tenant overview off",
|
|
6
|
+
"detail": "createAdminShellFeature({ includeTenantOverview: false }) registers neither the tenant overview screen nor its nav and leaves it out of the tenant workspace. The default stays true."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.363.0",
|
|
4
10
|
"type": "improvement",
|