@company-semantics/contracts 9.0.0 → 9.2.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 +6 -3
- package/src/__tests__/resource-keys.test.ts +30 -23
- package/src/admin/authz-simulate.ts +4 -4
- package/src/admin/direct-grants.ts +2 -2
- package/src/api/generated-spec-hash.ts +2 -2
- package/src/api/generated.ts +97 -0
- package/src/api/http/routes/ai-chat.ts +3 -3
- package/src/api/http/utils/resource-response.ts +5 -2
- package/src/api/index.ts +4 -4
- package/src/api/primitives.ts +6 -2
- package/src/auth/README.md +1 -0
- package/src/auth/index.ts +12 -5
- package/src/autotune.ts +5 -1
- package/src/billing/index.ts +1 -1
- package/src/billing/types.ts +1 -1
- package/src/chat/README.md +3 -0
- package/src/chat/__tests__/runtime-profile.test.ts +68 -48
- package/src/chat/index.ts +10 -4
- package/src/chat/runtime-profile.ts +25 -10
- package/src/chat/schemas.ts +49 -41
- package/src/chat/types.ts +48 -42
- package/src/ci-envelope/README.md +2 -0
- package/src/ci-envelope/__tests__/transitions.test.ts +56 -56
- package/src/ci-envelope/index.ts +2 -2
- package/src/ci-envelope/types.ts +20 -20
- package/src/ci-results/index.ts +2 -2
- package/src/ci-results/repo-ci-result.ts +15 -12
- package/src/compatibility.ts +6 -6
- package/src/content/index.ts +10 -4
- package/src/content/schemas.ts +42 -24
- package/src/dispatch/index.ts +18 -15
- package/src/email/__tests__/registry.test.ts +81 -77
- package/src/email/index.ts +3 -3
- package/src/email/registry.ts +25 -25
- package/src/email/types.ts +43 -43
- package/src/errors/index.ts +8 -8
- package/src/execution/__tests__/events.test.ts +42 -42
- package/src/execution/__tests__/lifecycle.test.ts +192 -190
- package/src/execution/__tests__/registry.test.ts +114 -114
- package/src/execution/audit-export.ts +4 -4
- package/src/execution/errors.ts +7 -7
- package/src/execution/event-metadata.ts +4 -4
- package/src/execution/events.ts +23 -21
- package/src/execution/expiry.ts +5 -5
- package/src/execution/hash-chain.ts +2 -2
- package/src/execution/index.ts +19 -28
- package/src/execution/kinds.ts +7 -7
- package/src/execution/lifecycle.ts +33 -33
- package/src/execution/registry.ts +63 -63
- package/src/execution/schemas.ts +31 -23
- package/src/execution/status.ts +45 -26
- package/src/execution/summary.ts +16 -17
- package/src/execution/timeline-ui.ts +9 -9
- package/src/execution/types.ts +31 -25
- package/src/generated/openapi-routes.ts +2 -0
- package/src/guards/config.ts +22 -18
- package/src/guards/index.ts +4 -4
- package/src/guards/types.ts +32 -24
- package/src/identity/__tests__/avatar.test.ts +68 -59
- package/src/identity/avatar.ts +8 -8
- package/src/identity/display-name.ts +3 -3
- package/src/identity/index.ts +8 -8
- package/src/identity/people-org-chart.ts +8 -4
- package/src/identity/schemas.ts +28 -18
- package/src/identity/types.ts +5 -5
- package/src/impersonation/index.ts +5 -5
- package/src/impersonation/schemas.ts +15 -9
- package/src/impersonation-events.ts +21 -21
- package/src/impersonation.ts +25 -24
- package/src/index.ts +118 -90
- package/src/interfaces/mcp/tools/help.ts +19 -19
- package/src/internal-admin.ts +6 -6
- package/src/mcp/README.md +2 -0
- package/src/mcp/__tests__/capability-graph.test.ts +290 -290
- package/src/mcp/capability-graph.ts +42 -40
- package/src/mcp/failure-context.ts +1 -3
- package/src/mcp/index.ts +69 -56
- package/src/mcp/resources.ts +9 -9
- package/src/meetings/index.ts +2 -2
- package/src/meetings/schemas.ts +51 -34
- package/src/message-parts/README.md +2 -0
- package/src/message-parts/__tests__/builder.test.ts +142 -142
- package/src/message-parts/__tests__/confirmation.test.ts +100 -86
- package/src/message-parts/__tests__/preview.test.ts +63 -63
- package/src/message-parts/__tests__/wire.test.ts +130 -124
- package/src/message-parts/builder.ts +23 -23
- package/src/message-parts/confirmation.ts +17 -14
- package/src/message-parts/execution.ts +7 -7
- package/src/message-parts/index.ts +10 -10
- package/src/message-parts/lifecycle.ts +25 -25
- package/src/message-parts/preview.ts +30 -30
- package/src/message-parts/types.ts +27 -27
- package/src/message-parts/wire.ts +24 -24
- package/src/mutations.ts +2 -2
- package/src/observability.ts +23 -11
- package/src/org/__tests__/org-units.test.ts +131 -96
- package/src/org/__tests__/tree-ordering.test.ts +57 -37
- package/src/org/__tests__/view-scopes.test.ts +40 -40
- package/src/org/domain.ts +9 -9
- package/src/org/index.ts +31 -21
- package/src/org/org-units.ts +34 -20
- package/src/org/schemas.ts +261 -124
- package/src/org/sharing.ts +17 -13
- package/src/org/tree-ordering.ts +3 -1
- package/src/org/types.ts +54 -47
- package/src/org/view-scopes.ts +9 -9
- package/src/permissions/access-levels.ts +7 -2
- package/src/permissions/access-source.ts +6 -6
- package/src/permissions/index.ts +5 -5
- package/src/permissions/orgchart-roles.ts +7 -7
- package/src/permissions/permission-introspection.ts +7 -5
- package/src/permissions/share-api.ts +19 -9
- package/src/pressure.ts +4 -4
- package/src/queryIntent.ts +21 -21
- package/src/ralph/__tests__/prd-groups.test.ts +159 -159
- package/src/ralph/__tests__/prd.test.ts +30 -30
- package/src/ralph/index.ts +3 -8
- package/src/ralph/prd.ts +33 -33
- package/src/ralph/progress.ts +1 -1
- package/src/rate-limit/README.md +4 -4
- package/src/rate-limit/index.ts +3 -3
- package/src/requests.ts +36 -8
- package/src/resource-keys.ts +207 -124
- package/src/resource-registry.ts +5 -5
- package/src/route-builder.ts +3 -3
- package/src/safe-mode.ts +2 -2
- package/src/security/index.ts +4 -4
- package/src/security/org-secrets.ts +13 -9
- package/src/security/secret.ts +3 -3
- package/src/sse.ts +3 -1
- package/src/system/README.md +3 -0
- package/src/system/capabilities.ts +22 -23
- package/src/system/diagram.ts +45 -45
- package/src/system/index.ts +14 -14
- package/src/tiers.ts +1 -1
- package/src/timeouts.ts +1 -1
- package/src/tracing.ts +30 -30
- package/src/types/analytics.ts +2 -2
- package/src/usage/README.md +3 -0
- package/src/usage/execution-types.ts +69 -69
- package/src/usage/types.ts +7 -3
package/src/identity/index.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type {
|
|
|
13
13
|
UserLifecycleStatus,
|
|
14
14
|
DeletionBlocker,
|
|
15
15
|
AccountDeletionEligibility,
|
|
16
|
-
} from
|
|
16
|
+
} from "./types";
|
|
17
17
|
|
|
18
18
|
// Functions - Display Name
|
|
19
19
|
export {
|
|
@@ -21,13 +21,13 @@ export {
|
|
|
21
21
|
resolveDisplayName,
|
|
22
22
|
/** @deprecated Use fullName directly */
|
|
23
23
|
deriveFullName,
|
|
24
|
-
} from
|
|
24
|
+
} from "./display-name";
|
|
25
25
|
|
|
26
26
|
// Types - Avatar
|
|
27
|
-
export type { AvatarSource, ResolvedAvatar } from
|
|
27
|
+
export type { AvatarSource, ResolvedAvatar } from "./avatar";
|
|
28
28
|
|
|
29
29
|
// Functions - Avatar
|
|
30
|
-
export { generateInitials, resolveAvatar } from
|
|
30
|
+
export { generateInitials, resolveAvatar } from "./avatar";
|
|
31
31
|
|
|
32
32
|
// Response Schemas (Zod) - canonical location per ADR-CONT-044
|
|
33
33
|
export {
|
|
@@ -44,7 +44,7 @@ export {
|
|
|
44
44
|
AccountCancelDeletionResponseSchema,
|
|
45
45
|
BannerDismissedListResponseSchema,
|
|
46
46
|
BannerDismissResponseSchema,
|
|
47
|
-
} from
|
|
47
|
+
} from "./schemas";
|
|
48
48
|
export type {
|
|
49
49
|
MeResponse,
|
|
50
50
|
AuthStartResponse,
|
|
@@ -59,7 +59,7 @@ export type {
|
|
|
59
59
|
AccountCancelDeletionResponse,
|
|
60
60
|
BannerDismissedListResponse,
|
|
61
61
|
BannerDismissResponse,
|
|
62
|
-
} from
|
|
62
|
+
} from "./schemas";
|
|
63
63
|
|
|
64
64
|
// People Org Chart (GET /api/users/org-chart)
|
|
65
65
|
export {
|
|
@@ -67,10 +67,10 @@ export {
|
|
|
67
67
|
PeopleOrgChartNodeSchema,
|
|
68
68
|
PeopleOrgChartEdgeSchema,
|
|
69
69
|
PeopleOrgChartResponseSchema,
|
|
70
|
-
} from
|
|
70
|
+
} from "./people-org-chart";
|
|
71
71
|
export type {
|
|
72
72
|
ReportingRelationshipType,
|
|
73
73
|
PeopleOrgChartNode,
|
|
74
74
|
PeopleOrgChartEdge,
|
|
75
75
|
PeopleOrgChartResponse,
|
|
76
|
-
} from
|
|
76
|
+
} from "./people-org-chart";
|
|
@@ -11,14 +11,16 @@
|
|
|
11
11
|
* `org_unit_relationships.type = 'reports_to'` (unit-to-unit graph overlay,
|
|
12
12
|
* ADR-BE-120). Tree traversal must never consult either.
|
|
13
13
|
*/
|
|
14
|
-
import { z } from
|
|
14
|
+
import { z } from "zod";
|
|
15
15
|
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
17
|
// Reporting Relationship Type
|
|
18
18
|
// ---------------------------------------------------------------------------
|
|
19
19
|
|
|
20
|
-
export const ReportingRelationshipTypeSchema = z.enum([
|
|
21
|
-
export type ReportingRelationshipType = z.infer<
|
|
20
|
+
export const ReportingRelationshipTypeSchema = z.enum(["solid", "dotted"]);
|
|
21
|
+
export type ReportingRelationshipType = z.infer<
|
|
22
|
+
typeof ReportingRelationshipTypeSchema
|
|
23
|
+
>;
|
|
22
24
|
|
|
23
25
|
// ---------------------------------------------------------------------------
|
|
24
26
|
// Node — a person in the chart
|
|
@@ -55,4 +57,6 @@ export const PeopleOrgChartResponseSchema = z.object({
|
|
|
55
57
|
edges: z.array(PeopleOrgChartEdgeSchema),
|
|
56
58
|
});
|
|
57
59
|
|
|
58
|
-
export type PeopleOrgChartResponse = z.infer<
|
|
60
|
+
export type PeopleOrgChartResponse = z.infer<
|
|
61
|
+
typeof PeopleOrgChartResponseSchema
|
|
62
|
+
>;
|
package/src/identity/schemas.ts
CHANGED
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
* z.object({ sent: boolean }), but the actual POST /auth/start route returns
|
|
9
9
|
* a discriminated union on `mode` (otp | sso | hybrid). Schema matches reality.
|
|
10
10
|
*/
|
|
11
|
-
import { z } from
|
|
11
|
+
import { z } from "zod";
|
|
12
12
|
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
14
14
|
// Shared sub-schemas
|
|
15
15
|
// ---------------------------------------------------------------------------
|
|
16
16
|
|
|
17
17
|
const ResolvedAvatarSchema = z.object({
|
|
18
|
-
source: z.enum([
|
|
18
|
+
source: z.enum(["photo", "initials"]),
|
|
19
19
|
url: z.string().optional(),
|
|
20
20
|
initials: z.string(),
|
|
21
21
|
});
|
|
@@ -34,7 +34,7 @@ export const MeResponseSchema = z.object({
|
|
|
34
34
|
fullName: z.string(),
|
|
35
35
|
preferredName: z.string().nullable(),
|
|
36
36
|
displayName: z.string(),
|
|
37
|
-
nameSource: z.enum([
|
|
37
|
+
nameSource: z.enum(["self", "sso"]),
|
|
38
38
|
nameEditable: z.boolean(),
|
|
39
39
|
primaryUnitId: z.string().nullable(),
|
|
40
40
|
slackUserId: z.string().nullable(),
|
|
@@ -56,18 +56,18 @@ export type MeResponse = z.infer<typeof MeResponseSchema>;
|
|
|
56
56
|
// Discriminated union on mode: otp | sso | hybrid
|
|
57
57
|
// ---------------------------------------------------------------------------
|
|
58
58
|
|
|
59
|
-
export const AuthStartResponseSchema = z.discriminatedUnion(
|
|
59
|
+
export const AuthStartResponseSchema = z.discriminatedUnion("mode", [
|
|
60
60
|
z.object({
|
|
61
|
-
mode: z.literal(
|
|
61
|
+
mode: z.literal("otp"),
|
|
62
62
|
devOtp: z.string().optional(),
|
|
63
63
|
}),
|
|
64
64
|
z.object({
|
|
65
|
-
mode: z.literal(
|
|
65
|
+
mode: z.literal("sso"),
|
|
66
66
|
providers: z.array(z.string()),
|
|
67
67
|
redirectUrl: z.string(),
|
|
68
68
|
}),
|
|
69
69
|
z.object({
|
|
70
|
-
mode: z.literal(
|
|
70
|
+
mode: z.literal("hybrid"),
|
|
71
71
|
providers: z.array(z.string()),
|
|
72
72
|
redirectUrl: z.string(),
|
|
73
73
|
otpAllowed: z.literal(true),
|
|
@@ -133,7 +133,7 @@ export const ProfileResponseSchema = z.object({
|
|
|
133
133
|
fullName: z.string(),
|
|
134
134
|
preferredName: z.string().nullable(),
|
|
135
135
|
displayName: z.string(),
|
|
136
|
-
nameSource: z.enum([
|
|
136
|
+
nameSource: z.enum(["self", "sso"]),
|
|
137
137
|
primaryUnitId: z.string().nullable(),
|
|
138
138
|
}),
|
|
139
139
|
});
|
|
@@ -168,20 +168,22 @@ export const AccountSessionRevokeResponseSchema = z.object({
|
|
|
168
168
|
ok: z.literal(true),
|
|
169
169
|
});
|
|
170
170
|
|
|
171
|
-
export type AccountSessionRevokeResponse = z.infer<
|
|
171
|
+
export type AccountSessionRevokeResponse = z.infer<
|
|
172
|
+
typeof AccountSessionRevokeResponseSchema
|
|
173
|
+
>;
|
|
172
174
|
|
|
173
175
|
// ---------------------------------------------------------------------------
|
|
174
176
|
// GET /api/account/deletion-eligibility
|
|
175
177
|
// ---------------------------------------------------------------------------
|
|
176
178
|
|
|
177
|
-
const DeletionBlockerSchema = z.discriminatedUnion(
|
|
179
|
+
const DeletionBlockerSchema = z.discriminatedUnion("type", [
|
|
178
180
|
z.object({
|
|
179
|
-
type: z.literal(
|
|
181
|
+
type: z.literal("sole_workspace_owner"),
|
|
180
182
|
workspaceId: z.string(),
|
|
181
183
|
workspaceName: z.string(),
|
|
182
184
|
}),
|
|
183
185
|
z.object({
|
|
184
|
-
type: z.literal(
|
|
186
|
+
type: z.literal("active_legal_hold"),
|
|
185
187
|
holdId: z.string(),
|
|
186
188
|
}),
|
|
187
189
|
]);
|
|
@@ -191,14 +193,16 @@ export const AccountDeletionEligibilityResponseSchema = z.object({
|
|
|
191
193
|
blockers: z.array(DeletionBlockerSchema),
|
|
192
194
|
});
|
|
193
195
|
|
|
194
|
-
export type AccountDeletionEligibilityResponse = z.infer<
|
|
196
|
+
export type AccountDeletionEligibilityResponse = z.infer<
|
|
197
|
+
typeof AccountDeletionEligibilityResponseSchema
|
|
198
|
+
>;
|
|
195
199
|
|
|
196
200
|
// ---------------------------------------------------------------------------
|
|
197
201
|
// POST /api/account/delete
|
|
198
202
|
// ---------------------------------------------------------------------------
|
|
199
203
|
|
|
200
204
|
export const AccountDeleteResponseSchema = z.object({
|
|
201
|
-
status: z.literal(
|
|
205
|
+
status: z.literal("confirmation_pending"),
|
|
202
206
|
message: z.string(),
|
|
203
207
|
});
|
|
204
208
|
|
|
@@ -209,10 +213,12 @@ export type AccountDeleteResponse = z.infer<typeof AccountDeleteResponseSchema>;
|
|
|
209
213
|
// ---------------------------------------------------------------------------
|
|
210
214
|
|
|
211
215
|
export const AccountConfirmDeletionResponseSchema = z.object({
|
|
212
|
-
status: z.literal(
|
|
216
|
+
status: z.literal("pending_deletion"),
|
|
213
217
|
});
|
|
214
218
|
|
|
215
|
-
export type AccountConfirmDeletionResponse = z.infer<
|
|
219
|
+
export type AccountConfirmDeletionResponse = z.infer<
|
|
220
|
+
typeof AccountConfirmDeletionResponseSchema
|
|
221
|
+
>;
|
|
216
222
|
|
|
217
223
|
// ---------------------------------------------------------------------------
|
|
218
224
|
// POST /api/account/cancel-deletion
|
|
@@ -223,7 +229,9 @@ export const AccountCancelDeletionResponseSchema = z.object({
|
|
|
223
229
|
ok: z.literal(true),
|
|
224
230
|
});
|
|
225
231
|
|
|
226
|
-
export type AccountCancelDeletionResponse = z.infer<
|
|
232
|
+
export type AccountCancelDeletionResponse = z.infer<
|
|
233
|
+
typeof AccountCancelDeletionResponseSchema
|
|
234
|
+
>;
|
|
227
235
|
|
|
228
236
|
// ---------------------------------------------------------------------------
|
|
229
237
|
// GET /api/user/preferences/dismissed-banners
|
|
@@ -233,7 +241,9 @@ export const BannerDismissedListResponseSchema = z.object({
|
|
|
233
241
|
bannerIds: z.array(z.string()),
|
|
234
242
|
});
|
|
235
243
|
|
|
236
|
-
export type BannerDismissedListResponse = z.infer<
|
|
244
|
+
export type BannerDismissedListResponse = z.infer<
|
|
245
|
+
typeof BannerDismissedListResponseSchema
|
|
246
|
+
>;
|
|
237
247
|
|
|
238
248
|
// ---------------------------------------------------------------------------
|
|
239
249
|
// POST /api/user/preferences/dismissed-banners/:bannerId
|
package/src/identity/types.ts
CHANGED
|
@@ -27,7 +27,7 @@ export type ISODateString = string;
|
|
|
27
27
|
* - 'self': User-provided (editable by user)
|
|
28
28
|
* - 'sso': SSO/IdP-provided (read-only, managed by organization)
|
|
29
29
|
*/
|
|
30
|
-
export type NameSource =
|
|
30
|
+
export type NameSource = "self" | "sso";
|
|
31
31
|
|
|
32
32
|
// =============================================================================
|
|
33
33
|
// User Identity
|
|
@@ -101,7 +101,7 @@ export type UserIdentity = {
|
|
|
101
101
|
* - 'slack': synced from a connected Slack workspace
|
|
102
102
|
* - 'upload': uploaded directly by the user
|
|
103
103
|
*/
|
|
104
|
-
avatarSource?:
|
|
104
|
+
avatarSource?: "slack" | "upload";
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* When the avatar was last updated (synced or uploaded).
|
|
@@ -135,15 +135,15 @@ export type UserIdentity = {
|
|
|
135
135
|
* deleted → (terminal, no transitions)
|
|
136
136
|
* active → deleted (FORBIDDEN — must pass through pending_deletion)
|
|
137
137
|
*/
|
|
138
|
-
export type UserLifecycleStatus =
|
|
138
|
+
export type UserLifecycleStatus = "active" | "pending_deletion" | "deleted";
|
|
139
139
|
|
|
140
140
|
/**
|
|
141
141
|
* Conditions that block account deletion.
|
|
142
142
|
* Discriminated union — extend with new blocker types without breaking changes.
|
|
143
143
|
*/
|
|
144
144
|
export type DeletionBlocker =
|
|
145
|
-
| { type:
|
|
146
|
-
| { type:
|
|
145
|
+
| { type: "sole_workspace_owner"; workspaceId: string; workspaceName: string }
|
|
146
|
+
| { type: "active_legal_hold"; holdId: string };
|
|
147
147
|
|
|
148
148
|
/**
|
|
149
149
|
* Result of an account deletion eligibility check.
|
|
@@ -16,9 +16,9 @@ export type {
|
|
|
16
16
|
ImpersonationCapability,
|
|
17
17
|
ImpersonationSessionSummary,
|
|
18
18
|
ImpersonationAuditEventType,
|
|
19
|
-
} from
|
|
19
|
+
} from "../impersonation";
|
|
20
20
|
|
|
21
|
-
export { RESTRICTED_IMPERSONATION_ACTIONS } from
|
|
21
|
+
export { RESTRICTED_IMPERSONATION_ACTIONS } from "../impersonation";
|
|
22
22
|
|
|
23
23
|
// =============================================================================
|
|
24
24
|
// HTTP Response Schemas (Zod)
|
|
@@ -30,13 +30,13 @@ export {
|
|
|
30
30
|
ImpersonationSessionNullableResponseSchema,
|
|
31
31
|
EndImpersonationResponseSchema,
|
|
32
32
|
ImpersonationSessionWireDtoSchema,
|
|
33
|
-
} from
|
|
33
|
+
} from "./schemas";
|
|
34
34
|
|
|
35
35
|
export type {
|
|
36
36
|
ImpersonationSessionResponse,
|
|
37
37
|
EndImpersonationResponse,
|
|
38
38
|
ImpersonationSessionWireDtoParsed,
|
|
39
|
-
} from
|
|
39
|
+
} from "./schemas";
|
|
40
40
|
|
|
41
41
|
// Wire DTO for SSE projection (PRD-00557 F5)
|
|
42
|
-
export type { ImpersonationSessionWireDto } from
|
|
42
|
+
export type { ImpersonationSessionWireDto } from "../impersonation-events";
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Both are maintained in parallel — Zod schema mirrors the TS interface.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { z } from
|
|
11
|
+
import { z } from "zod";
|
|
12
12
|
|
|
13
13
|
export const ImpersonationSessionSchema = z.object({
|
|
14
14
|
impersonationSessionId: z.string(),
|
|
@@ -21,20 +21,20 @@ export const ImpersonationSessionSchema = z.object({
|
|
|
21
21
|
endedAt: z.string().datetime({ offset: true }).nullable(),
|
|
22
22
|
ipAddress: z.string(),
|
|
23
23
|
userAgent: z.string(),
|
|
24
|
-
})
|
|
24
|
+
});
|
|
25
25
|
|
|
26
26
|
export const ImpersonationSessionResponseSchema = z.object({
|
|
27
27
|
session: ImpersonationSessionSchema,
|
|
28
|
-
})
|
|
28
|
+
});
|
|
29
29
|
|
|
30
30
|
export const ImpersonationSessionNullableResponseSchema = z.object({
|
|
31
31
|
session: ImpersonationSessionSchema.nullable(),
|
|
32
|
-
})
|
|
32
|
+
});
|
|
33
33
|
|
|
34
34
|
export const EndImpersonationResponseSchema = z.object({
|
|
35
35
|
success: z.literal(true),
|
|
36
36
|
ok: z.literal(true),
|
|
37
|
-
})
|
|
37
|
+
});
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* Wire-only DTO for SSE snapshot/started events (PRD-00557 F5).
|
|
@@ -52,8 +52,14 @@ export const ImpersonationSessionWireDtoSchema = z
|
|
|
52
52
|
expiresAt: z.string().datetime({ offset: true }),
|
|
53
53
|
endedAt: z.string().datetime({ offset: true }).nullable(),
|
|
54
54
|
})
|
|
55
|
-
.strict()
|
|
55
|
+
.strict();
|
|
56
56
|
|
|
57
|
-
export type ImpersonationSessionResponse = z.infer<
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
export type ImpersonationSessionResponse = z.infer<
|
|
58
|
+
typeof ImpersonationSessionResponseSchema
|
|
59
|
+
>;
|
|
60
|
+
export type EndImpersonationResponse = z.infer<
|
|
61
|
+
typeof EndImpersonationResponseSchema
|
|
62
|
+
>;
|
|
63
|
+
export type ImpersonationSessionWireDtoParsed = z.infer<
|
|
64
|
+
typeof ImpersonationSessionWireDtoSchema
|
|
65
|
+
>;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Follows the same BaseEvent envelope pattern as chat SSE events.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { BaseEvent } from
|
|
9
|
+
import type { BaseEvent } from "./chat/types";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Minimal projection of an impersonation session for over-the-wire delivery.
|
|
@@ -14,11 +14,11 @@ import type { BaseEvent } from './chat/types'
|
|
|
14
14
|
* (PRD-00557 F5: type-impossible wire exposure of admin-private fields).
|
|
15
15
|
*/
|
|
16
16
|
export interface ImpersonationSessionWireDto {
|
|
17
|
-
readonly id: string
|
|
18
|
-
readonly targetUserId: string
|
|
19
|
-
readonly startedAt: string
|
|
20
|
-
readonly expiresAt: string
|
|
21
|
-
readonly endedAt: string | null
|
|
17
|
+
readonly id: string;
|
|
18
|
+
readonly targetUserId: string;
|
|
19
|
+
readonly startedAt: string;
|
|
20
|
+
readonly expiresAt: string;
|
|
21
|
+
readonly endedAt: string | null;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -27,40 +27,40 @@ export interface ImpersonationSessionWireDto {
|
|
|
27
27
|
* Eliminates need for a separate GET /session request.
|
|
28
28
|
*/
|
|
29
29
|
export interface ImpersonationSessionSnapshotEvent extends BaseEvent {
|
|
30
|
-
type:
|
|
30
|
+
type: "impersonation.session.snapshot";
|
|
31
31
|
data: {
|
|
32
|
-
session: ImpersonationSessionWireDto | null
|
|
33
|
-
}
|
|
32
|
+
session: ImpersonationSessionWireDto | null;
|
|
33
|
+
};
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/** Emitted when a new impersonation session starts (enables multi-tab sync). */
|
|
37
37
|
export interface ImpersonationSessionStartedEvent extends BaseEvent {
|
|
38
|
-
type:
|
|
38
|
+
type: "impersonation.session.started";
|
|
39
39
|
data: {
|
|
40
|
-
session: ImpersonationSessionWireDto
|
|
41
|
-
}
|
|
40
|
+
session: ImpersonationSessionWireDto;
|
|
41
|
+
};
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/** Emitted when an admin manually ends an impersonation session. */
|
|
45
45
|
export interface ImpersonationSessionEndedEvent extends BaseEvent {
|
|
46
|
-
type:
|
|
46
|
+
type: "impersonation.session.ended";
|
|
47
47
|
data: {
|
|
48
|
-
sessionId: string
|
|
49
|
-
endedAt: string
|
|
50
|
-
}
|
|
48
|
+
sessionId: string;
|
|
49
|
+
endedAt: string;
|
|
50
|
+
};
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
/** Emitted when enforceExpiry() auto-expires a session. */
|
|
54
54
|
export interface ImpersonationSessionExpiredEvent extends BaseEvent {
|
|
55
|
-
type:
|
|
55
|
+
type: "impersonation.session.expired";
|
|
56
56
|
data: {
|
|
57
|
-
sessionId: string
|
|
58
|
-
expiredAt: string
|
|
59
|
-
}
|
|
57
|
+
sessionId: string;
|
|
58
|
+
expiredAt: string;
|
|
59
|
+
};
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
export type ImpersonationSseEvent =
|
|
63
63
|
| ImpersonationSessionSnapshotEvent
|
|
64
64
|
| ImpersonationSessionStartedEvent
|
|
65
65
|
| ImpersonationSessionEndedEvent
|
|
66
|
-
| ImpersonationSessionExpiredEvent
|
|
66
|
+
| ImpersonationSessionExpiredEvent;
|
package/src/impersonation.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
// Authentication mode — tags every request context
|
|
9
|
-
export type AuthMode =
|
|
9
|
+
export type AuthMode = "STANDARD" | "BREAK_GLASS";
|
|
10
10
|
|
|
11
11
|
// Impersonation session model — full session state
|
|
12
12
|
export interface ImpersonationSession {
|
|
@@ -26,27 +26,28 @@ export interface ImpersonationSession {
|
|
|
26
26
|
// Backend impersonation middleware consumes this enum centrally.
|
|
27
27
|
// Routes do NOT self-classify. This prevents bypass via new routes.
|
|
28
28
|
export type RestrictedImpersonationAction =
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
29
|
+
| "delete_chat"
|
|
30
|
+
| "delete_message"
|
|
31
|
+
| "modify_billing"
|
|
32
|
+
| "invite_remove_users"
|
|
33
|
+
| "accept_agreements"
|
|
34
|
+
| "irreversible_write"
|
|
35
|
+
| "manage_auth";
|
|
36
36
|
|
|
37
37
|
// All restricted actions as a const array for runtime checks
|
|
38
|
-
export const RESTRICTED_IMPERSONATION_ACTIONS: readonly RestrictedImpersonationAction[] =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
export const RESTRICTED_IMPERSONATION_ACTIONS: readonly RestrictedImpersonationAction[] =
|
|
39
|
+
[
|
|
40
|
+
"delete_chat",
|
|
41
|
+
"delete_message",
|
|
42
|
+
"modify_billing",
|
|
43
|
+
"invite_remove_users",
|
|
44
|
+
"accept_agreements",
|
|
45
|
+
"irreversible_write",
|
|
46
|
+
"manage_auth",
|
|
47
|
+
] as const;
|
|
47
48
|
|
|
48
49
|
// Impersonation-specific company capability
|
|
49
|
-
export type ImpersonationCapability =
|
|
50
|
+
export type ImpersonationCapability = "company.impersonate";
|
|
50
51
|
|
|
51
52
|
// Session summary — emitted on impersonation.ended and impersonation.expired
|
|
52
53
|
export interface ImpersonationSessionSummary {
|
|
@@ -60,9 +61,9 @@ export interface ImpersonationSessionSummary {
|
|
|
60
61
|
|
|
61
62
|
// Impersonation audit event types
|
|
62
63
|
export type ImpersonationAuditEventType =
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
64
|
+
| "impersonation.started"
|
|
65
|
+
| "impersonation.ended"
|
|
66
|
+
| "impersonation.expired"
|
|
67
|
+
| "impersonation.session_summary"
|
|
68
|
+
| "impersonated.action"
|
|
69
|
+
| "impersonation.blocked_action";
|