@versori/run 0.2.25 → 0.2.26
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/esm/src/dsl/http/versori/roundtripper.d.ts +8 -0
- package/esm/src/dsl/http/versori/roundtripper.d.ts.map +1 -1
- package/esm/src/dsl/http/versori/roundtripper.js +327 -38
- package/package.json +1 -1
- package/script/src/dsl/http/versori/roundtripper.d.ts +8 -0
- package/script/src/dsl/http/versori/roundtripper.d.ts.map +1 -1
- package/script/src/dsl/http/versori/roundtripper.js +327 -38
|
@@ -25,12 +25,20 @@ export declare class VersoriCredentialsFactory implements RoundTripperFactory {
|
|
|
25
25
|
private cfgReader;
|
|
26
26
|
private log;
|
|
27
27
|
private tracer;
|
|
28
|
+
private oauth2Cache;
|
|
28
29
|
private readonly defaultDynamic;
|
|
29
30
|
constructor(credsClient: VersoriCredentialClient, credsBaseURL: string, platformAPIClient: PlatformAPIClient, logger: Logger, tracer: Tracer, cfgReader: ConfigReader);
|
|
30
31
|
static fromEnv(logger: Logger, tracer: Tracer): VersoriCredentialsFactory;
|
|
31
32
|
private changeRequestInit;
|
|
32
33
|
private changeBaseUrl;
|
|
33
34
|
create(connName: string): Promise<denoFetch | undefined>;
|
|
35
|
+
private apiKeyFetcherStatic;
|
|
36
|
+
private basicAuthFetcherStatic;
|
|
37
|
+
private bearerTokenFetcherStatic;
|
|
38
|
+
private getOAuth2Token;
|
|
39
|
+
private oauth2FetcherStatic;
|
|
40
|
+
private oauth1FetcherStatic;
|
|
41
|
+
private mtlsFetcherStatic;
|
|
34
42
|
createDynamic(templateName: string): Promise<DynamicFetcher | undefined>;
|
|
35
43
|
private traceFetch;
|
|
36
44
|
credentials(): CredentialsProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roundtripper.d.ts","sourceRoot":"","sources":["../../../../../src/src/dsl/http/versori/roundtripper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,0CAA0C,CAAC;AAElE,OAAO,
|
|
1
|
+
{"version":3,"file":"roundtripper.d.ts","sourceRoot":"","sources":["../../../../../src/src/dsl/http/versori/roundtripper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,0CAA0C,CAAC;AAElE,OAAO,EAIH,cAAc,EACd,YAAY,EAGZ,cAAc,EACd,mBAAmB,EACtB,MAAM,aAAa,CAAC;AAQrB,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAQ9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOrD,KAAK,SAAS,GAAG,CACb,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,CAAC,EAAE,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,IAAI,CAAC,UAAU,CAAA;CAAE,KAChD,OAAO,CAAC,QAAQ,CAAC,CAAC;AAavB;;;;;;;;;;GAUG;AACH,qBAAa,yBAA0B,YAAW,mBAAmB;IACjE,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,CAAC,iBAAiB,CAAoB;IAE7C,OAAO,CAAC,SAAS,CAAe;IAEhC,OAAO,CAAC,GAAG,CAAS;IAEpB,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,WAAW,CAAuC;IAE1D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAK7B;gBAGE,WAAW,EAAE,uBAAuB,EACpC,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,iBAAiB,EACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,YAAY;IAe3B,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,yBAAyB;IAoCzE,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,aAAa;IAwBf,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAuG9D,OAAO,CAAC,mBAAmB;IAoD3B,OAAO,CAAC,sBAAsB;IA2B9B,OAAO,CAAC,wBAAwB;YA6BlB,cAAc;IAiB5B,OAAO,CAAC,mBAAmB;IA2D3B,OAAO,CAAC,mBAAmB;IAuE3B,OAAO,CAAC,iBAAiB;IAqBzB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAyDxE,OAAO,CAAC,UAAU;IAqClB,WAAW,IAAI,mBAAmB;IAQlC,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc;IAyC9C,cAAc,CAChB,IAAI,EAAE,MAAM,EACZ,YAAY,UAAQ,EACpB,YAAY,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,KAAK,CAAC;IAiBX,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;YAqB9D,uBAAuB;IAoDrC,OAAO,CAAC,aAAa;IAoDrB,OAAO,CAAC,gBAAgB;IAmCxB,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,aAAa;IAqErB,OAAO,CAAC,aAAa;IAyErB,OAAO,CAAC,WAAW;YA6BL,QAAQ;YA2BR,MAAM;YA2BN,iBAAiB;CA0BlC"}
|
|
@@ -57,6 +57,12 @@ export class VersoriCredentialsFactory {
|
|
|
57
57
|
writable: true,
|
|
58
58
|
value: void 0
|
|
59
59
|
});
|
|
60
|
+
Object.defineProperty(this, "oauth2Cache", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
configurable: true,
|
|
63
|
+
writable: true,
|
|
64
|
+
value: {}
|
|
65
|
+
});
|
|
60
66
|
Object.defineProperty(this, "defaultDynamic", {
|
|
61
67
|
enumerable: true,
|
|
62
68
|
configurable: true,
|
|
@@ -137,58 +143,341 @@ export class VersoriCredentialsFactory {
|
|
|
137
143
|
this.log.debug('Using baseURL from connection', { url: newURL.toString() });
|
|
138
144
|
return newURL.toString();
|
|
139
145
|
}
|
|
140
|
-
create(connName) {
|
|
146
|
+
async create(connName) {
|
|
141
147
|
const cnxId = this.cfgReader.getConnectionID(connName);
|
|
142
148
|
if (!cnxId) {
|
|
143
|
-
this.log.debug('Connection not found in config, could be a dynamic connection', {
|
|
144
|
-
connectionName: connName,
|
|
145
|
-
});
|
|
146
149
|
return Promise.resolve(undefined);
|
|
147
150
|
}
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
const conn = await this.platformAPIClient.getStaticConnection(cnxId);
|
|
152
|
+
let _fetch = this.traceFetch;
|
|
153
|
+
if (!conn) {
|
|
154
|
+
this.log.error('Connection not found - using default fetch', { 'connectionName': connName, 'connectionID': cnxId });
|
|
155
|
+
return _fetch;
|
|
156
|
+
}
|
|
157
|
+
for (const cred of conn?.credentials ?? []) {
|
|
158
|
+
switch (cred.authSchemeConfig.type) {
|
|
159
|
+
case 'api-key': {
|
|
160
|
+
const apiTokenResponse = await this.getToken(cred.credential.id);
|
|
161
|
+
if (!apiTokenResponse?.token?.accessToken || !cred.authSchemeConfig.apiKey) {
|
|
162
|
+
this.log.error('API Key credential is missing token or configuration', {
|
|
163
|
+
connectionName: connName,
|
|
164
|
+
credentialId: cred.credential.id,
|
|
165
|
+
});
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
_fetch = this.apiKeyFetcherStatic(apiTokenResponse.token.accessToken, cred.authSchemeConfig.apiKey, _fetch);
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
case 'basic-auth': {
|
|
172
|
+
const basicTokenResponse = await this.getToken(cred.credential.id);
|
|
173
|
+
if (!basicTokenResponse?.token?.accessToken) {
|
|
174
|
+
this.log.error('Basic Auth credential is missing token', {
|
|
175
|
+
connectionName: connName,
|
|
176
|
+
credentialId: cred.credential.id,
|
|
177
|
+
});
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
_fetch = this.basicAuthFetcherStatic(basicTokenResponse.token.accessToken, _fetch);
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
case 'jwt-bearer': {
|
|
184
|
+
const bearerTokenResponse = await this.getToken(cred.credential.id);
|
|
185
|
+
if (!bearerTokenResponse?.token?.accessToken) {
|
|
186
|
+
this.log.error('Bearer Token credential is missing token', {
|
|
187
|
+
connectionName: connName,
|
|
188
|
+
credentialId: cred.credential.id,
|
|
189
|
+
});
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
_fetch = this.bearerTokenFetcherStatic(bearerTokenResponse.token.accessToken, _fetch);
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case 'oauth2': {
|
|
196
|
+
if (!cred.credential?.id) {
|
|
197
|
+
this.log.error('OAuth2 credential is missing credential ID', {
|
|
198
|
+
connectionName: connName,
|
|
199
|
+
credentialId: cred.credential.id,
|
|
200
|
+
});
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
_fetch = this.oauth2FetcherStatic(cred.credential.id, _fetch);
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
case 'oauth1': {
|
|
207
|
+
const oauth1Metadata = await this.getOAuth1Metadata(cred.credential.id);
|
|
208
|
+
if (!oauth1Metadata?.authorizationMetadata) {
|
|
209
|
+
this.log.error('OAuth1 credential is missing metadata', {
|
|
210
|
+
connectionName: connName,
|
|
211
|
+
credentialId: cred.credential.id,
|
|
212
|
+
});
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
_fetch = this.oauth1FetcherStatic(oauth1Metadata, _fetch);
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case 'certificate': {
|
|
219
|
+
const mtlsData = await this.getRaw(cred.credential.id);
|
|
220
|
+
if (!mtlsData?.credential?.data['cert'] || !mtlsData?.credential?.data['key']) {
|
|
221
|
+
this.log.error('mTLS credential is missing cert or key data', {
|
|
222
|
+
connectionName: connName,
|
|
223
|
+
credentialId: cred.credential.id,
|
|
224
|
+
});
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
_fetch = this.mtlsFetcherStatic({
|
|
228
|
+
cert: mtlsData.credential.data['cert'],
|
|
229
|
+
key: mtlsData.credential.data['key'],
|
|
230
|
+
ca: mtlsData.credential.data['ca'],
|
|
231
|
+
}, _fetch);
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
155
234
|
}
|
|
235
|
+
}
|
|
236
|
+
const _fn = async (input, init) => {
|
|
156
237
|
const _input = this.changeRequestInit(input, conn);
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
238
|
+
return _fetch(_input, init);
|
|
239
|
+
};
|
|
240
|
+
return _fn;
|
|
241
|
+
}
|
|
242
|
+
apiKeyFetcherStatic(token, asc, fn) {
|
|
243
|
+
const _fn = async (input, init) => {
|
|
244
|
+
if (!token) {
|
|
245
|
+
throw new Error('Token not found');
|
|
246
|
+
}
|
|
247
|
+
if (!asc) {
|
|
248
|
+
throw new Error('API Key configuration not found');
|
|
249
|
+
}
|
|
250
|
+
if (!init) {
|
|
251
|
+
init = {};
|
|
252
|
+
}
|
|
253
|
+
switch (asc.in) {
|
|
254
|
+
case 'header':
|
|
255
|
+
if (!init.headers) {
|
|
256
|
+
init.headers = new Headers();
|
|
257
|
+
}
|
|
258
|
+
if (init.headers instanceof Headers) {
|
|
259
|
+
init.headers.set(asc.name, token);
|
|
260
|
+
}
|
|
261
|
+
else if (init.headers instanceof Array) {
|
|
262
|
+
init.headers.push([asc.name, token]);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
init.headers = {
|
|
266
|
+
...init.headers,
|
|
267
|
+
[asc.name]: token,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
break;
|
|
271
|
+
case 'query':
|
|
272
|
+
if (typeof input === 'string') {
|
|
273
|
+
const _input = new URL(input);
|
|
274
|
+
_input.searchParams.append(asc.name, token);
|
|
275
|
+
input = _input.toString();
|
|
276
|
+
}
|
|
277
|
+
else if (input instanceof Request) {
|
|
278
|
+
const _input = new URL(input.url);
|
|
279
|
+
_input.searchParams.append(asc.name, token);
|
|
280
|
+
input = new Request(_input.toString(), init);
|
|
281
|
+
}
|
|
282
|
+
else if (input instanceof URL) {
|
|
283
|
+
input.searchParams.append(asc.name, token);
|
|
284
|
+
}
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
return fn(input, init);
|
|
288
|
+
};
|
|
289
|
+
return _fn;
|
|
290
|
+
}
|
|
291
|
+
basicAuthFetcherStatic(token, fn) {
|
|
292
|
+
const _fn = async (input, init) => {
|
|
293
|
+
if (!init) {
|
|
294
|
+
init = {};
|
|
295
|
+
}
|
|
296
|
+
if (!init.headers) {
|
|
297
|
+
init.headers = new Headers();
|
|
298
|
+
}
|
|
299
|
+
if (init.headers instanceof Headers) {
|
|
300
|
+
init.headers.set('Authorization', `Basic ${token}`);
|
|
301
|
+
}
|
|
302
|
+
else if (init.headers instanceof Array) {
|
|
303
|
+
init.headers.push(['Authorization', `Basic ${token}`]);
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
init.headers = {
|
|
307
|
+
...init.headers,
|
|
308
|
+
['Authorization']: `Basic ${token}`,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
return fn(input, init);
|
|
312
|
+
};
|
|
313
|
+
return _fn;
|
|
314
|
+
}
|
|
315
|
+
bearerTokenFetcherStatic(token, fn) {
|
|
316
|
+
const _fn = async (input, init) => {
|
|
317
|
+
if (!init) {
|
|
318
|
+
init = {};
|
|
319
|
+
}
|
|
320
|
+
if (!init.headers) {
|
|
321
|
+
init.headers = new Headers();
|
|
322
|
+
}
|
|
323
|
+
if (init.headers instanceof Headers) {
|
|
324
|
+
init.headers.set('Authorization', `Bearer ${token}`);
|
|
325
|
+
}
|
|
326
|
+
else if (init.headers instanceof Array) {
|
|
327
|
+
init.headers.push(['Authorization', `Bearer ${token}`]);
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
init.headers = {
|
|
331
|
+
...init.headers,
|
|
332
|
+
['Authorization']: `Bearer ${token}`,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
return fn(input, init);
|
|
336
|
+
};
|
|
337
|
+
return _fn;
|
|
338
|
+
}
|
|
339
|
+
// getOauth2Token fetches an OAuth2 token, stores the result in a cache, and returns the token.
|
|
340
|
+
// If forceRefresh is true, it will bypass the cache and fetch a new token then update the cache.
|
|
341
|
+
async getOAuth2Token(credId, forceRefresh = false) {
|
|
342
|
+
if (credId in this.oauth2Cache && !forceRefresh) {
|
|
343
|
+
return Promise.resolve(this.oauth2Cache[credId]);
|
|
344
|
+
}
|
|
345
|
+
const tokenResponse = await this.getToken(credId, forceRefresh);
|
|
346
|
+
this.oauth2Cache[credId] = {
|
|
347
|
+
token: tokenResponse.token?.accessToken || '',
|
|
348
|
+
tokenType: tokenResponse.token?.tokenType,
|
|
349
|
+
};
|
|
350
|
+
this.log.debug('Refreshed OAuth2 token and updating cache');
|
|
351
|
+
return this.oauth2Cache[credId];
|
|
352
|
+
}
|
|
353
|
+
oauth2FetcherStatic(credId, fn) {
|
|
354
|
+
const refreshFn = async (input, init, forceRefresh = false) => {
|
|
355
|
+
const tokenResponse = await this.getOAuth2Token(credId, forceRefresh);
|
|
356
|
+
const token = tokenResponse.token;
|
|
357
|
+
const _tokenType = () => {
|
|
358
|
+
const _tt = tokenResponse.tokenType?.toLowerCase();
|
|
359
|
+
switch (_tt) {
|
|
360
|
+
case 'bearer':
|
|
361
|
+
return 'Bearer';
|
|
362
|
+
case 'mac':
|
|
363
|
+
return 'MAC';
|
|
364
|
+
case 'basic':
|
|
365
|
+
return 'Basic';
|
|
178
366
|
default:
|
|
179
|
-
|
|
367
|
+
return 'Bearer';
|
|
180
368
|
}
|
|
369
|
+
};
|
|
370
|
+
if (!init) {
|
|
371
|
+
init = {};
|
|
372
|
+
}
|
|
373
|
+
if (!init.headers) {
|
|
374
|
+
init.headers = new Headers();
|
|
375
|
+
}
|
|
376
|
+
if (init.headers instanceof Headers) {
|
|
377
|
+
init.headers.set('Authorization', `${_tokenType()} ${token}`);
|
|
378
|
+
}
|
|
379
|
+
else if (init.headers instanceof Array) {
|
|
380
|
+
init.headers.push(['Authorization', `${_tokenType()} ${token}`]);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
init.headers = {
|
|
384
|
+
...init.headers,
|
|
385
|
+
['Authorization']: `${_tokenType()} ${token}`,
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
return fn(input, init);
|
|
389
|
+
};
|
|
390
|
+
const _fn = async (input, init) => {
|
|
391
|
+
const resp = await refreshFn(input, init);
|
|
392
|
+
if (resp.status === 401) {
|
|
393
|
+
this.log.debug('Received 401 Unauthorized response, attempting refresh', {
|
|
394
|
+
url: input,
|
|
395
|
+
status: resp.status,
|
|
396
|
+
});
|
|
397
|
+
return refreshFn(input, init, true);
|
|
398
|
+
}
|
|
399
|
+
return resp;
|
|
400
|
+
};
|
|
401
|
+
return _fn;
|
|
402
|
+
}
|
|
403
|
+
oauth1FetcherStatic(metadata, fn) {
|
|
404
|
+
const _fn = async (input, init) => {
|
|
405
|
+
const authParams = new URLSearchParams(metadata.authorizationMetadata?.authorizationParams);
|
|
406
|
+
if (!metadata.authorizationMetadata) {
|
|
407
|
+
throw new Error('OAuth1 metadata not found');
|
|
408
|
+
}
|
|
409
|
+
const oauth = new OAuth({
|
|
410
|
+
consumer: {
|
|
411
|
+
key: metadata.authorizationMetadata.consumerKey,
|
|
412
|
+
secret: metadata.authorizationMetadata.consumerSecret,
|
|
413
|
+
},
|
|
414
|
+
signature_method: 'HMAC-SHA256',
|
|
415
|
+
hash_function: (baseString, key) => createHmac('sha256', key).update(baseString).digest('base64'),
|
|
416
|
+
realm: authParams.get('realm') || undefined,
|
|
181
417
|
});
|
|
182
|
-
|
|
418
|
+
let url;
|
|
419
|
+
if (input instanceof Request) {
|
|
420
|
+
url = input.url;
|
|
421
|
+
}
|
|
422
|
+
else if (input instanceof URL) {
|
|
423
|
+
url = input.toString();
|
|
424
|
+
}
|
|
425
|
+
else if (typeof input === 'string') {
|
|
426
|
+
url = input;
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
throw new Error('Invalid input type for OAuth1 fetcher');
|
|
430
|
+
}
|
|
431
|
+
const header = oauth.toHeader(oauth.authorize({
|
|
432
|
+
url: url,
|
|
433
|
+
method: init?.method || 'GET',
|
|
434
|
+
}, {
|
|
435
|
+
key: metadata.authorizationMetadata?.oauthToken,
|
|
436
|
+
secret: metadata.authorizationMetadata?.oauthTokenSecret,
|
|
437
|
+
}));
|
|
438
|
+
const authHeader = header.Authorization;
|
|
439
|
+
if (!init) {
|
|
440
|
+
init = {};
|
|
441
|
+
}
|
|
442
|
+
if (!init.headers) {
|
|
443
|
+
init.headers = new Headers();
|
|
444
|
+
}
|
|
445
|
+
if (init.headers instanceof Headers) {
|
|
446
|
+
init.headers.set('Authorization', authHeader);
|
|
447
|
+
}
|
|
448
|
+
else if (init.headers instanceof Array) {
|
|
449
|
+
init.headers.push(['Authorization', authHeader]);
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
init.headers = {
|
|
453
|
+
...init.headers,
|
|
454
|
+
['Authorization']: authHeader,
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
return fn(input, init);
|
|
183
458
|
};
|
|
184
|
-
return
|
|
459
|
+
return _fn;
|
|
460
|
+
}
|
|
461
|
+
mtlsFetcherStatic(mtlsdata, fn) {
|
|
462
|
+
const _fn = async (input, init) => {
|
|
463
|
+
const cert = new TextDecoder().decode(mtlsdata.cert);
|
|
464
|
+
const key = new TextDecoder().decode(mtlsdata.key);
|
|
465
|
+
const caCerts = new TextDecoder().decode(mtlsdata.ca ?? new Uint8Array());
|
|
466
|
+
const httpClient = Deno.createHttpClient({
|
|
467
|
+
cert,
|
|
468
|
+
key,
|
|
469
|
+
caCerts: caCerts ? [caCerts] : [],
|
|
470
|
+
});
|
|
471
|
+
return fn(input, {
|
|
472
|
+
...init,
|
|
473
|
+
client: httpClient,
|
|
474
|
+
});
|
|
475
|
+
};
|
|
476
|
+
return _fn;
|
|
185
477
|
}
|
|
186
478
|
createDynamic(templateName) {
|
|
187
479
|
const template = this.cfgReader.getTemplateID(templateName);
|
|
188
480
|
if (!template) {
|
|
189
|
-
this.log.debug('Template not found in config, could be a static connection', {
|
|
190
|
-
templateName: templateName,
|
|
191
|
-
});
|
|
192
481
|
return Promise.resolve(undefined);
|
|
193
482
|
}
|
|
194
483
|
const _fn = async (activation, input, init) => {
|
package/package.json
CHANGED
|
@@ -25,12 +25,20 @@ export declare class VersoriCredentialsFactory implements RoundTripperFactory {
|
|
|
25
25
|
private cfgReader;
|
|
26
26
|
private log;
|
|
27
27
|
private tracer;
|
|
28
|
+
private oauth2Cache;
|
|
28
29
|
private readonly defaultDynamic;
|
|
29
30
|
constructor(credsClient: VersoriCredentialClient, credsBaseURL: string, platformAPIClient: PlatformAPIClient, logger: Logger, tracer: Tracer, cfgReader: ConfigReader);
|
|
30
31
|
static fromEnv(logger: Logger, tracer: Tracer): VersoriCredentialsFactory;
|
|
31
32
|
private changeRequestInit;
|
|
32
33
|
private changeBaseUrl;
|
|
33
34
|
create(connName: string): Promise<denoFetch | undefined>;
|
|
35
|
+
private apiKeyFetcherStatic;
|
|
36
|
+
private basicAuthFetcherStatic;
|
|
37
|
+
private bearerTokenFetcherStatic;
|
|
38
|
+
private getOAuth2Token;
|
|
39
|
+
private oauth2FetcherStatic;
|
|
40
|
+
private oauth1FetcherStatic;
|
|
41
|
+
private mtlsFetcherStatic;
|
|
34
42
|
createDynamic(templateName: string): Promise<DynamicFetcher | undefined>;
|
|
35
43
|
private traceFetch;
|
|
36
44
|
credentials(): CredentialsProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roundtripper.d.ts","sourceRoot":"","sources":["../../../../../src/src/dsl/http/versori/roundtripper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,0CAA0C,CAAC;AAElE,OAAO,
|
|
1
|
+
{"version":3,"file":"roundtripper.d.ts","sourceRoot":"","sources":["../../../../../src/src/dsl/http/versori/roundtripper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,0CAA0C,CAAC;AAElE,OAAO,EAIH,cAAc,EACd,YAAY,EAGZ,cAAc,EACd,mBAAmB,EACtB,MAAM,aAAa,CAAC;AAQrB,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAQ9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOrD,KAAK,SAAS,GAAG,CACb,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,CAAC,EAAE,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,IAAI,CAAC,UAAU,CAAA;CAAE,KAChD,OAAO,CAAC,QAAQ,CAAC,CAAC;AAavB;;;;;;;;;;GAUG;AACH,qBAAa,yBAA0B,YAAW,mBAAmB;IACjE,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,CAAC,iBAAiB,CAAoB;IAE7C,OAAO,CAAC,SAAS,CAAe;IAEhC,OAAO,CAAC,GAAG,CAAS;IAEpB,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,WAAW,CAAuC;IAE1D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAK7B;gBAGE,WAAW,EAAE,uBAAuB,EACpC,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,iBAAiB,EACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,YAAY;IAe3B,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,yBAAyB;IAoCzE,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,aAAa;IAwBf,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAuG9D,OAAO,CAAC,mBAAmB;IAoD3B,OAAO,CAAC,sBAAsB;IA2B9B,OAAO,CAAC,wBAAwB;YA6BlB,cAAc;IAiB5B,OAAO,CAAC,mBAAmB;IA2D3B,OAAO,CAAC,mBAAmB;IAuE3B,OAAO,CAAC,iBAAiB;IAqBzB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAyDxE,OAAO,CAAC,UAAU;IAqClB,WAAW,IAAI,mBAAmB;IAQlC,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc;IAyC9C,cAAc,CAChB,IAAI,EAAE,MAAM,EACZ,YAAY,UAAQ,EACpB,YAAY,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,KAAK,CAAC;IAiBX,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;YAqB9D,uBAAuB;IAoDrC,OAAO,CAAC,aAAa;IAoDrB,OAAO,CAAC,gBAAgB;IAmCxB,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,aAAa;IAqErB,OAAO,CAAC,aAAa;IAyErB,OAAO,CAAC,WAAW;YA6BL,QAAQ;YA2BR,MAAM;YA2BN,iBAAiB;CA0BlC"}
|
|
@@ -63,6 +63,12 @@ class VersoriCredentialsFactory {
|
|
|
63
63
|
writable: true,
|
|
64
64
|
value: void 0
|
|
65
65
|
});
|
|
66
|
+
Object.defineProperty(this, "oauth2Cache", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
configurable: true,
|
|
69
|
+
writable: true,
|
|
70
|
+
value: {}
|
|
71
|
+
});
|
|
66
72
|
Object.defineProperty(this, "defaultDynamic", {
|
|
67
73
|
enumerable: true,
|
|
68
74
|
configurable: true,
|
|
@@ -143,58 +149,341 @@ class VersoriCredentialsFactory {
|
|
|
143
149
|
this.log.debug('Using baseURL from connection', { url: newURL.toString() });
|
|
144
150
|
return newURL.toString();
|
|
145
151
|
}
|
|
146
|
-
create(connName) {
|
|
152
|
+
async create(connName) {
|
|
147
153
|
const cnxId = this.cfgReader.getConnectionID(connName);
|
|
148
154
|
if (!cnxId) {
|
|
149
|
-
this.log.debug('Connection not found in config, could be a dynamic connection', {
|
|
150
|
-
connectionName: connName,
|
|
151
|
-
});
|
|
152
155
|
return Promise.resolve(undefined);
|
|
153
156
|
}
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
const conn = await this.platformAPIClient.getStaticConnection(cnxId);
|
|
158
|
+
let _fetch = this.traceFetch;
|
|
159
|
+
if (!conn) {
|
|
160
|
+
this.log.error('Connection not found - using default fetch', { 'connectionName': connName, 'connectionID': cnxId });
|
|
161
|
+
return _fetch;
|
|
162
|
+
}
|
|
163
|
+
for (const cred of conn?.credentials ?? []) {
|
|
164
|
+
switch (cred.authSchemeConfig.type) {
|
|
165
|
+
case 'api-key': {
|
|
166
|
+
const apiTokenResponse = await this.getToken(cred.credential.id);
|
|
167
|
+
if (!apiTokenResponse?.token?.accessToken || !cred.authSchemeConfig.apiKey) {
|
|
168
|
+
this.log.error('API Key credential is missing token or configuration', {
|
|
169
|
+
connectionName: connName,
|
|
170
|
+
credentialId: cred.credential.id,
|
|
171
|
+
});
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
_fetch = this.apiKeyFetcherStatic(apiTokenResponse.token.accessToken, cred.authSchemeConfig.apiKey, _fetch);
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case 'basic-auth': {
|
|
178
|
+
const basicTokenResponse = await this.getToken(cred.credential.id);
|
|
179
|
+
if (!basicTokenResponse?.token?.accessToken) {
|
|
180
|
+
this.log.error('Basic Auth credential is missing token', {
|
|
181
|
+
connectionName: connName,
|
|
182
|
+
credentialId: cred.credential.id,
|
|
183
|
+
});
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
_fetch = this.basicAuthFetcherStatic(basicTokenResponse.token.accessToken, _fetch);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
case 'jwt-bearer': {
|
|
190
|
+
const bearerTokenResponse = await this.getToken(cred.credential.id);
|
|
191
|
+
if (!bearerTokenResponse?.token?.accessToken) {
|
|
192
|
+
this.log.error('Bearer Token credential is missing token', {
|
|
193
|
+
connectionName: connName,
|
|
194
|
+
credentialId: cred.credential.id,
|
|
195
|
+
});
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
_fetch = this.bearerTokenFetcherStatic(bearerTokenResponse.token.accessToken, _fetch);
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
case 'oauth2': {
|
|
202
|
+
if (!cred.credential?.id) {
|
|
203
|
+
this.log.error('OAuth2 credential is missing credential ID', {
|
|
204
|
+
connectionName: connName,
|
|
205
|
+
credentialId: cred.credential.id,
|
|
206
|
+
});
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
_fetch = this.oauth2FetcherStatic(cred.credential.id, _fetch);
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
case 'oauth1': {
|
|
213
|
+
const oauth1Metadata = await this.getOAuth1Metadata(cred.credential.id);
|
|
214
|
+
if (!oauth1Metadata?.authorizationMetadata) {
|
|
215
|
+
this.log.error('OAuth1 credential is missing metadata', {
|
|
216
|
+
connectionName: connName,
|
|
217
|
+
credentialId: cred.credential.id,
|
|
218
|
+
});
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
_fetch = this.oauth1FetcherStatic(oauth1Metadata, _fetch);
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
case 'certificate': {
|
|
225
|
+
const mtlsData = await this.getRaw(cred.credential.id);
|
|
226
|
+
if (!mtlsData?.credential?.data['cert'] || !mtlsData?.credential?.data['key']) {
|
|
227
|
+
this.log.error('mTLS credential is missing cert or key data', {
|
|
228
|
+
connectionName: connName,
|
|
229
|
+
credentialId: cred.credential.id,
|
|
230
|
+
});
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
_fetch = this.mtlsFetcherStatic({
|
|
234
|
+
cert: mtlsData.credential.data['cert'],
|
|
235
|
+
key: mtlsData.credential.data['key'],
|
|
236
|
+
ca: mtlsData.credential.data['ca'],
|
|
237
|
+
}, _fetch);
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
161
240
|
}
|
|
241
|
+
}
|
|
242
|
+
const _fn = async (input, init) => {
|
|
162
243
|
const _input = this.changeRequestInit(input, conn);
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
244
|
+
return _fetch(_input, init);
|
|
245
|
+
};
|
|
246
|
+
return _fn;
|
|
247
|
+
}
|
|
248
|
+
apiKeyFetcherStatic(token, asc, fn) {
|
|
249
|
+
const _fn = async (input, init) => {
|
|
250
|
+
if (!token) {
|
|
251
|
+
throw new Error('Token not found');
|
|
252
|
+
}
|
|
253
|
+
if (!asc) {
|
|
254
|
+
throw new Error('API Key configuration not found');
|
|
255
|
+
}
|
|
256
|
+
if (!init) {
|
|
257
|
+
init = {};
|
|
258
|
+
}
|
|
259
|
+
switch (asc.in) {
|
|
260
|
+
case 'header':
|
|
261
|
+
if (!init.headers) {
|
|
262
|
+
init.headers = new Headers();
|
|
263
|
+
}
|
|
264
|
+
if (init.headers instanceof Headers) {
|
|
265
|
+
init.headers.set(asc.name, token);
|
|
266
|
+
}
|
|
267
|
+
else if (init.headers instanceof Array) {
|
|
268
|
+
init.headers.push([asc.name, token]);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
init.headers = {
|
|
272
|
+
...init.headers,
|
|
273
|
+
[asc.name]: token,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
case 'query':
|
|
278
|
+
if (typeof input === 'string') {
|
|
279
|
+
const _input = new URL(input);
|
|
280
|
+
_input.searchParams.append(asc.name, token);
|
|
281
|
+
input = _input.toString();
|
|
282
|
+
}
|
|
283
|
+
else if (input instanceof Request) {
|
|
284
|
+
const _input = new URL(input.url);
|
|
285
|
+
_input.searchParams.append(asc.name, token);
|
|
286
|
+
input = new Request(_input.toString(), init);
|
|
287
|
+
}
|
|
288
|
+
else if (input instanceof URL) {
|
|
289
|
+
input.searchParams.append(asc.name, token);
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
return fn(input, init);
|
|
294
|
+
};
|
|
295
|
+
return _fn;
|
|
296
|
+
}
|
|
297
|
+
basicAuthFetcherStatic(token, fn) {
|
|
298
|
+
const _fn = async (input, init) => {
|
|
299
|
+
if (!init) {
|
|
300
|
+
init = {};
|
|
301
|
+
}
|
|
302
|
+
if (!init.headers) {
|
|
303
|
+
init.headers = new Headers();
|
|
304
|
+
}
|
|
305
|
+
if (init.headers instanceof Headers) {
|
|
306
|
+
init.headers.set('Authorization', `Basic ${token}`);
|
|
307
|
+
}
|
|
308
|
+
else if (init.headers instanceof Array) {
|
|
309
|
+
init.headers.push(['Authorization', `Basic ${token}`]);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
init.headers = {
|
|
313
|
+
...init.headers,
|
|
314
|
+
['Authorization']: `Basic ${token}`,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
return fn(input, init);
|
|
318
|
+
};
|
|
319
|
+
return _fn;
|
|
320
|
+
}
|
|
321
|
+
bearerTokenFetcherStatic(token, fn) {
|
|
322
|
+
const _fn = async (input, init) => {
|
|
323
|
+
if (!init) {
|
|
324
|
+
init = {};
|
|
325
|
+
}
|
|
326
|
+
if (!init.headers) {
|
|
327
|
+
init.headers = new Headers();
|
|
328
|
+
}
|
|
329
|
+
if (init.headers instanceof Headers) {
|
|
330
|
+
init.headers.set('Authorization', `Bearer ${token}`);
|
|
331
|
+
}
|
|
332
|
+
else if (init.headers instanceof Array) {
|
|
333
|
+
init.headers.push(['Authorization', `Bearer ${token}`]);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
init.headers = {
|
|
337
|
+
...init.headers,
|
|
338
|
+
['Authorization']: `Bearer ${token}`,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
return fn(input, init);
|
|
342
|
+
};
|
|
343
|
+
return _fn;
|
|
344
|
+
}
|
|
345
|
+
// getOauth2Token fetches an OAuth2 token, stores the result in a cache, and returns the token.
|
|
346
|
+
// If forceRefresh is true, it will bypass the cache and fetch a new token then update the cache.
|
|
347
|
+
async getOAuth2Token(credId, forceRefresh = false) {
|
|
348
|
+
if (credId in this.oauth2Cache && !forceRefresh) {
|
|
349
|
+
return Promise.resolve(this.oauth2Cache[credId]);
|
|
350
|
+
}
|
|
351
|
+
const tokenResponse = await this.getToken(credId, forceRefresh);
|
|
352
|
+
this.oauth2Cache[credId] = {
|
|
353
|
+
token: tokenResponse.token?.accessToken || '',
|
|
354
|
+
tokenType: tokenResponse.token?.tokenType,
|
|
355
|
+
};
|
|
356
|
+
this.log.debug('Refreshed OAuth2 token and updating cache');
|
|
357
|
+
return this.oauth2Cache[credId];
|
|
358
|
+
}
|
|
359
|
+
oauth2FetcherStatic(credId, fn) {
|
|
360
|
+
const refreshFn = async (input, init, forceRefresh = false) => {
|
|
361
|
+
const tokenResponse = await this.getOAuth2Token(credId, forceRefresh);
|
|
362
|
+
const token = tokenResponse.token;
|
|
363
|
+
const _tokenType = () => {
|
|
364
|
+
const _tt = tokenResponse.tokenType?.toLowerCase();
|
|
365
|
+
switch (_tt) {
|
|
366
|
+
case 'bearer':
|
|
367
|
+
return 'Bearer';
|
|
368
|
+
case 'mac':
|
|
369
|
+
return 'MAC';
|
|
370
|
+
case 'basic':
|
|
371
|
+
return 'Basic';
|
|
184
372
|
default:
|
|
185
|
-
|
|
373
|
+
return 'Bearer';
|
|
186
374
|
}
|
|
375
|
+
};
|
|
376
|
+
if (!init) {
|
|
377
|
+
init = {};
|
|
378
|
+
}
|
|
379
|
+
if (!init.headers) {
|
|
380
|
+
init.headers = new Headers();
|
|
381
|
+
}
|
|
382
|
+
if (init.headers instanceof Headers) {
|
|
383
|
+
init.headers.set('Authorization', `${_tokenType()} ${token}`);
|
|
384
|
+
}
|
|
385
|
+
else if (init.headers instanceof Array) {
|
|
386
|
+
init.headers.push(['Authorization', `${_tokenType()} ${token}`]);
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
init.headers = {
|
|
390
|
+
...init.headers,
|
|
391
|
+
['Authorization']: `${_tokenType()} ${token}`,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
return fn(input, init);
|
|
395
|
+
};
|
|
396
|
+
const _fn = async (input, init) => {
|
|
397
|
+
const resp = await refreshFn(input, init);
|
|
398
|
+
if (resp.status === 401) {
|
|
399
|
+
this.log.debug('Received 401 Unauthorized response, attempting refresh', {
|
|
400
|
+
url: input,
|
|
401
|
+
status: resp.status,
|
|
402
|
+
});
|
|
403
|
+
return refreshFn(input, init, true);
|
|
404
|
+
}
|
|
405
|
+
return resp;
|
|
406
|
+
};
|
|
407
|
+
return _fn;
|
|
408
|
+
}
|
|
409
|
+
oauth1FetcherStatic(metadata, fn) {
|
|
410
|
+
const _fn = async (input, init) => {
|
|
411
|
+
const authParams = new node_url_1.URLSearchParams(metadata.authorizationMetadata?.authorizationParams);
|
|
412
|
+
if (!metadata.authorizationMetadata) {
|
|
413
|
+
throw new Error('OAuth1 metadata not found');
|
|
414
|
+
}
|
|
415
|
+
const oauth = new oauth_1_0a_1.default({
|
|
416
|
+
consumer: {
|
|
417
|
+
key: metadata.authorizationMetadata.consumerKey,
|
|
418
|
+
secret: metadata.authorizationMetadata.consumerSecret,
|
|
419
|
+
},
|
|
420
|
+
signature_method: 'HMAC-SHA256',
|
|
421
|
+
hash_function: (baseString, key) => (0, node_crypto_1.createHmac)('sha256', key).update(baseString).digest('base64'),
|
|
422
|
+
realm: authParams.get('realm') || undefined,
|
|
187
423
|
});
|
|
188
|
-
|
|
424
|
+
let url;
|
|
425
|
+
if (input instanceof Request) {
|
|
426
|
+
url = input.url;
|
|
427
|
+
}
|
|
428
|
+
else if (input instanceof URL) {
|
|
429
|
+
url = input.toString();
|
|
430
|
+
}
|
|
431
|
+
else if (typeof input === 'string') {
|
|
432
|
+
url = input;
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
throw new Error('Invalid input type for OAuth1 fetcher');
|
|
436
|
+
}
|
|
437
|
+
const header = oauth.toHeader(oauth.authorize({
|
|
438
|
+
url: url,
|
|
439
|
+
method: init?.method || 'GET',
|
|
440
|
+
}, {
|
|
441
|
+
key: metadata.authorizationMetadata?.oauthToken,
|
|
442
|
+
secret: metadata.authorizationMetadata?.oauthTokenSecret,
|
|
443
|
+
}));
|
|
444
|
+
const authHeader = header.Authorization;
|
|
445
|
+
if (!init) {
|
|
446
|
+
init = {};
|
|
447
|
+
}
|
|
448
|
+
if (!init.headers) {
|
|
449
|
+
init.headers = new Headers();
|
|
450
|
+
}
|
|
451
|
+
if (init.headers instanceof Headers) {
|
|
452
|
+
init.headers.set('Authorization', authHeader);
|
|
453
|
+
}
|
|
454
|
+
else if (init.headers instanceof Array) {
|
|
455
|
+
init.headers.push(['Authorization', authHeader]);
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
init.headers = {
|
|
459
|
+
...init.headers,
|
|
460
|
+
['Authorization']: authHeader,
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
return fn(input, init);
|
|
189
464
|
};
|
|
190
|
-
return
|
|
465
|
+
return _fn;
|
|
466
|
+
}
|
|
467
|
+
mtlsFetcherStatic(mtlsdata, fn) {
|
|
468
|
+
const _fn = async (input, init) => {
|
|
469
|
+
const cert = new TextDecoder().decode(mtlsdata.cert);
|
|
470
|
+
const key = new TextDecoder().decode(mtlsdata.key);
|
|
471
|
+
const caCerts = new TextDecoder().decode(mtlsdata.ca ?? new Uint8Array());
|
|
472
|
+
const httpClient = Deno.createHttpClient({
|
|
473
|
+
cert,
|
|
474
|
+
key,
|
|
475
|
+
caCerts: caCerts ? [caCerts] : [],
|
|
476
|
+
});
|
|
477
|
+
return fn(input, {
|
|
478
|
+
...init,
|
|
479
|
+
client: httpClient,
|
|
480
|
+
});
|
|
481
|
+
};
|
|
482
|
+
return _fn;
|
|
191
483
|
}
|
|
192
484
|
createDynamic(templateName) {
|
|
193
485
|
const template = this.cfgReader.getTemplateID(templateName);
|
|
194
486
|
if (!template) {
|
|
195
|
-
this.log.debug('Template not found in config, could be a static connection', {
|
|
196
|
-
templateName: templateName,
|
|
197
|
-
});
|
|
198
487
|
return Promise.resolve(undefined);
|
|
199
488
|
}
|
|
200
489
|
const _fn = async (activation, input, init) => {
|