@ai-ecoverse/slicc-kernel 1.177.0 → 1.178.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.
@@ -1611,10 +1611,10 @@ var RemoteWatch = class {
1611
1611
 
1612
1612
  // src/fs/view.ts
1613
1613
  function view(target, overrides) {
1614
- const keys = new Set(Object.keys(overrides));
1614
+ const keys2 = new Set(Object.keys(overrides));
1615
1615
  return new Proxy(target, {
1616
1616
  get(t, prop, receiver) {
1617
- if (keys.has(prop)) return overrides[prop];
1617
+ if (keys2.has(prop)) return overrides[prop];
1618
1618
  return Reflect.get(t, prop, receiver);
1619
1619
  },
1620
1620
  set(t, prop, value2) {
@@ -3599,8 +3599,8 @@ var OpfsFs = class {
3599
3599
  renamingDirs = /* @__PURE__ */ new Set();
3600
3600
  intents = 0;
3601
3601
  async intend(rename, at = `${RENAMES2}/${crypto.randomUUID()}`) {
3602
- const record2 = { ...rename, at: Date.now() * 1e3 + this.intents++ % 1e3 };
3603
- await this.meta.update(at, () => ({ path: at, rename: record2 }));
3602
+ const record3 = { ...rename, at: Date.now() * 1e3 + this.intents++ % 1e3 };
3603
+ await this.meta.update(at, () => ({ path: at, rename: record3 }));
3604
3604
  return at;
3605
3605
  }
3606
3606
  async rollBack(from, to, intents) {
@@ -4145,9 +4145,9 @@ async function same(a, b) {
4145
4145
  return false;
4146
4146
  }
4147
4147
  }
4148
- async function matches(record2, root, at) {
4149
- if (record2.handle) return same(record2.handle, root);
4150
- return "path" in at && record2.path !== void 0 && samePath(record2.path, at.path);
4148
+ async function matches(record3, root, at) {
4149
+ if (record3.handle) return same(record3.handle, root);
4150
+ return "path" in at && record3.path !== void 0 && samePath(record3.path, at.path);
4151
4151
  }
4152
4152
  var nameOf = (id2) => `${META_DB}:${id2}`;
4153
4153
  function done(tx) {
@@ -4190,7 +4190,7 @@ async function rootId(factory, root, locks = globalThis.navigator?.locks, top) {
4190
4190
  const all = await request(
4191
4191
  db.transaction(ROOTS_STORE, "readonly").objectStore(ROOTS_STORE).getAll()
4192
4192
  );
4193
- for (const record2 of all) if (await matches(record2, root, at)) return record2.id;
4193
+ for (const record3 of all) if (await matches(record3, root, at)) return record3.id;
4194
4194
  const id2 = crypto.randomUUID();
4195
4195
  if (await used(root)) await seed(factory, nameOf(id2));
4196
4196
  const tx = db.transaction(ROOTS_STORE, "readwrite");
@@ -5673,9 +5673,9 @@ function changeCred(cur, change) {
5673
5673
  }
5674
5674
  const privileged = cur.euid === 0;
5675
5675
  const next3 = copyCred(cur);
5676
- for (const keys of [UIDS, GIDS]) {
5677
- const own = keys.map((key) => cur[key]);
5678
- for (const key of keys) {
5676
+ for (const keys2 of [UIDS, GIDS]) {
5677
+ const own = keys2.map((key) => cur[key]);
5678
+ for (const key of keys2) {
5679
5679
  const value2 = id(change[key]);
5680
5680
  if (value2 === void 0) continue;
5681
5681
  if (!privileged && !own.includes(value2)) throw fsError("EPERM", `${key} ${value2}`);
@@ -7452,6 +7452,9 @@ var KERNEL_SIGINFO = Object.freeze({
7452
7452
  // src/body-idle.ts
7453
7453
  var BODY_IDLE_MS = 5 * 60 * 1e3;
7454
7454
 
7455
+ // src/kernel/net/transport.ts
7456
+ var FORBIDDEN_HEADER = "forbidden-header";
7457
+
7455
7458
  // src/kernel/net/ws-queue.ts
7456
7459
  var INBOUND_LIMIT = 16 * 1024 * 1024;
7457
7460
  var MESSAGE_LIMIT = 64 * 1024 * 1024;
@@ -7586,7 +7589,7 @@ function serveTransport(peer, transport, {
7586
7589
  message: e instanceof Error ? e.message : String(e),
7587
7590
  ...typeof status === "number" ? { status } : {},
7588
7591
  ...typeof code === "string" ? { code } : {},
7589
- ...detail === "transport" ? { detail } : {}
7592
+ ...detail === "transport" || detail === FORBIDDEN_HEADER ? { detail } : {}
7590
7593
  });
7591
7594
  };
7592
7595
  const uploads = uploadsFor(peer);
@@ -8682,12 +8685,12 @@ function next(p) {
8682
8685
  var ANY = [[">=", [0, 0, 0, []]]];
8683
8686
  var NOTHING = [["<", [0, 0, 0, ["0"]]]];
8684
8687
  function plain(op, p) {
8685
- const exact = !p.parts.includes(void 0);
8688
+ const exact2 = !p.parts.includes(void 0);
8686
8689
  const low = floor(p);
8687
8690
  const high = next(p);
8688
8691
  if (op === ">=") return [[">=", low]];
8689
- if (op === "<") return [["<", exact ? low : [low[0], low[1], low[2], ["0"]]]];
8690
- if (exact) return [[op === "" ? "=" : op, low]];
8692
+ if (op === "<") return [["<", exact2 ? low : [low[0], low[1], low[2], ["0"]]]];
8693
+ if (exact2) return [[op === "" ? "=" : op, low]];
8691
8694
  if (op === ">") return high ? [[">=", high]] : NOTHING;
8692
8695
  if (op === "<=") return high ? [["<", high]] : ANY;
8693
8696
  return high ? [
@@ -8774,7 +8777,7 @@ function satisfies(version, range2) {
8774
8777
  }
8775
8778
 
8776
8779
  // src/version.ts
8777
- var KERNEL_VERSION = true ? "1.177.0" : "0.0.0-dev";
8780
+ var KERNEL_VERSION = true ? "1.178.1" : "0.0.0-dev";
8778
8781
  var OS_RELEASE = "6.0.0-slicc";
8779
8782
  function procVersion() {
8780
8783
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -9364,7 +9367,7 @@ function intlZone(name2) {
9364
9367
  minute: "numeric",
9365
9368
  second: "numeric"
9366
9369
  });
9367
- const exact = (at) => {
9370
+ const exact2 = (at) => {
9368
9371
  const parts2 = {};
9369
9372
  for (const part of format.formatToParts(at)) parts2[part.type] = Number(part.value);
9370
9373
  const wall = Date.UTC(
@@ -9384,12 +9387,12 @@ function intlZone(name2) {
9384
9387
  const bucket = Math.floor(at / BUCKET_MS);
9385
9388
  let known = buckets.get(bucket);
9386
9389
  if (known === void 0) {
9387
- const start2 = exact(bucket * BUCKET_MS);
9388
- known = start2 === exact(bucket * BUCKET_MS + BUCKET_MS - MINUTE_MS) ? start2 : null;
9390
+ const start2 = exact2(bucket * BUCKET_MS);
9391
+ known = start2 === exact2(bucket * BUCKET_MS + BUCKET_MS - MINUTE_MS) ? start2 : null;
9389
9392
  if (buckets.size >= CACHE_MAX) buckets.clear();
9390
9393
  buckets.set(bucket, known);
9391
9394
  }
9392
- return known ?? exact(at);
9395
+ return known ?? exact2(at);
9393
9396
  }
9394
9397
  };
9395
9398
  }
@@ -10619,11 +10622,11 @@ var CronService = class {
10619
10622
  const now = this.clock.now();
10620
10623
  const system = this.host.timeZone;
10621
10624
  const due2 = [];
10622
- const keys = /* @__PURE__ */ new Set();
10625
+ const keys2 = /* @__PURE__ */ new Set();
10623
10626
  let next3 = now + WAKE_MS;
10624
10627
  for (const entry of loaded) {
10625
10628
  const key = keyOf2(entry);
10626
- keys.add(key);
10629
+ keys2.add(key);
10627
10630
  const { when } = entry.job;
10628
10631
  if (when.reboot) {
10629
10632
  if (this.rebooted || stamp.reboot[key] === this.host.bootId) continue;
@@ -10649,7 +10652,7 @@ var CronService = class {
10649
10652
  }
10650
10653
  this.rebooted = true;
10651
10654
  for (const map of [stamp.jobs, stamp.reboot, stamp.when])
10652
- for (const key of Object.keys(map)) if (!keys.has(key)) delete map[key];
10655
+ for (const key of Object.keys(map)) if (!keys2.has(key)) delete map[key];
10653
10656
  await this.writeStamp(stamp);
10654
10657
  for (const each of due2) void this.spawn(each);
10655
10658
  return next3;
@@ -11755,16 +11758,16 @@ function missing4(err) {
11755
11758
  return err?.code === "ENOENT";
11756
11759
  }
11757
11760
  function synthetic(directory, path) {
11758
- const epoch = /* @__PURE__ */ new Date(0);
11761
+ const epoch2 = /* @__PURE__ */ new Date(0);
11759
11762
  return {
11760
11763
  isFile: !directory,
11761
11764
  isDirectory: directory,
11762
11765
  isSymbolicLink: false,
11763
11766
  size: 0,
11764
11767
  mode: (directory ? S_IFDIR2 : S_IFREG2) | 493,
11765
- mtime: epoch,
11766
- atime: epoch,
11767
- ctime: epoch,
11768
+ mtime: epoch2,
11769
+ atime: epoch2,
11770
+ ctime: epoch2,
11768
11771
  ino: inodeOf(path)
11769
11772
  };
11770
11773
  }
@@ -11983,16 +11986,16 @@ function missing5(err) {
11983
11986
  return err?.code === "ENOENT";
11984
11987
  }
11985
11988
  function statOf(path, bytes) {
11986
- const epoch = /* @__PURE__ */ new Date(0);
11989
+ const epoch2 = /* @__PURE__ */ new Date(0);
11987
11990
  return {
11988
11991
  isFile: true,
11989
11992
  isDirectory: false,
11990
11993
  isSymbolicLink: false,
11991
11994
  size: bytes.length,
11992
11995
  mode: S_IFREG3 | 420,
11993
- mtime: epoch,
11994
- atime: epoch,
11995
- ctime: epoch,
11996
+ mtime: epoch2,
11997
+ atime: epoch2,
11998
+ ctime: epoch2,
11996
11999
  ino: inodeOf(path),
11997
12000
  nlink: 1,
11998
12001
  uid: 0,
@@ -14048,11 +14051,11 @@ var HeldPaths = class extends Map {
14048
14051
  handlesAt(path) {
14049
14052
  return [...this.handles].filter(([, key]) => key === path).map(([id2]) => id2);
14050
14053
  }
14051
- doubt(over, exact = false) {
14054
+ doubt(over, exact2 = false) {
14052
14055
  if (this.bound.size === 0) return;
14053
14056
  for (const [handle, key] of this.handles) {
14054
14057
  if (!this.bound.has(handle) || this.keptHandles.has(handle)) continue;
14055
- if (exact ? key === over : within7(key, over)) this.doubted.set(handle, ++this.doubts);
14058
+ if (exact2 ? key === over : within7(key, over)) this.doubted.set(handle, ++this.doubts);
14056
14059
  }
14057
14060
  }
14058
14061
  boundIno(handle) {
@@ -17907,8 +17910,8 @@ function refused2(engine, session, err, opening2) {
17907
17910
  const code = verifyCode(flags2);
17908
17911
  if (code && flags2 !== -1)
17909
17912
  return new KernelError("EPROTO", `${code}: ${engine.verifyInfo(flags2).trim()}`);
17910
- const record2 = recordRefusal(opening2);
17911
- if (record2) return record2;
17913
+ const record3 = recordRefusal(opening2);
17914
+ if (record3) return record3;
17912
17915
  const text = err instanceof TlsError ? err.message : String(err);
17913
17916
  return new KernelError("EPROTO", `ERR_SSL_HANDSHAKE_FAILURE: ${text}${alertOf(session)}`);
17914
17917
  }
@@ -19023,6 +19026,120 @@ var SessionScrubs = class {
19023
19026
  }
19024
19027
  };
19025
19028
 
19029
+ // src/kernel/sealed-oauth.ts
19030
+ var SEALED_OAUTH_TIMEOUT_MS = 45e3;
19031
+ var SEALED_OAUTH_OPS = /* @__PURE__ */ new Set([
19032
+ "oauthGrant",
19033
+ "oauthStatus",
19034
+ "oauthRefresh",
19035
+ "oauthRemove"
19036
+ ]);
19037
+ var MESSAGES = {
19038
+ EINVAL: "Invalid OAuth request",
19039
+ ENOENT: "OAuth credential not found",
19040
+ EEXIST: "OAuth credential identity conflicts",
19041
+ EACCES: "OAuth operation refused",
19042
+ EAGAIN: "OAuth credential changed; try again",
19043
+ ENOTSUP: "OAuth operation is not supported",
19044
+ ENOTCONN: "Vault is unavailable",
19045
+ ETIMEDOUT: "Vault request timed out",
19046
+ EIO: "Invalid vault reply"
19047
+ };
19048
+ var CAUSES = {
19049
+ "vault-locked": "Vault is locked",
19050
+ "oauth-reauth-required": "OAuth sign-in is required",
19051
+ "oauth-refresh-failed": "OAuth refresh failed"
19052
+ };
19053
+ var COMMON = ["v", "op", "caller"];
19054
+ var IDENTITY = [...COMMON, "name", "provider", "account"];
19055
+ var GRANT = [...IDENTITY, "accessToken", "refreshToken", "tokenType", "expiresAt", "oauth"];
19056
+ var CONFIG = ["tokenUrl", "clientId", "authMethod", "scope", "resource"];
19057
+ var UNSUPPORTED = ["auth", "clientSecret", "fields"];
19058
+ var STATES2 = /* @__PURE__ */ new Set([
19059
+ "ready",
19060
+ "refreshing",
19061
+ "expired",
19062
+ "reauth-required",
19063
+ "removed",
19064
+ "locked"
19065
+ ]);
19066
+ var NAME3 = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
19067
+ var PROVIDER = /^[a-z0-9][a-z0-9-]{0,127}$/;
19068
+ var PLACEHOLDER2 = /^fnox_proxy_[0-9a-f]{24}$/;
19069
+ var CONTROL = /[\u0000-\u001f\u007f-\u009f]/;
19070
+ function record(value2) {
19071
+ return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
19072
+ }
19073
+ function keys(value2, allowed) {
19074
+ return Object.keys(value2).every((key) => allowed.includes(key));
19075
+ }
19076
+ function exact(value2, fields) {
19077
+ return Object.keys(value2).length === fields.length && keys(value2, fields);
19078
+ }
19079
+ function nonempty(value2) {
19080
+ return typeof value2 === "string" && value2.length > 0;
19081
+ }
19082
+ function epoch(value2) {
19083
+ return typeof value2 === "number" && Number.isSafeInteger(value2) && value2 >= 0;
19084
+ }
19085
+ function sealedOAuthOperation(op) {
19086
+ return op === "capabilities" || SEALED_OAUTH_OPS.has(op);
19087
+ }
19088
+ function validateSealedOAuth(req) {
19089
+ const config = req.oauth;
19090
+ if (UNSUPPORTED.some((key) => Object.hasOwn(req, key)) || record(config) && UNSUPPORTED.some((key) => Object.hasOwn(config, key)))
19091
+ throw new KernelError("ENOTSUP");
19092
+ const allowed = req.op === "capabilities" ? COMMON : req.op === "oauthGrant" ? GRANT : IDENTITY;
19093
+ if (!keys(req, allowed)) throw new KernelError("EINVAL");
19094
+ if (req.op === "capabilities") return;
19095
+ if (typeof req.name !== "string" || !NAME3.test(req.name) || typeof req.provider !== "string" || !PROVIDER.test(req.provider) || !nonempty(req.account) || req.account.length > 256 || CONTROL.test(req.account))
19096
+ throw new KernelError("EINVAL");
19097
+ if (req.op !== "oauthGrant") return;
19098
+ if (!nonempty(req.accessToken) || req.refreshToken !== void 0 && !nonempty(req.refreshToken) || req.tokenType !== void 0 && typeof req.tokenType !== "string" || req.expiresAt !== void 0 && !epoch(req.expiresAt) || !record(config) || !keys(config, CONFIG) || !nonempty(config.tokenUrl) || !nonempty(config.clientId) || typeof config.authMethod !== "string" || config.scope !== void 0 && typeof config.scope !== "string" || config.resource !== void 0 && !nonempty(config.resource))
19099
+ throw new KernelError("EINVAL");
19100
+ if (config.authMethod !== "none" || typeof req.tokenType === "string" && req.tokenType.toLowerCase() !== "bearer")
19101
+ throw new KernelError("ENOTSUP");
19102
+ }
19103
+ function sealedOAuthError(code = "EIO", cause) {
19104
+ return {
19105
+ v: 1,
19106
+ error: { code, ...cause ? { cause } : {}, message: cause ? CAUSES[cause] : MESSAGES[code] }
19107
+ };
19108
+ }
19109
+ function sealedOAuthReply(op, value2) {
19110
+ try {
19111
+ return checkedReply(op, value2) ?? sealedOAuthError();
19112
+ } catch {
19113
+ return sealedOAuthError();
19114
+ }
19115
+ }
19116
+ function checkedError(value2) {
19117
+ const error = value2.error;
19118
+ if (!exact(value2, ["v", "error"]) || !record(error) || !Object.hasOwn(error, "code") || !Object.hasOwn(error, "message"))
19119
+ return void 0;
19120
+ const { code, cause, message: message3 } = error;
19121
+ if (!keys(error, ["code", "cause", "message"]) || typeof code !== "string" || !Object.hasOwn(MESSAGES, code) || typeof message3 !== "string" || cause !== void 0 && (typeof cause !== "string" || !Object.hasOwn(CAUSES, cause)))
19122
+ return void 0;
19123
+ return sealedOAuthError(code, cause);
19124
+ }
19125
+ function checkedReply(op, value2) {
19126
+ if (!record(value2) || !Object.hasOwn(value2, "v") || value2.v !== 1) return void 0;
19127
+ if (Object.hasOwn(value2, "error")) return checkedError(value2);
19128
+ if (op === "capabilities") {
19129
+ const caps = value2.capabilities;
19130
+ if (!exact(value2, ["v", "capabilities"]) || !record(caps) || !keys(caps, ["kernelOAuth"]))
19131
+ return void 0;
19132
+ if (Object.hasOwn(caps, "kernelOAuth") && caps.kernelOAuth !== 1) return void 0;
19133
+ return { v: 1, capabilities: Object.hasOwn(caps, "kernelOAuth") ? { kernelOAuth: 1 } : {} };
19134
+ }
19135
+ if (op === "oauthRemove")
19136
+ return exact(value2, ["v", "removed"]) && value2.removed === true ? { v: 1, removed: true } : void 0;
19137
+ const { placeholder, state, expiresAt, refreshable } = value2;
19138
+ if (!exact(value2, ["v", "placeholder", "state", "expiresAt", "refreshable"]) || typeof placeholder !== "string" || !PLACEHOLDER2.test(placeholder) || typeof state !== "string" || !STATES2.has(state) || expiresAt !== null && !epoch(expiresAt) || typeof refreshable !== "boolean")
19139
+ return void 0;
19140
+ return { v: 1, placeholder, state, expiresAt, refreshable };
19141
+ }
19142
+
19026
19143
  // src/kernel/sealed-session.ts
19027
19144
  var SESSION_WINDOW_MS = 6e4;
19028
19145
  var SESSION_PLACEHOLDERS = 16;
@@ -19133,8 +19250,8 @@ function sessionValues(reply, asked) {
19133
19250
  const { error, values } = reply;
19134
19251
  if (error !== void 0 || typeof values !== "object" || values === null) return void 0;
19135
19252
  const out = {};
19136
- const keys = Object.keys(values);
19137
- const wanted = asked ?? (keys.length === 1 && SESSION_PLACEHOLDER.test(keys[0]) ? keys : []);
19253
+ const keys2 = Object.keys(values);
19254
+ const wanted = asked ?? (keys2.length === 1 && SESSION_PLACEHOLDER.test(keys2[0]) ? keys2 : []);
19138
19255
  for (const ph of wanted) {
19139
19256
  const value2 = values[ph];
19140
19257
  if (typeof value2 === "string" && value2.length > 0 && !UNSAFE.test(value2)) out[ph] = value2;
@@ -19158,7 +19275,9 @@ var SEALED_OPS = /* @__PURE__ */ new Set([
19158
19275
  "request",
19159
19276
  "status",
19160
19277
  "cancel",
19161
- "materialize"
19278
+ "materialize",
19279
+ "capabilities",
19280
+ ...SEALED_OAUTH_OPS
19162
19281
  ]);
19163
19282
  function tagFields(tags) {
19164
19283
  const [tag] = tags ?? [];
@@ -19193,6 +19312,7 @@ function parseSealed(bytes) {
19193
19312
  throw new KernelError("EINVAL");
19194
19313
  if (req.op === "materialize" && !materializable(req)) throw new KernelError("EINVAL");
19195
19314
  if (req.op === "ask" && !askable(req)) throw new KernelError("EINVAL");
19315
+ if (sealedOAuthOperation(req.op)) validateSealedOAuth(req);
19196
19316
  return req;
19197
19317
  } finally {
19198
19318
  bytes.fill(0);
@@ -19271,7 +19391,7 @@ var SealedChannel = class {
19271
19391
  const ask = fields.op === "ask";
19272
19392
  const timer = setTimeout(
19273
19393
  () => control.abort(ask ? "expired" : "timeout"),
19274
- ask ? this.broker.askTimeoutMs : this.broker.timeoutMs
19394
+ ask ? this.broker.askTimeoutMs : SEALED_OAUTH_OPS.has(fields.op) ? this.broker.oauthTimeoutMs : this.broker.timeoutMs
19275
19395
  );
19276
19396
  const req = { ...fields, v: 1, op: fields.op, caller };
19277
19397
  const asked = ask ? this.asking(fields, caller, requester, control.signal) : void 0;
@@ -19294,24 +19414,26 @@ var SealedChannel = class {
19294
19414
  if (!facts) return errorReply("EIO", "the kernel has no record of this process");
19295
19415
  return this.answer(askRequest(fields, caller, facts), signal);
19296
19416
  }
19297
- stopped(signal) {
19417
+ stopped(signal, oauth = false) {
19298
19418
  if (signal.reason === "timeout")
19299
- return errorReply("ETIMEDOUT", "the vault did not answer within 10 s");
19419
+ return oauth ? sealedOAuthError("ETIMEDOUT") : errorReply("ETIMEDOUT", "the vault did not answer within 10 s");
19300
19420
  return signal.reason === "expired" ? { v: 1, state: "expired" } : void 0;
19301
19421
  }
19302
19422
  async answer(req, signal) {
19303
19423
  const hook = this.broker.hook;
19304
- if (!hook) return errorReply("ENOTCONN", "no vault is connected");
19424
+ const oauth = sealedOAuthOperation(req.op);
19425
+ if (!hook)
19426
+ return oauth ? sealedOAuthError("ENOTCONN") : errorReply("ENOTCONN", "no vault is connected");
19305
19427
  const stopped = new Promise((resolve2) => {
19306
19428
  signal.addEventListener("abort", () => resolve2(void 0), { once: true });
19307
19429
  });
19308
19430
  if (signal.aborted) return void 0;
19309
19431
  const asked = Promise.resolve().then(() => hook(req, { signal })).then(
19310
- (reply2) => isRecord(reply2) ? reply2 : errorReply("EIO", "the vault gave no reply"),
19311
- (err) => errorReply("EIO", lineOf3(err))
19432
+ (reply2) => oauth ? sealedOAuthReply(req.op, reply2) : isRecord(reply2) ? reply2 : errorReply("EIO", "the vault gave no reply"),
19433
+ (err) => oauth ? sealedOAuthError() : errorReply("EIO", lineOf3(err))
19312
19434
  );
19313
19435
  const reply = await Promise.race([asked, stopped]);
19314
- return signal.aborted ? this.stopped(signal) : reply;
19436
+ return signal.aborted ? this.stopped(signal, oauth) : reply;
19315
19437
  }
19316
19438
  drop() {
19317
19439
  this.reply?.fill(0);
@@ -19374,6 +19496,7 @@ var SealedBroker = class {
19374
19496
  tickets = new TicketBook();
19375
19497
  sessions = new SessionScrubs();
19376
19498
  askTimeoutMs = SEALED_ASK_TIMEOUT_MS;
19499
+ oauthTimeoutMs = SEALED_OAUTH_TIMEOUT_MS;
19377
19500
  userOf = async () => void 0;
19378
19501
  factsOf = async () => void 0;
19379
19502
  constructor(hook, users, timeoutMs = SEALED_TIMEOUT_MS, tagOf = () => void 0) {
@@ -19494,7 +19617,7 @@ var Timestamps = class {
19494
19617
  // src/sudoers.ts
19495
19618
  var SUDOERS = "/etc/sudoers";
19496
19619
  var SUDOERS_D = "/etc/sudoers.d";
19497
- var NAME3 = /^[a-z_][a-z0-9_.-]*$/;
19620
+ var NAME4 = /^[a-z_][a-z0-9_.-]*$/;
19498
19621
  var WORD = String.raw`(?:'[^']*'|"(?:[^"\\]|\\[\s\S])*"|\\[\s\S]|[^\s'"\\])+`;
19499
19622
  var KERNEL_FORM = new RegExp(
19500
19623
  String.raw`^(NOPASSWD\s+)?(\S+)\s+(?:\(([^()]*)\)\s+)?(?:Cwd\s+(${WORD})\s+)?(?:Stdin\s+(\S+)\s+)?Cmnd(?:\s+(.*))?$`
@@ -19504,7 +19627,7 @@ var RUNAS = /^\(([^()]*)\)\s*/;
19504
19627
  var TAG = /^([A-Z_]+)\s*:\s*/;
19505
19628
  var OPTION = /^([A-Z_]+)=/;
19506
19629
  var PLAIN2 = /^[A-Za-z0-9_@%+=:,./-]+$/;
19507
- var CONTROL = /[\p{Cc}\u2028\u2029]/u;
19630
+ var CONTROL2 = /[\p{Cc}\u2028\u2029]/u;
19508
19631
  var CONTROLS = /[\p{Cc}\u2028\u2029]/gu;
19509
19632
  var SHOWN_MAX = 60;
19510
19633
  var KERNEL_SYNTAX = "[NOPASSWD] <user|%group|ALL> [(<target>)] [Cwd <dir>] [Stdin none] Cmnd <command\u2026|*>";
@@ -19513,7 +19636,7 @@ var EXPECTED = `expected '${KERNEL_SYNTAX}' or '${SUDOERS_SYNTAX}'`;
19513
19636
  var TIMESTAMP_TIMEOUT = 5;
19514
19637
  var TIMESTAMP_TYPE = "tty";
19515
19638
  function hasControl(text) {
19516
- return CONTROL.test(text);
19639
+ return CONTROL2.test(text);
19517
19640
  }
19518
19641
  function withoutControl(text) {
19519
19642
  return text.replace(CONTROLS, (ch) => {
@@ -19651,7 +19774,7 @@ function commandText(cmnd) {
19651
19774
  }
19652
19775
  function validWho(who) {
19653
19776
  if (who === "ALL") return true;
19654
- return NAME3.test(who.startsWith("%") ? who.slice(1) : who);
19777
+ return NAME4.test(who.startsWith("%") ? who.slice(1) : who);
19655
19778
  }
19656
19779
  function whoError(who) {
19657
19780
  if (validWho(who)) return void 0;
@@ -19684,7 +19807,7 @@ function kernelRules(m) {
19684
19807
  const [, nopasswd, who = "", target = "root", dir, stdin, rest2 = ""] = m;
19685
19808
  const bad = whoError(who);
19686
19809
  if (bad !== void 0) return bad;
19687
- if (target !== "ALL" && !NAME3.test(target)) return targetError(target);
19810
+ if (target !== "ALL" && !NAME4.test(target)) return targetError(target);
19688
19811
  const cwd = dir === void 0 ? void 0 : cwdOf(dir);
19689
19812
  if (cwd === "") return `Cwd expects one absolute directory, not ${shown(dir)}`;
19690
19813
  if (stdin !== void 0 && stdin !== "none") return `Stdin takes none, not ${shown(stdin)}`;
@@ -19708,11 +19831,11 @@ function runasOf(list) {
19708
19831
  return colon < 0 ? "() names no user to run as: name one, or leave the (\u2026) out for root" : `(${list}) runs as the caller with another group, which the kernel's sudo can't do`;
19709
19832
  }
19710
19833
  for (const name2 of names2) {
19711
- if (name2 === "ALL" || NAME3.test(name2)) continue;
19834
+ if (name2 === "ALL" || NAME4.test(name2)) continue;
19712
19835
  return `expected user names or ALL to run as, not ${shown(name2)} (no %group, #uid or !user)`;
19713
19836
  }
19714
19837
  for (const group of groups) {
19715
- if (group === "" || group === "ALL" || NAME3.test(group)) continue;
19838
+ if (group === "" || group === "ALL" || NAME4.test(group)) continue;
19716
19839
  return `expected group names or ALL after ':' in (\u2026), not ${shown(group)}`;
19717
19840
  }
19718
19841
  return names2.includes("ALL") ? ["ALL"] : [...new Set(names2)];
@@ -19801,7 +19924,7 @@ function directiveError(text) {
19801
19924
  }
19802
19925
  function recordedBare(line, file, rule) {
19803
19926
  if (rule.cmnd === "*" || rule.cmnd.args !== void 0 || !rule.nopasswd) return false;
19804
- if (file !== `${SUDOERS_D}/${rule.who}` || !NAME3.test(rule.who) || !NAME3.test(rule.target)) {
19927
+ if (file !== `${SUDOERS_D}/${rule.who}` || !NAME4.test(rule.who) || !NAME4.test(rule.target)) {
19805
19928
  return false;
19806
19929
  }
19807
19930
  const head = `NOPASSWD ${rule.who} (${rule.target}) `;
@@ -20501,7 +20624,7 @@ ${lines2}
20501
20624
  async remember(self, target, cwd, argv) {
20502
20625
  const { fs } = this.o;
20503
20626
  const path = `${SUDOERS_D}/${self.name}`;
20504
- if (!NAME3.test(self.name)) return false;
20627
+ if (!NAME4.test(self.name)) return false;
20505
20628
  try {
20506
20629
  await this.provision();
20507
20630
  if (!await this.trusted(SUDOERS_D)) return false;
@@ -21870,8 +21993,8 @@ function sameCert(a, b) {
21870
21993
  if (!a || !b) return a === b;
21871
21994
  return a.cert.length === b.cert.length && a.cert.every((byte, i) => byte === b.cert[i]);
21872
21995
  }
21873
- function winner(current, expected, record2) {
21874
- return sameCert(current, expected) ? record2 : current;
21996
+ function winner(current, expected, record3) {
21997
+ return sameCert(current, expected) ? record3 : current;
21875
21998
  }
21876
21999
  var DAY = 24 * 60 * 60 * 1e3;
21877
22000
  var CA_LIFETIME = 3650 * DAY;
@@ -21904,15 +22027,15 @@ function indexedDbCaStore(dbName = "slicc-realm-ca") {
21904
22027
  const store = (await open2()).transaction("ca").objectStore("ca");
21905
22028
  return await request2(store.get(owner));
21906
22029
  },
21907
- async swap(owner, expected, record2) {
22030
+ async swap(owner, expected, record3) {
21908
22031
  const tx = (await open2()).transaction("ca", "readwrite");
21909
22032
  const store = tx.objectStore("ca");
21910
- let stored2 = record2;
22033
+ let stored2 = record3;
21911
22034
  const read = store.get(owner);
21912
22035
  read.onsuccess = () => {
21913
22036
  const current = read.result;
21914
- const kept = winner(current, expected, record2);
21915
- if (kept === record2) store.put(record2, owner);
22037
+ const kept = winner(current, expected, record3);
22038
+ if (kept === record3) store.put(record3, owner);
21916
22039
  else stored2 = kept;
21917
22040
  };
21918
22041
  await new Promise((resolve2, reject) => {
@@ -21932,14 +22055,14 @@ function validLeafName(host) {
21932
22055
  }
21933
22056
  var RealmCa = class _RealmCa {
21934
22057
  record;
21935
- constructor(record2) {
21936
- this.record = record2;
22058
+ constructor(record3) {
22059
+ this.record = record3;
21937
22060
  }
21938
22061
  static async open(owner, store, now = Date.now()) {
21939
22062
  const stored2 = await store.get(owner).catch(() => void 0);
21940
22063
  if (stored2 && stored2.notAfter - now > CA_RENEW_BEFORE) return new _RealmCa(stored2);
21941
- const record2 = await _RealmCa.create(owner, now);
21942
- return new _RealmCa(await store.swap(owner, stored2, record2));
22064
+ const record3 = await _RealmCa.create(owner, now);
22065
+ return new _RealmCa(await store.swap(owner, stored2, record3));
21943
22066
  }
21944
22067
  static async create(owner, now) {
21945
22068
  const pair = await crypto.subtle.generateKey(ECDSA, false, ["sign", "verify"]);
@@ -22166,8 +22289,8 @@ function memoryCaStore() {
22166
22289
  const records = /* @__PURE__ */ new Map();
22167
22290
  return {
22168
22291
  get: async (owner) => records.get(owner),
22169
- swap: async (owner, expected, record2) => {
22170
- const kept = winner(records.get(owner), expected, record2);
22292
+ swap: async (owner, expected, record3) => {
22293
+ const kept = winner(records.get(owner), expected, record3);
22171
22294
  records.set(owner, kept);
22172
22295
  return kept;
22173
22296
  }
@@ -22570,6 +22693,9 @@ var HttpHandles = class {
22570
22693
  if (e instanceof PlaceholderRefused) {
22571
22694
  return { ok: false, errno: e.code, message: text, detail: "placeholder" };
22572
22695
  }
22696
+ if (e.detail === FORBIDDEN_HEADER) {
22697
+ return { ok: false, errno: "ENOTSUP", message: text, detail: FORBIDDEN_HEADER };
22698
+ }
22573
22699
  const status = e.status;
22574
22700
  if (text === NO_TRANSPORT || typeof status !== "number" || status === 502) {
22575
22701
  const code = codeOf2(e);
@@ -30416,7 +30542,7 @@ function header2(id2, flags2, counts) {
30416
30542
  function opt() {
30417
30543
  return [0, 0, TYPE_OPT, UDP_EDNS >> 8, UDP_EDNS & 255, 0, 0, 0, 0, 0, 0];
30418
30544
  }
30419
- function record(type, rdata) {
30545
+ function record2(type, rdata) {
30420
30546
  const ttl = DNS_STUB_TTL;
30421
30547
  return [
30422
30548
  192,
@@ -30524,14 +30650,14 @@ var DnsStub = class {
30524
30650
  const address = reverseAddress(q.name);
30525
30651
  const name2 = address !== void 0 ? await this.reverse(address) : void 0;
30526
30652
  if (name2 !== void 0)
30527
- return answerReply(query, q, NOERROR, [record(TYPE_PTR, encodeName(name2))], true);
30653
+ return answerReply(query, q, NOERROR, [record2(TYPE_PTR, encodeName(name2))], true);
30528
30654
  return this.forward(query, q);
30529
30655
  }
30530
30656
  if (q.type === TYPE_A || q.type === TYPE_AAAA) {
30531
30657
  const addresses = q.name === "" ? [] : await this.lookup(q.name);
30532
30658
  const answers2 = addresses.flatMap((a) => {
30533
30659
  const data = addressData(a, q.type);
30534
- return data ? [record(q.type, data)] : [];
30660
+ return data ? [record2(q.type, data)] : [];
30535
30661
  });
30536
30662
  if (answers2.length > 0 || local(q.name) || await this.known(q.name)) {
30537
30663
  const rcode = addresses.length > 0 ? NOERROR : NXDOMAIN;
@@ -30720,7 +30846,7 @@ var TransportError = class extends Error {
30720
30846
  super(message3);
30721
30847
  this.status = status;
30722
30848
  this.code = code;
30723
- this.detail = detail === "transport" ? detail : void 0;
30849
+ this.detail = detail === "transport" || detail === FORBIDDEN_HEADER ? detail : void 0;
30724
30850
  }
30725
30851
  };
30726
30852
  function unfollowed2(redirect) {
@@ -34516,8 +34642,8 @@ var Launcher = class {
34516
34642
  const caller = this.jobs.shown(ppid);
34517
34643
  const named = typeof req.argv0 === "string" && !planned.script && !planned.target.fixed;
34518
34644
  const argv = named ? [req.argv0, ...req.argv.slice(1)] : req.argv;
34519
- const exact = booked?.pid === caller && req.file === booked.path && await physicalPathAsync(this.base, req.cwd) === booked.cwd && await argvDigest(argv) === booked.argv;
34520
- if (!exact) throw new SpawnError("EACCES");
34645
+ const exact2 = booked?.pid === caller && req.file === booked.path && await physicalPathAsync(this.base, req.cwd) === booked.cwd && await argvDigest(argv) === booked.argv;
34646
+ if (!exact2) throw new SpawnError("EACCES");
34521
34647
  const { requested: path, requestedCwd: cwd, path: resolved2 } = booked;
34522
34648
  const pid = this.nextPid++;
34523
34649
  const ids = { pid: req.exec ? caller : pid, ppid: caller };
@@ -35880,9 +36006,9 @@ var Launcher = class {
35880
36006
  }
35881
36007
  pnpmReady() {
35882
36008
  if (this.pnpmMade !== void 0) return this.pnpmMade;
35883
- const epoch = this.pnpmEpoch;
36009
+ const epoch2 = this.pnpmEpoch;
35884
36010
  const made2 = this.base.mkdir(this.pnpmHome, { recursive: true }).then(() => this.owners ? this.stampLayout() : void 0).catch(() => {
35885
- if (this.pnpmEpoch === epoch) this.pnpmMade = void 0;
36011
+ if (this.pnpmEpoch === epoch2) this.pnpmMade = void 0;
35886
36012
  });
35887
36013
  this.pnpmMade = made2;
35888
36014
  return made2;