esa-cli 1.0.9 → 1.0.10

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.
@@ -13,11 +13,42 @@ import t from '../../i18n/index.js';
13
13
  import logger from '../../libs/logger.js';
14
14
  import { getCliConfig, updateCliConfigFile, generateDefaultConfig } from '../../utils/fileUtils/index.js';
15
15
  import { validateCredentials } from '../../utils/validateCredentials.js';
16
+ /** Parse STS token string: "AccessKeyId,AccessKeySecret,SecurityToken" or JSON */
17
+ function parseStsToken(raw) {
18
+ var _a, _b, _c;
19
+ const s = raw.trim();
20
+ if (!s)
21
+ return null;
22
+ if (s.startsWith('{')) {
23
+ try {
24
+ const o = JSON.parse(s);
25
+ const accessKeyId = (_a = o.AccessKeyId) !== null && _a !== void 0 ? _a : o.accessKeyId;
26
+ const accessKeySecret = (_b = o.AccessKeySecret) !== null && _b !== void 0 ? _b : o.accessKeySecret;
27
+ const securityToken = (_c = o.SecurityToken) !== null && _c !== void 0 ? _c : o.securityToken;
28
+ if (accessKeyId && accessKeySecret && securityToken) {
29
+ return { accessKeyId, accessKeySecret, securityToken };
30
+ }
31
+ }
32
+ catch (_d) {
33
+ return null;
34
+ }
35
+ return null;
36
+ }
37
+ const parts = s.split(',').map((p) => p.trim());
38
+ if (parts.length >= 3) {
39
+ return {
40
+ accessKeyId: parts[0],
41
+ accessKeySecret: parts[1],
42
+ securityToken: parts.slice(2).join(',').trim()
43
+ };
44
+ }
45
+ return null;
46
+ }
16
47
  const login = {
17
48
  command: 'login',
18
49
  describe: `🔑 ${t('login_describe').d('Login to the server')}`,
19
50
  builder: (yargs) => {
20
- var _a, _b;
51
+ var _a, _b, _c;
21
52
  return yargs
22
53
  .option('access-key-id', {
23
54
  alias: 'ak',
@@ -28,6 +59,10 @@ const login = {
28
59
  alias: 'sk',
29
60
  describe: (_b = t('login_option_access_key_secret')) === null || _b === void 0 ? void 0 : _b.d('AccessKey Secret'),
30
61
  type: 'string'
62
+ })
63
+ .option('sts-token', {
64
+ describe: (_c = t('login_option_sts_token')) === null || _c === void 0 ? void 0 : _c.d('STS token: AccessKeyId,AccessKeySecret,SecurityToken (comma-separated, one-shot)'),
65
+ type: 'string'
31
66
  });
32
67
  },
33
68
  handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
@@ -38,8 +73,10 @@ export default login;
38
73
  export function handleLogin(argv) {
39
74
  return __awaiter(this, void 0, void 0, function* () {
40
75
  generateDefaultConfig();
41
- if (process.env.ESA_ACCESS_KEY_ID && process.env.ESA_ACCESS_KEY_SECRET) {
42
- const result = yield validateCredentials(process.env.ESA_ACCESS_KEY_ID, process.env.ESA_ACCESS_KEY_SECRET);
76
+ const envSecurityToken = process.env.ESA_SECURITY_TOKEN;
77
+ if (process.env.ESA_ACCESS_KEY_ID &&
78
+ process.env.ESA_ACCESS_KEY_SECRET) {
79
+ const result = yield validateCredentials(process.env.ESA_ACCESS_KEY_ID, process.env.ESA_ACCESS_KEY_SECRET, envSecurityToken);
43
80
  if (result.valid) {
44
81
  logger.log(t('login_get_credentials_from_environment_variables').d('Get credentials from environment variables'));
45
82
  logger.success(t('login_success').d('Login success!'));
@@ -49,6 +86,27 @@ export function handleLogin(argv) {
49
86
  }
50
87
  return;
51
88
  }
89
+ const stsTokenRaw = argv === null || argv === void 0 ? void 0 : argv['sts-token'];
90
+ if (stsTokenRaw) {
91
+ const parsed = parseStsToken(stsTokenRaw);
92
+ if (!parsed) {
93
+ logger.error(t('login_sts_token_format_invalid').d('Invalid STS token format. Use: AccessKeyId,AccessKeySecret,SecurityToken'));
94
+ return;
95
+ }
96
+ const result = yield validateCredentials(parsed.accessKeyId, parsed.accessKeySecret, parsed.securityToken);
97
+ if (result.valid) {
98
+ logger.success(t('login_success').d('Login success!'));
99
+ updateCliConfigFile(Object.assign({ auth: {
100
+ accessKeyId: parsed.accessKeyId,
101
+ accessKeySecret: parsed.accessKeySecret,
102
+ securityToken: parsed.securityToken
103
+ } }, (result.endpoint ? { endpoint: result.endpoint } : {})));
104
+ }
105
+ else {
106
+ logger.error(result.message || 'Login failed');
107
+ }
108
+ return;
109
+ }
52
110
  const accessKeyId = argv === null || argv === void 0 ? void 0 : argv['access-key-id'];
53
111
  const accessKeySecret = argv === null || argv === void 0 ? void 0 : argv['access-key-secret'];
54
112
  if (accessKeyId && accessKeySecret) {
@@ -73,7 +131,7 @@ export function handleLogin(argv) {
73
131
  cliConfig.auth &&
74
132
  cliConfig.auth.accessKeyId &&
75
133
  cliConfig.auth.accessKeySecret) {
76
- const loginStatus = yield validateCredentials(cliConfig.auth.accessKeyId, cliConfig.auth.accessKeySecret);
134
+ const loginStatus = yield validateCredentials(cliConfig.auth.accessKeyId, cliConfig.auth.accessKeySecret, cliConfig.auth.securityToken);
77
135
  if (loginStatus.valid) {
78
136
  logger.warn(t('login_already').d('You are already logged in.'));
79
137
  const selected = (yield clackSelect({
@@ -99,6 +157,47 @@ export function handleLogin(argv) {
99
157
  }
100
158
  export function interactiveLogin() {
101
159
  return __awaiter(this, void 0, void 0, function* () {
160
+ const loginMethod = (yield clackSelect({
161
+ message: t('login_method_select').d('Choose login method'),
162
+ options: [
163
+ {
164
+ label: t('login_method_aksk').d('AK/SK (AccessKey ID + AccessKey Secret)'),
165
+ value: 'aksk'
166
+ },
167
+ {
168
+ label: t('login_method_sts').d('STS Token (one-shot: AccessKeyId,AccessKeySecret,SecurityToken)'),
169
+ value: 'sts'
170
+ }
171
+ ]
172
+ }));
173
+ if (isCancel(loginMethod)) {
174
+ return;
175
+ }
176
+ if (loginMethod === 'sts') {
177
+ const stsInput = (yield clackText({
178
+ message: t('login_sts_token_prompt').d('Enter STS token (AccessKeyId,AccessKeySecret,SecurityToken):')
179
+ }));
180
+ if (isCancel(stsInput))
181
+ return;
182
+ const parsed = parseStsToken(stsInput);
183
+ if (!parsed) {
184
+ logger.error(t('login_sts_token_format_invalid').d('Invalid STS token format. Use: AccessKeyId,AccessKeySecret,SecurityToken'));
185
+ return;
186
+ }
187
+ const loginStatus = yield validateCredentials(parsed.accessKeyId, parsed.accessKeySecret, parsed.securityToken);
188
+ if (loginStatus.valid) {
189
+ yield updateCliConfigFile(Object.assign({ auth: {
190
+ accessKeyId: parsed.accessKeyId,
191
+ accessKeySecret: parsed.accessKeySecret,
192
+ securityToken: parsed.securityToken
193
+ } }, (loginStatus.endpoint ? { endpoint: loginStatus.endpoint } : {})));
194
+ logger.success(t('login_success').d('Login success!'));
195
+ }
196
+ else {
197
+ logger.error(loginStatus.message || 'Login failed');
198
+ }
199
+ return;
200
+ }
102
201
  const styledUrl = chalk.underline.blue('https://ram.console.aliyun.com/manage/ak');
103
202
  logger.log(`🔑 ${chalk.underline(t('login_get_ak_sk').d(`Please go to the following link to get your account's AccessKey ID and AccessKey Secret`))}`);
104
203
  logger.log(`👉 ${styledUrl}`);
@@ -28,11 +28,18 @@ export function handleLogout() {
28
28
  return;
29
29
  }
30
30
  if (!cliConfig.auth) {
31
- cliConfig.auth = { accessKeyId: '', accessKeySecret: '' };
31
+ cliConfig.auth = {
32
+ accessKeyId: '',
33
+ accessKeySecret: '',
34
+ securityToken: ''
35
+ };
32
36
  }
33
37
  else {
34
38
  cliConfig.auth.accessKeyId = '';
35
39
  cliConfig.auth.accessKeySecret = '';
40
+ if ('securityToken' in cliConfig.auth) {
41
+ cliConfig.auth.securityToken = '';
42
+ }
36
43
  }
37
44
  yield updateCliConfigFile(cliConfig);
38
45
  logger.success(t('logout_success').d('Logout successfully'));
@@ -16,7 +16,7 @@ import { ApiService } from '../libs/apiService.js';
16
16
  import { isInstalledGit } from '../libs/git/index.js';
17
17
  import logger from '../libs/logger.js';
18
18
  import { getRoot } from '../utils/fileUtils/base.js';
19
- import { getCliConfig, projectConfigPath } from '../utils/fileUtils/index.js';
19
+ import { getApiConfig, getCliConfig, projectConfigPath } from '../utils/fileUtils/index.js';
20
20
  import { validateCredentials } from '../utils/validateCredentials.js';
21
21
  import { getRoutineDetails } from './common/utils.js';
22
22
  export const checkDirectory = (isCheckGit = false) => {
@@ -78,28 +78,24 @@ export function validDomain(domain) {
78
78
  }
79
79
  export function checkIsLoginSuccess() {
80
80
  return __awaiter(this, void 0, void 0, function* () {
81
- var _a, _b;
81
+ var _a, _b, _c;
82
82
  const cliConfig = getCliConfig();
83
83
  let accessKeyId = process.env.ESA_ACCESS_KEY_ID || ((_a = cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId);
84
84
  let accessKeySecret = process.env.ESA_ACCESS_KEY_SECRET || ((_b = cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret);
85
+ const securityToken = process.env.ESA_SECURITY_TOKEN || ((_c = cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.auth) === null || _c === void 0 ? void 0 : _c.securityToken);
85
86
  if (accessKeyId && accessKeySecret) {
86
- const result = yield validateCredentials(accessKeyId, accessKeySecret);
87
+ const result = yield validateCredentials(accessKeyId, accessKeySecret, securityToken);
87
88
  const server = yield ApiService.getInstance();
88
89
  if (result.valid) {
89
- server.updateConfig({
90
- auth: {
91
- accessKeyId,
92
- accessKeySecret
93
- },
94
- endpoint: result.endpoint
95
- });
96
- api.updateConfig({
97
- auth: {
98
- accessKeyId,
99
- accessKeySecret
100
- },
101
- endpoint: result.endpoint
102
- });
90
+ const auth = {
91
+ accessKeyId,
92
+ accessKeySecret
93
+ };
94
+ if (securityToken)
95
+ auth.securityToken = securityToken;
96
+ const fileConfig = getApiConfig();
97
+ server.updateConfig(Object.assign(Object.assign({}, fileConfig), { auth }));
98
+ api.updateConfig(Object.assign(Object.assign({}, fileConfig), { auth }));
103
99
  return true;
104
100
  }
105
101
  }
@@ -1075,6 +1075,30 @@
1075
1075
  "en": "AccessKey Secret (SK)",
1076
1076
  "zh_CN": "AccessKey Secret (SK)"
1077
1077
  },
1078
+ "login_option_sts_token": {
1079
+ "en": "STS token: AccessKeyId,AccessKeySecret,SecurityToken (comma-separated, one-shot)",
1080
+ "zh_CN": "STS 临时凭证:AccessKeyId,AccessKeySecret,SecurityToken(逗号分隔,一次性输入)"
1081
+ },
1082
+ "login_sts_token_prompt": {
1083
+ "en": "Enter STS token (AccessKeyId,AccessKeySecret,SecurityToken):",
1084
+ "zh_CN": "请输入 STS 凭证(AccessKeyId,AccessKeySecret,SecurityToken):"
1085
+ },
1086
+ "login_sts_token_format_invalid": {
1087
+ "en": "Invalid STS token format. Use: AccessKeyId,AccessKeySecret,SecurityToken",
1088
+ "zh_CN": "STS 凭证格式错误,请使用:AccessKeyId,AccessKeySecret,SecurityToken"
1089
+ },
1090
+ "login_method_select": {
1091
+ "en": "Choose login method",
1092
+ "zh_CN": "选择登录方式"
1093
+ },
1094
+ "login_method_aksk": {
1095
+ "en": "AK/SK (AccessKey ID + AccessKey Secret)",
1096
+ "zh_CN": "AK/SK(AccessKey ID + AccessKey Secret)"
1097
+ },
1098
+ "login_method_sts": {
1099
+ "en": "STS Token (one-shot: AccessKeyId,AccessKeySecret,SecurityToken)",
1100
+ "zh_CN": "STS 临时凭证(一次性输入:AccessKeyId,AccessKeySecret,SecurityToken)"
1101
+ },
1078
1102
  "login_option_skip_login": {
1079
1103
  "en": "Skip login",
1080
1104
  "zh_CN": "跳过登录"
package/dist/libs/api.js CHANGED
@@ -74,13 +74,10 @@ class Client {
74
74
  this.client = Client.createClient(config);
75
75
  }
76
76
  static createClient(config) {
77
- var _a, _b;
78
- const apiConfig = new $OpenApi.Config({
79
- accessKeyId: (_a = config.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
80
- accessKeySecret: (_b = config.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
81
- endpoint: config.endpoint,
82
- userAgent: CLI_USER_AGENT
83
- });
77
+ var _a, _b, _c;
78
+ const apiConfig = new $OpenApi.Config(Object.assign({ accessKeyId: (_a = config.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId, accessKeySecret: (_b = config.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret, endpoint: config.endpoint, userAgent: CLI_USER_AGENT }, (((_c = config.auth) === null || _c === void 0 ? void 0 : _c.securityToken)
79
+ ? { securityToken: config.auth.securityToken }
80
+ : {})));
84
81
  return new ESA.default(apiConfig);
85
82
  }
86
83
  updateConfig(config) {
@@ -16,13 +16,10 @@ import { CLI_USER_AGENT } from './constants.js';
16
16
  import { Environment } from './interface.js';
17
17
  export class ApiService {
18
18
  constructor(cliConfig) {
19
- var _a, _b;
20
- let apiConfig = new $OpenApi.Config({
21
- accessKeyId: (_a = cliConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
22
- accessKeySecret: (_b = cliConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
23
- endpoint: cliConfig.endpoint,
24
- userAgent: CLI_USER_AGENT
25
- });
19
+ var _a, _b, _c;
20
+ let apiConfig = new $OpenApi.Config(Object.assign({ accessKeyId: (_a = cliConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId, accessKeySecret: (_b = cliConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret, endpoint: cliConfig.endpoint, userAgent: CLI_USER_AGENT }, (((_c = cliConfig.auth) === null || _c === void 0 ? void 0 : _c.securityToken)
21
+ ? { securityToken: cliConfig.auth.securityToken }
22
+ : {})));
26
23
  this.client = new $OpenApi.default.default(apiConfig);
27
24
  }
28
25
  static getInstance() {
@@ -35,13 +32,10 @@ export class ApiService {
35
32
  });
36
33
  }
37
34
  updateConfig(newConfig) {
38
- var _a, _b;
39
- let apiConfig = new $OpenApi.Config({
40
- accessKeyId: (_a = newConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
41
- accessKeySecret: (_b = newConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
42
- endpoint: newConfig.endpoint,
43
- userAgent: CLI_USER_AGENT
44
- });
35
+ var _a, _b, _c;
36
+ let apiConfig = new $OpenApi.Config(Object.assign({ accessKeyId: (_a = newConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId, accessKeySecret: (_b = newConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret, endpoint: newConfig.endpoint, userAgent: CLI_USER_AGENT }, (((_c = newConfig.auth) === null || _c === void 0 ? void 0 : _c.securityToken)
37
+ ? { securityToken: newConfig.auth.securityToken }
38
+ : {})));
45
39
  this.client = new $OpenApi.default.default(apiConfig);
46
40
  }
47
41
  /**
@@ -268,12 +268,13 @@ export function getDevOpenBrowserUrl() {
268
268
  return `http://localhost:${port}`;
269
269
  }
270
270
  export const getApiConfig = () => {
271
- var _a, _b;
271
+ var _a, _b, _c;
272
272
  const [cliConfig, projectConfig] = getConfigurations();
273
273
  let defaultConfig = {
274
274
  auth: {
275
275
  accessKeyId: '',
276
- accessKeySecret: ''
276
+ accessKeySecret: '',
277
+ securityToken: undefined
277
278
  },
278
279
  endpoint: `esa.cn-hangzhou.aliyuncs.com`
279
280
  };
@@ -281,7 +282,8 @@ export const getApiConfig = () => {
281
282
  const config = {
282
283
  auth: {
283
284
  accessKeyId: (_a = combinedConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
284
- accessKeySecret: (_b = combinedConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret
285
+ accessKeySecret: (_b = combinedConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
286
+ securityToken: (_c = combinedConfig.auth) === null || _c === void 0 ? void 0 : _c.securityToken
285
287
  },
286
288
  endpoint: combinedConfig.endpoint
287
289
  };
@@ -14,15 +14,14 @@ const DOMESTIC_ENDPOINT = 'esa.cn-hangzhou.aliyuncs.com';
14
14
  const INTERNATIONAL_ENDPOINT = 'esa.ap-southeast-1.aliyuncs.com';
15
15
  /**
16
16
  * Validate credentials for a single endpoint
17
+ * @param securityToken - Optional STS SecurityToken; when provided, uses STS auth
17
18
  */
18
- function validateEndpoint(accessKeyId, accessKeySecret, endpoint) {
19
+ function validateEndpoint(accessKeyId, accessKeySecret, endpoint, securityToken) {
19
20
  return __awaiter(this, void 0, void 0, function* () {
20
21
  try {
21
- const apiConfig = new $OpenApi.Config({
22
- accessKeyId,
22
+ const apiConfig = new $OpenApi.Config(Object.assign({ accessKeyId,
23
23
  accessKeySecret,
24
- endpoint
25
- });
24
+ endpoint }, (securityToken ? { securityToken } : {})));
26
25
  const client = new $OpenApi.default.default(apiConfig);
27
26
  const params = {
28
27
  action: 'GetErService',
@@ -80,25 +79,24 @@ function validateEndpoint(accessKeyId, accessKeySecret, endpoint) {
80
79
  });
81
80
  }
82
81
  /**
83
- * Validate if AK/SK/endpoint are valid
82
+ * Validate if AK/SK/endpoint are valid (supports STS when securityToken is provided)
84
83
  *
85
84
  * @param accessKeyId - AccessKey ID
86
85
  * @param accessKeySecret - AccessKey Secret
86
+ * @param securityToken - Optional STS SecurityToken for temporary credentials
87
87
  * @returns Validation result, including whether valid, site type and endpoint
88
88
  */
89
- export function validateCredentials(accessKeyId, accessKeySecret) {
89
+ export function validateCredentials(accessKeyId, accessKeySecret, securityToken) {
90
90
  return __awaiter(this, void 0, void 0, function* () {
91
+ const withToken = (ep) => validateEndpoint(accessKeyId, accessKeySecret, ep, securityToken);
91
92
  if (process.env.CUSTOM_ENDPOINT) {
92
- const result = yield validateEndpoint(accessKeyId, accessKeySecret, process.env.CUSTOM_ENDPOINT);
93
+ const result = yield withToken(process.env.CUSTOM_ENDPOINT);
93
94
  if (result.valid) {
94
95
  return { valid: true, endpoint: process.env.CUSTOM_ENDPOINT };
95
96
  }
96
- else {
97
- return { valid: false, message: result.message };
98
- }
97
+ return { valid: false, message: result.message };
99
98
  }
100
- // First validate domestic site
101
- const domesticResult = yield validateEndpoint(accessKeyId, accessKeySecret, DOMESTIC_ENDPOINT);
99
+ const domesticResult = yield withToken(DOMESTIC_ENDPOINT);
102
100
  if (domesticResult.valid) {
103
101
  return {
104
102
  valid: true,
@@ -106,8 +104,7 @@ export function validateCredentials(accessKeyId, accessKeySecret) {
106
104
  endpoint: DOMESTIC_ENDPOINT
107
105
  };
108
106
  }
109
- // If domestic site validation fails, validate international site
110
- const internationalResult = yield validateEndpoint(accessKeyId, accessKeySecret, INTERNATIONAL_ENDPOINT);
107
+ const internationalResult = yield withToken(INTERNATIONAL_ENDPOINT);
111
108
  if (internationalResult.valid) {
112
109
  return {
113
110
  valid: true,
@@ -115,7 +112,6 @@ export function validateCredentials(accessKeyId, accessKeySecret) {
115
112
  endpoint: INTERNATIONAL_ENDPOINT
116
113
  };
117
114
  }
118
- // Both failed, return failure result
119
115
  return {
120
116
  valid: false,
121
117
  message: domesticResult.message ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esa-cli",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "A CLI for operating Alibaba Cloud ESA Functions and Pages.",
5
5
  "main": "bin/enter.cjs",
6
6
  "type": "module",