@viewportai/daemon 0.5.3 → 0.6.1

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.
Files changed (118) hide show
  1. package/dist/cli/commands.d.ts +1 -0
  2. package/dist/cli/commands.d.ts.map +1 -1
  3. package/dist/cli/commands.js +1 -0
  4. package/dist/cli/commands.js.map +1 -1
  5. package/dist/cli/context-access-command.d.ts +0 -6
  6. package/dist/cli/context-access-command.d.ts.map +1 -1
  7. package/dist/cli/context-access-command.js +1 -71
  8. package/dist/cli/context-access-command.js.map +1 -1
  9. package/dist/cli/context-command.d.ts.map +1 -1
  10. package/dist/cli/context-command.js +575 -38
  11. package/dist/cli/context-command.js.map +1 -1
  12. package/dist/cli/context-vault-metadata-command.d.ts.map +1 -1
  13. package/dist/cli/context-vault-metadata-command.js +6 -1
  14. package/dist/cli/context-vault-metadata-command.js.map +1 -1
  15. package/dist/cli/lifecycle-commands.d.ts.map +1 -1
  16. package/dist/cli/lifecycle-commands.js +2 -8
  17. package/dist/cli/lifecycle-commands.js.map +1 -1
  18. package/dist/cli/skills-command.js +3 -3
  19. package/dist/cli/unlock-command.d.ts +2 -0
  20. package/dist/cli/unlock-command.d.ts.map +1 -0
  21. package/dist/cli/unlock-command.js +35 -0
  22. package/dist/cli/unlock-command.js.map +1 -0
  23. package/dist/context/local-edge-auto-sync.d.ts +17 -0
  24. package/dist/context/local-edge-auto-sync.d.ts.map +1 -0
  25. package/dist/context/local-edge-auto-sync.js +94 -0
  26. package/dist/context/local-edge-auto-sync.js.map +1 -0
  27. package/dist/context/local-edge-store.d.ts +11 -0
  28. package/dist/context/local-edge-store.d.ts.map +1 -1
  29. package/dist/context/local-edge-store.js +25 -0
  30. package/dist/context/local-edge-store.js.map +1 -1
  31. package/dist/context/local-edge-sync.d.ts +2 -15
  32. package/dist/context/local-edge-sync.d.ts.map +1 -1
  33. package/dist/context/local-edge-sync.js +306 -86
  34. package/dist/context/local-edge-sync.js.map +1 -1
  35. package/dist/context/local-edge-types.d.ts +12 -0
  36. package/dist/context/local-edge-types.d.ts.map +1 -1
  37. package/dist/context-providers/viewport-vault-provider.d.ts.map +1 -1
  38. package/dist/context-providers/viewport-vault-provider.js +11 -0
  39. package/dist/context-providers/viewport-vault-provider.js.map +1 -1
  40. package/dist/core/session-context-prompt.d.ts.map +1 -1
  41. package/dist/core/session-context-prompt.js +8 -0
  42. package/dist/core/session-context-prompt.js.map +1 -1
  43. package/dist/hooks/trusted-edge-plan-artifacts.d.ts +30 -27
  44. package/dist/hooks/trusted-edge-plan-artifacts.d.ts.map +1 -1
  45. package/dist/hooks/trusted-edge-plan-artifacts.js +71 -89
  46. package/dist/hooks/trusted-edge-plan-artifacts.js.map +1 -1
  47. package/dist/index.d.ts +1 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +3 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/relay/bridge-daemon-key-registration.d.ts.map +1 -1
  52. package/dist/relay/bridge-daemon-key-registration.js +27 -7
  53. package/dist/relay/bridge-daemon-key-registration.js.map +1 -1
  54. package/dist/security/epoch-enrollment.d.ts +48 -0
  55. package/dist/security/epoch-enrollment.d.ts.map +1 -0
  56. package/dist/security/epoch-enrollment.js +290 -0
  57. package/dist/security/epoch-enrollment.js.map +1 -0
  58. package/dist/security/epoch-protocol.d.ts +181 -0
  59. package/dist/security/epoch-protocol.d.ts.map +1 -0
  60. package/dist/security/epoch-protocol.js +285 -0
  61. package/dist/security/epoch-protocol.js.map +1 -0
  62. package/dist/security/epoch-public-pins.d.ts +19 -0
  63. package/dist/security/epoch-public-pins.d.ts.map +1 -0
  64. package/dist/security/epoch-public-pins.js +129 -0
  65. package/dist/security/epoch-public-pins.js.map +1 -0
  66. package/dist/security/epoch-recovery.d.ts +56 -0
  67. package/dist/security/epoch-recovery.d.ts.map +1 -0
  68. package/dist/security/epoch-recovery.js +314 -0
  69. package/dist/security/epoch-recovery.js.map +1 -0
  70. package/dist/security/epoch-store.d.ts +111 -0
  71. package/dist/security/epoch-store.d.ts.map +1 -0
  72. package/dist/security/epoch-store.js +224 -0
  73. package/dist/security/epoch-store.js.map +1 -0
  74. package/dist/security/epoch-sync.d.ts +47 -0
  75. package/dist/security/epoch-sync.d.ts.map +1 -0
  76. package/dist/security/epoch-sync.js +371 -0
  77. package/dist/security/epoch-sync.js.map +1 -0
  78. package/dist/security/team-epoch-grant-payloads.d.ts +44 -0
  79. package/dist/security/team-epoch-grant-payloads.d.ts.map +1 -0
  80. package/dist/security/team-epoch-grant-payloads.js +100 -0
  81. package/dist/security/team-epoch-grant-payloads.js.map +1 -0
  82. package/dist/security/team-epoch-grants.d.ts +31 -0
  83. package/dist/security/team-epoch-grants.d.ts.map +1 -0
  84. package/dist/security/team-epoch-grants.js +194 -0
  85. package/dist/security/team-epoch-grants.js.map +1 -0
  86. package/dist/server/http-context-routes.d.ts +2 -1
  87. package/dist/server/http-context-routes.d.ts.map +1 -1
  88. package/dist/server/http-context-routes.js +57 -15
  89. package/dist/server/http-context-routes.js.map +1 -1
  90. package/dist/server/http-server.js +1 -1
  91. package/dist/server/http-server.js.map +1 -1
  92. package/dist/server/rate-limiter.d.ts.map +1 -1
  93. package/dist/server/rate-limiter.js +2 -1
  94. package/dist/server/rate-limiter.js.map +1 -1
  95. package/dist/server/trusted-edge-command-capability.d.ts +2 -1
  96. package/dist/server/trusted-edge-command-capability.d.ts.map +1 -1
  97. package/dist/server/trusted-edge-command-capability.js +15 -0
  98. package/dist/server/trusted-edge-command-capability.js.map +1 -1
  99. package/dist/server/ws-command-handlers.d.ts.map +1 -1
  100. package/dist/server/ws-command-handlers.js +200 -28
  101. package/dist/server/ws-command-handlers.js.map +1 -1
  102. package/dist/server/ws-protocol.d.ts +281 -44
  103. package/dist/server/ws-protocol.d.ts.map +1 -1
  104. package/dist/server/ws-protocol.js +89 -19
  105. package/dist/server/ws-protocol.js.map +1 -1
  106. package/dist/startup.d.ts.map +1 -1
  107. package/dist/startup.js +0 -17
  108. package/dist/startup.js.map +1 -1
  109. package/docs/README.md +18 -0
  110. package/docs/configuration.md +3 -3
  111. package/docs/protocol-matrix.json +53 -8
  112. package/docs/security.md +11 -8
  113. package/node_modules/@viewportai/context-engine/src/repo/identities.js +7 -3
  114. package/node_modules/@viewportai/context-engine/src/repo/materializer.js +20 -5
  115. package/node_modules/@viewportai/context-engine/src/repo/membership.js +15 -0
  116. package/node_modules/@viewportai/context-engine/src/repo/sync.js +4 -4
  117. package/node_modules/@viewportai/context-engine/src/repo/vault.js +8 -3
  118. package/package.json +1 -1
