@zhafron/opencode-kiro-auth 1.2.0 → 1.2.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.
@@ -50,25 +50,46 @@ export async function startIDCAuthServer(authData, startPort = 19847, portRange
50
50
  };
51
51
  const poll = async () => {
52
52
  try {
53
- const body = new URLSearchParams({
54
- grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
55
- device_code: authData.deviceCode,
56
- client_id: authData.clientId,
57
- client_secret: authData.clientSecret
58
- });
53
+ const body = {
54
+ grantType: 'urn:ietf:params:oauth:grant-type:device_code',
55
+ deviceCode: authData.deviceCode,
56
+ clientId: authData.clientId,
57
+ clientSecret: authData.clientSecret
58
+ };
59
59
  const res = await fetch(`https://oidc.${authData.region}.amazonaws.com/token`, {
60
60
  method: 'POST',
61
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
62
- body: body.toString()
61
+ headers: { 'Content-Type': 'application/json' },
62
+ body: JSON.stringify(body)
63
63
  });
64
- const d = await res.json();
64
+ const responseText = await res.text();
65
+ let d = {};
66
+ if (responseText) {
67
+ try {
68
+ d = JSON.parse(responseText);
69
+ }
70
+ catch (parseError) {
71
+ logger.error(`Auth polling error: Failed to parse JSON (status ${res.status})`, parseError);
72
+ throw parseError;
73
+ }
74
+ }
65
75
  if (res.ok) {
66
- const acc = d.access_token, ref = d.refresh_token, exp = Date.now() + d.expires_in * 1000;
67
- const infoRes = await fetch('https://view.awsapps.com/api/user/info', {
68
- headers: { Authorization: `Bearer ${acc}` }
69
- });
70
- const info = await infoRes.json();
71
- const email = info.email || info.userName || 'builder-id@aws.amazon.com';
76
+ const acc = d.access_token || d.accessToken, ref = d.refresh_token || d.refreshToken, exp = Date.now() + (d.expires_in || d.expiresIn || 0) * 1000;
77
+ let email = 'builder-id@aws.amazon.com';
78
+ try {
79
+ const infoRes = await fetch('https://view.awsapps.com/api/user/info', {
80
+ headers: { Authorization: `Bearer ${acc}` }
81
+ });
82
+ if (infoRes.ok) {
83
+ const info = await infoRes.json();
84
+ email = info.email || info.userName || email;
85
+ }
86
+ else {
87
+ logger.warn(`User info request failed with status ${infoRes.status}; using fallback email`);
88
+ }
89
+ }
90
+ catch (infoError) {
91
+ logger.warn(`Failed to fetch user info; using fallback email: ${infoError?.message || infoError}`);
92
+ }
72
93
  status.status = 'success';
73
94
  if (resolver)
74
95
  resolver({
@@ -87,7 +108,7 @@ export async function startIDCAuthServer(authData, startPort = 19847, portRange
87
108
  else {
88
109
  status.status = 'failed';
89
110
  status.error = d.error_description || d.error;
90
- logger.error(`Auth polling failed: ${status.error}`);
111
+ logger.error(`Auth polling failed a: ${status.error}`);
91
112
  if (rejector)
92
113
  rejector(new Error(status.error));
93
114
  setTimeout(cleanup, 2000);
@@ -96,7 +117,7 @@ export async function startIDCAuthServer(authData, startPort = 19847, portRange
96
117
  catch (e) {
97
118
  status.status = 'failed';
98
119
  status.error = e.message;
99
- logger.error(`Auth polling error: ${e.message}`, e);
120
+ logger.error(`Auth polling error b: ${e.message}`, e);
100
121
  if (rejector)
101
122
  rejector(e);
102
123
  setTimeout(cleanup, 2000);
@@ -67,7 +67,11 @@ export async function loadAccounts() {
67
67
  return withLock(path, async () => {
68
68
  try {
69
69
  const content = await fs.readFile(path, 'utf-8');
70
- return JSON.parse(content);
70
+ const parsed = JSON.parse(content);
71
+ if (!parsed || !Array.isArray(parsed.accounts)) {
72
+ return { version: 1, accounts: [], activeIndex: -1 };
73
+ }
74
+ return parsed;
71
75
  }
72
76
  catch {
73
77
  return { version: 1, accounts: [], activeIndex: -1 };
@@ -93,7 +97,11 @@ export async function loadUsage() {
93
97
  return withLock(path, async () => {
94
98
  try {
95
99
  const content = await fs.readFile(path, 'utf-8');
96
- return JSON.parse(content);
100
+ const parsed = JSON.parse(content);
101
+ if (!parsed || typeof parsed.usage !== 'object' || parsed.usage === null) {
102
+ return { version: 1, usage: {} };
103
+ }
104
+ return parsed;
97
105
  }
98
106
  catch {
99
107
  return { version: 1, usage: {} };
package/dist/plugin.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { loadConfig } from './plugin/config';
2
+ import { exec } from 'node:child_process';
2
3
  import { AccountManager, generateAccountId } from './plugin/accounts';
3
4
  import { accessTokenExpired, encodeRefreshToken } from './kiro/auth';
4
5
  import { refreshAccessToken } from './plugin/token';
@@ -23,6 +24,19 @@ const formatUsageMessage = (usedCount, limitCount, email) => {
23
24
  }
24
25
  return `Usage (${email}): ${usedCount}`;
25
26
  };
27
+ const openBrowser = (url) => {
28
+ const escapedUrl = url.replace(/"/g, '\\"');
29
+ const platform = process.platform;
30
+ const command = platform === 'win32'
31
+ ? `cmd /c start "" "${escapedUrl}"`
32
+ : platform === 'darwin'
33
+ ? `open "${escapedUrl}"`
34
+ : `xdg-open "${escapedUrl}"`;
35
+ exec(command, (error) => {
36
+ if (error)
37
+ logger.warn(`Failed to open browser automatically: ${error.message}`, error);
38
+ });
39
+ };
26
40
  export const createKiroPlugin = (id) => async ({ client, directory }) => {
27
41
  const config = loadConfig(directory);
28
42
  const showToast = (message, variant) => {
@@ -272,9 +286,10 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
272
286
  try {
273
287
  const authData = await authorizeKiroIDC(region);
274
288
  const { url, waitForAuth } = await startIDCAuthServer(authData, config.auth_server_port_start, config.auth_server_port_range);
289
+ openBrowser(url);
275
290
  resolve({
276
291
  url,
277
- instructions: 'Opening browser...',
292
+ instructions: `Open this URL to continue: ${url}`,
278
293
  method: 'auto',
279
294
  callback: async () => {
280
295
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhafron/opencode-kiro-auth",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "OpenCode plugin for AWS Kiro (CodeWhisperer) providing access to Claude models",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",