@cloudbase/toolbox 0.7.20 → 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.
- package/lib/auth/common.d.ts +6 -0
- package/lib/auth/common.js +14 -5
- package/lib/auth/credential.js +53 -1
- package/lib/auth/oauth.js +20 -5
- package/lib/types.d.ts +97 -0
- package/package.json +1 -1
package/lib/auth/common.d.ts
CHANGED
|
@@ -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;
|
package/lib/auth/common.js
CHANGED
|
@@ -9,9 +9,12 @@ 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
|
+
const localstore_1 = require("../localstore");
|
|
16
|
+
exports.DEFAULT_CLIENT_ID = 'cloudbase-cli';
|
|
17
|
+
exports.configStore = new localstore_1.LocalStore({}, 'config');
|
|
15
18
|
// 调用 CheckTcbService 接口,检查密钥是否有效
|
|
16
19
|
// 相比 DescribeEnvs,该接口不会返回环境列表,仅验证登录态,性能更好
|
|
17
20
|
function checkAuth(credential, options = {}) {
|
|
@@ -39,7 +42,7 @@ function checkAuth(credential, options = {}) {
|
|
|
39
42
|
exports.checkAuth = checkAuth;
|
|
40
43
|
// 兼容解析旧的登录态
|
|
41
44
|
function resolveCredential(data) {
|
|
42
|
-
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;
|
|
43
46
|
// 兼容旧的登录态信息
|
|
44
47
|
token = token || tmpToken;
|
|
45
48
|
secretId = secretId || tmpSecretId;
|
|
@@ -55,12 +58,15 @@ function resolveCredential(data) {
|
|
|
55
58
|
refreshToken,
|
|
56
59
|
uin,
|
|
57
60
|
hash,
|
|
58
|
-
envId
|
|
61
|
+
envId,
|
|
62
|
+
envIds,
|
|
63
|
+
envList,
|
|
64
|
+
envBillingInfoList
|
|
59
65
|
};
|
|
60
66
|
}
|
|
61
67
|
exports.resolveCredential = resolveCredential;
|
|
62
68
|
function resolveWebCredential(credential) {
|
|
63
|
-
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;
|
|
64
70
|
const webCredential = {
|
|
65
71
|
tmpSecretId: secretId,
|
|
66
72
|
tmpSecretKey: secretKey,
|
|
@@ -71,7 +77,10 @@ function resolveWebCredential(credential) {
|
|
|
71
77
|
refreshToken,
|
|
72
78
|
uin,
|
|
73
79
|
hash,
|
|
74
|
-
envId
|
|
80
|
+
envId,
|
|
81
|
+
envIds,
|
|
82
|
+
envList,
|
|
83
|
+
envBillingInfoList
|
|
75
84
|
};
|
|
76
85
|
return webCredential;
|
|
77
86
|
}
|
package/lib/auth/credential.js
CHANGED
|
@@ -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(
|
|
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
|
|
21
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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;
|