@@ -0,0 +1,181 @@
1
+ export declare const USER_EPOCH_SCHEMA = "viewport.user_crypto_epoch/v1";
2
+ export declare const TEAM_EPOCH_SCHEMA = "viewport.team_crypto_epoch/v1";
3
+ export declare const DEVICE_ENROLLMENT_SCHEMA = "viewport.device_enrollment/v1";
4
+ export declare const RESOURCE_GRANT_SCHEMA = "viewport.resource_key_grant/v1";
5
+ export declare const WRAPPED_KEY_ENVELOPE_SCHEMA = "viewport.wrapped_key_envelope/v1";
6
+ export declare const TRUSTED_EDGE_CRYPTO_PROTOCOL_HEADER = "X-Viewport-Crypto-Protocol";
7
+ export declare const TRUSTED_EDGE_CRYPTO_PROTOCOL_VERSION = "viewport.trusted_edge_crypto/v2";
8
+ export type JsonValue = null | boolean | number | string | JsonValue[] | {
9
+ [key: string]: JsonValue;
10
+ };
11
+ export interface EpochDescriptor {
12
+ schema: typeof USER_EPOCH_SCHEMA | typeof TEAM_EPOCH_SCHEMA;
13
+ workspaceId: string;
14
+ subjectType: 'user' | 'team';
15
+ subjectId: string;
16
+ epoch: number;
17
+ encryptionPublicKeyJwk: JsonValue;
18
+ signingPublicKeyJwk: JsonValue;
19
+ previousEpochFingerprint?: string | null;
20
+ createdAt: string;
21
+ }
22
+ export interface DeviceEnrollmentRequest {
23
+ schema: typeof DEVICE_ENROLLMENT_SCHEMA;
24
+ workspaceId: string;
25
+ deviceId: string;
26
+ deviceLabel: string;
27
+ encryptionPublicKeyJwk: JsonValue;
28
+ signingPublicKeyJwk: JsonValue;
29
+ nonce: string;
30
+ }
31
+ export interface SignedDeviceEnrollmentRequest {
32
+ payload: DeviceEnrollmentRequest;
33
+ signature: string;
34
+ }
35
+ export interface UserEpochDeviceMaterializationPayload {
36
+ schema: 'viewport.user_epoch_device_materialization/v1';
37
+ workspaceId: string;
38
+ userId: string;
39
+ enrollmentId: string;
40
+ grantId: string;
41
+ userCryptoEpochId: string;
42
+ userEpochFingerprint: string;
43
+ recipientFingerprint: string;
44
+ }
45
+ export interface SignedUserEpochDeviceMaterialization {
46
+ payload: UserEpochDeviceMaterializationPayload;
47
+ signature: string;
48
+ signedByUserEpochFingerprint: string;
49
+ }
50
+ export interface TeamEpochMemberMaterializationPayload {
51
+ schema: 'viewport.team_epoch_member_materialization/v1';
52
+ workspaceId: string;
53
+ grantId: string;
54
+ teamCryptoEpochId: string;
55
+ teamEpochFingerprint: string;
56
+ recipientUserCryptoEpochId: string;
57
+ recipientUserEpochFingerprint: string;
58
+ }
59
+ export interface SignedTeamEpochMemberMaterialization {
60
+ payload: TeamEpochMemberMaterializationPayload;
61
+ signature: string;
62
+ signedByTeamEpochFingerprint: string;
63
+ }
64
+ export interface ContextGrantMaterializationPayload {
65
+ schema: 'viewport.context_vault_grant_materialization/v1';
66
+ workspaceId: string;
67
+ contextResourceId: string;
68
+ grantEventId: string;
69
+ recipientName: string;
70
+ keyEpoch: number | null;
71
+ }
72
+ export interface SignedContextGrantMaterialization {
73
+ payload: ContextGrantMaterializationPayload;
74
+ signature: string;
75
+ signedByEpochFingerprint: string;
76
+ }
77
+ export interface SignedEpochTransition {
78
+ payload: EpochTransitionPayload;
79
+ signature: string;
80
+ signedByEpochFingerprint: string;
81
+ }
82
+ export interface WrappedKeyEnvelope {
83
+ schema: typeof WRAPPED_KEY_ENVELOPE_SCHEMA;
84
+ alg: 'x25519-hkdf-sha256-aes-256-gcm';
85
+ ephemeralPublicKeyJwk: JsonValue;
86
+ iv: string;
87
+ ciphertext: string;
88
+ tag: string;
89
+ aadDigest: string;
90
+ createdAt: string;
91
+ }
92
+ export interface EpochTransitionPayload {
93
+ schema: 'viewport.epoch_transition/v1';
94
+ workspaceId: string;
95
+ subjectType: 'user' | 'team';
96
+ subjectId: string;
97
+ fromEpoch: number;
98
+ fromEpochFingerprint: string;
99
+ toEpoch: number;
100
+ toEpochFingerprint: string;
101
+ reason: 'initial' | 'device_enrolled' | 'device_revoked' | 'member_added' | 'member_revoked' | 'manual_rotation' | 'recovery';
102
+ createdAt: string;
103
+ }
104
+ export declare function canonicalJson(value: unknown): string;
105
+ export declare function sha256Base64Url(value: string | Buffer): string;
106
+ export declare function fingerprintPayload(value: JsonValue): string;
107
+ export declare function epochFingerprint(epoch: EpochDescriptor): string;
108
+ export declare function deviceEnrollmentFingerprint(request: DeviceEnrollmentRequest): string;
109
+ export declare function signDeviceEnrollmentRequest(input: {
110
+ payload: DeviceEnrollmentRequest;
111
+ signingPrivateKeyJwk: JsonValue;
112
+ }): SignedDeviceEnrollmentRequest;
113
+ export declare function userEpochDeviceMaterializationPayload(input: {
114
+ workspaceId: string;
115
+ userId: string;
116
+ enrollmentId: string;
117
+ grantId: string;
118
+ userCryptoEpochId: string;
119
+ userEpochFingerprint: string;
120
+ recipientFingerprint: string;
121
+ }): UserEpochDeviceMaterializationPayload;
122
+ export declare function signUserEpochDeviceMaterialization(input: {
123
+ payload: UserEpochDeviceMaterializationPayload;
124
+ signingPrivateKeyJwk: JsonValue;
125
+ signedByUserEpochFingerprint: string;
126
+ }): SignedUserEpochDeviceMaterialization;
127
+ export declare function teamEpochMemberMaterializationPayload(input: {
128
+ workspaceId: string;
129
+ grantId: string;
130
+ teamCryptoEpochId: string;
131
+ teamEpochFingerprint: string;
132
+ recipientUserCryptoEpochId: string;
133
+ recipientUserEpochFingerprint: string;
134
+ }): TeamEpochMemberMaterializationPayload;
135
+ export declare function signTeamEpochMemberMaterialization(input: {
136
+ payload: TeamEpochMemberMaterializationPayload;
137
+ signingPrivateKeyJwk: JsonValue;
138
+ signedByTeamEpochFingerprint: string;
139
+ }): SignedTeamEpochMemberMaterialization;
140
+ export declare function contextGrantMaterializationPayload(input: {
141
+ workspaceId: string;
142
+ contextResourceId: string;
143
+ grantEventId: string;
144
+ recipientName: string;
145
+ keyEpoch: number | null;
146
+ }): ContextGrantMaterializationPayload;
147
+ export declare function signContextGrantMaterialization(input: {
148
+ payload: ContextGrantMaterializationPayload;
149
+ signingPrivateKeyJwk: JsonValue;
150
+ signedByEpochFingerprint: string;
151
+ }): SignedContextGrantMaterialization;
152
+ export declare function epochTransitionPayload(input: {
153
+ from: EpochDescriptor;
154
+ to: EpochDescriptor;
155
+ reason: EpochTransitionPayload['reason'];
156
+ createdAt: string;
157
+ }): EpochTransitionPayload;
158
+ export declare function signEpochTransition(input: {
159
+ payload: EpochTransitionPayload;
160
+ signingPrivateKeyJwk: JsonValue;
161
+ signedByEpochFingerprint: string;
162
+ }): SignedEpochTransition;
163
+ export declare function verifyEpochTransition(input: {
164
+ signed: SignedEpochTransition;
165
+ signingPublicKeyJwk: JsonValue;
166
+ expectedFromEpochFingerprint: string;
167
+ expectedToEpochFingerprint: string;
168
+ }): boolean;
169
+ export declare function wrapJsonForX25519Recipient(input: {
170
+ recipientPublicKeyJwk: JsonValue;
171
+ payload: JsonValue;
172
+ aad: JsonValue;
173
+ createdAt?: string;
174
+ }): WrappedKeyEnvelope;
175
+ export declare function unwrapJsonFromX25519Envelope(input: {
176
+ recipientPrivateKeyJwk: JsonValue;
177
+ envelope: WrappedKeyEnvelope;
178
+ aad: JsonValue;
179
+ }): JsonValue;
180
+ export declare function assertNoPrivateKeyMaterial(value: JsonValue, path?: string): void;
181
+ //# sourceMappingURL=epoch-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epoch-protocol.d.ts","sourceRoot":"","sources":["../../src/security/epoch-protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,285 @@
1
+ import crypto from 'node:crypto';
2
+ export const USER_EPOCH_SCHEMA = 'viewport.user_crypto_epoch/v1';
3
+ export const TEAM_EPOCH_SCHEMA = 'viewport.team_crypto_epoch/v1';
4
+ export const DEVICE_ENROLLMENT_SCHEMA = 'viewport.device_enrollment/v1';
5
+ export const RESOURCE_GRANT_SCHEMA = 'viewport.resource_key_grant/v1';
6
+ export const WRAPPED_KEY_ENVELOPE_SCHEMA = 'viewport.wrapped_key_envelope/v1';
7
+ export const TRUSTED_EDGE_CRYPTO_PROTOCOL_HEADER = 'X-Viewport-Crypto-Protocol';
8
+ export const TRUSTED_EDGE_CRYPTO_PROTOCOL_VERSION = 'viewport.trusted_edge_crypto/v2';
9
+ const PRIVATE_JWK_FIELDS = new Set([
10
+ 'd',
11
+ 'p',
12
+ 'q',
13
+ 'dp',
14
+ 'dq',
15
+ 'qi',
16
+ 'oth',
17
+ 'k',
18
+ 'x5c_private',
19
+ 'hpkePrivateKey',
20
+ 'privateKey',
21
+ 'secretKey',
22
+ ]);
23
+ export function canonicalJson(value) {
24
+ return JSON.stringify(canonicalize(value));
25
+ }
26
+ export function sha256Base64Url(value) {
27
+ return crypto.createHash('sha256').update(value).digest('base64url');
28
+ }
29
+ export function fingerprintPayload(value) {
30
+ return `sha256:${sha256Base64Url(canonicalJson(value))}`;
31
+ }
32
+ export function epochFingerprint(epoch) {
33
+ return fingerprintPayload({
34
+ schema: epoch.schema,
35
+ workspaceId: epoch.workspaceId,
36
+ subjectType: epoch.subjectType,
37
+ subjectId: epoch.subjectId,
38
+ epoch: epoch.epoch,
39
+ encryptionPublicKeyJwk: epoch.encryptionPublicKeyJwk,
40
+ signingPublicKeyJwk: epoch.signingPublicKeyJwk,
41
+ previousEpochFingerprint: epoch.previousEpochFingerprint ?? null,
42
+ });
43
+ }
44
+ export function deviceEnrollmentFingerprint(request) {
45
+ assertNoPrivateKeyMaterial(request.encryptionPublicKeyJwk);
46
+ assertNoPrivateKeyMaterial(request.signingPublicKeyJwk);
47
+ return fingerprintPayload({
48
+ schema: request.schema,
49
+ workspaceId: request.workspaceId,
50
+ deviceId: request.deviceId,
51
+ deviceLabel: request.deviceLabel,
52
+ encryptionPublicKeyJwk: request.encryptionPublicKeyJwk,
53
+ signingPublicKeyJwk: request.signingPublicKeyJwk,
54
+ nonce: request.nonce,
55
+ });
56
+ }
57
+ export function signDeviceEnrollmentRequest(input) {
58
+ const key = crypto.createPrivateKey({
59
+ key: input.signingPrivateKeyJwk,
60
+ format: 'jwk',
61
+ });
62
+ return {
63
+ payload: input.payload,
64
+ signature: crypto
65
+ .sign(null, Buffer.from(canonicalJson(input.payload)), key)
66
+ .toString('base64url'),
67
+ };
68
+ }
69
+ export function userEpochDeviceMaterializationPayload(input) {
70
+ return {
71
+ schema: 'viewport.user_epoch_device_materialization/v1',
72
+ workspaceId: input.workspaceId,
73
+ userId: input.userId,
74
+ enrollmentId: input.enrollmentId,
75
+ grantId: input.grantId,
76
+ userCryptoEpochId: input.userCryptoEpochId,
77
+ userEpochFingerprint: input.userEpochFingerprint,
78
+ recipientFingerprint: input.recipientFingerprint,
79
+ };
80
+ }
81
+ export function signUserEpochDeviceMaterialization(input) {
82
+ const key = crypto.createPrivateKey({
83
+ key: input.signingPrivateKeyJwk,
84
+ format: 'jwk',
85
+ });
86
+ return {
87
+ payload: input.payload,
88
+ signature: crypto
89
+ .sign(null, Buffer.from(canonicalJson(input.payload)), key)
90
+ .toString('base64url'),
91
+ signedByUserEpochFingerprint: input.signedByUserEpochFingerprint,
92
+ };
93
+ }
94
+ export function teamEpochMemberMaterializationPayload(input) {
95
+ return {
96
+ schema: 'viewport.team_epoch_member_materialization/v1',
97
+ workspaceId: input.workspaceId,
98
+ grantId: input.grantId,
99
+ teamCryptoEpochId: input.teamCryptoEpochId,
100
+ teamEpochFingerprint: input.teamEpochFingerprint,
101
+ recipientUserCryptoEpochId: input.recipientUserCryptoEpochId,
102
+ recipientUserEpochFingerprint: input.recipientUserEpochFingerprint,
103
+ };
104
+ }
105
+ export function signTeamEpochMemberMaterialization(input) {
106
+ const key = crypto.createPrivateKey({
107
+ key: input.signingPrivateKeyJwk,
108
+ format: 'jwk',
109
+ });
110
+ return {
111
+ payload: input.payload,
112
+ signature: crypto
113
+ .sign(null, Buffer.from(canonicalJson(input.payload)), key)
114
+ .toString('base64url'),
115
+ signedByTeamEpochFingerprint: input.signedByTeamEpochFingerprint,
116
+ };
117
+ }
118
+ export function contextGrantMaterializationPayload(input) {
119
+ return {
120
+ schema: 'viewport.context_vault_grant_materialization/v1',
121
+ workspaceId: input.workspaceId,
122
+ contextResourceId: input.contextResourceId,
123
+ grantEventId: input.grantEventId,
124
+ recipientName: input.recipientName,
125
+ keyEpoch: input.keyEpoch,
126
+ };
127
+ }
128
+ export function signContextGrantMaterialization(input) {
129
+ const key = crypto.createPrivateKey({
130
+ key: input.signingPrivateKeyJwk,
131
+ format: 'jwk',
132
+ });
133
+ return {
134
+ payload: input.payload,
135
+ signature: crypto
136
+ .sign(null, Buffer.from(canonicalJson(input.payload)), key)
137
+ .toString('base64url'),
138
+ signedByEpochFingerprint: input.signedByEpochFingerprint,
139
+ };
140
+ }
141
+ export function epochTransitionPayload(input) {
142
+ if (input.from.workspaceId !== input.to.workspaceId) {
143
+ throw new Error('Epoch transition workspace mismatch.');
144
+ }
145
+ if (input.from.subjectType !== input.to.subjectType ||
146
+ input.from.subjectId !== input.to.subjectId) {
147
+ throw new Error('Epoch transition subject mismatch.');
148
+ }
149
+ if (input.to.epoch !== input.from.epoch + 1) {
150
+ throw new Error('Epoch transition must advance by exactly one epoch.');
151
+ }
152
+ return {
153
+ schema: 'viewport.epoch_transition/v1',
154
+ workspaceId: input.from.workspaceId,
155
+ subjectType: input.from.subjectType,
156
+ subjectId: input.from.subjectId,
157
+ fromEpoch: input.from.epoch,
158
+ fromEpochFingerprint: epochFingerprint(input.from),
159
+ toEpoch: input.to.epoch,
160
+ toEpochFingerprint: epochFingerprint(input.to),
161
+ reason: input.reason,
162
+ createdAt: input.createdAt,
163
+ };
164
+ }
165
+ export function signEpochTransition(input) {
166
+ const key = crypto.createPrivateKey({
167
+ key: input.signingPrivateKeyJwk,
168
+ format: 'jwk',
169
+ });
170
+ const signature = crypto
171
+ .sign(null, Buffer.from(canonicalJson(input.payload)), key)
172
+ .toString('base64url');
173
+ return {
174
+ payload: input.payload,
175
+ signature,
176
+ signedByEpochFingerprint: input.signedByEpochFingerprint,
177
+ };
178
+ }
179
+ export function verifyEpochTransition(input) {
180
+ if (input.signed.signedByEpochFingerprint !== input.expectedFromEpochFingerprint)
181
+ return false;
182
+ if (input.signed.payload.fromEpochFingerprint !== input.expectedFromEpochFingerprint)
183
+ return false;
184
+ if (input.signed.payload.toEpochFingerprint !== input.expectedToEpochFingerprint)
185
+ return false;
186
+ const key = crypto.createPublicKey({
187
+ key: input.signingPublicKeyJwk,
188
+ format: 'jwk',
189
+ });
190
+ return crypto.verify(null, Buffer.from(canonicalJson(input.signed.payload)), key, Buffer.from(input.signed.signature, 'base64url'));
191
+ }
192
+ export function wrapJsonForX25519Recipient(input) {
193
+ assertNoPrivateKeyMaterial(input.recipientPublicKeyJwk);
194
+ const ephemeral = crypto.generateKeyPairSync('x25519');
195
+ const recipientPublicKey = crypto.createPublicKey({
196
+ key: input.recipientPublicKeyJwk,
197
+ format: 'jwk',
198
+ });
199
+ const sharedSecret = crypto.diffieHellman({
200
+ privateKey: ephemeral.privateKey,
201
+ publicKey: recipientPublicKey,
202
+ });
203
+ const aad = Buffer.from(canonicalJson(input.aad));
204
+ const iv = crypto.randomBytes(12);
205
+ const cipher = crypto.createCipheriv('aes-256-gcm', deriveWrapKey(sharedSecret), iv);
206
+ cipher.setAAD(aad);
207
+ const ciphertext = Buffer.concat([
208
+ cipher.update(Buffer.from(canonicalJson(input.payload))),
209
+ cipher.final(),
210
+ ]);
211
+ return {
212
+ schema: WRAPPED_KEY_ENVELOPE_SCHEMA,
213
+ alg: 'x25519-hkdf-sha256-aes-256-gcm',
214
+ ephemeralPublicKeyJwk: ephemeral.publicKey.export({ format: 'jwk' }),
215
+ iv: iv.toString('base64url'),
216
+ ciphertext: ciphertext.toString('base64url'),
217
+ tag: cipher.getAuthTag().toString('base64url'),
218
+ aadDigest: fingerprintPayload(input.aad),
219
+ createdAt: input.createdAt ?? new Date().toISOString(),
220
+ };
221
+ }
222
+ export function unwrapJsonFromX25519Envelope(input) {
223
+ if (input.envelope.schema !== WRAPPED_KEY_ENVELOPE_SCHEMA) {
224
+ throw new Error('Unsupported wrapped key envelope schema.');
225
+ }
226
+ if (input.envelope.alg !== 'x25519-hkdf-sha256-aes-256-gcm') {
227
+ throw new Error('Unsupported wrapped key envelope algorithm.');
228
+ }
229
+ const expectedAadDigest = fingerprintPayload(input.aad);
230
+ if (input.envelope.aadDigest !== expectedAadDigest) {
231
+ throw new Error('Wrapped key envelope AAD mismatch.');
232
+ }
233
+ const recipientPrivateKey = crypto.createPrivateKey({
234
+ key: input.recipientPrivateKeyJwk,
235
+ format: 'jwk',
236
+ });
237
+ const ephemeralPublicKey = crypto.createPublicKey({
238
+ key: input.envelope.ephemeralPublicKeyJwk,
239
+ format: 'jwk',
240
+ });
241
+ const sharedSecret = crypto.diffieHellman({
242
+ privateKey: recipientPrivateKey,
243
+ publicKey: ephemeralPublicKey,
244
+ });
245
+ const decipher = crypto.createDecipheriv('aes-256-gcm', deriveWrapKey(sharedSecret), Buffer.from(input.envelope.iv, 'base64url'));
246
+ decipher.setAAD(Buffer.from(canonicalJson(input.aad)));
247
+ decipher.setAuthTag(Buffer.from(input.envelope.tag, 'base64url'));
248
+ const plaintext = Buffer.concat([
249
+ decipher.update(Buffer.from(input.envelope.ciphertext, 'base64url')),
250
+ decipher.final(),
251
+ ]);
252
+ return JSON.parse(plaintext.toString('utf8'));
253
+ }
254
+ export function assertNoPrivateKeyMaterial(value, path = '$') {
255
+ if (Array.isArray(value)) {
256
+ value.forEach((item, index) => assertNoPrivateKeyMaterial(item, `${path}[${index}]`));
257
+ return;
258
+ }
259
+ if (!value || typeof value !== 'object')
260
+ return;
261
+ for (const [key, child] of Object.entries(value)) {
262
+ if (PRIVATE_JWK_FIELDS.has(key)) {
263
+ throw new Error(`Private key material is not allowed at ${path}.${key}.`);
264
+ }
265
+ assertNoPrivateKeyMaterial(child, `${path}.${key}`);
266
+ }
267
+ }
268
+ function deriveWrapKey(sharedSecret) {
269
+ return Buffer.from(crypto.hkdfSync('sha256', sharedSecret, Buffer.from('viewport-wrapped-key-envelope-salt-v1'), Buffer.from('viewport-wrapped-key-envelope/v1'), 32));
270
+ }
271
+ function canonicalize(value) {
272
+ if (Array.isArray(value))
273
+ return value.map((item) => canonicalize(item));
274
+ if (!value || typeof value !== 'object')
275
+ return value;
276
+ return Object.keys(value)
277
+ .sort()
278
+ .reduce((acc, key) => {
279
+ const child = value[key];
280
+ if (child !== undefined)
281
+ acc[key] = canonicalize(child);
282
+ return acc;
283
+ }, {});
284
+ }
285
+ //# sourceMappingURL=epoch-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epoch-protocol.js","sourceRoot":"","sources":["../../src/security/epoch-protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type JsonValue } from './epoch-protocol.js';
2
+ import { type LocalPublicEpochPin } from './epoch-store.js';
3
+ export interface PublicEpochForPinning {
4
+ platformEpochId: string;
5
+ workspaceId: string;
6
+ subjectType: 'user' | 'team';
7
+ subjectId: string;
8
+ epoch: number;
9
+ schema: 'viewport.user_crypto_epoch/v1' | 'viewport.team_crypto_epoch/v1';
10
+ fingerprint: string;
11
+ encryptionPublicKeyJwk: JsonValue;
12
+ signingPublicKeyJwk: JsonValue;
13
+ previousEpochFingerprint?: string | null;
14
+ continuityPayload?: JsonValue | null;
15
+ continuitySignature?: string | null;
16
+ signedByEpochFingerprint?: string | null;
17
+ }
18
+ export declare function validateAndPinPublicEpoch(epoch: PublicEpochForPinning, home?: string): Promise<LocalPublicEpochPin>;
19
+ //# sourceMappingURL=epoch-public-pins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epoch-public-pins.d.ts","sourceRoot":"","sources":["../../src/security/epoch-public-pins.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,SAAS,EAEf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,+BAA+B,GAAG,+BAA+B,CAAC;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,EAAE,SAAS,CAAC;IAClC,mBAAmB,EAAE,SAAS,CAAC;IAC/B,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,iBAAiB,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACrC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,qBAAqB,EAC5B,IAAI,SAAc,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAoD9B"}
@@ -0,0 +1,129 @@
1
+ import { configDir } from '../core/config.js';
2
+ import { epochFingerprint, verifyEpochTransition, } from './epoch-protocol.js';
3
+ import { getLocalPublicEpochPin, upsertLocalPublicEpochPin, } from './epoch-store.js';
4
+ export async function validateAndPinPublicEpoch(epoch, home = configDir()) {
5
+ const descriptor = publicEpochDescriptor(epoch);
6
+ const computedFingerprint = epochFingerprint(descriptor);
7
+ if (computedFingerprint !== epoch.fingerprint) {
8
+ throw new Error(`Fetched ${epoch.subjectType} epoch fingerprint mismatch for ${epoch.subjectId}.`);
9
+ }
10
+ const previous = await getLocalPublicEpochPin({
11
+ workspaceId: epoch.workspaceId,
12
+ subjectType: epoch.subjectType,
13
+ subjectId: epoch.subjectId,
14
+ }, home);
15
+ if (previous) {
16
+ if (epoch.epoch < previous.epoch) {
17
+ throw new Error(`Fetched ${epoch.subjectType} epoch rollback for ${epoch.subjectId}: ${epoch.epoch} < ${previous.epoch}.`);
18
+ }
19
+ if (epoch.epoch === previous.epoch && epoch.fingerprint !== previous.fingerprint) {
20
+ throw new Error(`Fetched ${epoch.subjectType} epoch replacement for ${epoch.subjectId} requires signed continuity.`);
21
+ }
22
+ if (epoch.epoch > previous.epoch) {
23
+ assertSignedContinuity({ previous, next: epoch });
24
+ }
25
+ }
26
+ return upsertLocalPublicEpochPin({
27
+ workspaceId: epoch.workspaceId,
28
+ subjectType: epoch.subjectType,
29
+ subjectId: epoch.subjectId,
30
+ platformEpochId: epoch.platformEpochId,
31
+ epoch: epoch.epoch,
32
+ schema: epoch.schema,
33
+ fingerprint: epoch.fingerprint,
34
+ encryptionPublicKeyJwk: epoch.encryptionPublicKeyJwk,
35
+ signingPublicKeyJwk: epoch.signingPublicKeyJwk,
36
+ previousEpochFingerprint: epoch.previousEpochFingerprint ?? null,
37
+ continuityPayload: epoch.continuityPayload ?? null,
38
+ continuitySignature: epoch.continuitySignature ?? null,
39
+ signedByEpochFingerprint: epoch.signedByEpochFingerprint ?? null,
40
+ }, home);
41
+ }
42
+ function assertSignedContinuity(input) {
43
+ if (input.next.previousEpochFingerprint !== input.previous.fingerprint) {
44
+ throw new Error(`Fetched ${input.next.subjectType} epoch ${input.next.epoch} does not continue from pinned epoch ${input.previous.epoch}.`);
45
+ }
46
+ if (!input.next.continuityPayload || !input.next.continuitySignature) {
47
+ throw new Error(`Fetched ${input.next.subjectType} epoch ${input.next.epoch} is missing signed continuity.`);
48
+ }
49
+ const signed = {
50
+ payload: epochTransitionPayload(input.next.continuityPayload),
51
+ signature: input.next.continuitySignature,
52
+ signedByEpochFingerprint: input.next.signedByEpochFingerprint ?? input.next.previousEpochFingerprint ?? '',
53
+ };
54
+ const ok = verifyEpochTransition({
55
+ signed,
56
+ signingPublicKeyJwk: input.previous.signingPublicKeyJwk,
57
+ expectedFromEpochFingerprint: input.previous.fingerprint,
58
+ expectedToEpochFingerprint: input.next.fingerprint,
59
+ });
60
+ if (!ok) {
61
+ throw new Error(`Fetched ${input.next.subjectType} epoch ${input.next.epoch} continuity signature is invalid.`);
62
+ }
63
+ }
64
+ function publicEpochDescriptor(epoch) {
65
+ return {
66
+ schema: epoch.schema,
67
+ workspaceId: epoch.workspaceId,
68
+ subjectType: epoch.subjectType,
69
+ subjectId: epoch.subjectId,
70
+ epoch: epoch.epoch,
71
+ encryptionPublicKeyJwk: epoch.encryptionPublicKeyJwk,
72
+ signingPublicKeyJwk: epoch.signingPublicKeyJwk,
73
+ previousEpochFingerprint: epoch.previousEpochFingerprint ?? null,
74
+ createdAt: 'pinning-fingerprint-input',
75
+ };
76
+ }
77
+ function epochTransitionPayload(value) {
78
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
79
+ throw new Error('Epoch continuity payload must be an object.');
80
+ }
81
+ const data = value;
82
+ return {
83
+ schema: 'viewport.epoch_transition/v1',
84
+ workspaceId: stringField(data, 'workspaceId'),
85
+ subjectType: subjectTypeField(data, 'subjectType'),
86
+ subjectId: stringField(data, 'subjectId'),
87
+ fromEpoch: numberField(data, 'fromEpoch'),
88
+ fromEpochFingerprint: stringField(data, 'fromEpochFingerprint'),
89
+ toEpoch: numberField(data, 'toEpoch'),
90
+ toEpochFingerprint: stringField(data, 'toEpochFingerprint'),
91
+ reason: reasonField(data, 'reason'),
92
+ createdAt: stringField(data, 'createdAt'),
93
+ };
94
+ }
95
+ function stringField(value, field) {
96
+ const child = value[field];
97
+ if (typeof child !== 'string' || child.trim() === '') {
98
+ throw new Error(`Epoch continuity payload missing ${field}.`);
99
+ }
100
+ return child;
101
+ }
102
+ function numberField(value, field) {
103
+ const child = value[field];
104
+ if (typeof child !== 'number') {
105
+ throw new Error(`Epoch continuity payload missing numeric ${field}.`);
106
+ }
107
+ return child;
108
+ }
109
+ function subjectTypeField(value, field) {
110
+ const child = stringField(value, field);
111
+ if (child !== 'user' && child !== 'team') {
112
+ throw new Error(`Epoch continuity payload has unsupported ${field}.`);
113
+ }
114
+ return child;
115
+ }
116
+ function reasonField(value, field) {
117
+ const child = stringField(value, field);
118
+ if (child === 'initial' ||
119
+ child === 'device_enrolled' ||
120
+ child === 'device_revoked' ||
121
+ child === 'member_added' ||
122
+ child === 'member_revoked' ||
123
+ child === 'manual_rotation' ||
124
+ child === 'recovery') {
125
+ return child;
126
+ }
127
+ throw new Error(`Epoch continuity payload has unsupported ${field}.`);
128
+ }
129
+ //# sourceMappingURL=epoch-public-pins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epoch-public-pins.js","sourceRoot":"","sources":["../../src/security/epoch-public-pins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAKtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,sBAAsB,EACtB,yBAAyB,GAE1B,MAAM,kBAAkB,CAAC;AAkB1B,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,KAA4B,EAC5B,IAAI,GAAG,SAAS,EAAE;IAElB,MAAM,UAAU,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACzD,IAAI,mBAAmB,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,CAAC,WAAW,mCAAmC,KAAK,CAAC,SAAS,GAAG,CAClF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAC3C;QACE,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,EACD,IAAI,CACL,CAAC;IAEF,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,CAAC,WAAW,uBAAuB,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,KAAK,MAAM,QAAQ,CAAC,KAAK,GAAG,CAC1G,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,IAAI,KAAK,CAAC,WAAW,KAAK,QAAQ,CAAC,WAAW,EAAE,CAAC;YACjF,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,CAAC,WAAW,0BAA0B,KAAK,CAAC,SAAS,8BAA8B,CACpG,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,sBAAsB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,OAAO,yBAAyB,CAC9B;QACE,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;QACpD,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;QAC9C,wBAAwB,EAAE,KAAK,CAAC,wBAAwB,IAAI,IAAI;QAChE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,IAAI,IAAI;QAClD,mBAAmB,EAAE,KAAK,CAAC,mBAAmB,IAAI,IAAI;QACtD,wBAAwB,EAAE,KAAK,CAAC,wBAAwB,IAAI,IAAI;KACjE,EACD,IAAI,CACL,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,KAG/B;IACC,IAAI,KAAK,CAAC,IAAI,CAAC,wBAAwB,KAAK,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,CAAC,IAAI,CAAC,WAAW,UAAU,KAAK,CAAC,IAAI,CAAC,KAAK,wCAAwC,KAAK,CAAC,QAAQ,CAAC,KAAK,GAAG,CAC3H,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,CAAC,IAAI,CAAC,WAAW,UAAU,KAAK,CAAC,IAAI,CAAC,KAAK,gCAAgC,CAC5F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAA0B;QACpC,OAAO,EAAE,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC;QAC7D,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB;QACzC,wBAAwB,EACtB,KAAK,CAAC,IAAI,CAAC,wBAAwB,IAAI,KAAK,CAAC,IAAI,CAAC,wBAAwB,IAAI,EAAE;KACnF,CAAC;IACF,MAAM,EAAE,GAAG,qBAAqB,CAAC;QAC/B,MAAM;QACN,mBAAmB,EAAE,KAAK,CAAC,QAAQ,CAAC,mBAAmB;QACvD,4BAA4B,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW;QACxD,0BAA0B,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW;KACnD,CAAC,CAAC;IACH,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,CAAC,IAAI,CAAC,WAAW,UAAU,KAAK,CAAC,IAAI,CAAC,KAAK,mCAAmC,CAC/F,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,KAA4B;IACzD,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;QACpD,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;QAC9C,wBAAwB,EAAE,KAAK,CAAC,wBAAwB,IAAI,IAAI;QAChE,SAAS,EAAE,2BAA2B;KACvC,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAgB;IAC9C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,IAAI,GAAG,KAAkC,CAAC;IAChD,OAAO;QACL,MAAM,EAAE,8BAA8B;QACtC,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7C,WAAW,EAAE,gBAAgB,CAAC,IAAI,EAAE,aAAa,CAAC;QAClD,SAAS,EAAE,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC;QACzC,SAAS,EAAE,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC;QACzC,oBAAoB,EAAE,WAAW,CAAC,IAAI,EAAE,sBAAsB,CAAC;QAC/D,OAAO,EAAE,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC;QACrC,kBAAkB,EAAE,WAAW,CAAC,IAAI,EAAE,oBAAoB,CAAC;QAC3D,MAAM,EAAE,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC;QACnC,SAAS,EAAE,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,KAAgC,EAAE,KAAa;IAClE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,GAAG,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,KAAgC,EAAE,KAAa;IAClE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,4CAA4C,KAAK,GAAG,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAgC,EAAE,KAAa;IACvE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACxC,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,4CAA4C,KAAK,GAAG,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAClB,KAAgC,EAChC,KAAa;IAEb,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACxC,IACE,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,iBAAiB;QAC3B,KAAK,KAAK,gBAAgB;QAC1B,KAAK,KAAK,cAAc;QACxB,KAAK,KAAK,gBAAgB;QAC1B,KAAK,KAAK,iBAAiB;QAC3B,KAAK,KAAK,UAAU,EACpB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,4CAA4C,KAAK,GAAG,CAAC,CAAC;AACxE,CAAC"}