slybrowser 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/service.d.ts CHANGED
@@ -9,19 +9,10 @@ export interface LicenseAuthorization {
9
9
  }
10
10
  export interface LicenseFileReadOptions {
11
11
  allowInsecureLocalhost?: boolean;
12
- licenseFilePassphrase?: string;
13
12
  licenseFileTrustedKeys?: ReadonlyMap<string, Uint8Array> | Record<string, Uint8Array>;
14
- licenseFileResolutionServiceUrl?: string;
15
13
  trustedServiceUrls?: readonly string[];
16
14
  fetch?: typeof fetch;
17
15
  }
18
- export interface SealedLicenseImportResult {
19
- output: string;
20
- serviceUrl: string;
21
- channel: "stable";
22
- protection: "windows-dpapi-current-user";
23
- licenseKeySha256: string;
24
- }
25
16
  export interface LicensedSessionGrant {
26
17
  sessionId: string;
27
18
  sessionToken: string;
@@ -146,12 +137,10 @@ export interface LicenseServiceClientOptions {
146
137
  licenseTrustedKeys: ReadonlyMap<string, Uint8Array> | Record<string, Uint8Array>;
147
138
  releaseTrustedKeys: ReadonlyMap<string, Uint8Array> | Record<string, Uint8Array>;
148
139
  licenseFileTrustedKeys?: ReadonlyMap<string, Uint8Array> | Record<string, Uint8Array>;
149
- licenseFilePassphrase?: string;
150
140
  trustedServiceUrls?: readonly string[];
151
141
  fetch?: typeof fetch;
152
142
  allowInsecureLocalhost?: boolean;
153
143
  }
154
- export declare function importLicenseFileToSealedAuthorization(inputPath: string, outputPath: string, options?: LicenseFileReadOptions): Promise<SealedLicenseImportResult>;
155
144
  export declare function readLicenseAuthorization(path: string, options?: LicenseFileReadOptions): Promise<LicenseAuthorization>;
156
145
  export declare class LicenseServiceClient {
157
146
  #private;
@@ -200,7 +189,7 @@ export declare class LicenseServiceClient {
200
189
  closeRuntimeSession(grant: RuntimeActivationGrant): Promise<RuntimeHeartbeatGrant>;
201
190
  release(grant: Pick<LicensedSessionGrant, "sessionId" | "sessionToken">): Promise<void>;
202
191
  releaseRuntimeSession(grant: RuntimeSessionGrant | RuntimeActivationGrant): Promise<void>;
203
- downloadArtifact(grant: LicensedSessionGrant): Promise<Response>;
204
- downloadRuntimeArtifact(grant: RuntimeSessionGrant): Promise<Response>;
192
+ downloadArtifact(grant: LicensedSessionGrant, signal?: AbortSignal): Promise<Response>;
193
+ downloadRuntimeArtifact(grant: RuntimeSessionGrant, signal?: AbortSignal): Promise<Response>;
205
194
  }
206
195
  //# sourceMappingURL=service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
package/dist/service.js CHANGED
@@ -1,12 +1,32 @@
1
- import { spawn } from "node:child_process";
2
- import { createDecipheriv, createHash, createPublicKey, randomUUID, scryptSync, verify as verifySignature } from "node:crypto";
3
- import { readFile, writeFile } from "node:fs/promises";
1
+ import { createPublicKey, randomUUID, verify as verifySignature } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
4
3
  import { resolve } from "node:path";
5
4
  import { gunzipSync } from "node:zlib";
6
5
  import { canonicalJson, decodeBase64Url } from "./canonical.js";
7
6
  import { LicenseServiceError } from "./errors.js";
8
7
  import { LicenseVerifier } from "./license.js";
9
8
  import { isSdkCompatible, selectArtifact, verifyReleaseManifest, } from "./manifest.js";
9
+ const CDN_ARTIFACT_ORIGIN = "https://downloads.slybrowser.com";
10
+ const CDN_ARTIFACT_PREFIX = "/github.com/virtualfanc/slybrowser/releases/download/";
11
+ function isCdnArtifactUrl(urlText, artifact, browserVersion) {
12
+ const target = artifact.platform === "windows" ? "win" : artifact.platform === "macos" ? "mac" : "linux";
13
+ const filename = `slybrowser-${browserVersion}-${target}-${artifact.arch}.${artifact.archiveFormat}`;
14
+ let url;
15
+ try {
16
+ url = new URL(urlText);
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ if (url.origin !== CDN_ARTIFACT_ORIGIN || url.username || url.password || url.search || url.hash ||
22
+ !url.pathname.startsWith(CDN_ARTIFACT_PREFIX))
23
+ return false;
24
+ const remainder = url.pathname.slice(CDN_ARTIFACT_PREFIX.length);
25
+ const tag = remainder.slice(0, remainder.indexOf("/"));
26
+ return /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(tag) &&
27
+ remainder === `${tag}/${filename}` &&
28
+ urlText === `${CDN_ARTIFACT_ORIGIN}${url.pathname}`;
29
+ }
10
30
  function fail(code, message, status = 0, details = {}) {
11
31
  throw new LicenseServiceError(message, code, status, details);
12
32
  }
@@ -107,21 +127,6 @@ const LICENSE_FILE_TOP_LEVEL_FIELDS = new Set([
107
127
  "tag",
108
128
  "signature",
109
129
  ]);
110
- const LICENSE_FILE_SECRET_FIELDS = new Set([
111
- "schemaVersion",
112
- "type",
113
- "audience",
114
- "licenseId",
115
- "fileId",
116
- "serviceUrl",
117
- "channel",
118
- "licenseKey",
119
- "secretVersion",
120
- "createdAt",
121
- "expiresAt",
122
- "nonce",
123
- "scope",
124
- ]);
125
130
  const USER_LICENSE_FILE_FORMAT = "slybrowser-license-compact-v1";
126
131
  const USER_LICENSE_FILE_FIELDS = new Set(["schemaVersion", "type", "format", "license"]);
127
132
  const USER_LICENSE_FILE_MAX_COMPRESSED_BYTES = 64 * 1024;
@@ -214,7 +219,7 @@ function trustedKeyMap(keys) {
214
219
  const entries = keys instanceof Map ? keys.entries() : Object.entries(keys ?? {});
215
220
  return new Map([...entries].map(([key, value]) => [key, Buffer.from(value)]));
216
221
  }
217
- function parseEncryptedLicenseFile(value, options) {
222
+ function validateEncryptedLicenseFile(value, options) {
218
223
  const document = requiredObject(unwrapUserLicenseFile(value));
219
224
  if (Object.keys(document).some((name) => !LICENSE_FILE_TOP_LEVEL_FIELDS.has(name)) ||
220
225
  Object.keys(document).length !== LICENSE_FILE_TOP_LEVEL_FIELDS.size ||
@@ -266,70 +271,16 @@ function parseEncryptedLicenseFile(value, options) {
266
271
  const verified = verifySignature(null, signedBody, createPublicKey({ key: Buffer.concat([ED25519_SPKI_PREFIX, publicKey]), format: "der", type: "spki" }), decodeBase64Url(requiredText(signature, "signature", 256), 64));
267
272
  if (!verified)
268
273
  fail("license_file_signature_invalid", "License file signature is invalid", 401);
269
- const passphrase = options.licenseFilePassphrase;
270
- if (typeof passphrase !== "string" || passphrase.length < 12) {
271
- fail("license_file_locked", "License file passphrase is missing or too short", 401);
272
- }
273
- const salt = decodeBase64Url(requiredText(kdf, "salt", 64), 16);
274
- if (salt.length !== 16)
275
- fail("authorization_invalid", "License file salt length is invalid");
276
- const nonce = decodeBase64Url(requiredText(encryption, "nonce", 64), 12);
277
- if (nonce.length !== 12)
278
- fail("authorization_invalid", "License file nonce length is invalid");
279
- const decipher = createDecipheriv("aes-256-gcm", scryptSync(passphrase, salt, 32, { N: 16_384, r: 8, p: 1, maxmem: 64 * 1024 * 1024 }), nonce);
280
- decipher.setAAD(canonicalJson(publicLicenseFileHeader({ ...document, serviceUrl })));
281
- decipher.setAuthTag(decodeBase64Url(requiredText(document, "tag", 64), 16));
282
- let payload;
283
- try {
284
- const plaintext = Buffer.concat([
285
- decipher.update(decodeBase64Url(requiredText(document, "ciphertext", 64 * 1024), 64 * 1024)),
286
- decipher.final(),
287
- ]);
288
- payload = requiredObject(JSON.parse(plaintext.toString("utf8")));
289
- }
290
- catch (error) {
291
- if (error instanceof LicenseServiceError)
292
- throw error;
293
- fail("license_file_locked", "License file cannot be decrypted", 401);
294
- }
295
- if (Object.keys(payload).some((name) => !LICENSE_FILE_SECRET_FIELDS.has(name)) ||
296
- Object.keys(payload).length !== LICENSE_FILE_SECRET_FIELDS.size) {
297
- fail("license_file_payload_invalid", "License file payload contains unsupported claims");
298
- }
299
- const licenseKey = requiredText(payload, "licenseKey", 256);
300
- if (payload.schemaVersion !== 2 ||
301
- payload.type !== "slybrowser-license-secret" ||
302
- payload.audience !== document.audience ||
303
- payload.licenseId !== licenseId ||
304
- payload.fileId !== document.fileId ||
305
- normalizeServiceUrl(requiredText(payload, "serviceUrl"), options.allowInsecureLocalhost ?? false) !== serviceUrl ||
306
- payload.channel !== "stable" ||
307
- payload.secretVersion !== 1 ||
308
- payload.expiresAt !== document.expiresAt ||
309
- payload.scope !== expectedScope ||
310
- !/^sly_live_[0-9a-f-]{36}\.[A-Za-z0-9_-]{40,}$/.test(licenseKey) ||
311
- !licenseKey.startsWith(`sly_live_${licenseId}.`)) {
312
- fail("license_file_payload_invalid", "License file payload does not match its public header");
313
- }
314
- return { schemaVersion: 1, serviceUrl, licenseKey, channel: "stable" };
315
- }
316
- function localLicenseFileUnlockRequested(options) {
317
- return options.licenseFilePassphrase !== undefined;
274
+ return { serviceUrl, licenseId };
318
275
  }
319
276
  async function resolveEncryptedLicenseFileViaService(value, options) {
320
- const document = requiredObject(unwrapUserLicenseFile(value));
321
- if (document.schemaVersion !== 2 || document.type !== "slybrowser-license" ||
322
- document.audience !== "slybrowser-license-file" || document.channel !== "stable") {
323
- fail("authorization_invalid", "License file fields are invalid");
324
- }
325
- const documentServiceUrl = normalizeServiceUrl(requiredText(document, "serviceUrl"), options.allowInsecureLocalhost ?? false);
326
- assertTrustedAuthorizationOrigin(documentServiceUrl, options);
327
- const resolutionServiceUrl = normalizeServiceUrl(options.licenseFileResolutionServiceUrl ?? documentServiceUrl, options.allowInsecureLocalhost ?? false);
277
+ const { serviceUrl: documentServiceUrl, licenseId } = validateEncryptedLicenseFile(value, options);
328
278
  const fetchImplementation = options.fetch ?? fetch;
329
279
  let response;
330
280
  try {
331
- response = await fetchImplementation(`${resolutionServiceUrl}/v1/license-files/authorization`, {
281
+ response = await fetchImplementation(`${documentServiceUrl}/v1/license-files/authorization`, {
332
282
  method: "POST",
283
+ redirect: "error",
333
284
  headers: {
334
285
  "content-type": "application/json",
335
286
  "user-agent": "SlyBrowserNodeSDK/license-file",
@@ -362,205 +313,12 @@ async function resolveEncryptedLicenseFileViaService(value, options) {
362
313
  throw new LicenseServiceError(message, code, response.status, details);
363
314
  }
364
315
  const authorization = parseAuthorization(parsed, options.allowInsecureLocalhost ?? false);
365
- if (authorization.serviceUrl !== documentServiceUrl) {
366
- fail("license_service_invalid_response", "License-file authorization service URL does not match the license file", response.status);
367
- }
368
- return authorization;
369
- }
370
- const SEALED_LICENSE_TOP_LEVEL_FIELDS = new Set([
371
- "schemaVersion",
372
- "type",
373
- "audience",
374
- "serviceUrl",
375
- "channel",
376
- "sealedAt",
377
- "licenseKeySha256",
378
- "protection",
379
- "ciphertext",
380
- ]);
381
- function licenseKeySha256(licenseKey) {
382
- return createHash("sha256").update(licenseKey, "utf8").digest("hex");
383
- }
384
- function sealedLicenseEntropy(document) {
385
- return [
386
- "slybrowser-sealed-license-v1",
387
- requiredText(document, "serviceUrl", 2048),
388
- requiredText(document, "channel", 16),
389
- requiredText(document, "licenseKeySha256", 64),
390
- ].join("\0");
391
- }
392
- function assertTrustedAuthorizationOrigin(serviceUrl, options) {
393
- const trustedServiceUrls = (options.trustedServiceUrls ?? ["https://api.slybrowser.com"])
394
- .map((url) => normalizeServiceUrl(url, options.allowInsecureLocalhost ?? false));
395
- if (!trustedServiceUrls.includes(serviceUrl)) {
396
- fail("license_file_untrusted_origin", "License file service URL is not trusted", 403);
397
- }
398
- }
399
- async function windowsDpapi(operation, data, entropy) {
400
- if (process.platform !== "win32") {
401
- fail("sealed_license_unsupported", "Windows DPAPI sealed license files are only supported on Windows", 400);
402
- }
403
- const script = `
404
- $ErrorActionPreference = 'Stop'
405
- [System.Reflection.Assembly]::LoadWithPartialName('System.Security') | Out-Null
406
- $request = [Console]::In.ReadToEnd() | ConvertFrom-Json
407
- $data = [Convert]::FromBase64String([string]$request.data)
408
- $entropy = [Convert]::FromBase64String([string]$request.entropy)
409
- $scope = [System.Security.Cryptography.DataProtectionScope]::CurrentUser
410
- if ([string]$request.operation -eq 'protect') {
411
- $output = [System.Security.Cryptography.ProtectedData]::Protect($data, $entropy, $scope)
412
- } elseif ([string]$request.operation -eq 'unprotect') {
413
- $output = [System.Security.Cryptography.ProtectedData]::Unprotect($data, $entropy, $scope)
414
- } else {
415
- throw 'Unsupported DPAPI operation'
416
- }
417
- [Console]::Out.Write([Convert]::ToBase64String($output))
418
- `;
419
- const encodedCommand = Buffer.from(script, "utf16le").toString("base64");
420
- const request = JSON.stringify({
421
- operation,
422
- data: data.toString("base64"),
423
- entropy: Buffer.from(entropy, "utf8").toString("base64"),
424
- });
425
- return await new Promise((resolvePromise, reject) => {
426
- const child = spawn("powershell.exe", [
427
- "-NoLogo",
428
- "-NoProfile",
429
- "-NonInteractive",
430
- "-ExecutionPolicy",
431
- "Bypass",
432
- "-EncodedCommand",
433
- encodedCommand,
434
- ], { stdio: ["pipe", "pipe", "pipe"], windowsHide: true });
435
- const stdout = [];
436
- const stderr = [];
437
- let settled = false;
438
- const rejectOnce = (error) => {
439
- if (settled)
440
- return;
441
- settled = true;
442
- reject(error);
443
- };
444
- child.stdout.on("data", (chunk) => {
445
- stdout.push(chunk);
446
- if (Buffer.concat(stdout).length > 16 * 1024) {
447
- child.kill();
448
- rejectOnce(new LicenseServiceError("Windows DPAPI returned an oversized response", "sealed_license_invalid", 400));
449
- }
450
- });
451
- child.stderr.on("data", (chunk) => {
452
- stderr.push(chunk);
453
- if (Buffer.concat(stderr).length > 8 * 1024)
454
- child.kill();
455
- });
456
- child.on("error", () => {
457
- rejectOnce(new LicenseServiceError("Windows DPAPI is unavailable", "sealed_license_unsupported", 400));
458
- });
459
- child.on("close", (code) => {
460
- if (settled)
461
- return;
462
- settled = true;
463
- if (code !== 0) {
464
- reject(new LicenseServiceError("Sealed license file cannot be decrypted on this Windows user or machine", "sealed_license_locked", 401));
465
- return;
466
- }
467
- try {
468
- resolvePromise(Buffer.from(Buffer.concat(stdout).toString("utf8").trim(), "base64"));
469
- }
470
- catch {
471
- reject(new LicenseServiceError("Windows DPAPI returned an invalid sealed license response", "sealed_license_invalid", 400));
472
- }
473
- });
474
- child.stdin.end(request);
475
- });
476
- }
477
- async function parseSealedLicenseFile(value, options) {
478
- const document = requiredObject(value);
479
- if (Object.keys(document).some((name) => !SEALED_LICENSE_TOP_LEVEL_FIELDS.has(name)) ||
480
- Object.keys(document).length !== SEALED_LICENSE_TOP_LEVEL_FIELDS.size ||
481
- document.schemaVersion !== 3 ||
482
- document.type !== "slybrowser-sealed-authorization" ||
483
- document.audience !== "slybrowser") {
484
- fail("sealed_license_invalid", "Sealed license file fields are invalid");
485
- }
486
- const serviceUrl = normalizeServiceUrl(requiredText(document, "serviceUrl"), options.allowInsecureLocalhost ?? false);
487
- assertTrustedAuthorizationOrigin(serviceUrl, options);
488
- if (requiredText(document, "channel", 16) !== "stable")
489
- fail("sealed_license_invalid", "Sealed license channel is invalid");
490
- const sealedAt = Date.parse(requiredText(document, "sealedAt", 64));
491
- if (!Number.isFinite(sealedAt))
492
- fail("sealed_license_invalid", "Sealed license timestamp is invalid");
493
- const sha256 = requiredText(document, "licenseKeySha256", 64);
494
- if (!/^[0-9a-f]{64}$/.test(sha256))
495
- fail("sealed_license_invalid", "Sealed license fingerprint is invalid");
496
- const protection = requiredObject(document.protection);
497
- if (Object.keys(protection).sort().join(",") !== "provider,scope" ||
498
- protection.provider !== "windows-dpapi" ||
499
- protection.scope !== "current-user") {
500
- fail("sealed_license_unsupported", "Sealed license protection is not supported", 400);
501
- }
502
- const ciphertext = decodeBase64Url(requiredText(document, "ciphertext", 64 * 1024), 64 * 1024);
503
- let parsed;
504
- try {
505
- const plaintext = await windowsDpapi("unprotect", ciphertext, sealedLicenseEntropy({ ...document, serviceUrl }));
506
- parsed = JSON.parse(plaintext.toString("utf8"));
507
- }
508
- catch (error) {
509
- if (error instanceof LicenseServiceError)
510
- throw error;
511
- fail("sealed_license_locked", "Sealed license file cannot be decrypted on this Windows user or machine", 401);
512
- }
513
- const authorization = parseAuthorization(parsed, options.allowInsecureLocalhost ?? false);
514
- if (authorization.serviceUrl !== serviceUrl || authorization.channel !== "stable" ||
515
- licenseKeySha256(authorization.licenseKey) !== sha256) {
516
- fail("sealed_license_mismatch", "Sealed license payload does not match its public header", 400);
316
+ if (authorization.serviceUrl !== documentServiceUrl ||
317
+ !authorization.licenseKey.startsWith(`sly_live_${licenseId}.`)) {
318
+ fail("license_service_invalid_response", "License-file authorization does not match the signed file", response.status);
517
319
  }
518
320
  return authorization;
519
321
  }
520
- export async function importLicenseFileToSealedAuthorization(inputPath, outputPath, options = {}) {
521
- const raw = await readFile(resolve(inputPath));
522
- if (raw.length > 64 * 1024)
523
- fail("authorization_invalid", "Authorization file is too large");
524
- let parsed;
525
- try {
526
- parsed = JSON.parse(raw.toString("utf8"));
527
- }
528
- catch {
529
- fail("authorization_invalid", "Authorization file is not valid JSON");
530
- }
531
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.schemaVersion !== 2) {
532
- fail("license_file_invalid", "Only encrypted v2 SlyBrowser license files can be imported", 400);
533
- }
534
- const authorization = parseEncryptedLicenseFile(parsed, options);
535
- assertTrustedAuthorizationOrigin(authorization.serviceUrl, options);
536
- const fingerprint = licenseKeySha256(authorization.licenseKey);
537
- const sealedAt = new Date().toISOString();
538
- const document = {
539
- schemaVersion: 3,
540
- type: "slybrowser-sealed-authorization",
541
- audience: "slybrowser",
542
- serviceUrl: authorization.serviceUrl,
543
- channel: authorization.channel,
544
- sealedAt,
545
- licenseKeySha256: fingerprint,
546
- protection: {
547
- provider: "windows-dpapi",
548
- scope: "current-user",
549
- },
550
- ciphertext: "",
551
- };
552
- const ciphertext = await windowsDpapi("protect", Buffer.from(JSON.stringify(authorization), "utf8"), sealedLicenseEntropy(document));
553
- document.ciphertext = ciphertext.toString("base64url");
554
- const output = resolve(outputPath);
555
- await writeFile(output, `${JSON.stringify(document, null, 2)}\n`, { flag: "wx", mode: 0o600 });
556
- return {
557
- output,
558
- serviceUrl: authorization.serviceUrl,
559
- channel: "stable",
560
- protection: "windows-dpapi-current-user",
561
- licenseKeySha256: fingerprint,
562
- };
563
- }
564
322
  export async function readLicenseAuthorization(path, options = {}) {
565
323
  const raw = await readFile(resolve(path));
566
324
  if (raw.length > 64 * 1024)
@@ -578,14 +336,7 @@ export async function readLicenseAuthorization(path, options = {}) {
578
336
  : parsed;
579
337
  if (document && typeof document === "object" && !Array.isArray(document) &&
580
338
  document.schemaVersion === 2) {
581
- if (!localLicenseFileUnlockRequested(options)) {
582
- return await resolveEncryptedLicenseFileViaService(parsed, options);
583
- }
584
- return parseEncryptedLicenseFile(parsed, options);
585
- }
586
- if (document && typeof document === "object" && !Array.isArray(document) &&
587
- document.schemaVersion === 3) {
588
- return await parseSealedLicenseFile(parsed, options);
339
+ return await resolveEncryptedLicenseFileViaService(parsed, options);
589
340
  }
590
341
  return parseAuthorization(parsed, options.allowInsecureLocalhost ?? false);
591
342
  }
@@ -708,7 +459,7 @@ export class LicenseServiceClient {
708
459
  async licenseInfo(options = {}) {
709
460
  const platform = options.platform ?? currentPlatform();
710
461
  const arch = options.arch ?? currentArch();
711
- const sdkVersion = options.sdkVersion ?? "0.2.0";
462
+ const sdkVersion = options.sdkVersion ?? "0.3.1";
712
463
  const versionPolicy = options.versionPolicy ?? (options.browserVersion === undefined ? "latest" : "exact");
713
464
  if (versionPolicy === "latest" && options.browserVersion !== undefined) {
714
465
  fail("version_policy_invalid", "Latest selection cannot include a requested browser version");
@@ -814,7 +565,7 @@ export class LicenseServiceClient {
814
565
  async createSession(options = {}) {
815
566
  const platform = options.platform ?? currentPlatform();
816
567
  const arch = options.arch ?? currentArch();
817
- const sdkVersion = options.sdkVersion ?? "0.2.0";
568
+ const sdkVersion = options.sdkVersion ?? "0.3.1";
818
569
  const versionPolicy = options.versionPolicy ?? (options.browserVersion === undefined ? "latest" : "exact");
819
570
  if (versionPolicy === "latest" && options.browserVersion !== undefined) {
820
571
  fail("version_policy_invalid", "Latest selection cannot include a requested browser version");
@@ -899,8 +650,8 @@ export class LicenseServiceClient {
899
650
  }
900
651
  const artifact = selectArtifact(manifest, platform, arch);
901
652
  const serviceOrigin = new URL(this.authorization.serviceUrl).origin;
902
- if (new URL(artifact.url).origin !== serviceOrigin) {
903
- fail("artifact_origin_invalid", "Authorized artifacts must be served by the license service origin");
653
+ if (new URL(artifact.url).origin !== serviceOrigin && !isCdnArtifactUrl(artifact.url, artifact, browserVersion)) {
654
+ fail("artifact_origin_invalid", "Authorized artifact origin or CDN path is invalid");
904
655
  }
905
656
  const plan = value.plan;
906
657
  if (!new Set(["free", "basic", "pro", "max", "ultra"]).has(String(plan)) ||
@@ -940,7 +691,7 @@ export class LicenseServiceClient {
940
691
  async createRuntimeSession(options = {}) {
941
692
  const platform = options.platform ?? currentPlatform();
942
693
  const arch = options.arch ?? currentArch();
943
- const sdkVersion = options.sdkVersion ?? "0.2.0";
694
+ const sdkVersion = options.sdkVersion ?? "0.3.1";
944
695
  const startupId = options.startupId ?? newStartupId();
945
696
  if (!/^st_[A-Za-z0-9_-]{16,120}$/.test(startupId)) {
946
697
  fail("startup_id_invalid", "Runtime startup ID is invalid");
@@ -1043,8 +794,8 @@ export class LicenseServiceClient {
1043
794
  }
1044
795
  const artifact = selectArtifact(manifest, platform, arch);
1045
796
  const serviceOrigin = new URL(this.authorization.serviceUrl).origin;
1046
- if (new URL(artifact.url).origin !== serviceOrigin) {
1047
- fail("artifact_origin_invalid", "Authorized artifacts must be served by the license service origin");
797
+ if (new URL(artifact.url).origin !== serviceOrigin && !isCdnArtifactUrl(artifact.url, artifact, browserVersion)) {
798
+ fail("artifact_origin_invalid", "Authorized artifact origin or CDN path is invalid");
1048
799
  }
1049
800
  const ticket = value.downloadTicket;
1050
801
  const artifactUrl = String(ticket?.artifactUrl ?? "");
@@ -1052,7 +803,8 @@ export class LicenseServiceClient {
1052
803
  if (!ticket || typeof ticket.token !== "string" || !ticket.token ||
1053
804
  !Number.isSafeInteger(ticket.expiresAt) || ticket.expiresAt !== value.expiresAt ||
1054
805
  artifactSha256 !== artifact.sha256 || !artifactUrl ||
1055
- new URL(artifactUrl).origin !== serviceOrigin) {
806
+ (new URL(artifactUrl).origin !== serviceOrigin &&
807
+ !(artifactUrl === artifact.url && isCdnArtifactUrl(artifact.url, artifact, browserVersion)))) {
1056
808
  fail("license_service_invalid_response", "Runtime download ticket response is invalid");
1057
809
  }
1058
810
  const plan = value.plan;
@@ -1170,18 +922,52 @@ export class LicenseServiceClient {
1170
922
  authorization: `Bootstrap ${grant.bootstrapToken}`,
1171
923
  });
1172
924
  }
1173
- async downloadArtifact(grant) {
1174
- const response = await this.#fetch(grant.artifact.url, {
925
+ async downloadArtifact(grant, signal) {
926
+ let artifactUrl;
927
+ try {
928
+ artifactUrl = new URL(grant.artifact.url);
929
+ }
930
+ catch {
931
+ fail("license_service_invalid_response", "Artifact URL is invalid");
932
+ }
933
+ const cdn = isCdnArtifactUrl(grant.artifact.url, grant.artifact, grant.browserVersion);
934
+ if (!cdn && artifactUrl.origin !== new URL(this.authorization.serviceUrl).origin) {
935
+ fail("artifact_origin_invalid", "Authorized artifact origin or CDN path is invalid");
936
+ }
937
+ const response = await this.#fetch(artifactUrl.toString(), {
1175
938
  method: "GET",
1176
- headers: { authorization: `Session ${grant.sessionToken}` },
939
+ headers: cdn ? {} : { authorization: `Session ${grant.sessionToken}` },
1177
940
  redirect: "error",
941
+ ...(signal === undefined ? {} : { signal }),
1178
942
  });
1179
943
  if (!response.ok || !response.body)
1180
944
  await this.#throwResponse(response);
1181
945
  return response;
1182
946
  }
1183
- async downloadRuntimeArtifact(grant) {
1184
- const artifactUrl = new URL(grant.downloadTicket.artifactUrl);
947
+ async downloadRuntimeArtifact(grant, signal) {
948
+ let artifactUrl;
949
+ try {
950
+ artifactUrl = new URL(grant.downloadTicket.artifactUrl);
951
+ }
952
+ catch {
953
+ fail("license_service_invalid_response", "Runtime artifact URL is invalid");
954
+ }
955
+ const cdn = grant.downloadTicket.artifactUrl === grant.artifact.url &&
956
+ isCdnArtifactUrl(grant.artifact.url, grant.artifact, grant.browserVersion);
957
+ if (cdn) {
958
+ const response = await this.#fetch(artifactUrl.toString(), {
959
+ method: "GET",
960
+ headers: {},
961
+ redirect: "error",
962
+ ...(signal === undefined ? {} : { signal }),
963
+ });
964
+ if (!response.ok || !response.body)
965
+ await this.#throwResponse(response);
966
+ return response;
967
+ }
968
+ if (artifactUrl.origin !== new URL(this.authorization.serviceUrl).origin) {
969
+ fail("artifact_origin_invalid", "Runtime artifact origin is invalid");
970
+ }
1185
971
  if (artifactUrl.pathname.startsWith("/v1/releases/artifacts/")) {
1186
972
  artifactUrl.pathname = artifactUrl.pathname.replace("/v1/releases/artifacts/", "/v2/runtime/artifacts/");
1187
973
  }
@@ -1192,6 +978,7 @@ export class LicenseServiceClient {
1192
978
  method: "GET",
1193
979
  headers: { authorization: `Download ${grant.downloadTicket.token}` },
1194
980
  redirect: "error",
981
+ ...(signal === undefined ? {} : { signal }),
1195
982
  });
1196
983
  if (!response.ok || !response.body)
1197
984
  await this.#throwResponse(response);