casualos 3.9.0-alpha.19838926610 → 3.9.0-alpha.20044586852

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +756 -188
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -90229,6 +90229,7 @@ var WEB_CONFIG_SCHEMA = external_exports.object({
90229
90229
  staticRepoLocalPersistence: external_exports.boolean().prefault(true),
90230
90230
  sharedPartitionsVersion: external_exports.enum(["v2"]).prefault("v2"),
90231
90231
  vmOrigin: external_exports.string().min(1).max(128).nullable().optional(),
90232
+ disableVM: external_exports.boolean().nullable().optional(),
90232
90233
  authOrigin: external_exports.string().min(1).max(128).nullable().optional(),
90233
90234
  recordsOrigin: external_exports.string().min(1).max(128).nullable().optional(),
90234
90235
  disableCollaboration: external_exports.boolean().nullable().optional(),
@@ -100506,10 +100507,11 @@ var ProcBuilder = class {
100506
100507
  this._allowedOrigins = allowedOrigins;
100507
100508
  return this;
100508
100509
  }
100509
- http(method, path6) {
100510
+ http(method, path6, scope) {
100510
100511
  this._http = {
100511
100512
  method,
100512
- path: path6
100513
+ path: path6,
100514
+ scope
100513
100515
  };
100514
100516
  return this;
100515
100517
  }
@@ -100562,7 +100564,7 @@ function getSchemaMetadata(schema) {
100562
100564
  return { type: "boolean", description: getDescription(schema) };
100563
100565
  } else if (schema instanceof $ZodNumber) {
100564
100566
  return { type: "number", description: getDescription(schema) };
100565
- } else if (schema instanceof $ZodAny) {
100567
+ } else if (schema instanceof $ZodAny || schema instanceof $ZodUnknown) {
100566
100568
  return { type: "any", description: getDescription(schema) };
100567
100569
  } else if (schema instanceof $ZodNull) {
100568
100570
  return { type: "null", description: getDescription(schema) };
@@ -102057,7 +102059,7 @@ var trace = TraceAPI.getInstance();
102057
102059
  function hashLowEntropyPasswordWithSalt2(password, salt) {
102058
102060
  const tracer = trace.getTracer(
102059
102061
  "InstrumentedHashHelpers",
102060
- false ? void 0 : "v3.9.0-alpha.19838926610"
102062
+ false ? void 0 : "v3.9.0-alpha.20044586852"
102061
102063
  );
102062
102064
  return tracer.startActiveSpan(
102063
102065
  "hashLowEntropyPasswordWithSalt",
@@ -102075,7 +102077,7 @@ function hashLowEntropyPasswordWithSalt2(password, salt) {
102075
102077
  function hashHighEntropyPasswordWithSalt2(password, salt) {
102076
102078
  const tracer = trace.getTracer(
102077
102079
  "InstrumentedHashHelpers",
102078
- false ? void 0 : "v3.9.0-alpha.19838926610"
102080
+ false ? void 0 : "v3.9.0-alpha.20044586852"
102079
102081
  );
102080
102082
  return tracer.startActiveSpan(
102081
102083
  "hashHighEntropyPasswordWithSalt",
@@ -102093,7 +102095,7 @@ function hashHighEntropyPasswordWithSalt2(password, salt) {
102093
102095
  function verifyPasswordAgainstHashes2(password, salt, hashes) {
102094
102096
  const tracer = trace.getTracer(
102095
102097
  "InstrumentedHashHelpers",
102096
- false ? void 0 : "v3.9.0-alpha.19838926610"
102098
+ false ? void 0 : "v3.9.0-alpha.20044586852"
102097
102099
  );
102098
102100
  return tracer.startActiveSpan(
102099
102101
  "verifyPasswordAgainstHashes",
@@ -105814,6 +105816,9 @@ var subscriptionFeaturesSchema = external_exports.object({
105814
105816
  allowed: external_exports.boolean().describe("Whether comId features are granted to the studio."),
105815
105817
  maxStudios: external_exports.int().positive().optional().describe(
105816
105818
  "The maximum number of studios that can be created in this comId. If omitted, then there is no limit."
105819
+ ),
105820
+ maxDomains: external_exports.int().positive().optional().describe(
105821
+ "The maximum number of custom domains that can be used with this comId. If omitted, then there is no limit."
105817
105822
  )
105818
105823
  }).optional().prefault({
105819
105824
  allowed: false
@@ -109620,7 +109625,7 @@ var import_semantic_conventions = __toESM(require_src3());
109620
109625
  function traced(tracerName, options = {}, metricOptions = {}) {
109621
109626
  const tracer = trace.getTracer(
109622
109627
  tracerName,
109623
- false ? void 0 : "v3.9.0-alpha.19838926610"
109628
+ false ? void 0 : "v3.9.0-alpha.20044586852"
109624
109629
  );
109625
109630
  return function(target, propertyKey, descriptor) {
109626
109631
  const originalMethod = descriptor.value;
@@ -109702,7 +109707,7 @@ function getHistogram(meter) {
109702
109707
  }
109703
109708
  return metrics.getMeter(
109704
109709
  meter.meter,
109705
- false ? void 0 : "v3.9.0-alpha.19838926610"
109710
+ false ? void 0 : "v3.9.0-alpha.20044586852"
109706
109711
  ).createHistogram(meter.name, meter.options);
109707
109712
  }
109708
109713
  function getCounter(meter) {
@@ -109711,7 +109716,7 @@ function getCounter(meter) {
109711
109716
  }
109712
109717
  return metrics.getMeter(
109713
109718
  meter.meter,
109714
- false ? void 0 : "v3.9.0-alpha.19838926610"
109719
+ false ? void 0 : "v3.9.0-alpha.20044586852"
109715
109720
  ).createCounter(meter.name, meter.options);
109716
109721
  }
109717
109722
  function traceHttpResponse(options = {}) {
@@ -112412,6 +112417,7 @@ var RecordsController = class {
112412
112417
  this._config = config3.config;
112413
112418
  this._messenger = config3.messenger;
112414
112419
  this._privo = config3.privo;
112420
+ this._domainNameValidator = config3.domainNameValidator;
112415
112421
  }
112416
112422
  async createRecord(request2) {
112417
112423
  try {
@@ -113340,6 +113346,176 @@ var RecordsController = class {
113340
113346
  };
113341
113347
  }
113342
113348
  }
113349
+ async addCustomDomain(request2) {
113350
+ if (!this._domainNameValidator) {
113351
+ return failure({
113352
+ errorCode: "not_supported",
113353
+ errorMessage: "Custom domains are not supported on this server."
113354
+ });
113355
+ }
113356
+ const studio = await this._store.getStudioById(request2.studioId);
113357
+ if (!studio) {
113358
+ return failure({
113359
+ errorCode: "studio_not_found",
113360
+ errorMessage: "The given studio was not found."
113361
+ });
113362
+ }
113363
+ const list = await this._store.listStudioAssignments(request2.studioId, {
113364
+ userId: request2.userId,
113365
+ role: "admin"
113366
+ });
113367
+ if (list.length <= 0) {
113368
+ return failure({
113369
+ errorCode: "not_authorized",
113370
+ errorMessage: "You are not authorized to perform this operation."
113371
+ });
113372
+ }
113373
+ const config3 = await this._config.getSubscriptionConfiguration();
113374
+ const features = getComIdFeatures(
113375
+ config3,
113376
+ studio.subscriptionStatus,
113377
+ studio.subscriptionId,
113378
+ studio.subscriptionPeriodStartMs,
113379
+ studio.subscriptionPeriodEndMs
113380
+ );
113381
+ if (!features.allowed) {
113382
+ return failure({
113383
+ errorCode: "not_authorized",
113384
+ errorMessage: "comId features are not allowed for this comId. Make sure you have an active subscription that provides comId features."
113385
+ });
113386
+ }
113387
+ if (typeof features.maxDomains === "number") {
113388
+ const domainCount = (await this._store.listCustomDomainsByStudioId(request2.studioId)).length;
113389
+ if (domainCount >= features.maxDomains) {
113390
+ return failure({
113391
+ errorCode: "subscription_limit_reached",
113392
+ errorMessage: "The maximum number of custom domains allowed for your comId subscription has been reached."
113393
+ });
113394
+ }
113395
+ }
113396
+ const verificationKey = (0, import_base64_js11.fromByteArray)((0, import_tweetnacl5.randomBytes)(16));
113397
+ const customDomain = {
113398
+ id: v7_default(),
113399
+ domainName: request2.domain,
113400
+ studioId: request2.studioId,
113401
+ verificationKey,
113402
+ verified: null
113403
+ };
113404
+ await this._store.saveCustomDomain(customDomain);
113405
+ const verificationDnsRecord = await this._domainNameValidator.getVerificationDNSRecord(
113406
+ customDomain.domainName,
113407
+ customDomain.verificationKey
113408
+ );
113409
+ return verificationDnsRecord;
113410
+ }
113411
+ async deleteCustomDomain(request2) {
113412
+ if (!this._domainNameValidator) {
113413
+ return failure({
113414
+ errorCode: "not_supported",
113415
+ errorMessage: "Custom domains are not supported on this server."
113416
+ });
113417
+ }
113418
+ const customDomain = await this._store.getCustomDomainById(
113419
+ request2.customDomainId
113420
+ );
113421
+ if (!customDomain) {
113422
+ return failure({
113423
+ errorCode: "not_found",
113424
+ errorMessage: "The given custom domain was not found."
113425
+ });
113426
+ }
113427
+ const list = await this._store.listStudioAssignments(
113428
+ customDomain.studioId,
113429
+ {
113430
+ userId: request2.userId,
113431
+ role: "admin"
113432
+ }
113433
+ );
113434
+ if (list.length <= 0) {
113435
+ return failure({
113436
+ errorCode: "not_authorized",
113437
+ errorMessage: "You are not authorized to perform this operation."
113438
+ });
113439
+ }
113440
+ await this._store.deleteCustomDomain(customDomain.id);
113441
+ return success2(void 0);
113442
+ }
113443
+ async listCustomDomains(request2) {
113444
+ if (!this._domainNameValidator) {
113445
+ return failure({
113446
+ errorCode: "not_supported",
113447
+ errorMessage: "Custom domains are not supported on this server."
113448
+ });
113449
+ }
113450
+ const studio = await this._store.getStudioById(request2.studioId);
113451
+ if (!studio) {
113452
+ return failure({
113453
+ errorCode: "studio_not_found",
113454
+ errorMessage: "The given studio was not found."
113455
+ });
113456
+ }
113457
+ const list = await this._store.listStudioAssignments(request2.studioId, {
113458
+ userId: request2.userId,
113459
+ role: "admin"
113460
+ });
113461
+ if (list.length <= 0) {
113462
+ return failure({
113463
+ errorCode: "not_authorized",
113464
+ errorMessage: "You are not authorized to perform this operation."
113465
+ });
113466
+ }
113467
+ const domains = await this._store.listCustomDomainsByStudioId(
113468
+ request2.studioId
113469
+ );
113470
+ return success2({
113471
+ domains: domains.map(
113472
+ (d2) => ({
113473
+ id: d2.id,
113474
+ domainName: d2.domainName,
113475
+ verified: d2.verified
113476
+ })
113477
+ )
113478
+ });
113479
+ }
113480
+ async verifyCustomDomain(request2) {
113481
+ if (!this._domainNameValidator) {
113482
+ return failure({
113483
+ errorCode: "not_supported",
113484
+ errorMessage: "Custom domains are not supported on this server."
113485
+ });
113486
+ }
113487
+ const customDomain = await this._store.getCustomDomainById(
113488
+ request2.customDomainId
113489
+ );
113490
+ if (!customDomain) {
113491
+ return failure({
113492
+ errorCode: "not_found",
113493
+ errorMessage: "The given custom domain was not found."
113494
+ });
113495
+ }
113496
+ const list = await this._store.listStudioAssignments(
113497
+ customDomain.studioId,
113498
+ {
113499
+ userId: request2.userId,
113500
+ role: "admin"
113501
+ }
113502
+ );
113503
+ if (list.length <= 0) {
113504
+ return failure({
113505
+ errorCode: "not_authorized",
113506
+ errorMessage: "You are not authorized to perform this operation."
113507
+ });
113508
+ }
113509
+ const result = await this._domainNameValidator.validateDomainName(
113510
+ customDomain.domainName,
113511
+ customDomain.verificationKey
113512
+ );
113513
+ if (isFailure(result)) {
113514
+ return result;
113515
+ }
113516
+ await this._store.markCustomDomainAsVerified(customDomain.id);
113517
+ return success2();
113518
+ }
113343
113519
  async getPlayerConfig(comId) {
113344
113520
  try {
113345
113521
  const studio = await this._store.getStudioByComId(comId);
@@ -113372,21 +113548,71 @@ var RecordsController = class {
113372
113548
  };
113373
113549
  }
113374
113550
  }
113375
- async getWebConfig() {
113376
- const [config3, subscriptions, privo] = await Promise.all([
113551
+ async getWebConfig(hostname3) {
113552
+ const [config3, subscriptions, privo, customDomain] = await Promise.all([
113377
113553
  this._config.getWebConfig(),
113378
113554
  this._config.getSubscriptionConfiguration(),
113379
- this._config.getPrivoConfiguration()
113555
+ this._config.getPrivoConfiguration(),
113556
+ this._store.getVerifiedCustomDomainByName(hostname3)
113380
113557
  ]);
113381
- return success2({
113558
+ const webConfig = {
113382
113559
  ...config3 ?? {
113383
113560
  version: 2,
113384
113561
  causalRepoConnectionProtocol: "websocket"
113385
113562
  },
113563
+ ...customDomain?.studio.playerConfig ?? {},
113386
113564
  studiosSupported: !!subscriptions,
113387
113565
  subscriptionsSupported: !!subscriptions,
113388
- requirePrivoLogin: !!privo
113389
- });
113566
+ requirePrivoLogin: !!privo,
113567
+ comId: customDomain?.studio.comId
113568
+ };
113569
+ if (customDomain) {
113570
+ webConfig.logoUrl = customDomain.studio.logoUrl ?? webConfig.logoUrl;
113571
+ webConfig.logoTitle = customDomain.studio.displayName ?? customDomain.studio.comId ?? webConfig.logoTitle;
113572
+ }
113573
+ return success2(webConfig);
113574
+ }
113575
+ async getPlayerWebManifest(hostname3) {
113576
+ const customDomain = await this._store.getVerifiedCustomDomainByName(
113577
+ hostname3
113578
+ );
113579
+ if (customDomain?.studio.playerWebManifest) {
113580
+ return success2(customDomain.studio.playerWebManifest);
113581
+ }
113582
+ const manifest = await this._config.getPlayerWebManifest();
113583
+ if (!manifest) {
113584
+ return failure({
113585
+ errorCode: "not_found",
113586
+ errorMessage: "No web manifest found."
113587
+ });
113588
+ }
113589
+ return success2(manifest);
113590
+ }
113591
+ async getVerifiedCustomDomainByName(hostname3) {
113592
+ const customDomain = await this._store.getVerifiedCustomDomainByName(
113593
+ hostname3
113594
+ );
113595
+ return success2(customDomain);
113596
+ }
113597
+ async getConfigurationValue(request2) {
113598
+ if (!isSuperUserRole(request2.userRole)) {
113599
+ return failure({
113600
+ errorCode: "not_authorized",
113601
+ errorMessage: "You are not authorized to perform this operation."
113602
+ });
113603
+ }
113604
+ const value = await this._config.getConfiguration(request2.key);
113605
+ return success2(value);
113606
+ }
113607
+ async setConfigurationValue(request2) {
113608
+ if (!isSuperUserRole(request2.userRole)) {
113609
+ return failure({
113610
+ errorCode: "not_authorized",
113611
+ errorMessage: "You are not authorized to perform this operation."
113612
+ });
113613
+ }
113614
+ await this._config.setConfiguration(request2.key, request2.value);
113615
+ return success2();
113390
113616
  }
113391
113617
  async listStudios(userId) {
113392
113618
  try {
@@ -113825,12 +114051,36 @@ __decorateClass([
113825
114051
  __decorateClass([
113826
114052
  traced(TRACE_NAME2)
113827
114053
  ], RecordsController.prototype, "getStudio", 1);
114054
+ __decorateClass([
114055
+ traced(TRACE_NAME2)
114056
+ ], RecordsController.prototype, "addCustomDomain", 1);
114057
+ __decorateClass([
114058
+ traced(TRACE_NAME2)
114059
+ ], RecordsController.prototype, "deleteCustomDomain", 1);
114060
+ __decorateClass([
114061
+ traced(TRACE_NAME2)
114062
+ ], RecordsController.prototype, "listCustomDomains", 1);
114063
+ __decorateClass([
114064
+ traced(TRACE_NAME2)
114065
+ ], RecordsController.prototype, "verifyCustomDomain", 1);
113828
114066
  __decorateClass([
113829
114067
  traced(TRACE_NAME2)
113830
114068
  ], RecordsController.prototype, "getPlayerConfig", 1);
113831
114069
  __decorateClass([
113832
114070
  traced(TRACE_NAME2)
113833
114071
  ], RecordsController.prototype, "getWebConfig", 1);
114072
+ __decorateClass([
114073
+ traced(TRACE_NAME2)
114074
+ ], RecordsController.prototype, "getPlayerWebManifest", 1);
114075
+ __decorateClass([
114076
+ traced(TRACE_NAME2)
114077
+ ], RecordsController.prototype, "getVerifiedCustomDomainByName", 1);
114078
+ __decorateClass([
114079
+ traced(TRACE_NAME2)
114080
+ ], RecordsController.prototype, "getConfigurationValue", 1);
114081
+ __decorateClass([
114082
+ traced(TRACE_NAME2)
114083
+ ], RecordsController.prototype, "setConfigurationValue", 1);
113834
114084
  __decorateClass([
113835
114085
  traced(TRACE_NAME2)
113836
114086
  ], RecordsController.prototype, "listStudios", 1);
@@ -117923,7 +118173,8 @@ var COM_ID_PLAYER_CONFIG = WEB_CONFIG_SCHEMA.pick({
117923
118173
  defaultBiosOption: true,
117924
118174
  jitsiAppName: true,
117925
118175
  what3WordsApiKey: true,
117926
- logoBackgroundColor: true
118176
+ logoBackgroundColor: true,
118177
+ disableVM: true
117927
118178
  }).partial();
117928
118179
  var COM_ID_WEB_CONFIG_SCHEMA = external_exports.object({
117929
118180
  playerConfig: COM_ID_PLAYER_CONFIG,
@@ -119289,14 +119540,14 @@ var PUSH_NOTIFICATION_PAYLOAD = external_exports.object({
119289
119540
  });
119290
119541
 
119291
119542
  // ../aux-records/packages/version/PackageVersionRecordsStore.ts
119292
- function getPackageVersionSpecifier(key, major2, minor, patch, tag, sha2566) {
119293
- if (sha2566 && key) {
119543
+ function getPackageVersionSpecifier(key, major2, minor, patch, tag, sha2567) {
119544
+ if (sha2567 && key) {
119294
119545
  return {
119295
119546
  success: false,
119296
119547
  errorCode: "unacceptable_request",
119297
119548
  errorMessage: "You cannot provide both key and sha256 version number."
119298
119549
  };
119299
- } else if (sha2566 && major2) {
119550
+ } else if (sha2567 && major2) {
119300
119551
  return {
119301
119552
  success: false,
119302
119553
  errorCode: "unacceptable_request",
@@ -119308,11 +119559,11 @@ function getPackageVersionSpecifier(key, major2, minor, patch, tag, sha2566) {
119308
119559
  errorCode: "unacceptable_request",
119309
119560
  errorMessage: "You cannot provide both key and major version number."
119310
119561
  };
119311
- } else if (sha2566) {
119562
+ } else if (sha2567) {
119312
119563
  return {
119313
119564
  success: true,
119314
119565
  key: {
119315
- sha256: sha2566
119566
+ sha256: sha2567
119316
119567
  }
119317
119568
  };
119318
119569
  } else if (key) {
@@ -120176,6 +120427,213 @@ function omitBy2(obj, shouldOmit) {
120176
120427
  return result;
120177
120428
  }
120178
120429
 
120430
+ // ../aux-common/common/WebManifest.js
120431
+ var WEB_MANIFEST_SCHEMA = zod_default.looseObject({
120432
+ name: zod_default.string().describe("The name of the PWA app."),
120433
+ short_name: zod_default.string().describe("The short name of the PWA app."),
120434
+ description: zod_default.string().optional().describe("The description of the PWA app."),
120435
+ start_url: zod_default.string().prefault("/").describe('The URL that should be launched when opening the PWA. Defaults to "/"'),
120436
+ display: zod_default.enum(["fullscreen", "standalone", "minimal-ui", "browser"]).prefault("standalone").describe("The display mode that should be used for the PWA app."),
120437
+ background_color: zod_default.string().prefault("#ffffff").describe("The background color that should be used on the splash screen when the PWA is launched."),
120438
+ theme_color: zod_default.string().prefault("#000000").describe("The theme color that should be used for the PWA app."),
120439
+ icons: zod_default.array(zod_default.object({
120440
+ src: zod_default.string().describe("The source URL of the icon."),
120441
+ type: zod_default.string().describe("The MIME type of the icon."),
120442
+ sizes: zod_default.union([
120443
+ zod_default.literal("any").describe("The icon is scalable and can be used at any size."),
120444
+ zod_default.string().check(zod_default.regex(/^(\d+x\d+)(\s+\d+x\d+)*$/)).describe("The sizes of the icon.")
120445
+ ]).describe('The size(s) that the icon can display formatted as "{width}x{height}". Use "any" for scalable icons like SVG.'),
120446
+ purpose: zod_default.string().optional().describe("The purpose of the icon.")
120447
+ })).prefault([
120448
+ {
120449
+ src: "/pwa-192x192.png",
120450
+ sizes: "192x192",
120451
+ type: "image/png",
120452
+ purpose: "any"
120453
+ },
120454
+ {
120455
+ src: "/pwa-512x512.png",
120456
+ sizes: "512x512",
120457
+ type: "image/png",
120458
+ purpose: "any"
120459
+ },
120460
+ {
120461
+ src: "/pwa-maskable-192x192.png",
120462
+ sizes: "192x192",
120463
+ type: "image/png",
120464
+ purpose: "maskable"
120465
+ },
120466
+ {
120467
+ src: "/pwa-maskable-512x512.png",
120468
+ sizes: "512x512",
120469
+ type: "image/png",
120470
+ purpose: "maskable"
120471
+ }
120472
+ ]).describe("The icons that should be used for the PWA app.\nSee https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Manifest/Reference/icons\nAlso see https://favicon.inbrowser.app/tools/favicon-generator to generate icons.")
120473
+ }).refine((obj) => Object.keys(obj).length < 20, {
120474
+ error: "Web manifest has too many top-level properties. Maximum allowed is 20."
120475
+ }).optional();
120476
+
120477
+ // ../aux-records/PrivoConfiguration.ts
120478
+ var privoSchema = zod_default.object({
120479
+ gatewayEndpoint: zod_default.string().nonempty().describe("The Privo API (aslo called the Gateway) URL."),
120480
+ publicEndpoint: zod_default.string().nonempty().describe("The Privo Public API URL."),
120481
+ clientId: zod_default.string().nonempty().describe("The Client ID that should be used."),
120482
+ clientSecret: zod_default.string().nonempty().describe("The client secret that should be used."),
120483
+ redirectUri: zod_default.string().nonempty().describe(
120484
+ "The URI that Privo users should be redirected to after a login."
120485
+ ),
120486
+ // verificationIntegration: z
120487
+ // .string()
120488
+ // .describe('The verification integration that should be used.')
120489
+ // .nonempty(),
120490
+ // verificationServiceId: z
120491
+ // .string()
120492
+ // .describe('The service ID that should be used.')
120493
+ // .nonempty(),
120494
+ // verificationSiteId: z
120495
+ // .string()
120496
+ // .describe('The site ID that should be used.')
120497
+ // .nonempty(),
120498
+ roleIds: zod_default.object({
120499
+ child: zod_default.string().nonempty().describe("The ID of the child role."),
120500
+ parent: zod_default.string().nonempty().describe("The ID of the parent role."),
120501
+ adult: zod_default.string().nonempty().describe("The ID of the adult role.")
120502
+ }),
120503
+ featureIds: zod_default.object({
120504
+ childPrivoSSO: zod_default.string().nonempty().describe("The ID of the child Privo ID Single Sign-On feature"),
120505
+ adultPrivoSSO: zod_default.string().nonempty().describe("The ID of the adult Privo ID Single Sign-On feature"),
120506
+ joinAndCollaborate: zod_default.string().nonempty().describe('The ID of the "Join & Collaborate" feature.'),
120507
+ publishProjects: zod_default.string().nonempty().describe(
120508
+ 'The ID of the "Publish Projects" feature. Also known as the "Publish Public Eggs" feature.'
120509
+ ),
120510
+ projectDevelopment: zod_default.string().nonempty().describe(
120511
+ 'The ID of the "Project Development" feature. Also known as the "Build Private Eggs" feature.'
120512
+ ),
120513
+ buildAIEggs: zod_default.string().nonempty().describe('The ID of the "Build AI Eggs" feature.')
120514
+ }),
120515
+ clientTokenScopes: zod_default.string().nonempty().optional().prefault(
120516
+ "openid profile email user_profile offline_access address additional_info TRUST delete_account service_profile connected_profiles manage_consent consent_url update_password_link"
120517
+ ).describe("The scopes that should be requested for client tokens."),
120518
+ userTokenScopes: zod_default.string().nonempty().optional().prefault(
120519
+ "TRUST openid profile user_profile address service_profile connected_profiles manage_consent email additional_info offline_access delete_account consent_url update_password_link"
120520
+ ).describe("The scopes that should be requested for user tokens."),
120521
+ ageOfConsent: zod_default.int().positive().prefault(18).describe(
120522
+ "The age of consent for users. Users who are under this age must have consent given for them via a parent account."
120523
+ )
120524
+ });
120525
+
120526
+ // ../aux-records/ModerationConfiguration.ts
120527
+ var moderationSchema = zod_default.object({
120528
+ allowUnauthenticatedReports: zod_default.boolean().prefault(true).describe(
120529
+ "Whether to allow unauthenticated users to report insts. Defaults to true."
120530
+ ),
120531
+ jobs: zod_default.object({
120532
+ files: zod_default.object({
120533
+ enabled: zod_default.boolean().describe("Whether to enable file moderation."),
120534
+ fileExtensions: zod_default.array(zod_default.string()).optional().prefault([".png", ".webp", ".jpg", ".jpeg", ".gif"]).describe(
120535
+ "The file extensions to scan. Defaults to common image formats."
120536
+ ),
120537
+ minConfidence: zod_default.number().min(0).max(1).optional().describe(
120538
+ "The minimum confidence to consider a detected label. Should be between 0 and 1. For AWS Rekognition, this defaults to 0.5."
120539
+ ),
120540
+ bannedLabels: zod_default.array(
120541
+ zod_default.object({
120542
+ label: zod_default.string().optional().describe(
120543
+ "The label that should be matched. If omitted, then labels will be matched by category. See https://docs.aws.amazon.com/rekognition/latest/dg/moderation.html#moderation-api for AWS Rekognition moderation labels."
120544
+ ),
120545
+ threshold: zod_default.number().min(0).max(1).prefault(0.7).describe(
120546
+ "The threshold that the label confidence must equal or exceed in order to be considered a match. Defaults to 0.7."
120547
+ ),
120548
+ actions: zod_default.array(zod_default.enum(["notify"])).optional().prefault(["notify"]).describe(
120549
+ "The actions that should be taken when a file is detected with the label. Defaults to [notify]."
120550
+ )
120551
+ })
120552
+ ).optional().prefault([
120553
+ {
120554
+ label: "Explicit",
120555
+ threshold: 0.5,
120556
+ actions: ["notify"]
120557
+ },
120558
+ {
120559
+ label: "Non-Explicit Nudity of Intimate parts and Kissing",
120560
+ threshold: 0.5,
120561
+ actions: ["notify"]
120562
+ },
120563
+ {
120564
+ label: "Swimwear or Underwear",
120565
+ threshold: 0.5,
120566
+ actions: ["notify"]
120567
+ },
120568
+ {
120569
+ label: "Violence",
120570
+ threshold: 0.5,
120571
+ actions: ["notify"]
120572
+ },
120573
+ {
120574
+ label: "Visually Disturbing",
120575
+ threshold: 0.5,
120576
+ actions: ["notify"]
120577
+ },
120578
+ {
120579
+ label: "Drugs & Tobacco",
120580
+ threshold: 0.5,
120581
+ actions: ["notify"]
120582
+ },
120583
+ {
120584
+ label: "Alcohol",
120585
+ threshold: 0.5,
120586
+ actions: ["notify"]
120587
+ },
120588
+ {
120589
+ label: "Rude Gestures",
120590
+ threshold: 0.5,
120591
+ actions: ["notify"]
120592
+ },
120593
+ {
120594
+ label: "Gambling",
120595
+ threshold: 0.5,
120596
+ actions: ["notify"]
120597
+ },
120598
+ {
120599
+ label: "Hate Symbols",
120600
+ threshold: 0.5,
120601
+ actions: ["notify"]
120602
+ }
120603
+ ]).describe(
120604
+ "The labels that should be banned. If a file contains any of these labels, it will be marked as banned. Additionally, a notification will be sent "
120605
+ )
120606
+ }).describe("Options for moderating files.")
120607
+ }).optional().describe("The moderation jobs that are enabled.")
120608
+ });
120609
+
120610
+ // ../aux-records/ConfigurationStore.ts
120611
+ var SUBSCRIPTIONS_CONFIG_KEY = "subscriptions";
120612
+ var PRIVO_CONFIG_KEY = "privo";
120613
+ var MODERATION_CONFIG_KEY = "moderation";
120614
+ var WEB_CONFIG_KEY = "web";
120615
+ var PLAYER_WEB_MANIFEST_KEY = "playerWebManifest";
120616
+ var CONFIGURATION_SCHEMAS = [
120617
+ {
120618
+ key: SUBSCRIPTIONS_CONFIG_KEY,
120619
+ schema: subscriptionConfigSchema
120620
+ },
120621
+ { key: PRIVO_CONFIG_KEY, schema: privoSchema },
120622
+ { key: MODERATION_CONFIG_KEY, schema: moderationSchema },
120623
+ { key: WEB_CONFIG_KEY, schema: WEB_CONFIG_SCHEMA },
120624
+ { key: PLAYER_WEB_MANIFEST_KEY, schema: WEB_MANIFEST_SCHEMA }
120625
+ ];
120626
+ var CONFIGURATION_SCHEMAS_MAP = {
120627
+ [SUBSCRIPTIONS_CONFIG_KEY]: subscriptionConfigSchema,
120628
+ [PRIVO_CONFIG_KEY]: privoSchema,
120629
+ [MODERATION_CONFIG_KEY]: moderationSchema,
120630
+ [WEB_CONFIG_KEY]: WEB_CONFIG_SCHEMA,
120631
+ [PLAYER_WEB_MANIFEST_KEY]: WEB_MANIFEST_SCHEMA
120632
+ };
120633
+ var CONFIGURATION_KEYS = CONFIGURATION_SCHEMAS.map(
120634
+ (c2) => c2.key
120635
+ );
120636
+
120179
120637
  // ../aux-records/RecordsServer.tsx
120180
120638
  var NOT_LOGGED_IN_RESULT = {
120181
120639
  success: false,
@@ -120298,7 +120756,7 @@ var RecordsServer = class {
120298
120756
  this._viewTemplateRenderer = viewTemplateRenderer;
120299
120757
  this._tracer = trace.getTracer(
120300
120758
  "RecordsServer",
120301
- false ? void 0 : "v3.9.0-alpha.19838926610"
120759
+ false ? void 0 : "v3.9.0-alpha.20044586852"
120302
120760
  );
120303
120761
  this._purchasableItems = purchasableItemsController;
120304
120762
  this._procedures = this._createProcedures();
@@ -120325,7 +120783,9 @@ var RecordsServer = class {
120325
120783
  _createProcedures() {
120326
120784
  return {
120327
120785
  playerIndex: procedure().origins(true).view("player", true).handler(async (_2, context) => {
120328
- const config3 = await this._records.getWebConfig();
120786
+ const config3 = await this._records.getWebConfig(
120787
+ context.url.hostname
120788
+ );
120329
120789
  const postApp = [];
120330
120790
  if (isSuccess(config3) && config3.value) {
120331
120791
  postApp.push(
@@ -120359,7 +120819,9 @@ var RecordsServer = class {
120359
120819
  return genericResult(result);
120360
120820
  }),
120361
120821
  authIndex: procedure().origins(true).view("auth", true).handler(async (_2, context) => {
120362
- const config3 = await this._records.getWebConfig();
120822
+ const config3 = await this._records.getWebConfig(
120823
+ context.url.hostname
120824
+ );
120363
120825
  const postApp = [];
120364
120826
  if (isSuccess(config3) && config3.value) {
120365
120827
  postApp.push(
@@ -120381,7 +120843,9 @@ var RecordsServer = class {
120381
120843
  return genericResult(result);
120382
120844
  }),
120383
120845
  authIframe: procedure().origins(true).view("auth", "/iframe.html").handler(async (_2, context) => {
120384
- const config3 = await this._records.getWebConfig();
120846
+ const config3 = await this._records.getWebConfig(
120847
+ context.url.hostname
120848
+ );
120385
120849
  const postApp = [];
120386
120850
  if (isSuccess(config3) && config3.value) {
120387
120851
  postApp.push(
@@ -121551,7 +122015,7 @@ var RecordsServer = class {
121551
122015
  minor,
121552
122016
  patch,
121553
122017
  tag,
121554
- sha256: sha2566,
122018
+ sha256: sha2567,
121555
122019
  key,
121556
122020
  instances
121557
122021
  }, context) => {
@@ -121577,7 +122041,7 @@ var RecordsServer = class {
121577
122041
  minor,
121578
122042
  patch,
121579
122043
  tag,
121580
- sha2566
122044
+ sha2567
121581
122045
  );
121582
122046
  if (keyResult.success === false) {
121583
122047
  return keyResult;
@@ -123149,7 +123613,10 @@ var RecordsServer = class {
123149
123613
  loomConfig: LOOM_CONFIG.optional().describe(
123150
123614
  "The configuration that can be used by studios to setup loom."
123151
123615
  ),
123152
- humeConfig: HUME_CONFIG.optional()
123616
+ humeConfig: HUME_CONFIG.optional(),
123617
+ playerWebManifest: WEB_MANIFEST_SCHEMA.optional().describe(
123618
+ "The PWA web manifest that should be served for custom domains for the studio."
123619
+ )
123153
123620
  })
123154
123621
  ).handler(
123155
123622
  async ({
@@ -123159,7 +123626,8 @@ var RecordsServer = class {
123159
123626
  comIdConfig,
123160
123627
  playerConfig,
123161
123628
  loomConfig,
123162
- humeConfig
123629
+ humeConfig,
123630
+ playerWebManifest
123163
123631
  }, context) => {
123164
123632
  const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
123165
123633
  if (sessionKeyValidation.success === false) {
@@ -123177,12 +123645,99 @@ var RecordsServer = class {
123177
123645
  comIdConfig,
123178
123646
  playerConfig,
123179
123647
  loomConfig,
123180
- humeConfig
123648
+ humeConfig,
123649
+ playerWebManifest
123181
123650
  }
123182
123651
  });
123183
123652
  return result;
123184
123653
  }
123185
123654
  ),
123655
+ addCustomDomain: procedure().origins("account").http("POST", "/api/v2/studios/domains").inputs(
123656
+ external_exports.object({
123657
+ studioId: STUDIO_ID_VALIDATION,
123658
+ domain: external_exports.string().min(1).max(255)
123659
+ })
123660
+ ).handler(async ({ studioId, domain: domain2 }, context) => {
123661
+ const sessionKeyValidation = await this._validateSessionKey(
123662
+ context.sessionKey
123663
+ );
123664
+ if (sessionKeyValidation.success === false) {
123665
+ if (sessionKeyValidation.errorCode === "no_session_key") {
123666
+ return NOT_LOGGED_IN_RESULT;
123667
+ }
123668
+ return sessionKeyValidation;
123669
+ }
123670
+ const result = await this._records.addCustomDomain({
123671
+ userId: sessionKeyValidation.userId,
123672
+ userRole: sessionKeyValidation.role,
123673
+ studioId,
123674
+ domain: domain2
123675
+ });
123676
+ return genericResult(result);
123677
+ }),
123678
+ deleteCustomDomain: procedure().origins("account").http("DELETE", "/api/v2/studios/domains").inputs(
123679
+ external_exports.object({
123680
+ customDomainId: external_exports.string().nonempty()
123681
+ })
123682
+ ).handler(async ({ customDomainId }, context) => {
123683
+ const sessionKeyValidation = await this._validateSessionKey(
123684
+ context.sessionKey
123685
+ );
123686
+ if (sessionKeyValidation.success === false) {
123687
+ if (sessionKeyValidation.errorCode === "no_session_key") {
123688
+ return NOT_LOGGED_IN_RESULT;
123689
+ }
123690
+ return sessionKeyValidation;
123691
+ }
123692
+ const result = await this._records.deleteCustomDomain({
123693
+ userId: sessionKeyValidation.userId,
123694
+ userRole: sessionKeyValidation.role,
123695
+ customDomainId
123696
+ });
123697
+ return genericResult(result);
123698
+ }),
123699
+ listCustomDomains: procedure().origins("account").http("GET", "/api/v2/studios/domains/list").inputs(
123700
+ external_exports.object({
123701
+ studioId: STUDIO_ID_VALIDATION
123702
+ })
123703
+ ).handler(async ({ studioId }, context) => {
123704
+ const sessionKeyValidation = await this._validateSessionKey(
123705
+ context.sessionKey
123706
+ );
123707
+ if (sessionKeyValidation.success === false) {
123708
+ if (sessionKeyValidation.errorCode === "no_session_key") {
123709
+ return NOT_LOGGED_IN_RESULT;
123710
+ }
123711
+ return sessionKeyValidation;
123712
+ }
123713
+ const result = await this._records.listCustomDomains({
123714
+ userId: sessionKeyValidation.userId,
123715
+ userRole: sessionKeyValidation.role,
123716
+ studioId
123717
+ });
123718
+ return genericResult(result);
123719
+ }),
123720
+ verifyCustomDomain: procedure().origins("account").http("POST", "/api/v2/studios/domains/verify").inputs(
123721
+ external_exports.object({
123722
+ customDomainId: external_exports.string().nonempty()
123723
+ })
123724
+ ).handler(async ({ customDomainId }, context) => {
123725
+ const sessionKeyValidation = await this._validateSessionKey(
123726
+ context.sessionKey
123727
+ );
123728
+ if (sessionKeyValidation.success === false) {
123729
+ if (sessionKeyValidation.errorCode === "no_session_key") {
123730
+ return NOT_LOGGED_IN_RESULT;
123731
+ }
123732
+ return sessionKeyValidation;
123733
+ }
123734
+ const result = await this._records.verifyCustomDomain({
123735
+ userId: sessionKeyValidation.userId,
123736
+ userRole: sessionKeyValidation.role,
123737
+ customDomainId
123738
+ });
123739
+ return genericResult(result);
123740
+ }),
123186
123741
  requestStudioComId: procedure().origins("account").http("POST", "/api/v2/studios/requestComId").inputs(
123187
123742
  external_exports.object({
123188
123743
  studioId: STUDIO_ID_VALIDATION,
@@ -123364,9 +123919,29 @@ var RecordsServer = class {
123364
123919
  return genericResult(result);
123365
123920
  }),
123366
123921
  getWebConfig: procedure().origins("api").http("GET", "/api/config").inputs(external_exports.object({})).handler(async (inputs, context) => {
123367
- const result = await this._records.getWebConfig();
123922
+ const result = await this._records.getWebConfig(null);
123368
123923
  return genericResult(result);
123369
123924
  }),
123925
+ getPlayerWebManifest: procedure().origins(true).http("GET", "/api/v2/site.webmanifest", "player").inputs(external_exports.object({})).handler(
123926
+ async (_2, context) => {
123927
+ const result = await this._records.getPlayerWebManifest(
123928
+ context.url.hostname
123929
+ );
123930
+ return genericResult(result);
123931
+ },
123932
+ async (result) => {
123933
+ if (result.success === true) {
123934
+ const { success: success3, ...data } = result;
123935
+ return {
123936
+ body: JSON.stringify(data),
123937
+ headers: {
123938
+ "content-type": "application/manifest+json"
123939
+ }
123940
+ };
123941
+ }
123942
+ return {};
123943
+ }
123944
+ ),
123370
123945
  getPlayerConfig: procedure().origins("api").http("GET", "/api/v2/player/config").inputs(
123371
123946
  external_exports.object({
123372
123947
  comId: external_exports.string().nonempty()
@@ -123980,8 +124555,8 @@ var RecordsServer = class {
123980
124555
  return {
123981
124556
  success: true,
123982
124557
  ...metadata,
123983
- version: true ? "v3.9.0-alpha.19838926610" : void 0,
123984
- versionHash: true ? "2fb87ec50142d8a7dc03a40456f31c4c9924fec7" : void 0
124558
+ version: true ? "v3.9.0-alpha.20044586852" : void 0,
124559
+ versionHash: true ? "48d43b4fc051e5456c465bc1f43d0f7ae1b7ec55" : void 0
123985
124560
  };
123986
124561
  }),
123987
124562
  getPurchasableItem: procedure().origins(true).http("GET", "/api/v2/records/purchasableItems").inputs(
@@ -124249,6 +124824,53 @@ var RecordsServer = class {
124249
124824
  }
124250
124825
  );
124251
124826
  return result;
124827
+ }),
124828
+ getConfigurationValue: procedure().origins("account").http("GET", "/api/v2/configuration").inputs(
124829
+ external_exports.object({
124830
+ key: external_exports.enum(CONFIGURATION_KEYS)
124831
+ })
124832
+ ).handler(async ({ key }, context) => {
124833
+ const validation = await this._validateSessionKey(
124834
+ context.sessionKey
124835
+ );
124836
+ if (validation.success === false) {
124837
+ if (validation.errorCode === "no_session_key") {
124838
+ return NOT_LOGGED_IN_RESULT;
124839
+ }
124840
+ return validation;
124841
+ }
124842
+ const result = await this._records.getConfigurationValue({
124843
+ userRole: validation.role,
124844
+ key
124845
+ });
124846
+ return genericResult(result);
124847
+ }),
124848
+ setConfigurationValue: procedure().origins("account").http("POST", "/api/v2/configuration").inputs(
124849
+ external_exports.discriminatedUnion(
124850
+ "key",
124851
+ CONFIGURATION_SCHEMAS.map(
124852
+ (s3) => external_exports.object({
124853
+ key: external_exports.literal(s3.key),
124854
+ value: s3.schema
124855
+ })
124856
+ )
124857
+ )
124858
+ ).handler(async ({ key, value }, context) => {
124859
+ const validation = await this._validateSessionKey(
124860
+ context.sessionKey
124861
+ );
124862
+ if (validation.success === false) {
124863
+ if (validation.errorCode === "no_session_key") {
124864
+ return NOT_LOGGED_IN_RESULT;
124865
+ }
124866
+ return validation;
124867
+ }
124868
+ const result = await this._records.setConfigurationValue({
124869
+ userRole: validation.role,
124870
+ key,
124871
+ value
124872
+ });
124873
+ return genericResult(result);
124252
124874
  })
124253
124875
  };
124254
124876
  }
@@ -124299,7 +124921,11 @@ var RecordsServer = class {
124299
124921
  ipAddress: request2.ipAddress,
124300
124922
  sessionKey: getSessionKey(request2),
124301
124923
  httpRequest: request2,
124302
- origin: request2.headers.origin ?? null
124924
+ origin: request2.headers.origin ?? null,
124925
+ url: new URL(
124926
+ request2.path,
124927
+ `http://${request2.headers.host}`
124928
+ )
124303
124929
  };
124304
124930
  let result;
124305
124931
  if (proc.schema) {
@@ -124381,13 +125007,18 @@ var RecordsServer = class {
124381
125007
  path: route.path,
124382
125008
  schema: procedure2.schema,
124383
125009
  querySchema: procedure2.querySchema,
125010
+ scope: route.scope,
124384
125011
  name,
124385
125012
  handler: async (request2, data, query2) => {
124386
125013
  const context = {
124387
125014
  ipAddress: request2.ipAddress,
124388
125015
  sessionKey: getSessionKey(request2),
124389
125016
  httpRequest: request2,
124390
- origin: request2.headers.origin ?? null
125017
+ origin: request2.headers.origin ?? null,
125018
+ url: new URL(
125019
+ request2.path,
125020
+ `http://${request2.headers.host}`
125021
+ )
124391
125022
  };
124392
125023
  const result = await procedure2.handler(data, context, query2);
124393
125024
  const response = returnProcedureOutput(result);
@@ -124432,7 +125063,11 @@ var RecordsServer = class {
124432
125063
  ipAddress: request2.ipAddress,
124433
125064
  sessionKey: getSessionKey(request2),
124434
125065
  httpRequest: request2,
124435
- origin: request2.headers.origin ?? null
125066
+ origin: request2.headers.origin ?? null,
125067
+ url: new URL(
125068
+ request2.path,
125069
+ `http://${request2.headers.host}`
125070
+ )
124436
125071
  };
124437
125072
  let result;
124438
125073
  try {
@@ -124595,15 +125230,35 @@ var RecordsServer = class {
124595
125230
  if (span && route.name) {
124596
125231
  span.updateName(`http:${route.name}`);
124597
125232
  }
124598
- const origins = route.allowedOrigins === "account" ? this._allowedAccountOrigins : route.allowedOrigins === "api" ? this._allowedApiOrigins : route.allowedOrigins ?? true;
124599
- if (origins !== true && !validateOrigin(request2, origins)) {
124600
- return formatResponse(
124601
- request2,
124602
- returnResult(INVALID_ORIGIN_RESULT),
124603
- origins
124604
- );
124605
- }
125233
+ let origins = route.allowedOrigins === "account" ? this._allowedAccountOrigins : route.allowedOrigins === "api" ? this._allowedApiOrigins : route.allowedOrigins ?? true;
124606
125234
  try {
125235
+ if (origins !== true && !validateOrigin(request2, origins)) {
125236
+ let allow = false;
125237
+ const host = request2.headers.host;
125238
+ if (host && route.allowedOrigins === "api") {
125239
+ const requestUrl = new URL(
125240
+ request2.path,
125241
+ `http://${host}`
125242
+ );
125243
+ const origin2 = new URL(request2.headers.origin);
125244
+ if (origin2.host === requestUrl.host) {
125245
+ const customDomain = await this._records.getVerifiedCustomDomainByName(
125246
+ requestUrl.hostname
125247
+ );
125248
+ if (isSuccess(customDomain) && customDomain.value) {
125249
+ allow = true;
125250
+ origins = true;
125251
+ }
125252
+ }
125253
+ }
125254
+ if (!allow) {
125255
+ return formatResponse(
125256
+ request2,
125257
+ returnResult(INVALID_ORIGIN_RESULT),
125258
+ origins
125259
+ );
125260
+ }
125261
+ }
124607
125262
  let response;
124608
125263
  if (route.schema) {
124609
125264
  let data;
@@ -141114,9 +141769,6 @@ __decorateClass([
141114
141769
  traced(TRACE_NAME20)
141115
141770
  ], OpenAIRealtimeInterface.prototype, "createRealtimeSessionToken", 1);
141116
141771
 
141117
- // ../aux-records/ConfigurationStore.ts
141118
- var WEB_CONFIG_KEY = "web";
141119
-
141120
141772
  // ../aux-records/CachingConfigStore.ts
141121
141773
  var TRACE_NAME21 = "CachingConfigStore";
141122
141774
  var CachingConfigStore = class {
@@ -141131,6 +141783,23 @@ var CachingConfigStore = class {
141131
141783
  this._cache = cache2;
141132
141784
  this._cacheSeconds = cacheSeconds;
141133
141785
  }
141786
+ async setConfiguration(key, value) {
141787
+ await this._cache.remove(key);
141788
+ await this._store.setConfiguration(key, value);
141789
+ }
141790
+ async getConfiguration(key, defaultValue) {
141791
+ const cached2 = await this._cache.retrieve(
141792
+ key
141793
+ );
141794
+ if (cached2) {
141795
+ return cached2;
141796
+ }
141797
+ const result = await this._store.getConfiguration(key, defaultValue);
141798
+ if (result) {
141799
+ await this._cache.store(key, result, this._cacheSeconds);
141800
+ }
141801
+ return result;
141802
+ }
141134
141803
  async getWebConfig() {
141135
141804
  const cached2 = await this._cache.retrieve(WEB_CONFIG_KEY);
141136
141805
  if (cached2) {
@@ -141142,6 +141811,23 @@ var CachingConfigStore = class {
141142
141811
  }
141143
141812
  return result;
141144
141813
  }
141814
+ async getPlayerWebManifest() {
141815
+ const cached2 = await this._cache.retrieve(
141816
+ PLAYER_WEB_MANIFEST_KEY
141817
+ );
141818
+ if (cached2) {
141819
+ return cached2;
141820
+ }
141821
+ const result = await this._store.getPlayerWebManifest();
141822
+ if (result) {
141823
+ await this._cache.store(
141824
+ PLAYER_WEB_MANIFEST_KEY,
141825
+ result,
141826
+ this._cacheSeconds
141827
+ );
141828
+ }
141829
+ return result;
141830
+ }
141145
141831
  async getSubscriptionConfiguration() {
141146
141832
  const cached2 = await this._cache.retrieve(
141147
141833
  "subscriptions"
@@ -141184,9 +141870,18 @@ var CachingConfigStore = class {
141184
141870
  return result;
141185
141871
  }
141186
141872
  };
141873
+ __decorateClass([
141874
+ traced(TRACE_NAME21)
141875
+ ], CachingConfigStore.prototype, "setConfiguration", 1);
141876
+ __decorateClass([
141877
+ traced(TRACE_NAME21)
141878
+ ], CachingConfigStore.prototype, "getConfiguration", 1);
141187
141879
  __decorateClass([
141188
141880
  traced(TRACE_NAME21)
141189
141881
  ], CachingConfigStore.prototype, "getWebConfig", 1);
141882
+ __decorateClass([
141883
+ traced(TRACE_NAME21)
141884
+ ], CachingConfigStore.prototype, "getPlayerWebManifest", 1);
141190
141885
  __decorateClass([
141191
141886
  traced(TRACE_NAME21)
141192
141887
  ], CachingConfigStore.prototype, "getSubscriptionConfiguration", 1);
@@ -141442,90 +142137,6 @@ __decorateClass([
141442
142137
  traced(TRACE_NAME22)
141443
142138
  ], ModerationController.prototype, "scanFile", 1);
141444
142139
 
141445
- // ../aux-records/ModerationConfiguration.ts
141446
- var moderationSchema = zod_default.object({
141447
- allowUnauthenticatedReports: zod_default.boolean().prefault(true).describe(
141448
- "Whether to allow unauthenticated users to report insts. Defaults to true."
141449
- ),
141450
- jobs: zod_default.object({
141451
- files: zod_default.object({
141452
- enabled: zod_default.boolean().describe("Whether to enable file moderation."),
141453
- fileExtensions: zod_default.array(zod_default.string()).optional().prefault([".png", ".webp", ".jpg", ".jpeg", ".gif"]).describe(
141454
- "The file extensions to scan. Defaults to common image formats."
141455
- ),
141456
- minConfidence: zod_default.number().min(0).max(1).optional().describe(
141457
- "The minimum confidence to consider a detected label. Should be between 0 and 1. For AWS Rekognition, this defaults to 0.5."
141458
- ),
141459
- bannedLabels: zod_default.array(
141460
- zod_default.object({
141461
- label: zod_default.string().optional().describe(
141462
- "The label that should be matched. If omitted, then labels will be matched by category. See https://docs.aws.amazon.com/rekognition/latest/dg/moderation.html#moderation-api for AWS Rekognition moderation labels."
141463
- ),
141464
- threshold: zod_default.number().min(0).max(1).prefault(0.7).describe(
141465
- "The threshold that the label confidence must equal or exceed in order to be considered a match. Defaults to 0.7."
141466
- ),
141467
- actions: zod_default.array(zod_default.enum(["notify"])).optional().prefault(["notify"]).describe(
141468
- "The actions that should be taken when a file is detected with the label. Defaults to [notify]."
141469
- )
141470
- })
141471
- ).optional().prefault([
141472
- {
141473
- label: "Explicit",
141474
- threshold: 0.5,
141475
- actions: ["notify"]
141476
- },
141477
- {
141478
- label: "Non-Explicit Nudity of Intimate parts and Kissing",
141479
- threshold: 0.5,
141480
- actions: ["notify"]
141481
- },
141482
- {
141483
- label: "Swimwear or Underwear",
141484
- threshold: 0.5,
141485
- actions: ["notify"]
141486
- },
141487
- {
141488
- label: "Violence",
141489
- threshold: 0.5,
141490
- actions: ["notify"]
141491
- },
141492
- {
141493
- label: "Visually Disturbing",
141494
- threshold: 0.5,
141495
- actions: ["notify"]
141496
- },
141497
- {
141498
- label: "Drugs & Tobacco",
141499
- threshold: 0.5,
141500
- actions: ["notify"]
141501
- },
141502
- {
141503
- label: "Alcohol",
141504
- threshold: 0.5,
141505
- actions: ["notify"]
141506
- },
141507
- {
141508
- label: "Rude Gestures",
141509
- threshold: 0.5,
141510
- actions: ["notify"]
141511
- },
141512
- {
141513
- label: "Gambling",
141514
- threshold: 0.5,
141515
- actions: ["notify"]
141516
- },
141517
- {
141518
- label: "Hate Symbols",
141519
- threshold: 0.5,
141520
- actions: ["notify"]
141521
- }
141522
- ]).describe(
141523
- "The labels that should be banned. If a file contains any of these labels, it will be marked as banned. Additionally, a notification will be sent "
141524
- )
141525
- }).describe("Options for moderating files.")
141526
- }).optional().describe("The moderation jobs that are enabled.")
141527
- });
141528
-
141529
142140
  // ../aux-records/SystemNotificationMessenger.ts
141530
142141
  var slackSchema = external_exports.object({
141531
142142
  webhookUrl: external_exports.url().describe(
@@ -142094,9 +142705,9 @@ var oneShotSign = (0, import_node_util6.promisify)(crypto6.sign);
142094
142705
  var sign2 = async (alg, key, data) => {
142095
142706
  const keyObject = getSignVerifyKey(alg, key, "sign");
142096
142707
  if (alg.startsWith("HS")) {
142097
- const hmac5 = crypto6.createHmac(hmacDigest(alg), keyObject);
142098
- hmac5.update(data);
142099
- return hmac5.digest();
142708
+ const hmac6 = crypto6.createHmac(hmacDigest(alg), keyObject);
142709
+ hmac6.update(data);
142710
+ return hmac6.digest();
142100
142711
  }
142101
142712
  return oneShotSign(dsaDigest(alg), data, keyForCrypto(alg, keyObject));
142102
142713
  };
@@ -142949,7 +143560,7 @@ var PackageVersionRecordsController = class {
142949
143560
  if (action2 === "update") {
142950
143561
  const sizeInBytes = request2.item.auxFileRequest.fileByteLength;
142951
143562
  const fileName = existingItem.item.auxFileName;
142952
- const sha2566 = getHash({
143563
+ const sha2567 = getHash({
142953
143564
  auxFileName: fileName,
142954
143565
  auxSha256: request2.item.auxFileRequest.fileSha256Hex,
142955
143566
  createdAtMs: existingItem.item.createdAtMs,
@@ -142957,7 +143568,7 @@ var PackageVersionRecordsController = class {
142957
143568
  description: request2.item.description,
142958
143569
  sizeInBytes
142959
143570
  });
142960
- if (sha2566 !== existingItem.item.sha256) {
143571
+ if (sha2567 !== existingItem.item.sha256) {
142961
143572
  return {
142962
143573
  success: false,
142963
143574
  errorCode: "not_supported",
@@ -143015,7 +143626,7 @@ var PackageVersionRecordsController = class {
143015
143626
  "Unable to determine file name for package"
143016
143627
  );
143017
143628
  }
143018
- const sha2566 = getHash({
143629
+ const sha2567 = getHash({
143019
143630
  auxFileName: fileName,
143020
143631
  auxSha256: request2.item.auxFileRequest.fileSha256Hex,
143021
143632
  createdAtMs,
@@ -143031,7 +143642,7 @@ var PackageVersionRecordsController = class {
143031
143642
  description: request2.item.description,
143032
143643
  auxFileName: fileName,
143033
143644
  auxSha256: request2.item.auxFileRequest.fileSha256Hex,
143034
- sha256: sha2566,
143645
+ sha256: sha2567,
143035
143646
  sizeInBytes,
143036
143647
  createdAtMs,
143037
143648
  createdFile: recordFileResult.success,
@@ -146566,55 +147177,6 @@ function isEventForDevice(event, device3) {
146566
147177
  return false;
146567
147178
  }
146568
147179
 
146569
- // ../aux-records/PrivoConfiguration.ts
146570
- var privoSchema = zod_default.object({
146571
- gatewayEndpoint: zod_default.string().nonempty().describe("The Privo API (aslo called the Gateway) URL."),
146572
- publicEndpoint: zod_default.string().nonempty().describe("The Privo Public API URL."),
146573
- clientId: zod_default.string().nonempty().describe("The Client ID that should be used."),
146574
- clientSecret: zod_default.string().nonempty().describe("The client secret that should be used."),
146575
- redirectUri: zod_default.string().nonempty().describe(
146576
- "The URI that Privo users should be redirected to after a login."
146577
- ),
146578
- // verificationIntegration: z
146579
- // .string()
146580
- // .describe('The verification integration that should be used.')
146581
- // .nonempty(),
146582
- // verificationServiceId: z
146583
- // .string()
146584
- // .describe('The service ID that should be used.')
146585
- // .nonempty(),
146586
- // verificationSiteId: z
146587
- // .string()
146588
- // .describe('The site ID that should be used.')
146589
- // .nonempty(),
146590
- roleIds: zod_default.object({
146591
- child: zod_default.string().nonempty().describe("The ID of the child role."),
146592
- parent: zod_default.string().nonempty().describe("The ID of the parent role."),
146593
- adult: zod_default.string().nonempty().describe("The ID of the adult role.")
146594
- }),
146595
- featureIds: zod_default.object({
146596
- childPrivoSSO: zod_default.string().nonempty().describe("The ID of the child Privo ID Single Sign-On feature"),
146597
- adultPrivoSSO: zod_default.string().nonempty().describe("The ID of the adult Privo ID Single Sign-On feature"),
146598
- joinAndCollaborate: zod_default.string().nonempty().describe('The ID of the "Join & Collaborate" feature.'),
146599
- publishProjects: zod_default.string().nonempty().describe(
146600
- 'The ID of the "Publish Projects" feature. Also known as the "Publish Public Eggs" feature.'
146601
- ),
146602
- projectDevelopment: zod_default.string().nonempty().describe(
146603
- 'The ID of the "Project Development" feature. Also known as the "Build Private Eggs" feature.'
146604
- ),
146605
- buildAIEggs: zod_default.string().nonempty().describe('The ID of the "Build AI Eggs" feature.')
146606
- }),
146607
- clientTokenScopes: zod_default.string().nonempty().optional().prefault(
146608
- "openid profile email user_profile offline_access address additional_info TRUST delete_account service_profile connected_profiles manage_consent consent_url update_password_link"
146609
- ).describe("The scopes that should be requested for client tokens."),
146610
- userTokenScopes: zod_default.string().nonempty().optional().prefault(
146611
- "TRUST openid profile user_profile address service_profile connected_profiles manage_consent email additional_info offline_access delete_account consent_url update_password_link"
146612
- ).describe("The scopes that should be requested for user tokens."),
146613
- ageOfConsent: zod_default.int().positive().prefault(18).describe(
146614
- "The age of consent for users. Users who are under this age must have consent given for them via a parent account."
146615
- )
146616
- });
146617
-
146618
147180
  // ../aux-records/ServerConfig.ts
146619
147181
  var s3Schema = external_exports.object({
146620
147182
  region: external_exports.string().nonempty().describe(
@@ -147308,6 +147870,9 @@ var serverConfigSchema = external_exports.object({
147308
147870
  defaultBiosOption: null,
147309
147871
  automaticBiosOption: null
147310
147872
  }).describe("The web configuration for the CasualOS frontend."),
147873
+ playerWebManifest: WEB_MANIFEST_SCHEMA.optional().nullable().describe(
147874
+ "The PWA web manifest that should be served by CasualOS. If omitted or null, then none will be used."
147875
+ ),
147311
147876
  drives: external_exports.object({
147312
147877
  dirs: external_exports.array(external_exports.string()).describe(
147313
147878
  "The list of extra directories that should be served by the CasualOS app on the /drives path."
@@ -147323,6 +147888,9 @@ var serverConfigSchema = external_exports.object({
147323
147888
  )
147324
147889
  });
147325
147890
 
147891
+ // ../aux-records/dns/DNSDomainNameValidator.ts
147892
+ var import_hash6 = __toESM(require_hash());
147893
+
147326
147894
  // cli.ts
147327
147895
  var import_node_stream3 = require("node:stream");
147328
147896
  var import_path3 = __toESM(require("path"));
@@ -158645,7 +159213,7 @@ var config2 = new Conf({
158645
159213
  projectName: "casualos-cli"
158646
159214
  });
158647
159215
  var program2 = new Command();
158648
- program2.name("casualos").description("A CLI for CasualOS").version("v3.9.0-alpha.19838926610").option(
159216
+ program2.name("casualos").description("A CLI for CasualOS").version("v3.9.0-alpha.20044586852").option(
158649
159217
  "-e, --endpoint <url>",
158650
159218
  "The endpoint to use for queries. Can be used to override the current endpoint."
158651
159219
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "casualos",
3
- "version": "3.9.0-alpha.19838926610",
3
+ "version": "3.9.0-alpha.20044586852",
4
4
  "description": "Command line interface for CasualOS.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "index.d.ts",
@@ -64,5 +64,5 @@
64
64
  "**/*.def",
65
65
  "templates/**"
66
66
  ],
67
- "gitHead": "2fb87ec50142d8a7dc03a40456f31c4c9924fec7"
67
+ "gitHead": "48d43b4fc051e5456c465bc1f43d0f7ae1b7ec55"
68
68
  }