@cosmicdrift/kumiko-bundled-features 0.37.0 → 0.38.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/package.json +5 -5
- package/src/auth-email-password/email-templates.ts +4 -0
- package/src/auth-email-password/errors.ts +84 -0
- package/src/auth-email-password/handlers/change-password.write.ts +1 -10
- package/src/auth-email-password/handlers/invite-accept-with-login.write.ts +3 -19
- package/src/auth-email-password/handlers/invite-accept.write.ts +15 -28
- package/src/auth-email-password/handlers/invite-signup-complete.write.ts +2 -14
- package/src/auth-email-password/handlers/login.write.ts +7 -51
- package/src/auth-email-password/handlers/reset-password.write.ts +3 -10
- package/src/auth-email-password/handlers/signup-confirm.write.ts +2 -14
- package/src/auth-email-password/handlers/verify-email.write.ts +3 -10
- package/src/auth-email-password/web/__tests__/tenant-switcher.test.tsx +24 -0
- package/src/auth-email-password/web/forgot-password-screen.tsx +1 -0
- package/src/auth-email-password/web/tenant-switcher.tsx +2 -1
- package/src/cap-counter/enforce-cap.ts +5 -0
- package/src/compliance-profiles/README.md +1 -1
- package/src/custom-fields/__tests__/feature.test.ts +1 -1
- package/src/custom-fields/__tests__/wire-for-entity.test.ts +4 -4
- package/src/custom-fields/db/queries/retention.ts +1 -0
- package/src/custom-fields/lib/parse-serialized-field.ts +11 -0
- package/src/custom-fields/run-retention.ts +4 -22
- package/src/custom-fields/web/__tests__/custom-fields-form-section.test.tsx +148 -0
- package/src/custom-fields/web/custom-fields-form-section.tsx +26 -12
- package/src/custom-fields/wire-for-entity.ts +4 -12
- package/src/custom-fields/wire-user-data-rights.ts +3 -22
- package/src/data-retention/__tests__/data-retention.integration.test.ts +2 -2
- package/src/file-foundation/feature.ts +13 -3
- package/src/file-foundation/index.ts +1 -0
- package/src/file-provider-inmemory/__tests__/feature.test.ts +4 -7
- package/src/file-provider-s3/__tests__/feature.test.ts +4 -6
- package/src/files/README.md +1 -1
- package/src/subscription-stripe/feature.ts +5 -2
- package/src/template-resolver/feature.ts +1 -2
- package/src/template-resolver/handlers/list.query.ts +7 -14
- package/src/template-resolver/handlers/toggle-status.write.ts +37 -0
- package/src/tenant/command-schemas.ts +1 -1
- package/src/tenant/feature.ts +1 -2
- package/src/tenant/handlers/toggle-enabled.write.ts +23 -0
- package/src/user-data-rights/README.md +8 -8
- package/src/template-resolver/handlers/archive.write.ts +0 -39
- package/src/template-resolver/handlers/publish.write.ts +0 -42
- package/src/tenant/handlers/disable.write.ts +0 -18
- package/src/tenant/handlers/enable.write.ts +0 -20
|
@@ -90,15 +90,15 @@ weglassen wenn er Custom-Hooks registrieren will.
|
|
|
90
90
|
|
|
91
91
|
| Datei | Pinst |
|
|
92
92
|
|-------|-------|
|
|
93
|
-
| `audit-log.integration.ts` | Cross-User-Isolation, Account-weite Sicht, eventType-Filter, Admin-only operator-query, download-attempt 90d-retention |
|
|
94
|
-
| `cross-data-matrix.integration.ts` | 3-Provider-Pipeline (user + fileRef + custom-domain), Cross-Tenant Forget mit user-anonymize, Other-User-Isolation |
|
|
95
|
-
| `download.integration.ts` | HTTP-e2e via `r.httpRoute`: Magic-Link, multi-use, expired, failed-job, storage-cleared, cross-tenant-same-user, malicious-filename |
|
|
96
|
-
| `request-export.integration.ts` | Idempotency, active-job-constraint, cross-tenant-anyMember-userId-pattern |
|
|
97
|
-
| `request-deletion-callback.integration.ts` + `request-cancel-deletion.integration.ts` | Grace + Cancel-Pfad + Email-Callback best-effort |
|
|
98
|
-
| `restriction-flow.integration.ts` | Status-Flip + Auth-Middleware-Block + Lift |
|
|
99
|
-
| `run-{export-jobs,forget-cleanup,user-export}.integration.ts` | Worker-Logic + Idempotency + Email-Callbacks |
|
|
93
|
+
| `audit-log.integration.test.ts` | Cross-User-Isolation, Account-weite Sicht, eventType-Filter, Admin-only operator-query, download-attempt 90d-retention |
|
|
94
|
+
| `cross-data-matrix.integration.test.ts` | 3-Provider-Pipeline (user + fileRef + custom-domain), Cross-Tenant Forget mit user-anonymize, Other-User-Isolation |
|
|
95
|
+
| `download.integration.test.ts` | HTTP-e2e via `r.httpRoute`: Magic-Link, multi-use, expired, failed-job, storage-cleared, cross-tenant-same-user, malicious-filename |
|
|
96
|
+
| `request-export.integration.test.ts` | Idempotency, active-job-constraint, cross-tenant-anyMember-userId-pattern |
|
|
97
|
+
| `request-deletion-callback.integration.test.ts` + `request-cancel-deletion.integration.test.ts` | Grace + Cancel-Pfad + Email-Callback best-effort |
|
|
98
|
+
| `restriction-flow.integration.test.ts` | Status-Flip + Auth-Middleware-Block + Lift |
|
|
99
|
+
| `run-{export-jobs,forget-cleanup,user-export}.integration.test.ts` | Worker-Logic + Idempotency + Email-Callbacks |
|
|
100
100
|
| `policy-to-strategy.test.ts` | Retention.strategy → UserDataDeleteStrategy mapping |
|
|
101
|
-
| `user-data-rights.integration.ts` | Boot-Smoke + Feature-Meta |
|
|
101
|
+
| `user-data-rights.integration.test.ts` | Boot-Smoke + Feature-Meta |
|
|
102
102
|
| `token-helpers.test.ts` + `zip-path.test.ts` | Token-Hashing + Path-Traversal-Schutz |
|
|
103
103
|
| `export-job-{idempotency,schema}.test.ts` | Active-job-uniqueness + Schema-Constraints |
|
|
104
104
|
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
|
-
import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
-
import { NotFoundError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
|
-
import { z } from "zod";
|
|
5
|
-
import type { TemplateResourceRow } from "../table";
|
|
6
|
-
import { templateResourcesTable } from "../table";
|
|
7
|
-
import { executor } from "./shared";
|
|
8
|
-
|
|
9
|
-
// Setzt einen Template-Eintrag auf status='archived'. Resolver liefert
|
|
10
|
-
// archivierte Templates nicht zurück — sie bleiben aber als Audit-Trail
|
|
11
|
-
// in der DB (kein physisches Delete). Reaktivierung via publish.
|
|
12
|
-
export const archiveWrite = defineWriteHandler({
|
|
13
|
-
name: "archive",
|
|
14
|
-
schema: z.object({ id: z.string().min(1) }),
|
|
15
|
-
access: { roles: ["TenantAdmin", "SystemAdmin"] },
|
|
16
|
-
handler: async (event, ctx) => {
|
|
17
|
-
const existing = await fetchOne<TemplateResourceRow>(ctx.db, templateResourcesTable, {
|
|
18
|
-
id: event.payload.id,
|
|
19
|
-
});
|
|
20
|
-
// ctx.db ist via createTenantDb tenant-scoped — existing ist null wenn
|
|
21
|
-
// das Template einem fremden Tenant gehört (SystemAdmin-Cross-Tenant
|
|
22
|
-
// braucht tenantIdOverride im Schema, M2-Erweiterung).
|
|
23
|
-
if (!existing) {
|
|
24
|
-
return writeFailure(new NotFoundError("template-resource", event.payload.id));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const result = await executor.update(
|
|
28
|
-
{
|
|
29
|
-
id: existing.id,
|
|
30
|
-
version: existing.version,
|
|
31
|
-
changes: { status: "archived" as const },
|
|
32
|
-
},
|
|
33
|
-
event.user,
|
|
34
|
-
ctx.db,
|
|
35
|
-
);
|
|
36
|
-
if (!result.isSuccess) return result;
|
|
37
|
-
return { isSuccess: true as const, data: { id: String(existing.id), status: "archived" } };
|
|
38
|
-
},
|
|
39
|
-
});
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
|
-
import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
-
import { NotFoundError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
|
-
import { z } from "zod";
|
|
5
|
-
import type { TemplateResourceRow } from "../table";
|
|
6
|
-
import { templateResourcesTable } from "../table";
|
|
7
|
-
import { executor } from "./shared";
|
|
8
|
-
|
|
9
|
-
// Setzt einen Template-Eintrag auf status='active'. Typischer Workflow:
|
|
10
|
-
// User editiert ein Draft, ist zufrieden, drückt Publish.
|
|
11
|
-
//
|
|
12
|
-
// Tenant-Isolation: Template muss zum event.user.tenantId gehören
|
|
13
|
-
// (oder zu SYSTEM_TENANT wenn SystemAdmin). Cross-Tenant-Publish-
|
|
14
|
-
// Versuche → NotFound (Pattern aus row-level-security).
|
|
15
|
-
export const publishWrite = defineWriteHandler({
|
|
16
|
-
name: "publish",
|
|
17
|
-
schema: z.object({ id: z.string().min(1) }),
|
|
18
|
-
access: { roles: ["TenantAdmin", "SystemAdmin"] },
|
|
19
|
-
handler: async (event, ctx) => {
|
|
20
|
-
const existing = await fetchOne<TemplateResourceRow>(ctx.db, templateResourcesTable, {
|
|
21
|
-
id: event.payload.id,
|
|
22
|
-
});
|
|
23
|
-
// ctx.db ist via createTenantDb tenant-scoped — existing ist null wenn
|
|
24
|
-
// das Template einem fremden Tenant gehört (SystemAdmin-Cross-Tenant
|
|
25
|
-
// braucht tenantIdOverride im Schema, M2-Erweiterung).
|
|
26
|
-
if (!existing) {
|
|
27
|
-
return writeFailure(new NotFoundError("template-resource", event.payload.id));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const result = await executor.update(
|
|
31
|
-
{
|
|
32
|
-
id: existing.id,
|
|
33
|
-
version: existing.version,
|
|
34
|
-
changes: { status: "active" as const },
|
|
35
|
-
},
|
|
36
|
-
event.user,
|
|
37
|
-
ctx.db,
|
|
38
|
-
);
|
|
39
|
-
if (!result.isSuccess) return result;
|
|
40
|
-
return { isSuccess: true as const, data: { id: String(existing.id), status: "active" } };
|
|
41
|
-
},
|
|
42
|
-
});
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
-
import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
import { tenantEntity, tenantTable } from "../schema/tenant";
|
|
5
|
-
|
|
6
|
-
const crud = createEventStoreExecutor(tenantTable, tenantEntity, { entityName: "tenant" });
|
|
7
|
-
|
|
8
|
-
export const disableWrite = defineWriteHandler({
|
|
9
|
-
name: "disable",
|
|
10
|
-
schema: z.object({ id: z.uuid() }),
|
|
11
|
-
access: { roles: ["SystemAdmin"] },
|
|
12
|
-
// Admin flip: last-writer-wins is fine. SystemAdmin is the only caller and
|
|
13
|
-
// there's no meaningful concurrent-edit race on this single boolean.
|
|
14
|
-
handler: async (event, ctx) =>
|
|
15
|
-
crud.update({ id: event.payload.id, changes: { isEnabled: false } }, event.user, ctx.db, {
|
|
16
|
-
skipOptimisticLock: true,
|
|
17
|
-
}),
|
|
18
|
-
});
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
-
import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
import { tenantEntity, tenantTable } from "../schema/tenant";
|
|
5
|
-
|
|
6
|
-
const crud = createEventStoreExecutor(tenantTable, tenantEntity, { entityName: "tenant" });
|
|
7
|
-
|
|
8
|
-
// Recovery-Gegenstück zu disable — ohne enable wäre ein Fehlklick des
|
|
9
|
-
// Operators nur per Event-Hack reversibel.
|
|
10
|
-
export const enableWrite = defineWriteHandler({
|
|
11
|
-
name: "enable",
|
|
12
|
-
schema: z.object({ id: z.uuid() }),
|
|
13
|
-
access: { roles: ["SystemAdmin"] },
|
|
14
|
-
// Admin flip: last-writer-wins is fine. SystemAdmin is the only caller and
|
|
15
|
-
// there's no meaningful concurrent-edit race on this single boolean.
|
|
16
|
-
handler: async (event, ctx) =>
|
|
17
|
-
crud.update({ id: event.payload.id, changes: { isEnabled: true } }, event.user, ctx.db, {
|
|
18
|
-
skipOptimisticLock: true,
|
|
19
|
-
}),
|
|
20
|
-
});
|