@magpie-community/opencode-kiro-auth 0.1.12 → 0.1.13

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 (3) hide show
  1. package/README.md +6 -0
  2. package/index.mjs +24 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -19,6 +19,12 @@ Power) and makes its requests, in OpenCode and in magpie. Provider id:
19
19
  the browser to AWS, and trades the code AWS returns.
20
20
  - The account is named by the email Kiro has for it (`Get-Usage-Limits`),
21
21
  and its plan is read from the same call.
22
+ - Kiro keeps a Google, a GitHub, a Builder ID and an Identity Center
23
+ sign-in of one email as different accounts. The sign-in carries a `uid`
24
+ (`google`, `github`, `builderid`, `enterprise`), so magpie keeps each one
25
+ beside the others, and a sign-in again the same way replaces only its
26
+ own account. An account signed in before 0.1.13 is given its `uid` on
27
+ its first request, model listing, usage read or renewal.
22
28
  - A company's own identity provider (`external_idp`) is not supported
23
29
  here. Sign in with `kiro-cli login` and use the next method instead.
24
30
  - **Kiro CLI's or Kiro IDE's sign-in**: uses the account kiro-cli is signed
package/index.mjs CHANGED
@@ -50,6 +50,12 @@ const SIGN_IN_TIMEOUT = 10 * 60 * 1000
50
50
  const BUILDER_ID_START = "https://view.awsapps.com/start"
51
51
  const BUILDER_ID_PROFILE = "arn:aws:codewhisperer:us-east-1:638616132270:profile/AAAACCCCXXXX"
52
52
  const isBuilderID = (provider) => String(provider ?? "").toLowerCase() === "builderid"
53
+ // uidOf is what tells two Kiro accounts of one email apart: the way it was
54
+ // signed in to. Kiro keeps a Google and a GitHub sign-in of one email (or
55
+ // Builder ID's, or Identity Center's) as different accounts, and magpie
56
+ // keeps a sign-in of an email already signed in as that account unless
57
+ // both have a uid and the two differ (#309). "" when it isn't known.
58
+ const uidOf = (loginProvider) => String(loginProvider ?? "").trim().toLowerCase()
53
59
 
54
60
  const env = (k) => process.env[k] ?? ""
55
61
  const home = () => env("HOME") || homedir()
@@ -438,11 +444,15 @@ function account(client) {
438
444
  lock = run.catch(() => {})
439
445
  return run
440
446
  }
447
+ // an account signed in here before its uid was kept is given it, so a
448
+ // sign-in with another way to the same email no longer replaces it
449
+ const uidSaved = new Set()
450
+ const uidField = (auth) => (!auth?.uid && uidOf(auth?.loginProvider) ? { uid: uidOf(auth.loginProvider) } : {})
441
451
  const save = async (auth, c) => {
442
452
  if (!c.own || !client?.auth?.set) return
443
453
  const { type: _t, ...rest } = auth
444
454
  await client.auth.set({ path: { id: ID }, body: { ...rest, type: "oauth", access: c.access, refresh: c.refresh, expires: c.expires,
445
- profileArn: c.profile, region: c.region } }).catch(() => {})
455
+ profileArn: c.profile, region: c.region, ...uidField(auth) } }).catch(() => {})
446
456
  }
447
457
  const creds = (auth, stale = false) =>
448
458
  locked(async () => {
@@ -460,6 +470,7 @@ function account(client) {
460
470
  }
461
471
  read = newest(read)
462
472
  let c = held?.id === id ? held.c : null
473
+ let saved = false
463
474
  if (!c || read.access !== c.access || !fresh(c) || stale) {
464
475
  if (!read.profile && c && read.access === c.access) read.profile = c.profile
465
476
  if (stale && c && read.access !== c.access && fresh(read)) stale = false // the owner refreshed it already
@@ -468,11 +479,20 @@ function account(client) {
468
479
  if (c.method === "apikey") throw gone("Kiro turned down the API key saved on the provider")
469
480
  c = renewed(c, await refresh(c))
470
481
  await save(auth, c)
482
+ saved = true
471
483
  }
472
484
  }
473
485
  if (!c.profile) {
474
486
  c.profile = await profileOf(c)
475
- if (!auth?.profileArn) await save(auth, c)
487
+ if (!auth?.profileArn && !saved) {
488
+ await save(auth, c)
489
+ saved = true
490
+ }
491
+ }
492
+ // once per token: a save that didn't take isn't tried on every request
493
+ if (!saved && c.own && uidField(auth).uid && !uidSaved.has(c.access)) {
494
+ uidSaved.add(c.access)
495
+ await save(auth, c)
476
496
  }
477
497
  held = { id, c }
478
498
  return { token: c.access, tokenType: tokenType(c), profile: c.profile, region: regionOf(c.profile, c.region) }
@@ -493,7 +513,7 @@ function account(client) {
493
513
  const out = { access: c.access, expires: c.expires }
494
514
  if (c.refresh !== auth.refresh) out.refresh = c.refresh
495
515
  if (c.profile && c.profile !== auth.profileArn) out.profileArn = c.profile
496
- return out
516
+ return { ...out, ...uidField(auth) }
497
517
  })
498
518
  return creds
499
519
  }
@@ -1405,6 +1425,7 @@ async function browserSignIn() {
1405
1425
  const who = await whoIs(c)
1406
1426
  const user = who.email || "Kiro account"
1407
1427
  finish({ type: "success", provider: ID, refresh: c.refresh, access: c.access, expires: c.expires, accountId: user,
1428
+ ...(uidOf(c.loginProvider) ? { uid: uidOf(c.loginProvider) } : {}),
1408
1429
  method: c.method, loginProvider: c.loginProvider, region: c.region, profileArn: who.profile,
1409
1430
  ...(c.clientId ? { clientId: c.clientId, clientSecret: c.clientSecret } : {}), ...(who.plan ? { plan: who.plan } : {}) })
1410
1431
  html(200, page(true, "You're signed in", `${user} is signed in. You can close this tab.`))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-kiro-auth",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Kiro subscriptions (Free, Pro, Pro+, Power) in OpenCode and magpie",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",