@solcreek/cli 0.4.20 → 0.4.21
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
CHANGED
|
@@ -62,7 +62,7 @@ export const loginCommand = defineCommand({
|
|
|
62
62
|
* Default login: open browser → dashboard creates API key → redirect to localhost callback.
|
|
63
63
|
*/
|
|
64
64
|
async function browserLogin() {
|
|
65
|
-
const { port, state, waitForCallback, close } = startAuthServer();
|
|
65
|
+
const { port, state, waitForCallback, close } = await startAuthServer();
|
|
66
66
|
const dashboardUrl = getDashboardUrl();
|
|
67
67
|
const authUrl = `${dashboardUrl}/cli-auth?port=${port}&state=${state}`;
|
|
68
68
|
consola.info("Opening browser to authenticate...");
|
|
@@ -13,10 +13,10 @@ export interface AuthCallbackResult {
|
|
|
13
13
|
* 4. This server receives the callback, validates state, resolves the promise
|
|
14
14
|
* 5. Server auto-closes
|
|
15
15
|
*/
|
|
16
|
-
export declare function startAuthServer(): {
|
|
16
|
+
export declare function startAuthServer(): Promise<{
|
|
17
17
|
port: number;
|
|
18
18
|
state: string;
|
|
19
19
|
waitForCallback: () => Promise<string>;
|
|
20
20
|
close: () => void;
|
|
21
|
-
}
|
|
21
|
+
}>;
|
|
22
22
|
//# sourceMappingURL=auth-server.d.ts.map
|
|
@@ -11,7 +11,7 @@ import { randomBytes } from "node:crypto";
|
|
|
11
11
|
* 4. This server receives the callback, validates state, resolves the promise
|
|
12
12
|
* 5. Server auto-closes
|
|
13
13
|
*/
|
|
14
|
-
export function startAuthServer() {
|
|
14
|
+
export async function startAuthServer() {
|
|
15
15
|
const state = randomBytes(16).toString("hex");
|
|
16
16
|
let resolveCallback;
|
|
17
17
|
let rejectCallback;
|
|
@@ -45,10 +45,23 @@ export function startAuthServer() {
|
|
|
45
45
|
res.writeHead(404);
|
|
46
46
|
res.end("Not found");
|
|
47
47
|
});
|
|
48
|
-
// Listen on port 0 = OS picks a random available port
|
|
49
|
-
server.listen(
|
|
48
|
+
// Listen on port 0 = OS picks a random available port.
|
|
49
|
+
// server.listen() is async — we MUST await the 'listening' event before
|
|
50
|
+
// reading server.address(), otherwise address() returns null and the
|
|
51
|
+
// callback URL ships ?port=0 to the dashboard (which correctly rejects
|
|
52
|
+
// with "Missing port or state parameter"). Regression seen in the wild
|
|
53
|
+
// on macOS — Node's behavior here is timing-dependent.
|
|
54
|
+
await new Promise((resolve, reject) => {
|
|
55
|
+
server.once("listening", () => resolve());
|
|
56
|
+
server.once("error", (err) => reject(err));
|
|
57
|
+
server.listen(0, "localhost");
|
|
58
|
+
});
|
|
50
59
|
const address = server.address();
|
|
51
60
|
const port = typeof address === "object" && address ? address.port : 0;
|
|
61
|
+
if (port === 0) {
|
|
62
|
+
server.close();
|
|
63
|
+
throw new Error("Could not determine local port for auth callback — server.address() returned null after listening.");
|
|
64
|
+
}
|
|
52
65
|
// Timeout after 2 minutes
|
|
53
66
|
const timeout = setTimeout(() => {
|
|
54
67
|
rejectCallback(new Error("Login timed out after 2 minutes"));
|