@magpie-community/opencode-kiro-auth 0.1.2 → 0.1.3

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/index.mjs +20 -12
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -189,6 +189,11 @@ async function saveBack(c) {
189
189
  // ---- tokens --------------------------------------------------------------------
190
190
 
191
191
  const EXPIRED = "Kiro's sign-in has expired; sign in again"
192
+
193
+ // gone is an error saying the sign-in itself is gone — refused, or never
194
+ // there — which alone answers a request with the 401 magpie marks the
195
+ // account lapsed on; a refresh that timed out or met a 5xx may pass.
196
+ const gone = (msg) => Object.assign(new Error(msg), { gone: true })
192
197
  const fresh = (c) => c.method === "apikey" || !c.expires || c.expires - Date.now() > 2 * 60 * 1000
193
198
 
194
199
  async function post(url, contentType, body, headers = {}) {
@@ -201,7 +206,7 @@ async function post(url, contentType, body, headers = {}) {
201
206
  }
202
207
  const text = await res.text()
203
208
  if (!res.ok) {
204
- if ([400, 401, 403].includes(res.status)) throw new Error(EXPIRED)
209
+ if ([400, 401, 403].includes(res.status)) throw gone(EXPIRED)
205
210
  throw new Error(`refreshing Kiro's sign-in: ${res.status}`)
206
211
  }
207
212
  return JSON.parse(text)
@@ -218,7 +223,7 @@ async function refresh(c) {
218
223
  if (n && n.dbKey === c.dbKey && n.access !== c.access && fresh(n)) return n
219
224
  }
220
225
  }
221
- if (!c.refresh) throw new Error(EXPIRED)
226
+ if (!c.refresh) throw gone(EXPIRED)
222
227
  let out
223
228
  switch (c.method) {
224
229
  case "social": {
@@ -234,16 +239,16 @@ async function refresh(c) {
234
239
  break
235
240
  }
236
241
  case "external-idp": {
237
- if (!c.tokenURL) throw new Error(EXPIRED + " with `kiro-cli login`")
242
+ if (!c.tokenURL) throw gone(EXPIRED + " with `kiro-cli login`")
238
243
  const form = new URLSearchParams({ grant_type: "refresh_token", client_id: c.clientId ?? "", refresh_token: c.refresh })
239
244
  const r = await post(c.tokenURL, "application/x-www-form-urlencoded", form.toString())
240
245
  out = { access: r.access_token, refresh: r.refresh_token, expiresIn: r.expires_in }
241
246
  break
242
247
  }
243
248
  default:
244
- throw new Error(EXPIRED)
249
+ throw gone(EXPIRED)
245
250
  }
246
- if (!out.access) throw new Error(EXPIRED)
251
+ if (!out.access) throw gone(EXPIRED)
247
252
  const n = { ...c, access: out.access, expires: Date.now() + (out.expiresIn > 0 ? out.expiresIn : 3600) * 1000 }
248
253
  if (out.refresh) n.refresh = out.refresh
249
254
  await saveBack(n)
@@ -309,7 +314,10 @@ async function profileOf(c) {
309
314
  body: "{}",
310
315
  signal: AbortSignal.timeout(20_000),
311
316
  })
312
- if (!res.ok) throw new Error(`Kiro didn't take the API key: ${res.status}`)
317
+ if (!res.ok) {
318
+ const msg = `Kiro didn't take the API key: ${res.status}`
319
+ throw res.status === 401 || res.status === 403 ? gone(msg) : new Error(msg)
320
+ }
313
321
  const arn = (await res.json().catch(() => null))?.profile?.arn
314
322
  if (!arn) throw new Error("Kiro didn't say which profile the API key is for")
315
323
  return arn
@@ -411,7 +419,7 @@ function account(client) {
411
419
  const read = await credOf(auth)
412
420
  if (!read) {
413
421
  held = null
414
- throw new Error(
422
+ throw gone(
415
423
  auth?.source
416
424
  ? "Kiro isn't signed in; add the Kiro subscription in magpie, sign in with `kiro-cli login` or the Kiro IDE, or save a Kiro API key on the provider"
417
425
  : "this Kiro account's sign-in is gone; add it again in magpie",
@@ -423,7 +431,7 @@ function account(client) {
423
431
  if (stale && c && read.access !== c.access && fresh(read)) stale = false // the owner refreshed it already
424
432
  c = read
425
433
  if (!fresh(c) || stale) {
426
- if (c.method === "apikey") throw new Error("Kiro turned down the API key")
434
+ if (c.method === "apikey") throw gone("Kiro turned down the API key")
427
435
  c = await refresh(c)
428
436
  await save(auth, c)
429
437
  }
@@ -716,7 +724,7 @@ const ERROR_TYPES = { 400: "invalid_request_error", 401: "authentication_error",
716
724
  404: "not_found_error", 413: "request_too_large", 429: "rate_limit_error", 503: "overloaded_error", 529: "overloaded_error" }
717
725
  const errorType = (status) => ERROR_TYPES[status] ?? "api_error"
718
726
  const errorResponse = (status, message) =>
719
- new Response(JSON.stringify({ type: "error", error: { type: errorType(status), message: "Kiro: " + message } }), {
727
+ new Response(JSON.stringify({ type: "error", error: { type: errorType(status), message } }), {
720
728
  status,
721
729
  headers: { "Content-Type": "application/json" },
722
730
  })
@@ -1037,7 +1045,7 @@ async function reply(it, model, stream) {
1037
1045
  break
1038
1046
  case "error":
1039
1047
  close()
1040
- ctl.enqueue(sse("error", { error: { type: "api_error", message: "Kiro: " + e.text } }))
1048
+ ctl.enqueue(sse("error", { error: { type: "api_error", message: e.text } }))
1041
1049
  return ctl.close()
1042
1050
  case "stop":
1043
1051
  close()
@@ -1062,7 +1070,7 @@ async function generate(creds, auth, req, signal) {
1062
1070
  try {
1063
1071
  a = await creds(auth)
1064
1072
  } catch (e) {
1065
- return errorResponse(401, e.message)
1073
+ return errorResponse(e?.gone ? 401 : 502, e.message)
1066
1074
  }
1067
1075
  let res
1068
1076
  try {
@@ -1076,7 +1084,7 @@ async function generate(creds, auth, req, signal) {
1076
1084
  try {
1077
1085
  a = await creds(auth, true)
1078
1086
  } catch (e) {
1079
- return errorResponse(401, e.message)
1087
+ return errorResponse(e?.gone ? 401 : 502, e.message)
1080
1088
  }
1081
1089
  try {
1082
1090
  res = await sendKiro(a, buildKiro(req, model, a.profile, budget), signal)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-kiro-auth",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Kiro subscriptions (Free, Pro, Pro+, Power) in OpenCode and magpie",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",