@cosmicdrift/kumiko-bundled-features 0.269.2 → 0.273.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 +9 -9
- package/src/__tests__/account-security-composition.boot.test.ts +25 -7
- package/src/__tests__/account-security-composition.integration.test.ts +23 -1
- package/src/__tests__/account-security-fixture.ts +3 -0
- package/src/agent-tools/__tests__/agent-doc-lint.test.ts +3 -1
- package/src/agent-tools/__tests__/feature.test.ts +10 -4
- package/src/audit/__tests__/escape-hatch-audit.integration.test.ts +96 -0
- package/src/audit/changes.json +12 -0
- package/src/audit/escape-hatch-audit-sink.ts +52 -0
- package/src/audit/feature.ts +5 -1
- package/src/audit/index.ts +1 -0
- package/src/auth-email-password/__tests__/query-as-member.integration.test.ts +303 -0
- package/src/auth-email-password/handlers/invite-accept.write.ts +8 -1
- package/src/auth-mfa/handlers/disable.write.ts +7 -1
- package/src/auth-mfa/handlers/enable-confirm.write.ts +7 -1
- package/src/auth-mfa/handlers/enable-start.write.ts +7 -1
- package/src/auth-mfa/handlers/regenerate-recovery.write.ts +7 -1
- package/src/auth-mfa/handlers/status.query.ts +7 -1
- package/src/auth-mfa/screens.ts +26 -3
- package/src/cap-counter/feature.ts +5 -3
- package/src/cap-overview/screens.ts +6 -0
- package/src/channel-in-app/handlers/inbox.query.ts +7 -1
- package/src/channel-in-app/handlers/mark-all-read.write.ts +7 -1
- package/src/channel-in-app/handlers/mark-read.write.ts +7 -1
- package/src/channel-in-app/handlers/unread-count.query.ts +7 -1
- package/src/compliance-profiles/handlers/for-tenant.query.ts +7 -1
- package/src/compliance-profiles/handlers/list-profiles.query.ts +7 -1
- package/src/config/__tests__/config.integration.test.ts +1 -1
- package/src/config/__tests__/reencrypt-job-tenant-checks.integration.test.ts +2 -1
- package/src/config/__tests__/tz-resolution.integration.test.ts +1 -1
- package/src/config/changes.json +6 -0
- package/src/config/db/queries/__tests__/resolver.test.ts +43 -38
- package/src/config/db/queries/resolver.ts +22 -22
- package/src/config/handlers/cascade.query.ts +13 -1
- package/src/config/handlers/readiness.query.ts +13 -1
- package/src/config/handlers/reencrypt.job.ts +21 -2
- package/src/config/handlers/reset.write.ts +7 -1
- package/src/config/handlers/schema.query.ts +13 -1
- package/src/config/handlers/set.write.ts +7 -1
- package/src/config/handlers/values.query.ts +13 -1
- package/src/data-retention/handlers/policy-for.query.ts +8 -1
- package/src/delivery/__tests__/delivery-pii-kms.integration.test.ts +2 -2
- package/src/delivery/__tests__/delivery-screens.boot.test.ts +2 -4
- package/src/delivery/__tests__/delivery.integration.test.ts +39 -5
- package/src/delivery/changes.json +6 -0
- package/src/delivery/delivery-service.ts +25 -3
- package/src/delivery/handlers/preferences.query.ts +13 -1
- package/src/delivery/handlers/set-preference.write.ts +7 -1
- package/src/delivery/testing.ts +8 -1
- package/src/derivatives-sharp/__tests__/derivatives-sharp.integration.test.ts +1 -1
- package/src/folders/__tests__/feature.test.ts +14 -5
- package/src/folders/__tests__/folders-parent-visibility.integration.test.ts +6 -1
- package/src/folders/__tests__/folders-read-gate.integration.test.ts +6 -1
- package/src/folders/__tests__/folders.integration.test.ts +6 -1
- package/src/folders/feature.ts +2 -2
- package/src/form-draft/constants.ts +7 -1
- package/src/jobs/handlers/list.query.ts +3 -1
- package/src/ledger/__tests__/ledger.integration.test.ts +57 -0
- package/src/managed-pages/screens/branding-screen.ts +3 -0
- package/src/managed-pages/screens/page-screens.ts +3 -0
- package/src/notes-history/__tests__/notes-read-gate.integration.test.ts +10 -2
- package/src/notes-history/__tests__/notes-section.test.tsx +23 -0
- package/src/notes-history/feature.ts +2 -2
- package/src/notes-history/web/i18n.ts +3 -0
- package/src/notes-history/web/notes-section.tsx +61 -51
- package/src/personal-access-tokens/handlers/available-scopes.query.ts +7 -1
- package/src/personal-access-tokens/handlers/create.write.ts +7 -1
- package/src/personal-access-tokens/handlers/list.query.ts +7 -1
- package/src/personal-access-tokens/handlers/revoke.write.ts +7 -1
- package/src/personal-access-tokens/screens.ts +15 -2
- package/src/secrets/__tests__/access-options-precedence.test.ts +11 -4
- package/src/secrets/__tests__/access-options.integration.test.ts +5 -1
- package/src/secrets/feature.ts +2 -2
- package/src/sessions/handlers/mine.query.ts +7 -1
- package/src/sessions/handlers/revoke-all-others.write.ts +7 -1
- package/src/sessions/handlers/revoke.write.ts +7 -1
- package/src/sessions/screens.ts +9 -1
- package/src/tags/__tests__/feature.test.ts +25 -8
- package/src/tags/__tests__/tags-parent-visibility.integration.test.ts +6 -1
- package/src/tags/__tests__/tags-read-gate.integration.test.ts +7 -2
- package/src/tags/__tests__/tags.integration.test.ts +6 -1
- package/src/tags/constants.ts +1 -1
- package/src/tags/feature.ts +2 -2
- package/src/tags/screens.ts +3 -0
- package/src/tenant/__tests__/members-facet-i18n.test.ts +5 -5
- package/src/tenant/__tests__/tenant-timezone-boot.integration.test.ts +2 -2
- package/src/tenant/__tests__/tenant.integration.test.ts +5 -1
- package/src/tenant/changes.json +6 -0
- package/src/tenant/handlers/me.query.ts +13 -1
- package/src/tenant/handlers/update-member-roles.write.ts +10 -1
- package/src/tenant/screens.ts +3 -0
- package/src/tenant/seeding.ts +25 -19
- package/src/tier-engine/feature.ts +3 -0
- package/src/user/changes.json +6 -0
- package/src/user/handlers/me.query.ts +13 -1
- package/src/user/handlers/update-roles.ts +8 -5
- package/src/user/screens.ts +3 -0
- package/src/user-data-rights/__tests__/boot-checks.test.ts +16 -0
- package/src/user-data-rights/__tests__/export-job-list-cross-tenant.integration.test.ts +1 -1
- package/src/user-data-rights/__tests__/inspector-screens.boot.test.ts +6 -1
- package/src/user-data-rights/feature.ts +11 -6
- package/src/user-data-rights/handlers/cancel-deletion.write.ts +7 -1
- package/src/user-data-rights/handlers/download-attempt-list.query.ts +4 -1
- package/src/user-data-rights/handlers/download-by-job.query.ts +7 -1
- package/src/user-data-rights/handlers/export-job-detail.query.ts +4 -1
- package/src/user-data-rights/handlers/export-job-list.query.ts +4 -1
- package/src/user-data-rights/handlers/export-status.query.ts +7 -1
- package/src/user-data-rights/handlers/my-audit-log.query.ts +8 -1
- package/src/user-data-rights/handlers/request-deletion.write.ts +7 -1
- package/src/user-data-rights/handlers/request-export.write.ts +7 -1
- package/src/user-data-rights/handlers/restrict-account.write.ts +8 -1
- package/src/user-data-rights/lib/is-admin-actor.ts +1 -1
- package/src/user-data-rights/screens.ts +3 -0
- package/src/user-profile/__tests__/profile-screen.boot.test.ts +6 -1
- package/src/user-profile/feature.ts +11 -1
- package/src/workflow-runner/__tests__/pending-projection.integration.test.ts +1 -1
|
@@ -4,7 +4,10 @@ import { exportJobEntity } from "../schema/export-job";
|
|
|
4
4
|
// Detail fetch backing the read-only export-job inspector screen.
|
|
5
5
|
export const exportJobDetailQuery = defineEntityDetailHandler("export-job", exportJobEntity, {
|
|
6
6
|
access: { roles: access.systemAdmin },
|
|
7
|
-
|
|
7
|
+
escapeHatch: {
|
|
8
|
+
reason:
|
|
9
|
+
"SystemAdmin GDPR Art. 20 export inspector opens one data-export job owned by any tenant for platform-operator support",
|
|
10
|
+
},
|
|
8
11
|
description:
|
|
9
12
|
"Read-only cross-tenant detail view of one GDPR data-export job for the system-admin inspector, showing its lifecycle timestamps, storage key, byte count and error message.",
|
|
10
13
|
});
|
|
@@ -5,7 +5,10 @@ import { exportJobEntity } from "../schema/export-job";
|
|
|
5
5
|
// rows are created by the user's request-export flow, never through this handler.
|
|
6
6
|
export const exportJobListQuery = defineEntityListHandler("export-job", exportJobEntity, {
|
|
7
7
|
access: { roles: access.systemAdmin },
|
|
8
|
-
|
|
8
|
+
escapeHatch: {
|
|
9
|
+
reason:
|
|
10
|
+
"SystemAdmin GDPR Art. 20 export inspector lists data-export jobs of every tenant for platform-operator support",
|
|
11
|
+
},
|
|
9
12
|
description:
|
|
10
13
|
"Read-only cross-tenant list of GDPR Art. 20 data-export jobs for the system-admin inspector; use export-status instead when a user asks about their own export.",
|
|
11
14
|
});
|
|
@@ -35,7 +35,13 @@ type ExportJobRow = {
|
|
|
35
35
|
export const exportStatusQuery = defineQueryHandler({
|
|
36
36
|
name: "export-status",
|
|
37
37
|
schema: z.object({}),
|
|
38
|
-
access: {
|
|
38
|
+
access: {
|
|
39
|
+
openToAll: {
|
|
40
|
+
reason:
|
|
41
|
+
"each signed-in user reads only their own most recent export job; the query " +
|
|
42
|
+
"filters exportJobsTable by the caller's own userId",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
39
45
|
description:
|
|
40
46
|
"Returns the calling user's own most recent data-export job with its status, expiry and error, or hasJob false, for polling after a request-export while the job is still running.",
|
|
41
47
|
escapeHatch: {
|
|
@@ -28,7 +28,14 @@ export const myAuditLogQuery = defineQueryHandler({
|
|
|
28
28
|
message: "`from` must be less than or equal to `to`",
|
|
29
29
|
path: ["from"],
|
|
30
30
|
}),
|
|
31
|
-
access: {
|
|
31
|
+
access: {
|
|
32
|
+
openToAll: {
|
|
33
|
+
reason:
|
|
34
|
+
"each signed-in user reads only their own event-store history for the GDPR " +
|
|
35
|
+
"Art. 15 self-disclosure; the query hard-codes createdBy = caller and can never " +
|
|
36
|
+
"read another user's history",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
32
39
|
description:
|
|
33
40
|
"Returns the calling user's own event-store entries across all their tenant memberships, paged and filterable by aggregate type, event type and time range, for the GDPR Art. 15 self-disclosure; it can never read another user's history.",
|
|
34
41
|
escapeHatch: {
|
|
@@ -43,7 +43,13 @@ export function createRequestDeletionHandler(opts: RequestDeletionOptions = {})
|
|
|
43
43
|
return defineWriteHandler({
|
|
44
44
|
name: "request-deletion",
|
|
45
45
|
schema: z.object({}),
|
|
46
|
-
access: {
|
|
46
|
+
access: {
|
|
47
|
+
openToAll: {
|
|
48
|
+
reason:
|
|
49
|
+
"each signed-in user starts deletion of only their own account; the grace " +
|
|
50
|
+
"period is armed for the caller's own userId",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
47
53
|
escapeHatch: {
|
|
48
54
|
reason:
|
|
49
55
|
"startDeletionGracePeriod reads the tenant compliance profile via ctx.queryAs(SYSTEM, " +
|
|
@@ -60,7 +60,13 @@ function isActiveJobConflict(failure: WriteFailure): boolean {
|
|
|
60
60
|
export const requestExportWrite = defineWriteHandler({
|
|
61
61
|
name: "request-export",
|
|
62
62
|
schema: z.object({}),
|
|
63
|
-
access: {
|
|
63
|
+
access: {
|
|
64
|
+
openToAll: {
|
|
65
|
+
reason:
|
|
66
|
+
"each signed-in user queues only their own data export; the active-job " +
|
|
67
|
+
"check and the created job are both keyed by the caller's own userId",
|
|
68
|
+
},
|
|
69
|
+
},
|
|
64
70
|
description:
|
|
65
71
|
"Queues a GDPR Art. 15 and 20 data export for the calling user and returns its job id, handing back the running job with isExisting true instead of a second one when an export is already pending.",
|
|
66
72
|
escapeHatch: {
|
|
@@ -40,7 +40,14 @@ import { updateUserLifecycle } from "../lib/update-user-lifecycle";
|
|
|
40
40
|
export const restrictAccountWrite = defineWriteHandler({
|
|
41
41
|
name: "restrict-account",
|
|
42
42
|
schema: z.object({ userId: z.string().uuid().optional() }),
|
|
43
|
-
access: {
|
|
43
|
+
access: {
|
|
44
|
+
openToAll: {
|
|
45
|
+
reason:
|
|
46
|
+
"each signed-in user may restrict only their own account by default; targeting " +
|
|
47
|
+
"another userId additionally requires isAdminActor(event.user) and a membership " +
|
|
48
|
+
"row for the target in the admin's own tenant, both checked in the handler body",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
44
51
|
escapeHatch: {
|
|
45
52
|
reason:
|
|
46
53
|
"Revokes all live sessions of the (possibly self-)restricted user via ctx.writeAs(SYSTEM, " +
|
|
@@ -4,7 +4,7 @@ import { access } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
4
4
|
const ADMIN_ROLES: ReadonlySet<string> = new Set(access.admin);
|
|
5
5
|
const SYSTEM_ADMIN_ROLES: ReadonlySet<string> = new Set(access.systemAdmin);
|
|
6
6
|
|
|
7
|
-
// Reused by handlers that
|
|
7
|
+
// Reused by handlers that declare `openToAll` but still need a manual
|
|
8
8
|
// self-or-admin gate (e.g. restrict-account.write.ts) — Set-lookup instead
|
|
9
9
|
// of the O(n·m) `roles.some(role => access.admin.includes(role))` re-scan.
|
|
10
10
|
export function isAdminActor(user: Pick<SessionUser, "roles">): boolean {
|
|
@@ -71,4 +71,7 @@ export const downloadAttemptListScreen: EntityListScreenDefinition = {
|
|
|
71
71
|
columns: ["attemptedAt", "result", "via", "ip", "attemptedByUserId", "jobId"],
|
|
72
72
|
searchable: false,
|
|
73
73
|
access: { roles: access.systemAdmin },
|
|
74
|
+
// Inert until an app navs it (see file header) — no nav area to resolve
|
|
75
|
+
// in isolation.
|
|
76
|
+
dormant: true,
|
|
74
77
|
};
|
|
@@ -46,7 +46,12 @@ describe("user-profile screen (fw#2312 projectionDetail conversion)", () => {
|
|
|
46
46
|
expect(screen?.type).toBe("projectionDetail");
|
|
47
47
|
if (screen?.type === "projectionDetail") {
|
|
48
48
|
expect(screen.query).toBe("user:query:user:me");
|
|
49
|
-
expect(screen.access).toEqual({
|
|
49
|
+
expect(screen.access).toEqual({
|
|
50
|
+
openToAll: {
|
|
51
|
+
reason:
|
|
52
|
+
"each signed-in user manages only their own profile: change-email/password re-authenticate the caller, and deletion request/cancel act on the caller's own userId; no app role name is portable enough to gate this",
|
|
53
|
+
},
|
|
54
|
+
});
|
|
50
55
|
}
|
|
51
56
|
});
|
|
52
57
|
|
|
@@ -77,7 +77,17 @@ export function createUserProfileFeature(): FeatureDefinition {
|
|
|
77
77
|
type: "projectionDetail",
|
|
78
78
|
query: UserProfileQueries.me,
|
|
79
79
|
singleton: true,
|
|
80
|
-
access: {
|
|
80
|
+
access: {
|
|
81
|
+
openToAll: {
|
|
82
|
+
reason:
|
|
83
|
+
"each signed-in user manages only their own profile: change-email/password " +
|
|
84
|
+
"re-authenticate the caller, and deletion request/cancel act on the caller's " +
|
|
85
|
+
"own userId; no app role name is portable enough to gate this",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
// Self-service settings-area screen, placed by the consuming app's own
|
|
89
|
+
// r.nav() (see samples/apps/use-all-bundled's screens-feature.ts).
|
|
90
|
+
dormant: true,
|
|
81
91
|
description:
|
|
82
92
|
"Self-service account page: change password, change email (with re-auth and " +
|
|
83
93
|
"a verification-mail follow-up), and request or cancel account deletion " +
|
|
@@ -52,7 +52,7 @@ const testEventsFeature = defineFeature("wr-pending-test", (r) => {
|
|
|
52
52
|
});
|
|
53
53
|
return { isSuccess: true, data: {} };
|
|
54
54
|
},
|
|
55
|
-
{ access: { openToAll:
|
|
55
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
56
56
|
);
|
|
57
57
|
});
|
|
58
58
|
|