@pmate/cli 0.9.0 → 0.10.0
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/LoginCommandHandler.d.ts +6 -4
- package/dist/commands/LoginCommandHandler.js +133 -73
- package/dist/commands/LoginCommandHandler.js.map +1 -1
- package/dist/tests/LoginCommandHandler.test.d.ts +1 -0
- package/dist/tests/LoginCommandHandler.test.js +13 -0
- package/dist/tests/LoginCommandHandler.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { LoginCommandArgs } from "../types";
|
|
2
|
+
export declare function buildHostedLoginUrl(redirectUrl: string): string;
|
|
2
3
|
export declare class LoginCommandHandler {
|
|
3
4
|
handle(_args: LoginCommandArgs): Promise<void>;
|
|
4
|
-
private
|
|
5
|
-
private
|
|
6
|
-
private
|
|
7
|
-
private
|
|
5
|
+
private fetchSession;
|
|
6
|
+
private startCallbackServer;
|
|
7
|
+
private handleCallbackRequest;
|
|
8
|
+
private renderHtml;
|
|
9
|
+
private openBrowser;
|
|
8
10
|
private writeSession;
|
|
9
11
|
}
|
|
@@ -1,102 +1,162 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LoginCommandHandler = void 0;
|
|
4
|
+
exports.buildHostedLoginUrl = buildHostedLoginUrl;
|
|
4
5
|
const tslib_1 = require("tslib");
|
|
5
6
|
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_http_1 = require("node:http");
|
|
6
8
|
const node_os_1 = tslib_1.__importDefault(require("node:os"));
|
|
7
9
|
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
8
|
-
const
|
|
10
|
+
const node_child_process_1 = require("node:child_process");
|
|
9
11
|
const cli_1 = require("../cli");
|
|
10
|
-
const
|
|
12
|
+
const AUTH_UI_BASE_URL = "https://auth.pmate.chat";
|
|
13
|
+
const AUTH_API_BASE_URL = "https://auth-api-v2.pmate.chat";
|
|
14
|
+
const CALLBACK_PATH = "/pmate-login-callback";
|
|
15
|
+
const APP_ID = "@pmate/cli";
|
|
16
|
+
const LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
|
|
17
|
+
function buildHostedLoginUrl(redirectUrl) {
|
|
18
|
+
const url = new URL(AUTH_UI_BASE_URL);
|
|
19
|
+
url.searchParams.set("redirect", redirectUrl);
|
|
20
|
+
url.searchParams.set("app", APP_ID);
|
|
21
|
+
return url.toString();
|
|
22
|
+
}
|
|
11
23
|
class LoginCommandHandler {
|
|
12
24
|
async handle(_args) {
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
const callback = await this.startCallbackServer();
|
|
26
|
+
const loginUrl = buildHostedLoginUrl(callback.redirectUrl);
|
|
27
|
+
cli_1.ui.info("Opening browser for login.", {
|
|
28
|
+
url: loginUrl,
|
|
29
|
+
});
|
|
30
|
+
if (!this.openBrowser(loginUrl)) {
|
|
31
|
+
cli_1.ui.warn("Unable to open the browser automatically.");
|
|
32
|
+
cli_1.ui.plain(loginUrl);
|
|
33
|
+
}
|
|
34
|
+
cli_1.ui.info("Waiting for login redirect...", {
|
|
35
|
+
callback: callback.redirectUrl,
|
|
18
36
|
});
|
|
19
37
|
try {
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const testAuthKey = (_b = (_a = config.test) === null || _a === void 0 ? void 0 : _a.authKey) === null || _b === void 0 ? void 0 : _b.trim();
|
|
23
|
-
const isTestLogin = mobile === "99999999999";
|
|
24
|
-
if (isTestLogin && !testAuthKey) {
|
|
25
|
-
throw new Error("test.authKey is required for test login. Set it in ~/.pmate/config.yaml.");
|
|
26
|
-
}
|
|
27
|
-
let loginPayload;
|
|
28
|
-
if (isTestLogin) {
|
|
29
|
-
const timestamp = Date.now();
|
|
30
|
-
const issuedAt = new Date(timestamp).toISOString();
|
|
31
|
-
loginPayload = {
|
|
32
|
-
body: { type: "sms", mobile: `test_${timestamp}`, vcode: "000000" },
|
|
33
|
-
nonce: `test_${timestamp}`,
|
|
34
|
-
issuedAt,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
const issue = await this.issueVCode(baseUrl, mobile);
|
|
39
|
-
cli_1.ui.info("Verification code issued.", issue);
|
|
40
|
-
const vcodeInput = await rl.question(`VCode (press enter to use mocked ${issue.vcode}): `);
|
|
41
|
-
const vcode = vcodeInput.trim() || issue.vcode;
|
|
42
|
-
loginPayload = {
|
|
43
|
-
body: { type: "sms", mobile, vcode },
|
|
44
|
-
nonce: issue.nonce,
|
|
45
|
-
issuedAt: issue.issuedAt,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
const loginResponse = await this.login(baseUrl, loginPayload, isTestLogin ? testAuthKey : undefined);
|
|
38
|
+
const token = await callback.waitForToken;
|
|
39
|
+
const loginResponse = await this.fetchSession(token);
|
|
49
40
|
const sessionPath = this.writeSession(loginResponse);
|
|
50
41
|
cli_1.ui.success(`Logged in. Session saved to ${sessionPath}`);
|
|
51
42
|
}
|
|
52
43
|
finally {
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
normalizeBaseUrl(value) {
|
|
57
|
-
return value.replace(/\/+$/, "");
|
|
58
|
-
}
|
|
59
|
-
async promptRequired(rl, question) {
|
|
60
|
-
while (true) {
|
|
61
|
-
const answer = (await rl.question(question)).trim();
|
|
62
|
-
if (answer) {
|
|
63
|
-
return answer;
|
|
64
|
-
}
|
|
65
|
-
cli_1.ui.warn("Please enter a value.");
|
|
44
|
+
await callback.close();
|
|
66
45
|
}
|
|
67
46
|
}
|
|
68
|
-
async
|
|
69
|
-
const response = await fetch(`${
|
|
70
|
-
method: "
|
|
71
|
-
headers: {
|
|
72
|
-
|
|
47
|
+
async fetchSession(token) {
|
|
48
|
+
const response = await fetch(`${AUTH_API_BASE_URL}/session`, {
|
|
49
|
+
method: "GET",
|
|
50
|
+
headers: {
|
|
51
|
+
Authorization: `Bearer ${token}`,
|
|
52
|
+
},
|
|
73
53
|
});
|
|
74
54
|
if (!response.ok) {
|
|
75
55
|
const detail = await response.text();
|
|
76
|
-
throw new Error(`Failed to
|
|
56
|
+
throw new Error(`Failed to validate session (${response.status}): ${detail || response.statusText}`);
|
|
77
57
|
}
|
|
78
58
|
const resp = (await response.json());
|
|
79
|
-
return
|
|
59
|
+
return {
|
|
60
|
+
...resp.data,
|
|
61
|
+
token,
|
|
62
|
+
};
|
|
80
63
|
}
|
|
81
|
-
async
|
|
82
|
-
|
|
83
|
-
|
|
64
|
+
async startCallbackServer() {
|
|
65
|
+
let resolveToken;
|
|
66
|
+
let rejectToken;
|
|
67
|
+
const waitForToken = new Promise((resolve, reject) => {
|
|
68
|
+
resolveToken = resolve;
|
|
69
|
+
rejectToken = reject;
|
|
70
|
+
});
|
|
71
|
+
const server = (0, node_http_1.createServer)((request, response) => {
|
|
72
|
+
this.handleCallbackRequest(request, response, resolveToken, rejectToken);
|
|
73
|
+
});
|
|
74
|
+
await new Promise((resolve, reject) => {
|
|
75
|
+
server.once("error", reject);
|
|
76
|
+
server.listen(0, "127.0.0.1", () => resolve());
|
|
77
|
+
});
|
|
78
|
+
const address = server.address();
|
|
79
|
+
if (!address || typeof address === "string") {
|
|
80
|
+
server.close();
|
|
81
|
+
throw new Error("Failed to start login callback server.");
|
|
82
|
+
}
|
|
83
|
+
const redirectUrl = `http://127.0.0.1:${address.port}${CALLBACK_PATH}`;
|
|
84
|
+
const timeout = setTimeout(() => {
|
|
85
|
+
rejectToken(new Error(`Timed out waiting for browser login after ${LOGIN_TIMEOUT_MS / 1000} seconds.`));
|
|
86
|
+
}, LOGIN_TIMEOUT_MS);
|
|
87
|
+
const close = async () => {
|
|
88
|
+
clearTimeout(timeout);
|
|
89
|
+
await new Promise((resolve) => {
|
|
90
|
+
server.close(() => resolve());
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
return {
|
|
94
|
+
redirectUrl,
|
|
95
|
+
waitForToken,
|
|
96
|
+
close,
|
|
84
97
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
98
|
+
}
|
|
99
|
+
handleCallbackRequest(request, response, resolveToken, rejectToken) {
|
|
100
|
+
var _a;
|
|
101
|
+
const url = new URL(request.url || "/", "http://127.0.0.1");
|
|
102
|
+
if (url.pathname !== CALLBACK_PATH) {
|
|
103
|
+
response.statusCode = 404;
|
|
104
|
+
response.end("Not found");
|
|
105
|
+
return;
|
|
88
106
|
}
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
107
|
+
const token = (_a = url.searchParams.get("sessionId")) === null || _a === void 0 ? void 0 : _a.trim();
|
|
108
|
+
if (!token) {
|
|
109
|
+
response.statusCode = 400;
|
|
110
|
+
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
111
|
+
response.end(this.renderHtml("Login failed", "Missing sessionId in redirect URL."));
|
|
112
|
+
rejectToken(new Error("Login callback did not include sessionId."));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
response.statusCode = 200;
|
|
116
|
+
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
117
|
+
response.end(this.renderHtml("Login complete", "You can close this tab and return to the terminal."));
|
|
118
|
+
resolveToken(token);
|
|
119
|
+
}
|
|
120
|
+
renderHtml(title, message) {
|
|
121
|
+
return `<!doctype html>
|
|
122
|
+
<html lang="en">
|
|
123
|
+
<head>
|
|
124
|
+
<meta charset="utf-8" />
|
|
125
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
126
|
+
<title>${title}</title>
|
|
127
|
+
<style>
|
|
128
|
+
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; padding: 32px; color: #111; }
|
|
129
|
+
main { max-width: 560px; margin: 10vh auto; }
|
|
130
|
+
h1 { font-size: 28px; margin-bottom: 12px; }
|
|
131
|
+
p { font-size: 16px; line-height: 1.5; }
|
|
132
|
+
</style>
|
|
133
|
+
</head>
|
|
134
|
+
<body>
|
|
135
|
+
<main>
|
|
136
|
+
<h1>${title}</h1>
|
|
137
|
+
<p>${message}</p>
|
|
138
|
+
</main>
|
|
139
|
+
</body>
|
|
140
|
+
</html>`;
|
|
141
|
+
}
|
|
142
|
+
openBrowser(url) {
|
|
143
|
+
const platform = process.platform;
|
|
144
|
+
const command = platform === "darwin"
|
|
145
|
+
? { cmd: "open", args: [url] }
|
|
146
|
+
: platform === "win32"
|
|
147
|
+
? { cmd: "cmd", args: ["/c", "start", "", url] }
|
|
148
|
+
: { cmd: "xdg-open", args: [url] };
|
|
149
|
+
try {
|
|
150
|
+
const child = (0, node_child_process_1.spawn)(command.cmd, command.args, {
|
|
151
|
+
detached: true,
|
|
152
|
+
stdio: "ignore",
|
|
153
|
+
});
|
|
154
|
+
child.unref();
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return false;
|
|
97
159
|
}
|
|
98
|
-
const resp = (await response.json());
|
|
99
|
-
return resp.data;
|
|
100
160
|
}
|
|
101
161
|
writeSession(session) {
|
|
102
162
|
const sessionDir = node_path_1.default.join(node_os_1.default.homedir(), ".pmate");
|
|
@@ -109,7 +169,7 @@ class LoginCommandHandler {
|
|
|
109
169
|
(0, node_fs_1.chmodSync)(sessionPath, 0o600);
|
|
110
170
|
}
|
|
111
171
|
catch {
|
|
112
|
-
//
|
|
172
|
+
// Ignore chmod failures on filesystems that do not support it.
|
|
113
173
|
}
|
|
114
174
|
return sessionPath;
|
|
115
175
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoginCommandHandler.js","sourceRoot":"","sources":["../../src/commands/LoginCommandHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LoginCommandHandler.js","sourceRoot":"","sources":["../../src/commands/LoginCommandHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const LoginCommandHandler_1 = require("../commands/LoginCommandHandler");
|
|
5
|
+
(0, vitest_1.describe)("LoginCommandHandler", () => {
|
|
6
|
+
(0, vitest_1.it)("builds the hosted login URL with redirect and app", () => {
|
|
7
|
+
const url = new URL((0, LoginCommandHandler_1.buildHostedLoginUrl)("http://127.0.0.1:57123/pmate-login-callback"));
|
|
8
|
+
(0, vitest_1.expect)(url.origin).toBe("https://auth.pmate.chat");
|
|
9
|
+
(0, vitest_1.expect)(url.searchParams.get("app")).toBe("@pmate/cli");
|
|
10
|
+
(0, vitest_1.expect)(url.searchParams.get("redirect")).toBe("http://127.0.0.1:57123/pmate-login-callback");
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
//# sourceMappingURL=LoginCommandHandler.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginCommandHandler.test.js","sourceRoot":"","sources":["../../src/tests/LoginCommandHandler.test.ts"],"names":[],"mappings":";;AAAA,mCAA6C;AAC7C,yEAAqE;AAErE,IAAA,iBAAQ,EAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAA,WAAE,EAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,IAAA,yCAAmB,EAAC,6CAA6C,CAAC,CACnE,CAAA;QAED,IAAA,eAAM,EAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA;QAClD,IAAA,eAAM,EAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QACtD,IAAA,eAAM,EAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAC3C,6CAA6C,CAC9C,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|