@cloudbase/toolbox 0.7.19 → 0.7.21-beta.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.
@@ -1,4 +1,10 @@
1
+ import { LocalStore } from '../localstore';
1
2
  import { Credential, WebAuthCredential, RequestConfig } from '../types';
3
+ export declare const DEFAULT_CLIENT_ID = "cloudbase-cli";
4
+ export declare const configStore: LocalStore<{
5
+ customOAuthEndpoint?: string;
6
+ client_id?: string;
7
+ }>;
2
8
  export declare function checkAuth(credential: Credential, options?: RequestConfig): Promise<any>;
3
9
  export declare function resolveCredential(data: Partial<Credential> & Partial<WebAuthCredential>): Credential;
4
10
  export declare function resolveWebCredential(credential: Credential): WebAuthCredential;
@@ -9,10 +9,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.resolveWebCredential = exports.resolveCredential = exports.checkAuth = void 0;
12
+ exports.resolveWebCredential = exports.resolveCredential = exports.checkAuth = exports.configStore = exports.DEFAULT_CLIENT_ID = void 0;
13
13
  const cloud_api_1 = require("@cloudbase/cloud-api");
14
14
  const config_1 = require("../config");
15
- // 调用 env:list 接口,检查密钥是否有效
15
+ const localstore_1 = require("../localstore");
16
+ exports.DEFAULT_CLIENT_ID = 'cloudbase-cli';
17
+ exports.configStore = new localstore_1.LocalStore({}, 'config');
18
+ // 调用 CheckTcbService 接口,检查密钥是否有效
19
+ // 相比 DescribeEnvs,该接口不会返回环境列表,仅验证登录态,性能更好
16
20
  function checkAuth(credential, options = {}) {
17
21
  return __awaiter(this, void 0, void 0, function* () {
18
22
  // 兼容原临时秘钥
@@ -31,14 +35,14 @@ function checkAuth(credential, options = {}) {
31
35
  });
32
36
  return tcbService.request({
33
37
  region,
34
- action: 'DescribeEnvs'
38
+ action: 'CheckTcbService'
35
39
  });
36
40
  });
37
41
  }
38
42
  exports.checkAuth = checkAuth;
39
43
  // 兼容解析旧的登录态
40
44
  function resolveCredential(data) {
41
- let { secretId, secretKey, token, accessTokenExpired, tmpSecretId, tmpSecretKey, tmpToken, tmpExpired, expired, authTime, refreshToken, uin, hash, envId } = data;
45
+ let { secretId, secretKey, token, accessTokenExpired, tmpSecretId, tmpSecretKey, tmpToken, tmpExpired, expired, authTime, refreshToken, uin, hash, envId, envIds, envList, envBillingInfoList } = data;
42
46
  // 兼容旧的登录态信息
43
47
  token = token || tmpToken;
44
48
  secretId = secretId || tmpSecretId;
@@ -54,12 +58,15 @@ function resolveCredential(data) {
54
58
  refreshToken,
55
59
  uin,
56
60
  hash,
57
- envId
61
+ envId,
62
+ envIds,
63
+ envList,
64
+ envBillingInfoList
58
65
  };
59
66
  }
60
67
  exports.resolveCredential = resolveCredential;
