@canonmsg/agent-sdk 12.5.1 → 13.0.2
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/README.md +57 -24
- package/dist/chunks/{chunk-C2WJT3VX.js → chunk-5WPAB5MB.js} +1047 -856
- package/dist/chunks/{chunk-3KFVBOVI.js → chunk-DNHJGAEL.js} +1115 -1020
- package/dist/chunks/chunk-DTAWEQCM.js +406 -0
- package/dist/chunks/{chunk-TFSURFF6.js → chunk-TYZT346O.js} +1720 -4006
- package/dist/chunks/chunk-YHDDOADK.js +118 -0
- package/dist/chunks/chunk-YJUPKU47.js +1490 -0
- package/dist/chunks/{mls-crypto-Y44BOSEM.js → mls-crypto-NZVMSUFU.js} +2 -1
- package/dist/cli.js +86 -48
- package/dist/drivers/acp.d.ts +56 -0
- package/dist/drivers/codex.d.ts +1 -2
- package/dist/drivers/subprocess.d.ts +38 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +12 -3
- package/dist/internal/backend-contracts/endpointContentPolicy.d.ts +2 -2
- package/dist/internal/backend-contracts/index.d.ts +1 -0
- package/dist/internal/backend-contracts/loggedOutSessions.d.ts +7 -0
- package/dist/internal/backend-contracts/mlsDevCredential.d.ts +3 -0
- package/dist/internal/backend-contracts/mlsDevGroup.d.ts +17 -0
- package/dist/internal/core/completed-output-journal.d.ts +0 -5
- package/dist/internal/core/index.d.ts +3 -9
- package/dist/internal/core/retry.d.ts +2 -89
- package/dist/internal/core/silent-turn.d.ts +4 -33
- package/dist/internal/endpoint/engine.d.ts +6 -0
- package/dist/internal/endpoint/mls-dev-client.d.ts +2 -0
- package/dist/internal/endpoint/mls-dev-groups.d.ts +12 -0
- package/dist/internal/endpoint/mls-dev-text.d.ts +32 -0
- package/dist/internal/endpoint/node-mls-custody-protocol.d.ts +5 -0
- package/dist/internal/endpoint/node.d.ts +1 -0
- package/dist/internal/endpoint/transport.d.ts +1 -1
- package/dist/media.js +4 -2
- package/dist/mls/darwin-arm64/canon-mls-custody +0 -0
- package/dist/mls/linux-arm64/canon-mls-custody +0 -0
- package/dist/mls/linux-x64/canon-mls-custody +0 -0
- package/dist/mls/wasm/canon_mls_wasm.js +363 -0
- package/dist/mls/wasm/canon_mls_wasm_bg.wasm +0 -0
- package/dist/mls-wasm-host.js +258 -0
- package/dist/runner/mls-bundled.d.ts +15 -2
- package/dist/runner/mls-managed.d.ts +6 -3
- package/dist/runner/mls.d.ts +4 -7
- package/dist/runner/runner.d.ts +9 -12
- package/dist/runner/types.d.ts +37 -1
- package/package.json +1 -1
- package/dist/internal/core/approval-manager.d.ts +0 -43
- package/dist/internal/core/runtime-request-manager.d.ts +0 -283
- package/dist/internal/core/turn-verbosity.d.ts +0 -79
|
@@ -1,32 +1,6 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
|
-
// ../endpoint/src/mls-crypto.ts
|
|
5
|
-
import { ed25519 } from "@noble/curves/ed25519.js";
|
|
6
|
-
|
|
7
|
-
// ../backend-contracts/src/environment.ts
|
|
8
|
-
var CANON_ENVIRONMENT_CONTRACTS = Object.freeze({
|
|
9
|
-
"canon-dev-v1": Object.freeze({
|
|
10
|
-
name: "dev",
|
|
11
|
-
projectId: "canonmail-dev",
|
|
12
|
-
region: "europe-west1"
|
|
13
|
-
}),
|
|
14
|
-
"canon-prod-v1": Object.freeze({
|
|
15
|
-
name: "prod",
|
|
16
|
-
projectId: "canonmail-prod",
|
|
17
|
-
region: "europe-west1"
|
|
18
|
-
})
|
|
19
|
-
});
|
|
20
|
-
function getCanonEnvironmentContract(value) {
|
|
21
|
-
const environmentId = value.trim();
|
|
22
|
-
const contract = CANON_ENVIRONMENT_CONTRACTS[environmentId];
|
|
23
|
-
if (!contract) {
|
|
24
|
-
throw new Error(`Unsupported Canon environment ID: ${value}`);
|
|
25
|
-
}
|
|
26
|
-
return Object.freeze({ environmentId, ...contract });
|
|
27
|
-
}
|
|
28
|
-
__name(getCanonEnvironmentContract, "getCanonEnvironmentContract");
|
|
29
|
-
|
|
30
4
|
// ../backend-contracts/src/clientFloor.ts
|
|
31
5
|
var CANON_CLIENT_HEADER = "X-Canon-Client";
|
|
32
6
|
var CLIENT_UPDATE_REQUIRED = "CLIENT_UPDATE_REQUIRED";
|
|
@@ -76,6 +50,29 @@ var MEDIA_ORIGINS = {
|
|
|
76
50
|
"canonmail-prod.firebasestorage.app": "https://api.canonmail.com"
|
|
77
51
|
};
|
|
78
52
|
|
|
53
|
+
// ../backend-contracts/src/environment.ts
|
|
54
|
+
var CANON_ENVIRONMENT_CONTRACTS = Object.freeze({
|
|
55
|
+
"canon-dev-v1": Object.freeze({
|
|
56
|
+
name: "dev",
|
|
57
|
+
projectId: "canonmail-dev",
|
|
58
|
+
region: "europe-west1"
|
|
59
|
+
}),
|
|
60
|
+
"canon-prod-v1": Object.freeze({
|
|
61
|
+
name: "prod",
|
|
62
|
+
projectId: "canonmail-prod",
|
|
63
|
+
region: "europe-west1"
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
function getCanonEnvironmentContract(value) {
|
|
67
|
+
const environmentId = value.trim();
|
|
68
|
+
const contract = CANON_ENVIRONMENT_CONTRACTS[environmentId];
|
|
69
|
+
if (!contract) {
|
|
70
|
+
throw new Error(`Unsupported Canon environment ID: ${value}`);
|
|
71
|
+
}
|
|
72
|
+
return Object.freeze({ environmentId, ...contract });
|
|
73
|
+
}
|
|
74
|
+
__name(getCanonEnvironmentContract, "getCanonEnvironmentContract");
|
|
75
|
+
|
|
79
76
|
// ../backend-contracts/src/media-url.ts
|
|
80
77
|
function validMediaPath(path) {
|
|
81
78
|
const parts = path.split("/");
|
|
@@ -123,131 +120,50 @@ function isCanonUploadUrl(url, input) {
|
|
|
123
120
|
}
|
|
124
121
|
__name(isCanonUploadUrl, "isCanonUploadUrl");
|
|
125
122
|
|
|
126
|
-
// ../backend-contracts/src/
|
|
127
|
-
var
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
"
|
|
143
|
-
|
|
144
|
-
var SAFE_VIDEO_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
145
|
-
"video/mp4",
|
|
146
|
-
"video/quicktime",
|
|
147
|
-
"video/webm",
|
|
148
|
-
"video/x-m4v"
|
|
149
|
-
]);
|
|
150
|
-
var SAFE_FILE_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
151
|
-
"application/pdf",
|
|
152
|
-
"text/plain",
|
|
153
|
-
"text/markdown",
|
|
154
|
-
"text/x-markdown",
|
|
155
|
-
"text/csv",
|
|
156
|
-
"application/csv",
|
|
157
|
-
"application/json",
|
|
158
|
-
"application/zip",
|
|
159
|
-
"application/vnd.ms-excel",
|
|
160
|
-
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
161
|
-
]);
|
|
162
|
-
var SAFE_FILE_MIME_BY_EXTENSION = {
|
|
163
|
-
csv: "text/csv",
|
|
164
|
-
json: "application/json",
|
|
165
|
-
md: "text/markdown",
|
|
166
|
-
markdown: "text/markdown",
|
|
167
|
-
pdf: "application/pdf",
|
|
168
|
-
txt: "text/plain",
|
|
169
|
-
xls: "application/vnd.ms-excel",
|
|
170
|
-
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
171
|
-
zip: "application/zip"
|
|
172
|
-
};
|
|
173
|
-
var SAFE_VIDEO_MIME_BY_EXTENSION = {
|
|
174
|
-
m4v: "video/x-m4v",
|
|
175
|
-
mov: "video/quicktime",
|
|
176
|
-
mp4: "video/mp4",
|
|
177
|
-
webm: "video/webm"
|
|
178
|
-
};
|
|
179
|
-
var SAFE_AUDIO_MIME_BY_EXTENSION = {
|
|
180
|
-
aac: "audio/aac",
|
|
181
|
-
m4a: "audio/x-m4a",
|
|
182
|
-
mp3: "audio/mpeg",
|
|
183
|
-
oga: "audio/ogg",
|
|
184
|
-
ogg: "audio/ogg",
|
|
185
|
-
wav: "audio/wav"
|
|
186
|
-
};
|
|
187
|
-
function normalizeMimeType(value) {
|
|
188
|
-
if (typeof value !== "string") return null;
|
|
189
|
-
const normalized = value.split(";")[0].trim().toLowerCase();
|
|
190
|
-
if (!MIME_TYPE_RE.test(normalized)) return null;
|
|
191
|
-
if (normalized === "image/jpg") return "image/jpeg";
|
|
192
|
-
return normalized;
|
|
193
|
-
}
|
|
194
|
-
__name(normalizeMimeType, "normalizeMimeType");
|
|
195
|
-
function inferSafeFileMimeTypeFromName(value) {
|
|
196
|
-
if (typeof value !== "string") return null;
|
|
197
|
-
const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
|
|
198
|
-
return SAFE_FILE_MIME_BY_EXTENSION[extension] ?? null;
|
|
123
|
+
// ../backend-contracts/src/mlsEnvironment.ts
|
|
124
|
+
var MLS_ENVIRONMENT_PROFILES = Object.freeze({
|
|
125
|
+
"canon-dev-v1": Object.freeze({
|
|
126
|
+
issuer: "canon-mls-dev-v1",
|
|
127
|
+
credentialType: "canon-mls-dev-credential+jws",
|
|
128
|
+
issuerKeyPath: "projects/canonmail-dev/locations/europe-west1/keyRings/canon-mls/cryptoKeys/device-issuer",
|
|
129
|
+
receiptKeyPath: "projects/canonmail-dev/locations/europe-west1/keyRings/canon-mls/cryptoKeys/feed-receipt"
|
|
130
|
+
}),
|
|
131
|
+
"canon-prod-v1": Object.freeze({
|
|
132
|
+
issuer: "canon-mls-prod-v1",
|
|
133
|
+
credentialType: "canon-mls-prod-credential+jws",
|
|
134
|
+
issuerKeyPath: "projects/canonmail-prod/locations/europe-west1/keyRings/canon-mls/cryptoKeys/device-issuer",
|
|
135
|
+
receiptKeyPath: "projects/canonmail-prod/locations/europe-west1/keyRings/canon-mls/cryptoKeys/feed-receipt"
|
|
136
|
+
})
|
|
137
|
+
});
|
|
138
|
+
function requireMlsEnvironmentId(value) {
|
|
139
|
+
if (!isMlsEnvironmentId(value)) throw new Error("INVALID_MLS_DATA");
|
|
140
|
+
return value;
|
|
199
141
|
}
|
|
200
|
-
__name(
|
|
201
|
-
function
|
|
202
|
-
|
|
203
|
-
const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
|
|
204
|
-
return SAFE_VIDEO_MIME_BY_EXTENSION[extension] ?? null;
|
|
142
|
+
__name(requireMlsEnvironmentId, "requireMlsEnvironmentId");
|
|
143
|
+
function isMlsEnvironmentId(value) {
|
|
144
|
+
return typeof value === "string" && Object.hasOwn(MLS_ENVIRONMENT_PROFILES, value);
|
|
205
145
|
}
|
|
206
|
-
__name(
|
|
207
|
-
function
|
|
208
|
-
|
|
209
|
-
const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
|
|
210
|
-
return SAFE_AUDIO_MIME_BY_EXTENSION[extension] ?? null;
|
|
146
|
+
__name(isMlsEnvironmentId, "isMlsEnvironmentId");
|
|
147
|
+
function mlsEnvironmentProfile(environmentId) {
|
|
148
|
+
return MLS_ENVIRONMENT_PROFILES[environmentId];
|
|
211
149
|
}
|
|
212
|
-
__name(
|
|
213
|
-
function
|
|
214
|
-
return
|
|
150
|
+
__name(mlsEnvironmentProfile, "mlsEnvironmentProfile");
|
|
151
|
+
function mlsEnvironmentOfIssuerKeyVersion(value) {
|
|
152
|
+
return environmentOfKeyVersion(value, "issuerKeyPath");
|
|
215
153
|
}
|
|
216
|
-
__name(
|
|
217
|
-
function
|
|
218
|
-
|
|
219
|
-
if (!mimeType) return null;
|
|
220
|
-
if (SAFE_IMAGE_MIME_TYPES.has(mimeType)) return "image";
|
|
221
|
-
if (SAFE_AUDIO_MIME_TYPES.has(mimeType)) return "audio";
|
|
222
|
-
if (SAFE_VIDEO_MIME_TYPES.has(mimeType)) return "video";
|
|
223
|
-
if (SAFE_FILE_MIME_TYPES.has(mimeType)) return "file";
|
|
224
|
-
return null;
|
|
154
|
+
__name(mlsEnvironmentOfIssuerKeyVersion, "mlsEnvironmentOfIssuerKeyVersion");
|
|
155
|
+
function mlsEnvironmentOfReceiptKeyVersion(value) {
|
|
156
|
+
return environmentOfKeyVersion(value, "receiptKeyPath");
|
|
225
157
|
}
|
|
226
|
-
__name(
|
|
227
|
-
function
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const inferredAudioMimeType = inferSafeAudioMimeTypeFromName(input.fileName);
|
|
232
|
-
const inferredFileMimeType = inferSafeFileMimeTypeFromName(input.fileName);
|
|
233
|
-
if (hasExplicitMimeType && !normalizedMimeType) {
|
|
234
|
-
return null;
|
|
235
|
-
}
|
|
236
|
-
if (inferredVideoMimeType && (!normalizedMimeType || normalizedMimeType === "application/octet-stream")) {
|
|
237
|
-
return inferredVideoMimeType;
|
|
238
|
-
}
|
|
239
|
-
if (inferredAudioMimeType && (!normalizedMimeType || normalizedMimeType === "application/octet-stream")) {
|
|
240
|
-
return inferredAudioMimeType;
|
|
241
|
-
}
|
|
242
|
-
if (inferredFileMimeType && shouldTrustSafeFileName(normalizedMimeType)) {
|
|
243
|
-
return inferredFileMimeType;
|
|
244
|
-
}
|
|
245
|
-
if (normalizedMimeType && classifyAllowedUploadMimeType(normalizedMimeType)) {
|
|
246
|
-
return normalizedMimeType;
|
|
158
|
+
__name(mlsEnvironmentOfReceiptKeyVersion, "mlsEnvironmentOfReceiptKeyVersion");
|
|
159
|
+
function environmentOfKeyVersion(value, key) {
|
|
160
|
+
for (const [environmentId, profile] of Object.entries(MLS_ENVIRONMENT_PROFILES)) {
|
|
161
|
+
const prefix = profile[key] + "/cryptoKeyVersions/";
|
|
162
|
+
if (value.startsWith(prefix) && /^[1-9][0-9]{0,9}$/.test(value.slice(prefix.length))) return environmentId;
|
|
247
163
|
}
|
|
248
|
-
return
|
|
164
|
+
return void 0;
|
|
249
165
|
}
|
|
250
|
-
__name(
|
|
166
|
+
__name(environmentOfKeyVersion, "environmentOfKeyVersion");
|
|
251
167
|
|
|
252
168
|
// ../backend-contracts/src/mlsDevValidation.ts
|
|
253
169
|
function invalid() {
|
|
@@ -288,51 +204,6 @@ function requireMlsUuid(value) {
|
|
|
288
204
|
}
|
|
289
205
|
__name(requireMlsUuid, "requireMlsUuid");
|
|
290
206
|
|
|
291
|
-
// ../backend-contracts/src/mlsEnvironment.ts
|
|
292
|
-
var MLS_ENVIRONMENT_PROFILES = Object.freeze({
|
|
293
|
-
"canon-dev-v1": Object.freeze({
|
|
294
|
-
issuer: "canon-mls-dev-v1",
|
|
295
|
-
credentialType: "canon-mls-dev-credential+jws",
|
|
296
|
-
issuerKeyPath: "projects/canonmail-dev/locations/europe-west1/keyRings/canon-mls/cryptoKeys/device-issuer",
|
|
297
|
-
receiptKeyPath: "projects/canonmail-dev/locations/europe-west1/keyRings/canon-mls/cryptoKeys/feed-receipt"
|
|
298
|
-
}),
|
|
299
|
-
"canon-prod-v1": Object.freeze({
|
|
300
|
-
issuer: "canon-mls-prod-v1",
|
|
301
|
-
credentialType: "canon-mls-prod-credential+jws",
|
|
302
|
-
issuerKeyPath: "projects/canonmail-prod/locations/europe-west1/keyRings/canon-mls/cryptoKeys/device-issuer",
|
|
303
|
-
receiptKeyPath: "projects/canonmail-prod/locations/europe-west1/keyRings/canon-mls/cryptoKeys/feed-receipt"
|
|
304
|
-
})
|
|
305
|
-
});
|
|
306
|
-
function requireMlsEnvironmentId(value) {
|
|
307
|
-
if (!isMlsEnvironmentId(value)) throw new Error("INVALID_MLS_DATA");
|
|
308
|
-
return value;
|
|
309
|
-
}
|
|
310
|
-
__name(requireMlsEnvironmentId, "requireMlsEnvironmentId");
|
|
311
|
-
function isMlsEnvironmentId(value) {
|
|
312
|
-
return typeof value === "string" && Object.hasOwn(MLS_ENVIRONMENT_PROFILES, value);
|
|
313
|
-
}
|
|
314
|
-
__name(isMlsEnvironmentId, "isMlsEnvironmentId");
|
|
315
|
-
function mlsEnvironmentProfile(environmentId) {
|
|
316
|
-
return MLS_ENVIRONMENT_PROFILES[environmentId];
|
|
317
|
-
}
|
|
318
|
-
__name(mlsEnvironmentProfile, "mlsEnvironmentProfile");
|
|
319
|
-
function mlsEnvironmentOfIssuerKeyVersion(value) {
|
|
320
|
-
return environmentOfKeyVersion(value, "issuerKeyPath");
|
|
321
|
-
}
|
|
322
|
-
__name(mlsEnvironmentOfIssuerKeyVersion, "mlsEnvironmentOfIssuerKeyVersion");
|
|
323
|
-
function mlsEnvironmentOfReceiptKeyVersion(value) {
|
|
324
|
-
return environmentOfKeyVersion(value, "receiptKeyPath");
|
|
325
|
-
}
|
|
326
|
-
__name(mlsEnvironmentOfReceiptKeyVersion, "mlsEnvironmentOfReceiptKeyVersion");
|
|
327
|
-
function environmentOfKeyVersion(value, key) {
|
|
328
|
-
for (const [environmentId, profile] of Object.entries(MLS_ENVIRONMENT_PROFILES)) {
|
|
329
|
-
const prefix = profile[key] + "/cryptoKeyVersions/";
|
|
330
|
-
if (value.startsWith(prefix) && /^[1-9][0-9]{0,9}$/.test(value.slice(prefix.length))) return environmentId;
|
|
331
|
-
}
|
|
332
|
-
return void 0;
|
|
333
|
-
}
|
|
334
|
-
__name(environmentOfKeyVersion, "environmentOfKeyVersion");
|
|
335
|
-
|
|
336
207
|
// ../backend-contracts/src/mlsDevEnrollment.ts
|
|
337
208
|
var MLS_DEV_ENROLLMENT_CHALLENGE_TTL_MS = 3e5;
|
|
338
209
|
var MLS_DEV_ENROLLMENT_MAX_BYTES = 4096;
|
|
@@ -540,6 +411,7 @@ __name(decodeCanonicalMlsBase64Url, "decodeCanonicalMlsBase64Url");
|
|
|
540
411
|
|
|
541
412
|
// ../backend-contracts/src/mlsDevCredential.ts
|
|
542
413
|
var MLS_DEV_CREDENTIAL_TTL_MS = 864e5;
|
|
414
|
+
var MLS_DEV_CREDENTIAL_LONG_TTL_MS = 14 * MLS_DEV_CREDENTIAL_TTL_MS;
|
|
543
415
|
var MLS_DEV_CREDENTIAL_CHALLENGE_TTL_MS = 3e5;
|
|
544
416
|
var MLS_DEV_CREDENTIAL_MAX_BYTES = 8192;
|
|
545
417
|
var MlsDevCredentialValidationError = class extends Error {
|
|
@@ -591,8 +463,9 @@ function parseMlsDevCredentialClaims(value) {
|
|
|
591
463
|
const input = readMlsDataRecord(value, ["version", "credentialId", "issuer", "device", "generation", "issuedAtMs", "expiresAtMs"]);
|
|
592
464
|
const issuedAtMs = requireMlsInteger(input.issuedAtMs);
|
|
593
465
|
const expiresAtMs = requireMlsInteger(input.expiresAtMs);
|
|
594
|
-
if (expiresAtMs - issuedAtMs !== MLS_DEV_CREDENTIAL_TTL_MS) invalid3();
|
|
595
466
|
const device = parseMlsDevEnrollmentResult({ version: 1, authorization: "registration_only", device: input.device }).device;
|
|
467
|
+
const lifetimeMs = expiresAtMs - issuedAtMs;
|
|
468
|
+
if (lifetimeMs !== MLS_DEV_CREDENTIAL_TTL_MS && (lifetimeMs !== MLS_DEV_CREDENTIAL_LONG_TTL_MS || device.principal.type !== "human")) invalid3();
|
|
596
469
|
return bounded2({
|
|
597
470
|
version: requireMlsLiteral(input.version, 1),
|
|
598
471
|
credentialId: requireMlsUuid(input.credentialId),
|
|
@@ -723,19 +596,21 @@ function parseMlsDevCredentialReceipt(value) {
|
|
|
723
596
|
}
|
|
724
597
|
__name(parseMlsDevCredentialReceipt, "parseMlsDevCredentialReceipt");
|
|
725
598
|
|
|
726
|
-
// ../backend-contracts/src/
|
|
727
|
-
var
|
|
599
|
+
// ../backend-contracts/src/mlsDevGroupFeed.ts
|
|
600
|
+
var MLS_DEV_GROUP_FEED_MAX_ENTRIES = 4;
|
|
601
|
+
var MLS_DEV_GROUP_FEED_MAX_BYTES = 4 * 1024 * 1024;
|
|
602
|
+
var MlsDevGroupFeedValidationError = class extends Error {
|
|
728
603
|
static {
|
|
729
|
-
__name(this, "
|
|
604
|
+
__name(this, "MlsDevGroupFeedValidationError");
|
|
730
605
|
}
|
|
731
|
-
code = "
|
|
606
|
+
code = "INVALID_MLS_DEV_GROUP_FEED";
|
|
732
607
|
constructor() {
|
|
733
|
-
super("
|
|
734
|
-
this.name = "
|
|
608
|
+
super("INVALID_MLS_DEV_GROUP_FEED");
|
|
609
|
+
this.name = "MlsDevGroupFeedValidationError";
|
|
735
610
|
}
|
|
736
611
|
};
|
|
737
612
|
function invalid4() {
|
|
738
|
-
throw new
|
|
613
|
+
throw new MlsDevGroupFeedValidationError();
|
|
739
614
|
}
|
|
740
615
|
__name(invalid4, "invalid");
|
|
741
616
|
function boundary3(read) {
|
|
@@ -746,139 +621,89 @@ function boundary3(read) {
|
|
|
746
621
|
}
|
|
747
622
|
}
|
|
748
623
|
__name(boundary3, "boundary");
|
|
749
|
-
function parseMlsDevReceiptKeyVersion(value, environmentId) {
|
|
750
|
-
return boundary3(() => {
|
|
751
|
-
if (typeof value !== "string" || value.length > 200) invalid4();
|
|
752
|
-
const owner = mlsEnvironmentOfReceiptKeyVersion(value);
|
|
753
|
-
if (!owner || environmentId !== void 0 && owner !== environmentId) invalid4();
|
|
754
|
-
return value;
|
|
755
|
-
});
|
|
756
|
-
}
|
|
757
|
-
__name(parseMlsDevReceiptKeyVersion, "parseMlsDevReceiptKeyVersion");
|
|
758
|
-
function parseMlsDevFeedReceiptProof(value) {
|
|
759
|
-
return boundary3(() => {
|
|
760
|
-
const input = readMlsDataRecord(value, ["keyVersion", "signature"]);
|
|
761
|
-
decodeCanonicalMlsBase64Url(input.signature, 64);
|
|
762
|
-
return Object.freeze({ keyVersion: parseMlsDevReceiptKeyVersion(input.keyVersion), signature: input.signature });
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
__name(parseMlsDevFeedReceiptProof, "parseMlsDevFeedReceiptProof");
|
|
766
|
-
var MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW = "MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW";
|
|
767
|
-
function isMlsDevReceiptClockSkew(value) {
|
|
768
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
769
|
-
const keys2 = Object.keys(value).sort().join(), input = value;
|
|
770
|
-
return (keys2 === "error,ok,retryable" || keys2 === "error,ok,retryable,version" && input.version === 1) && input.ok === false && input.error === MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW && input.retryable === true;
|
|
771
|
-
}
|
|
772
|
-
__name(isMlsDevReceiptClockSkew, "isMlsDevReceiptClockSkew");
|
|
773
|
-
|
|
774
|
-
// ../backend-contracts/src/mlsDevGroupFeed.ts
|
|
775
|
-
var MLS_DEV_GROUP_FEED_MAX_ENTRIES = 4;
|
|
776
|
-
var MLS_DEV_GROUP_FEED_MAX_BYTES = 4 * 1024 * 1024;
|
|
777
|
-
var MlsDevGroupFeedValidationError = class extends Error {
|
|
778
|
-
static {
|
|
779
|
-
__name(this, "MlsDevGroupFeedValidationError");
|
|
780
|
-
}
|
|
781
|
-
code = "INVALID_MLS_DEV_GROUP_FEED";
|
|
782
|
-
constructor() {
|
|
783
|
-
super("INVALID_MLS_DEV_GROUP_FEED");
|
|
784
|
-
this.name = "MlsDevGroupFeedValidationError";
|
|
785
|
-
}
|
|
786
|
-
};
|
|
787
|
-
function invalid5() {
|
|
788
|
-
throw new MlsDevGroupFeedValidationError();
|
|
789
|
-
}
|
|
790
|
-
__name(invalid5, "invalid");
|
|
791
|
-
function boundary4(read) {
|
|
792
|
-
try {
|
|
793
|
-
return read();
|
|
794
|
-
} catch {
|
|
795
|
-
return invalid5();
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
__name(boundary4, "boundary");
|
|
799
624
|
function id(value) {
|
|
800
625
|
if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..")
|
|
801
|
-
|
|
626
|
+
invalid4();
|
|
802
627
|
return value;
|
|
803
628
|
}
|
|
804
629
|
__name(id, "id");
|
|
805
630
|
function boolean(value) {
|
|
806
631
|
if (typeof value !== "boolean")
|
|
807
|
-
|
|
632
|
+
invalid4();
|
|
808
633
|
return value;
|
|
809
634
|
}
|
|
810
635
|
__name(boolean, "boolean");
|
|
811
636
|
function bounded3(value) {
|
|
812
637
|
if (new TextEncoder().encode(JSON.stringify(value)).length > MLS_DEV_GROUP_FEED_MAX_BYTES)
|
|
813
|
-
|
|
638
|
+
invalid4();
|
|
814
639
|
return Object.freeze(value);
|
|
815
640
|
}
|
|
816
641
|
__name(bounded3, "bounded");
|
|
817
642
|
function array(value) {
|
|
818
643
|
if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || value.length > MLS_DEV_GROUP_FEED_MAX_ENTRIES)
|
|
819
|
-
|
|
644
|
+
invalid4();
|
|
820
645
|
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
821
646
|
if (Reflect.ownKeys(descriptors).length !== value.length + 1)
|
|
822
|
-
|
|
647
|
+
invalid4();
|
|
823
648
|
return Array.from({ length: value.length }, (_, index) => {
|
|
824
649
|
const field = descriptors[index];
|
|
825
650
|
if (!field || !field.enumerable || !Object.hasOwn(field, "value"))
|
|
826
|
-
|
|
651
|
+
invalid4();
|
|
827
652
|
return field.value;
|
|
828
653
|
});
|
|
829
654
|
}
|
|
830
655
|
__name(array, "array");
|
|
831
656
|
function parseMlsDevGroupFeedEntry(value) {
|
|
832
|
-
return
|
|
657
|
+
return boundary3(() => {
|
|
833
658
|
const signed = value !== null && typeof value === "object" && Object.hasOwn(value, "receiptProof") ? ["receiptProof"] : [];
|
|
834
659
|
const input = readMlsDataRecord(value, ["version", "ordinal", "kind", "accepted", ...signed], ["version", "ordinal", "kind", "receipt", "envelope", ...signed]);
|
|
835
660
|
const version = requireMlsLiteral(input.version, 1), ordinal = requireMlsInteger(input.ordinal, 1);
|
|
836
661
|
const proof = signed.length ? { receiptProof: parseMlsDevFeedReceiptProof(input.receiptProof) } : {};
|
|
837
662
|
if (input.kind === "control") {
|
|
838
663
|
if (!Object.hasOwn(input, "accepted"))
|
|
839
|
-
|
|
664
|
+
invalid4();
|
|
840
665
|
return bounded3({ version, ordinal, kind: "control", accepted: parseMlsDevGroupAcceptedControl(input.accepted), ...proof });
|
|
841
666
|
}
|
|
842
667
|
const kind = requireMlsLiteral(input.kind, "application"), receipt = parseMlsDevApplicationReceipt(input.receipt), envelope = parseMlsDevApplicationEnvelope(input.envelope);
|
|
843
668
|
if (ordinal !== receipt.feedOrdinal || receipt.conversationId !== envelope.conversationId || receipt.groupId !== envelope.groupId || receipt.messageId !== envelope.messageId || JSON.stringify(receipt.head) !== JSON.stringify(envelope.expectedHead))
|
|
844
|
-
|
|
669
|
+
invalid4();
|
|
845
670
|
return bounded3({ version, ordinal, kind, receipt, envelope, ...proof });
|
|
846
671
|
});
|
|
847
672
|
}
|
|
848
673
|
__name(parseMlsDevGroupFeedEntry, "parseMlsDevGroupFeedEntry");
|
|
849
674
|
function parseMlsDevGroupFeedQuery(value) {
|
|
850
|
-
return
|
|
675
|
+
return boundary3(() => {
|
|
851
676
|
const input = readMlsDataRecord(value, ["version", "conversationId", "credential", "afterOrdinal", "limit"]);
|
|
852
677
|
const limit2 = requireMlsInteger(input.limit, 1);
|
|
853
678
|
if (limit2 > MLS_DEV_GROUP_FEED_MAX_ENTRIES)
|
|
854
|
-
|
|
679
|
+
invalid4();
|
|
855
680
|
parseMlsDevCredentialToken(input.credential);
|
|
856
681
|
return Object.freeze({ version: requireMlsLiteral(input.version, 1), conversationId: id(input.conversationId), credential: input.credential, afterOrdinal: requireMlsInteger(input.afterOrdinal), limit: limit2 });
|
|
857
682
|
});
|
|
858
683
|
}
|
|
859
684
|
__name(parseMlsDevGroupFeedQuery, "parseMlsDevGroupFeedQuery");
|
|
860
685
|
function parseMlsDevGroupFeedResult(value) {
|
|
861
|
-
return
|
|
686
|
+
return boundary3(() => {
|
|
862
687
|
const input = readMlsDataRecord(value, ["version", "protocol", "conversationId", "marker", "membershipRevision", "admissionId", "roster", "minimumOrdinal", "latestOrdinal", "nextOrdinal", "entries", "hasMore", "terminal"]);
|
|
863
688
|
const conversationId = id(input.conversationId), marker = input.marker === null ? null : parseMlsDevGroupMarker(input.marker);
|
|
864
689
|
const minimumOrdinal = input.minimumOrdinal === null ? null : requireMlsInteger(input.minimumOrdinal, 1);
|
|
865
690
|
const latestOrdinal = requireMlsInteger(input.latestOrdinal), nextOrdinal = requireMlsInteger(input.nextOrdinal);
|
|
866
691
|
const entries = array(input.entries).map(parseMlsDevGroupFeedEntry), hasMore = boolean(input.hasMore), terminal = boolean(input.terminal);
|
|
867
692
|
if (nextOrdinal > latestOrdinal || minimumOrdinal !== null && minimumOrdinal > latestOrdinal || minimumOrdinal === null && (entries.length || nextOrdinal || hasMore || terminal) || !marker && (latestOrdinal || minimumOrdinal !== null || entries.length || terminal))
|
|
868
|
-
|
|
869
|
-
const protocol = isMlsDevTextProtocol(input.protocol) ? input.protocol :
|
|
693
|
+
invalid4();
|
|
694
|
+
const protocol = isMlsDevTextProtocol(input.protocol) ? input.protocol : invalid4();
|
|
870
695
|
for (let i = 0; i < entries.length; i++) {
|
|
871
696
|
const entry = entries[i], subject = entry.kind === "control" ? entry.accepted.control : entry.envelope;
|
|
872
697
|
if (entry.kind === "application" && entry.envelope.interaction && !mlsDevProtocolCarriesCards(protocol))
|
|
873
|
-
|
|
698
|
+
invalid4();
|
|
874
699
|
if (!marker || minimumOrdinal === null || entry.ordinal < minimumOrdinal || entry.ordinal > latestOrdinal || subject.conversationId !== conversationId || subject.groupId !== marker.groupId || i > 0 && entry.ordinal !== entries[i - 1].ordinal + 1)
|
|
875
|
-
|
|
700
|
+
invalid4();
|
|
876
701
|
const head = entry.kind === "control" ? entry.accepted.head : entry.receipt.head;
|
|
877
702
|
if (head.sequence > marker.head.sequence || head.epoch > marker.head.epoch)
|
|
878
|
-
|
|
703
|
+
invalid4();
|
|
879
704
|
}
|
|
880
705
|
if (entries.length && entries.at(-1).ordinal !== nextOrdinal || hasMore !== (minimumOrdinal !== null && nextOrdinal < latestOrdinal))
|
|
881
|
-
|
|
706
|
+
invalid4();
|
|
882
707
|
return bounded3({
|
|
883
708
|
version: requireMlsLiteral(input.version, 1),
|
|
884
709
|
protocol,
|
|
@@ -911,25 +736,25 @@ var MlsDevKeyPackagesValidationError = class extends Error {
|
|
|
911
736
|
this.name = "MlsDevKeyPackagesValidationError";
|
|
912
737
|
}
|
|
913
738
|
};
|
|
914
|
-
function
|
|
739
|
+
function invalid5() {
|
|
915
740
|
throw new MlsDevKeyPackagesValidationError();
|
|
916
741
|
}
|
|
917
|
-
__name(
|
|
918
|
-
function
|
|
742
|
+
__name(invalid5, "invalid");
|
|
743
|
+
function boundary4(read) {
|
|
919
744
|
try {
|
|
920
745
|
return read();
|
|
921
746
|
} catch {
|
|
922
|
-
return
|
|
747
|
+
return invalid5();
|
|
923
748
|
}
|
|
924
749
|
}
|
|
925
|
-
__name(
|
|
750
|
+
__name(boundary4, "boundary");
|
|
926
751
|
function bounded4(value) {
|
|
927
|
-
if (new TextEncoder().encode(JSON.stringify(value)).length > MLS_DEV_KEY_PACKAGES_MAX_BYTES)
|
|
752
|
+
if (new TextEncoder().encode(JSON.stringify(value)).length > MLS_DEV_KEY_PACKAGES_MAX_BYTES) invalid5();
|
|
928
753
|
return Object.freeze(value);
|
|
929
754
|
}
|
|
930
755
|
__name(bounded4, "bounded");
|
|
931
756
|
function id2(value) {
|
|
932
|
-
if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..")
|
|
757
|
+
if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..") invalid5();
|
|
933
758
|
return value;
|
|
934
759
|
}
|
|
935
760
|
__name(id2, "id");
|
|
@@ -939,18 +764,18 @@ function ref(value) {
|
|
|
939
764
|
}
|
|
940
765
|
__name(ref, "ref");
|
|
941
766
|
function parseMlsDevKeyPackageWire(value) {
|
|
942
|
-
return
|
|
943
|
-
if (typeof value !== "string" || value.length < 2 || value.length > Math.ceil(MLS_DEV_KEY_PACKAGE_TLS_MAX_BYTES * 4 / 3))
|
|
767
|
+
return boundary4(() => {
|
|
768
|
+
if (typeof value !== "string" || value.length < 2 || value.length > Math.ceil(MLS_DEV_KEY_PACKAGE_TLS_MAX_BYTES * 4 / 3)) invalid5();
|
|
944
769
|
const bytes = Math.floor(value.length * 3 / 4);
|
|
945
|
-
if (bytes < 1 || bytes > MLS_DEV_KEY_PACKAGE_TLS_MAX_BYTES || value.length !== Math.ceil(bytes * 4 / 3) || !/^[A-Za-z0-9_-]+$/.test(value))
|
|
770
|
+
if (bytes < 1 || bytes > MLS_DEV_KEY_PACKAGE_TLS_MAX_BYTES || value.length !== Math.ceil(bytes * 4 / 3) || !/^[A-Za-z0-9_-]+$/.test(value)) invalid5();
|
|
946
771
|
const last = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(value.at(-1));
|
|
947
|
-
if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0)
|
|
772
|
+
if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0) invalid5();
|
|
948
773
|
return value;
|
|
949
774
|
});
|
|
950
775
|
}
|
|
951
776
|
__name(parseMlsDevKeyPackageWire, "parseMlsDevKeyPackageWire");
|
|
952
777
|
function parseMlsDevKeyPackageClaimPreconditions(value) {
|
|
953
|
-
return
|
|
778
|
+
return boundary4(() => {
|
|
954
779
|
const input = readMlsDataRecord(value, ["conversationId", "membershipRevision", "admissionId", "targetAdmissionId"]);
|
|
955
780
|
return Object.freeze({
|
|
956
781
|
conversationId: id2(input.conversationId),
|
|
@@ -962,17 +787,17 @@ function parseMlsDevKeyPackageClaimPreconditions(value) {
|
|
|
962
787
|
}
|
|
963
788
|
__name(parseMlsDevKeyPackageClaimPreconditions, "parseMlsDevKeyPackageClaimPreconditions");
|
|
964
789
|
function parseMlsDevKeyPackagePublish(value) {
|
|
965
|
-
return
|
|
790
|
+
return boundary4(() => {
|
|
966
791
|
const input = readMlsDataRecord(value, ["version", "requestId", "keyPackage"]);
|
|
967
792
|
return bounded4({ version: requireMlsLiteral(input.version, 1), requestId: requireMlsUuid(input.requestId), keyPackage: parseMlsDevKeyPackageWire(input.keyPackage) });
|
|
968
793
|
});
|
|
969
794
|
}
|
|
970
795
|
__name(parseMlsDevKeyPackagePublish, "parseMlsDevKeyPackagePublish");
|
|
971
796
|
function parseMlsDevKeyPackagePublicationReceipt(value) {
|
|
972
|
-
return
|
|
797
|
+
return boundary4(() => {
|
|
973
798
|
const input = readMlsDataRecord(value, ["version", "authorization", "requestId", "keyPackageRef", "deviceId", "publishedAtMs", "expiresAtMs"]);
|
|
974
799
|
const publishedAtMs = requireMlsInteger(input.publishedAtMs), expiresAtMs = requireMlsInteger(input.expiresAtMs);
|
|
975
|
-
if (publishedAtMs >= expiresAtMs)
|
|
800
|
+
if (publishedAtMs >= expiresAtMs) invalid5();
|
|
976
801
|
return bounded4({
|
|
977
802
|
version: requireMlsLiteral(input.version, 1),
|
|
978
803
|
authorization: requireMlsLiteral(input.authorization, "key_package_publication_only"),
|
|
@@ -986,7 +811,7 @@ function parseMlsDevKeyPackagePublicationReceipt(value) {
|
|
|
986
811
|
}
|
|
987
812
|
__name(parseMlsDevKeyPackagePublicationReceipt, "parseMlsDevKeyPackagePublicationReceipt");
|
|
988
813
|
function parseMlsDevKeyPackageClaim(value) {
|
|
989
|
-
return
|
|
814
|
+
return boundary4(() => {
|
|
990
815
|
const input = readMlsDataRecord(value, ["version", "requestId", "claimantCredential", "recipientDeviceId", "preconditions"]);
|
|
991
816
|
parseMlsDevCredentialToken(input.claimantCredential);
|
|
992
817
|
return bounded4({
|
|
@@ -1000,7 +825,7 @@ function parseMlsDevKeyPackageClaim(value) {
|
|
|
1000
825
|
}
|
|
1001
826
|
__name(parseMlsDevKeyPackageClaim, "parseMlsDevKeyPackageClaim");
|
|
1002
827
|
function parseMlsDevKeyPackageClaimReceipt(value) {
|
|
1003
|
-
return
|
|
828
|
+
return boundary4(() => {
|
|
1004
829
|
const input = readMlsDataRecord(value, [
|
|
1005
830
|
"version",
|
|
1006
831
|
"authorization",
|
|
@@ -1013,7 +838,7 @@ function parseMlsDevKeyPackageClaimReceipt(value) {
|
|
|
1013
838
|
"claimedAtMs"
|
|
1014
839
|
]);
|
|
1015
840
|
const claimantDeviceId = requireMlsUuid(input.claimantDeviceId), recipientDeviceId = requireMlsUuid(input.recipientDeviceId);
|
|
1016
|
-
if (claimantDeviceId === recipientDeviceId)
|
|
841
|
+
if (claimantDeviceId === recipientDeviceId) invalid5();
|
|
1017
842
|
return bounded4({
|
|
1018
843
|
version: requireMlsLiteral(input.version, 1),
|
|
1019
844
|
authorization: requireMlsLiteral(input.authorization, "key_package_claim_only"),
|
|
@@ -1044,25 +869,25 @@ var MlsDevInteractionValidationError = class extends Error {
|
|
|
1044
869
|
}
|
|
1045
870
|
};
|
|
1046
871
|
var utf83 = new TextEncoder();
|
|
1047
|
-
function
|
|
872
|
+
function invalid6() {
|
|
1048
873
|
throw new MlsDevInteractionValidationError();
|
|
1049
874
|
}
|
|
1050
|
-
__name(
|
|
1051
|
-
function
|
|
875
|
+
__name(invalid6, "invalid");
|
|
876
|
+
function boundary5(read) {
|
|
1052
877
|
try {
|
|
1053
878
|
return read();
|
|
1054
879
|
} catch {
|
|
1055
|
-
return
|
|
880
|
+
return invalid6();
|
|
1056
881
|
}
|
|
1057
882
|
}
|
|
1058
|
-
__name(
|
|
883
|
+
__name(boundary5, "boundary");
|
|
1059
884
|
function id3(value) {
|
|
1060
|
-
if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..")
|
|
885
|
+
if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..") invalid6();
|
|
1061
886
|
return value;
|
|
1062
887
|
}
|
|
1063
888
|
__name(id3, "id");
|
|
1064
889
|
function interactionId(value) {
|
|
1065
|
-
if (typeof value !== "string" || !MLS_DEV_INTERACTION_ID_PATTERN.test(value) || value === "." || value === "..")
|
|
890
|
+
if (typeof value !== "string" || !MLS_DEV_INTERACTION_ID_PATTERN.test(value) || value === "." || value === "..") invalid6();
|
|
1066
891
|
return value;
|
|
1067
892
|
}
|
|
1068
893
|
__name(interactionId, "interactionId");
|
|
@@ -1072,39 +897,39 @@ function encoded3(value, bytes) {
|
|
|
1072
897
|
}
|
|
1073
898
|
__name(encoded3, "encoded");
|
|
1074
899
|
function wire(value, min, max) {
|
|
1075
|
-
if (typeof value !== "string" || !/^[A-Za-z0-9_-]*$/.test(value) || value.length % 4 === 1)
|
|
900
|
+
if (typeof value !== "string" || !/^[A-Za-z0-9_-]*$/.test(value) || value.length % 4 === 1) invalid6();
|
|
1076
901
|
const bytes = Math.floor(value.length * 3 / 4);
|
|
1077
|
-
if (bytes < min || bytes > max)
|
|
902
|
+
if (bytes < min || bytes > max) invalid6();
|
|
1078
903
|
const last = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(value.at(-1));
|
|
1079
|
-
if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0)
|
|
904
|
+
if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0) invalid6();
|
|
1080
905
|
return value;
|
|
1081
906
|
}
|
|
1082
907
|
__name(wire, "wire");
|
|
1083
908
|
function text(value, max) {
|
|
1084
|
-
if (typeof value !== "string" || !value.trim() || [...value].length > max || new TextDecoder("utf-8", { fatal: true }).decode(utf83.encode(value)) !== value)
|
|
909
|
+
if (typeof value !== "string" || !value.trim() || [...value].length > max || new TextDecoder("utf-8", { fatal: true }).decode(utf83.encode(value)) !== value) invalid6();
|
|
1085
910
|
return value;
|
|
1086
911
|
}
|
|
1087
912
|
__name(text, "text");
|
|
1088
913
|
function boolean2(value) {
|
|
1089
|
-
if (typeof value !== "boolean")
|
|
914
|
+
if (typeof value !== "boolean") invalid6();
|
|
1090
915
|
return value;
|
|
1091
916
|
}
|
|
1092
917
|
__name(boolean2, "boolean");
|
|
1093
918
|
function array2(value, min, max) {
|
|
1094
|
-
if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || value.length < min || value.length > max)
|
|
919
|
+
if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || value.length < min || value.length > max) invalid6();
|
|
1095
920
|
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
1096
|
-
if (Reflect.ownKeys(descriptors).length !== value.length + 1)
|
|
921
|
+
if (Reflect.ownKeys(descriptors).length !== value.length + 1) invalid6();
|
|
1097
922
|
return Array.from({ length: value.length }, (_, index) => {
|
|
1098
923
|
const field = descriptors[index];
|
|
1099
|
-
if (!field || !field.enumerable || !Object.hasOwn(field, "value"))
|
|
924
|
+
if (!field || !field.enumerable || !Object.hasOwn(field, "value")) invalid6();
|
|
1100
925
|
return field.value;
|
|
1101
926
|
});
|
|
1102
927
|
}
|
|
1103
928
|
__name(array2, "array");
|
|
1104
929
|
function closed(value, required, optional) {
|
|
1105
|
-
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
930
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) invalid6();
|
|
1106
931
|
const present2 = Reflect.ownKeys(value);
|
|
1107
|
-
if (present2.some((key) => typeof key !== "string" || !required.includes(key) && !optional.includes(key)))
|
|
932
|
+
if (present2.some((key) => typeof key !== "string" || !required.includes(key) && !optional.includes(key))) invalid6();
|
|
1108
933
|
return readMlsDataRecord(value, present2);
|
|
1109
934
|
}
|
|
1110
935
|
__name(closed, "closed");
|
|
@@ -1113,31 +938,31 @@ function ordered(value) {
|
|
|
1113
938
|
}
|
|
1114
939
|
__name(ordered, "ordered");
|
|
1115
940
|
function parseMlsDevInteractionRequestBody(value) {
|
|
1116
|
-
return
|
|
941
|
+
return boundary5(() => {
|
|
1117
942
|
const input = closed(
|
|
1118
943
|
value,
|
|
1119
944
|
["requestId", "kind", "title", "responderIds", "expiresAtMs"],
|
|
1120
945
|
["details", "options", "multiple", "risk", "allowSession", "scopeKey", "secretKey"]
|
|
1121
946
|
);
|
|
1122
947
|
const kind = input.kind;
|
|
1123
|
-
if (typeof kind !== "string" || !MLS_DEV_INTERACTION_KINDS.includes(kind))
|
|
948
|
+
if (typeof kind !== "string" || !MLS_DEV_INTERACTION_KINDS.includes(kind)) invalid6();
|
|
1124
949
|
const has = /* @__PURE__ */ __name((key) => Object.hasOwn(input, key), "has");
|
|
1125
950
|
const options = has("options") ? array2(input.options, 1, MLS_DEV_INTERACTION_LIMITS.options).map((option) => {
|
|
1126
951
|
const fields2 = readMlsDataRecord(option, ["id", "label"]);
|
|
1127
|
-
if (typeof fields2.id !== "string" || !/^[A-Za-z0-9_.:-]{1,64}$/.test(fields2.id))
|
|
952
|
+
if (typeof fields2.id !== "string" || !/^[A-Za-z0-9_.:-]{1,64}$/.test(fields2.id)) invalid6();
|
|
1128
953
|
return Object.freeze({ id: fields2.id, label: text(fields2.label, MLS_DEV_INTERACTION_LIMITS.optionLabel) });
|
|
1129
954
|
}) : void 0;
|
|
1130
|
-
if (options && new Set(options.map((option) => option.id)).size !== options.length)
|
|
955
|
+
if (options && new Set(options.map((option) => option.id)).size !== options.length) invalid6();
|
|
1131
956
|
const binding3 = parseMlsDevInteractionBinding({ role: "request", requestId: input.requestId, kind, responderIds: input.responderIds, expiresAtMs: input.expiresAtMs });
|
|
1132
|
-
if (binding3.role !== "request")
|
|
1133
|
-
if (kind !== "approval" && ["risk", "allowSession", "scopeKey"].some(has))
|
|
1134
|
-
if (kind !== "question" && (has("options") || has("multiple")))
|
|
1135
|
-
if (has("multiple") && !options)
|
|
1136
|
-
if (kind === "secret" !== has("secretKey"))
|
|
957
|
+
if (binding3.role !== "request") invalid6();
|
|
958
|
+
if (kind !== "approval" && ["risk", "allowSession", "scopeKey"].some(has)) invalid6();
|
|
959
|
+
if (kind !== "question" && (has("options") || has("multiple"))) invalid6();
|
|
960
|
+
if (has("multiple") && !options) invalid6();
|
|
961
|
+
if (kind === "secret" !== has("secretKey")) invalid6();
|
|
1137
962
|
const allowSession = has("allowSession") ? boolean2(input.allowSession) : void 0;
|
|
1138
|
-
if (has("scopeKey") && (typeof input.scopeKey !== "string" || !/^[A-Za-z0-9_:-]{1,64}$/.test(input.scopeKey)))
|
|
1139
|
-
if (allowSession === true && !has("scopeKey"))
|
|
1140
|
-
if (has("risk") && input.risk !== "normal" && input.risk !== "destructive")
|
|
963
|
+
if (has("scopeKey") && (typeof input.scopeKey !== "string" || !/^[A-Za-z0-9_:-]{1,64}$/.test(input.scopeKey))) invalid6();
|
|
964
|
+
if (allowSession === true && !has("scopeKey")) invalid6();
|
|
965
|
+
if (has("risk") && input.risk !== "normal" && input.risk !== "destructive") invalid6();
|
|
1141
966
|
const secretKey = has("secretKey") ? (() => {
|
|
1142
967
|
const key = readMlsDataRecord(input.secretKey, ["kem", "publicKey"]);
|
|
1143
968
|
return Object.freeze({ kem: requireMlsLiteral(key.kem, "x25519"), publicKey: encoded3(key.publicKey, 32) });
|
|
@@ -1160,20 +985,20 @@ function parseMlsDevInteractionRequestBody(value) {
|
|
|
1160
985
|
}
|
|
1161
986
|
__name(parseMlsDevInteractionRequestBody, "parseMlsDevInteractionRequestBody");
|
|
1162
987
|
function parseMlsDevInteractionAnswer(value) {
|
|
1163
|
-
return
|
|
1164
|
-
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
988
|
+
return boundary5(() => {
|
|
989
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) invalid6();
|
|
1165
990
|
const keys2 = Reflect.ownKeys(value);
|
|
1166
991
|
if (keys2.includes("decision")) {
|
|
1167
992
|
const input = readMlsDataRecord(value, ["decision", "scope"]);
|
|
1168
|
-
if (input.decision !== "allow" && input.decision !== "deny" || input.scope !== "once" && input.scope !== "session")
|
|
993
|
+
if (input.decision !== "allow" && input.decision !== "deny" || input.scope !== "once" && input.scope !== "session") invalid6();
|
|
1169
994
|
return Object.freeze({ decision: input.decision, scope: input.scope });
|
|
1170
995
|
}
|
|
1171
996
|
if (keys2.includes("choices")) {
|
|
1172
997
|
const choices = array2(readMlsDataRecord(value, ["choices"]).choices, 1, MLS_DEV_INTERACTION_LIMITS.options).map((choice) => {
|
|
1173
|
-
if (typeof choice !== "string" || !/^[A-Za-z0-9_.:-]{1,64}$/.test(choice))
|
|
998
|
+
if (typeof choice !== "string" || !/^[A-Za-z0-9_.:-]{1,64}$/.test(choice)) invalid6();
|
|
1174
999
|
return choice;
|
|
1175
1000
|
});
|
|
1176
|
-
if (new Set(choices).size !== choices.length)
|
|
1001
|
+
if (new Set(choices).size !== choices.length) invalid6();
|
|
1177
1002
|
return Object.freeze({ choices: Object.freeze(choices) });
|
|
1178
1003
|
}
|
|
1179
1004
|
if (keys2.includes("text")) return Object.freeze({ text: text(readMlsDataRecord(value, ["text"]).text, MLS_DEV_INTERACTION_LIMITS.text) });
|
|
@@ -1181,31 +1006,31 @@ function parseMlsDevInteractionAnswer(value) {
|
|
|
1181
1006
|
const sealed = readMlsDataRecord(readMlsDataRecord(value, ["sealed"]).sealed, ["enc", "ciphertext"]);
|
|
1182
1007
|
return Object.freeze({ sealed: Object.freeze({ enc: encoded3(sealed.enc, 32), ciphertext: wire(sealed.ciphertext, 17, MLS_DEV_SECRET_ANSWER_MAX_BYTES) }) });
|
|
1183
1008
|
}
|
|
1184
|
-
if (readMlsDataRecord(value, ["cancelled"]).cancelled !== true)
|
|
1009
|
+
if (readMlsDataRecord(value, ["cancelled"]).cancelled !== true) invalid6();
|
|
1185
1010
|
return Object.freeze({ cancelled: true });
|
|
1186
1011
|
});
|
|
1187
1012
|
}
|
|
1188
1013
|
__name(parseMlsDevInteractionAnswer, "parseMlsDevInteractionAnswer");
|
|
1189
1014
|
function parseMlsDevInteractionResponseBody(value) {
|
|
1190
|
-
return
|
|
1015
|
+
return boundary5(() => {
|
|
1191
1016
|
const input = readMlsDataRecord(value, ["requestId", "agentId", "answer"]);
|
|
1192
1017
|
return Object.freeze({ requestId: interactionId(input.requestId), agentId: id3(input.agentId), answer: parseMlsDevInteractionAnswer(input.answer) });
|
|
1193
1018
|
});
|
|
1194
1019
|
}
|
|
1195
1020
|
__name(parseMlsDevInteractionResponseBody, "parseMlsDevInteractionResponseBody");
|
|
1196
1021
|
function parseMlsDevInteractionWithdrawBody(value) {
|
|
1197
|
-
return
|
|
1022
|
+
return boundary5(() => {
|
|
1198
1023
|
const input = readMlsDataRecord(value, ["requestId", "reason"]);
|
|
1199
|
-
if (!MLS_DEV_INTERACTION_WITHDRAW_REASONS.includes(input.reason))
|
|
1024
|
+
if (!MLS_DEV_INTERACTION_WITHDRAW_REASONS.includes(input.reason)) invalid6();
|
|
1200
1025
|
return Object.freeze({ requestId: interactionId(input.requestId), reason: input.reason });
|
|
1201
1026
|
});
|
|
1202
1027
|
}
|
|
1203
1028
|
__name(parseMlsDevInteractionWithdrawBody, "parseMlsDevInteractionWithdrawBody");
|
|
1204
1029
|
var payloadFields = ["version", "kind", "conversationId", "groupId", "messageId", "operationId", "senderDeviceId"];
|
|
1205
1030
|
function parseMlsDevApplicationPayload(value) {
|
|
1206
|
-
return
|
|
1031
|
+
return boundary5(() => {
|
|
1207
1032
|
const kind = value && typeof value === "object" ? Object.getOwnPropertyDescriptor(value, "kind") : void 0;
|
|
1208
|
-
if (!kind || !Object.hasOwn(kind, "value"))
|
|
1033
|
+
if (!kind || !Object.hasOwn(kind, "value")) invalid6();
|
|
1209
1034
|
if (kind.value === "text") return parseMlsDevTextPayload(value);
|
|
1210
1035
|
if (kind.value === "item") return parseMlsDevItemPayload(value);
|
|
1211
1036
|
const input = readMlsDataRecord(value, [...payloadFields, "interaction"]);
|
|
@@ -1218,26 +1043,26 @@ function parseMlsDevApplicationPayload(value) {
|
|
|
1218
1043
|
operationId: id3(input.operationId),
|
|
1219
1044
|
senderDeviceId: requireMlsUuid(input.senderDeviceId)
|
|
1220
1045
|
};
|
|
1221
|
-
if (ids.messageId.startsWith("membership-"))
|
|
1222
|
-
const interaction = kind.value === "interaction.request" ? parseMlsDevInteractionRequestBody(input.interaction) : kind.value === "interaction.response" ? parseMlsDevInteractionResponseBody(input.interaction) : kind.value === "interaction.withdraw" ? parseMlsDevInteractionWithdrawBody(input.interaction) :
|
|
1046
|
+
if (ids.messageId.startsWith("membership-")) invalid6();
|
|
1047
|
+
const interaction = kind.value === "interaction.request" ? parseMlsDevInteractionRequestBody(input.interaction) : kind.value === "interaction.response" ? parseMlsDevInteractionResponseBody(input.interaction) : kind.value === "interaction.withdraw" ? parseMlsDevInteractionWithdrawBody(input.interaction) : invalid6();
|
|
1223
1048
|
const payload = Object.freeze({ ...ids, interaction });
|
|
1224
|
-
if (utf83.encode(JSON.stringify(payload)).length > MLS_DEV_TEXT_MAX_BYTES)
|
|
1049
|
+
if (utf83.encode(JSON.stringify(payload)).length > MLS_DEV_TEXT_MAX_BYTES) invalid6();
|
|
1225
1050
|
return payload;
|
|
1226
1051
|
});
|
|
1227
1052
|
}
|
|
1228
1053
|
__name(parseMlsDevApplicationPayload, "parseMlsDevApplicationPayload");
|
|
1229
1054
|
function assertMlsDevInteractionPayloadBinding(payload, binding3) {
|
|
1230
|
-
|
|
1055
|
+
boundary5(() => {
|
|
1231
1056
|
if (payload.kind === "text" || payload.kind === "item") {
|
|
1232
|
-
if (binding3 !== void 0)
|
|
1057
|
+
if (binding3 !== void 0) invalid6();
|
|
1233
1058
|
return;
|
|
1234
1059
|
}
|
|
1235
|
-
if (!binding3 || payload.interaction.requestId !== binding3.requestId)
|
|
1060
|
+
if (!binding3 || payload.interaction.requestId !== binding3.requestId) invalid6();
|
|
1236
1061
|
if (payload.kind === "interaction.request") {
|
|
1237
|
-
if (binding3.role !== "request" || payload.interaction.kind !== binding3.kind || payload.interaction.expiresAtMs !== binding3.expiresAtMs || payload.interaction.responderIds.length !== 1 || payload.interaction.responderIds[0] !== binding3.responderIds[0])
|
|
1062
|
+
if (binding3.role !== "request" || payload.interaction.kind !== binding3.kind || payload.interaction.expiresAtMs !== binding3.expiresAtMs || payload.interaction.responderIds.length !== 1 || payload.interaction.responderIds[0] !== binding3.responderIds[0]) invalid6();
|
|
1238
1063
|
} else if (payload.kind === "interaction.response") {
|
|
1239
|
-
if (binding3.role !== "response" || payload.interaction.agentId !== binding3.agentId)
|
|
1240
|
-
} else if (binding3.role !== "withdraw")
|
|
1064
|
+
if (binding3.role !== "response" || payload.interaction.agentId !== binding3.agentId) invalid6();
|
|
1065
|
+
} else if (binding3.role !== "withdraw") invalid6();
|
|
1241
1066
|
});
|
|
1242
1067
|
}
|
|
1243
1068
|
__name(assertMlsDevInteractionPayloadBinding, "assertMlsDevInteractionPayloadBinding");
|
|
@@ -1271,27 +1096,27 @@ var MlsDevGroupValidationError = class extends Error {
|
|
|
1271
1096
|
}
|
|
1272
1097
|
};
|
|
1273
1098
|
var utf84 = new TextEncoder();
|
|
1274
|
-
function
|
|
1099
|
+
function invalid7() {
|
|
1275
1100
|
throw new MlsDevGroupValidationError();
|
|
1276
1101
|
}
|
|
1277
|
-
__name(
|
|
1278
|
-
function
|
|
1102
|
+
__name(invalid7, "invalid");
|
|
1103
|
+
function boundary6(read) {
|
|
1279
1104
|
try {
|
|
1280
1105
|
return read();
|
|
1281
1106
|
} catch {
|
|
1282
|
-
return
|
|
1107
|
+
return invalid7();
|
|
1283
1108
|
}
|
|
1284
1109
|
}
|
|
1285
|
-
__name(
|
|
1110
|
+
__name(boundary6, "boundary");
|
|
1286
1111
|
function bounded5(value, maximum = MLS_DEV_GROUP_CONTROL_MAX_BYTES) {
|
|
1287
1112
|
if (utf84.encode(JSON.stringify(value)).length > maximum)
|
|
1288
|
-
|
|
1113
|
+
invalid7();
|
|
1289
1114
|
return Object.freeze(value);
|
|
1290
1115
|
}
|
|
1291
1116
|
__name(bounded5, "bounded");
|
|
1292
1117
|
function id4(value) {
|
|
1293
1118
|
if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..")
|
|
1294
|
-
|
|
1119
|
+
invalid7();
|
|
1295
1120
|
return value;
|
|
1296
1121
|
}
|
|
1297
1122
|
__name(id4, "id");
|
|
@@ -1302,13 +1127,13 @@ function encoded4(value, bytes) {
|
|
|
1302
1127
|
__name(encoded4, "encoded");
|
|
1303
1128
|
function boolean3(value) {
|
|
1304
1129
|
if (typeof value !== "boolean")
|
|
1305
|
-
|
|
1130
|
+
invalid7();
|
|
1306
1131
|
return value;
|
|
1307
1132
|
}
|
|
1308
1133
|
__name(boolean3, "boolean");
|
|
1309
1134
|
function textProtocol(value) {
|
|
1310
1135
|
if (!isMlsDevTextProtocol(value))
|
|
1311
|
-
|
|
1136
|
+
invalid7();
|
|
1312
1137
|
return value;
|
|
1313
1138
|
}
|
|
1314
1139
|
__name(textProtocol, "textProtocol");
|
|
@@ -1319,19 +1144,19 @@ function token(value) {
|
|
|
1319
1144
|
__name(token, "token");
|
|
1320
1145
|
function wire2(value) {
|
|
1321
1146
|
if (typeof value !== "string" || value.length < 2 || value.length > Math.ceil(MLS_DEV_GROUP_TLS_MAX_BYTES * 4 / 3))
|
|
1322
|
-
|
|
1147
|
+
invalid7();
|
|
1323
1148
|
const bytes = Math.floor(value.length * 3 / 4);
|
|
1324
1149
|
if (value.length !== Math.ceil(bytes * 4 / 3) || !/^[A-Za-z0-9_-]+$/.test(value))
|
|
1325
|
-
|
|
1150
|
+
invalid7();
|
|
1326
1151
|
const last = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(value.at(-1));
|
|
1327
1152
|
if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0)
|
|
1328
|
-
|
|
1153
|
+
invalid7();
|
|
1329
1154
|
return value;
|
|
1330
1155
|
}
|
|
1331
1156
|
__name(wire2, "wire");
|
|
1332
1157
|
function plaintextJson(value) {
|
|
1333
1158
|
if (typeof value !== "string" || !value || utf84.encode(value).length > MLS_DEV_TEXT_MAX_BYTES || new TextDecoder("utf-8", { fatal: true }).decode(utf84.encode(value)) !== value)
|
|
1334
|
-
|
|
1159
|
+
invalid7();
|
|
1335
1160
|
return value;
|
|
1336
1161
|
}
|
|
1337
1162
|
__name(plaintextJson, "plaintextJson");
|
|
@@ -1342,92 +1167,100 @@ __name(present, "present");
|
|
|
1342
1167
|
var pick = /* @__PURE__ */ __name((value, keys2) => Object.fromEntries(keys2.map((key) => [key, value[key]])), "pick");
|
|
1343
1168
|
var textExtras = /* @__PURE__ */ __name((text5) => ({ ...text5.replyTo ? { replyTo: text5.replyTo } : {}, ...text5.mentions ? { mentions: text5.mentions } : {} }), "textExtras");
|
|
1344
1169
|
function sealedCiphertext(value) {
|
|
1345
|
-
if (typeof value !== "string" || !/^[A-Za-z0-9_-]+$/.test(value) || value.length % 4 === 1)
|
|
1170
|
+
if (typeof value !== "string" || !/^[A-Za-z0-9_-]+$/.test(value) || value.length % 4 === 1) invalid7();
|
|
1346
1171
|
const bytes = Math.floor(value.length * 3 / 4);
|
|
1347
|
-
if (bytes < 17 || bytes > MLS_DEV_SECRET_ANSWER_MAX_BYTES)
|
|
1172
|
+
if (bytes < 17 || bytes > MLS_DEV_SECRET_ANSWER_MAX_BYTES) invalid7();
|
|
1348
1173
|
const last = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(value.at(-1));
|
|
1349
|
-
if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0)
|
|
1174
|
+
if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0) invalid7();
|
|
1350
1175
|
return value;
|
|
1351
1176
|
}
|
|
1352
1177
|
__name(sealedCiphertext, "sealedCiphertext");
|
|
1353
1178
|
function array3(value, maximum) {
|
|
1354
1179
|
if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || value.length > maximum)
|
|
1355
|
-
|
|
1180
|
+
invalid7();
|
|
1356
1181
|
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
1357
1182
|
if (Reflect.ownKeys(descriptors).length !== value.length + 1)
|
|
1358
|
-
|
|
1183
|
+
invalid7();
|
|
1359
1184
|
return Array.from({ length: value.length }, (_, index) => {
|
|
1360
1185
|
const descriptor = descriptors[index];
|
|
1361
1186
|
if (!descriptor || !descriptor.enumerable || !Object.hasOwn(descriptor, "value"))
|
|
1362
|
-
|
|
1187
|
+
invalid7();
|
|
1363
1188
|
return descriptor.value;
|
|
1364
1189
|
});
|
|
1365
1190
|
}
|
|
1366
1191
|
__name(array3, "array");
|
|
1367
1192
|
function parseMlsDevGroupCreateConversation(value) {
|
|
1368
|
-
return
|
|
1193
|
+
return boundary6(() => {
|
|
1369
1194
|
const input = readMlsDataRecord(value, ["name", "memberIds", "mlsDev"]), config = readMlsDataRecord(input.mlsDev, ["version", "conversationId", "credential"], ["version", "conversationId", "credential", "protocol"]);
|
|
1370
1195
|
if (typeof input.name !== "string" || input.name.trim().length > 100)
|
|
1371
|
-
|
|
1196
|
+
invalid7();
|
|
1372
1197
|
const memberIds = array3(input.memberIds, 31).map((value2) => parseMlsDevEnrollmentPrincipal({ type: "human", id: value2 }).id);
|
|
1373
1198
|
if (!memberIds.length || new Set(memberIds).size !== memberIds.length || memberIds.some((value2) => value2.includes("/") || value2 === "." || value2 === ".."))
|
|
1374
|
-
|
|
1199
|
+
invalid7();
|
|
1375
1200
|
return bounded5({ name: input.name, memberIds: Object.freeze(memberIds), mlsDev: Object.freeze({ version: requireMlsLiteral(config.version, 1), conversationId: id4(config.conversationId), credential: token(config.credential), ...Object.hasOwn(config, "protocol") ? { protocol: textProtocol(config.protocol) } : {} }) }, 16 * 1024);
|
|
1376
1201
|
});
|
|
1377
1202
|
}
|
|
1378
1203
|
__name(parseMlsDevGroupCreateConversation, "parseMlsDevGroupCreateConversation");
|
|
1379
1204
|
function parseMlsDevGroupHead(value) {
|
|
1380
|
-
return
|
|
1205
|
+
return boundary6(() => {
|
|
1381
1206
|
const input = readMlsDataRecord(value, ["sequence", "epoch", "hash"]);
|
|
1382
1207
|
return Object.freeze({ sequence: requireMlsInteger(input.sequence, 1), epoch: requireMlsInteger(input.epoch), hash: encoded4(input.hash, 32) });
|
|
1383
1208
|
});
|
|
1384
1209
|
}
|
|
1385
1210
|
__name(parseMlsDevGroupHead, "parseMlsDevGroupHead");
|
|
1386
1211
|
function parseMlsDevGroupMarker(value) {
|
|
1387
|
-
return
|
|
1212
|
+
return boundary6(() => {
|
|
1388
1213
|
const input = readMlsDataRecord(value, ["version", "groupId", "head"]);
|
|
1389
1214
|
return Object.freeze({ version: requireMlsLiteral(input.version, 1), groupId: encoded4(input.groupId, 32), head: parseMlsDevGroupHead(input.head) });
|
|
1390
1215
|
});
|
|
1391
1216
|
}
|
|
1392
1217
|
__name(parseMlsDevGroupMarker, "parseMlsDevGroupMarker");
|
|
1393
1218
|
function parseMlsDevGroupRoster(value) {
|
|
1394
|
-
return
|
|
1219
|
+
return boundary6(() => {
|
|
1395
1220
|
const values = array3(value, MLS_DEV_GROUP_ROSTER_MAX).map((item2) => {
|
|
1396
1221
|
const entry = readMlsDataRecord(item2, ["device", "admissionId"]);
|
|
1397
1222
|
return Object.freeze({ device: parseMlsDevEnrollmentResult({ version: 1, authorization: "registration_only", device: entry.device }).device, admissionId: id4(entry.admissionId) });
|
|
1398
1223
|
});
|
|
1399
1224
|
for (let i = 1; i < values.length; i++)
|
|
1400
1225
|
if (values[i - 1].device.deviceId >= values[i].device.deviceId)
|
|
1401
|
-
|
|
1226
|
+
invalid7();
|
|
1402
1227
|
return Object.freeze(values);
|
|
1403
1228
|
});
|
|
1404
1229
|
}
|
|
1405
1230
|
__name(parseMlsDevGroupRoster, "parseMlsDevGroupRoster");
|
|
1231
|
+
var MLS_MEMBER_JOIN_WAIT_MS = 6e4;
|
|
1232
|
+
function mlsAdmissionWait(input) {
|
|
1233
|
+
const { senderId, memberIds, admitted } = input;
|
|
1234
|
+
const expected = [.../* @__PURE__ */ new Set([...memberIds, ...input.unacceptedIds])];
|
|
1235
|
+
if (!expected.some((id7) => id7 !== senderId && admitted.has(id7))) return expected.filter((id7) => !admitted.has(id7));
|
|
1236
|
+
return input.nowMs < input.joinedAtMs + MLS_MEMBER_JOIN_WAIT_MS ? memberIds.filter((id7) => !admitted.has(id7)) : [];
|
|
1237
|
+
}
|
|
1238
|
+
__name(mlsAdmissionWait, "mlsAdmissionWait");
|
|
1406
1239
|
var MLS_DEV_ROOM_REMOVAL_DEADLINE_MS = 72 * 60 * 60 * 1e3;
|
|
1407
1240
|
function parseMlsDevRoomRemoval(value) {
|
|
1408
|
-
return
|
|
1241
|
+
return boundary6(() => {
|
|
1409
1242
|
const input = readMlsDataRecord(value, ["version", "status", "pending", "closedAtMs"]), devices = /* @__PURE__ */ new Set(), principals = /* @__PURE__ */ new Set();
|
|
1410
|
-
const status = ["pending", "closing", "closed"].includes(input.status) ? input.status :
|
|
1243
|
+
const status = ["pending", "closing", "closed"].includes(input.status) ? input.status : invalid7();
|
|
1411
1244
|
const pending = array3(input.pending, MLS_DEV_GROUP_ROSTER_MAX).map((item2) => {
|
|
1412
1245
|
const entry = readMlsDataRecord(item2, ["principalId", "deviceIds", "deadlineAtMs"]);
|
|
1413
1246
|
const principalId2 = parseMlsDevEnrollmentPrincipal({ type: "human", id: entry.principalId }).id;
|
|
1414
1247
|
const deviceIds = array3(entry.deviceIds, MLS_DEV_GROUP_ROSTER_MAX).map(requireMlsUuid);
|
|
1415
|
-
if (principals.has(principalId2))
|
|
1248
|
+
if (principals.has(principalId2)) invalid7();
|
|
1416
1249
|
principals.add(principalId2);
|
|
1417
1250
|
for (const deviceId of deviceIds) {
|
|
1418
|
-
if (devices.has(deviceId))
|
|
1251
|
+
if (devices.has(deviceId)) invalid7();
|
|
1419
1252
|
devices.add(deviceId);
|
|
1420
1253
|
}
|
|
1421
1254
|
return Object.freeze({ principalId: principalId2, deviceIds: Object.freeze(deviceIds), deadlineAtMs: requireMlsInteger(entry.deadlineAtMs, 1) });
|
|
1422
1255
|
});
|
|
1423
1256
|
const closedAtMs = input.closedAtMs === null ? null : requireMlsInteger(input.closedAtMs, 1);
|
|
1424
|
-
if (status === "pending" ? !pending.length || closedAtMs !== null : closedAtMs === null || status === "closed" && pending.length)
|
|
1257
|
+
if (status === "pending" ? !pending.length || closedAtMs !== null : closedAtMs === null || status === "closed" && pending.length) invalid7();
|
|
1425
1258
|
return Object.freeze({ version: requireMlsLiteral(input.version, 1), status, pending: Object.freeze(pending), closedAtMs });
|
|
1426
1259
|
});
|
|
1427
1260
|
}
|
|
1428
1261
|
__name(parseMlsDevRoomRemoval, "parseMlsDevRoomRemoval");
|
|
1429
1262
|
function parseMlsDevGroupPreconditions(value) {
|
|
1430
|
-
return
|
|
1263
|
+
return boundary6(() => {
|
|
1431
1264
|
const input = readMlsDataRecord(value, ["membershipRevision", "admissionId", "targetAdmissionId"]);
|
|
1432
1265
|
return Object.freeze({
|
|
1433
1266
|
membershipRevision: requireMlsInteger(input.membershipRevision),
|
|
@@ -1456,33 +1289,33 @@ var unsignedFields = [
|
|
|
1456
1289
|
];
|
|
1457
1290
|
function unsigned(input) {
|
|
1458
1291
|
if (typeof input.kind !== "string" || !["create", "add", "remove"].includes(input.kind))
|
|
1459
|
-
|
|
1292
|
+
invalid7();
|
|
1460
1293
|
const kind = input.kind;
|
|
1461
1294
|
const senderCredential = token(input.senderCredential), sender = parseMlsDevCredentialToken(senderCredential).unsigned.claims.device;
|
|
1462
1295
|
const expectedHead = input.expectedHead === null ? null : parseMlsDevGroupHead(input.expectedHead);
|
|
1463
1296
|
const epoch = requireMlsInteger(input.epoch), preconditions = parseMlsDevGroupPreconditions(input.preconditions), roster = parseMlsDevGroupRoster(input.roster);
|
|
1464
1297
|
const environmentId = requireMlsEnvironmentId(input.environmentId);
|
|
1465
1298
|
if (sender.environmentId !== environmentId || roster.some((entry) => entry.device.environmentId !== environmentId))
|
|
1466
|
-
|
|
1299
|
+
invalid7();
|
|
1467
1300
|
const groupInfo = input.groupInfo === null ? null : wire2(input.groupInfo), commit = input.commit === null ? null : wire2(input.commit);
|
|
1468
1301
|
const welcome = input.welcome === null ? null : wire2(input.welcome);
|
|
1469
1302
|
const keyPackageClaim = input.keyPackageClaim === null ? null : parseMlsDevKeyPackageClaimReceipt(input.keyPackageClaim);
|
|
1470
1303
|
const removedDeviceId = input.removedDeviceId === null ? null : requireMlsUuid(input.removedDeviceId);
|
|
1471
1304
|
const own = roster.find((entry) => entry.device.deviceId === sender.deviceId);
|
|
1472
1305
|
if (!own || JSON.stringify(own.device) !== JSON.stringify(sender) || own.admissionId !== preconditions.admissionId)
|
|
1473
|
-
|
|
1306
|
+
invalid7();
|
|
1474
1307
|
if (kind === "create") {
|
|
1475
1308
|
if (expectedHead !== null || epoch !== 0 || roster.length !== 1 || !groupInfo || commit !== null || welcome !== null || keyPackageClaim !== null || removedDeviceId !== null || preconditions.targetAdmissionId !== null)
|
|
1476
|
-
|
|
1309
|
+
invalid7();
|
|
1477
1310
|
} else {
|
|
1478
1311
|
if (!expectedHead || expectedHead.sequence >= Number.MAX_SAFE_INTEGER || expectedHead.epoch >= Number.MAX_SAFE_INTEGER || epoch !== expectedHead.epoch + 1 || !commit || preconditions.targetAdmissionId === null)
|
|
1479
|
-
|
|
1312
|
+
invalid7();
|
|
1480
1313
|
if (kind === "add") {
|
|
1481
1314
|
const target = roster.find((entry) => entry.device.deviceId === keyPackageClaim?.recipientDeviceId);
|
|
1482
1315
|
if (!welcome || !keyPackageClaim || removedDeviceId !== null || !target || keyPackageClaim.claimantDeviceId !== sender.deviceId || keyPackageClaim.preconditions.conversationId !== input.conversationId || keyPackageClaim.preconditions.membershipRevision !== preconditions.membershipRevision || keyPackageClaim.preconditions.admissionId !== preconditions.admissionId || keyPackageClaim.preconditions.targetAdmissionId !== preconditions.targetAdmissionId || target.admissionId !== preconditions.targetAdmissionId)
|
|
1483
|
-
|
|
1316
|
+
invalid7();
|
|
1484
1317
|
} else if (!removedDeviceId || removedDeviceId === sender.deviceId || roster.some((entry) => entry.device.deviceId === removedDeviceId) || welcome !== null || keyPackageClaim !== null)
|
|
1485
|
-
|
|
1318
|
+
invalid7();
|
|
1486
1319
|
}
|
|
1487
1320
|
return bounded5({
|
|
1488
1321
|
version: requireMlsLiteral(input.version, 1),
|
|
@@ -1504,21 +1337,21 @@ function unsigned(input) {
|
|
|
1504
1337
|
}
|
|
1505
1338
|
__name(unsigned, "unsigned");
|
|
1506
1339
|
function parseMlsDevGroupControl(value) {
|
|
1507
|
-
return
|
|
1340
|
+
return boundary6(() => {
|
|
1508
1341
|
const input = readMlsDataRecord(value, [...unsignedFields, "proof"]);
|
|
1509
1342
|
return bounded5({ ...unsigned(input), proof: encoded4(input.proof, 64) });
|
|
1510
1343
|
});
|
|
1511
1344
|
}
|
|
1512
1345
|
__name(parseMlsDevGroupControl, "parseMlsDevGroupControl");
|
|
1513
1346
|
function parseMlsDevGroupAcceptedControl(value) {
|
|
1514
|
-
return
|
|
1347
|
+
return boundary6(() => {
|
|
1515
1348
|
const input = readMlsDataRecord(value, ["version", "authorization", "operationId", "control", "head", "acceptedAtMs", "membershipRevision"]);
|
|
1516
1349
|
const control = parseMlsDevGroupControl(input.control), head = parseMlsDevGroupHead(input.head);
|
|
1517
1350
|
if (head.sequence !== (control.expectedHead?.sequence ?? 0) + 1 || head.epoch !== control.epoch)
|
|
1518
|
-
|
|
1351
|
+
invalid7();
|
|
1519
1352
|
const membershipRevision = requireMlsInteger(input.membershipRevision);
|
|
1520
1353
|
if (membershipRevision !== control.preconditions.membershipRevision && !(control.kind === "remove" && membershipRevision === control.preconditions.membershipRevision + 1))
|
|
1521
|
-
|
|
1354
|
+
invalid7();
|
|
1522
1355
|
return bounded5({
|
|
1523
1356
|
version: requireMlsLiteral(input.version, 1),
|
|
1524
1357
|
authorization: requireMlsLiteral(input.authorization, "group_control_only"),
|
|
@@ -1532,20 +1365,20 @@ function parseMlsDevGroupAcceptedControl(value) {
|
|
|
1532
1365
|
}
|
|
1533
1366
|
__name(parseMlsDevGroupAcceptedControl, "parseMlsDevGroupAcceptedControl");
|
|
1534
1367
|
function parseMlsDevGroupAdmissionsResult(value) {
|
|
1535
|
-
return
|
|
1368
|
+
return boundary6(() => {
|
|
1536
1369
|
const input = readMlsDataRecord(value, ["version", "conversationId", "membershipRevision", "candidates", "waitingPrincipalIds"]);
|
|
1537
1370
|
const candidates = array3(input.candidates, MLS_DEV_GROUP_ADMISSION_MAX_CANDIDATES).map((raw) => {
|
|
1538
1371
|
const entry = readMlsDataRecord(raw, ["principal", "deviceId", "targetAdmissionId"]), principal2 = readMlsDataRecord(entry.principal, ["type", "id"]);
|
|
1539
|
-
if (principal2.type !== "human" && principal2.type !== "ai_agent")
|
|
1372
|
+
if (principal2.type !== "human" && principal2.type !== "ai_agent") invalid7();
|
|
1540
1373
|
return Object.freeze({
|
|
1541
1374
|
principal: Object.freeze({ type: principal2.type, id: id4(principal2.id) }),
|
|
1542
1375
|
deviceId: requireMlsUuid(entry.deviceId),
|
|
1543
1376
|
targetAdmissionId: id4(entry.targetAdmissionId)
|
|
1544
1377
|
});
|
|
1545
1378
|
});
|
|
1546
|
-
if (new Set(candidates.map((entry) => entry.deviceId)).size !== candidates.length)
|
|
1379
|
+
if (new Set(candidates.map((entry) => entry.deviceId)).size !== candidates.length) invalid7();
|
|
1547
1380
|
const waiting = array3(input.waitingPrincipalIds, 32).map(id4);
|
|
1548
|
-
if (new Set(waiting).size !== waiting.length)
|
|
1381
|
+
if (new Set(waiting).size !== waiting.length) invalid7();
|
|
1549
1382
|
return bounded5(Object.freeze({
|
|
1550
1383
|
version: requireMlsLiteral(input.version, 1),
|
|
1551
1384
|
conversationId: id4(input.conversationId),
|
|
@@ -1557,11 +1390,11 @@ function parseMlsDevGroupAdmissionsResult(value) {
|
|
|
1557
1390
|
}
|
|
1558
1391
|
__name(parseMlsDevGroupAdmissionsResult, "parseMlsDevGroupAdmissionsResult");
|
|
1559
1392
|
function parseMlsDevGroupQuery(value) {
|
|
1560
|
-
return
|
|
1393
|
+
return boundary6(() => {
|
|
1561
1394
|
const input = readMlsDataRecord(value, ["version", "conversationId", "credential", "afterSequence", "limit"]);
|
|
1562
1395
|
const limit2 = requireMlsInteger(input.limit, 1);
|
|
1563
1396
|
if (limit2 > MLS_DEV_GROUP_QUERY_MAX_CONTROLS)
|
|
1564
|
-
|
|
1397
|
+
invalid7();
|
|
1565
1398
|
return bounded5({
|
|
1566
1399
|
version: requireMlsLiteral(input.version, 1),
|
|
1567
1400
|
conversationId: id4(input.conversationId),
|
|
@@ -1573,17 +1406,17 @@ function parseMlsDevGroupQuery(value) {
|
|
|
1573
1406
|
}
|
|
1574
1407
|
__name(parseMlsDevGroupQuery, "parseMlsDevGroupQuery");
|
|
1575
1408
|
function parseMlsDevGroupQueryResult(value) {
|
|
1576
|
-
return
|
|
1409
|
+
return boundary6(() => {
|
|
1577
1410
|
const input = readMlsDataRecord(value, ["version", "conversationId", "marker", "membershipRevision", "admissionId", "roster", "controls", "nextSequence", "hasMore", "terminal"]);
|
|
1578
1411
|
const conversationId = id4(input.conversationId), marker = input.marker === null ? null : parseMlsDevGroupMarker(input.marker);
|
|
1579
1412
|
const controls = array3(input.controls, MLS_DEV_GROUP_QUERY_MAX_CONTROLS).map(parseMlsDevGroupAcceptedControl);
|
|
1580
1413
|
const nextSequence = requireMlsInteger(input.nextSequence), terminal = boolean3(input.terminal), hasMore = boolean3(input.hasMore);
|
|
1581
1414
|
for (let i = 0; i < controls.length; i++) {
|
|
1582
1415
|
if (!marker || controls[i].control.conversationId !== conversationId || controls[i].control.groupId !== marker.groupId || controls[i].head.sequence > marker.head.sequence || i > 0 && controls[i].head.sequence !== controls[i - 1].head.sequence + 1)
|
|
1583
|
-
|
|
1416
|
+
invalid7();
|
|
1584
1417
|
}
|
|
1585
1418
|
if (controls.length && controls.at(-1).head.sequence !== nextSequence || marker && nextSequence > marker.head.sequence || !marker && (controls.length || nextSequence || terminal || hasMore))
|
|
1586
|
-
|
|
1419
|
+
invalid7();
|
|
1587
1420
|
return bounded5({
|
|
1588
1421
|
version: requireMlsLiteral(input.version, 1),
|
|
1589
1422
|
conversationId,
|
|
@@ -1600,11 +1433,11 @@ function parseMlsDevGroupQueryResult(value) {
|
|
|
1600
1433
|
}
|
|
1601
1434
|
__name(parseMlsDevGroupQueryResult, "parseMlsDevGroupQueryResult");
|
|
1602
1435
|
function parseMlsDevGroupContext(value) {
|
|
1603
|
-
return
|
|
1436
|
+
return boundary6(() => {
|
|
1604
1437
|
const input = readMlsDataRecord(value, ["version", "environmentId", "conversationId", "groupId", "deviceId", "installationId", "revision"], ["version", "environmentId", "conversationId", "groupId", "deviceId", "installationId", "revision", "protocol"]);
|
|
1605
1438
|
const revision2 = requireMlsInteger(input.revision);
|
|
1606
1439
|
if (revision2 >= Number.MAX_SAFE_INTEGER)
|
|
1607
|
-
|
|
1440
|
+
invalid7();
|
|
1608
1441
|
return Object.freeze({
|
|
1609
1442
|
version: requireMlsLiteral(input.version, 1),
|
|
1610
1443
|
environmentId: requireMlsEnvironmentId(input.environmentId),
|
|
@@ -1619,17 +1452,17 @@ function parseMlsDevGroupContext(value) {
|
|
|
1619
1452
|
}
|
|
1620
1453
|
__name(parseMlsDevGroupContext, "parseMlsDevGroupContext");
|
|
1621
1454
|
function parseMlsDevGroupCommand(value) {
|
|
1622
|
-
return
|
|
1455
|
+
return boundary6(() => {
|
|
1623
1456
|
if (!value || typeof value !== "object")
|
|
1624
|
-
|
|
1457
|
+
invalid7();
|
|
1625
1458
|
const descriptor = Object.getOwnPropertyDescriptor(value, "op");
|
|
1626
1459
|
if (!descriptor || !Object.hasOwn(descriptor, "value"))
|
|
1627
|
-
|
|
1460
|
+
invalid7();
|
|
1628
1461
|
const op = descriptor.value;
|
|
1629
1462
|
if (op === "process_application") {
|
|
1630
1463
|
const input2 = readMlsDataRecord(value, ["op", "entry"]), entry = parseMlsDevGroupFeedEntry(input2.entry);
|
|
1631
1464
|
if (entry.kind !== "application" || !entry.receiptProof)
|
|
1632
|
-
|
|
1465
|
+
invalid7();
|
|
1633
1466
|
return bounded5({ op, entry });
|
|
1634
1467
|
}
|
|
1635
1468
|
if (op === "encrypt_text") {
|
|
@@ -1688,23 +1521,23 @@ function parseMlsDevGroupCommand(value) {
|
|
|
1688
1521
|
let seal = null;
|
|
1689
1522
|
if (interaction.role === "request") {
|
|
1690
1523
|
if (Object.hasOwn(body, "secretKey") || input2.seal !== null)
|
|
1691
|
-
|
|
1524
|
+
invalid7();
|
|
1692
1525
|
const parsed = parseMlsDevInteractionRequestBody(interaction.kind === "secret" ? { ...body, secretKey: { kem: "x25519", publicKey: "A".repeat(43) } } : body);
|
|
1693
1526
|
if (parsed.requestId !== interaction.requestId || parsed.kind !== interaction.kind || parsed.expiresAtMs !== interaction.expiresAtMs || parsed.responderIds[0] !== interaction.responderIds[0])
|
|
1694
|
-
|
|
1527
|
+
invalid7();
|
|
1695
1528
|
} else if (interaction.role === "response") {
|
|
1696
1529
|
if (input2.seal === null) {
|
|
1697
1530
|
const parsed = parseMlsDevInteractionResponseBody(body);
|
|
1698
1531
|
if (parsed.requestId !== interaction.requestId || parsed.agentId !== interaction.agentId || "sealed" in parsed.answer)
|
|
1699
|
-
|
|
1532
|
+
invalid7();
|
|
1700
1533
|
} else {
|
|
1701
1534
|
const fields3 = readMlsDataRecord(input2.seal, ["text", "publicKey", "requesterDeviceId"]), ids2 = readMlsDataRecord(body, ["requestId", "agentId"]);
|
|
1702
1535
|
if (ids2.requestId !== interaction.requestId || ids2.agentId !== interaction.agentId || typeof fields3.text !== "string" || !fields3.text.trim() || [...fields3.text].length > MLS_DEV_INTERACTION_LIMITS.text || utf84.encode(fields3.text).length > MLS_DEV_SECRET_ANSWER_MAX_BYTES - 16 || new TextDecoder("utf-8", { fatal: true }).decode(utf84.encode(fields3.text)) !== fields3.text)
|
|
1703
|
-
|
|
1536
|
+
invalid7();
|
|
1704
1537
|
seal = Object.freeze({ text: fields3.text, publicKey: encoded4(fields3.publicKey, 32), requesterDeviceId: requireMlsUuid(fields3.requesterDeviceId) });
|
|
1705
1538
|
}
|
|
1706
1539
|
} else if (input2.seal !== null || parseMlsDevInteractionWithdrawBody(body).requestId !== interaction.requestId)
|
|
1707
|
-
|
|
1540
|
+
invalid7();
|
|
1708
1541
|
const ids = parseMlsDevTextPayload({
|
|
1709
1542
|
version: 1,
|
|
1710
1543
|
kind: "text",
|
|
@@ -1716,7 +1549,7 @@ function parseMlsDevGroupCommand(value) {
|
|
|
1716
1549
|
text: "x"
|
|
1717
1550
|
});
|
|
1718
1551
|
if (utf84.encode(JSON.stringify(body)).length > MLS_DEV_TEXT_MAX_BYTES)
|
|
1719
|
-
|
|
1552
|
+
invalid7();
|
|
1720
1553
|
return bounded5({
|
|
1721
1554
|
op,
|
|
1722
1555
|
operationId: ids.operationId,
|
|
@@ -1758,7 +1591,7 @@ function parseMlsDevGroupCommand(value) {
|
|
|
1758
1591
|
};
|
|
1759
1592
|
if (op === "join") {
|
|
1760
1593
|
if (common2.accepted.control.kind !== "add")
|
|
1761
|
-
|
|
1594
|
+
invalid7();
|
|
1762
1595
|
return bounded5({ op, ...common2, keyPackageId: requireMlsUuid(input2.keyPackageId) });
|
|
1763
1596
|
}
|
|
1764
1597
|
return bounded5({ op, ...common2 });
|
|
@@ -1768,11 +1601,11 @@ function parseMlsDevGroupCommand(value) {
|
|
|
1768
1601
|
const fields2 = { operationId: id4(input.operationId), credential: token(input.credential), preconditions: parseMlsDevGroupPreconditions(input.preconditions) };
|
|
1769
1602
|
if (op === "create") {
|
|
1770
1603
|
if (fields2.preconditions.targetAdmissionId !== null)
|
|
1771
|
-
|
|
1604
|
+
invalid7();
|
|
1772
1605
|
return bounded5({ op, ...fields2 });
|
|
1773
1606
|
}
|
|
1774
1607
|
if (fields2.preconditions.targetAdmissionId === null)
|
|
1775
|
-
|
|
1608
|
+
invalid7();
|
|
1776
1609
|
const expectedHead = parseMlsDevGroupHead(input.expectedHead);
|
|
1777
1610
|
if (op === "add")
|
|
1778
1611
|
return bounded5({
|
|
@@ -1788,24 +1621,24 @@ function parseMlsDevGroupCommand(value) {
|
|
|
1788
1621
|
expectedHead,
|
|
1789
1622
|
removedDeviceId: requireMlsUuid(input.removedDeviceId)
|
|
1790
1623
|
});
|
|
1791
|
-
return
|
|
1624
|
+
return invalid7();
|
|
1792
1625
|
});
|
|
1793
1626
|
}
|
|
1794
1627
|
__name(parseMlsDevGroupCommand, "parseMlsDevGroupCommand");
|
|
1795
1628
|
function parseMlsDevGroupPreparation(value) {
|
|
1796
|
-
return
|
|
1629
|
+
return boundary6(() => {
|
|
1797
1630
|
const input = readMlsDataRecord(value, ["wrappedState", "payload"]);
|
|
1798
1631
|
if (typeof input.wrappedState !== "string" || input.wrappedState.length > MLS_DEV_GROUP_WRAPPED_MAX_BYTES || !input.wrappedState.startsWith("v1:"))
|
|
1799
|
-
|
|
1632
|
+
invalid7();
|
|
1800
1633
|
const body = input.wrappedState.slice(3);
|
|
1801
1634
|
if (body.length < 40 || body.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(body))
|
|
1802
|
-
|
|
1635
|
+
invalid7();
|
|
1803
1636
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1804
1637
|
if (body.endsWith("==") && (alphabet.indexOf(body.at(-3)) & 15) !== 0 || !body.endsWith("==") && body.endsWith("=") && (alphabet.indexOf(body.at(-2)) & 3) !== 0)
|
|
1805
|
-
|
|
1638
|
+
invalid7();
|
|
1806
1639
|
const kind = Object.getOwnPropertyDescriptor(input.payload ?? {}, "kind");
|
|
1807
1640
|
if (!kind || !Object.hasOwn(kind, "value"))
|
|
1808
|
-
|
|
1641
|
+
invalid7();
|
|
1809
1642
|
let payload;
|
|
1810
1643
|
if (kind.value === "application") {
|
|
1811
1644
|
const fields2 = readMlsDataRecord(input.payload, ["kind", "envelope", ...present(input.payload, ["payload"])]);
|
|
@@ -1861,7 +1694,7 @@ function parseMlsDevGroupPreparation(value) {
|
|
|
1861
1694
|
const fields2 = readMlsDataRecord(input.payload, ["kind", "envelope", "payload"]);
|
|
1862
1695
|
payload = Object.freeze({ kind: "interaction_application", envelope: parseMlsDevApplicationEnvelope(fields2.envelope), payload: plaintextJson(fields2.payload) });
|
|
1863
1696
|
if (!payload.envelope.interaction)
|
|
1864
|
-
|
|
1697
|
+
invalid7();
|
|
1865
1698
|
} else if (kind.value === "interaction") {
|
|
1866
1699
|
const fields2 = readMlsDataRecord(input.payload, ["kind", "messageId", "operationId", "senderDeviceId", "payload", "feedOrdinal"]);
|
|
1867
1700
|
const ids = parseMlsDevTextPayload({
|
|
@@ -1905,7 +1738,7 @@ function parseMlsDevGroupPreparation(value) {
|
|
|
1905
1738
|
const fields2 = readMlsDataRecord(input.payload, ["kind", "requestId", "text"]);
|
|
1906
1739
|
const binding3 = parseMlsDevInteractionBinding({ role: "withdraw", requestId: fields2.requestId });
|
|
1907
1740
|
if (typeof fields2.text !== "string" || !fields2.text.trim() || [...fields2.text].length > MLS_DEV_INTERACTION_LIMITS.text || new TextDecoder("utf-8", { fatal: true }).decode(utf84.encode(fields2.text)) !== fields2.text)
|
|
1908
|
-
|
|
1741
|
+
invalid7();
|
|
1909
1742
|
payload = Object.freeze({ kind: "secret", requestId: binding3.requestId, text: fields2.text });
|
|
1910
1743
|
} else if (kind.value === "control") {
|
|
1911
1744
|
const fields2 = readMlsDataRecord(input.payload, ["kind", "control"]);
|
|
@@ -1960,27 +1793,27 @@ var MlsDevApplicationValidationError = class extends Error {
|
|
|
1960
1793
|
}
|
|
1961
1794
|
};
|
|
1962
1795
|
var utf85 = new TextEncoder();
|
|
1963
|
-
function
|
|
1796
|
+
function invalid8() {
|
|
1964
1797
|
throw new MlsDevApplicationValidationError();
|
|
1965
1798
|
}
|
|
1966
|
-
__name(
|
|
1967
|
-
function
|
|
1799
|
+
__name(invalid8, "invalid");
|
|
1800
|
+
function boundary7(read) {
|
|
1968
1801
|
try {
|
|
1969
1802
|
return read();
|
|
1970
1803
|
} catch {
|
|
1971
|
-
return
|
|
1804
|
+
return invalid8();
|
|
1972
1805
|
}
|
|
1973
1806
|
}
|
|
1974
|
-
__name(
|
|
1807
|
+
__name(boundary7, "boundary");
|
|
1975
1808
|
function bounded6(value) {
|
|
1976
1809
|
if (utf85.encode(JSON.stringify(value)).length > MLS_DEV_APPLICATION_MAX_BYTES)
|
|
1977
|
-
|
|
1810
|
+
invalid8();
|
|
1978
1811
|
return Object.freeze(value);
|
|
1979
1812
|
}
|
|
1980
1813
|
__name(bounded6, "bounded");
|
|
1981
1814
|
function id5(value) {
|
|
1982
1815
|
if (typeof value !== "string" || !/^[A-Za-z0-9_.:~-]{1,200}$/.test(value) || value === "." || value === "..")
|
|
1983
|
-
|
|
1816
|
+
invalid8();
|
|
1984
1817
|
return value;
|
|
1985
1818
|
}
|
|
1986
1819
|
__name(id5, "id");
|
|
@@ -1990,31 +1823,31 @@ function isMlsDevMessageId(value) {
|
|
|
1990
1823
|
__name(isMlsDevMessageId, "isMlsDevMessageId");
|
|
1991
1824
|
function messageId(value) {
|
|
1992
1825
|
if (!isMlsDevMessageId(value))
|
|
1993
|
-
|
|
1826
|
+
invalid8();
|
|
1994
1827
|
return value;
|
|
1995
1828
|
}
|
|
1996
1829
|
__name(messageId, "messageId");
|
|
1997
1830
|
function interactionId2(value) {
|
|
1998
1831
|
if (typeof value !== "string" || !MLS_DEV_INTERACTION_ID_PATTERN.test(value) || value === "." || value === "..")
|
|
1999
|
-
|
|
1832
|
+
invalid8();
|
|
2000
1833
|
return value;
|
|
2001
1834
|
}
|
|
2002
1835
|
__name(interactionId2, "interactionId");
|
|
2003
1836
|
function parseMlsDevInteractionBinding(value) {
|
|
2004
|
-
return
|
|
1837
|
+
return boundary7(() => {
|
|
2005
1838
|
const role = value && typeof value === "object" ? Object.getOwnPropertyDescriptor(value, "role") : void 0;
|
|
2006
1839
|
if (!role || !Object.hasOwn(role, "value"))
|
|
2007
|
-
|
|
1840
|
+
invalid8();
|
|
2008
1841
|
if (role.value === "request") {
|
|
2009
1842
|
const input2 = readMlsDataRecord(value, ["role", "requestId", "kind", "responderIds", "expiresAtMs"]);
|
|
2010
1843
|
if (typeof input2.kind !== "string" || !MLS_DEV_INTERACTION_KINDS.includes(input2.kind))
|
|
2011
|
-
|
|
1844
|
+
invalid8();
|
|
2012
1845
|
const responders = input2.responderIds;
|
|
2013
1846
|
if (!Array.isArray(responders) || Object.getPrototypeOf(responders) !== Array.prototype || responders.length !== 1 || Reflect.ownKeys(Object.getOwnPropertyDescriptors(responders)).length !== 2)
|
|
2014
|
-
|
|
1847
|
+
invalid8();
|
|
2015
1848
|
const only = Object.getOwnPropertyDescriptor(responders, 0);
|
|
2016
1849
|
if (!only || !only.enumerable || !Object.hasOwn(only, "value"))
|
|
2017
|
-
|
|
1850
|
+
invalid8();
|
|
2018
1851
|
const expiresAtMs = requireMlsInteger(input2.expiresAtMs, 1);
|
|
2019
1852
|
return Object.freeze({
|
|
2020
1853
|
role: "request",
|
|
@@ -2039,21 +1872,21 @@ function encoded5(value, bytes) {
|
|
|
2039
1872
|
}
|
|
2040
1873
|
__name(encoded5, "encoded");
|
|
2041
1874
|
function parseMlsDevApplicationWire(value) {
|
|
2042
|
-
return
|
|
1875
|
+
return boundary7(() => {
|
|
2043
1876
|
if (typeof value !== "string" || value.length < 2 || value.length > Math.ceil(MLS_DEV_APPLICATION_TLS_MAX_BYTES * 4 / 3))
|
|
2044
|
-
|
|
1877
|
+
invalid8();
|
|
2045
1878
|
const bytes = Math.floor(value.length * 3 / 4);
|
|
2046
1879
|
if (bytes > MLS_DEV_APPLICATION_TLS_MAX_BYTES || value.length !== Math.ceil(bytes * 4 / 3) || !/^[A-Za-z0-9_-]+$/.test(value))
|
|
2047
|
-
|
|
1880
|
+
invalid8();
|
|
2048
1881
|
const last = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(value.at(-1));
|
|
2049
1882
|
if (value.length % 4 === 2 && (last & 15) !== 0 || value.length % 4 === 3 && (last & 3) !== 0)
|
|
2050
|
-
|
|
1883
|
+
invalid8();
|
|
2051
1884
|
return value;
|
|
2052
1885
|
});
|
|
2053
1886
|
}
|
|
2054
1887
|
__name(parseMlsDevApplicationWire, "parseMlsDevApplicationWire");
|
|
2055
1888
|
function parseMlsDevApplicationPreconditions(value) {
|
|
2056
|
-
return
|
|
1889
|
+
return boundary7(() => {
|
|
2057
1890
|
const input = readMlsDataRecord(value, ["membershipRevision", "admissionId"]);
|
|
2058
1891
|
return Object.freeze({ membershipRevision: requireMlsInteger(input.membershipRevision), admissionId: id5(input.admissionId) });
|
|
2059
1892
|
});
|
|
@@ -2063,7 +1896,7 @@ var bindingFields = ["version", "environmentId", "conversationId", "groupId", "m
|
|
|
2063
1896
|
var interactionBindingFields = [...bindingFields, "interaction"];
|
|
2064
1897
|
function binding(input) {
|
|
2065
1898
|
const environmentId = requireMlsEnvironmentId(input.environmentId);
|
|
2066
|
-
if (parseMlsDevCredentialToken(input.senderCredential).unsigned.claims.device.environmentId !== environmentId)
|
|
1899
|
+
if (parseMlsDevCredentialToken(input.senderCredential).unsigned.claims.device.environmentId !== environmentId) invalid8();
|
|
2067
1900
|
return {
|
|
2068
1901
|
version: requireMlsLiteral(input.version, 1),
|
|
2069
1902
|
environmentId,
|
|
@@ -2082,14 +1915,14 @@ function fields(value, extra) {
|
|
|
2082
1915
|
}
|
|
2083
1916
|
__name(fields, "fields");
|
|
2084
1917
|
function parseMlsDevApplicationEnvelope(value) {
|
|
2085
|
-
return
|
|
1918
|
+
return boundary7(() => {
|
|
2086
1919
|
const input = fields(value, ["ciphertext", "proof"]);
|
|
2087
1920
|
return bounded6({ ...binding(input), ciphertext: parseMlsDevApplicationWire(input.ciphertext), proof: encoded5(input.proof, 64) });
|
|
2088
1921
|
});
|
|
2089
1922
|
}
|
|
2090
1923
|
__name(parseMlsDevApplicationEnvelope, "parseMlsDevApplicationEnvelope");
|
|
2091
1924
|
function parseMlsDevApplicationReceipt(value) {
|
|
2092
|
-
return
|
|
1925
|
+
return boundary7(() => {
|
|
2093
1926
|
const input = readMlsDataRecord(value, ["version", "authorization", "operationId", "conversationId", "groupId", "messageId", "feedOrdinal", "head", "acceptedAtMs", "envelopeHash"]);
|
|
2094
1927
|
return bounded6({
|
|
2095
1928
|
version: requireMlsLiteral(input.version, 1),
|
|
@@ -2108,7 +1941,7 @@ function parseMlsDevApplicationReceipt(value) {
|
|
|
2108
1941
|
__name(parseMlsDevApplicationReceipt, "parseMlsDevApplicationReceipt");
|
|
2109
1942
|
function text2(value) {
|
|
2110
1943
|
if (typeof value !== "string" || !value.trim() || utf85.encode(value).length > MLS_DEV_TEXT_MAX_BYTES || new TextDecoder("utf-8", { fatal: true }).decode(utf85.encode(value)) !== value)
|
|
2111
|
-
|
|
1944
|
+
invalid8();
|
|
2112
1945
|
return value;
|
|
2113
1946
|
}
|
|
2114
1947
|
__name(text2, "text");
|
|
@@ -2117,13 +1950,13 @@ function textExtras2(value) {
|
|
|
2117
1950
|
if (Object.hasOwn(value, "replyTo")) {
|
|
2118
1951
|
const reply = readMlsDataRecord(value.replyTo, ["messageId", "quote"]);
|
|
2119
1952
|
if ([...text2(reply.quote)].length > MLS_DEV_REPLY_QUOTE_MAX_CHARACTERS)
|
|
2120
|
-
|
|
1953
|
+
invalid8();
|
|
2121
1954
|
extras.replyTo = Object.freeze({ messageId: messageId(reply.messageId), quote: reply.quote });
|
|
2122
1955
|
}
|
|
2123
1956
|
if (Object.hasOwn(value, "mentions")) {
|
|
2124
1957
|
const mentions = value.mentions;
|
|
2125
1958
|
if (!Array.isArray(mentions) || mentions.length < 1 || mentions.length > MLS_DEV_MENTIONS_MAX || new Set(mentions).size !== mentions.length)
|
|
2126
|
-
|
|
1959
|
+
invalid8();
|
|
2127
1960
|
extras.mentions = Object.freeze(mentions.map(id5));
|
|
2128
1961
|
}
|
|
2129
1962
|
return extras;
|
|
@@ -2131,7 +1964,7 @@ function textExtras2(value) {
|
|
|
2131
1964
|
__name(textExtras2, "textExtras");
|
|
2132
1965
|
var optionalKeys = /* @__PURE__ */ __name((value, keys2) => value && typeof value === "object" ? keys2.filter((key) => Object.hasOwn(value, key)) : [], "optionalKeys");
|
|
2133
1966
|
function parseMlsDevTextPayload(value) {
|
|
2134
|
-
return
|
|
1967
|
+
return boundary7(() => {
|
|
2135
1968
|
const input = readMlsDataRecord(value, ["version", "kind", "conversationId", "groupId", "messageId", "operationId", "senderDeviceId", "text", ...optionalKeys(value, ["replyTo", "mentions"])]);
|
|
2136
1969
|
return bounded6({
|
|
2137
1970
|
version: requireMlsLiteral(input.version, 1),
|
|
@@ -2149,19 +1982,19 @@ function parseMlsDevTextPayload(value) {
|
|
|
2149
1982
|
__name(parseMlsDevTextPayload, "parseMlsDevTextPayload");
|
|
2150
1983
|
var itemFields = ["type", "uploadId", "url", "mimeType", "sizeBytes", "fileName", "width", "height", "durationMs", "thumbnailUrl", "caption", "replyTo", "mentions"];
|
|
2151
1984
|
function httpsUrl(value) {
|
|
2152
|
-
if (typeof value !== "string" || value.length > 2048)
|
|
2153
|
-
const url =
|
|
2154
|
-
if (url.protocol !== "https:" || url.username || url.password)
|
|
1985
|
+
if (typeof value !== "string" || value.length > 2048) invalid8();
|
|
1986
|
+
const url = boundary7(() => new URL(value));
|
|
1987
|
+
if (url.protocol !== "https:" || url.username || url.password) invalid8();
|
|
2155
1988
|
return value;
|
|
2156
1989
|
}
|
|
2157
1990
|
__name(httpsUrl, "httpsUrl");
|
|
2158
|
-
var dimension = /* @__PURE__ */ __name((value) => requireMlsInteger(value, 0) <= 1e5 ? value :
|
|
1991
|
+
var dimension = /* @__PURE__ */ __name((value) => requireMlsInteger(value, 0) <= 1e5 ? value : invalid8(), "dimension");
|
|
2159
1992
|
function item(value) {
|
|
2160
1993
|
const input = readMlsDataRecord(value, ["type", "uploadId", "url", "mimeType", "sizeBytes", ...optionalKeys(value, itemFields.slice(5))]);
|
|
2161
1994
|
if (!MLS_DEV_ITEM_TYPES.some((type) => type === input.type) || typeof input.mimeType !== "string" || !/^[a-z0-9.+-]{1,64}\/[a-z0-9.+-]{1,128}$/i.test(input.mimeType))
|
|
2162
|
-
|
|
1995
|
+
invalid8();
|
|
2163
1996
|
if (input.fileName !== void 0 && (typeof input.fileName !== "string" || !input.fileName.trim() || [...input.fileName].length > 240))
|
|
2164
|
-
|
|
1997
|
+
invalid8();
|
|
2165
1998
|
return Object.freeze({
|
|
2166
1999
|
type: input.type,
|
|
2167
2000
|
uploadId: requireMlsUuid(input.uploadId),
|
|
@@ -2177,7 +2010,7 @@ function item(value) {
|
|
|
2177
2010
|
}
|
|
2178
2011
|
__name(item, "item");
|
|
2179
2012
|
function parseMlsDevItemPayload(value) {
|
|
2180
|
-
return
|
|
2013
|
+
return boundary7(() => {
|
|
2181
2014
|
const input = readMlsDataRecord(value, ["version", "kind", "conversationId", "groupId", "messageId", "operationId", "senderDeviceId", "item"]);
|
|
2182
2015
|
const payload = {
|
|
2183
2016
|
version: requireMlsLiteral(input.version, 1),
|
|
@@ -2190,7 +2023,7 @@ function parseMlsDevItemPayload(value) {
|
|
|
2190
2023
|
item: item(input.item)
|
|
2191
2024
|
};
|
|
2192
2025
|
if (utf85.encode(JSON.stringify(payload)).length > MLS_DEV_TEXT_MAX_BYTES)
|
|
2193
|
-
|
|
2026
|
+
invalid8();
|
|
2194
2027
|
return bounded6(payload);
|
|
2195
2028
|
});
|
|
2196
2029
|
}
|
|
@@ -2212,40 +2045,443 @@ function framed(domain4, value, operationId) {
|
|
|
2212
2045
|
}
|
|
2213
2046
|
__name(framed, "framed");
|
|
2214
2047
|
function encodeMlsDevApplicationEnvelopeHash(value, operationId) {
|
|
2215
|
-
return
|
|
2048
|
+
return boundary7(() => framed("canon.mls.dev-application-envelope.v1\0", parseMlsDevApplicationEnvelope(value), operationId));
|
|
2216
2049
|
}
|
|
2217
2050
|
__name(encodeMlsDevApplicationEnvelopeHash, "encodeMlsDevApplicationEnvelopeHash");
|
|
2218
2051
|
|
|
2219
|
-
// ../backend-contracts/src/
|
|
2220
|
-
var
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2052
|
+
// ../backend-contracts/src/mlsDevFeedReceipt.ts
|
|
2053
|
+
var MlsDevFeedReceiptValidationError = class extends Error {
|
|
2054
|
+
static {
|
|
2055
|
+
__name(this, "MlsDevFeedReceiptValidationError");
|
|
2056
|
+
}
|
|
2057
|
+
code = "INVALID_MLS_DEV_FEED_RECEIPT";
|
|
2058
|
+
constructor() {
|
|
2059
|
+
super("INVALID_MLS_DEV_FEED_RECEIPT");
|
|
2060
|
+
this.name = "MlsDevFeedReceiptValidationError";
|
|
2061
|
+
}
|
|
2062
|
+
};
|
|
2063
|
+
function invalid9() {
|
|
2064
|
+
throw new MlsDevFeedReceiptValidationError();
|
|
2065
|
+
}
|
|
2066
|
+
__name(invalid9, "invalid");
|
|
2067
|
+
function boundary8(read) {
|
|
2068
|
+
try {
|
|
2069
|
+
return read();
|
|
2070
|
+
} catch {
|
|
2071
|
+
return invalid9();
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
__name(boundary8, "boundary");
|
|
2075
|
+
function parseMlsDevReceiptKeyVersion(value, environmentId) {
|
|
2076
|
+
return boundary8(() => {
|
|
2077
|
+
if (typeof value !== "string" || value.length > 200) invalid9();
|
|
2078
|
+
const owner = mlsEnvironmentOfReceiptKeyVersion(value);
|
|
2079
|
+
if (!owner || environmentId !== void 0 && owner !== environmentId) invalid9();
|
|
2080
|
+
return value;
|
|
2081
|
+
});
|
|
2082
|
+
}
|
|
2083
|
+
__name(parseMlsDevReceiptKeyVersion, "parseMlsDevReceiptKeyVersion");
|
|
2084
|
+
function parseMlsDevFeedReceiptProof(value) {
|
|
2085
|
+
return boundary8(() => {
|
|
2086
|
+
const input = readMlsDataRecord(value, ["keyVersion", "signature"]);
|
|
2087
|
+
decodeCanonicalMlsBase64Url(input.signature, 64);
|
|
2088
|
+
return Object.freeze({ keyVersion: parseMlsDevReceiptKeyVersion(input.keyVersion), signature: input.signature });
|
|
2089
|
+
});
|
|
2090
|
+
}
|
|
2091
|
+
__name(parseMlsDevFeedReceiptProof, "parseMlsDevFeedReceiptProof");
|
|
2092
|
+
var MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW = "MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW";
|
|
2093
|
+
function isMlsDevReceiptClockSkew(value) {
|
|
2094
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
2095
|
+
const keys2 = Object.keys(value).sort().join(), input = value;
|
|
2096
|
+
return (keys2 === "error,ok,retryable" || keys2 === "error,ok,retryable,version" && input.version === 1) && input.ok === false && input.error === MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW && input.retryable === true;
|
|
2097
|
+
}
|
|
2098
|
+
__name(isMlsDevReceiptClockSkew, "isMlsDevReceiptClockSkew");
|
|
2099
|
+
|
|
2100
|
+
// ../backend-contracts/src/mlsDevCredentialReconciliation.ts
|
|
2101
|
+
var MLS_DEV_CREDENTIAL_RECONCILIATION_CHALLENGE_TTL_MS = 3e5;
|
|
2102
|
+
var MLS_DEV_CREDENTIAL_RECONCILIATION_MAX_BYTES = 8192;
|
|
2103
|
+
var MlsDevCredentialReconciliationValidationError = class extends Error {
|
|
2104
|
+
static {
|
|
2105
|
+
__name(this, "MlsDevCredentialReconciliationValidationError");
|
|
2106
|
+
}
|
|
2107
|
+
code = "INVALID_MLS_DEV_CREDENTIAL_RECONCILIATION";
|
|
2108
|
+
constructor() {
|
|
2109
|
+
super("INVALID_MLS_DEV_CREDENTIAL_RECONCILIATION");
|
|
2110
|
+
this.name = "MlsDevCredentialReconciliationValidationError";
|
|
2111
|
+
}
|
|
2112
|
+
};
|
|
2113
|
+
var utf86 = new TextEncoder();
|
|
2114
|
+
var domain2 = utf86.encode("canon.mls.credential-reconciliation-proof.v1\0");
|
|
2115
|
+
function invalid10() {
|
|
2116
|
+
throw new MlsDevCredentialReconciliationValidationError();
|
|
2117
|
+
}
|
|
2118
|
+
__name(invalid10, "invalid");
|
|
2119
|
+
function boundary9(read) {
|
|
2120
|
+
try {
|
|
2121
|
+
return read();
|
|
2122
|
+
} catch {
|
|
2123
|
+
return invalid10();
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
__name(boundary9, "boundary");
|
|
2127
|
+
function bounded7(value) {
|
|
2128
|
+
if (utf86.encode(JSON.stringify(value)).length > MLS_DEV_CREDENTIAL_RECONCILIATION_MAX_BYTES) invalid10();
|
|
2129
|
+
return Object.freeze(value);
|
|
2130
|
+
}
|
|
2131
|
+
__name(bounded7, "bounded");
|
|
2132
|
+
function encoded6(value, bytes) {
|
|
2133
|
+
decodeCanonicalMlsBase64Url(value, bytes);
|
|
2134
|
+
return value;
|
|
2135
|
+
}
|
|
2136
|
+
__name(encoded6, "encoded");
|
|
2137
|
+
function parseMlsDevCredentialReconciliationBegin(value) {
|
|
2138
|
+
return boundary9(() => {
|
|
2139
|
+
const input = readMlsDataRecord(value, ["version", "deviceId", "requestId", "expectedCredentialGeneration"]);
|
|
2140
|
+
return bounded7({
|
|
2141
|
+
version: requireMlsLiteral(input.version, 1),
|
|
2142
|
+
deviceId: requireMlsUuid(input.deviceId),
|
|
2143
|
+
requestId: requireMlsUuid(input.requestId),
|
|
2144
|
+
expectedCredentialGeneration: requireMlsInteger(input.expectedCredentialGeneration)
|
|
2145
|
+
});
|
|
2146
|
+
});
|
|
2147
|
+
}
|
|
2148
|
+
__name(parseMlsDevCredentialReconciliationBegin, "parseMlsDevCredentialReconciliationBegin");
|
|
2149
|
+
function parseMlsDevCredentialReconciliationChallenge(value) {
|
|
2150
|
+
return boundary9(() => {
|
|
2151
|
+
const input = readMlsDataRecord(value, [
|
|
2152
|
+
"version",
|
|
2153
|
+
"challengeId",
|
|
2154
|
+
"requestId",
|
|
2155
|
+
"nonce",
|
|
2156
|
+
"device",
|
|
2157
|
+
"expectedCredentialGeneration",
|
|
2158
|
+
"issuedAtMs",
|
|
2159
|
+
"expiresAtMs"
|
|
2160
|
+
]);
|
|
2161
|
+
const device = parseMlsDevEnrollmentResult({ version: 1, authorization: "registration_only", device: input.device }).device;
|
|
2162
|
+
const issuedAtMs = requireMlsInteger(input.issuedAtMs), expiresAtMs = requireMlsInteger(input.expiresAtMs);
|
|
2163
|
+
if (issuedAtMs < device.registeredAtMs || expiresAtMs - issuedAtMs !== MLS_DEV_CREDENTIAL_RECONCILIATION_CHALLENGE_TTL_MS) invalid10();
|
|
2164
|
+
return bounded7({
|
|
2165
|
+
version: requireMlsLiteral(input.version, 1),
|
|
2166
|
+
challengeId: requireMlsUuid(input.challengeId),
|
|
2167
|
+
requestId: requireMlsUuid(input.requestId),
|
|
2168
|
+
nonce: encoded6(input.nonce, 32),
|
|
2169
|
+
device,
|
|
2170
|
+
expectedCredentialGeneration: requireMlsInteger(input.expectedCredentialGeneration),
|
|
2171
|
+
issuedAtMs,
|
|
2172
|
+
expiresAtMs
|
|
2173
|
+
});
|
|
2174
|
+
});
|
|
2175
|
+
}
|
|
2176
|
+
__name(parseMlsDevCredentialReconciliationChallenge, "parseMlsDevCredentialReconciliationChallenge");
|
|
2177
|
+
function parseMlsDevCredentialReconciliationComplete(value) {
|
|
2178
|
+
return boundary9(() => {
|
|
2179
|
+
const input = readMlsDataRecord(value, ["version", "challengeId", "proof"]);
|
|
2180
|
+
return bounded7({ version: requireMlsLiteral(input.version, 1), challengeId: requireMlsUuid(input.challengeId), proof: encoded6(input.proof, 64) });
|
|
2181
|
+
});
|
|
2182
|
+
}
|
|
2183
|
+
__name(parseMlsDevCredentialReconciliationComplete, "parseMlsDevCredentialReconciliationComplete");
|
|
2184
|
+
function parseMlsDevCredentialReconciliationReceipt(value) {
|
|
2185
|
+
return boundary9(() => {
|
|
2186
|
+
const input = readMlsDataRecord(value, ["version", "authorization", "challenge", "observedCredentialGeneration", "observedAtMs"]);
|
|
2187
|
+
const challenge = parseMlsDevCredentialReconciliationChallenge(input.challenge);
|
|
2188
|
+
const observedCredentialGeneration = requireMlsInteger(input.observedCredentialGeneration), observedAtMs = requireMlsInteger(input.observedAtMs);
|
|
2189
|
+
if (observedCredentialGeneration < challenge.expectedCredentialGeneration || observedAtMs < challenge.issuedAtMs || observedAtMs >= challenge.expiresAtMs) invalid10();
|
|
2190
|
+
return bounded7({
|
|
2191
|
+
version: requireMlsLiteral(input.version, 1),
|
|
2192
|
+
authorization: requireMlsLiteral(input.authorization, "credential_generation_observation_only"),
|
|
2193
|
+
challenge,
|
|
2194
|
+
observedCredentialGeneration,
|
|
2195
|
+
observedAtMs
|
|
2196
|
+
});
|
|
2197
|
+
});
|
|
2198
|
+
}
|
|
2199
|
+
__name(parseMlsDevCredentialReconciliationReceipt, "parseMlsDevCredentialReconciliationReceipt");
|
|
2200
|
+
|
|
2201
|
+
// ../backend-contracts/src/mlsDevDeviceCustody.ts
|
|
2202
|
+
var MLS_DEV_DEVICE_CONTEXT_MAX_BYTES = 2048;
|
|
2203
|
+
var MLS_DEV_DEVICE_COMMAND_MAX_BYTES = 16384;
|
|
2204
|
+
var MLS_DEV_DEVICE_WRAPPED_STATE_MAX_BYTES = 6144;
|
|
2205
|
+
var MlsDevDeviceCustodyValidationError = class extends Error {
|
|
2206
|
+
static {
|
|
2207
|
+
__name(this, "MlsDevDeviceCustodyValidationError");
|
|
2208
|
+
}
|
|
2209
|
+
code = "INVALID_MLS_DEV_DEVICE_CUSTODY";
|
|
2210
|
+
constructor() {
|
|
2211
|
+
super("INVALID_MLS_DEV_DEVICE_CUSTODY");
|
|
2212
|
+
this.name = "MlsDevDeviceCustodyValidationError";
|
|
2213
|
+
}
|
|
2214
|
+
};
|
|
2215
|
+
var utf87 = new TextEncoder();
|
|
2216
|
+
function invalid11() {
|
|
2217
|
+
throw new MlsDevDeviceCustodyValidationError();
|
|
2218
|
+
}
|
|
2219
|
+
__name(invalid11, "invalid");
|
|
2220
|
+
function boundary10(read) {
|
|
2221
|
+
try {
|
|
2222
|
+
return read();
|
|
2223
|
+
} catch {
|
|
2224
|
+
return invalid11();
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
__name(boundary10, "boundary");
|
|
2228
|
+
function bounded8(value, limit2) {
|
|
2229
|
+
if (utf87.encode(JSON.stringify(value)).length > limit2) invalid11();
|
|
2230
|
+
return Object.freeze(value);
|
|
2231
|
+
}
|
|
2232
|
+
__name(bounded8, "bounded");
|
|
2233
|
+
function binding2(input) {
|
|
2234
|
+
return {
|
|
2235
|
+
version: requireMlsLiteral(input.version, 1),
|
|
2236
|
+
environmentId: requireMlsEnvironmentId(input.environmentId),
|
|
2237
|
+
principal: parseMlsDevEnrollmentPrincipal(input.principal),
|
|
2238
|
+
installationId: parseMlsDevInstallationId(input.installationId)
|
|
2239
|
+
};
|
|
2240
|
+
}
|
|
2241
|
+
__name(binding2, "binding");
|
|
2242
|
+
function parseMlsDevDeviceBinding(value) {
|
|
2243
|
+
return boundary10(() => bounded8(binding2(readMlsDataRecord(value, ["version", "environmentId", "principal", "installationId"])), MLS_DEV_DEVICE_CONTEXT_MAX_BYTES));
|
|
2244
|
+
}
|
|
2245
|
+
__name(parseMlsDevDeviceBinding, "parseMlsDevDeviceBinding");
|
|
2246
|
+
function parseMlsDevDeviceContext(value) {
|
|
2247
|
+
return boundary10(() => {
|
|
2248
|
+
const input = readMlsDataRecord(value, ["version", "environmentId", "principal", "installationId", "revision"]);
|
|
2249
|
+
const revision2 = requireMlsInteger(input.revision);
|
|
2250
|
+
if (revision2 >= Number.MAX_SAFE_INTEGER) invalid11();
|
|
2251
|
+
return bounded8({ ...binding2(input), revision: revision2 }, MLS_DEV_DEVICE_CONTEXT_MAX_BYTES);
|
|
2252
|
+
});
|
|
2253
|
+
}
|
|
2254
|
+
__name(parseMlsDevDeviceContext, "parseMlsDevDeviceContext");
|
|
2255
|
+
function parseMlsDevDeviceCommand(value) {
|
|
2256
|
+
return boundary10(() => {
|
|
2257
|
+
if (value === null || typeof value !== "object") invalid11();
|
|
2258
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, "op");
|
|
2259
|
+
if (!descriptor || !Object.hasOwn(descriptor, "value")) invalid11();
|
|
2260
|
+
if (descriptor.value === "create") {
|
|
2261
|
+
const input2 = readMlsDataRecord(value, ["op"]);
|
|
2262
|
+
return Object.freeze({ op: requireMlsLiteral(input2.op, "create") });
|
|
2263
|
+
}
|
|
2264
|
+
if (descriptor.value === "enrollment_proof") {
|
|
2265
|
+
const input2 = readMlsDataRecord(value, ["op", "challenge"]);
|
|
2266
|
+
return bounded8({
|
|
2267
|
+
op: requireMlsLiteral(input2.op, "enrollment_proof"),
|
|
2268
|
+
challenge: parseMlsDevEnrollmentChallenge(input2.challenge)
|
|
2269
|
+
}, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
|
|
2270
|
+
}
|
|
2271
|
+
if (descriptor.value === "credential_reconciliation_proof") {
|
|
2272
|
+
const input2 = readMlsDataRecord(value, ["op", "challenge", "expectedCredentialGeneration"]);
|
|
2273
|
+
const challenge2 = parseMlsDevCredentialReconciliationChallenge(input2.challenge);
|
|
2274
|
+
const expectedCredentialGeneration2 = requireMlsInteger(input2.expectedCredentialGeneration);
|
|
2275
|
+
if (challenge2.expectedCredentialGeneration !== expectedCredentialGeneration2) invalid11();
|
|
2276
|
+
return bounded8({
|
|
2277
|
+
op: requireMlsLiteral(input2.op, "credential_reconciliation_proof"),
|
|
2278
|
+
challenge: challenge2,
|
|
2279
|
+
expectedCredentialGeneration: expectedCredentialGeneration2
|
|
2280
|
+
}, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
|
|
2281
|
+
}
|
|
2282
|
+
if (descriptor.value !== "credential_proof") invalid11();
|
|
2283
|
+
const input = readMlsDataRecord(value, ["op", "challenge", "registrationResult", "expectedCredentialGeneration"]);
|
|
2284
|
+
const challenge = parseMlsDevCredentialChallenge(input.challenge);
|
|
2285
|
+
const registrationResult = parseMlsDevEnrollmentResult(input.registrationResult);
|
|
2286
|
+
const expectedCredentialGeneration = requireMlsInteger(input.expectedCredentialGeneration);
|
|
2287
|
+
if (expectedCredentialGeneration >= Number.MAX_SAFE_INTEGER || challenge.credential.claims.generation !== expectedCredentialGeneration + 1 || JSON.stringify(challenge.credential.claims.device) !== JSON.stringify(registrationResult.device)) invalid11();
|
|
2288
|
+
return bounded8({
|
|
2289
|
+
op: requireMlsLiteral(input.op, "credential_proof"),
|
|
2290
|
+
challenge,
|
|
2291
|
+
registrationResult,
|
|
2292
|
+
expectedCredentialGeneration
|
|
2293
|
+
}, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
|
|
2294
|
+
});
|
|
2295
|
+
}
|
|
2296
|
+
__name(parseMlsDevDeviceCommand, "parseMlsDevDeviceCommand");
|
|
2297
|
+
function encoded7(value, bytes) {
|
|
2298
|
+
decodeCanonicalMlsBase64Url(value, bytes);
|
|
2299
|
+
return value;
|
|
2300
|
+
}
|
|
2301
|
+
__name(encoded7, "encoded");
|
|
2302
|
+
function wrapped(value) {
|
|
2303
|
+
if (typeof value !== "string" || value.length > MLS_DEV_DEVICE_WRAPPED_STATE_MAX_BYTES || !value.startsWith("v1:")) invalid11();
|
|
2304
|
+
const body = value.slice(3);
|
|
2305
|
+
if (body.length < 40 || body.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(body)) invalid11();
|
|
2306
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
2307
|
+
if (body.endsWith("==") && (alphabet.indexOf(body.at(-3)) & 15) !== 0) invalid11();
|
|
2308
|
+
if (!body.endsWith("==") && body.endsWith("=") && (alphabet.indexOf(body.at(-2)) & 3) !== 0) invalid11();
|
|
2309
|
+
return value;
|
|
2310
|
+
}
|
|
2311
|
+
__name(wrapped, "wrapped");
|
|
2312
|
+
function parseMlsDevDevicePreparation(value, op) {
|
|
2313
|
+
return boundary10(() => {
|
|
2314
|
+
if (!["create", "enrollment_proof", "credential_proof", "credential_reconciliation_proof"].includes(op)) invalid11();
|
|
2315
|
+
const input = readMlsDataRecord(value, ["wrappedState", "payload"]);
|
|
2316
|
+
const payload = readMlsDataRecord(input.payload, op === "create" ? ["signaturePublicKey"] : ["signaturePublicKey", "proof"]);
|
|
2317
|
+
return bounded8({ wrappedState: wrapped(input.wrappedState), payload: Object.freeze({
|
|
2318
|
+
signaturePublicKey: encoded7(payload.signaturePublicKey, 32),
|
|
2319
|
+
...op === "create" ? {} : { proof: encoded7(payload.proof, 64) }
|
|
2320
|
+
}) }, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
|
|
2321
|
+
});
|
|
2322
|
+
}
|
|
2323
|
+
__name(parseMlsDevDevicePreparation, "parseMlsDevDevicePreparation");
|
|
2324
|
+
|
|
2325
|
+
// ../backend-contracts/src/upload-mime-types.ts
|
|
2326
|
+
var MIME_TYPE_RE = /^[a-z0-9.+-]+\/[a-z0-9.+-]+$/i;
|
|
2327
|
+
var SAFE_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
2328
|
+
"image/jpeg",
|
|
2329
|
+
"image/png",
|
|
2330
|
+
"image/webp",
|
|
2331
|
+
"image/gif"
|
|
2332
|
+
]);
|
|
2333
|
+
var SAFE_AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
2334
|
+
"audio/mp4",
|
|
2335
|
+
"audio/x-m4a",
|
|
2336
|
+
"audio/mpeg",
|
|
2337
|
+
"audio/webm",
|
|
2338
|
+
"audio/ogg",
|
|
2339
|
+
"audio/wav",
|
|
2340
|
+
// ADTS AAC — the future Android streamable-memo lane; harmless standalone.
|
|
2341
|
+
"audio/aac"
|
|
2342
|
+
]);
|
|
2343
|
+
var SAFE_VIDEO_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
2344
|
+
"video/mp4",
|
|
2345
|
+
"video/quicktime",
|
|
2346
|
+
"video/webm",
|
|
2347
|
+
"video/x-m4v"
|
|
2348
|
+
]);
|
|
2349
|
+
var SAFE_FILE_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
2350
|
+
"application/pdf",
|
|
2351
|
+
"text/plain",
|
|
2352
|
+
"text/markdown",
|
|
2353
|
+
"text/x-markdown",
|
|
2354
|
+
"text/csv",
|
|
2355
|
+
"application/csv",
|
|
2356
|
+
"application/json",
|
|
2357
|
+
"application/zip",
|
|
2358
|
+
"application/vnd.ms-excel",
|
|
2359
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
2360
|
+
]);
|
|
2361
|
+
var SAFE_FILE_MIME_BY_EXTENSION = {
|
|
2362
|
+
csv: "text/csv",
|
|
2363
|
+
json: "application/json",
|
|
2364
|
+
md: "text/markdown",
|
|
2365
|
+
markdown: "text/markdown",
|
|
2366
|
+
pdf: "application/pdf",
|
|
2367
|
+
txt: "text/plain",
|
|
2368
|
+
xls: "application/vnd.ms-excel",
|
|
2369
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
2370
|
+
zip: "application/zip"
|
|
2371
|
+
};
|
|
2372
|
+
var SAFE_VIDEO_MIME_BY_EXTENSION = {
|
|
2373
|
+
m4v: "video/x-m4v",
|
|
2374
|
+
mov: "video/quicktime",
|
|
2375
|
+
mp4: "video/mp4",
|
|
2376
|
+
webm: "video/webm"
|
|
2377
|
+
};
|
|
2378
|
+
var SAFE_AUDIO_MIME_BY_EXTENSION = {
|
|
2379
|
+
aac: "audio/aac",
|
|
2380
|
+
m4a: "audio/x-m4a",
|
|
2381
|
+
mp3: "audio/mpeg",
|
|
2382
|
+
oga: "audio/ogg",
|
|
2383
|
+
ogg: "audio/ogg",
|
|
2384
|
+
wav: "audio/wav"
|
|
2385
|
+
};
|
|
2386
|
+
function normalizeMimeType(value) {
|
|
2387
|
+
if (typeof value !== "string") return null;
|
|
2388
|
+
const normalized = value.split(";")[0].trim().toLowerCase();
|
|
2389
|
+
if (!MIME_TYPE_RE.test(normalized)) return null;
|
|
2390
|
+
if (normalized === "image/jpg") return "image/jpeg";
|
|
2391
|
+
return normalized;
|
|
2392
|
+
}
|
|
2393
|
+
__name(normalizeMimeType, "normalizeMimeType");
|
|
2394
|
+
function inferSafeFileMimeTypeFromName(value) {
|
|
2395
|
+
if (typeof value !== "string") return null;
|
|
2396
|
+
const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
|
|
2397
|
+
return SAFE_FILE_MIME_BY_EXTENSION[extension] ?? null;
|
|
2398
|
+
}
|
|
2399
|
+
__name(inferSafeFileMimeTypeFromName, "inferSafeFileMimeTypeFromName");
|
|
2400
|
+
function inferSafeVideoMimeTypeFromName(value) {
|
|
2401
|
+
if (typeof value !== "string") return null;
|
|
2402
|
+
const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
|
|
2403
|
+
return SAFE_VIDEO_MIME_BY_EXTENSION[extension] ?? null;
|
|
2404
|
+
}
|
|
2405
|
+
__name(inferSafeVideoMimeTypeFromName, "inferSafeVideoMimeTypeFromName");
|
|
2406
|
+
function inferSafeAudioMimeTypeFromName(value) {
|
|
2407
|
+
if (typeof value !== "string") return null;
|
|
2408
|
+
const extension = value.trim().split(/[\\/]/).pop()?.split(".").pop()?.toLowerCase() ?? "";
|
|
2409
|
+
return SAFE_AUDIO_MIME_BY_EXTENSION[extension] ?? null;
|
|
2410
|
+
}
|
|
2411
|
+
__name(inferSafeAudioMimeTypeFromName, "inferSafeAudioMimeTypeFromName");
|
|
2412
|
+
function shouldTrustSafeFileName(mimeType) {
|
|
2413
|
+
return !mimeType || mimeType === "application/octet-stream" || mimeType === "application/vnd.ms-excel" || mimeType === "text/plain";
|
|
2414
|
+
}
|
|
2415
|
+
__name(shouldTrustSafeFileName, "shouldTrustSafeFileName");
|
|
2416
|
+
function classifyAllowedUploadMimeType(value) {
|
|
2417
|
+
const mimeType = normalizeMimeType(value);
|
|
2418
|
+
if (!mimeType) return null;
|
|
2419
|
+
if (SAFE_IMAGE_MIME_TYPES.has(mimeType)) return "image";
|
|
2420
|
+
if (SAFE_AUDIO_MIME_TYPES.has(mimeType)) return "audio";
|
|
2421
|
+
if (SAFE_VIDEO_MIME_TYPES.has(mimeType)) return "video";
|
|
2422
|
+
if (SAFE_FILE_MIME_TYPES.has(mimeType)) return "file";
|
|
2423
|
+
return null;
|
|
2424
|
+
}
|
|
2425
|
+
__name(classifyAllowedUploadMimeType, "classifyAllowedUploadMimeType");
|
|
2426
|
+
function resolveAllowedUploadMimeType(input) {
|
|
2427
|
+
const normalizedMimeType = normalizeMimeType(input.mimeType);
|
|
2428
|
+
const hasExplicitMimeType = typeof input.mimeType === "string" && input.mimeType.trim().length > 0;
|
|
2429
|
+
const inferredVideoMimeType = inferSafeVideoMimeTypeFromName(input.fileName);
|
|
2430
|
+
const inferredAudioMimeType = inferSafeAudioMimeTypeFromName(input.fileName);
|
|
2431
|
+
const inferredFileMimeType = inferSafeFileMimeTypeFromName(input.fileName);
|
|
2432
|
+
if (hasExplicitMimeType && !normalizedMimeType) {
|
|
2433
|
+
return null;
|
|
2434
|
+
}
|
|
2435
|
+
if (inferredVideoMimeType && (!normalizedMimeType || normalizedMimeType === "application/octet-stream")) {
|
|
2436
|
+
return inferredVideoMimeType;
|
|
2437
|
+
}
|
|
2438
|
+
if (inferredAudioMimeType && (!normalizedMimeType || normalizedMimeType === "application/octet-stream")) {
|
|
2439
|
+
return inferredAudioMimeType;
|
|
2440
|
+
}
|
|
2441
|
+
if (inferredFileMimeType && shouldTrustSafeFileName(normalizedMimeType)) {
|
|
2442
|
+
return inferredFileMimeType;
|
|
2443
|
+
}
|
|
2444
|
+
if (normalizedMimeType && classifyAllowedUploadMimeType(normalizedMimeType)) {
|
|
2445
|
+
return normalizedMimeType;
|
|
2446
|
+
}
|
|
2447
|
+
return normalizedMimeType ? null : inferredFileMimeType;
|
|
2448
|
+
}
|
|
2449
|
+
__name(resolveAllowedUploadMimeType, "resolveAllowedUploadMimeType");
|
|
2450
|
+
|
|
2451
|
+
// ../backend-contracts/src/messageText.ts
|
|
2452
|
+
var HUMAN_MESSAGE_TEXT_MAX_BYTES = 32 * 1024;
|
|
2453
|
+
var UTF8_ENCODER = new TextEncoder();
|
|
2454
|
+
|
|
2455
|
+
// ../backend-contracts/src/runtimeCardFields.ts
|
|
2456
|
+
var RUNTIME_CARD_FIELD_TYPES = [
|
|
2457
|
+
"text",
|
|
2458
|
+
"textarea",
|
|
2459
|
+
"select",
|
|
2460
|
+
"multiSelect",
|
|
2461
|
+
"boolean",
|
|
2462
|
+
"date",
|
|
2463
|
+
"number",
|
|
2464
|
+
"currency",
|
|
2465
|
+
"searchSelect",
|
|
2466
|
+
"lineItems"
|
|
2467
|
+
];
|
|
2468
|
+
var RUNTIME_CARD_LINE_ITEM_COLUMN_TYPES = [
|
|
2469
|
+
"text",
|
|
2470
|
+
"number",
|
|
2471
|
+
"currency",
|
|
2472
|
+
"date",
|
|
2473
|
+
"select"
|
|
2474
|
+
];
|
|
2475
|
+
|
|
2476
|
+
// ../backend-contracts/src/membershipChange.ts
|
|
2477
|
+
function isRecord(value) {
|
|
2478
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2247
2479
|
}
|
|
2248
2480
|
__name(isRecord, "isRecord");
|
|
2481
|
+
function isMembershipChangeMessage(message) {
|
|
2482
|
+
return isRecord(message.metadata) && message.metadata.type === "membership_change";
|
|
2483
|
+
}
|
|
2484
|
+
__name(isMembershipChangeMessage, "isMembershipChangeMessage");
|
|
2249
2485
|
function isNameOrId(value) {
|
|
2250
2486
|
return value === null || typeof value === "string" && value.trim().length > 0;
|
|
2251
2487
|
}
|
|
@@ -2273,15 +2509,262 @@ function formatMembershipChangeNotice(metadata, currentUserId) {
|
|
|
2273
2509
|
if (metadata.action === "left") {
|
|
2274
2510
|
return `${isMember ? "You" : metadata.memberName} left`;
|
|
2275
2511
|
}
|
|
2276
|
-
const actor = isActor ? "You" : metadata.actorName ?? "A member";
|
|
2277
|
-
const member2 = isMember ? "you" : metadata.memberName;
|
|
2278
|
-
return `${actor} ${metadata.action} ${member2}`;
|
|
2512
|
+
const actor = isActor ? "You" : metadata.actorName ?? "A member";
|
|
2513
|
+
const member2 = isMember ? "you" : metadata.memberName;
|
|
2514
|
+
return `${actor} ${metadata.action} ${member2}`;
|
|
2515
|
+
}
|
|
2516
|
+
__name(formatMembershipChangeNotice, "formatMembershipChangeNotice");
|
|
2517
|
+
|
|
2518
|
+
// ../backend-contracts/src/turnProtocol.ts
|
|
2519
|
+
var ACTIVE_TURN_STALE_THRESHOLD_MS = 30 * 60 * 1e3;
|
|
2520
|
+
var WAITING_INPUT_STALE_THRESHOLD_MS = 12 * 60 * 60 * 1e3;
|
|
2521
|
+
var TURN_SEMANTICS = [
|
|
2522
|
+
"progress",
|
|
2523
|
+
"turn_complete",
|
|
2524
|
+
"control"
|
|
2525
|
+
];
|
|
2526
|
+
var DELIVERY_INTENTS = [
|
|
2527
|
+
"queue",
|
|
2528
|
+
"interrupt",
|
|
2529
|
+
"interleave",
|
|
2530
|
+
"stop"
|
|
2531
|
+
];
|
|
2532
|
+
function isRecord2(value) {
|
|
2533
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2534
|
+
}
|
|
2535
|
+
__name(isRecord2, "isRecord");
|
|
2536
|
+
function normalizeTurnMetadata(metadata) {
|
|
2537
|
+
if (!isRecord2(metadata)) return null;
|
|
2538
|
+
const turnId = typeof metadata.turnId === "string" && metadata.turnId.trim() ? metadata.turnId.trim() : null;
|
|
2539
|
+
const turnSemantics = TURN_SEMANTICS.includes(metadata.turnSemantics) ? metadata.turnSemantics : void 0;
|
|
2540
|
+
const deliveryIntent = DELIVERY_INTENTS.includes(metadata.deliveryIntent) ? metadata.deliveryIntent : void 0;
|
|
2541
|
+
const replyBehavior = metadata.replyBehavior === "allow_auto_reply" || metadata.replyBehavior === "suppress_auto_reply" ? metadata.replyBehavior : void 0;
|
|
2542
|
+
const inboundDisposition = metadata.inboundDisposition === "queued" || metadata.inboundDisposition === "accepted_now" || metadata.inboundDisposition === "interleaved" || metadata.inboundDisposition === "trigger_suppressed" || metadata.inboundDisposition === "rejected" || metadata.inboundDisposition === "cancelled" ? metadata.inboundDisposition : void 0;
|
|
2543
|
+
const requestedTurnMode = typeof metadata.requestedTurnMode === "string" && /^[A-Za-z0-9_.:-]{1,80}$/.test(metadata.requestedTurnMode.trim()) ? metadata.requestedTurnMode.trim() : void 0;
|
|
2544
|
+
if (!turnId && !turnSemantics && !deliveryIntent && !replyBehavior && !inboundDisposition && !requestedTurnMode) {
|
|
2545
|
+
return null;
|
|
2546
|
+
}
|
|
2547
|
+
return {
|
|
2548
|
+
...turnId ? { turnId } : {},
|
|
2549
|
+
...turnSemantics ? { turnSemantics } : {},
|
|
2550
|
+
...deliveryIntent ? { deliveryIntent } : {},
|
|
2551
|
+
...replyBehavior ? { replyBehavior } : {},
|
|
2552
|
+
...inboundDisposition ? { inboundDisposition } : {},
|
|
2553
|
+
...requestedTurnMode ? { requestedTurnMode } : {}
|
|
2554
|
+
};
|
|
2555
|
+
}
|
|
2556
|
+
__name(normalizeTurnMetadata, "normalizeTurnMetadata");
|
|
2557
|
+
function resolveTurnMessageSemantics(input) {
|
|
2558
|
+
if (isMembershipChangeMessage(input)) return "control";
|
|
2559
|
+
const turnMetadata = normalizeTurnMetadata(input.metadata);
|
|
2560
|
+
if (turnMetadata?.turnSemantics) return turnMetadata.turnSemantics;
|
|
2561
|
+
if (input.senderType === "human") return "turn_complete";
|
|
2562
|
+
return "progress";
|
|
2563
|
+
}
|
|
2564
|
+
__name(resolveTurnMessageSemantics, "resolveTurnMessageSemantics");
|
|
2565
|
+
function shouldTriggerAgentTurn(input) {
|
|
2566
|
+
if (isMembershipChangeMessage(input)) {
|
|
2567
|
+
return { allow: false, semantics: "control", reason: "membership notices do not trigger agent replies" };
|
|
2568
|
+
}
|
|
2569
|
+
const semantics = resolveTurnMessageSemantics(input);
|
|
2570
|
+
const turnMetadata = normalizeTurnMetadata(input.metadata);
|
|
2571
|
+
if (turnMetadata?.replyBehavior === "suppress_auto_reply") {
|
|
2572
|
+
return {
|
|
2573
|
+
allow: false,
|
|
2574
|
+
semantics,
|
|
2575
|
+
reason: "metadata explicitly suppresses auto-reply"
|
|
2576
|
+
};
|
|
2577
|
+
}
|
|
2578
|
+
if (input.senderType === "human") {
|
|
2579
|
+
return {
|
|
2580
|
+
allow: true,
|
|
2581
|
+
semantics,
|
|
2582
|
+
reason: "human messages always remain triggerable"
|
|
2583
|
+
};
|
|
2584
|
+
}
|
|
2585
|
+
if (semantics === "progress") {
|
|
2586
|
+
return {
|
|
2587
|
+
allow: false,
|
|
2588
|
+
semantics,
|
|
2589
|
+
reason: turnMetadata?.turnSemantics === "progress" ? "non-final agent progress does not trigger other agents" : "agent messages require explicit turn_complete semantics"
|
|
2590
|
+
};
|
|
2591
|
+
}
|
|
2592
|
+
return {
|
|
2593
|
+
allow: true,
|
|
2594
|
+
semantics,
|
|
2595
|
+
reason: "agent message is treated as turn-complete"
|
|
2596
|
+
};
|
|
2597
|
+
}
|
|
2598
|
+
__name(shouldTriggerAgentTurn, "shouldTriggerAgentTurn");
|
|
2599
|
+
|
|
2600
|
+
// ../backend-contracts/src/agentBehaviorPolicy.ts
|
|
2601
|
+
var PARTICIPATION_HISTORY_FETCH_LIMIT = 50;
|
|
2602
|
+
var DEFAULT_GROUP_MAX_CONSECUTIVE_AGENT_TURNS = 4;
|
|
2603
|
+
var DEFAULT_DIRECT_MAX_CONSECUTIVE_AGENT_TURNS = 4;
|
|
2604
|
+
function defaultMaxConsecutiveAgentTurns(conversationType) {
|
|
2605
|
+
if (conversationType === "group") {
|
|
2606
|
+
return DEFAULT_GROUP_MAX_CONSECUTIVE_AGENT_TURNS;
|
|
2607
|
+
}
|
|
2608
|
+
if (conversationType === "direct") {
|
|
2609
|
+
return DEFAULT_DIRECT_MAX_CONSECUTIVE_AGENT_TURNS;
|
|
2610
|
+
}
|
|
2611
|
+
return null;
|
|
2612
|
+
}
|
|
2613
|
+
__name(defaultMaxConsecutiveAgentTurns, "defaultMaxConsecutiveAgentTurns");
|
|
2614
|
+
var DEFAULT_POLICY = {
|
|
2615
|
+
participation: {
|
|
2616
|
+
style: "natural",
|
|
2617
|
+
allowAgentToAgent: true,
|
|
2618
|
+
allowHumanToAgent: true,
|
|
2619
|
+
allowLongRunningCollaboration: true,
|
|
2620
|
+
requireMentionForGroupReplies: false,
|
|
2621
|
+
maxConsecutiveAgentTurns: null
|
|
2622
|
+
},
|
|
2623
|
+
instructions: [],
|
|
2624
|
+
source: {
|
|
2625
|
+
hasAgentDefault: false,
|
|
2626
|
+
hasConversationOverride: false
|
|
2627
|
+
}
|
|
2628
|
+
};
|
|
2629
|
+
function coalesceBoolean(overrideValue, fallbackValue, defaultValue) {
|
|
2630
|
+
if (typeof overrideValue === "boolean") return overrideValue;
|
|
2631
|
+
if (typeof fallbackValue === "boolean") return fallbackValue;
|
|
2632
|
+
return defaultValue;
|
|
2633
|
+
}
|
|
2634
|
+
__name(coalesceBoolean, "coalesceBoolean");
|
|
2635
|
+
function normalizeAgentBehaviorInstructions(value) {
|
|
2636
|
+
if (typeof value !== "string") return null;
|
|
2637
|
+
const trimmed = value.trim();
|
|
2638
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
2639
|
+
}
|
|
2640
|
+
__name(normalizeAgentBehaviorInstructions, "normalizeAgentBehaviorInstructions");
|
|
2641
|
+
function resolveAgentBehaviorPolicy(params) {
|
|
2642
|
+
const agentDefault = params?.agentDefault ?? null;
|
|
2643
|
+
const conversationOverride = params?.conversationOverride ?? null;
|
|
2644
|
+
const defaultInstructions = normalizeAgentBehaviorInstructions(agentDefault?.instructions);
|
|
2645
|
+
const overrideInstructions = normalizeAgentBehaviorInstructions(conversationOverride?.instructions);
|
|
2646
|
+
return {
|
|
2647
|
+
participation: {
|
|
2648
|
+
style: conversationOverride?.participationStyle ?? agentDefault?.participationStyle ?? DEFAULT_POLICY.participation.style,
|
|
2649
|
+
allowAgentToAgent: coalesceBoolean(
|
|
2650
|
+
conversationOverride?.allowAgentToAgent,
|
|
2651
|
+
agentDefault?.allowAgentToAgent,
|
|
2652
|
+
DEFAULT_POLICY.participation.allowAgentToAgent
|
|
2653
|
+
),
|
|
2654
|
+
allowHumanToAgent: DEFAULT_POLICY.participation.allowHumanToAgent,
|
|
2655
|
+
allowLongRunningCollaboration: coalesceBoolean(
|
|
2656
|
+
conversationOverride?.allowLongRunningCollaboration,
|
|
2657
|
+
agentDefault?.allowLongRunningCollaboration,
|
|
2658
|
+
DEFAULT_POLICY.participation.allowLongRunningCollaboration
|
|
2659
|
+
),
|
|
2660
|
+
requireMentionForGroupReplies: coalesceBoolean(
|
|
2661
|
+
conversationOverride?.requireMentionForGroupReplies,
|
|
2662
|
+
agentDefault?.requireMentionForGroupReplies,
|
|
2663
|
+
DEFAULT_POLICY.participation.requireMentionForGroupReplies
|
|
2664
|
+
),
|
|
2665
|
+
maxConsecutiveAgentTurns: conversationOverride?.maxConsecutiveAgentTurns !== void 0 ? conversationOverride.maxConsecutiveAgentTurns ?? null : agentDefault?.maxConsecutiveAgentTurns !== void 0 ? agentDefault.maxConsecutiveAgentTurns ?? null : defaultMaxConsecutiveAgentTurns(params?.conversationType)
|
|
2666
|
+
},
|
|
2667
|
+
instructions: [
|
|
2668
|
+
...defaultInstructions ? [defaultInstructions] : [],
|
|
2669
|
+
...overrideInstructions ? [overrideInstructions] : []
|
|
2670
|
+
],
|
|
2671
|
+
source: {
|
|
2672
|
+
hasAgentDefault: agentDefault != null,
|
|
2673
|
+
hasConversationOverride: conversationOverride != null
|
|
2674
|
+
}
|
|
2675
|
+
};
|
|
2676
|
+
}
|
|
2677
|
+
__name(resolveAgentBehaviorPolicy, "resolveAgentBehaviorPolicy");
|
|
2678
|
+
function toHistorySenderType(message) {
|
|
2679
|
+
if (isMembershipChangeMessage(message)) return null;
|
|
2680
|
+
if (message.senderType !== "ai_agent") {
|
|
2681
|
+
return "human";
|
|
2682
|
+
}
|
|
2683
|
+
return shouldTriggerAgentTurn({
|
|
2684
|
+
senderType: "ai_agent",
|
|
2685
|
+
metadata: message.metadata
|
|
2686
|
+
}).allow ? "ai_agent" : null;
|
|
2687
|
+
}
|
|
2688
|
+
__name(toHistorySenderType, "toHistorySenderType");
|
|
2689
|
+
function buildParticipationHistorySnapshotFromSenderTypes(recentSenderTypes) {
|
|
2690
|
+
let consecutiveAgentTurns = 0;
|
|
2691
|
+
for (const senderType of recentSenderTypes) {
|
|
2692
|
+
if (senderType !== "ai_agent") break;
|
|
2693
|
+
consecutiveAgentTurns += 1;
|
|
2694
|
+
}
|
|
2695
|
+
return {
|
|
2696
|
+
recentSenderTypes,
|
|
2697
|
+
recentHumanCount: recentSenderTypes.filter((senderType) => senderType === "human").length,
|
|
2698
|
+
recentAgentCount: recentSenderTypes.filter((senderType) => senderType === "ai_agent").length,
|
|
2699
|
+
consecutiveAgentTurns,
|
|
2700
|
+
currentAgentStreakStartedByHuman: consecutiveAgentTurns > 0 && recentSenderTypes[consecutiveAgentTurns] === "human"
|
|
2701
|
+
};
|
|
2702
|
+
}
|
|
2703
|
+
__name(buildParticipationHistorySnapshotFromSenderTypes, "buildParticipationHistorySnapshotFromSenderTypes");
|
|
2704
|
+
function buildParticipationHistorySnapshot(messages, agentId) {
|
|
2705
|
+
void agentId;
|
|
2706
|
+
const recentSenderTypes = messages.flatMap((message) => {
|
|
2707
|
+
const senderType = toHistorySenderType(message);
|
|
2708
|
+
return senderType ? [senderType] : [];
|
|
2709
|
+
});
|
|
2710
|
+
return buildParticipationHistorySnapshotFromSenderTypes(recentSenderTypes);
|
|
2711
|
+
}
|
|
2712
|
+
__name(buildParticipationHistorySnapshot, "buildParticipationHistorySnapshot");
|
|
2713
|
+
function evaluateParticipationPolicy(policy, input) {
|
|
2714
|
+
const resolved = policy ?? resolveAgentBehaviorPolicy({ conversationType: input.conversationType });
|
|
2715
|
+
const participation = resolved.participation;
|
|
2716
|
+
const priorAgentTurns = Math.max(input.consecutiveAgentTurns ?? 0, 0);
|
|
2717
|
+
const agentTurnsWithCurrent = priorAgentTurns + (input.senderType === "ai_agent" ? 1 : 0);
|
|
2718
|
+
const consecutiveAgentTurns = Math.max(
|
|
2719
|
+
priorAgentTurns,
|
|
2720
|
+
input.senderType === "ai_agent" ? 1 : 0
|
|
2721
|
+
);
|
|
2722
|
+
const currentAgentStreakStartedByHuman = input.currentAgentStreakStartedByHuman === true;
|
|
2723
|
+
if (input.conversationType === "group" && participation.requireMentionForGroupReplies && !input.mentionedAgent) {
|
|
2724
|
+
return {
|
|
2725
|
+
allow: false,
|
|
2726
|
+
reasonCode: "group_mention_required",
|
|
2727
|
+
reason: "group replies require a direct mention"
|
|
2728
|
+
};
|
|
2729
|
+
}
|
|
2730
|
+
if (input.isOwner) {
|
|
2731
|
+
return {
|
|
2732
|
+
allow: true,
|
|
2733
|
+
reasonCode: "owner_sender",
|
|
2734
|
+
reason: "owner messages pass through outside mention-required group turns"
|
|
2735
|
+
};
|
|
2736
|
+
}
|
|
2737
|
+
if (input.senderType !== "ai_agent") {
|
|
2738
|
+
return { allow: true, reasonCode: "human_sender", reason: "latest sender is human" };
|
|
2739
|
+
}
|
|
2740
|
+
if (!participation.allowAgentToAgent) {
|
|
2741
|
+
return {
|
|
2742
|
+
allow: false,
|
|
2743
|
+
reasonCode: "agent_to_agent_disabled",
|
|
2744
|
+
reason: "agent-to-agent participation is disabled by policy"
|
|
2745
|
+
};
|
|
2746
|
+
}
|
|
2747
|
+
if (!participation.allowLongRunningCollaboration && (consecutiveAgentTurns > 1 || !currentAgentStreakStartedByHuman)) {
|
|
2748
|
+
return {
|
|
2749
|
+
allow: false,
|
|
2750
|
+
reasonCode: "human_reset_required",
|
|
2751
|
+
reason: "a fresh human steer is required before continuing agent collaboration"
|
|
2752
|
+
};
|
|
2753
|
+
}
|
|
2754
|
+
if (typeof participation.maxConsecutiveAgentTurns === "number" && participation.maxConsecutiveAgentTurns >= 0 && agentTurnsWithCurrent >= participation.maxConsecutiveAgentTurns) {
|
|
2755
|
+
return {
|
|
2756
|
+
allow: false,
|
|
2757
|
+
reasonCode: "agent_turn_limit_reached",
|
|
2758
|
+
reason: "maximum consecutive agent turns reached"
|
|
2759
|
+
};
|
|
2760
|
+
}
|
|
2761
|
+
return {
|
|
2762
|
+
allow: true,
|
|
2763
|
+
reasonCode: input.conversationType === "group" ? "group_agent_allowed" : "direct_agent_allowed",
|
|
2764
|
+
reason: participation.requireMentionForGroupReplies ? "policy allows this directly mentioned group reply" : "agent-to-agent participation allowed by policy"
|
|
2765
|
+
};
|
|
2279
2766
|
}
|
|
2280
|
-
__name(
|
|
2281
|
-
|
|
2282
|
-
// ../backend-contracts/src/turnProtocol.ts
|
|
2283
|
-
var ACTIVE_TURN_STALE_THRESHOLD_MS = 30 * 60 * 1e3;
|
|
2284
|
-
var WAITING_INPUT_STALE_THRESHOLD_MS = 12 * 60 * 60 * 1e3;
|
|
2767
|
+
__name(evaluateParticipationPolicy, "evaluateParticipationPolicy");
|
|
2285
2768
|
|
|
2286
2769
|
// ../backend-contracts/src/agentDirectory.ts
|
|
2287
2770
|
var MAX_DISCOVER_AGENTS_QUERY_LENGTH = 64;
|
|
@@ -3681,9 +4164,9 @@ function splitTurnMetadata(metadata) {
|
|
|
3681
4164
|
};
|
|
3682
4165
|
}
|
|
3683
4166
|
__name(splitTurnMetadata, "splitTurnMetadata");
|
|
3684
|
-
function compact(
|
|
4167
|
+
function compact(record4) {
|
|
3685
4168
|
const out = {};
|
|
3686
|
-
for (const [key, value] of Object.entries(
|
|
4169
|
+
for (const [key, value] of Object.entries(record4)) {
|
|
3687
4170
|
if (value !== void 0) out[key] = value;
|
|
3688
4171
|
}
|
|
3689
4172
|
return out;
|
|
@@ -3864,12 +4347,12 @@ function parseDirectConversationSelection(value) {
|
|
|
3864
4347
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
3865
4348
|
throw new Error("selection must be an object");
|
|
3866
4349
|
}
|
|
3867
|
-
const
|
|
3868
|
-
if (
|
|
3869
|
-
return { mode:
|
|
4350
|
+
const record4 = value;
|
|
4351
|
+
if (record4.mode === "latest_or_new" || record4.mode === "new") {
|
|
4352
|
+
return { mode: record4.mode };
|
|
3870
4353
|
}
|
|
3871
|
-
if (
|
|
3872
|
-
const conversationId = typeof
|
|
4354
|
+
if (record4.mode === "specific") {
|
|
4355
|
+
const conversationId = typeof record4.conversationId === "string" ? record4.conversationId.trim() : "";
|
|
3873
4356
|
if (!conversationId) throw new Error("selection.conversationId is required");
|
|
3874
4357
|
return { mode: "specific", conversationId };
|
|
3875
4358
|
}
|
|
@@ -4063,6 +4546,14 @@ function normalizePublicRuntimeFacts(value) {
|
|
|
4063
4546
|
}
|
|
4064
4547
|
__name(normalizePublicRuntimeFacts, "normalizePublicRuntimeFacts");
|
|
4065
4548
|
|
|
4549
|
+
// ../backend-contracts/src/conversationMembership.ts
|
|
4550
|
+
function resolveConversationPolicyScope(memberIdsOrCount) {
|
|
4551
|
+
const count = Array.isArray(memberIdsOrCount) ? new Set(memberIdsOrCount.filter((id7) => typeof id7 === "string" && id7.length > 0)).size : memberIdsOrCount;
|
|
4552
|
+
if (typeof count !== "number" || !Number.isSafeInteger(count)) return "unknown";
|
|
4553
|
+
return count === 2 ? "direct" : count > 2 ? "group" : "unknown";
|
|
4554
|
+
}
|
|
4555
|
+
__name(resolveConversationPolicyScope, "resolveConversationPolicyScope");
|
|
4556
|
+
|
|
4066
4557
|
// ../backend-contracts/src/endpointContentPolicy.ts
|
|
4067
4558
|
var MLS_DEV_UNSUPPORTED_CONTENT_ACTIONS = ["forward_message"];
|
|
4068
4559
|
var MLS_DEV_DISCLOSED_PROCESSING_FIELDS = {
|
|
@@ -4129,6 +4620,7 @@ var ENDPOINT_CONTENT_FUNCTION_QUERIES = [
|
|
|
4129
4620
|
"mls_group_controls",
|
|
4130
4621
|
"mls_group_admissions",
|
|
4131
4622
|
"mls_interactions",
|
|
4623
|
+
"mls_devices",
|
|
4132
4624
|
"list_artifacts",
|
|
4133
4625
|
"get_artifact_log",
|
|
4134
4626
|
"get_artifact_asset",
|
|
@@ -4283,15 +4775,19 @@ var actionRouting = {
|
|
|
4283
4775
|
create_conversation: ["memberIds.*"],
|
|
4284
4776
|
add_member: ["conversationId", "userId", "agentId"],
|
|
4285
4777
|
remove_member: ["conversationId", "userId", "agentId", "targetUserId"],
|
|
4778
|
+
// A member's role is membership, which Canon sees and enforces in any room (ruling 3).
|
|
4286
4779
|
leave_conversation: ["conversationId"],
|
|
4287
|
-
update_member_role: ["conversationId", "userId", "targetUserId"],
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4780
|
+
update_member_role: ["conversationId", "userId", "targetUserId", "role"],
|
|
4781
|
+
// A room's name, topic and picture are its public details, as in any room: Canon stores and serves them. The picture
|
|
4782
|
+
// names no file: Canon takes its type from `mimeType`.
|
|
4783
|
+
update_conversation: ["conversationId", "name", "topic"],
|
|
4784
|
+
rename_conversation: ["conversationId", "name"],
|
|
4785
|
+
update_topic: ["conversationId", "topic"],
|
|
4786
|
+
update_group_avatar: ["conversationId", "data", "mimeType"],
|
|
4292
4787
|
mark_read: ["conversationId"],
|
|
4293
4788
|
cancel_queued_message: ["conversationId", "messageId"],
|
|
4294
|
-
|
|
4789
|
+
// A person's own settings for a room, muting it or hiding it from their list: Canon applies them, as it decides who gets a push.
|
|
4790
|
+
set_conversation_preferences: ["conversationId", "mutedUntil", "deleted"],
|
|
4295
4791
|
set_block: ["targetUserId"],
|
|
4296
4792
|
save_contact: ["contactUserId"],
|
|
4297
4793
|
remove_contact: ["contactId", "contactUserId"],
|
|
@@ -4323,10 +4819,21 @@ var actionRouting = {
|
|
|
4323
4819
|
consume_runtime_primitive: ["conversationId", "requestId", "expectedRevision"],
|
|
4324
4820
|
generate_image: ["conversationId", "requestId"],
|
|
4325
4821
|
update_agent_behavior_policy: ["agentId"],
|
|
4326
|
-
|
|
4822
|
+
// A room's rules are settings Canon stores and an encrypted room's runner reads back, so they are metadata; its free-text
|
|
4823
|
+
// `instructions` stay private, which keeps them out of an encrypted room (plaintext-retirement.md §5.5).
|
|
4824
|
+
update_conversation_agent_behavior_policy: [
|
|
4825
|
+
"conversationId",
|
|
4826
|
+
"agentId",
|
|
4827
|
+
"policy.participationStyle",
|
|
4828
|
+
"policy.allowAgentToAgent",
|
|
4829
|
+
"policy.allowLongRunningCollaboration",
|
|
4830
|
+
"policy.requireMentionForGroupReplies",
|
|
4831
|
+
"policy.maxConsecutiveAgentTurns"
|
|
4832
|
+
]
|
|
4327
4833
|
};
|
|
4328
4834
|
var queryRouting = {
|
|
4329
4835
|
mls_interactions: ["version", "conversationId"],
|
|
4836
|
+
mls_devices: [],
|
|
4330
4837
|
list_artifacts: ["conversationId", "cursor", "limit"],
|
|
4331
4838
|
get_artifact_log: ["conversationId", "artifactId", "afterSequence", "cursor", "limit"],
|
|
4332
4839
|
get_artifact_asset: ["conversationId", "artifactId", "assetId"],
|
|
@@ -4428,8 +4935,8 @@ function endpointOperationRequestRetention(action, body, envelope) {
|
|
|
4428
4935
|
__name(endpointOperationRequestRetention, "endpointOperationRequestRetention");
|
|
4429
4936
|
function endpointContentBoundary(lane, name, payload) {
|
|
4430
4937
|
if (!namesForLane[lane]?.includes(name)) throw new EndpointContentPolicyError(lane, name);
|
|
4431
|
-
const
|
|
4432
|
-
if (lane === "query.request" && name === "get_ephemeral" &&
|
|
4938
|
+
const record4 = payload && typeof payload === "object" ? payload : void 0;
|
|
4939
|
+
if (lane === "query.request" && name === "get_ephemeral" && record4 && !ENDPOINT_CONTENT_EPHEMERAL_FAMILIES.includes(record4.family)) {
|
|
4433
4940
|
throw new EndpointContentPolicyError(lane, `${name}/unknown-family`);
|
|
4434
4941
|
}
|
|
4435
4942
|
const requestRoutingPaths = (actionRouting[name] ?? []).flatMap((field) => [`body.value.${field}`, `envelope.${field}`]);
|
|
@@ -4437,7 +4944,7 @@ function endpointContentBoundary(lane, name, payload) {
|
|
|
4437
4944
|
if (path.some((part) => secretSegments.has(part))) return "restricted-secret";
|
|
4438
4945
|
if (lane === "operation.request" && ["respond_interaction", "sync_phone_contacts"].includes(name) && matches(path, "preparedContent.payload")) return "restricted-secret";
|
|
4439
4946
|
if (lane === "operation.request" && ["respond_interaction", "sync_phone_contacts"].includes(name) && path[0] === "body" && path[1] === "value" && !publicMatch(path, requestRoutingPaths)) return "restricted-secret";
|
|
4440
|
-
if (lane === "operation.receipt" && path[0] === "result" && (["consume_interaction", "respond_interaction"].includes(name) ||
|
|
4947
|
+
if (lane === "operation.receipt" && path[0] === "result" && (["consume_interaction", "respond_interaction"].includes(name) || record4?.resultReference?.kind === "interaction")) return "restricted-secret";
|
|
4441
4948
|
let selected = payload;
|
|
4442
4949
|
for (const part of path) selected = selected && typeof selected === "object" && Object.hasOwn(selected, part) ? selected[part] : void 0;
|
|
4443
4950
|
if (selected !== null && typeof selected === "object") return "private-content";
|
|
@@ -4446,7 +4953,7 @@ function endpointContentBoundary(lane, name, payload) {
|
|
|
4446
4953
|
if (name === "respond_interaction" && path[0] === "body" && path[1] === "value") return "restricted-secret";
|
|
4447
4954
|
if (name === "sync_phone_contacts" && path[0] === "body" && path[1] === "value") return "restricted-secret";
|
|
4448
4955
|
if (name === "verb_execute") {
|
|
4449
|
-
const wire4 =
|
|
4956
|
+
const wire4 = record4?.body?.value;
|
|
4450
4957
|
const spec = VERB_WIRE_ENVELOPE_FIELDS[wire4?.verb];
|
|
4451
4958
|
if (path[0] === "body" && path[1] === "value") {
|
|
4452
4959
|
if (path.length === 3 && ["wire", "verb"].includes(path[2])) return "public-metadata";
|
|
@@ -4459,7 +4966,7 @@ function endpointContentBoundary(lane, name, payload) {
|
|
|
4459
4966
|
}
|
|
4460
4967
|
} else if (lane === "operation.receipt") {
|
|
4461
4968
|
if (publicMatch(path, [...protocolPaths, "status", "createdAt", "updatedAt", "error.code", "error.status", "error.retryable", "error.retryAfterMs", "resultError.code", "resultError.status", "resultReference.kind", "resultReference.conversationId", "resultReference.artifactId", "resultReference.assetId", "resultReference.uploadId", "resultReference.sessionId", "resultReference.requestId"])) return "public-metadata";
|
|
4462
|
-
if (path[0] === "result" && (name === "consume_interaction" || name === "respond_interaction" ||
|
|
4969
|
+
if (path[0] === "result" && (name === "consume_interaction" || name === "respond_interaction" || record4?.resultReference?.kind === "interaction")) return "restricted-secret";
|
|
4463
4970
|
} else if (lane === "query.request") {
|
|
4464
4971
|
if (publicMatch(path, queryRouting[name] ?? [])) return "public-metadata";
|
|
4465
4972
|
} else if (lane === "query.result" || lane === "ephemeral.result") {
|
|
@@ -4491,10 +4998,10 @@ var PreparedContentError = class extends Error {
|
|
|
4491
4998
|
__name(this, "PreparedContentError");
|
|
4492
4999
|
}
|
|
4493
5000
|
};
|
|
4494
|
-
function
|
|
5001
|
+
function invalid12() {
|
|
4495
5002
|
throw new PreparedContentError("INVALID_PREPARED_CONTENT");
|
|
4496
5003
|
}
|
|
4497
|
-
__name(
|
|
5004
|
+
__name(invalid12, "invalid");
|
|
4498
5005
|
var record2 = /* @__PURE__ */ __name((value) => !!value && typeof value === "object" && !Array.isArray(value), "record");
|
|
4499
5006
|
var keys = /* @__PURE__ */ __name((value, allowed) => Object.keys(value).every((key) => allowed.includes(key)), "keys");
|
|
4500
5007
|
var revision = /* @__PURE__ */ __name((value) => Number.isSafeInteger(value) && value >= 0, "revision");
|
|
@@ -4515,25 +5022,25 @@ function canonicalEndpointJson(value) {
|
|
|
4515
5022
|
}
|
|
4516
5023
|
__name(canonicalEndpointJson, "canonicalEndpointJson");
|
|
4517
5024
|
function validateMetadata(value) {
|
|
4518
|
-
if (!record2(value))
|
|
5025
|
+
if (!record2(value)) invalid12();
|
|
4519
5026
|
if (value.version !== PREPARED_CONTENT_VERSION) throw new PreparedContentError("UNSUPPORTED_PREPARED_CONTENT_VERSION");
|
|
4520
5027
|
if (value.codec !== PREPARED_JSON_CODEC) throw new PreparedContentError("UNSUPPORTED_PREPARED_CONTENT_CODEC");
|
|
4521
|
-
if (!keys(value, ["version", "context", "codec", "payload", "blobs", "expected"]))
|
|
5028
|
+
if (!keys(value, ["version", "context", "codec", "payload", "blobs", "expected"])) invalid12();
|
|
4522
5029
|
const context = value.context;
|
|
4523
|
-
if (!record2(context) || !keys(context, ["action", "conversationId", "messageId"]) || typeof context.action !== "string" || !ENDPOINT_ACTION_PATTERN.test(context.action) || context.conversationId !== void 0 && !identity(context.conversationId) || context.messageId !== void 0 && !identity(context.messageId))
|
|
5030
|
+
if (!record2(context) || !keys(context, ["action", "conversationId", "messageId"]) || typeof context.action !== "string" || !ENDPOINT_ACTION_PATTERN.test(context.action) || context.conversationId !== void 0 && !identity(context.conversationId) || context.messageId !== void 0 && !identity(context.messageId)) invalid12();
|
|
4524
5031
|
const expected = value.expected;
|
|
4525
|
-
if (!record2(expected) || !keys(expected, ["installationGeneration", "protocolRevision", "admission"]) || !revision(expected.installationGeneration) || !revision(expected.protocolRevision))
|
|
5032
|
+
if (!record2(expected) || !keys(expected, ["installationGeneration", "protocolRevision", "admission"]) || !revision(expected.installationGeneration) || !revision(expected.protocolRevision)) invalid12();
|
|
4526
5033
|
if (expected.admission !== void 0) {
|
|
4527
5034
|
const admission = expected.admission;
|
|
4528
|
-
if (!record2(admission) || !keys(admission, ["conversationId", "membershipRevision", "admissionId", "targetAdmissionId"]) || ["conversationId", "admissionId", "targetAdmissionId"].some((key) => admission[key] !== void 0 && !identity(admission[key])) || admission.membershipRevision !== void 0 && !revision(admission.membershipRevision) || context.conversationId !== void 0 && admission.conversationId !== void 0 && admission.conversationId !== context.conversationId)
|
|
5035
|
+
if (!record2(admission) || !keys(admission, ["conversationId", "membershipRevision", "admissionId", "targetAdmissionId"]) || ["conversationId", "admissionId", "targetAdmissionId"].some((key) => admission[key] !== void 0 && !identity(admission[key])) || admission.membershipRevision !== void 0 && !revision(admission.membershipRevision) || context.conversationId !== void 0 && admission.conversationId !== void 0 && admission.conversationId !== context.conversationId) invalid12();
|
|
4529
5036
|
}
|
|
4530
|
-
if (!Array.isArray(value.blobs))
|
|
5037
|
+
if (!Array.isArray(value.blobs)) invalid12();
|
|
4531
5038
|
const ids = /* @__PURE__ */ new Set();
|
|
4532
5039
|
for (const [index, blob] of value.blobs.entries()) {
|
|
4533
|
-
if (!record2(blob) || !keys(blob, ["id", "index"]) || !blobIdentity(blob.id) || blob.index !== index || ids.has(blob.id))
|
|
5040
|
+
if (!record2(blob) || !keys(blob, ["id", "index"]) || !blobIdentity(blob.id) || blob.index !== index || ids.has(blob.id)) invalid12();
|
|
4534
5041
|
ids.add(blob.id);
|
|
4535
5042
|
}
|
|
4536
|
-
if (typeof value.payload !== "string")
|
|
5043
|
+
if (typeof value.payload !== "string") invalid12();
|
|
4537
5044
|
}
|
|
4538
5045
|
__name(validateMetadata, "validateMetadata");
|
|
4539
5046
|
function decodePreparedJsonContent(value) {
|
|
@@ -4542,10 +5049,10 @@ function decodePreparedJsonContent(value) {
|
|
|
4542
5049
|
try {
|
|
4543
5050
|
decoded = JSON.parse(value.payload);
|
|
4544
5051
|
} catch {
|
|
4545
|
-
|
|
5052
|
+
invalid12();
|
|
4546
5053
|
}
|
|
4547
|
-
if (!record2(decoded) || !keys(decoded, ["body", "envelope"]) || !record2(decoded.body) || decoded.envelope !== void 0 && !record2(decoded.envelope))
|
|
4548
|
-
if (canonicalEndpointJson(decoded) !== value.payload)
|
|
5054
|
+
if (!record2(decoded) || !keys(decoded, ["body", "envelope"]) || !record2(decoded.body) || decoded.envelope !== void 0 && !record2(decoded.envelope)) invalid12();
|
|
5055
|
+
if (canonicalEndpointJson(decoded) !== value.payload) invalid12();
|
|
4549
5056
|
const { body, envelope } = decoded;
|
|
4550
5057
|
if (endpointOperationRequestRetention(value.context.action, body, envelope) === "memory") {
|
|
4551
5058
|
throw new PreparedContentError("PREPARED_CONTENT_MEMORY_ONLY");
|
|
@@ -4553,7 +5060,7 @@ function decodePreparedJsonContent(value) {
|
|
|
4553
5060
|
const effective = { ...body, ...envelope };
|
|
4554
5061
|
for (const key of ["conversationId", "messageId"]) {
|
|
4555
5062
|
const bound = value.context[key];
|
|
4556
|
-
if (bound !== void 0 && effective[key] !== void 0 && effective[key] !== bound)
|
|
5063
|
+
if (bound !== void 0 && effective[key] !== void 0 && effective[key] !== bound) invalid12();
|
|
4557
5064
|
}
|
|
4558
5065
|
return envelope === void 0 ? { body } : { body, envelope };
|
|
4559
5066
|
}
|
|
@@ -4583,7 +5090,7 @@ function prepareJsonContent(input) {
|
|
|
4583
5090
|
}
|
|
4584
5091
|
__name(prepareJsonContent, "prepareJsonContent");
|
|
4585
5092
|
function logicalMediaBlobId(conversationId, messageId2, index) {
|
|
4586
|
-
if (!identity(conversationId) || !identity(messageId2) || !revision(index))
|
|
5093
|
+
if (!identity(conversationId) || !identity(messageId2) || !revision(index)) invalid12();
|
|
4587
5094
|
return JSON.stringify([conversationId, messageId2, index]);
|
|
4588
5095
|
}
|
|
4589
5096
|
__name(logicalMediaBlobId, "logicalMediaBlobId");
|
|
@@ -4626,31 +5133,31 @@ var ConnectorRelayRequestError = class extends Error {
|
|
|
4626
5133
|
}
|
|
4627
5134
|
name = "ConnectorRelayRequestError";
|
|
4628
5135
|
};
|
|
4629
|
-
function
|
|
5136
|
+
function invalid13(what) {
|
|
4630
5137
|
throw new ConnectorRelayRequestError(`Invalid relay request: ${what}`);
|
|
4631
5138
|
}
|
|
4632
|
-
__name(
|
|
5139
|
+
__name(invalid13, "invalid");
|
|
4633
5140
|
function record3(value, required, optional = []) {
|
|
4634
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
5141
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) invalid13("expected an object");
|
|
4635
5142
|
const result = value;
|
|
4636
|
-
for (const key of Object.keys(result)) if (!required.includes(key) && !optional.includes(key))
|
|
4637
|
-
for (const key of required) if (!Object.hasOwn(result, key))
|
|
5143
|
+
for (const key of Object.keys(result)) if (!required.includes(key) && !optional.includes(key)) invalid13(`unexpected ${key}`);
|
|
5144
|
+
for (const key of required) if (!Object.hasOwn(result, key)) invalid13(`missing ${key}`);
|
|
4638
5145
|
return result;
|
|
4639
5146
|
}
|
|
4640
5147
|
__name(record3, "record");
|
|
4641
5148
|
function id6(value, what, pattern = ENDPOINT_ID_PATTERN) {
|
|
4642
|
-
if (typeof value !== "string" || !pattern.test(value))
|
|
5149
|
+
if (typeof value !== "string" || !pattern.test(value)) invalid13(what);
|
|
4643
5150
|
return value;
|
|
4644
5151
|
}
|
|
4645
5152
|
__name(id6, "id");
|
|
4646
5153
|
function doc(value, what) {
|
|
4647
|
-
if (typeof value !== "string" || !value || value.length > 200 || value.includes("/"))
|
|
5154
|
+
if (typeof value !== "string" || !value || value.length > 200 || value.includes("/")) invalid13(what);
|
|
4648
5155
|
return value;
|
|
4649
5156
|
}
|
|
4650
5157
|
__name(doc, "doc");
|
|
4651
5158
|
var room = /* @__PURE__ */ __name((value) => doc(value, "conversationId"), "room");
|
|
4652
5159
|
function text4(value) {
|
|
4653
|
-
if (typeof value !== "string" || !value.trim() || new TextEncoder().encode(value).length > CONNECTOR_RELAY_MAX_TEXT_BYTES)
|
|
5160
|
+
if (typeof value !== "string" || !value.trim() || new TextEncoder().encode(value).length > CONNECTOR_RELAY_MAX_TEXT_BYTES) invalid13("text");
|
|
4654
5161
|
return value;
|
|
4655
5162
|
}
|
|
4656
5163
|
__name(text4, "text");
|
|
@@ -4658,18 +5165,18 @@ function selection(value) {
|
|
|
4658
5165
|
const args = record3(value, ["mode"], ["conversationId"]);
|
|
4659
5166
|
if ((args.mode === "new" || args.mode === "latest_or_new") && args.conversationId === void 0) return { mode: args.mode };
|
|
4660
5167
|
if (args.mode === "specific") return { mode: "specific", conversationId: room(args.conversationId) };
|
|
4661
|
-
return
|
|
5168
|
+
return invalid13("selection");
|
|
4662
5169
|
}
|
|
4663
5170
|
__name(selection, "selection");
|
|
4664
5171
|
function limit(value) {
|
|
4665
5172
|
if (value === void 0) return void 0;
|
|
4666
|
-
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1 || value > 100)
|
|
5173
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1 || value > 100) invalid13("limit");
|
|
4667
5174
|
return value;
|
|
4668
5175
|
}
|
|
4669
5176
|
__name(limit, "limit");
|
|
4670
5177
|
function parseConnectorRelayRequest(value) {
|
|
4671
5178
|
const body = record3(value, ["version", "agentId", "grantId", "op", "args"]);
|
|
4672
|
-
if (body.version !== 1)
|
|
5179
|
+
if (body.version !== 1) invalid13("version");
|
|
4673
5180
|
const head = { version: 1, agentId: doc(body.agentId, "agentId"), grantId: id6(body.grantId, "grantId") };
|
|
4674
5181
|
switch (body.op) {
|
|
4675
5182
|
case "pending": {
|
|
@@ -4690,7 +5197,7 @@ function parseConnectorRelayRequest(value) {
|
|
|
4690
5197
|
}
|
|
4691
5198
|
case "settle": {
|
|
4692
5199
|
const args = record3(body.args, ["inputId", "requestId", "outcome"]);
|
|
4693
|
-
if (!["completed", "no_reply", "failed"].includes(args.outcome))
|
|
5200
|
+
if (!["completed", "no_reply", "failed"].includes(args.outcome)) invalid13("outcome");
|
|
4694
5201
|
return { ...head, op: "settle", args: {
|
|
4695
5202
|
inputId: id6(args.inputId, "inputId", CONNECTOR_RELAY_INPUT_ID_PATTERN),
|
|
4696
5203
|
requestId: id6(args.requestId, "requestId"),
|
|
@@ -4699,7 +5206,7 @@ function parseConnectorRelayRequest(value) {
|
|
|
4699
5206
|
}
|
|
4700
5207
|
case "read": {
|
|
4701
5208
|
const args = record3(body.args, ["conversationId"], ["limit", "before"]);
|
|
4702
|
-
if (args.before !== void 0 && (typeof args.before !== "string" || !/^[1-9][0-9]{0,15}$/.test(args.before)))
|
|
5209
|
+
if (args.before !== void 0 && (typeof args.before !== "string" || !/^[1-9][0-9]{0,15}$/.test(args.before))) invalid13("before");
|
|
4703
5210
|
return { ...head, op: "read", args: {
|
|
4704
5211
|
conversationId: room(args.conversationId),
|
|
4705
5212
|
...args.limit === void 0 ? {} : { limit: limit(args.limit) },
|
|
@@ -4721,8 +5228,8 @@ function parseConnectorRelayRequest(value) {
|
|
|
4721
5228
|
}
|
|
4722
5229
|
case "credential": {
|
|
4723
5230
|
const args = record3(body.args, ["installationId", "generation", "credential"]);
|
|
4724
|
-
if (!Number.isSafeInteger(args.generation) || args.generation < 1)
|
|
4725
|
-
if (!isConnectorRelayCredential(args.credential))
|
|
5231
|
+
if (!Number.isSafeInteger(args.generation) || args.generation < 1) invalid13("generation");
|
|
5232
|
+
if (!isConnectorRelayCredential(args.credential)) invalid13("credential");
|
|
4726
5233
|
return { ...head, op: "credential", args: {
|
|
4727
5234
|
installationId: id6(args.installationId, "installationId", CONNECTOR_RELAY_INSTALLATION_PATTERN),
|
|
4728
5235
|
generation: args.generation,
|
|
@@ -4730,7 +5237,7 @@ function parseConnectorRelayRequest(value) {
|
|
|
4730
5237
|
} };
|
|
4731
5238
|
}
|
|
4732
5239
|
default:
|
|
4733
|
-
return
|
|
5240
|
+
return invalid13("op");
|
|
4734
5241
|
}
|
|
4735
5242
|
}
|
|
4736
5243
|
__name(parseConnectorRelayRequest, "parseConnectorRelayRequest");
|
|
@@ -4804,231 +5311,6 @@ var ARTIFACT_LIMITS = Object.freeze({
|
|
|
4804
5311
|
});
|
|
4805
5312
|
var NUMBER_MAX_TEXT = String(ARTIFACT_LIMITS.formNumberMax).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
4806
5313
|
|
|
4807
|
-
// ../backend-contracts/src/mlsDevCredentialReconciliation.ts
|
|
4808
|
-
var MLS_DEV_CREDENTIAL_RECONCILIATION_CHALLENGE_TTL_MS = 3e5;
|
|
4809
|
-
var MLS_DEV_CREDENTIAL_RECONCILIATION_MAX_BYTES = 8192;
|
|
4810
|
-
var MlsDevCredentialReconciliationValidationError = class extends Error {
|
|
4811
|
-
static {
|
|
4812
|
-
__name(this, "MlsDevCredentialReconciliationValidationError");
|
|
4813
|
-
}
|
|
4814
|
-
code = "INVALID_MLS_DEV_CREDENTIAL_RECONCILIATION";
|
|
4815
|
-
constructor() {
|
|
4816
|
-
super("INVALID_MLS_DEV_CREDENTIAL_RECONCILIATION");
|
|
4817
|
-
this.name = "MlsDevCredentialReconciliationValidationError";
|
|
4818
|
-
}
|
|
4819
|
-
};
|
|
4820
|
-
var utf86 = new TextEncoder();
|
|
4821
|
-
var domain2 = utf86.encode("canon.mls.credential-reconciliation-proof.v1\0");
|
|
4822
|
-
function invalid12() {
|
|
4823
|
-
throw new MlsDevCredentialReconciliationValidationError();
|
|
4824
|
-
}
|
|
4825
|
-
__name(invalid12, "invalid");
|
|
4826
|
-
function boundary9(read) {
|
|
4827
|
-
try {
|
|
4828
|
-
return read();
|
|
4829
|
-
} catch {
|
|
4830
|
-
return invalid12();
|
|
4831
|
-
}
|
|
4832
|
-
}
|
|
4833
|
-
__name(boundary9, "boundary");
|
|
4834
|
-
function bounded7(value) {
|
|
4835
|
-
if (utf86.encode(JSON.stringify(value)).length > MLS_DEV_CREDENTIAL_RECONCILIATION_MAX_BYTES) invalid12();
|
|
4836
|
-
return Object.freeze(value);
|
|
4837
|
-
}
|
|
4838
|
-
__name(bounded7, "bounded");
|
|
4839
|
-
function encoded6(value, bytes) {
|
|
4840
|
-
decodeCanonicalMlsBase64Url(value, bytes);
|
|
4841
|
-
return value;
|
|
4842
|
-
}
|
|
4843
|
-
__name(encoded6, "encoded");
|
|
4844
|
-
function parseMlsDevCredentialReconciliationBegin(value) {
|
|
4845
|
-
return boundary9(() => {
|
|
4846
|
-
const input = readMlsDataRecord(value, ["version", "deviceId", "requestId", "expectedCredentialGeneration"]);
|
|
4847
|
-
return bounded7({
|
|
4848
|
-
version: requireMlsLiteral(input.version, 1),
|
|
4849
|
-
deviceId: requireMlsUuid(input.deviceId),
|
|
4850
|
-
requestId: requireMlsUuid(input.requestId),
|
|
4851
|
-
expectedCredentialGeneration: requireMlsInteger(input.expectedCredentialGeneration)
|
|
4852
|
-
});
|
|
4853
|
-
});
|
|
4854
|
-
}
|
|
4855
|
-
__name(parseMlsDevCredentialReconciliationBegin, "parseMlsDevCredentialReconciliationBegin");
|
|
4856
|
-
function parseMlsDevCredentialReconciliationChallenge(value) {
|
|
4857
|
-
return boundary9(() => {
|
|
4858
|
-
const input = readMlsDataRecord(value, [
|
|
4859
|
-
"version",
|
|
4860
|
-
"challengeId",
|
|
4861
|
-
"requestId",
|
|
4862
|
-
"nonce",
|
|
4863
|
-
"device",
|
|
4864
|
-
"expectedCredentialGeneration",
|
|
4865
|
-
"issuedAtMs",
|
|
4866
|
-
"expiresAtMs"
|
|
4867
|
-
]);
|
|
4868
|
-
const device = parseMlsDevEnrollmentResult({ version: 1, authorization: "registration_only", device: input.device }).device;
|
|
4869
|
-
const issuedAtMs = requireMlsInteger(input.issuedAtMs), expiresAtMs = requireMlsInteger(input.expiresAtMs);
|
|
4870
|
-
if (issuedAtMs < device.registeredAtMs || expiresAtMs - issuedAtMs !== MLS_DEV_CREDENTIAL_RECONCILIATION_CHALLENGE_TTL_MS) invalid12();
|
|
4871
|
-
return bounded7({
|
|
4872
|
-
version: requireMlsLiteral(input.version, 1),
|
|
4873
|
-
challengeId: requireMlsUuid(input.challengeId),
|
|
4874
|
-
requestId: requireMlsUuid(input.requestId),
|
|
4875
|
-
nonce: encoded6(input.nonce, 32),
|
|
4876
|
-
device,
|
|
4877
|
-
expectedCredentialGeneration: requireMlsInteger(input.expectedCredentialGeneration),
|
|
4878
|
-
issuedAtMs,
|
|
4879
|
-
expiresAtMs
|
|
4880
|
-
});
|
|
4881
|
-
});
|
|
4882
|
-
}
|
|
4883
|
-
__name(parseMlsDevCredentialReconciliationChallenge, "parseMlsDevCredentialReconciliationChallenge");
|
|
4884
|
-
function parseMlsDevCredentialReconciliationComplete(value) {
|
|
4885
|
-
return boundary9(() => {
|
|
4886
|
-
const input = readMlsDataRecord(value, ["version", "challengeId", "proof"]);
|
|
4887
|
-
return bounded7({ version: requireMlsLiteral(input.version, 1), challengeId: requireMlsUuid(input.challengeId), proof: encoded6(input.proof, 64) });
|
|
4888
|
-
});
|
|
4889
|
-
}
|
|
4890
|
-
__name(parseMlsDevCredentialReconciliationComplete, "parseMlsDevCredentialReconciliationComplete");
|
|
4891
|
-
function parseMlsDevCredentialReconciliationReceipt(value) {
|
|
4892
|
-
return boundary9(() => {
|
|
4893
|
-
const input = readMlsDataRecord(value, ["version", "authorization", "challenge", "observedCredentialGeneration", "observedAtMs"]);
|
|
4894
|
-
const challenge = parseMlsDevCredentialReconciliationChallenge(input.challenge);
|
|
4895
|
-
const observedCredentialGeneration = requireMlsInteger(input.observedCredentialGeneration), observedAtMs = requireMlsInteger(input.observedAtMs);
|
|
4896
|
-
if (observedCredentialGeneration < challenge.expectedCredentialGeneration || observedAtMs < challenge.issuedAtMs || observedAtMs >= challenge.expiresAtMs) invalid12();
|
|
4897
|
-
return bounded7({
|
|
4898
|
-
version: requireMlsLiteral(input.version, 1),
|
|
4899
|
-
authorization: requireMlsLiteral(input.authorization, "credential_generation_observation_only"),
|
|
4900
|
-
challenge,
|
|
4901
|
-
observedCredentialGeneration,
|
|
4902
|
-
observedAtMs
|
|
4903
|
-
});
|
|
4904
|
-
});
|
|
4905
|
-
}
|
|
4906
|
-
__name(parseMlsDevCredentialReconciliationReceipt, "parseMlsDevCredentialReconciliationReceipt");
|
|
4907
|
-
|
|
4908
|
-
// ../backend-contracts/src/mlsDevDeviceCustody.ts
|
|
4909
|
-
var MLS_DEV_DEVICE_CONTEXT_MAX_BYTES = 2048;
|
|
4910
|
-
var MLS_DEV_DEVICE_COMMAND_MAX_BYTES = 16384;
|
|
4911
|
-
var MLS_DEV_DEVICE_WRAPPED_STATE_MAX_BYTES = 6144;
|
|
4912
|
-
var MlsDevDeviceCustodyValidationError = class extends Error {
|
|
4913
|
-
static {
|
|
4914
|
-
__name(this, "MlsDevDeviceCustodyValidationError");
|
|
4915
|
-
}
|
|
4916
|
-
code = "INVALID_MLS_DEV_DEVICE_CUSTODY";
|
|
4917
|
-
constructor() {
|
|
4918
|
-
super("INVALID_MLS_DEV_DEVICE_CUSTODY");
|
|
4919
|
-
this.name = "MlsDevDeviceCustodyValidationError";
|
|
4920
|
-
}
|
|
4921
|
-
};
|
|
4922
|
-
var utf87 = new TextEncoder();
|
|
4923
|
-
function invalid13() {
|
|
4924
|
-
throw new MlsDevDeviceCustodyValidationError();
|
|
4925
|
-
}
|
|
4926
|
-
__name(invalid13, "invalid");
|
|
4927
|
-
function boundary10(read) {
|
|
4928
|
-
try {
|
|
4929
|
-
return read();
|
|
4930
|
-
} catch {
|
|
4931
|
-
return invalid13();
|
|
4932
|
-
}
|
|
4933
|
-
}
|
|
4934
|
-
__name(boundary10, "boundary");
|
|
4935
|
-
function bounded8(value, limit2) {
|
|
4936
|
-
if (utf87.encode(JSON.stringify(value)).length > limit2) invalid13();
|
|
4937
|
-
return Object.freeze(value);
|
|
4938
|
-
}
|
|
4939
|
-
__name(bounded8, "bounded");
|
|
4940
|
-
function binding2(input) {
|
|
4941
|
-
return {
|
|
4942
|
-
version: requireMlsLiteral(input.version, 1),
|
|
4943
|
-
environmentId: requireMlsEnvironmentId(input.environmentId),
|
|
4944
|
-
principal: parseMlsDevEnrollmentPrincipal(input.principal),
|
|
4945
|
-
installationId: parseMlsDevInstallationId(input.installationId)
|
|
4946
|
-
};
|
|
4947
|
-
}
|
|
4948
|
-
__name(binding2, "binding");
|
|
4949
|
-
function parseMlsDevDeviceBinding(value) {
|
|
4950
|
-
return boundary10(() => bounded8(binding2(readMlsDataRecord(value, ["version", "environmentId", "principal", "installationId"])), MLS_DEV_DEVICE_CONTEXT_MAX_BYTES));
|
|
4951
|
-
}
|
|
4952
|
-
__name(parseMlsDevDeviceBinding, "parseMlsDevDeviceBinding");
|
|
4953
|
-
function parseMlsDevDeviceContext(value) {
|
|
4954
|
-
return boundary10(() => {
|
|
4955
|
-
const input = readMlsDataRecord(value, ["version", "environmentId", "principal", "installationId", "revision"]);
|
|
4956
|
-
const revision2 = requireMlsInteger(input.revision);
|
|
4957
|
-
if (revision2 >= Number.MAX_SAFE_INTEGER) invalid13();
|
|
4958
|
-
return bounded8({ ...binding2(input), revision: revision2 }, MLS_DEV_DEVICE_CONTEXT_MAX_BYTES);
|
|
4959
|
-
});
|
|
4960
|
-
}
|
|
4961
|
-
__name(parseMlsDevDeviceContext, "parseMlsDevDeviceContext");
|
|
4962
|
-
function parseMlsDevDeviceCommand(value) {
|
|
4963
|
-
return boundary10(() => {
|
|
4964
|
-
if (value === null || typeof value !== "object") invalid13();
|
|
4965
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, "op");
|
|
4966
|
-
if (!descriptor || !Object.hasOwn(descriptor, "value")) invalid13();
|
|
4967
|
-
if (descriptor.value === "create") {
|
|
4968
|
-
const input2 = readMlsDataRecord(value, ["op"]);
|
|
4969
|
-
return Object.freeze({ op: requireMlsLiteral(input2.op, "create") });
|
|
4970
|
-
}
|
|
4971
|
-
if (descriptor.value === "enrollment_proof") {
|
|
4972
|
-
const input2 = readMlsDataRecord(value, ["op", "challenge"]);
|
|
4973
|
-
return bounded8({
|
|
4974
|
-
op: requireMlsLiteral(input2.op, "enrollment_proof"),
|
|
4975
|
-
challenge: parseMlsDevEnrollmentChallenge(input2.challenge)
|
|
4976
|
-
}, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
|
|
4977
|
-
}
|
|
4978
|
-
if (descriptor.value === "credential_reconciliation_proof") {
|
|
4979
|
-
const input2 = readMlsDataRecord(value, ["op", "challenge", "expectedCredentialGeneration"]);
|
|
4980
|
-
const challenge2 = parseMlsDevCredentialReconciliationChallenge(input2.challenge);
|
|
4981
|
-
const expectedCredentialGeneration2 = requireMlsInteger(input2.expectedCredentialGeneration);
|
|
4982
|
-
if (challenge2.expectedCredentialGeneration !== expectedCredentialGeneration2) invalid13();
|
|
4983
|
-
return bounded8({
|
|
4984
|
-
op: requireMlsLiteral(input2.op, "credential_reconciliation_proof"),
|
|
4985
|
-
challenge: challenge2,
|
|
4986
|
-
expectedCredentialGeneration: expectedCredentialGeneration2
|
|
4987
|
-
}, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
|
|
4988
|
-
}
|
|
4989
|
-
if (descriptor.value !== "credential_proof") invalid13();
|
|
4990
|
-
const input = readMlsDataRecord(value, ["op", "challenge", "registrationResult", "expectedCredentialGeneration"]);
|
|
4991
|
-
const challenge = parseMlsDevCredentialChallenge(input.challenge);
|
|
4992
|
-
const registrationResult = parseMlsDevEnrollmentResult(input.registrationResult);
|
|
4993
|
-
const expectedCredentialGeneration = requireMlsInteger(input.expectedCredentialGeneration);
|
|
4994
|
-
if (expectedCredentialGeneration >= Number.MAX_SAFE_INTEGER || challenge.credential.claims.generation !== expectedCredentialGeneration + 1 || JSON.stringify(challenge.credential.claims.device) !== JSON.stringify(registrationResult.device)) invalid13();
|
|
4995
|
-
return bounded8({
|
|
4996
|
-
op: requireMlsLiteral(input.op, "credential_proof"),
|
|
4997
|
-
challenge,
|
|
4998
|
-
registrationResult,
|
|
4999
|
-
expectedCredentialGeneration
|
|
5000
|
-
}, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
|
|
5001
|
-
});
|
|
5002
|
-
}
|
|
5003
|
-
__name(parseMlsDevDeviceCommand, "parseMlsDevDeviceCommand");
|
|
5004
|
-
function encoded7(value, bytes) {
|
|
5005
|
-
decodeCanonicalMlsBase64Url(value, bytes);
|
|
5006
|
-
return value;
|
|
5007
|
-
}
|
|
5008
|
-
__name(encoded7, "encoded");
|
|
5009
|
-
function wrapped(value) {
|
|
5010
|
-
if (typeof value !== "string" || value.length > MLS_DEV_DEVICE_WRAPPED_STATE_MAX_BYTES || !value.startsWith("v1:")) invalid13();
|
|
5011
|
-
const body = value.slice(3);
|
|
5012
|
-
if (body.length < 40 || body.length % 4 !== 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(body)) invalid13();
|
|
5013
|
-
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
5014
|
-
if (body.endsWith("==") && (alphabet.indexOf(body.at(-3)) & 15) !== 0) invalid13();
|
|
5015
|
-
if (!body.endsWith("==") && body.endsWith("=") && (alphabet.indexOf(body.at(-2)) & 3) !== 0) invalid13();
|
|
5016
|
-
return value;
|
|
5017
|
-
}
|
|
5018
|
-
__name(wrapped, "wrapped");
|
|
5019
|
-
function parseMlsDevDevicePreparation(value, op) {
|
|
5020
|
-
return boundary10(() => {
|
|
5021
|
-
if (!["create", "enrollment_proof", "credential_proof", "credential_reconciliation_proof"].includes(op)) invalid13();
|
|
5022
|
-
const input = readMlsDataRecord(value, ["wrappedState", "payload"]);
|
|
5023
|
-
const payload = readMlsDataRecord(input.payload, op === "create" ? ["signaturePublicKey"] : ["signaturePublicKey", "proof"]);
|
|
5024
|
-
return bounded8({ wrappedState: wrapped(input.wrappedState), payload: Object.freeze({
|
|
5025
|
-
signaturePublicKey: encoded7(payload.signaturePublicKey, 32),
|
|
5026
|
-
...op === "create" ? {} : { proof: encoded7(payload.proof, 64) }
|
|
5027
|
-
}) }, MLS_DEV_DEVICE_COMMAND_MAX_BYTES);
|
|
5028
|
-
});
|
|
5029
|
-
}
|
|
5030
|
-
__name(parseMlsDevDevicePreparation, "parseMlsDevDevicePreparation");
|
|
5031
|
-
|
|
5032
5314
|
// ../backend-contracts/src/mlsDevKeyPackage.ts
|
|
5033
5315
|
var MLS_DEV_KEY_PACKAGE_COMMAND_MAX_BYTES = 16384;
|
|
5034
5316
|
var MLS_DEV_KEY_PACKAGE_WIRE_MAX_BYTES = 16384;
|
|
@@ -5122,7 +5404,7 @@ function parseMlsDevKeyPackagePayload(value) {
|
|
|
5122
5404
|
"expiresAtMs"
|
|
5123
5405
|
]);
|
|
5124
5406
|
const notBeforeMs = requireMlsInteger(input.notBeforeMs), expiresAtMs = requireMlsInteger(input.expiresAtMs);
|
|
5125
|
-
if (notBeforeMs % 1e3 !== 0 || expiresAtMs % 1e3 !== 0 || expiresAtMs <= notBeforeMs || expiresAtMs - notBeforeMs >
|
|
5407
|
+
if (notBeforeMs % 1e3 !== 0 || expiresAtMs % 1e3 !== 0 || expiresAtMs <= notBeforeMs || expiresAtMs - notBeforeMs > MLS_DEV_CREDENTIAL_LONG_TTL_MS) invalid14();
|
|
5126
5408
|
return bounded9({
|
|
5127
5409
|
version: requireMlsLiteral(input.version, 1),
|
|
5128
5410
|
keyPackageId: requireMlsUuid(input.keyPackageId),
|
|
@@ -5218,103 +5500,6 @@ function parseMlsRoomIdentities(value) {
|
|
|
5218
5500
|
}
|
|
5219
5501
|
__name(parseMlsRoomIdentities, "parseMlsRoomIdentities");
|
|
5220
5502
|
|
|
5221
|
-
// ../endpoint/src/runtime-api-origins.generated.ts
|
|
5222
|
-
var RUNTIME_API_ORIGINS = {
|
|
5223
|
-
"canon-dev-v1": "https://dev.api.canonmail.com",
|
|
5224
|
-
"canon-prod-v1": "https://api.canonmail.com"
|
|
5225
|
-
};
|
|
5226
|
-
|
|
5227
|
-
// ../endpoint/src/mls-crypto.ts
|
|
5228
|
-
function mlsDevDeviceHttpConfiguration(environmentId) {
|
|
5229
|
-
if (!isMlsEnvironmentId(environmentId)) invalid16();
|
|
5230
|
-
const origin = RUNTIME_API_ORIGINS[environmentId];
|
|
5231
|
-
return Object.freeze({
|
|
5232
|
-
enrollmentUrl: `${origin}/mls/enrollment`,
|
|
5233
|
-
credentialUrl: `${origin}/mls/credential`,
|
|
5234
|
-
reconciliationUrl: `${origin}/mls/reconciliation`,
|
|
5235
|
-
keyPackagesUrl: `${origin}/mls/key-packages`,
|
|
5236
|
-
trustedOrigins: Object.freeze([origin])
|
|
5237
|
-
});
|
|
5238
|
-
}
|
|
5239
|
-
__name(mlsDevDeviceHttpConfiguration, "mlsDevDeviceHttpConfiguration");
|
|
5240
|
-
function invalid16() {
|
|
5241
|
-
throw new Error("MLS_DEV_CLIENT_CONFIGURATION_INVALID");
|
|
5242
|
-
}
|
|
5243
|
-
__name(invalid16, "invalid");
|
|
5244
|
-
function record4(value, keys2) {
|
|
5245
|
-
if (!value || typeof value !== "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) invalid16();
|
|
5246
|
-
const fields2 = Object.getOwnPropertyDescriptors(value);
|
|
5247
|
-
if (Reflect.ownKeys(fields2).length !== keys2.length || keys2.some((key) => !Object.hasOwn(fields2, key) || !Object.hasOwn(fields2[key], "value"))) invalid16();
|
|
5248
|
-
return value;
|
|
5249
|
-
}
|
|
5250
|
-
__name(record4, "record");
|
|
5251
|
-
function primeOrderPoint(value) {
|
|
5252
|
-
const point = ed25519.Point.fromBytes(value, false);
|
|
5253
|
-
return !point.isSmallOrder() && point.isTorsionFree();
|
|
5254
|
-
}
|
|
5255
|
-
__name(primeOrderPoint, "primeOrderPoint");
|
|
5256
|
-
function issuerKeys(value, environmentId, receipt = false) {
|
|
5257
|
-
if (!Array.isArray(value) || value.length < 1 || value.length > 8) invalid16();
|
|
5258
|
-
const seen = /* @__PURE__ */ new Set();
|
|
5259
|
-
let environment = environmentId;
|
|
5260
|
-
return Object.freeze(Array.from(value, (item2) => {
|
|
5261
|
-
const key = record4(item2, ["keyVersion", "signaturePublicKey"]);
|
|
5262
|
-
const keyVersion = receipt ? parseMlsDevReceiptKeyVersion(key.keyVersion, environment) : parseMlsDevIssuerKeyVersion(key.keyVersion, environment);
|
|
5263
|
-
environment ??= receipt ? mlsEnvironmentOfReceiptKeyVersion(keyVersion) : mlsEnvironmentOfIssuerKeyVersion(keyVersion);
|
|
5264
|
-
if (seen.has(keyVersion) || typeof key.signaturePublicKey !== "string" || !primeOrderPoint(decodeCanonicalMlsBase64Url(key.signaturePublicKey, 32))) invalid16();
|
|
5265
|
-
seen.add(keyVersion);
|
|
5266
|
-
return Object.freeze({ keyVersion, signaturePublicKey: key.signaturePublicKey });
|
|
5267
|
-
}));
|
|
5268
|
-
}
|
|
5269
|
-
__name(issuerKeys, "issuerKeys");
|
|
5270
|
-
function parseMlsDevClientConfiguration(value) {
|
|
5271
|
-
try {
|
|
5272
|
-
const listed = !!value && typeof value === "object" && Object.hasOwn(value, "principalIds");
|
|
5273
|
-
const input = record4(value, ["version", "environmentId", "enabled", ...listed ? ["principalIds"] : [], "issuerKeys", "receiptKeys"]);
|
|
5274
|
-
if (input.version !== 1 || !isMlsEnvironmentId(input.environmentId) || input.enabled !== true || listed && (!Array.isArray(input.principalIds) || input.principalIds.length < 1 || input.principalIds.length > 100)) invalid16();
|
|
5275
|
-
const environmentId = input.environmentId;
|
|
5276
|
-
const principalIds = listed ? Array.from(input.principalIds, (id7) => parseMlsDevEnrollmentPrincipal({ type: "human", id: id7 }).id) : void 0;
|
|
5277
|
-
if (principalIds && new Set(principalIds).size !== principalIds.length) invalid16();
|
|
5278
|
-
return Object.freeze({
|
|
5279
|
-
version: 1,
|
|
5280
|
-
environmentId,
|
|
5281
|
-
enabled: true,
|
|
5282
|
-
...principalIds ? { principalIds: Object.freeze(principalIds) } : {},
|
|
5283
|
-
issuerKeys: issuerKeys(input.issuerKeys, environmentId),
|
|
5284
|
-
receiptKeys: issuerKeys(input.receiptKeys, environmentId, true)
|
|
5285
|
-
});
|
|
5286
|
-
} catch {
|
|
5287
|
-
return invalid16();
|
|
5288
|
-
}
|
|
5289
|
-
}
|
|
5290
|
-
__name(parseMlsDevClientConfiguration, "parseMlsDevClientConfiguration");
|
|
5291
|
-
function createMlsDevCredentialVerifier(options) {
|
|
5292
|
-
let trusted;
|
|
5293
|
-
try {
|
|
5294
|
-
trusted = new Map(issuerKeys(options.issuerKeys).map((key) => [key.keyVersion, key.signaturePublicKey]));
|
|
5295
|
-
} catch {
|
|
5296
|
-
return invalid16();
|
|
5297
|
-
}
|
|
5298
|
-
const clock = options.clock ?? Date.now;
|
|
5299
|
-
return async (value) => {
|
|
5300
|
-
try {
|
|
5301
|
-
const receipt = parseMlsDevCredentialReceipt(value);
|
|
5302
|
-
const parsed = parseMlsDevCredentialToken(receipt.credential);
|
|
5303
|
-
const key = trusted.get(parsed.unsigned.keyVersion);
|
|
5304
|
-
const now = clock();
|
|
5305
|
-
const { issuedAtMs, expiresAtMs } = parsed.unsigned.claims;
|
|
5306
|
-
if (!key || !Number.isSafeInteger(now) || now < issuedAtMs || now >= expiresAtMs) return false;
|
|
5307
|
-
const publicKey = decodeCanonicalMlsBase64Url(key, 32);
|
|
5308
|
-
const signature = decodeCanonicalMlsBase64Url(parsed.signature, 64);
|
|
5309
|
-
if (!primeOrderPoint(publicKey) || !primeOrderPoint(signature.subarray(0, 32))) return false;
|
|
5310
|
-
return ed25519.verify(signature, new TextEncoder().encode(parsed.signingInput), publicKey, { zip215: false });
|
|
5311
|
-
} catch {
|
|
5312
|
-
return false;
|
|
5313
|
-
}
|
|
5314
|
-
};
|
|
5315
|
-
}
|
|
5316
|
-
__name(createMlsDevCredentialVerifier, "createMlsDevCredentialVerifier");
|
|
5317
|
-
|
|
5318
5503
|
export {
|
|
5319
5504
|
__name,
|
|
5320
5505
|
getCanonEnvironmentContract,
|
|
@@ -5328,6 +5513,8 @@ export {
|
|
|
5328
5513
|
isCanonUploadUrl,
|
|
5329
5514
|
resolveAllowedUploadMimeType,
|
|
5330
5515
|
isMlsEnvironmentId,
|
|
5516
|
+
mlsEnvironmentOfIssuerKeyVersion,
|
|
5517
|
+
mlsEnvironmentOfReceiptKeyVersion,
|
|
5331
5518
|
MLS_DEV_ENROLLMENT_MAX_BYTES,
|
|
5332
5519
|
parseMlsDevEnrollmentPrincipal,
|
|
5333
5520
|
parseMlsDevEnrollmentBegin,
|
|
@@ -5335,7 +5522,9 @@ export {
|
|
|
5335
5522
|
parseMlsDevEnrollmentChallenge,
|
|
5336
5523
|
parseMlsDevEnrollmentResult,
|
|
5337
5524
|
encodeCanonicalMlsBase64Url,
|
|
5525
|
+
decodeCanonicalMlsBase64Url,
|
|
5338
5526
|
MLS_DEV_CREDENTIAL_MAX_BYTES,
|
|
5527
|
+
parseMlsDevIssuerKeyVersion,
|
|
5339
5528
|
parseMlsDevCredentialChallenge,
|
|
5340
5529
|
parseMlsDevCredentialBegin,
|
|
5341
5530
|
parseMlsDevCredentialComplete,
|
|
@@ -5344,6 +5533,7 @@ export {
|
|
|
5344
5533
|
createMlsDevCredentialSigningInput,
|
|
5345
5534
|
parseMlsDevCredentialToken,
|
|
5346
5535
|
parseMlsDevCredentialReceipt,
|
|
5536
|
+
parseMlsDevReceiptKeyVersion,
|
|
5347
5537
|
MLS_DEV_GROUP_RECEIPT_CLOCK_SKEW,
|
|
5348
5538
|
isMlsDevReceiptClockSkew,
|
|
5349
5539
|
parseMlsDevGroupFeedEntry,
|
|
@@ -5366,6 +5556,7 @@ export {
|
|
|
5366
5556
|
parseMlsDevGroupHead,
|
|
5367
5557
|
parseMlsDevGroupMarker,
|
|
5368
5558
|
parseMlsDevGroupRoster,
|
|
5559
|
+
mlsAdmissionWait,
|
|
5369
5560
|
parseMlsDevRoomRemoval,
|
|
5370
5561
|
parseMlsDevGroupControl,
|
|
5371
5562
|
parseMlsDevGroupAcceptedControl,
|
|
@@ -5388,8 +5579,10 @@ export {
|
|
|
5388
5579
|
RUNTIME_CARD_LINE_ITEM_COLUMN_TYPES,
|
|
5389
5580
|
readMembershipChangeMetadata,
|
|
5390
5581
|
formatMembershipChangeNotice,
|
|
5582
|
+
PARTICIPATION_HISTORY_FETCH_LIMIT,
|
|
5583
|
+
buildParticipationHistorySnapshot,
|
|
5584
|
+
evaluateParticipationPolicy,
|
|
5391
5585
|
MAX_DISCOVER_AGENTS_QUERY_LENGTH,
|
|
5392
|
-
VERB_LIMITS,
|
|
5393
5586
|
NO_REPLY_ACK_NOTE,
|
|
5394
5587
|
CANON_VERB_WIRE_SCHEMA_VERSION,
|
|
5395
5588
|
projectVerbIntentToWire,
|
|
@@ -5399,6 +5592,7 @@ export {
|
|
|
5399
5592
|
MAX_PUBLIC_RUNTIME_COMMANDS,
|
|
5400
5593
|
normalizePublicRuntimeDescriptor,
|
|
5401
5594
|
normalizePublicRuntimeFacts,
|
|
5595
|
+
resolveConversationPolicyScope,
|
|
5402
5596
|
MLS_DEV_UNSUPPORTED_CONTENT_ACTIONS,
|
|
5403
5597
|
MLS_DEV_DISCLOSED_PROCESSING_FIELDS,
|
|
5404
5598
|
endpointOperationRequestRetention,
|
|
@@ -5442,8 +5636,5 @@ export {
|
|
|
5442
5636
|
isMlsPrincipalAlias,
|
|
5443
5637
|
parseMlsPrincipalOpening,
|
|
5444
5638
|
encodeMlsPrincipalAliasInput,
|
|
5445
|
-
parseMlsRoomIdentities
|
|
5446
|
-
mlsDevDeviceHttpConfiguration,
|
|
5447
|
-
parseMlsDevClientConfiguration,
|
|
5448
|
-
createMlsDevCredentialVerifier
|
|
5639
|
+
parseMlsRoomIdentities
|
|
5449
5640
|
};
|