@openbkn/bkn-sdk 0.1.1-alpha.18 → 0.1.1-alpha.19

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.
@@ -78,6 +78,23 @@ function truncate(s, n) {
78
78
 
79
79
  // src/auth/oauth.ts
80
80
  import { spawn } from "child_process";
81
+
82
+ // src/api/tls.ts
83
+ import { Agent, fetch as undiciFetch } from "undici";
84
+ var insecureAgent;
85
+ function insecureDispatcher() {
86
+ insecureAgent ??= new Agent({ connect: { rejectUnauthorized: false } });
87
+ return insecureAgent;
88
+ }
89
+ function tlsFetch(insecure, url, init) {
90
+ if (!insecure) return fetch(url, init);
91
+ return undiciFetch(url, {
92
+ ...init,
93
+ dispatcher: insecureDispatcher()
94
+ });
95
+ }
96
+
97
+ // src/auth/oauth.ts
81
98
  function normalizeBaseUrl(value) {
82
99
  return value.replace(/\/+$/, "");
83
100
  }
@@ -118,22 +135,9 @@ function mergeCookies(existing, res) {
118
135
  for (const sc of setCookies) add(sc.split(";")[0]?.trim() ?? "");
119
136
  return [...map.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
120
137
  }
121
- async function fetchAuthStatus(baseUrl) {
122
- try {
123
- const res = await fetch(`${normalizeBaseUrl(baseUrl)}/install-status.json`, {
124
- headers: { Accept: "application/json" }
125
- });
126
- if (!res.ok) return null;
127
- const j = await res.json();
128
- if (!j.auth) return null;
129
- return { enabled: Boolean(j.auth.enabled), stack: j.auth.stack };
130
- } catch {
131
- return null;
132
- }
133
- }
134
- async function refreshAccessToken(baseUrl, refreshToken, clientId = "openbkn-sdk") {
138
+ async function refreshAccessToken(baseUrl, refreshToken, clientId = "openbkn-sdk", insecure) {
135
139
  const base = normalizeBaseUrl(baseUrl);
136
- const res = await fetch(`${base}/oauth2/token`, {
140
+ const res = await tlsFetch(insecure, `${base}/oauth2/token`, {
137
141
  method: "POST",
138
142
  headers: {
139
143
  "Content-Type": "application/x-www-form-urlencoded",
@@ -163,10 +167,10 @@ var form = (body) => ({
163
167
  },
164
168
  body: new URLSearchParams(body).toString()
165
169
  });
166
- async function requestDeviceCode(base, clientId, scope, audience) {
170
+ async function requestDeviceCode(base, clientId, scope, audience, insecure) {
167
171
  const params = { client_id: clientId, scope };
168
172
  if (audience) params.audience = audience;
169
- const res = await fetch(`${base}/oauth2/device/auth`, form(params));
173
+ const res = await tlsFetch(insecure, `${base}/oauth2/device/auth`, form(params));
170
174
  if (!res.ok) {
171
175
  throw new Error(`Device auth failed (${res.status}): ${await res.text() || res.statusText}`);
172
176
  }
@@ -178,12 +182,13 @@ async function requestDeviceCode(base, clientId, scope, audience) {
178
182
  }
179
183
  return da;
180
184
  }
181
- async function pollDeviceToken(base, deviceCode, clientId, intervalMs, windowMs) {
185
+ async function pollDeviceToken(base, deviceCode, clientId, intervalMs, windowMs, insecure) {
182
186
  let interval = intervalMs;
183
187
  const deadline = Date.now() + windowMs;
184
188
  while (Date.now() < deadline) {
185
189
  await new Promise((r) => setTimeout(r, interval));
186
- const tokRes = await fetch(
190
+ const tokRes = await tlsFetch(
191
+ insecure,
187
192
  `${base}/oauth2/token`,
188
193
  form({ grant_type: DEVICE_GRANT, device_code: deviceCode, client_id: clientId })
189
194
  );
@@ -209,14 +214,27 @@ async function pollDeviceToken(base, deviceCode, clientId, intervalMs, windowMs)
209
214
  async function deviceLogin(baseUrl, opts = {}) {
210
215
  const base = normalizeBaseUrl(baseUrl);
211
216
  const clientId = opts.clientId ?? DEFAULT_DEVICE_CLIENT_ID;
212
- const da = await requestDeviceCode(base, clientId, opts.scope ?? DEVICE_SCOPE, opts.audience);
217
+ const da = await requestDeviceCode(
218
+ base,
219
+ clientId,
220
+ opts.scope ?? DEVICE_SCOPE,
221
+ opts.audience,
222
+ opts.insecure
223
+ );
213
224
  opts.onPrompt?.({
214
225
  userCode: da.user_code,
215
226
  verificationUri: onBaseHost(base, da.verification_uri),
216
227
  verificationUriComplete: da.verification_uri_complete ? onBaseHost(base, da.verification_uri_complete) : void 0
217
228
  });
218
229
  const windowMs = Math.min(opts.timeoutMs ?? Number.POSITIVE_INFINITY, da.expires_in * 1e3);
219
- return pollDeviceToken(base, da.device_code, clientId, (da.interval ?? 5) * 1e3, windowMs);
230
+ return pollDeviceToken(
231
+ base,
232
+ da.device_code,
233
+ clientId,
234
+ (da.interval ?? 5) * 1e3,
235
+ windowMs,
236
+ opts.insecure
237
+ );
220
238
  }
221
239
  function onBaseHost(base, uri) {
222
240
  try {
@@ -230,10 +248,16 @@ function onBaseHost(base, uri) {
230
248
  async function credentialDeviceLogin(baseUrl, username, password, opts = {}) {
231
249
  const base = normalizeBaseUrl(baseUrl);
232
250
  const clientId = opts.clientId ?? DEFAULT_DEVICE_CLIENT_ID;
233
- const da = await requestDeviceCode(base, clientId, opts.scope ?? DEVICE_SCOPE, opts.audience);
251
+ const da = await requestDeviceCode(
252
+ base,
253
+ clientId,
254
+ opts.scope ?? DEVICE_SCOPE,
255
+ opts.audience,
256
+ opts.insecure
257
+ );
234
258
  let jar = "";
235
259
  const hop = async (url, init) => {
236
- const r = await fetch(url, {
260
+ const r = await tlsFetch(opts.insecure, url, {
237
261
  method: init?.method ?? "GET",
238
262
  headers: { Cookie: jar, Accept: "text/html,*/*;q=0.8", ...init?.headers ?? {} },
239
263
  body: init?.body,
@@ -271,26 +295,25 @@ async function credentialDeviceLogin(baseUrl, username, password, opts = {}) {
271
295
  loc = r.headers.get("location");
272
296
  }
273
297
  const windowMs = Math.min(opts.timeoutMs ?? Number.POSITIVE_INFINITY, da.expires_in * 1e3);
274
- return pollDeviceToken(base, da.device_code, clientId, (da.interval ?? 5) * 1e3, windowMs);
298
+ return pollDeviceToken(
299
+ base,
300
+ da.device_code,
301
+ clientId,
302
+ (da.interval ?? 5) * 1e3,
303
+ windowMs,
304
+ opts.insecure
305
+ );
275
306
  }
276
307
 
277
308
  // src/api/headers.ts
278
309
  function buildHeaders(ctx, extra) {
279
310
  return {
280
- // No token = a no-auth platform (no bkn-safe); send no Authorization.
281
- ...ctx.token ? { authorization: `Bearer ${ctx.token}`, token: ctx.token } : {},
311
+ authorization: `Bearer ${ctx.token}`,
282
312
  "x-business-domain": ctx.businessDomain,
283
313
  ...extra
284
314
  };
285
315
  }
286
316
 
287
- // src/api/tls.ts
288
- function applyTls(ctx) {
289
- if (ctx.insecure && process.env.NODE_TLS_REJECT_UNAUTHORIZED !== "0") {
290
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
291
- }
292
- }
293
-
294
317
  // src/api/http.ts
295
318
  var DEFAULT_TIMEOUT_MS = 3e4;
296
319
  async function request(ctx, path, init = {}) {
@@ -302,11 +325,10 @@ async function request(ctx, path, init = {}) {
302
325
  url.searchParams.set(k, String(v));
303
326
  }
304
327
  }
305
- applyTls(ctx);
306
328
  const hasBody = init.body !== void 0;
307
329
  const controller = new AbortController();
308
330
  const timer = setTimeout(() => controller.abort(), init.timeoutMs ?? DEFAULT_TIMEOUT_MS);
309
- const send = () => fetch(url, {
331
+ const send = () => tlsFetch(ctx.insecure, url, {
310
332
  method: init.method ?? (hasBody ? "POST" : "GET"),
311
333
  headers: buildHeaders(ctx, {
312
334
  ...hasBody ? { "content-type": "application/json" } : {},
@@ -336,7 +358,12 @@ function hintFor(ctx, status2) {
336
358
  async function tryRefresh(ctx) {
337
359
  if (!ctx.refresh) return false;
338
360
  try {
339
- const t = await refreshAccessToken(ctx.baseUrl, ctx.refresh.refreshToken, ctx.refresh.clientId);
361
+ const t = await refreshAccessToken(
362
+ ctx.baseUrl,
363
+ ctx.refresh.refreshToken,
364
+ ctx.refresh.clientId,
365
+ ctx.insecure
366
+ );
340
367
  ctx.token = t.accessToken;
341
368
  if (t.refreshToken) ctx.refresh.refreshToken = t.refreshToken;
342
369
  ctx.refresh.persist(t);
@@ -381,6 +408,7 @@ function isExpired(claims, nowMs = Date.now()) {
381
408
 
382
409
  // src/config/store.ts
383
410
  var PROFILE_RE = /^[A-Za-z0-9_-]{1,64}$/;
411
+ var USER_ID_RE = /^[A-Za-z0-9._@-]{1,128}$/;
384
412
  var IS_WIN = process.platform === "win32";
385
413
  function configDir() {
386
414
  return process.env.BKN_CONFIG_DIR ?? join(homedir(), ".bkn");
@@ -407,7 +435,14 @@ function userDir(baseUrl, userId) {
407
435
  return join(platformDir(baseUrl), "users", userId);
408
436
  }
409
437
  function userIdFromToken(token) {
410
- return decodeJwt(token.idToken ?? "")?.sub ?? decodeJwt(token.accessToken)?.sub ?? "default";
438
+ const sub = decodeJwt(token.idToken ?? "")?.sub ?? decodeJwt(token.accessToken)?.sub;
439
+ if (sub === void 0) return "default";
440
+ if (typeof sub !== "string" || !USER_ID_RE.test(sub) || sub === "." || sub === "..") {
441
+ throw new Error(
442
+ `Token subject '${String(sub)}' is not a usable user id (expected 1-128 chars from [A-Za-z0-9._@-]). Refusing to store this token.`
443
+ );
444
+ }
445
+ return sub;
411
446
  }
412
447
  function readState() {
413
448
  return readJson(statePath()) ?? {};
@@ -432,10 +467,10 @@ function readToken(baseUrl, userId = activeUserId(baseUrl)) {
432
467
  if (!userId) return void 0;
433
468
  return readJson(join(userDir(baseUrl, userId), "token.json")) ?? void 0;
434
469
  }
435
- function writeToken(baseUrl, token) {
470
+ function writeToken(baseUrl, token, opts = {}) {
436
471
  const userId = userIdFromToken(token);
437
472
  writeJson(join(userDir(baseUrl, userId), "token.json"), token, 384);
438
- setActiveUser(baseUrl, userId);
473
+ if (opts.setActive !== false) setActiveUser(baseUrl, userId);
439
474
  return userId;
440
475
  }
441
476
  function deleteToken(baseUrl, userId = activeUserId(baseUrl)) {
@@ -474,6 +509,14 @@ function listPlatforms() {
474
509
  }
475
510
  return out;
476
511
  }
512
+ function findUserId(baseUrl, userOrName) {
513
+ const users = listPlatforms().find((p) => p.baseUrl === baseUrl)?.users ?? [];
514
+ const match = users.find((u) => u.userId === userOrName) ?? users.find((u) => (u.username ?? u.displayName) === userOrName);
515
+ return match?.userId ?? null;
516
+ }
517
+ function usersOfPlatform(baseUrl) {
518
+ return listPlatforms().find((p) => p.baseUrl === baseUrl)?.users ?? [];
519
+ }
477
520
  function decodeKey(key) {
478
521
  try {
479
522
  const b64 = key.replace(/-/g, "+").replace(/_/g, "/");
@@ -499,6 +542,14 @@ function writeJson(path, value, mode = 384) {
499
542
  }
500
543
 
501
544
  // src/config/resolve.ts
545
+ function resolveUserId(baseUrl, userOrName) {
546
+ const id = findUserId(baseUrl, userOrName);
547
+ if (id) return id;
548
+ const known = usersOfPlatform(baseUrl).map((u) => u.username ?? u.userId).join(", ");
549
+ throw new InputError(
550
+ `No saved user '${userOrName}' on ${baseUrl}. Saved: ${known || "(none)"}. See \`openbkn auth users ${baseUrl}\`.`
551
+ );
552
+ }
502
553
  function resolveContext(opts = {}) {
503
554
  const baseUrl = opts.baseUrl ?? process.env.BKN_BASE_URL ?? activePlatform();
504
555
  if (!baseUrl) {
@@ -507,22 +558,29 @@ function resolveContext(opts = {}) {
507
558
  );
508
559
  }
509
560
  const normalized = baseUrl.replace(/\/+$/, "");
510
- const stored = readToken(normalized);
561
+ const user = opts.user ?? process.env.BKN_USER;
562
+ const stored = user ? readToken(normalized, resolveUserId(normalized, user)) : readToken(normalized);
511
563
  const explicit = opts.token ?? process.env.BKN_TOKEN;
512
564
  const token = explicit ?? stored?.accessToken ?? "";
513
- if (!token && !stored?.noAuth) {
565
+ if (!token) {
514
566
  throw new InputError("No access token. Set BKN_TOKEN or run `openbkn auth login`.");
515
567
  }
516
- const insecure = opts.insecure ?? stored?.tlsInsecure ?? false;
568
+ const insecure = opts.insecure ?? false;
517
569
  const refresh = !explicit && stored?.refreshToken ? {
518
570
  refreshToken: stored.refreshToken,
519
571
  persist: (t) => {
520
- writeToken(normalized, {
521
- ...stored,
522
- accessToken: t.accessToken,
523
- refreshToken: t.refreshToken ?? stored.refreshToken,
524
- idToken: t.idToken ?? stored.idToken
525
- });
572
+ writeToken(
573
+ normalized,
574
+ {
575
+ ...stored,
576
+ accessToken: t.accessToken,
577
+ refreshToken: t.refreshToken ?? stored.refreshToken,
578
+ idToken: t.idToken ?? stored.idToken
579
+ },
580
+ // `--user` picks an identity for this command only; a refresh
581
+ // must not promote it to the default for the next one.
582
+ { setActive: !user }
583
+ );
526
584
  }
527
585
  } : void 0;
528
586
  return {
@@ -585,6 +643,13 @@ async function setUserPasswordSafe(ctx, userId, password) {
585
643
  });
586
644
  return { ok: true };
587
645
  }
646
+ async function changePasswordSafe(ctx, account, oldPassword, newPassword) {
647
+ await request(ctx, "/api/safe/v1/auth/change-password", {
648
+ method: "POST",
649
+ body: { account, old_password: oldPassword, new_password: newPassword }
650
+ });
651
+ return { ok: true };
652
+ }
588
653
  function getUserRolesSafe(ctx, userId) {
589
654
  return request(ctx, `${ADMIN}/role-bindings`, { query: { accessor_id: userId } });
590
655
  }
@@ -873,7 +938,6 @@ function extractText(result) {
873
938
  return "";
874
939
  }
875
940
  async function sendChat(ctx, info, query, opts = {}) {
876
- applyTls(ctx);
877
941
  const body = {
878
942
  agent_id: info.id,
879
943
  agent_key: info.key,
@@ -884,7 +948,7 @@ async function sendChat(ctx, info, query, opts = {}) {
884
948
  if (opts.conversationId) body.conversation_id = opts.conversationId;
885
949
  const res = await authFetch(
886
950
  ctx,
887
- () => fetch(`${ctx.baseUrl}${FACTORY}/v1/app/${info.key}/chat/completion`, {
951
+ () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${FACTORY}/v1/app/${info.key}/chat/completion`, {
888
952
  method: "POST",
889
953
  headers: {
890
954
  ...buildHeaders(ctx),
@@ -1110,10 +1174,9 @@ function parseBody(text) {
1110
1174
  }
1111
1175
  }
1112
1176
  async function post(ctx, knId, sessionId, body) {
1113
- applyTls(ctx);
1114
1177
  const res = await authFetch(
1115
1178
  ctx,
1116
- () => fetch(mcpUrl(ctx), {
1179
+ () => tlsFetch(ctx.insecure, mcpUrl(ctx), {
1117
1180
  method: "POST",
1118
1181
  headers: headers(ctx, knId, sessionId),
1119
1182
  body: JSON.stringify(body)
@@ -2906,7 +2969,6 @@ function knPath(knId, path) {
2906
2969
  return `${BASE4}/${encodeURIComponent(knId)}/${path}`;
2907
2970
  }
2908
2971
  async function uploadBkn(ctx, tarBuffer, opts = {}) {
2909
- applyTls(ctx);
2910
2972
  const url = new URL(`${ctx.baseUrl}${BKNS}`);
2911
2973
  url.searchParams.set("branch", opts.branch ?? "main");
2912
2974
  const form2 = new FormData();
@@ -2917,17 +2979,19 @@ async function uploadBkn(ctx, tarBuffer, opts = {}) {
2917
2979
  );
2918
2980
  const res = await authFetch(
2919
2981
  ctx,
2920
- () => fetch(url, { method: "POST", headers: buildHeaders(ctx), body: form2 })
2982
+ () => tlsFetch(ctx.insecure, url, { method: "POST", headers: buildHeaders(ctx), body: form2 })
2921
2983
  );
2922
2984
  const text = await res.text();
2923
2985
  if (!res.ok) throw new HttpError(res.status, res.statusText, text);
2924
2986
  return text ? JSON.parse(text) : void 0;
2925
2987
  }
2926
2988
  async function downloadBkn(ctx, knId, opts = {}) {
2927
- applyTls(ctx);
2928
2989
  const url = new URL(`${ctx.baseUrl}${BKNS}/${encodeURIComponent(knId)}`);
2929
2990
  url.searchParams.set("branch", opts.branch ?? "main");
2930
- const res = await authFetch(ctx, () => fetch(url, { method: "GET", headers: buildHeaders(ctx) }));
2991
+ const res = await authFetch(
2992
+ ctx,
2993
+ () => tlsFetch(ctx.insecure, url, { method: "GET", headers: buildHeaders(ctx) })
2994
+ );
2931
2995
  if (!res.ok) throw new HttpError(res.status, res.statusText, await res.text());
2932
2996
  return Buffer.from(await res.arrayBuffer());
2933
2997
  }
@@ -3921,10 +3985,9 @@ function deltaContent(chunk) {
3921
3985
  return typeof c === "string" ? c : "";
3922
3986
  }
3923
3987
  async function chatCompletionsStream(ctx, model, messages, onDelta) {
3924
- applyTls(ctx);
3925
3988
  const res = await authFetch(
3926
3989
  ctx,
3927
- () => fetch(`${ctx.baseUrl}${API}/chat/completions`, {
3990
+ () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${API}/chat/completions`, {
3928
3991
  method: "POST",
3929
3992
  headers: {
3930
3993
  ...buildHeaders(ctx),
@@ -4059,7 +4122,6 @@ import { basename as basename2, dirname as dirname3, resolve as resolve5 } from
4059
4122
  // src/api/skills.ts
4060
4123
  var BASE5 = "/api/agent-operator-integration/v1";
4061
4124
  async function registerSkillZip(ctx, bytes, opts = {}) {
4062
- applyTls(ctx);
4063
4125
  const form2 = new FormData();
4064
4126
  form2.set("file_type", "zip");
4065
4127
  form2.set("file", new Blob([bytes]), opts.filename ?? "skill.zip");
@@ -4067,7 +4129,7 @@ async function registerSkillZip(ctx, bytes, opts = {}) {
4067
4129
  if (opts.extendInfo) form2.set("extend_info", JSON.stringify(opts.extendInfo));
4068
4130
  const res = await authFetch(
4069
4131
  ctx,
4070
- () => fetch(`${ctx.baseUrl}${BASE5}/skills`, {
4132
+ () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${BASE5}/skills`, {
4071
4133
  method: "POST",
4072
4134
  headers: buildHeaders(ctx),
4073
4135
  body: form2
@@ -4078,13 +4140,12 @@ async function registerSkillZip(ctx, bytes, opts = {}) {
4078
4140
  return text ? JSON.parse(text) : void 0;
4079
4141
  }
4080
4142
  async function updateSkillPackageZip(ctx, skillId, bytes, filename = "skill.zip") {
4081
- applyTls(ctx);
4082
4143
  const form2 = new FormData();
4083
4144
  form2.set("file_type", "zip");
4084
4145
  form2.set("file", new Blob([bytes]), filename);
4085
4146
  const res = await authFetch(
4086
4147
  ctx,
4087
- () => fetch(`${ctx.baseUrl}${BASE5}/skills/${encodeURIComponent(skillId)}/package`, {
4148
+ () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${BASE5}/skills/${encodeURIComponent(skillId)}/package`, {
4088
4149
  method: "PUT",
4089
4150
  headers: buildHeaders(ctx),
4090
4151
  body: form2
@@ -4095,10 +4156,9 @@ async function updateSkillPackageZip(ctx, skillId, bytes, filename = "skill.zip"
4095
4156
  return text ? JSON.parse(text) : void 0;
4096
4157
  }
4097
4158
  async function downloadSkill(ctx, skillId) {
4098
- applyTls(ctx);
4099
4159
  const res = await authFetch(
4100
4160
  ctx,
4101
- () => fetch(`${ctx.baseUrl}${BASE5}/skills/${encodeURIComponent(skillId)}/download`, {
4161
+ () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${BASE5}/skills/${encodeURIComponent(skillId)}/download`, {
4102
4162
  headers: buildHeaders(ctx)
4103
4163
  })
4104
4164
  );
@@ -4254,25 +4314,27 @@ import { basename as basename3 } from "path";
4254
4314
  var PATH = "/api/agent-operator-integration/v1/tool-box";
4255
4315
  var IMPEX = "/api/agent-operator-integration/v1/impex";
4256
4316
  async function exportConfig(ctx, id, type = "toolbox") {
4257
- applyTls(ctx);
4258
4317
  const res = await authFetch(
4259
4318
  ctx,
4260
- () => fetch(`${ctx.baseUrl}${IMPEX}/export/${encodeURIComponent(type)}/${encodeURIComponent(id)}`, {
4261
- headers: buildHeaders(ctx)
4262
- })
4319
+ () => tlsFetch(
4320
+ ctx.insecure,
4321
+ `${ctx.baseUrl}${IMPEX}/export/${encodeURIComponent(type)}/${encodeURIComponent(id)}`,
4322
+ {
4323
+ headers: buildHeaders(ctx)
4324
+ }
4325
+ )
4263
4326
  );
4264
4327
  const buf = new Uint8Array(await res.arrayBuffer());
4265
4328
  if (!res.ok) throw new HttpError(res.status, res.statusText, new TextDecoder().decode(buf));
4266
4329
  return buf;
4267
4330
  }
4268
4331
  async function importConfig(ctx, filePath, type = "toolbox") {
4269
- applyTls(ctx);
4270
4332
  const buf = await readFile2(filePath);
4271
4333
  const form2 = new FormData();
4272
4334
  form2.append("data", new Blob([new Uint8Array(buf)]), basename3(filePath));
4273
4335
  const res = await authFetch(
4274
4336
  ctx,
4275
- () => fetch(`${ctx.baseUrl}${IMPEX}/import/${encodeURIComponent(type)}`, {
4337
+ () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${IMPEX}/import/${encodeURIComponent(type)}`, {
4276
4338
  method: "POST",
4277
4339
  headers: buildHeaders(ctx),
4278
4340
  body: form2
@@ -4283,14 +4345,13 @@ async function importConfig(ctx, filePath, type = "toolbox") {
4283
4345
  return text ? JSON.parse(text) : text;
4284
4346
  }
4285
4347
  async function uploadTool(ctx, boxId, filePath, metadataType = "openapi") {
4286
- applyTls(ctx);
4287
4348
  const buf = await readFile2(filePath);
4288
4349
  const form2 = new FormData();
4289
4350
  form2.append("metadata_type", metadataType);
4290
4351
  form2.append("data", new Blob([new Uint8Array(buf)]), basename3(filePath));
4291
4352
  const res = await authFetch(
4292
4353
  ctx,
4293
- () => fetch(`${ctx.baseUrl}${PATH}/${encodeURIComponent(boxId)}/tool`, {
4354
+ () => tlsFetch(ctx.insecure, `${ctx.baseUrl}${PATH}/${encodeURIComponent(boxId)}/tool`, {
4294
4355
  method: "POST",
4295
4356
  headers: buildHeaders(ctx),
4296
4357
  body: form2
@@ -5257,7 +5318,6 @@ function resolveUrl(ctx, path) {
5257
5318
  return path.startsWith("http") ? path : `${ctx.baseUrl}${path.startsWith("/") ? "" : "/"}${path}`;
5258
5319
  }
5259
5320
  async function rawCall(ctx, path, opts = {}) {
5260
- applyTls(ctx);
5261
5321
  const url = resolveUrl(ctx, path);
5262
5322
  const extra = {};
5263
5323
  for (const h of opts.header ?? []) {
@@ -5286,7 +5346,12 @@ async function rawCall(ctx, path, opts = {}) {
5286
5346
  try {
5287
5347
  const res = await authFetch(
5288
5348
  ctx,
5289
- () => fetch(url, { method, headers: headersFor(), body, signal: controller.signal })
5349
+ () => tlsFetch(ctx.insecure, url, {
5350
+ method,
5351
+ headers: headersFor(),
5352
+ body,
5353
+ signal: controller.signal
5354
+ })
5290
5355
  );
5291
5356
  return { status: res.status, statusText: res.statusText, body: await res.text() };
5292
5357
  } finally {
@@ -5365,7 +5430,6 @@ function createClient(opts = {}) {
5365
5430
  // src/resources/auth.ts
5366
5431
  var auth_exports = {};
5367
5432
  __export(auth_exports, {
5368
- attachNoAuth: () => attachNoAuth,
5369
5433
  attachToken: () => attachToken,
5370
5434
  currentToken: () => currentToken,
5371
5435
  currentTokenFresh: () => currentTokenFresh,
@@ -5403,7 +5467,6 @@ function attachToken(baseUrl, accessToken, opts = {}) {
5403
5467
  accessToken,
5404
5468
  refreshToken: opts.refreshToken,
5405
5469
  idToken: opts.idToken,
5406
- tlsInsecure: opts.insecure,
5407
5470
  // Prefer the account the user typed (-u); device tokens carry no username.
5408
5471
  username: opts.username ?? decodeJwt(opts.idToken ?? accessToken)?.preferred_username
5409
5472
  };
@@ -5411,33 +5474,40 @@ function attachToken(baseUrl, accessToken, opts = {}) {
5411
5474
  setActivePlatform(url);
5412
5475
  return { baseUrl: url, userId, username: usernameOf(token) };
5413
5476
  }
5414
- function attachNoAuth(baseUrl, opts = {}) {
5415
- const url = normalize(baseUrl);
5416
- writeToken(url, { baseUrl: url, accessToken: "", noAuth: true, tlsInsecure: opts.insecure });
5417
- setActivePlatform(url);
5418
- return { baseUrl: url, noAuth: true };
5477
+ function targetUser(baseUrl, userOrName) {
5478
+ if (!userOrName) return activeUserId(baseUrl);
5479
+ const id = findUserId(baseUrl, userOrName);
5480
+ if (!id) {
5481
+ const known = usersOfPlatform(baseUrl).map((u) => u.username ?? u.userId).join(", ");
5482
+ throw new InputError(
5483
+ `No saved user '${userOrName}' on ${baseUrl}. Saved: ${known || "(none)"}.`
5484
+ );
5485
+ }
5486
+ return id;
5419
5487
  }
5420
- function status() {
5488
+ function status(opts = {}) {
5421
5489
  const baseUrl = activePlatform();
5422
5490
  if (!baseUrl) return { hasToken: false };
5423
- const token = readToken(baseUrl);
5491
+ const userId = targetUser(baseUrl, opts.user);
5492
+ const token = readToken(baseUrl, userId);
5424
5493
  return {
5425
5494
  baseUrl,
5426
- userId: activeUserId(baseUrl),
5495
+ userId,
5427
5496
  hasToken: token !== void 0,
5428
5497
  username: usernameOf(token),
5429
5498
  expired: token ? isExpired(decodeJwt(token.accessToken)) : void 0
5430
5499
  };
5431
5500
  }
5432
- function currentToken() {
5501
+ function currentToken(opts = {}) {
5433
5502
  const baseUrl = activePlatform();
5434
- const token = baseUrl ? readToken(baseUrl) : void 0;
5503
+ const token = baseUrl ? readToken(baseUrl, targetUser(baseUrl, opts.user)) : void 0;
5435
5504
  if (!token) throw new InputError("Not logged in. Run `openbkn auth login <url> --token <t>`.");
5436
5505
  return token.accessToken;
5437
5506
  }
5438
- async function currentTokenFresh() {
5507
+ async function currentTokenFresh(opts = {}) {
5439
5508
  const baseUrl = activePlatform();
5440
- const token = baseUrl ? readToken(baseUrl) : void 0;
5509
+ const userId = baseUrl ? targetUser(baseUrl, opts.user) : void 0;
5510
+ const token = baseUrl ? readToken(baseUrl, userId) : void 0;
5441
5511
  if (!baseUrl || !token) {
5442
5512
  throw new InputError("Not logged in. Run `openbkn auth login <url> --token <t>`.");
5443
5513
  }
@@ -5446,22 +5516,27 @@ async function currentTokenFresh() {
5446
5516
  const needsRefresh = decodable ? isExpired(claims) : true;
5447
5517
  if (token.refreshToken && needsRefresh) {
5448
5518
  try {
5449
- const t = await refreshAccessToken(baseUrl, token.refreshToken);
5450
- writeToken(baseUrl, {
5451
- ...token,
5452
- accessToken: t.accessToken,
5453
- refreshToken: t.refreshToken ?? token.refreshToken,
5454
- idToken: t.idToken ?? token.idToken
5455
- });
5519
+ const t = await refreshAccessToken(baseUrl, token.refreshToken, void 0, opts.insecure);
5520
+ writeToken(
5521
+ baseUrl,
5522
+ {
5523
+ ...token,
5524
+ accessToken: t.accessToken,
5525
+ refreshToken: t.refreshToken ?? token.refreshToken,
5526
+ idToken: t.idToken ?? token.idToken
5527
+ },
5528
+ { setActive: !opts.user }
5529
+ );
5456
5530
  return t.accessToken;
5457
5531
  } catch {
5458
5532
  }
5459
5533
  }
5460
5534
  return token.accessToken;
5461
5535
  }
5462
- function whoami() {
5536
+ function whoami(opts = {}) {
5463
5537
  const baseUrl = activePlatform();
5464
- const token = baseUrl ? readToken(baseUrl) : void 0;
5538
+ const userId = baseUrl ? targetUser(baseUrl, opts.user) : void 0;
5539
+ const token = baseUrl ? readToken(baseUrl, userId) : void 0;
5465
5540
  const claims = decodeJwt(token?.idToken ?? "") ?? decodeJwt(token?.accessToken ?? "");
5466
5541
  if (!claims) {
5467
5542
  throw new InputError(
@@ -5471,7 +5546,7 @@ function whoami() {
5471
5546
  return {
5472
5547
  ...claims,
5473
5548
  baseUrl: baseUrl ?? void 0,
5474
- userId: baseUrl ? activeUserId(baseUrl) : void 0,
5549
+ userId,
5475
5550
  username: usernameOf(token)
5476
5551
  };
5477
5552
  }
@@ -5535,7 +5610,6 @@ export {
5535
5610
  formatError,
5536
5611
  isHeadless,
5537
5612
  openBrowser,
5538
- fetchAuthStatus,
5539
5613
  deviceLogin,
5540
5614
  credentialDeviceLogin,
5541
5615
  request,
@@ -5550,6 +5624,7 @@ export {
5550
5624
  writePlatformConfig,
5551
5625
  resolveContext,
5552
5626
  getUserSafe,
5627
+ changePasswordSafe,
5553
5628
  admin,
5554
5629
  agents,
5555
5630
  context,
@@ -5566,7 +5641,6 @@ export {
5566
5641
  vega,
5567
5642
  createClient,
5568
5643
  attachToken,
5569
- attachNoAuth,
5570
5644
  status,
5571
5645
  currentToken,
5572
5646
  currentTokenFresh,
@@ -5579,4 +5653,4 @@ export {
5579
5653
  exportCreds,
5580
5654
  auth_exports
5581
5655
  };
5582
- //# sourceMappingURL=chunk-LCOMMFH7.js.map
5656
+ //# sourceMappingURL=chunk-ISJHU26W.js.map