61
68
  function resolveWebCredential(credential) {
62
- const { secretId, secretKey, token, accessTokenExpired, expired, authTime, refreshToken, uin, hash, envId } = credential;
69
+ const { secretId, secretKey, token, accessTokenExpired, expired, authTime, refreshToken, uin, hash, envId, envIds, envList, envBillingInfoList } = credential;
63
70
  const webCredential = {
64
71
  tmpSecretId: secretId,
65
72
  tmpSecretKey: secretKey,
@@ -70,7 +77,10 @@ function resolveWebCredential(credential) {
70
77
  refreshToken,
71
78
  uin,
72
79
  hash,
73
- envId
80
+ envId,
81
+ envIds,
82
+ envList,
83
+ envBillingInfoList
74
84
  };
75
85
  return webCredential;
76
86
  }
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
11
22
  Object.defineProperty(exports, "__esModule", { value: true });
12
23
  exports.getCredentialWithoutCheck = exports.checkAndGetCredential = exports.isCamRefused = exports.refreshTmpToken = exports.getCredentialData = exports.ENV_NAME = exports.authStore = void 0;
13
24
  const cloud_api_1 = require("@cloudbase/cloud-api");
@@ -67,12 +78,53 @@ function refreshTmpToken(metaData) {
67
78
  const mac = yield (0, system_1.getMacAddress)();
68
79
  const hash = (0, coding_1.md5Encoding)(mac);
69
80
  metaData.hash = hash;
81
+ // 读取自定义 OAuth 配置
82
+ const customOAuthEndpoint = yield common_1.configStore.get('customOAuthEndpoint');
83
+ if (customOAuthEndpoint) {
84
+ // ===== 自定义模式 =====
85
+ const clientId = (yield common_1.configStore.get('client_id')) || common_1.DEFAULT_CLIENT_ID;
86
+ const body = {
87
+ grant_type: metaData.isLogout ? 'revoke_token' : 'refresh_token',
88
+ refresh_token: metaData.refreshToken,
89
+ client_id: clientId,
90
+ };
91
+ const res = yield async_1.AsyncMerge.merge(() => (0, cloud_api_1.fetch)(`${customOAuthEndpoint}/token`, {
92
+ method: 'POST',
93
+ timeout: 15000,
94
+ body: JSON.stringify(body),
95
+ headers: { 'Content-Type': 'application/json' }
96
+ }, (0, system_1.getProxy)()), 'refreshToken', {
97
+ maxAge: 5000
98
+ });
99
+ // 自定义模式错误响应:{ error, error_description }
100
+ if (res.error) {
101
+ throw new error_1.CloudBaseError(res.error_description || res.error, {
102
+ action: metaData.isLogout ? 'RevokeToken' : 'RefreshAccessToken',
103
+ code: res.error,
104
+ });
105
+ }
106
+ // 登出(revoke_token)成功,无需返回凭证
107
+ if (metaData.isLogout) {
108
+ return res;
109
+ }
110
+ // 刷新 token 成功响应直接是 WebAuthCredential(无 code/data 包装)
111
+ if (!res || !res.tmpSecretId) {
112
+ throw new error_1.CloudBaseError('Token 刷新失败,可能是网络访问异常,请尝试重试');
113
+ }
114
+ if (metaData.envId) {
115
+ res.envId = metaData.envId;
116
+ }
117
+ return res;
118
+ }
119
+ // ===== 标准模式 =====
70
120
  const credential = (0, common_1.resolveWebCredential)(metaData);
121
+ // 发送请求时不带 envIds/envList/envBillingInfoList
122
+ const { envIds: _a, envList: _b, envBillingInfoList: _c } = credential, requestBody = __rest(credential, ["envIds", "envList", "envBillingInfoList"]);
71
123
  const res = yield async_1.AsyncMerge.merge(() => (0, cloud_api_1.fetch)(refreshTokenUrl, {
72
124
  method: 'POST',
73
125
  // 超时时间:15S
74
126
  timeout: 15000,
75
- body: JSON.stringify(credential),
127
+ body: JSON.stringify(requestBody),
76
128
  headers: { 'Content-Type': 'application/json' }
77
129
  }, (0, system_1.getProxy)()), 'refreshToken', {
78
130
  maxAge: 5000
package/lib/auth/oauth.js CHANGED
@@ -16,9 +16,24 @@ 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
+ const common_1 = require("./common");
19
20
  /** 默认国内站 应用侧可通过 getOAuthEndpoint 覆写 */
20
- const OAUTH_ENDPOINT = process.env.TCB_OAUTH_ENDPOINT || 'https://tcb-api.cloud.tencent.com/qcloud-tcb/v1/oauth';
21
- const DEFAULT_CLIENT_ID = 'cloudbase-toolbox';
21
+ const DEFAULT_OAUTH_ENDPOINT = process.env.TCB_OAUTH_ENDPOINT || 'https://tcb-api.cloud.tencent.com/qcloud-tcb/v1/oauth';
22
+ /**
23
+ * 解析 OAuth Endpoint,优先级:getOAuthEndpoint > customOAuthEndpoint > default
24
+ */
25
+ function resolveOAuthEndpoint(getOAuthEndpoint) {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ if (getOAuthEndpoint) {
28
+ return getOAuthEndpoint(DEFAULT_OAUTH_ENDPOINT);
29
+ }
30
+ const customOAuthEndpoint = yield common_1.configStore.get('customOAuthEndpoint');
31
+ if (customOAuthEndpoint) {
32
+ return customOAuthEndpoint;
33
+ }
34
+ return DEFAULT_OAUTH_ENDPOINT;
35
+ });
36
+ }
22
37
  const POLL_ERROR_CODES = {
23
38
  AUTHORIZATION_PENDING: 'authorization_pending',
24
39
  SLOW_DOWN: 'slow_down',
@@ -27,12 +42,12 @@ const POLL_ERROR_CODES = {
27
42
  };
28
43
  const SUCCESS_CODE = 'NORMAL';
29
44
  function fetchDeviceCode(options = {}) {
30
- const { client_id = DEFAULT_CLIENT_ID, endpoint = OAUTH_ENDPOINT } = options;
45
+ const { client_id = common_1.DEFAULT_CLIENT_ID, endpoint = DEFAULT_OAUTH_ENDPOINT } = options;
31
46
  return (0, net_1.postFetch)(`${endpoint}/device/code`, { client_id });
32
47
  }
33
48
  function fetchPollToken(options) {
34
49
  return __awaiter(this, void 0, void 0, function* () {
35
- const { device_code, client_id = DEFAULT_CLIENT_ID, endpoint = OAUTH_ENDPOINT } = options;
50
+ const { device_code, client_id = common_1.DEFAULT_CLIENT_ID, endpoint = DEFAULT_OAUTH_ENDPOINT } = options;
36
51
  const mac = yield (0, system_1.getMacAddress)();
37
52
  return (0, net_1.postFetch)(`${endpoint}/token`, {
38
53
  device_code,
@@ -89,7 +104,7 @@ function unwrapTokenResponse(raw, custom) {
89
104
  function getAuthTokenByDeviceFlow(options = {}) {
90
105
  return __awaiter(this, void 0, void 0, function* () {
91
106
  const { client_id, onDeviceCode, getOAuthEndpoint, getAuthUrl, silent, custom } = options;
92
- const endpoint = getOAuthEndpoint ? getOAuthEndpoint(OAUTH_ENDPOINT) : OAUTH_ENDPOINT;
107
+ const endpoint = yield resolveOAuthEndpoint(getOAuthEndpoint);
93
108
  // ---- 获取 device code ----
94
109
  const deviceCodeRaw = yield fetchDeviceCode({ client_id, endpoint });
95
110
  const { data: deviceCodeData } = unwrapDeviceCodeResponse(deviceCodeRaw, !!custom);
package/lib/types.d.ts CHANGED
@@ -1,3 +1,88 @@
1
+ export interface EnvInfo {
2
+ EnvId: string;
3
+ PackageType?: string;
4
+ EnvType?: string;
5
+ IsDauPackage?: boolean;
6
+ Source?: string;
7
+ Alias?: string;
8
+ Status?: string;
9
+ PayMode?: string;
10
+ Tags?: Record<string, string>[];
11
+ PackageName?: string;
12
+ IsAutoDegrade?: boolean;
13
+ EnvChannel?: string;
14
+ Region?: string;
15
+ IsDefault?: boolean;
16
+ PackageId?: string;
17
+ CreateTime?: string;
18
+ UpdateTime?: string;
19
+ Databases?: {
20
+ InstanceId: string;
21
+ Region: string;
22
+ Status: string;
23
+ UpdateTime: string;
24
+ }[];
25
+ Storages?: {
26
+ Region: string;
27
+ Bucket: string;
28
+ CdnDomain: string;
29
+ AppId: string;
30
+ }[];
31
+ Functions?: {
32
+ Namespace: string;
33
+ Region: string;
34
+ }[];
35
+ LogServices?: {
36
+ LogsetName: string;
37
+ LogsetId: string;
38
+ TopicName: string;
39
+ TopicId: string;
40
+ Region: string;
41
+ }[];
42
+ StaticStorages?: {
43
+ Type: string;
44
+ Bucket: string;
45
+ Region: string;
46
+ Status: string;
47
+ }[];
48
+ CustomLogServices?: {
49
+ ClsTopicId: string;
50
+ ClsRegion: string;
51
+ ClsLogsetId: string;
52
+ CreateTime: string;
53
+ }[];
54
+ }
55
+ export interface OrderInfo {
56
+ TranId?: string;
57
+ PackageId?: string;
58
+ TranType?: string;
59
+ TranStatus?: string;
60
+ UpdateTime?: string;
61
+ CreateTime?: string;
62
+ PayMode?: string;
63
+ ExtensionId?: string;
64
+ ResourceReady?: string;
65
+ Flag?: string;
66
+ ReqBody?: string;
67
+ }
68
+ export interface EnvBillingInfoItem {
69
+ EnvId: string;
70
+ PackageId?: string;
71
+ PackageName?: string;
72
+ IsAutoRenew?: boolean;
73
+ Status?: string;
74
+ PayMode?: string;
75
+ IsolatedTime?: string;
76
+ ExpireTime?: string;
77
+ CreateTime?: string;
78
+ UpdateTime?: string;
79
+ FreeQuota?: string;
80
+ PaymentChannel?: string;
81
+ ExtPackageType?: string;
82
+ OrderInfo?: OrderInfo;
83
+ IsAlwaysFree?: boolean;
84
+ EnableOverrun?: boolean;
85
+ }
1
86
  export interface Credential {
2
87
  secretId: string;
3
88
  secretKey: string;
@@ -9,6 +94,12 @@ export interface Credential {
9
94
  uin?: string;
10
95
  hash?: string;
11
96
  envId?: string;
97
+ /** 该用户可用的环境 ID 列表(有序,与 envList 顺序一致) */
98
+ envIds?: string[];
99
+ /** 环境批量详情,结构同 DescribeEnvs 接口返回的 EnvList */
100
+ envList?: EnvInfo[];
101
+ /** 环境计费信息列表,结构同 DescribeBillingInfo 接口返回的 EnvBillingInfoList */
102
+ envBillingInfoList?: EnvBillingInfoItem[];
12
103
  }
13
104
  export interface WebAuthCredential {
14
105
  tmpSecretId: string;
@@ -21,6 +112,12 @@ export interface WebAuthCredential {
21
112
  uin?: string;
22
113
  hash?: string;
23
114
  envId?: string;
115
+ /** 该用户可用的环境 ID 列表(有序,与 envList 顺序一致) */
116
+ envIds?: string[];
117
+ /** 环境批量详情,结构同 DescribeEnvs 接口返回的 EnvList */
118
+ envList?: EnvInfo[];
119
+ /** 环境计费信息列表,结构同 DescribeBillingInfo 接口返回的 EnvBillingInfoList */
120
+ envBillingInfoList?: EnvBillingInfoItem[];
24
121
  }
25
122
  export interface RequestConfig {
26
123
  proxy?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/toolbox",
3
- "version": "0.7.19",
3
+ "version": "0.7.21-beta.0",
4
4
  "description": "The toolbox for cloudbase",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {