@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.
- package/index.mjs +20 -12
- 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
|
|
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
|
|
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
|
|
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
|
|
249
|
+
throw gone(EXPIRED)
|
|
245
250
|
}
|
|
246
|
-
if (!out.access) throw
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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)
|