@convext/cli 0.3.1 → 1.0.6

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.
@@ -0,0 +1,418 @@
1
+ import { createServer } from "node:http";
2
+ import { randomBytes, createHash } from "node:crypto";
3
+ import { platform } from "node:os";
4
+ import { exec } from "node:child_process";
5
+ import chalk from "chalk";
6
+ import ora from "ora";
7
+ import { getApiUrl, saveConfig, loadConfig } from "../config.js";
8
+ // OAuth configuration
9
+ const OAUTH_CLIENT_ID = process.env.CONVEXT_OAUTH_CLIENT_ID || "convext-cli";
10
+ const CALLBACK_PORT = 9876;
11
+ const CALLBACK_PATH = "/callback";
12
+ /**
13
+ * Generate PKCE code verifier and challenge
14
+ */
15
+ function generatePKCE() {
16
+ const verifier = randomBytes(32).toString("base64url");
17
+ const challenge = createHash("sha256").update(verifier).digest("base64url");
18
+ return { verifier, challenge };
19
+ }
20
+ /**
21
+ * Generate random state for CSRF protection
22
+ */
23
+ function generateState() {
24
+ return randomBytes(16).toString("hex");
25
+ }
26
+ /**
27
+ * Check if we can open a browser
28
+ */
29
+ function canOpenBrowser() {
30
+ // Check for SSH session
31
+ if (process.env.SSH_CLIENT || process.env.SSH_TTY) {
32
+ return false;
33
+ }
34
+ // Check for display on Linux
35
+ if (platform() === "linux" && !process.env.DISPLAY && !process.env.WAYLAND_DISPLAY) {
36
+ return false;
37
+ }
38
+ // Check if running in CI
39
+ if (process.env.CI) {
40
+ return false;
41
+ }
42
+ // Check if TTY is available
43
+ if (!process.stdin.isTTY) {
44
+ return false;
45
+ }
46
+ return true;
47
+ }
48
+ /**
49
+ * Open URL in default browser
50
+ */
51
+ function openBrowser(url) {
52
+ return new Promise((resolve, reject) => {
53
+ let command;
54
+ switch (platform()) {
55
+ case "darwin":
56
+ command = `open "${url}"`;
57
+ break;
58
+ case "win32":
59
+ command = `start "" "${url}"`;
60
+ break;
61
+ default:
62
+ command = `xdg-open "${url}"`;
63
+ }
64
+ exec(command, (error) => {
65
+ if (error) {
66
+ reject(error);
67
+ }
68
+ else {
69
+ resolve();
70
+ }
71
+ });
72
+ });
73
+ }
74
+ /**
75
+ * Start local HTTP server to receive OAuth callback
76
+ */
77
+ function startCallbackServer(expectedState, codeVerifier) {
78
+ return new Promise((resolve, reject) => {
79
+ const server = createServer(async (req, res) => {
80
+ const url = new URL(req.url || "/", `http://localhost:${CALLBACK_PORT}`);
81
+ if (url.pathname !== CALLBACK_PATH) {
82
+ res.writeHead(404);
83
+ res.end("Not found");
84
+ return;
85
+ }
86
+ const code = url.searchParams.get("code");
87
+ const state = url.searchParams.get("state");
88
+ const error = url.searchParams.get("error");
89
+ const errorDescription = url.searchParams.get("error_description");
90
+ if (error) {
91
+ res.writeHead(400, { "Content-Type": "text/html" });
92
+ res.end(`
93
+ <html>
94
+ <body style="font-family: system-ui; padding: 40px; text-align: center;">
95
+ <h1 style="color: #dc2626;">Authentication Failed</h1>
96
+ <p>${errorDescription || error}</p>
97
+ <p>You can close this window.</p>
98
+ </body>
99
+ </html>
100
+ `);
101
+ server.close();
102
+ reject(new Error(errorDescription || error));
103
+ return;
104
+ }
105
+ if (state !== expectedState) {
106
+ res.writeHead(400, { "Content-Type": "text/html" });
107
+ res.end(`
108
+ <html>
109
+ <body style="font-family: system-ui; padding: 40px; text-align: center;">
110
+ <h1 style="color: #dc2626;">Authentication Failed</h1>
111
+ <p>Invalid state parameter. This may be a CSRF attack.</p>
112
+ <p>You can close this window.</p>
113
+ </body>
114
+ </html>
115
+ `);
116
+ server.close();
117
+ reject(new Error("Invalid state parameter"));
118
+ return;
119
+ }
120
+ if (!code) {
121
+ res.writeHead(400, { "Content-Type": "text/html" });
122
+ res.end(`
123
+ <html>
124
+ <body style="font-family: system-ui; padding: 40px; text-align: center;">
125
+ <h1 style="color: #dc2626;">Authentication Failed</h1>
126
+ <p>No authorization code received.</p>
127
+ <p>You can close this window.</p>
128
+ </body>
129
+ </html>
130
+ `);
131
+ server.close();
132
+ reject(new Error("No authorization code received"));
133
+ return;
134
+ }
135
+ // Exchange code for tokens
136
+ try {
137
+ const tokenResponse = await exchangeCodeForTokens(code, codeVerifier);
138
+ res.writeHead(200, { "Content-Type": "text/html" });
139
+ res.end(`
140
+ <html>
141
+ <body style="font-family: system-ui; padding: 40px; text-align: center;">
142
+ <h1 style="color: #16a34a;">Authentication Successful!</h1>
143
+ <p>You can close this window and return to your terminal.</p>
144
+ </body>
145
+ </html>
146
+ `);
147
+ server.close();
148
+ resolve(tokenResponse);
149
+ }
150
+ catch (err) {
151
+ res.writeHead(500, { "Content-Type": "text/html" });
152
+ res.end(`
153
+ <html>
154
+ <body style="font-family: system-ui; padding: 40px; text-align: center;">
155
+ <h1 style="color: #dc2626;">Authentication Failed</h1>
156
+ <p>${err instanceof Error ? err.message : "Unknown error"}</p>
157
+ <p>You can close this window.</p>
158
+ </body>
159
+ </html>
160
+ `);
161
+ server.close();
162
+ reject(err);
163
+ }
164
+ });
165
+ server.on("error", (err) => {
166
+ reject(err);
167
+ });
168
+ // Set timeout for callback
169
+ const timeout = setTimeout(() => {
170
+ server.close();
171
+ reject(new Error("Authentication timeout - no callback received within 5 minutes"));
172
+ }, 5 * 60 * 1000);
173
+ server.on("close", () => {
174
+ clearTimeout(timeout);
175
+ });
176
+ server.listen(CALLBACK_PORT, "127.0.0.1");
177
+ });
178
+ }
179
+ /**
180
+ * Exchange authorization code for tokens
181
+ */
182
+ async function exchangeCodeForTokens(code, codeVerifier) {
183
+ const apiUrl = getApiUrl();
184
+ const redirectUri = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;
185
+ const response = await fetch(`${apiUrl}/oauth/token`, {
186
+ method: "POST",
187
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
188
+ body: new URLSearchParams({
189
+ grant_type: "authorization_code",
190
+ client_id: OAUTH_CLIENT_ID,
191
+ code,
192
+ redirect_uri: redirectUri,
193
+ code_verifier: codeVerifier,
194
+ }),
195
+ });
196
+ if (!response.ok) {
197
+ const error = await response.json().catch(() => ({}));
198
+ throw new Error(error.error_description ||
199
+ error.error ||
200
+ `Token exchange failed: ${response.status}`);
201
+ }
202
+ return response.json();
203
+ }
204
+ /**
205
+ * PKCE OAuth flow - opens browser for authentication
206
+ */
207
+ async function pkceFlow() {
208
+ const apiUrl = getApiUrl();
209
+ const { verifier, challenge } = generatePKCE();
210
+ const state = generateState();
211
+ const redirectUri = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;
212
+ const authUrl = new URL(`${apiUrl}/oauth/authorize`);
213
+ authUrl.searchParams.set("client_id", OAUTH_CLIENT_ID);
214
+ authUrl.searchParams.set("redirect_uri", redirectUri);
215
+ authUrl.searchParams.set("response_type", "code");
216
+ authUrl.searchParams.set("scope", "read write");
217
+ authUrl.searchParams.set("state", state);
218
+ authUrl.searchParams.set("code_challenge", challenge);
219
+ authUrl.searchParams.set("code_challenge_method", "S256");
220
+ // Start callback server first
221
+ const tokenPromise = startCallbackServer(state, verifier);
222
+ console.log(chalk.cyan("\nOpening browser for authentication...\n"));
223
+ try {
224
+ await openBrowser(authUrl.toString());
225
+ }
226
+ catch {
227
+ console.log(chalk.yellow("Could not open browser automatically."));
228
+ console.log(chalk.gray("Please open this URL manually:\n"));
229
+ console.log(chalk.cyan(authUrl.toString()));
230
+ console.log();
231
+ }
232
+ console.log(chalk.gray("Waiting for authentication...\n"));
233
+ return tokenPromise;
234
+ }
235
+ /**
236
+ * Request device code from server
237
+ */
238
+ async function requestDeviceCode() {
239
+ const apiUrl = getApiUrl();
240
+ const response = await fetch(`${apiUrl}/oauth/authorize_device`, {
241
+ method: "POST",
242
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
243
+ body: new URLSearchParams({
244
+ client_id: OAUTH_CLIENT_ID,
245
+ scope: "read write",
246
+ }),
247
+ });
248
+ if (!response.ok) {
249
+ const error = await response.json().catch(() => ({}));
250
+ throw new Error(error.error_description ||
251
+ error.error ||
252
+ `Device code request failed: ${response.status}`);
253
+ }
254
+ return response.json();
255
+ }
256
+ /**
257
+ * Poll for device authorization completion
258
+ */
259
+ async function pollForDeviceAuthorization(deviceCode, interval, expiresIn) {
260
+ const apiUrl = getApiUrl();
261
+ const startTime = Date.now();
262
+ const expiresAt = startTime + expiresIn * 1000;
263
+ while (Date.now() < expiresAt) {
264
+ await new Promise((resolve) => setTimeout(resolve, interval * 1000));
265
+ const response = await fetch(`${apiUrl}/oauth/token`, {
266
+ method: "POST",
267
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
268
+ body: new URLSearchParams({
269
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
270
+ client_id: OAUTH_CLIENT_ID,
271
+ device_code: deviceCode,
272
+ }),
273
+ });
274
+ if (response.ok) {
275
+ return response.json();
276
+ }
277
+ const error = (await response.json().catch(() => ({})));
278
+ if (error.error === "authorization_pending") {
279
+ // User hasn't authorized yet, keep polling
280
+ continue;
281
+ }
282
+ if (error.error === "slow_down") {
283
+ // Server wants us to slow down
284
+ interval += 5;
285
+ continue;
286
+ }
287
+ if (error.error === "expired_token") {
288
+ throw new Error("Device code expired. Please try again.");
289
+ }
290
+ if (error.error === "access_denied") {
291
+ throw new Error("Authorization was denied.");
292
+ }
293
+ throw new Error(error.error_description || error.error || "Authorization failed");
294
+ }
295
+ throw new Error("Device code expired. Please try again.");
296
+ }
297
+ /**
298
+ * Device authorization flow - for headless environments
299
+ */
300
+ async function deviceFlow() {
301
+ const spinner = ora("Requesting device code...").start();
302
+ let deviceCodeResponse;
303
+ try {
304
+ deviceCodeResponse = await requestDeviceCode();
305
+ spinner.stop();
306
+ }
307
+ catch (error) {
308
+ spinner.fail("Failed to request device code");
309
+ throw error;
310
+ }
311
+ const { device_code, user_code, verification_uri, verification_uri_complete, interval, expires_in } = deviceCodeResponse;
312
+ console.log("\n" + chalk.bold("To authenticate, visit:"));
313
+ console.log(chalk.cyan(` ${verification_uri_complete || verification_uri}`));
314
+ console.log();
315
+ console.log(chalk.bold("And enter this code:"));
316
+ console.log(chalk.yellow.bold(` ${user_code}`));
317
+ console.log();
318
+ console.log(chalk.gray(`Code expires in ${Math.floor(expires_in / 60)} minutes\n`));
319
+ const pollSpinner = ora("Waiting for authorization...").start();
320
+ try {
321
+ const tokens = await pollForDeviceAuthorization(device_code, interval, expires_in);
322
+ pollSpinner.succeed("Authorized!");
323
+ return tokens;
324
+ }
325
+ catch (error) {
326
+ pollSpinner.fail("Authorization failed");
327
+ throw error;
328
+ }
329
+ }
330
+ /**
331
+ * Save OAuth tokens to config
332
+ */
333
+ function saveTokens(tokens) {
334
+ const expiresAt = new Date((tokens.created_at + tokens.expires_in) * 1000).toISOString();
335
+ saveConfig({
336
+ apiToken: tokens.access_token,
337
+ });
338
+ // Save additional OAuth data in separate credentials file
339
+ const config = loadConfig();
340
+ const credentialsPath = `${process.env.HOME}/.convext/credentials.json`;
341
+ const credentials = {
342
+ access_token: tokens.access_token,
343
+ refresh_token: tokens.refresh_token,
344
+ expires_at: expiresAt,
345
+ token_type: tokens.token_type,
346
+ scope: tokens.scope,
347
+ };
348
+ const { writeFileSync, mkdirSync, existsSync } = require("node:fs");
349
+ const { dirname } = require("node:path");
350
+ const dir = dirname(credentialsPath);
351
+ if (!existsSync(dir)) {
352
+ mkdirSync(dir, { recursive: true });
353
+ }
354
+ writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), { mode: 0o600 });
355
+ }
356
+ /**
357
+ * Main login command
358
+ */
359
+ export async function loginCommand(options = {}) {
360
+ const apiUrl = getApiUrl();
361
+ // Check if already logged in
362
+ const config = loadConfig();
363
+ if (config.apiToken && !options.device) {
364
+ console.log(chalk.yellow("Already logged in. Use 'convext logout' first to re-authenticate."));
365
+ return;
366
+ }
367
+ console.log(chalk.bold(`Logging in to ${apiUrl}...\n`));
368
+ try {
369
+ let tokens;
370
+ if (options.device || !canOpenBrowser()) {
371
+ if (!options.device && !canOpenBrowser()) {
372
+ console.log(chalk.gray("Browser not available, using device flow...\n"));
373
+ }
374
+ tokens = await deviceFlow();
375
+ }
376
+ else {
377
+ try {
378
+ tokens = await pkceFlow();
379
+ }
380
+ catch (error) {
381
+ // If PKCE fails (e.g., browser couldn't open), fall back to device flow
382
+ if (error.message?.includes("Could not open browser") ||
383
+ error.message?.includes("EADDRINUSE")) {
384
+ console.log(chalk.yellow("\nBrowser flow failed, falling back to device flow...\n"));
385
+ tokens = await deviceFlow();
386
+ }
387
+ else {
388
+ throw error;
389
+ }
390
+ }
391
+ }
392
+ saveTokens(tokens);
393
+ console.log(chalk.green("\n✓ Successfully logged in!"));
394
+ console.log(chalk.gray("\nRun 'convext whoami' to verify your identity."));
395
+ }
396
+ catch (error) {
397
+ console.error(chalk.red("\n✗ Login failed"));
398
+ if (error instanceof Error) {
399
+ console.error(chalk.gray(` ${error.message}`));
400
+ }
401
+ process.exit(1);
402
+ }
403
+ }
404
+ /**
405
+ * Logout command - clear stored credentials
406
+ */
407
+ export async function logoutCommand() {
408
+ const { existsSync, unlinkSync } = require("node:fs");
409
+ // Clear API token from config
410
+ saveConfig({ apiToken: undefined });
411
+ // Remove credentials file
412
+ const credentialsPath = `${process.env.HOME}/.convext/credentials.json`;
413
+ if (existsSync(credentialsPath)) {
414
+ unlinkSync(credentialsPath);
415
+ }
416
+ console.log(chalk.green("✓ Logged out successfully"));
417
+ }
418
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}