@cloudbase/toolbox 0.7.17-beta.2 → 0.7.17

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.
@@ -43,6 +43,10 @@ export interface WebAuthOptions {
43
43
  client_id?: string;
44
44
  /** Device Flow 回调,获取设备码后通知调用方 */
45
45
  onDeviceCode?: DeviceFlowOptions['onDeviceCode'];
46
+ /** 自定义 OAuth API 请求的 endpoint */
47
+ getOAuthEndpoint?: DeviceFlowOptions['getOAuthEndpoint'];
48
+ /** 静默模式,不打印任何日志 */
49
+ silent?: boolean;
46
50
  }
47
51
  export interface LoginByApiSecretOptions {
48
52
  /**
package/lib/auth/index.js CHANGED
@@ -82,7 +82,7 @@ class AuthSupervisor {
82
82
  */
83
83
  loginByWebAuth(options = {}) {
84
84
  return __awaiter(this, void 0, void 0, function* () {
85
- const { getAuthUrl, throwError, noBrowser, callbackTimeout, flow = 'device', client_id, onDeviceCode } = options;
85
+ const { getAuthUrl, throwError, noBrowser, callbackTimeout, flow = 'device', client_id, onDeviceCode, getOAuthEndpoint, silent } = options;
86
86
  if (this.cacheCredential && this.needCache && !this.isCacheExpire()) {
87
87
  return this.cacheCredential;
88
88
  }
@@ -95,11 +95,12 @@ class AuthSupervisor {
95
95
  credential = yield (0, web_auth_1.getAuthTokenFromWeb)({
96
96
  getAuthUrl,
97
97
  noBrowser,
98
- callbackTimeout
98
+ callbackTimeout,
99
+ silent
99
100
  });
100
101
  }
101
102
  else {
102
- credential = yield (0, oauth_1.getAuthTokenByDeviceFlow)({ client_id, onDeviceCode });
103
+ credential = yield (0, oauth_1.getAuthTokenByDeviceFlow)({ client_id, onDeviceCode, getOAuthEndpoint, getAuthUrl, silent });
103
104
  }
104
105
  credential = (0, common_1.resolveCredential)(credential);
105
106
  try {
@@ -7,5 +7,11 @@ export interface DeviceFlowOptions {
7
7
  device_code: string;
8
8
  expires_in: number;
9
9
  }) => void;
10
+ /** 自定义 OAuth API 请求的 endpoint */
11
+ getOAuthEndpoint?: (rawEndpoint: string) => string;
12
+ /** 自定义授权跳转链接 */
13
+ getAuthUrl?: (rawUrl: string) => string;
14
+ /** 静默模式,不打印任何日志 */
15
+ silent?: boolean;
10
16
  }
11
17
  export declare function getAuthTokenByDeviceFlow(options?: DeviceFlowOptions): Promise<Credential>;
package/lib/auth/oauth.js CHANGED
@@ -16,6 +16,7 @@ const error_1 = require("../error");
16
16
  const coding_1 = require("../coding");
17
17
  const system_1 = require("../system");
18
18
  const web_auth_1 = require("./web-auth");
19
+ /** 默认国内站 应用侧可通过 getOAuthEndpoint 覆写 */
19
20
  const OAUTH_ENDPOINT = process.env.TCB_OAUTH_ENDPOINT || 'https://tcb-api.cloud.tencent.com/qcloud-tcb/v1/oauth';
20
21
  const DEFAULT_CLIENT_ID = 'cloudbase-toolbox';
21
22
  const POLL_ERROR_CODES = {
@@ -26,14 +27,14 @@ const POLL_ERROR_CODES = {
26
27
  };
27
28
  const SUCCESS_CODE = 'NORMAL';
28
29
  function fetchDeviceCode(options = {}) {
29
- const { client_id = DEFAULT_CLIENT_ID } = options;
30
- return (0, net_1.postFetch)(`${OAUTH_ENDPOINT}/device/code`, { client_id });
30
+ const { client_id = DEFAULT_CLIENT_ID, endpoint = OAUTH_ENDPOINT } = options;
31
+ return (0, net_1.postFetch)(`${endpoint}/device/code`, { client_id });
31
32
  }
32
33
  function fetchPollToken(options) {
33
34
  return __awaiter(this, void 0, void 0, function* () {
34
- const { device_code, client_id = DEFAULT_CLIENT_ID } = options;
35
+ const { device_code, client_id = DEFAULT_CLIENT_ID, endpoint = OAUTH_ENDPOINT } = options;
35
36
  const mac = yield (0, system_1.getMacAddress)();
36
- return (0, net_1.postFetch)(`${OAUTH_ENDPOINT}/token`, {
37
+ return (0, net_1.postFetch)(`${endpoint}/token`, {
37
38
  device_code,
38
39
  client_id,
39
40
  grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
@@ -52,8 +53,9 @@ function sleep(ms) {
52
53
  }
53
54
  function getAuthTokenByDeviceFlow(options = {}) {
54
55
  return __awaiter(this, void 0, void 0, function* () {
55
- const { client_id, onDeviceCode } = options;
56
- const deviceCodeResp = yield fetchDeviceCode({ client_id });
56
+ const { client_id, onDeviceCode, getOAuthEndpoint, getAuthUrl, silent } = options;
57
+ const endpoint = getOAuthEndpoint ? getOAuthEndpoint(OAUTH_ENDPOINT) : OAUTH_ENDPOINT;
58
+ const deviceCodeResp = yield fetchDeviceCode({ client_id, endpoint });
57
59
  if (deviceCodeResp.code !== SUCCESS_CODE) {
58
60
  throw new error_1.CloudBaseError('Device Flow fetchDeviceCode failed', {
59
61
  code: deviceCodeResp.code,
@@ -61,15 +63,17 @@ function getAuthTokenByDeviceFlow(options = {}) {
61
63
  });
62
64
  }
63
65
  const { device_code, user_code, expires_in, interval } = deviceCodeResp.result;
64
- // const defaultVerificationUri = deviceCodeResp.result.verification_uri || `${CLI_AUTH_BASE_URL}#/cli-auth`;
65
66
  // 暂时不消费 verification_uri,由客户端控制跳转
66
67
  const defaultVerificationUri = `${web_auth_1.CLI_AUTH_BASE_URL}#/cli-auth`;
67
68
  // from=cli 后续考虑改用 client_id,因为 toolbox 作为公共依赖,可能被不同 client 所引用
68
- const verification_uri = `${defaultVerificationUri}?user_code=${user_code}&from=cli&mode=device`;
69
- // 打印授权信息,引导用户操作
70
- console.log('\n\n若链接未自动打开,请手动复制至浏览器,或尝试其他登录方式:');
71
- console.log(`\n${verification_uri}`);
72
- console.log(`\n用户码: ${user_code}\n`);
69
+ const rawVerificationUri = `${defaultVerificationUri}?user_code=${user_code}&from=cli&flow=device`;
70
+ const verification_uri = getAuthUrl ? getAuthUrl(rawVerificationUri) : rawVerificationUri;
71
+ if (!silent) {
72
+ // 打印授权信息,引导用户操作
73
+ console.log('\n\n若链接未自动打开,请手动复制至浏览器,或尝试其他登录方式:');
74
+ console.log(`\n${verification_uri}`);
75
+ console.log(`\n用户码: ${user_code}\n`);
76
+ }
73
77
  // 尝试自动打开授权页面
74
78
  yield (0, web_1.openUrl)(verification_uri);
75
79
  if (onDeviceCode) {
@@ -81,7 +85,7 @@ function getAuthTokenByDeviceFlow(options = {}) {
81
85
  yield sleep(pollInterval * 1000);
82
86
  let resp;
83
87
  try {
84
- resp = yield fetchPollToken({ device_code, interval: pollInterval, client_id });
88
+ resp = yield fetchPollToken({ device_code, interval: pollInterval, client_id, endpoint });
85
89
  }
86
90
  catch (e) {
87
91
  throw new error_1.CloudBaseError('Device Flow 轮询请求失败', { original: e });
@@ -4,4 +4,6 @@ export declare function getAuthTokenFromWeb(options?: {
4
4
  getAuthUrl?: (rawUrl: string) => string;
5
5
  noBrowser?: boolean;
6
6
  callbackTimeout?: number;
7
+ /** 静默模式,不打印任何日志 */
8
+ silent?: boolean;
7
9
  }): Promise<Credential>;
@@ -18,7 +18,7 @@ exports.CLI_AUTH_BASE_URL = 'https://tcb.cloud.tencent.com/dev';
18
18
  // 打开云开发控制台,获取授权
19
19
  function getAuthTokenFromWeb(options = {}) {
20
20
  return __awaiter(this, void 0, void 0, function* () {
21
- const { getAuthUrl, noBrowser, callbackTimeout } = options;
21
+ const { getAuthUrl, noBrowser, callbackTimeout, silent } = options;
22
22
  const mac = yield (0, system_1.getMacAddress)();
23
23
  const os = (0, system_1.getOSInfo)();
24
24
  const macHash = (0, coding_1.md5Encoding)(mac);
@@ -44,7 +44,8 @@ function getAuthTokenFromWeb(options = {}) {
44
44
  return cliAuthUrl;
45
45
  }, 'login', {
46
46
  noBrowser,
47
- callbackTimeout
47
+ callbackTimeout,
48
+ silent
48
49
  });
49
50
  const credential = (0, common_1.resolveCredential)(query);
50
51
  return credential;
package/lib/web/web.d.ts CHANGED
@@ -6,6 +6,8 @@ export type CheckFn = (query: IQuery) => Promise<void>;
6
6
  export interface GetDataFromWebOptions {
7
7
  noBrowser?: boolean;
8
8
  callbackTimeout?: number;
9
+ /** 静默模式,不打印任何日志,也不自动打开浏览器 */
10
+ silent?: boolean;
9
11
  }
10
12
  export declare function isTruthyFlag(value?: string): boolean;
11
13
  export declare function openUrl(url: string): Promise<boolean>;
package/lib/web/web.js CHANGED
@@ -118,17 +118,20 @@ function openUrl(url) {
118
118
  exports.openUrl = openUrl;
119
119
  // 从 Web 页面中获取数据
120
120
  function getDataFromWeb(getUrl, type, options = {}) {
121
- var _a, _b;
121
+ var _a, _b, _c;
122
122
  return __awaiter(this, void 0, void 0, function* () {
123
123
  const { server, port } = yield createLocalServer();
124
124
  const noBrowser = (_a = options.noBrowser) !== null && _a !== void 0 ? _a : isTruthyFlag(process.env.TCB_NO_BROWSER);
125
125
  const callbackTimeout = (_b = options.callbackTimeout) !== null && _b !== void 0 ? _b : 180000;
126
+ const silent = (_c = options.silent) !== null && _c !== void 0 ? _c : false;
126
127
  if (!Number.isFinite(callbackTimeout) || callbackTimeout <= 0) {
127
128
  throw new error_1.CloudBaseError('callbackTimeout must be a positive number');
128
129
  }
129
130
  const url = getUrl(port);
130
- console.log('\n\n若链接未自动打开,请手动复制至浏览器,或尝试其他登录方式:');
131
- console.log(`\n${url}\n`);
131
+ if (!silent) {
132
+ console.log('\n\n若链接未自动打开,请手动复制至浏览器,或尝试其他登录方式:');
133
+ console.log(`\n${url}\n`);
134
+ }
132
135
  if (!noBrowser) {
133
136
  // 对 url 转码, 避免 wsl 无法正常打开地址
134
137
  // https://www.npmjs.com/package/open#url
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/toolbox",
3
- "version": "0.7.17-beta.2",
3
+ "version": "0.7.17",
4
4
  "description": "The toolbox for cloudbase",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -67,4 +67,4 @@
67
67
  }
68
68
  },
69
69
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
70
- }
70
+ }