xuanwu-cli 2.1.0 → 2.2.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/auth/login.js +12 -11
- package/package.json +1 -1
- package/src/commands/auth/login.ts +14 -11
|
@@ -11,22 +11,23 @@ const formatter_1 = require("../../output/formatter");
|
|
|
11
11
|
function makeLoginCommand() {
|
|
12
12
|
const cmd = new commander_1.Command('login')
|
|
13
13
|
.description('Login to xuanwu factory')
|
|
14
|
+
.option('-u, --api-url <url>', 'API server URL', 'https://i.xuanwu.dev.aimstek.cn')
|
|
14
15
|
.option('-e, --email <email>', 'Email address (for non-interactive login)')
|
|
15
16
|
.option('-p, --password <password>', 'Password (for non-interactive login)')
|
|
16
17
|
.option('--expires-in <duration>', 'Token expiration (30d, 90d, never)', '30d')
|
|
17
18
|
.action(async (options) => {
|
|
18
19
|
const sessionManager = new session_1.SessionManager();
|
|
19
20
|
if (options.email && options.password) {
|
|
20
|
-
await loginWithCredentials(sessionManager, options.email, options.password, options.expiresIn);
|
|
21
|
+
await loginWithCredentials(sessionManager, options.email, options.password, options.expiresIn, options.apiUrl);
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
23
|
-
await loginWithBrowser(sessionManager);
|
|
24
|
+
await loginWithBrowser(sessionManager, options.apiUrl);
|
|
24
25
|
});
|
|
25
26
|
return cmd;
|
|
26
27
|
}
|
|
27
|
-
async function loginWithBrowser(sessionManager) {
|
|
28
|
-
const
|
|
29
|
-
const deviceAuthRes = await fetch(`${
|
|
28
|
+
async function loginWithBrowser(sessionManager, apiUrl) {
|
|
29
|
+
const finalApiUrl = process.env.XW_API_URL || apiUrl;
|
|
30
|
+
const deviceAuthRes = await fetch(`${finalApiUrl}/api/cli/auth/device-code`, {
|
|
30
31
|
method: 'POST'
|
|
31
32
|
});
|
|
32
33
|
if (!deviceAuthRes.ok) {
|
|
@@ -49,7 +50,7 @@ async function loginWithBrowser(sessionManager) {
|
|
|
49
50
|
let attempts = 0;
|
|
50
51
|
while (attempts < maxAttempts) {
|
|
51
52
|
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
52
|
-
const pollRes = await fetch(`${
|
|
53
|
+
const pollRes = await fetch(`${finalApiUrl}/api/cli/auth/poll?session_id=${sessionId}`);
|
|
53
54
|
if (!pollRes.ok) {
|
|
54
55
|
formatter_1.OutputFormatter.error('Failed to poll auth status');
|
|
55
56
|
process.exit(1);
|
|
@@ -66,7 +67,7 @@ async function loginWithBrowser(sessionManager) {
|
|
|
66
67
|
userRole: user.role,
|
|
67
68
|
deviceId: 'CLI Device',
|
|
68
69
|
expiresAt: new Date(Date.now() + expiresIn).toISOString(),
|
|
69
|
-
apiUrl
|
|
70
|
+
apiUrl: finalApiUrl
|
|
70
71
|
});
|
|
71
72
|
console.log('');
|
|
72
73
|
formatter_1.OutputFormatter.success('授权成功!');
|
|
@@ -88,10 +89,10 @@ async function loginWithBrowser(sessionManager) {
|
|
|
88
89
|
formatter_1.OutputFormatter.error('授权超时,请重新尝试');
|
|
89
90
|
process.exit(1);
|
|
90
91
|
}
|
|
91
|
-
async function loginWithCredentials(sessionManager, email, password, expiresIn) {
|
|
92
|
-
const
|
|
92
|
+
async function loginWithCredentials(sessionManager, email, password, expiresIn, apiUrl) {
|
|
93
|
+
const finalApiUrl = process.env.XW_API_URL || apiUrl;
|
|
93
94
|
console.log(`使用邮箱密码登录: ${email}`);
|
|
94
|
-
const res = await fetch(`${
|
|
95
|
+
const res = await fetch(`${finalApiUrl}/api/cli/auth/login`, {
|
|
95
96
|
method: 'POST',
|
|
96
97
|
headers: { 'Content-Type': 'application/json' },
|
|
97
98
|
body: JSON.stringify({
|
|
@@ -121,7 +122,7 @@ async function loginWithCredentials(sessionManager, email, password, expiresIn)
|
|
|
121
122
|
userRole: user.role,
|
|
122
123
|
deviceId,
|
|
123
124
|
expiresAt,
|
|
124
|
-
apiUrl
|
|
125
|
+
apiUrl: finalApiUrl
|
|
125
126
|
});
|
|
126
127
|
formatter_1.OutputFormatter.success('登录成功!');
|
|
127
128
|
console.log(` 用户: ${user.name} (${user.email})`);
|
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ import { OutputFormatter } from '../../output/formatter'
|
|
|
6
6
|
export function makeLoginCommand(): Command {
|
|
7
7
|
const cmd = new Command('login')
|
|
8
8
|
.description('Login to xuanwu factory')
|
|
9
|
+
.option('-u, --api-url <url>', 'API server URL', 'https://i.xuanwu.dev.aimstek.cn')
|
|
9
10
|
.option('-e, --email <email>', 'Email address (for non-interactive login)')
|
|
10
11
|
.option('-p, --password <password>', 'Password (for non-interactive login)')
|
|
11
12
|
.option('--expires-in <duration>', 'Token expiration (30d, 90d, never)', '30d')
|
|
@@ -17,21 +18,22 @@ export function makeLoginCommand(): Command {
|
|
|
17
18
|
sessionManager,
|
|
18
19
|
options.email,
|
|
19
20
|
options.password,
|
|
20
|
-
options.expiresIn
|
|
21
|
+
options.expiresIn,
|
|
22
|
+
options.apiUrl
|
|
21
23
|
)
|
|
22
24
|
return
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
await loginWithBrowser(sessionManager)
|
|
27
|
+
await loginWithBrowser(sessionManager, options.apiUrl)
|
|
26
28
|
})
|
|
27
29
|
|
|
28
30
|
return cmd
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
async function loginWithBrowser(sessionManager: SessionManager): Promise<void> {
|
|
32
|
-
const
|
|
33
|
+
async function loginWithBrowser(sessionManager: SessionManager, apiUrl: string): Promise<void> {
|
|
34
|
+
const finalApiUrl = process.env.XW_API_URL || apiUrl
|
|
33
35
|
|
|
34
|
-
const deviceAuthRes = await fetch(`${
|
|
36
|
+
const deviceAuthRes = await fetch(`${finalApiUrl}/api/cli/auth/device-code`, {
|
|
35
37
|
method: 'POST'
|
|
36
38
|
})
|
|
37
39
|
|
|
@@ -61,7 +63,7 @@ async function loginWithBrowser(sessionManager: SessionManager): Promise<void> {
|
|
|
61
63
|
await new Promise(resolve => setTimeout(resolve, 3000))
|
|
62
64
|
|
|
63
65
|
const pollRes = await fetch(
|
|
64
|
-
`${
|
|
66
|
+
`${finalApiUrl}/api/cli/auth/poll?session_id=${sessionId}`
|
|
65
67
|
)
|
|
66
68
|
|
|
67
69
|
if (!pollRes.ok) {
|
|
@@ -82,7 +84,7 @@ async function loginWithBrowser(sessionManager: SessionManager): Promise<void> {
|
|
|
82
84
|
userRole: user.role,
|
|
83
85
|
deviceId: 'CLI Device',
|
|
84
86
|
expiresAt: new Date(Date.now() + expiresIn).toISOString(),
|
|
85
|
-
apiUrl
|
|
87
|
+
apiUrl: finalApiUrl
|
|
86
88
|
})
|
|
87
89
|
|
|
88
90
|
console.log('')
|
|
@@ -114,13 +116,14 @@ async function loginWithCredentials(
|
|
|
114
116
|
sessionManager: SessionManager,
|
|
115
117
|
email: string,
|
|
116
118
|
password: string,
|
|
117
|
-
expiresIn: string
|
|
119
|
+
expiresIn: string,
|
|
120
|
+
apiUrl: string
|
|
118
121
|
): Promise<void> {
|
|
119
|
-
const
|
|
122
|
+
const finalApiUrl = process.env.XW_API_URL || apiUrl
|
|
120
123
|
|
|
121
124
|
console.log(`使用邮箱密码登录: ${email}`)
|
|
122
125
|
|
|
123
|
-
const res = await fetch(`${
|
|
126
|
+
const res = await fetch(`${finalApiUrl}/api/cli/auth/login`, {
|
|
124
127
|
method: 'POST',
|
|
125
128
|
headers: { 'Content-Type': 'application/json' },
|
|
126
129
|
body: JSON.stringify({
|
|
@@ -155,7 +158,7 @@ async function loginWithCredentials(
|
|
|
155
158
|
userRole: user.role,
|
|
156
159
|
deviceId,
|
|
157
160
|
expiresAt,
|
|
158
|
-
apiUrl
|
|
161
|
+
apiUrl: finalApiUrl
|
|
159
162
|
})
|
|
160
163
|
|
|
161
164
|
OutputFormatter.success('登录成功!')
|