@wayai/cli 0.2.47 → 0.2.48
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/dist/commands/login.js +28 -16
- package/dist/commands/login.js.map +1 -1
- package/dist/lib/auth.d.ts +2 -28
- package/dist/lib/auth.js +3 -51
- package/dist/lib/auth.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/login.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Token login: User pastes a way_ scoped token directly
|
|
6
6
|
*/
|
|
7
7
|
import * as readline from 'node:readline';
|
|
8
|
-
import { generateState, generateCodeVerifier, generateCodeChallenge,
|
|
8
|
+
import { generateState, generateCodeVerifier, generateCodeChallenge, startCallbackServer, exchangeCodeForTokens, validateToken, getAuthKitDomain, getAuthKitClientId, OAUTH_CALLBACK_PORT, } from '../lib/auth.js';
|
|
9
9
|
import { writeConfig } from '../lib/config.js';
|
|
10
10
|
function prompt(question, defaultValue) {
|
|
11
11
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -43,8 +43,8 @@ async function loginWithBrowser(apiUrl) {
|
|
|
43
43
|
const codeVerifier = generateCodeVerifier();
|
|
44
44
|
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
45
45
|
const state = generateState();
|
|
46
|
-
//
|
|
47
|
-
const port =
|
|
46
|
+
// Fixed port so the redirect URI matches what's registered in WorkOS
|
|
47
|
+
const port = OAUTH_CALLBACK_PORT;
|
|
48
48
|
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
49
49
|
// Build AuthKit authorization URL with PKCE
|
|
50
50
|
const authorizeUrl = new URL(`${authkitDomain}/oauth2/authorize`);
|
|
@@ -54,25 +54,37 @@ async function loginWithBrowser(apiUrl) {
|
|
|
54
54
|
authorizeUrl.searchParams.set('code_challenge', codeChallenge);
|
|
55
55
|
authorizeUrl.searchParams.set('code_challenge_method', 'S256');
|
|
56
56
|
authorizeUrl.searchParams.set('state', state);
|
|
57
|
-
// Start callback server before opening browser
|
|
58
|
-
const callbackPromise = startCallbackServer(port, state);
|
|
59
|
-
// Try to open browser
|
|
60
|
-
const openedBrowser = await tryOpenBrowser(authorizeUrl.toString());
|
|
61
|
-
if (!openedBrowser) {
|
|
62
|
-
console.log(`\nOpen this URL in your browser to log in:\n\n ${authorizeUrl.toString()}\n`);
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
console.log('Opening browser for login...');
|
|
66
|
-
}
|
|
67
57
|
try {
|
|
58
|
+
// Start callback server before opening browser
|
|
59
|
+
const callbackPromise = startCallbackServer(port, state);
|
|
60
|
+
// Try to open browser
|
|
61
|
+
const openedBrowser = await tryOpenBrowser(authorizeUrl.toString());
|
|
62
|
+
if (!openedBrowser) {
|
|
63
|
+
console.log(`\nOpen this URL in your browser to log in:\n\n ${authorizeUrl.toString()}\n`);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.log('Opening browser for login...');
|
|
67
|
+
}
|
|
68
68
|
const { code } = await callbackPromise;
|
|
69
69
|
console.log('Exchanging authorization code...');
|
|
70
70
|
const tokens = await exchangeCodeForTokens(authkitDomain, clientId, code, codeVerifier, redirectUri);
|
|
71
|
+
// Exchange the short-lived JWT for a long-lived way_ token
|
|
72
|
+
console.log('Generating API token...');
|
|
73
|
+
const tokenRes = await fetch(`${apiUrl}/auth/connect/token`, {
|
|
74
|
+
method: 'POST',
|
|
75
|
+
headers: { Authorization: `Bearer ${tokens.access_token}` },
|
|
76
|
+
});
|
|
77
|
+
if (!tokenRes.ok) {
|
|
78
|
+
const body = await tokenRes.text();
|
|
79
|
+
throw new Error(`Token generation failed (${tokenRes.status}): ${body}`);
|
|
80
|
+
}
|
|
81
|
+
const { token } = await tokenRes.json();
|
|
82
|
+
if (!token || typeof token !== 'string') {
|
|
83
|
+
throw new Error('Invalid response from token endpoint');
|
|
84
|
+
}
|
|
71
85
|
writeConfig({
|
|
72
86
|
api_url: apiUrl,
|
|
73
|
-
|
|
74
|
-
refresh_token: tokens.refresh_token,
|
|
75
|
-
token_expires_at: new Date(Date.now() + tokens.expires_in * 1000).toISOString(),
|
|
87
|
+
token,
|
|
76
88
|
});
|
|
77
89
|
console.log('\nLogin successful!');
|
|
78
90
|
console.log('Configuration saved to ~/.wayai/config.json');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/auth.d.ts
CHANGED
|
@@ -6,51 +6,28 @@
|
|
|
6
6
|
* 2. Token login (--token): User pastes a way_ scoped token directly
|
|
7
7
|
*
|
|
8
8
|
* The CLI exchanges codes directly with AuthKit's token endpoint.
|
|
9
|
-
* No backend involvement in the auth flow (unlike the old /auth/cli/* endpoints).
|
|
10
9
|
*/
|
|
11
10
|
import type { CliConfig } from './config.js';
|
|
12
|
-
/**
|
|
13
|
-
* Generate a cryptographically random PKCE code verifier (43-128 chars, base64url).
|
|
14
|
-
*/
|
|
15
11
|
export declare function generateCodeVerifier(): string;
|
|
16
|
-
/**
|
|
17
|
-
* Generate the S256 code challenge from a code verifier.
|
|
18
|
-
*/
|
|
19
12
|
export declare function generateCodeChallenge(verifier: string): Promise<string>;
|
|
20
|
-
/**
|
|
21
|
-
* Generate a random state parameter for CSRF protection.
|
|
22
|
-
*/
|
|
23
13
|
export declare function generateState(): string;
|
|
24
|
-
/**
|
|
25
|
-
* Exchange an authorization code for JWT + refresh token at AuthKit's token endpoint.
|
|
26
|
-
*/
|
|
27
14
|
export declare function exchangeCodeForTokens(authkitDomain: string, clientId: string, code: string, codeVerifier: string, redirectUri: string): Promise<{
|
|
28
15
|
access_token: string;
|
|
29
16
|
refresh_token: string;
|
|
30
17
|
expires_in: number;
|
|
31
18
|
}>;
|
|
32
|
-
/**
|
|
33
|
-
* Refresh an expired access token using the refresh token.
|
|
34
|
-
* Returns new tokens. If the server rotates refresh tokens,
|
|
35
|
-
* the new refresh_token is included in the response.
|
|
36
|
-
*/
|
|
37
19
|
export declare function refreshAccessToken(authkitDomain: string, clientId: string, refreshToken: string): Promise<{
|
|
38
20
|
access_token: string;
|
|
39
21
|
refresh_token?: string;
|
|
40
22
|
expires_in: number;
|
|
41
23
|
}>;
|
|
42
|
-
/**
|
|
43
|
-
* Validate a way_ token by making a lightweight API call.
|
|
44
|
-
*/
|
|
45
24
|
export declare function validateToken(apiUrl: string, token: string): Promise<void>;
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
*/
|
|
25
|
+
/** Fixed port for OAuth callback — must match the redirect URI registered in WorkOS */
|
|
26
|
+
export declare const OAUTH_CALLBACK_PORT = 3829;
|
|
49
27
|
export declare function startCallbackServer(port: number, expectedState: string, timeoutMs?: number): Promise<{
|
|
50
28
|
code: string;
|
|
51
29
|
port: number;
|
|
52
30
|
}>;
|
|
53
|
-
export declare function findAvailablePort(): Promise<number>;
|
|
54
31
|
export declare function getAuthKitDomain(): string;
|
|
55
32
|
export declare function getAuthKitClientId(): string;
|
|
56
33
|
/**
|
|
@@ -59,9 +36,6 @@ export declare function getAuthKitClientId(): string;
|
|
|
59
36
|
* - For OAuth JWT: checks expiry, refreshes if needed, updates config
|
|
60
37
|
*/
|
|
61
38
|
export declare function getAccessToken(config: CliConfig): Promise<string>;
|
|
62
|
-
/**
|
|
63
|
-
* Read config and get access token, or exit with error.
|
|
64
|
-
*/
|
|
65
39
|
export declare function requireAuth(): Promise<{
|
|
66
40
|
config: CliConfig;
|
|
67
41
|
accessToken: string;
|
package/dist/lib/auth.js
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* 2. Token login (--token): User pastes a way_ scoped token directly
|
|
7
7
|
*
|
|
8
8
|
* The CLI exchanges codes directly with AuthKit's token endpoint.
|
|
9
|
-
* No backend involvement in the auth flow (unlike the old /auth/cli/* endpoints).
|
|
10
9
|
*/
|
|
11
10
|
import * as crypto from 'node:crypto';
|
|
12
11
|
import * as http from 'node:http';
|
|
@@ -15,31 +14,19 @@ import { setSentryUser } from './sentry.js';
|
|
|
15
14
|
// =============================================================================
|
|
16
15
|
// PKCE Utilities
|
|
17
16
|
// =============================================================================
|
|
18
|
-
/**
|
|
19
|
-
* Generate a cryptographically random PKCE code verifier (43-128 chars, base64url).
|
|
20
|
-
*/
|
|
21
17
|
export function generateCodeVerifier() {
|
|
22
18
|
return crypto.randomBytes(32).toString('base64url');
|
|
23
19
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Generate the S256 code challenge from a code verifier.
|
|
26
|
-
*/
|
|
27
20
|
export async function generateCodeChallenge(verifier) {
|
|
28
21
|
const hash = crypto.createHash('sha256').update(verifier).digest();
|
|
29
22
|
return hash.toString('base64url');
|
|
30
23
|
}
|
|
31
|
-
/**
|
|
32
|
-
* Generate a random state parameter for CSRF protection.
|
|
33
|
-
*/
|
|
34
24
|
export function generateState() {
|
|
35
25
|
return crypto.randomBytes(16).toString('base64url');
|
|
36
26
|
}
|
|
37
27
|
// =============================================================================
|
|
38
28
|
// AuthKit Token Exchange
|
|
39
29
|
// =============================================================================
|
|
40
|
-
/**
|
|
41
|
-
* Exchange an authorization code for JWT + refresh token at AuthKit's token endpoint.
|
|
42
|
-
*/
|
|
43
30
|
export async function exchangeCodeForTokens(authkitDomain, clientId, code, codeVerifier, redirectUri) {
|
|
44
31
|
const response = await fetch(`${authkitDomain}/oauth2/token`, {
|
|
45
32
|
method: 'POST',
|
|
@@ -58,11 +45,6 @@ export async function exchangeCodeForTokens(authkitDomain, clientId, code, codeV
|
|
|
58
45
|
}
|
|
59
46
|
return response.json();
|
|
60
47
|
}
|
|
61
|
-
/**
|
|
62
|
-
* Refresh an expired access token using the refresh token.
|
|
63
|
-
* Returns new tokens. If the server rotates refresh tokens,
|
|
64
|
-
* the new refresh_token is included in the response.
|
|
65
|
-
*/
|
|
66
48
|
export async function refreshAccessToken(authkitDomain, clientId, refreshToken) {
|
|
67
49
|
const response = await fetch(`${authkitDomain}/oauth2/token`, {
|
|
68
50
|
method: 'POST',
|
|
@@ -76,7 +58,6 @@ export async function refreshAccessToken(authkitDomain, clientId, refreshToken)
|
|
|
76
58
|
if (!response.ok) {
|
|
77
59
|
const status = response.status;
|
|
78
60
|
const body = await response.text();
|
|
79
|
-
// Only clear tokens on invalid_grant (expired/revoked refresh token)
|
|
80
61
|
if (status === 400 || status === 401) {
|
|
81
62
|
let isInvalidGrant = false;
|
|
82
63
|
try {
|
|
@@ -92,9 +73,6 @@ export async function refreshAccessToken(authkitDomain, clientId, refreshToken)
|
|
|
92
73
|
}
|
|
93
74
|
return response.json();
|
|
94
75
|
}
|
|
95
|
-
/**
|
|
96
|
-
* Validate a way_ token by making a lightweight API call.
|
|
97
|
-
*/
|
|
98
76
|
export async function validateToken(apiUrl, token) {
|
|
99
77
|
const response = await fetch(`${apiUrl}/api/auth/me`, {
|
|
100
78
|
headers: { Authorization: `Bearer ${token}` },
|
|
@@ -106,9 +84,8 @@ export async function validateToken(apiUrl, token) {
|
|
|
106
84
|
// =============================================================================
|
|
107
85
|
// Callback Server
|
|
108
86
|
// =============================================================================
|
|
109
|
-
/**
|
|
110
|
-
|
|
111
|
-
*/
|
|
87
|
+
/** Fixed port for OAuth callback — must match the redirect URI registered in WorkOS */
|
|
88
|
+
export const OAUTH_CALLBACK_PORT = 3829;
|
|
112
89
|
export function startCallbackServer(port, expectedState, timeoutMs = 120_000) {
|
|
113
90
|
return new Promise((resolve, reject) => {
|
|
114
91
|
const server = http.createServer((req, res) => {
|
|
@@ -166,28 +143,11 @@ export function startCallbackServer(port, expectedState, timeoutMs = 120_000) {
|
|
|
166
143
|
});
|
|
167
144
|
});
|
|
168
145
|
}
|
|
169
|
-
export async function findAvailablePort() {
|
|
170
|
-
return new Promise((resolve, reject) => {
|
|
171
|
-
const server = http.createServer();
|
|
172
|
-
server.listen(0, '127.0.0.1', () => {
|
|
173
|
-
const addr = server.address();
|
|
174
|
-
if (addr && typeof addr === 'object') {
|
|
175
|
-
const port = addr.port;
|
|
176
|
-
server.close(() => resolve(port));
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
server.close(() => reject(new Error('Could not find available port')));
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
server.on('error', reject);
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
146
|
// =============================================================================
|
|
186
147
|
// Token Resolution (for API calls)
|
|
187
148
|
// =============================================================================
|
|
188
|
-
/** Default AuthKit configuration for WayAI */
|
|
189
149
|
const AUTHKIT_DOMAIN = 'https://sprightly-comic-51.authkit.app';
|
|
190
|
-
const AUTHKIT_CLIENT_ID = 'client_01KMZHB50KENM5SV90ZA80VXK4'; // WayAI CLI (public
|
|
150
|
+
const AUTHKIT_CLIENT_ID = 'client_01KMZHB50KENM5SV90ZA80VXK4'; // WayAI CLI Connect app (public, PKCE)
|
|
191
151
|
export function getAuthKitDomain() {
|
|
192
152
|
return process.env.WAYAI_AUTHKIT_DOMAIN || AUTHKIT_DOMAIN;
|
|
193
153
|
}
|
|
@@ -208,9 +168,7 @@ export async function getAccessToken(config) {
|
|
|
208
168
|
if (!config.access_token || !config.refresh_token) {
|
|
209
169
|
throw new Error('No token found. Run `wayai login` to authenticate.');
|
|
210
170
|
}
|
|
211
|
-
// Check if JWT is still valid (with 60s buffer)
|
|
212
171
|
if (!config.token_expires_at) {
|
|
213
|
-
// No expiry recorded — use the token as-is (don't unnecessarily refresh)
|
|
214
172
|
return config.access_token;
|
|
215
173
|
}
|
|
216
174
|
const expiresAt = new Date(config.token_expires_at).getTime();
|
|
@@ -220,13 +178,11 @@ export async function getAccessToken(config) {
|
|
|
220
178
|
// Token expired — refresh
|
|
221
179
|
try {
|
|
222
180
|
const result = await refreshAccessToken(getAuthKitDomain(), getAuthKitClientId(), config.refresh_token);
|
|
223
|
-
// Atomically update config with new tokens
|
|
224
181
|
const updatedConfig = {
|
|
225
182
|
...config,
|
|
226
183
|
access_token: result.access_token,
|
|
227
184
|
token_expires_at: new Date(Date.now() + result.expires_in * 1000).toISOString(),
|
|
228
185
|
};
|
|
229
|
-
// Handle refresh token rotation
|
|
230
186
|
if (result.refresh_token) {
|
|
231
187
|
updatedConfig.refresh_token = result.refresh_token;
|
|
232
188
|
}
|
|
@@ -235,16 +191,12 @@ export async function getAccessToken(config) {
|
|
|
235
191
|
}
|
|
236
192
|
catch (err) {
|
|
237
193
|
if (err instanceof Error && err.message === 'SESSION_EXPIRED') {
|
|
238
|
-
// Clear stored tokens — user must re-login
|
|
239
194
|
writeConfig({ api_url: config.api_url });
|
|
240
195
|
throw new Error('Session expired. Please run `wayai login` again.');
|
|
241
196
|
}
|
|
242
197
|
throw err;
|
|
243
198
|
}
|
|
244
199
|
}
|
|
245
|
-
/**
|
|
246
|
-
* Read config and get access token, or exit with error.
|
|
247
|
-
*/
|
|
248
200
|
export async function requireAuth() {
|
|
249
201
|
const config = readConfig();
|
|
250
202
|
if (!config) {
|
package/dist/lib/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
|