@cloudbase/node-sdk 3.17.0 → 3.17.1-alpha.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/auth/index.js +4 -0
- package/dist/cloudbase.js +9 -36
- package/dist/utils/tcbapirequester.js +11 -3
- package/dist/utils/tcbcontext.js +1 -0
- package/dist/utils/tcbopenapicommonrequester.js +25 -7
- package/dist/utils/tcbopenapirequester.js +26 -5
- package/dist/utils/utils.js +73 -1
- package/package.json +1 -1
- package/src/auth/index.ts +5 -1
- package/src/cloudbase.ts +9 -38
- package/src/utils/tcbapirequester.ts +11 -4
- package/src/utils/tcbcontext.ts +1 -0
- package/src/utils/tcbdbapirequester.ts +0 -1
- package/src/utils/tcbopenapicommonrequester.ts +22 -8
- package/src/utils/tcbopenapirequester.ts +24 -6
- package/src/utils/utils.ts +62 -0
- package/types/index.d.ts +1 -0
package/dist/auth/index.js
CHANGED
|
@@ -135,6 +135,10 @@ class Auth {
|
|
|
135
135
|
});
|
|
136
136
|
}
|
|
137
137
|
async getClientCredential(opts) {
|
|
138
|
+
// 如果有 accessKey 直接返回 accessKey,不用再去换取 token
|
|
139
|
+
if (this.cloudbase.config.accessKey) {
|
|
140
|
+
return this.cloudbase.config.accessKey;
|
|
141
|
+
}
|
|
138
142
|
return await tcbopenapicommonrequester.request({
|
|
139
143
|
config: this.cloudbase.config,
|
|
140
144
|
method: 'POST',
|
package/dist/cloudbase.js
CHANGED
|
@@ -22,17 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
26
|
-
var t = {};
|
|
27
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
28
|
-
t[p] = s[p];
|
|
29
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
30
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
31
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
32
|
-
t[p[i]] = s[p[i]];
|
|
33
|
-
}
|
|
34
|
-
return t;
|
|
35
|
-
};
|
|
36
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
27
|
};
|
|
@@ -49,14 +38,13 @@ const wx_1 = require("./wx");
|
|
|
49
38
|
const analytics_1 = require("./analytics");
|
|
50
39
|
const ai_1 = require("./ai");
|
|
51
40
|
const logger_1 = require("./logger");
|
|
52
|
-
const code_1 = require("./const/code");
|
|
53
|
-
const utils = __importStar(require("./utils/utils"));
|
|
54
41
|
const cloudplatform_1 = require("./utils/cloudplatform");
|
|
55
42
|
const tcbcontext_1 = require("./utils/tcbcontext");
|
|
56
43
|
const notification_1 = require("./notification");
|
|
57
44
|
const openapicommonrequester = __importStar(require("./utils/tcbopenapicommonrequester"));
|
|
58
45
|
const tcbopenapiendpoint_1 = require("./utils/tcbopenapiendpoint");
|
|
59
46
|
const symbol_1 = require("./const/symbol");
|
|
47
|
+
const utils_1 = require("./utils/utils");
|
|
60
48
|
class CloudBase {
|
|
61
49
|
static parseContext(context) {
|
|
62
50
|
const parseResult = (0, tcbcontext_1.parseContext)(context);
|
|
@@ -70,33 +58,14 @@ class CloudBase {
|
|
|
70
58
|
this.init(config);
|
|
71
59
|
}
|
|
72
60
|
init(config = {}) {
|
|
73
|
-
var _a, _b, _c, _d;
|
|
74
61
|
// 预检运行环境,调用与否并不影响后续逻辑
|
|
75
62
|
// 注意:该函数为异步函数,这里并不等待检查结果
|
|
76
63
|
/* eslint-disable-next-line */
|
|
77
64
|
(0, cloudplatform_1.preflightRuntimeCloudPlatform)();
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const newConfig = Object.assign(Object.assign({}, restConfig), { debug: !!debug, secretId,
|
|
83
|
-
secretKey,
|
|
84
|
-
sessionToken,
|
|
85
|
-
env, envName: env, headers: Object.assign({}, headers), timeout: timeout || 15000 });
|
|
86
|
-
if ((_a = config.context) === null || _a === void 0 ? void 0 : _a.extendedContext) {
|
|
87
|
-
const extendedContext = config.context.extendedContext;
|
|
88
|
-
if (!newConfig.env) {
|
|
89
|
-
newConfig.env = extendedContext.envId;
|
|
90
|
-
newConfig.envName = newConfig.env;
|
|
91
|
-
}
|
|
92
|
-
// 从 context 中获取 secret
|
|
93
|
-
if (!newConfig.secretId && !newConfig.secretKey) {
|
|
94
|
-
newConfig.secretId = (_b = extendedContext === null || extendedContext === void 0 ? void 0 : extendedContext.tmpSecret) === null || _b === void 0 ? void 0 : _b.secretId;
|
|
95
|
-
newConfig.secretKey = (_c = extendedContext === null || extendedContext === void 0 ? void 0 : extendedContext.tmpSecret) === null || _c === void 0 ? void 0 : _c.secretKey;
|
|
96
|
-
newConfig.sessionToken = (_d = extendedContext === null || extendedContext === void 0 ? void 0 : extendedContext.tmpSecret) === null || _d === void 0 ? void 0 : _d.token;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
this.config = newConfig;
|
|
65
|
+
// 所有的鉴权,参数塑形都在 normalizeConfig 中处理
|
|
66
|
+
// 后续其他模块获取 config 都通过 CloudBase 实例的 config 获取
|
|
67
|
+
// 禁止在业务模块中直接修改 config 配置
|
|
68
|
+
this.config = (0, utils_1.normalizeConfig)(config);
|
|
100
69
|
this.extensionMap = new Map();
|
|
101
70
|
// NOTE:try-catch 为防止 init 报错
|
|
102
71
|
try {
|
|
@@ -112,6 +81,10 @@ class CloudBase {
|
|
|
112
81
|
method: (_a = options.method) === null || _a === void 0 ? void 0 : _a.toUpperCase(),
|
|
113
82
|
url: options.url,
|
|
114
83
|
headers: Object.assign({ 'Content-Type': 'application/json' }, headersInitToRecord(options.headers)),
|
|
84
|
+
/**
|
|
85
|
+
* 既然 openapicommonrequester.request 的参数里的 token 获取也是通过 openapicommonrequester.request 方法去获取的
|
|
86
|
+
* 为什么不把这里的 token 去掉,全部放在 openapicommonrequester.request 中去统一处理 token 获取的逻辑
|
|
87
|
+
*/
|
|
115
88
|
token: (await this.auth().getClientCredential()).access_token
|
|
116
89
|
});
|
|
117
90
|
return result.body;
|
|
@@ -127,9 +127,15 @@ class TcbApiHttpRequester {
|
|
|
127
127
|
this.tracingInfo = (0, tracing_1.generateTracingInfo)((_b = (_a = args.config) === null || _a === void 0 ? void 0 : _a.context) === null || _b === void 0 ? void 0 : _b.eventID);
|
|
128
128
|
}
|
|
129
129
|
async request() {
|
|
130
|
-
|
|
130
|
+
// 如果没有配置 accessKey,则通过密钥获取签名,这里先检查密钥是否存在
|
|
131
|
+
if (!this.config.accessKey) {
|
|
132
|
+
// 检查密钥是否存在
|
|
133
|
+
await this.prepareCredentials();
|
|
134
|
+
}
|
|
131
135
|
const params = await this.makeParams();
|
|
136
|
+
// console.log('params', params)
|
|
132
137
|
const opts = this.makeReqOpts(params);
|
|
138
|
+
// console.log('opts', opts)
|
|
133
139
|
const action = this.getAction();
|
|
134
140
|
const key = {
|
|
135
141
|
functions: 'function_name',
|
|
@@ -277,7 +283,7 @@ class TcbApiHttpRequester {
|
|
|
277
283
|
getHeaders(method, url, params) {
|
|
278
284
|
var _a;
|
|
279
285
|
const config = this.config;
|
|
280
|
-
const { context, secretId, secretKey } = config;
|
|
286
|
+
const { context, secretId, secretKey, accessKey } = config;
|
|
281
287
|
const args = this.args;
|
|
282
288
|
const { TCB_SOURCE } = cloudbase_1.CloudBase.getCloudbaseContext();
|
|
283
289
|
// Note: 云函数被调用时可能调用端未传递 SOURCE,TCB_SOURCE 可能为空
|
|
@@ -317,7 +323,8 @@ class TcbApiHttpRequester {
|
|
|
317
323
|
timestamp: second() - 1
|
|
318
324
|
});
|
|
319
325
|
/* eslint-disable @typescript-eslint/dot-notation */
|
|
320
|
-
|
|
326
|
+
// 优先使用 accessKey,否则使用签名
|
|
327
|
+
requiredHeaders['Authorization'] = accessKey ? `Bearer ${accessKey}` : authorization;
|
|
321
328
|
requiredHeaders['X-Signature-Expires'] = 600;
|
|
322
329
|
requiredHeaders['X-Timestamp'] = timestamp;
|
|
323
330
|
return Object.assign({}, requiredHeaders);
|
|
@@ -334,6 +341,7 @@ const handleWxOpenApiData = (res, err, response, body) => {
|
|
|
334
341
|
return transformRes;
|
|
335
342
|
};
|
|
336
343
|
async function request(args) {
|
|
344
|
+
// console.log('args', args)
|
|
337
345
|
if (typeof args.isInternal === 'undefined') {
|
|
338
346
|
args.isInternal = await (0, cloudplatform_1.checkIsInternalAsync)();
|
|
339
347
|
}
|
package/dist/utils/tcbcontext.js
CHANGED
|
@@ -60,6 +60,7 @@ exports.parseContext = parseContext;
|
|
|
60
60
|
* 获取当前函数内的所有环境变量(作为获取变量的统一方法,取值来源 process.env 和 context)
|
|
61
61
|
*/
|
|
62
62
|
function getCloudbaseContext(context) {
|
|
63
|
+
// console.log('context', context)
|
|
63
64
|
if ((0, cloudplatform_1.checkIsInScf)()) {
|
|
64
65
|
// 云函数环境下,应该包含以下环境变量,如果没有,后续逻辑可能会有问题
|
|
65
66
|
if (!process.env.TENCENTCLOUD_REGION) {
|
|
@@ -56,8 +56,13 @@ class TcbOpenApiHttpCommonRequester {
|
|
|
56
56
|
this.tracingInfo = (0, tracing_1.generateTracingInfo)((_b = (_a = args.config) === null || _a === void 0 ? void 0 : _a.context) === null || _b === void 0 ? void 0 : _b.eventID);
|
|
57
57
|
}
|
|
58
58
|
async request() {
|
|
59
|
-
|
|
59
|
+
// 如果没有 accessKey,去检查密钥是否存在,有则直接使用
|
|
60
|
+
if (!this.config.accessKey) {
|
|
61
|
+
// 检查密钥是否存在
|
|
62
|
+
await this.prepareCredentials();
|
|
63
|
+
}
|
|
60
64
|
const opts = this.makeReqOpts();
|
|
65
|
+
// console.log('opts', opts)
|
|
61
66
|
const argopts = this.opts;
|
|
62
67
|
const config = this.config;
|
|
63
68
|
// 注意:必须初始化为 null
|
|
@@ -140,7 +145,7 @@ class TcbOpenApiHttpCommonRequester {
|
|
|
140
145
|
buildHeaders(method, url) {
|
|
141
146
|
var _a;
|
|
142
147
|
const config = this.config;
|
|
143
|
-
const { context, secretId, secretKey, sessionToken } = config;
|
|
148
|
+
const { context, secretId, secretKey, sessionToken, accessKey } = config;
|
|
144
149
|
const args = this.args;
|
|
145
150
|
const { TCB_SOURCE } = cloudbase_1.CloudBase.getCloudbaseContext();
|
|
146
151
|
// Note: 云函数被调用时可能调用端未传递 SOURCE,TCB_SOURCE 可能为空
|
|
@@ -181,12 +186,25 @@ class TcbOpenApiHttpCommonRequester {
|
|
|
181
186
|
withSignedParams: false,
|
|
182
187
|
isCloudApi: true
|
|
183
188
|
});
|
|
189
|
+
// console.log('xxxx', authorization)
|
|
190
|
+
let token = '';
|
|
191
|
+
// 如果请求参数里面传了 token,优先使用 token
|
|
192
|
+
if (args.token) {
|
|
193
|
+
token = makeBearerToken(args.token);
|
|
194
|
+
}
|
|
195
|
+
else if (accessKey) {
|
|
196
|
+
// 如果配置了 API_KEY,优先使用 API_KEY
|
|
197
|
+
token = makeBearerToken(accessKey);
|
|
198
|
+
}
|
|
199
|
+
else if (typeof sessionToken === 'string' && sessionToken !== '') {
|
|
200
|
+
// 如果配置了 sessionToken,携带 sessionToken
|
|
201
|
+
token = `${authorization}, Timestamp=${timestamp}, Token=${sessionToken}`;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
token = `${authorization}, Timestamp=${timestamp}`;
|
|
205
|
+
}
|
|
184
206
|
/* eslint-disable @typescript-eslint/dot-notation */
|
|
185
|
-
requiredHeaders['Authorization'] =
|
|
186
|
-
? makeBearerToken(args.token)
|
|
187
|
-
: typeof sessionToken === 'string' && sessionToken !== ''
|
|
188
|
-
? `${authorization}, Timestamp=${timestamp}, Token=${sessionToken}`
|
|
189
|
-
: `${authorization}, Timestamp=${timestamp}`;
|
|
207
|
+
requiredHeaders['Authorization'] = token;
|
|
190
208
|
return Object.assign({}, requiredHeaders);
|
|
191
209
|
}
|
|
192
210
|
}
|
|
@@ -56,8 +56,11 @@ class TcbOpenApiHttpRequester {
|
|
|
56
56
|
this.tracingInfo = (0, tracing_1.generateTracingInfo)((_b = (_a = args.config) === null || _a === void 0 ? void 0 : _a.context) === null || _b === void 0 ? void 0 : _b.eventID);
|
|
57
57
|
}
|
|
58
58
|
async request() {
|
|
59
|
-
|
|
59
|
+
if (!this.config.accessKey) {
|
|
60
|
+
await this.prepareCredentials();
|
|
61
|
+
}
|
|
60
62
|
const opts = this.makeReqOpts();
|
|
63
|
+
// console.log('opts', opts)
|
|
61
64
|
const argopts = this.opts;
|
|
62
65
|
const config = this.config;
|
|
63
66
|
// 注意:必须初始化为 null
|
|
@@ -140,7 +143,7 @@ class TcbOpenApiHttpRequester {
|
|
|
140
143
|
buildHeaders(method, url) {
|
|
141
144
|
var _a;
|
|
142
145
|
const config = this.config;
|
|
143
|
-
const { context, secretId, secretKey, sessionToken } = config;
|
|
146
|
+
const { context, secretId, secretKey, sessionToken, accessKey } = config;
|
|
144
147
|
const args = this.args;
|
|
145
148
|
const { TCB_SOURCE } = cloudbase_1.CloudBase.getCloudbaseContext();
|
|
146
149
|
// Note: 云函数被调用时可能调用端未传递 SOURCE,TCB_SOURCE 可能为空
|
|
@@ -186,10 +189,24 @@ class TcbOpenApiHttpRequester {
|
|
|
186
189
|
withSignedParams: false,
|
|
187
190
|
isCloudApi: true
|
|
188
191
|
});
|
|
192
|
+
let token = '';
|
|
193
|
+
// 如果请求参数里面传了 token,优先使用 token
|
|
194
|
+
if (args.token) {
|
|
195
|
+
token = makeBearerToken(args.token);
|
|
196
|
+
}
|
|
197
|
+
else if (accessKey) {
|
|
198
|
+
// 如果配置了 API_KEY,优先使用 API_KEY
|
|
199
|
+
token = makeBearerToken(accessKey);
|
|
200
|
+
}
|
|
201
|
+
else if (typeof sessionToken === 'string' && sessionToken !== '') {
|
|
202
|
+
// 如果配置了 sessionToken,使用 sessionToken
|
|
203
|
+
token = `${authorization}, Timestamp=${timestamp}, Token=${sessionToken}`;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
token = `${authorization}, Timestamp=${timestamp}`;
|
|
207
|
+
}
|
|
189
208
|
/* eslint-disable @typescript-eslint/dot-notation */
|
|
190
|
-
requiredHeaders['Authorization'] =
|
|
191
|
-
? `${authorization}, Timestamp=${timestamp}, Token=${sessionToken}`
|
|
192
|
-
: `${authorization}, Timestamp=${timestamp}`;
|
|
209
|
+
requiredHeaders['Authorization'] = token;
|
|
193
210
|
return Object.assign({}, requiredHeaders);
|
|
194
211
|
}
|
|
195
212
|
}
|
|
@@ -204,3 +221,7 @@ async function request(args) {
|
|
|
204
221
|
return await requester.request();
|
|
205
222
|
}
|
|
206
223
|
exports.request = request;
|
|
224
|
+
function makeBearerToken(token) {
|
|
225
|
+
const trimmed = token.trim();
|
|
226
|
+
return trimmed.startsWith('Bearer ') ? trimmed : `Bearer ${trimmed}`;
|
|
227
|
+
}
|
package/dist/utils/utils.js
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isValidEnvFormat = exports.isPageModuleName = exports.processReturn = exports.setThrowOnCode = exports.second = exports.isNonEmptyString = exports.E = exports.filterUndefined = exports.filterValue = exports.isAppId = exports.TcbError = void 0;
|
|
26
|
+
exports.normalizeConfig = exports.isValidEnvFormat = exports.isPageModuleName = exports.processReturn = exports.setThrowOnCode = exports.second = exports.isNonEmptyString = exports.E = exports.filterUndefined = exports.filterValue = exports.isAppId = exports.TcbError = void 0;
|
|
27
|
+
const utils = __importStar(require("../utils/utils"));
|
|
28
|
+
const code_1 = require("../const/code");
|
|
4
29
|
class TcbError extends Error {
|
|
5
30
|
constructor(error) {
|
|
6
31
|
super(error.message);
|
|
@@ -72,3 +97,50 @@ function isValidEnvFormat(env = '') {
|
|
|
72
97
|
return typeof env === 'string' && kEnvRuleReg.test(env);
|
|
73
98
|
}
|
|
74
99
|
exports.isValidEnvFormat = isValidEnvFormat;
|
|
100
|
+
function normalizeConfig(config) {
|
|
101
|
+
var _a, _b, _c, _d;
|
|
102
|
+
const { debug = false, secretId, secretKey, env, timeout = 15000, headers = {}, accessKey } = config;
|
|
103
|
+
// 检查用户显示配置的 secretId 和 secretKey 是否成对出现,要么都有,要么都没有
|
|
104
|
+
if (!secretId !== !secretKey) {
|
|
105
|
+
throw utils.E(Object.assign(Object.assign({}, code_1.ERROR.INVALID_PARAM), { message: 'secretId and secretKey must be a pair' }));
|
|
106
|
+
}
|
|
107
|
+
const cloudbaseConfigBase = Object.assign(Object.assign({}, config), { debug,
|
|
108
|
+
// secretId,
|
|
109
|
+
// secretKey,
|
|
110
|
+
envName: env, headers: Object.assign({}, headers), // 结构用户传进来的 headers,防止用户修改原对象
|
|
111
|
+
timeout
|
|
112
|
+
// accessKey: accessKey || process.env.CLOUDBASE_APIKEY
|
|
113
|
+
});
|
|
114
|
+
const { TENCENTCLOUD_SECRETID, TENCENTCLOUD_SECRETKEY, TENCENTCLOUD_SESSIONTOKEN, CLOUDBASE_APIKEY } = process.env;
|
|
115
|
+
// 如果用户显示配置了accessKey,取用户显示配置的 accessKey,优先级最高
|
|
116
|
+
if (accessKey) {
|
|
117
|
+
return Object.assign(cloudbaseConfigBase, { secretId: undefined, secretKey: undefined, accessKey });
|
|
118
|
+
}
|
|
119
|
+
// 显示配置了 secretId, secretKey,取 secretId, secretKey
|
|
120
|
+
if (secretId && secretKey) {
|
|
121
|
+
return Object.assign(cloudbaseConfigBase, { secretId, secretKey, accessKey: undefined });
|
|
122
|
+
}
|
|
123
|
+
// 下面从环境变量取 secretId, secretKey, accessKey
|
|
124
|
+
if (CLOUDBASE_APIKEY) {
|
|
125
|
+
return Object.assign(cloudbaseConfigBase, { secretId: undefined, secretKey: undefined, accessKey: CLOUDBASE_APIKEY });
|
|
126
|
+
}
|
|
127
|
+
if (TENCENTCLOUD_SECRETID && TENCENTCLOUD_SECRETKEY) {
|
|
128
|
+
return Object.assign(cloudbaseConfigBase, { secretId: TENCENTCLOUD_SECRETID, secretKey: TENCENTCLOUD_SECRETKEY, sessionToken: TENCENTCLOUD_SESSIONTOKEN, accessKey: undefined });
|
|
129
|
+
}
|
|
130
|
+
if ((_a = config.context) === null || _a === void 0 ? void 0 : _a.extendedContext) {
|
|
131
|
+
const extendedContext = config.context.extendedContext;
|
|
132
|
+
if (!cloudbaseConfigBase.env) {
|
|
133
|
+
cloudbaseConfigBase.env = extendedContext.envId;
|
|
134
|
+
cloudbaseConfigBase.envName = extendedContext.envId;
|
|
135
|
+
}
|
|
136
|
+
// 从 context 中获取 secret
|
|
137
|
+
if (!cloudbaseConfigBase.secretId && !cloudbaseConfigBase.secretKey) {
|
|
138
|
+
cloudbaseConfigBase.secretId = (_b = extendedContext === null || extendedContext === void 0 ? void 0 : extendedContext.tmpSecret) === null || _b === void 0 ? void 0 : _b.secretId;
|
|
139
|
+
cloudbaseConfigBase.secretKey = (_c = extendedContext === null || extendedContext === void 0 ? void 0 : extendedContext.tmpSecret) === null || _c === void 0 ? void 0 : _c.secretKey;
|
|
140
|
+
cloudbaseConfigBase.sessionToken = (_d = extendedContext === null || extendedContext === void 0 ? void 0 : extendedContext.tmpSecret) === null || _d === void 0 ? void 0 : _d.token;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// 都没有配置,返回原始的配置
|
|
144
|
+
return cloudbaseConfigBase;
|
|
145
|
+
}
|
|
146
|
+
exports.normalizeConfig = normalizeConfig;
|
package/package.json
CHANGED
package/src/auth/index.ts
CHANGED
|
@@ -147,6 +147,10 @@ export class Auth {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
public async getClientCredential(opts?: ICustomReqOpts): Promise<any> {
|
|
150
|
+
// 如果有 accessKey 直接返回 accessKey,不用再去换取 token
|
|
151
|
+
if (this.cloudbase.config.accessKey) {
|
|
152
|
+
return this.cloudbase.config.accessKey
|
|
153
|
+
}
|
|
150
154
|
return await tcbopenapicommonrequester.request({
|
|
151
155
|
config: this.cloudbase.config,
|
|
152
156
|
method: 'POST',
|
|
@@ -183,7 +187,7 @@ export class Auth {
|
|
|
183
187
|
throw E({
|
|
184
188
|
...ERROR.INVALID_PARAM,
|
|
185
189
|
message:
|
|
186
|
-
|
|
190
|
+
'当前私钥未包含env_id 信息, 请前往腾讯云云开发控制台,获取自定义登录最新私钥'
|
|
187
191
|
})
|
|
188
192
|
}
|
|
189
193
|
|
package/src/cloudbase.ts
CHANGED
|
@@ -63,7 +63,7 @@ import { IFetchOptions } from '@cloudbase/adapter-interface'
|
|
|
63
63
|
import { buildCommonOpenApiUrlWithPath } from './utils/tcbopenapiendpoint'
|
|
64
64
|
import { SYMBOL_CURRENT_ENV } from './const/symbol'
|
|
65
65
|
import { IncomingHttpHeaders } from 'http'
|
|
66
|
-
|
|
66
|
+
import { normalizeConfig } from './utils/utils'
|
|
67
67
|
export class CloudBase {
|
|
68
68
|
public static scfContext: ISCFContext
|
|
69
69
|
|
|
@@ -100,43 +100,10 @@ export class CloudBase {
|
|
|
100
100
|
/* eslint-disable-next-line */
|
|
101
101
|
preflightRuntimeCloudPlatform()
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
...ERROR.INVALID_PARAM,
|
|
108
|
-
message: 'secretId and secretKey must be a pair'
|
|
109
|
-
})
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const newConfig: ICloudBaseConfig = {
|
|
113
|
-
...restConfig,
|
|
114
|
-
debug: !!debug,
|
|
115
|
-
secretId,
|
|
116
|
-
secretKey,
|
|
117
|
-
sessionToken,
|
|
118
|
-
env,
|
|
119
|
-
envName: env,
|
|
120
|
-
headers: { ...headers },
|
|
121
|
-
timeout: timeout || 15000
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (config.context?.extendedContext) {
|
|
125
|
-
const extendedContext = config.context.extendedContext
|
|
126
|
-
if (!newConfig.env) {
|
|
127
|
-
newConfig.env = extendedContext.envId
|
|
128
|
-
newConfig.envName = newConfig.env
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// 从 context 中获取 secret
|
|
132
|
-
if (!newConfig.secretId && !newConfig.secretKey) {
|
|
133
|
-
newConfig.secretId = extendedContext?.tmpSecret?.secretId
|
|
134
|
-
newConfig.secretKey = extendedContext?.tmpSecret?.secretKey
|
|
135
|
-
newConfig.sessionToken = extendedContext?.tmpSecret?.token
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
this.config = newConfig
|
|
103
|
+
// 所有的鉴权,参数塑形都在 normalizeConfig 中处理
|
|
104
|
+
// 后续其他模块获取 config 都通过 CloudBase 实例的 config 获取
|
|
105
|
+
// 禁止在业务模块中直接修改 config 配置
|
|
106
|
+
this.config = normalizeConfig(config)
|
|
140
107
|
this.extensionMap = new Map()
|
|
141
108
|
|
|
142
109
|
// NOTE:try-catch 为防止 init 报错
|
|
@@ -155,6 +122,10 @@ export class CloudBase {
|
|
|
155
122
|
'Content-Type': 'application/json',
|
|
156
123
|
...headersInitToRecord(options.headers)
|
|
157
124
|
},
|
|
125
|
+
/**
|
|
126
|
+
* 既然 openapicommonrequester.request 的参数里的 token 获取也是通过 openapicommonrequester.request 方法去获取的
|
|
127
|
+
* 为什么不把这里的 token 去掉,全部放在 openapicommonrequester.request 中去统一处理 token 获取的逻辑
|
|
128
|
+
*/
|
|
158
129
|
token: (await this.auth().getClientCredential()).access_token
|
|
159
130
|
})
|
|
160
131
|
return result.body
|
|
@@ -147,10 +147,15 @@ export class TcbApiHttpRequester {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
public async request(): Promise<any> {
|
|
150
|
-
|
|
150
|
+
// 如果没有配置 accessKey,则通过密钥获取签名,这里先检查密钥是否存在
|
|
151
|
+
if (!this.config.accessKey) {
|
|
152
|
+
// 检查密钥是否存在
|
|
153
|
+
await this.prepareCredentials()
|
|
154
|
+
}
|
|
151
155
|
const params = await this.makeParams()
|
|
152
|
-
|
|
156
|
+
// console.log('params', params)
|
|
153
157
|
const opts = this.makeReqOpts(params)
|
|
158
|
+
// console.log('opts', opts)
|
|
154
159
|
const action = this.getAction()
|
|
155
160
|
const key = {
|
|
156
161
|
functions: 'function_name',
|
|
@@ -320,7 +325,7 @@ export class TcbApiHttpRequester {
|
|
|
320
325
|
|
|
321
326
|
private getHeaders(method: string, url: string, params: any): any {
|
|
322
327
|
const config = this.config
|
|
323
|
-
const { context, secretId, secretKey } = config
|
|
328
|
+
const { context, secretId, secretKey, accessKey } = config
|
|
324
329
|
const args = this.args
|
|
325
330
|
|
|
326
331
|
const { TCB_SOURCE } = CloudBase.getCloudbaseContext()
|
|
@@ -370,7 +375,8 @@ export class TcbApiHttpRequester {
|
|
|
370
375
|
})
|
|
371
376
|
|
|
372
377
|
/* eslint-disable @typescript-eslint/dot-notation */
|
|
373
|
-
|
|
378
|
+
// 优先使用 accessKey,否则使用签名
|
|
379
|
+
requiredHeaders['Authorization'] = accessKey ? `Bearer ${accessKey}` : authorization
|
|
374
380
|
requiredHeaders['X-Signature-Expires'] = 600
|
|
375
381
|
requiredHeaders['X-Timestamp'] = timestamp
|
|
376
382
|
|
|
@@ -389,6 +395,7 @@ const handleWxOpenApiData = (res: any, err: any, response: any, body: any): any
|
|
|
389
395
|
}
|
|
390
396
|
|
|
391
397
|
export async function request(args: IRequestInfo): Promise<any> {
|
|
398
|
+
// console.log('args', args)
|
|
392
399
|
if (typeof args.isInternal === 'undefined') {
|
|
393
400
|
args.isInternal = await checkIsInternalAsync()
|
|
394
401
|
}
|
package/src/utils/tcbcontext.ts
CHANGED
|
@@ -76,6 +76,7 @@ export function parseContext(context: IContextParam): ISCFContext {
|
|
|
76
76
|
* 获取当前函数内的所有环境变量(作为获取变量的统一方法,取值来源 process.env 和 context)
|
|
77
77
|
*/
|
|
78
78
|
export function getCloudbaseContext(context?: IContextParam): ICompleteCloudbaseContext {
|
|
79
|
+
// console.log('context', context)
|
|
79
80
|
if (checkIsInScf()) {
|
|
80
81
|
// 云函数环境下,应该包含以下环境变量,如果没有,后续逻辑可能会有问题
|
|
81
82
|
if (!process.env.TENCENTCLOUD_REGION) {
|
|
@@ -17,7 +17,6 @@ export class TcbDBApiHttpRequester {
|
|
|
17
17
|
public async send(api: string, data: any, opts?: ICustomReqOpts): Promise<any> {
|
|
18
18
|
const { instance, database, ...config } = this.config
|
|
19
19
|
const params = { ...data, action: api, instance, database }
|
|
20
|
-
|
|
21
20
|
return await tcbapicaller.request({
|
|
22
21
|
config,
|
|
23
22
|
params,
|
|
@@ -54,9 +54,14 @@ export class TcbOpenApiHttpCommonRequester {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
public async request() {
|
|
57
|
-
|
|
57
|
+
// 如果没有 accessKey,去检查密钥是否存在,有则直接使用
|
|
58
|
+
if (!this.config.accessKey) {
|
|
59
|
+
// 检查密钥是否存在
|
|
60
|
+
await this.prepareCredentials()
|
|
61
|
+
}
|
|
58
62
|
|
|
59
63
|
const opts = this.makeReqOpts()
|
|
64
|
+
// console.log('opts', opts)
|
|
60
65
|
|
|
61
66
|
const argopts: any = this.opts
|
|
62
67
|
const config = this.config
|
|
@@ -144,7 +149,7 @@ export class TcbOpenApiHttpCommonRequester {
|
|
|
144
149
|
|
|
145
150
|
private buildHeaders(method: string, url: string): any {
|
|
146
151
|
const config = this.config
|
|
147
|
-
const { context, secretId, secretKey, sessionToken } = config
|
|
152
|
+
const { context, secretId, secretKey, sessionToken, accessKey } = config
|
|
148
153
|
const args = this.args
|
|
149
154
|
|
|
150
155
|
const { TCB_SOURCE } = CloudBase.getCloudbaseContext()
|
|
@@ -194,13 +199,22 @@ export class TcbOpenApiHttpCommonRequester {
|
|
|
194
199
|
withSignedParams: false,
|
|
195
200
|
isCloudApi: true
|
|
196
201
|
})
|
|
197
|
-
|
|
202
|
+
// console.log('xxxx', authorization)
|
|
203
|
+
let token = ''
|
|
204
|
+
// 如果请求参数里面传了 token,优先使用 token
|
|
205
|
+
if (args.token) {
|
|
206
|
+
token = makeBearerToken(args.token)
|
|
207
|
+
} else if (accessKey) {
|
|
208
|
+
// 如果配置了 API_KEY,优先使用 API_KEY
|
|
209
|
+
token = makeBearerToken(accessKey)
|
|
210
|
+
} else if (typeof sessionToken === 'string' && sessionToken !== '') {
|
|
211
|
+
// 如果配置了 sessionToken,携带 sessionToken
|
|
212
|
+
token = `${authorization}, Timestamp=${timestamp}, Token=${sessionToken}`
|
|
213
|
+
} else {
|
|
214
|
+
token = `${authorization}, Timestamp=${timestamp}`
|
|
215
|
+
}
|
|
198
216
|
/* eslint-disable @typescript-eslint/dot-notation */
|
|
199
|
-
requiredHeaders['Authorization'] =
|
|
200
|
-
? makeBearerToken(args.token)
|
|
201
|
-
: typeof sessionToken === 'string' && sessionToken !== ''
|
|
202
|
-
? `${authorization}, Timestamp=${timestamp}, Token=${sessionToken}`
|
|
203
|
-
: `${authorization}, Timestamp=${timestamp}`
|
|
217
|
+
requiredHeaders['Authorization'] = token
|
|
204
218
|
|
|
205
219
|
return { ...requiredHeaders }
|
|
206
220
|
}
|
|
@@ -30,6 +30,7 @@ export function getEnvIdFromContext(): string {
|
|
|
30
30
|
type ICallContainerRequestInfo = Omit<IRequestInfo, 'params'> & {
|
|
31
31
|
path: string
|
|
32
32
|
data: any
|
|
33
|
+
token?: string
|
|
33
34
|
cloudrun: {
|
|
34
35
|
name: string
|
|
35
36
|
// version: string
|
|
@@ -56,9 +57,12 @@ export class TcbOpenApiHttpRequester {
|
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
public async request(): Promise<any> {
|
|
59
|
-
|
|
60
|
+
if (!this.config.accessKey) {
|
|
61
|
+
await this.prepareCredentials()
|
|
62
|
+
}
|
|
60
63
|
|
|
61
64
|
const opts = this.makeReqOpts()
|
|
65
|
+
// console.log('opts', opts)
|
|
62
66
|
|
|
63
67
|
const argopts: any = this.opts
|
|
64
68
|
const config = this.config
|
|
@@ -147,7 +151,7 @@ export class TcbOpenApiHttpRequester {
|
|
|
147
151
|
|
|
148
152
|
private buildHeaders(method: string, url: string): any {
|
|
149
153
|
const config = this.config
|
|
150
|
-
const { context, secretId, secretKey, sessionToken } = config
|
|
154
|
+
const { context, secretId, secretKey, sessionToken, accessKey } = config
|
|
151
155
|
const args = this.args
|
|
152
156
|
|
|
153
157
|
const { TCB_SOURCE } = CloudBase.getCloudbaseContext()
|
|
@@ -204,11 +208,21 @@ export class TcbOpenApiHttpRequester {
|
|
|
204
208
|
withSignedParams: false,
|
|
205
209
|
isCloudApi: true
|
|
206
210
|
})
|
|
207
|
-
|
|
211
|
+
let token = ''
|
|
212
|
+
// 如果请求参数里面传了 token,优先使用 token
|
|
213
|
+
if (args.token) {
|
|
214
|
+
token = makeBearerToken(args.token)
|
|
215
|
+
} else if (accessKey) {
|
|
216
|
+
// 如果配置了 API_KEY,优先使用 API_KEY
|
|
217
|
+
token = makeBearerToken(accessKey)
|
|
218
|
+
} else if (typeof sessionToken === 'string' && sessionToken !== '') {
|
|
219
|
+
// 如果配置了 sessionToken,使用 sessionToken
|
|
220
|
+
token = `${authorization}, Timestamp=${timestamp}, Token=${sessionToken}`
|
|
221
|
+
} else {
|
|
222
|
+
token = `${authorization}, Timestamp=${timestamp}`
|
|
223
|
+
}
|
|
208
224
|
/* eslint-disable @typescript-eslint/dot-notation */
|
|
209
|
-
requiredHeaders['Authorization'] =
|
|
210
|
-
? `${authorization}, Timestamp=${timestamp}, Token=${sessionToken}`
|
|
211
|
-
: `${authorization}, Timestamp=${timestamp}`
|
|
225
|
+
requiredHeaders['Authorization'] = token
|
|
212
226
|
|
|
213
227
|
return { ...requiredHeaders }
|
|
214
228
|
}
|
|
@@ -225,3 +239,7 @@ export async function request(args: ICallContainerRequestInfo & { path: string }
|
|
|
225
239
|
|
|
226
240
|
return await requester.request()
|
|
227
241
|
}
|
|
242
|
+
function makeBearerToken(token: string): string {
|
|
243
|
+
const trimmed = token.trim()
|
|
244
|
+
return trimmed.startsWith('Bearer ') ? trimmed : `Bearer ${trimmed}`
|
|
245
|
+
}
|
package/src/utils/utils.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { ICloudBaseConfig } from '../../types'
|
|
2
|
+
import * as utils from '../utils/utils'
|
|
3
|
+
import { ERROR } from '../const/code'
|
|
4
|
+
|
|
1
5
|
interface IErrorInfo {
|
|
2
6
|
requestId?: string
|
|
3
7
|
code?: string
|
|
@@ -81,3 +85,61 @@ const kEnvRuleReg = /^[a-z0-9_-]{1,40}$/
|
|
|
81
85
|
export function isValidEnvFormat(env = '') {
|
|
82
86
|
return typeof env === 'string' && kEnvRuleReg.test(env)
|
|
83
87
|
}
|
|
88
|
+
export function normalizeConfig(config: ICloudBaseConfig) {
|
|
89
|
+
const { debug = false, secretId, secretKey, env, timeout = 15000, headers = {}, accessKey } = config
|
|
90
|
+
|
|
91
|
+
// 检查用户显示配置的 secretId 和 secretKey 是否成对出现,要么都有,要么都没有
|
|
92
|
+
if (!secretId !== !secretKey) {
|
|
93
|
+
throw utils.E({
|
|
94
|
+
...ERROR.INVALID_PARAM,
|
|
95
|
+
message: 'secretId and secretKey must be a pair'
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
const cloudbaseConfigBase: ICloudBaseConfig = {
|
|
99
|
+
...config,
|
|
100
|
+
debug,
|
|
101
|
+
// secretId,
|
|
102
|
+
// secretKey,
|
|
103
|
+
envName: env,
|
|
104
|
+
headers: { ...headers }, // 结构用户传进来的 headers,防止用户修改原对象
|
|
105
|
+
timeout
|
|
106
|
+
// accessKey: accessKey || process.env.CLOUDBASE_APIKEY
|
|
107
|
+
}
|
|
108
|
+
const {
|
|
109
|
+
TENCENTCLOUD_SECRETID,
|
|
110
|
+
TENCENTCLOUD_SECRETKEY,
|
|
111
|
+
TENCENTCLOUD_SESSIONTOKEN,
|
|
112
|
+
CLOUDBASE_APIKEY
|
|
113
|
+
} = process.env
|
|
114
|
+
// 如果用户显示配置了accessKey,取用户显示配置的 accessKey,优先级最高
|
|
115
|
+
if (accessKey) {
|
|
116
|
+
return Object.assign(cloudbaseConfigBase, { secretId: undefined, secretKey: undefined, accessKey })
|
|
117
|
+
}
|
|
118
|
+
// 显示配置了 secretId, secretKey,取 secretId, secretKey
|
|
119
|
+
if (secretId && secretKey) {
|
|
120
|
+
return Object.assign(cloudbaseConfigBase, { secretId, secretKey, accessKey: undefined })
|
|
121
|
+
}
|
|
122
|
+
// 下面从环境变量取 secretId, secretKey, accessKey
|
|
123
|
+
if (CLOUDBASE_APIKEY) {
|
|
124
|
+
return Object.assign(cloudbaseConfigBase, { secretId: undefined, secretKey: undefined, accessKey: CLOUDBASE_APIKEY })
|
|
125
|
+
}
|
|
126
|
+
if (TENCENTCLOUD_SECRETID && TENCENTCLOUD_SECRETKEY) {
|
|
127
|
+
return Object.assign(cloudbaseConfigBase, { secretId: TENCENTCLOUD_SECRETID, secretKey: TENCENTCLOUD_SECRETKEY, sessionToken: TENCENTCLOUD_SESSIONTOKEN, accessKey: undefined })
|
|
128
|
+
}
|
|
129
|
+
if (config.context?.extendedContext) {
|
|
130
|
+
const extendedContext = config.context.extendedContext
|
|
131
|
+
if (!cloudbaseConfigBase.env) {
|
|
132
|
+
cloudbaseConfigBase.env = extendedContext.envId
|
|
133
|
+
cloudbaseConfigBase.envName = extendedContext.envId
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// 从 context 中获取 secret
|
|
137
|
+
if (!cloudbaseConfigBase.secretId && !cloudbaseConfigBase.secretKey) {
|
|
138
|
+
cloudbaseConfigBase.secretId = extendedContext?.tmpSecret?.secretId
|
|
139
|
+
cloudbaseConfigBase.secretKey = extendedContext?.tmpSecret?.secretKey
|
|
140
|
+
cloudbaseConfigBase.sessionToken = extendedContext?.tmpSecret?.token
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// 都没有配置,返回原始的配置
|
|
144
|
+
return cloudbaseConfigBase
|
|
145
|
+
}
|
package/types/index.d.ts
CHANGED