@aligent/microservice-util-lib 1.4.1 → 1.5.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/package.json +1 -1
- package/src/index.d.ts +2 -2
- package/src/index.js +2 -1
- package/src/openapi-fetch-middlewares/authentications.d.ts +49 -8
- package/src/openapi-fetch-middlewares/authentications.js +52 -8
- package/src/openapi-fetch-middlewares/oauth10a/oauth10a.d.ts +18 -0
- package/src/openapi-fetch-middlewares/oauth10a/oauth10a.js +63 -19
- package/src/openapi-fetch-middlewares/retry.d.ts +20 -3
- package/src/openapi-fetch-middlewares/retry.js +24 -4
- package/src/openapi-fetch-middlewares/types/authentications.d.ts +31 -14
- package/src/openapi-fetch-middlewares/types/retry.d.ts +12 -3
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import chunkBy from './chunk-by/chunk-by';
|
|
|
2
2
|
import fetchSsmParams from './fetch-ssm-params/fetch-ssm-params';
|
|
3
3
|
import getAwsIdFromArn from './get-aws-id-from-arn/get-aws-id-from-arn';
|
|
4
4
|
import hasDefinedProperties from './has-properties-defined/has-properties-defined';
|
|
5
|
-
import { ApiKey, Basic, OAuth10a, OAuth20, apiKeyAuthMiddleware, basicAuthMiddleware, oAuth10aAuthMiddleware, oAuth20AuthMiddleware } from './openapi-fetch-middlewares/authentications';
|
|
5
|
+
import { ApiKey, Basic, OAuth10a, OAuth20, apiKeyAuthMiddleware, basicAuthMiddleware, oAuth10aAuthMiddleware, oAuth20AuthMiddleware, resignOauth10aRequest } from './openapi-fetch-middlewares/authentications';
|
|
6
6
|
import { LogLevel, Logger, logMiddleware } from './openapi-fetch-middlewares/log';
|
|
7
7
|
import { RetryConfig as RetryMiddlewareConfig, retryMiddleware } from './openapi-fetch-middlewares/retry';
|
|
8
8
|
import remap, { ObjectMap, Remap } from './remap/remap';
|
|
9
9
|
import retryWrapper, { RetryConfig } from './retry-wrapper/retry-wrapper';
|
|
10
10
|
import S3Dao from './s3/s3';
|
|
11
11
|
export type { ApiKey, Basic, LogLevel, Logger, OAuth10a, OAuth20, ObjectMap, Remap, RetryConfig, RetryMiddlewareConfig, S3Dao, };
|
|
12
|
-
export { apiKeyAuthMiddleware, basicAuthMiddleware, chunkBy, fetchSsmParams, getAwsIdFromArn, hasDefinedProperties, logMiddleware, oAuth10aAuthMiddleware, oAuth20AuthMiddleware, remap, retryMiddleware, retryWrapper, };
|
|
12
|
+
export { apiKeyAuthMiddleware, basicAuthMiddleware, chunkBy, fetchSsmParams, getAwsIdFromArn, hasDefinedProperties, logMiddleware, oAuth10aAuthMiddleware, oAuth20AuthMiddleware, remap, resignOauth10aRequest, retryMiddleware, retryWrapper, };
|
package/src/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.retryWrapper = exports.retryMiddleware = exports.remap = exports.oAuth20AuthMiddleware = exports.oAuth10aAuthMiddleware = exports.logMiddleware = exports.hasDefinedProperties = exports.getAwsIdFromArn = exports.fetchSsmParams = exports.chunkBy = exports.basicAuthMiddleware = exports.apiKeyAuthMiddleware = void 0;
|
|
6
|
+
exports.retryWrapper = exports.retryMiddleware = exports.resignOauth10aRequest = exports.remap = exports.oAuth20AuthMiddleware = exports.oAuth10aAuthMiddleware = exports.logMiddleware = exports.hasDefinedProperties = exports.getAwsIdFromArn = exports.fetchSsmParams = exports.chunkBy = exports.basicAuthMiddleware = exports.apiKeyAuthMiddleware = void 0;
|
|
7
7
|
/* v8 ignore start */
|
|
8
8
|
const chunk_by_1 = __importDefault(require("./chunk-by/chunk-by"));
|
|
9
9
|
exports.chunkBy = chunk_by_1.default;
|
|
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "apiKeyAuthMiddleware", { enumerable: true, get:
|
|
|
18
18
|
Object.defineProperty(exports, "basicAuthMiddleware", { enumerable: true, get: function () { return authentications_1.basicAuthMiddleware; } });
|
|
19
19
|
Object.defineProperty(exports, "oAuth10aAuthMiddleware", { enumerable: true, get: function () { return authentications_1.oAuth10aAuthMiddleware; } });
|
|
20
20
|
Object.defineProperty(exports, "oAuth20AuthMiddleware", { enumerable: true, get: function () { return authentications_1.oAuth20AuthMiddleware; } });
|
|
21
|
+
Object.defineProperty(exports, "resignOauth10aRequest", { enumerable: true, get: function () { return authentications_1.resignOauth10aRequest; } });
|
|
21
22
|
const log_1 = require("./openapi-fetch-middlewares/log");
|
|
22
23
|
Object.defineProperty(exports, "logMiddleware", { enumerable: true, get: function () { return log_1.logMiddleware; } });
|
|
23
24
|
const retry_1 = require("./openapi-fetch-middlewares/retry");
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { Middleware } from 'openapi-fetch';
|
|
2
|
-
import
|
|
2
|
+
import { resignOauth10aRequest } from './oauth10a/oauth10a';
|
|
3
|
+
import type { ApiKey, Basic, OAuth10a, OAuth20, Resolvable } from './types/authentications';
|
|
4
|
+
/**
|
|
5
|
+
* Resolves a `Resolvable<T>` value to its underlying type.
|
|
6
|
+
* If the value is a function, it is called and awaited; otherwise, it is returned as-is.
|
|
7
|
+
*
|
|
8
|
+
* @param {Resolvable<T>} value - The resolvable value.
|
|
9
|
+
* @returns {Promise<T>} The resolved value.
|
|
10
|
+
*/
|
|
11
|
+
declare function resolve<T>(value: Resolvable<T>): Promise<T>;
|
|
3
12
|
/**
|
|
4
13
|
* Creates an openapi-fetch middleware for API key authentication.
|
|
5
14
|
* This middleware sets the API key in the specified header for each request.
|
|
@@ -8,9 +17,17 @@ import type { ApiKey, Basic, OAuth10a, OAuth20 } from './types/authentications';
|
|
|
8
17
|
* @returns {Middleware} The middleware for API key authentication.
|
|
9
18
|
*
|
|
10
19
|
* @example
|
|
20
|
+
* // Static value
|
|
11
21
|
* const middleware = apiKeyAuthMiddleware({
|
|
12
22
|
* header: 'x-api-key',
|
|
13
|
-
* value:
|
|
23
|
+
* value: 'your-api-key',
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Dynamic value (async function)
|
|
28
|
+
* const middleware = apiKeyAuthMiddleware({
|
|
29
|
+
* header: 'x-api-key',
|
|
30
|
+
* value: async () => fetchApiKey(),
|
|
14
31
|
* });
|
|
15
32
|
*/
|
|
16
33
|
declare function apiKeyAuthMiddleware(config: ApiKey): Middleware;
|
|
@@ -23,8 +40,15 @@ declare function apiKeyAuthMiddleware(config: ApiKey): Middleware;
|
|
|
23
40
|
* @returns {Middleware} The middleware for Basic authentication.
|
|
24
41
|
*
|
|
25
42
|
* @example
|
|
43
|
+
* // Static credentials
|
|
44
|
+
* const middleware = basicAuthMiddleware({
|
|
45
|
+
* credentials: { username: 'user', password: 'pass' },
|
|
46
|
+
* });
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // Dynamic credentials (async function)
|
|
26
50
|
* const middleware = basicAuthMiddleware({
|
|
27
|
-
* credentials: async () => (
|
|
51
|
+
* credentials: async () => fetchCredentials(),
|
|
28
52
|
* });
|
|
29
53
|
*/
|
|
30
54
|
declare function basicAuthMiddleware(config: Basic): Middleware;
|
|
@@ -37,14 +61,22 @@ declare function basicAuthMiddleware(config: Basic): Middleware;
|
|
|
37
61
|
* @returns {Middleware} The middleware for OAuth 1.0a authentication.
|
|
38
62
|
*
|
|
39
63
|
* @example
|
|
64
|
+
* // Static credentials
|
|
40
65
|
* const middleware = oAuth10aAuthMiddleware({
|
|
41
66
|
* algorithm: 'HMAC-SHA256',
|
|
42
|
-
* credentials:
|
|
67
|
+
* credentials: {
|
|
43
68
|
* consumerKey: 'key',
|
|
44
69
|
* consumerSecret: 'secret',
|
|
45
70
|
* token: 'token',
|
|
46
71
|
* tokenSecret: 'tokenSecret',
|
|
47
|
-
* }
|
|
72
|
+
* },
|
|
73
|
+
* });
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* // Dynamic credentials (async function)
|
|
77
|
+
* const middleware = oAuth10aAuthMiddleware({
|
|
78
|
+
* algorithm: 'HMAC-SHA256',
|
|
79
|
+
* credentials: async () => fetchOAuthCredentials(),
|
|
48
80
|
* });
|
|
49
81
|
*/
|
|
50
82
|
declare function oAuth10aAuthMiddleware(config: OAuth10a): Middleware;
|
|
@@ -56,11 +88,20 @@ declare function oAuth10aAuthMiddleware(config: OAuth10a): Middleware;
|
|
|
56
88
|
* @returns {Middleware} The middleware for OAuth 2.0 authentication.
|
|
57
89
|
*
|
|
58
90
|
* @example
|
|
91
|
+
* // Static token
|
|
92
|
+
* const middleware = oAuth20AuthMiddleware({
|
|
93
|
+
* token: 'your-access-token',
|
|
94
|
+
* tokenType: 'Bearer',
|
|
95
|
+
* });
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* // Dynamic token (async function)
|
|
59
99
|
* const middleware = oAuth20AuthMiddleware({
|
|
60
|
-
* token: async () =>
|
|
100
|
+
* token: async () => fetchAccessToken(),
|
|
61
101
|
* tokenType: 'Bearer',
|
|
62
102
|
* });
|
|
63
103
|
*/
|
|
64
104
|
declare function oAuth20AuthMiddleware(options: OAuth20): Middleware;
|
|
65
|
-
export
|
|
66
|
-
export {
|
|
105
|
+
export { resolve };
|
|
106
|
+
export type { ApiKey, Basic, OAuth10a, OAuth20, Resolvable };
|
|
107
|
+
export { apiKeyAuthMiddleware, basicAuthMiddleware, oAuth10aAuthMiddleware, oAuth20AuthMiddleware, resignOauth10aRequest, };
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resignOauth10aRequest = void 0;
|
|
4
|
+
exports.resolve = resolve;
|
|
3
5
|
exports.apiKeyAuthMiddleware = apiKeyAuthMiddleware;
|
|
4
6
|
exports.basicAuthMiddleware = basicAuthMiddleware;
|
|
5
7
|
exports.oAuth10aAuthMiddleware = oAuth10aAuthMiddleware;
|
|
6
8
|
exports.oAuth20AuthMiddleware = oAuth20AuthMiddleware;
|
|
7
9
|
const oauth10a_1 = require("./oauth10a/oauth10a");
|
|
10
|
+
Object.defineProperty(exports, "resignOauth10aRequest", { enumerable: true, get: function () { return oauth10a_1.resignOauth10aRequest; } });
|
|
11
|
+
/**
|
|
12
|
+
* Resolves a `Resolvable<T>` value to its underlying type.
|
|
13
|
+
* If the value is a function, it is called and awaited; otherwise, it is returned as-is.
|
|
14
|
+
*
|
|
15
|
+
* @param {Resolvable<T>} value - The resolvable value.
|
|
16
|
+
* @returns {Promise<T>} The resolved value.
|
|
17
|
+
*/
|
|
18
|
+
async function resolve(value) {
|
|
19
|
+
return typeof value === 'function' ? await value() : value;
|
|
20
|
+
}
|
|
8
21
|
/**
|
|
9
22
|
* Creates an openapi-fetch middleware for API key authentication.
|
|
10
23
|
* This middleware sets the API key in the specified header for each request.
|
|
@@ -13,15 +26,23 @@ const oauth10a_1 = require("./oauth10a/oauth10a");
|
|
|
13
26
|
* @returns {Middleware} The middleware for API key authentication.
|
|
14
27
|
*
|
|
15
28
|
* @example
|
|
29
|
+
* // Static value
|
|
30
|
+
* const middleware = apiKeyAuthMiddleware({
|
|
31
|
+
* header: 'x-api-key',
|
|
32
|
+
* value: 'your-api-key',
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // Dynamic value (async function)
|
|
16
37
|
* const middleware = apiKeyAuthMiddleware({
|
|
17
38
|
* header: 'x-api-key',
|
|
18
|
-
* value: async () =>
|
|
39
|
+
* value: async () => fetchApiKey(),
|
|
19
40
|
* });
|
|
20
41
|
*/
|
|
21
42
|
function apiKeyAuthMiddleware(config) {
|
|
22
43
|
return {
|
|
23
44
|
onRequest: async ({ request }) => {
|
|
24
|
-
request.headers.set(config.header, await config.value
|
|
45
|
+
request.headers.set(config.header, await resolve(config.value));
|
|
25
46
|
},
|
|
26
47
|
};
|
|
27
48
|
}
|
|
@@ -34,14 +55,21 @@ function apiKeyAuthMiddleware(config) {
|
|
|
34
55
|
* @returns {Middleware} The middleware for Basic authentication.
|
|
35
56
|
*
|
|
36
57
|
* @example
|
|
58
|
+
* // Static credentials
|
|
37
59
|
* const middleware = basicAuthMiddleware({
|
|
38
|
-
* credentials:
|
|
60
|
+
* credentials: { username: 'user', password: 'pass' },
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Dynamic credentials (async function)
|
|
65
|
+
* const middleware = basicAuthMiddleware({
|
|
66
|
+
* credentials: async () => fetchCredentials(),
|
|
39
67
|
* });
|
|
40
68
|
*/
|
|
41
69
|
function basicAuthMiddleware(config) {
|
|
42
70
|
return {
|
|
43
71
|
onRequest: async ({ request }) => {
|
|
44
|
-
const { username, password } = await config.credentials
|
|
72
|
+
const { username, password } = await resolve(config.credentials);
|
|
45
73
|
request.headers.set('Authorization', `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`);
|
|
46
74
|
},
|
|
47
75
|
};
|
|
@@ -55,14 +83,22 @@ function basicAuthMiddleware(config) {
|
|
|
55
83
|
* @returns {Middleware} The middleware for OAuth 1.0a authentication.
|
|
56
84
|
*
|
|
57
85
|
* @example
|
|
86
|
+
* // Static credentials
|
|
58
87
|
* const middleware = oAuth10aAuthMiddleware({
|
|
59
88
|
* algorithm: 'HMAC-SHA256',
|
|
60
|
-
* credentials:
|
|
89
|
+
* credentials: {
|
|
61
90
|
* consumerKey: 'key',
|
|
62
91
|
* consumerSecret: 'secret',
|
|
63
92
|
* token: 'token',
|
|
64
93
|
* tokenSecret: 'tokenSecret',
|
|
65
|
-
* }
|
|
94
|
+
* },
|
|
95
|
+
* });
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* // Dynamic credentials (async function)
|
|
99
|
+
* const middleware = oAuth10aAuthMiddleware({
|
|
100
|
+
* algorithm: 'HMAC-SHA256',
|
|
101
|
+
* credentials: async () => fetchOAuthCredentials(),
|
|
66
102
|
* });
|
|
67
103
|
*/
|
|
68
104
|
function oAuth10aAuthMiddleware(config) {
|
|
@@ -81,8 +117,16 @@ function oAuth10aAuthMiddleware(config) {
|
|
|
81
117
|
* @returns {Middleware} The middleware for OAuth 2.0 authentication.
|
|
82
118
|
*
|
|
83
119
|
* @example
|
|
120
|
+
* // Static token
|
|
121
|
+
* const middleware = oAuth20AuthMiddleware({
|
|
122
|
+
* token: 'your-access-token',
|
|
123
|
+
* tokenType: 'Bearer',
|
|
124
|
+
* });
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* // Dynamic token (async function)
|
|
84
128
|
* const middleware = oAuth20AuthMiddleware({
|
|
85
|
-
* token: async () =>
|
|
129
|
+
* token: async () => fetchAccessToken(),
|
|
86
130
|
* tokenType: 'Bearer',
|
|
87
131
|
* });
|
|
88
132
|
*/
|
|
@@ -90,7 +134,7 @@ function oAuth20AuthMiddleware(options) {
|
|
|
90
134
|
return {
|
|
91
135
|
onRequest: async ({ request }) => {
|
|
92
136
|
const { tokenType = 'Bearer' } = options;
|
|
93
|
-
request.headers.set('Authorization', `${tokenType} ${await options.token
|
|
137
|
+
request.headers.set('Authorization', `${tokenType} ${await resolve(options.token)}`);
|
|
94
138
|
},
|
|
95
139
|
};
|
|
96
140
|
}
|
|
@@ -10,3 +10,21 @@ import { OAuth10a } from '../authentications';
|
|
|
10
10
|
* @returns {Promise<string>} The generated OAuth 1.0a Authorization header.
|
|
11
11
|
*/
|
|
12
12
|
export declare function generateOauthParams(request: MiddlewareCallbackParams['request'], options: MiddlewareCallbackParams['options'], params: MiddlewareCallbackParams['params'], config: OAuth10a): Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Standalone function that re-signs a `Request` with fresh OAuth 1.0a credentials.
|
|
15
|
+
* This function derives all information (URL, method, query params, body)
|
|
16
|
+
* directly from the `Request` object, without requiring openapi-fetch middleware context.
|
|
17
|
+
*
|
|
18
|
+
* Designed for use with the retry middleware's `onRetry` hook to regenerate
|
|
19
|
+
* OAuth 1.0a signatures on retried requests.
|
|
20
|
+
*
|
|
21
|
+
* @param {Request} request - The request to re-sign.
|
|
22
|
+
* @param {OAuth10a} config - The OAuth 1.0a configuration.
|
|
23
|
+
* @returns {Promise<Request>} The request with a fresh `Authorization` header.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* client.use(retryMiddleware({
|
|
27
|
+
* onRetry: ({ request }) => resignOauth10aRequest(request, config),
|
|
28
|
+
* }));
|
|
29
|
+
*/
|
|
30
|
+
export declare function resignOauth10aRequest(request: Request, config: OAuth10a): Promise<Request>;
|
|
@@ -4,8 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.generateOauthParams = generateOauthParams;
|
|
7
|
+
exports.resignOauth10aRequest = resignOauth10aRequest;
|
|
7
8
|
const crypto_1 = __importDefault(require("crypto"));
|
|
8
9
|
const oauth_sign_1 = require("oauth-sign");
|
|
10
|
+
const authentications_1 = require("../authentications");
|
|
9
11
|
/**
|
|
10
12
|
* Determines whether a given URL is absolute.
|
|
11
13
|
*
|
|
@@ -129,25 +131,16 @@ function shouldGenerateBodyHash(body, method, includeBodyHash) {
|
|
|
129
131
|
return includeBodyHash === true;
|
|
130
132
|
}
|
|
131
133
|
/**
|
|
132
|
-
*
|
|
134
|
+
* Core signing logic shared by both the middleware path and the standalone re-sign path.
|
|
133
135
|
*
|
|
134
|
-
* @param
|
|
135
|
-
* @param
|
|
136
|
-
* @
|
|
137
|
-
* @param {OAuth10a} config - The OAuth 1.0a configuration.
|
|
138
|
-
* @returns {Promise<string>} The generated OAuth 1.0a Authorization header.
|
|
136
|
+
* @param input - The request details needed for signing.
|
|
137
|
+
* @param config - The OAuth 1.0a configuration.
|
|
138
|
+
* @returns The OAuth 1.0a Authorization header value (without the "OAuth " prefix).
|
|
139
139
|
*/
|
|
140
|
-
async function
|
|
140
|
+
async function signOauth10a(input, config) {
|
|
141
141
|
const { algorithm, includeBodyHash = 'auto', realm, callback, verifier } = config;
|
|
142
|
-
const {
|
|
143
|
-
|
|
144
|
-
// each request only can be used ONCE. We have to clone the request like this to extract information
|
|
145
|
-
// Otherwise, undici will not be able to create & send the request.
|
|
146
|
-
const clonedRequest = request.clone();
|
|
147
|
-
const method = (clonedRequest.method || 'GET').toUpperCase();
|
|
148
|
-
const url = combineUrlAndPathParams(clonedRequest.url, params.path);
|
|
149
|
-
const contentType = clonedRequest.headers.get('Content-Type');
|
|
150
|
-
const body = await clonedRequest.text();
|
|
142
|
+
const { method, oauthUrl, body, contentType, query } = input;
|
|
143
|
+
const { consumerKey, consumerSecret, token, tokenSecret } = await (0, authentications_1.resolve)(config.credentials);
|
|
151
144
|
const oauthParams = {
|
|
152
145
|
oauth_consumer_key: consumerKey,
|
|
153
146
|
oauth_nonce: crypto_1.default.randomUUID(),
|
|
@@ -168,8 +161,8 @@ async function generateOauthParams(request, options, params, config) {
|
|
|
168
161
|
}
|
|
169
162
|
const paramsToSign = {};
|
|
170
163
|
addParamsToSign(paramsToSign, oauthParams);
|
|
171
|
-
if (
|
|
172
|
-
addParamsToSign(paramsToSign,
|
|
164
|
+
if (query) {
|
|
165
|
+
addParamsToSign(paramsToSign, query);
|
|
173
166
|
}
|
|
174
167
|
// If user submit a form, then include form parameters in the
|
|
175
168
|
// signature as parameters rather than the body hash
|
|
@@ -184,7 +177,6 @@ async function generateOauthParams(request, options, params, config) {
|
|
|
184
177
|
oauthParams.oauth_body_hash = bodyHash;
|
|
185
178
|
addParamToSign(paramsToSign, 'oauth_body_hash', bodyHash);
|
|
186
179
|
}
|
|
187
|
-
const oauthUrl = getOAuthUrl(options.baseUrl, url);
|
|
188
180
|
oauthParams.oauth_signature = (0, oauth_sign_1.sign)(algorithm, method, oauthUrl, paramsToSign, consumerSecret, tokenSecret);
|
|
189
181
|
// realm should not be included in the signature calculation
|
|
190
182
|
// but is optional in the OAuth 1.0 Authorization header
|
|
@@ -197,3 +189,55 @@ async function generateOauthParams(request, options, params, config) {
|
|
|
197
189
|
.map(e => [e[0], '="', (0, oauth_sign_1.rfc3986)(e[1]), '"'].join(''))
|
|
198
190
|
.join(',');
|
|
199
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Generates OAuth 1.0a parameters for signing a request.
|
|
194
|
+
*
|
|
195
|
+
* @param {MiddlewareCallbackParams['request']} request - The request object.
|
|
196
|
+
* @param {MiddlewareCallbackParams['options']} options - The options object.
|
|
197
|
+
* @param {MiddlewareCallbackParams['params']} params - The parameters object.
|
|
198
|
+
* @param {OAuth10a} config - The OAuth 1.0a configuration.
|
|
199
|
+
* @returns {Promise<string>} The generated OAuth 1.0a Authorization header.
|
|
200
|
+
*/
|
|
201
|
+
async function generateOauthParams(request, options, params, config) {
|
|
202
|
+
const clonedRequest = request.clone();
|
|
203
|
+
const method = (clonedRequest.method || 'GET').toUpperCase();
|
|
204
|
+
const url = combineUrlAndPathParams(clonedRequest.url, params.path);
|
|
205
|
+
return signOauth10a({
|
|
206
|
+
method,
|
|
207
|
+
oauthUrl: getOAuthUrl(options.baseUrl, url),
|
|
208
|
+
contentType: clonedRequest.headers.get('Content-Type'),
|
|
209
|
+
body: await clonedRequest.text(),
|
|
210
|
+
query: params.query,
|
|
211
|
+
}, config);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Standalone function that re-signs a `Request` with fresh OAuth 1.0a credentials.
|
|
215
|
+
* This function derives all information (URL, method, query params, body)
|
|
216
|
+
* directly from the `Request` object, without requiring openapi-fetch middleware context.
|
|
217
|
+
*
|
|
218
|
+
* Designed for use with the retry middleware's `onRetry` hook to regenerate
|
|
219
|
+
* OAuth 1.0a signatures on retried requests.
|
|
220
|
+
*
|
|
221
|
+
* @param {Request} request - The request to re-sign.
|
|
222
|
+
* @param {OAuth10a} config - The OAuth 1.0a configuration.
|
|
223
|
+
* @returns {Promise<Request>} The request with a fresh `Authorization` header.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* client.use(retryMiddleware({
|
|
227
|
+
* onRetry: ({ request }) => resignOauth10aRequest(request, config),
|
|
228
|
+
* }));
|
|
229
|
+
*/
|
|
230
|
+
async function resignOauth10aRequest(request, config) {
|
|
231
|
+
const clonedRequest = request.clone();
|
|
232
|
+
const method = (clonedRequest.method || 'GET').toUpperCase();
|
|
233
|
+
const parsedUrl = new URL(clonedRequest.url);
|
|
234
|
+
const oauthParams = await signOauth10a({
|
|
235
|
+
method,
|
|
236
|
+
oauthUrl: getOAuthUrl(parsedUrl.origin, parsedUrl.pathname),
|
|
237
|
+
contentType: clonedRequest.headers.get('Content-Type'),
|
|
238
|
+
body: await clonedRequest.text(),
|
|
239
|
+
query: parsedUrl.search ? parsedUrl.searchParams : undefined,
|
|
240
|
+
}, config);
|
|
241
|
+
request.headers.set('Authorization', `OAuth ${oauthParams}`);
|
|
242
|
+
return request;
|
|
243
|
+
}
|
|
@@ -18,14 +18,31 @@ export type { HttpRequestData, HttpResponseData } from './utils/http-response-er
|
|
|
18
18
|
* const middleware = retryMiddleware();
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
21
|
-
* // Custom configuration
|
|
21
|
+
* // Custom configuration with logging
|
|
22
22
|
* const middleware = retryMiddleware({
|
|
23
23
|
* retries: 5,
|
|
24
24
|
* retryDelay: 'linear',
|
|
25
25
|
* baseDelay: 200,
|
|
26
26
|
* retryOn: [500, 502, 503, 504],
|
|
27
27
|
* onRetry: (context) => {
|
|
28
|
-
* console.log(`Retrying request (attempt ${context.
|
|
28
|
+
* console.log(`Retrying request (attempt ${context.attempt})`);
|
|
29
|
+
* },
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // Re-sign OAuth 1.0a requests on retry (returns a Request to replace the original)
|
|
34
|
+
* const middleware = retryMiddleware({
|
|
35
|
+
* retries: 3,
|
|
36
|
+
* onRetry: (context) => resignOauth10aRequest(context.request, oauthConfig),
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Combine logging and request transformation in onRetry
|
|
41
|
+
* const middleware = retryMiddleware({
|
|
42
|
+
* retries: 3,
|
|
43
|
+
* onRetry: async (context) => {
|
|
44
|
+
* console.log(`Retrying request (attempt ${context.attempt})`);
|
|
45
|
+
* return resignOauth10aRequest(context.request, oauthConfig);
|
|
29
46
|
* },
|
|
30
47
|
* });
|
|
31
48
|
*
|
|
@@ -35,7 +52,7 @@ export type { HttpRequestData, HttpResponseData } from './utils/http-response-er
|
|
|
35
52
|
* retries: 3,
|
|
36
53
|
* retryCondition: async (context) => {
|
|
37
54
|
* // Only retry on 503 Service Unavailable
|
|
38
|
-
* return context.response
|
|
55
|
+
* return context.response?.status === 503;
|
|
39
56
|
* },
|
|
40
57
|
* });
|
|
41
58
|
*
|
|
@@ -118,14 +118,31 @@ async function throwErrorIfNotOkResponse(response, request, throwOnNotOk) {
|
|
|
118
118
|
* const middleware = retryMiddleware();
|
|
119
119
|
*
|
|
120
120
|
* @example
|
|
121
|
-
* // Custom configuration
|
|
121
|
+
* // Custom configuration with logging
|
|
122
122
|
* const middleware = retryMiddleware({
|
|
123
123
|
* retries: 5,
|
|
124
124
|
* retryDelay: 'linear',
|
|
125
125
|
* baseDelay: 200,
|
|
126
126
|
* retryOn: [500, 502, 503, 504],
|
|
127
127
|
* onRetry: (context) => {
|
|
128
|
-
* console.log(`Retrying request (attempt ${context.
|
|
128
|
+
* console.log(`Retrying request (attempt ${context.attempt})`);
|
|
129
|
+
* },
|
|
130
|
+
* });
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* // Re-sign OAuth 1.0a requests on retry (returns a Request to replace the original)
|
|
134
|
+
* const middleware = retryMiddleware({
|
|
135
|
+
* retries: 3,
|
|
136
|
+
* onRetry: (context) => resignOauth10aRequest(context.request, oauthConfig),
|
|
137
|
+
* });
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* // Combine logging and request transformation in onRetry
|
|
141
|
+
* const middleware = retryMiddleware({
|
|
142
|
+
* retries: 3,
|
|
143
|
+
* onRetry: async (context) => {
|
|
144
|
+
* console.log(`Retrying request (attempt ${context.attempt})`);
|
|
145
|
+
* return resignOauth10aRequest(context.request, oauthConfig);
|
|
129
146
|
* },
|
|
130
147
|
* });
|
|
131
148
|
*
|
|
@@ -135,7 +152,7 @@ async function throwErrorIfNotOkResponse(response, request, throwOnNotOk) {
|
|
|
135
152
|
* retries: 3,
|
|
136
153
|
* retryCondition: async (context) => {
|
|
137
154
|
* // Only retry on 503 Service Unavailable
|
|
138
|
-
* return context.response
|
|
155
|
+
* return context.response?.status === 503;
|
|
139
156
|
* },
|
|
140
157
|
* });
|
|
141
158
|
*
|
|
@@ -204,7 +221,10 @@ async function performRetries(config, context) {
|
|
|
204
221
|
const delay = await config.retryDelay(attempt, { ...context, attempt, response });
|
|
205
222
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
206
223
|
if (config.onRetry) {
|
|
207
|
-
await config.onRetry({ ...context, attempt, response });
|
|
224
|
+
const mutatedReq = await config.onRetry({ ...context, attempt, response });
|
|
225
|
+
if (mutatedReq instanceof Request) {
|
|
226
|
+
context = { ...context, attempt, request: mutatedReq };
|
|
227
|
+
}
|
|
208
228
|
}
|
|
209
229
|
try {
|
|
210
230
|
const clonedRequest = context.request.clone();
|
|
@@ -1,28 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A value that can be provided either statically or as a function (sync or async).
|
|
3
|
+
* Used by authentication config interfaces to allow both static credentials
|
|
4
|
+
* and dynamic credential retrieval (e.g., from a secrets manager).
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* // Static value
|
|
8
|
+
* const value: Resolvable<string> = 'my-api-key';
|
|
9
|
+
*
|
|
10
|
+
* // Sync function
|
|
11
|
+
* const value: Resolvable<string> = () => getKey();
|
|
12
|
+
*
|
|
13
|
+
* // Async function
|
|
14
|
+
* const value: Resolvable<string> = async () => await fetchKey();
|
|
15
|
+
*/
|
|
16
|
+
export type Resolvable<T> = T | (() => T | Promise<T>);
|
|
1
17
|
/**
|
|
2
18
|
* Represents an API key authentication method.
|
|
3
19
|
*
|
|
4
20
|
* This interface is used for API key-based authentication, where the key is sent
|
|
5
|
-
* in a specific header. The value
|
|
21
|
+
* in a specific header. The value can be a static string or a function that returns one.
|
|
6
22
|
*
|
|
7
23
|
* @interface ApiKey
|
|
8
24
|
* @property {string} header - The header name where the API key will be set.
|
|
9
|
-
* @property {
|
|
25
|
+
* @property {Resolvable<string>} value - The API key value, or a function returning it.
|
|
10
26
|
*/
|
|
11
27
|
export interface ApiKey {
|
|
12
28
|
header: string;
|
|
13
|
-
value:
|
|
29
|
+
value: Resolvable<string>;
|
|
14
30
|
}
|
|
15
31
|
/**
|
|
16
32
|
* Represents basic authentication credentials.
|
|
17
33
|
*
|
|
18
34
|
* This interface is used for basic authentication, where the username and password
|
|
19
|
-
*
|
|
35
|
+
* can be provided statically or retrieved dynamically via a function.
|
|
20
36
|
*
|
|
21
37
|
* @interface Basic
|
|
22
|
-
* @property {
|
|
38
|
+
* @property {Resolvable<{ username: string; password: string }>} credentials - The credentials, or a function returning them.
|
|
23
39
|
*/
|
|
24
40
|
export interface Basic {
|
|
25
|
-
credentials:
|
|
41
|
+
credentials: Resolvable<{
|
|
26
42
|
username: string;
|
|
27
43
|
password: string;
|
|
28
44
|
}>;
|
|
@@ -31,12 +47,12 @@ export interface Basic {
|
|
|
31
47
|
* Represents OAuth 1.0a authentication credentials.
|
|
32
48
|
*
|
|
33
49
|
* This interface is used for OAuth 1.0a authentication, where the consumer key, consumer secret,
|
|
34
|
-
* token, and token secret
|
|
35
|
-
* like body hash inclusion, realm, callback, and verifier.
|
|
50
|
+
* token, and token secret can be provided statically or retrieved dynamically via a function.
|
|
51
|
+
* It also supports optional parameters like body hash inclusion, realm, callback, and verifier.
|
|
36
52
|
*
|
|
37
53
|
* @interface OAuth10a
|
|
38
54
|
* @property {'HMAC-SHA1' | 'HMAC-SHA256'} algorithm - The signing algorithm to use.
|
|
39
|
-
* @property {
|
|
55
|
+
* @property {Resolvable<{ consumerKey: string; consumerSecret: string; token?: string; tokenSecret: string }>} credentials - The OAuth 1.0a credentials, or a function returning them.
|
|
40
56
|
* @property {boolean | 'auto'} [includeBodyHash] - Whether to include a body hash in the signature. Defaults to 'auto'.
|
|
41
57
|
* @property {string} [realm] - The realm parameter for the Authorization header.
|
|
42
58
|
* @property {string} [callback] - The callback URL for OAuth 1.0a.
|
|
@@ -44,7 +60,7 @@ export interface Basic {
|
|
|
44
60
|
*/
|
|
45
61
|
export interface OAuth10a {
|
|
46
62
|
algorithm: 'HMAC-SHA1' | 'HMAC-SHA256';
|
|
47
|
-
credentials:
|
|
63
|
+
credentials: Resolvable<{
|
|
48
64
|
consumerKey: string;
|
|
49
65
|
consumerSecret: string;
|
|
50
66
|
token?: string;
|
|
@@ -58,14 +74,15 @@ export interface OAuth10a {
|
|
|
58
74
|
/**
|
|
59
75
|
* Represents OAuth 2.0 authentication credentials.
|
|
60
76
|
*
|
|
61
|
-
* This interface is used for OAuth 2.0 authentication, where an access token
|
|
62
|
-
*
|
|
77
|
+
* This interface is used for OAuth 2.0 authentication, where an access token can be
|
|
78
|
+
* provided statically or retrieved dynamically via a function.
|
|
79
|
+
* It also supports an optional token type (e.g., 'Bearer').
|
|
63
80
|
*
|
|
64
81
|
* @interface OAuth20
|
|
65
|
-
* @property {
|
|
82
|
+
* @property {Resolvable<string>} token - The access token, or a function returning it.
|
|
66
83
|
* @property {string} [tokenType] - The type of the token (e.g., 'Bearer'). Defaults to 'Bearer' if not specified.
|
|
67
84
|
*/
|
|
68
85
|
export interface OAuth20 {
|
|
69
|
-
token:
|
|
86
|
+
token: Resolvable<string>;
|
|
70
87
|
tokenType?: string;
|
|
71
88
|
}
|
|
@@ -35,10 +35,15 @@ export type RetryDelayFn = (attempt: number, context: RetryContext) => number |
|
|
|
35
35
|
* Function type for the onRetry callback.
|
|
36
36
|
* Called before each retry attempt.
|
|
37
37
|
*
|
|
38
|
+
* - If the function returns a `Request` (or `Promise<Request>`), that request replaces
|
|
39
|
+
* the current one for the retry attempt. This is useful for regenerating authentication
|
|
40
|
+
* headers (e.g., OAuth 1.0a re-signing).
|
|
41
|
+
* - If the function returns `void`, the original request is used as-is.
|
|
42
|
+
*
|
|
38
43
|
* @param {RetryContext} context - The retry context containing attempt information.
|
|
39
|
-
* @returns {void | Promise<void>}
|
|
44
|
+
* @returns {Request | void | Promise<Request | void>}
|
|
40
45
|
*/
|
|
41
|
-
export type OnRetryFn = (context: RetryContext) => void | Promise<void>;
|
|
46
|
+
export type OnRetryFn = (context: RetryContext) => Request | void | Promise<Request | void>;
|
|
42
47
|
/**
|
|
43
48
|
* Configuration for the retry middleware.
|
|
44
49
|
*
|
|
@@ -61,7 +66,11 @@ export type OnRetryFn = (context: RetryContext) => void | Promise<void>;
|
|
|
61
66
|
* @property {number} [baseDelay=100] - Base delay in milliseconds for built-in delay strategies.
|
|
62
67
|
* @property {number} [maxDelay=30000] - Maximum delay in milliseconds between retry attempts.
|
|
63
68
|
* @property {boolean} [shouldResetTimeout=false] - Whether to reset the timeout between retries.
|
|
64
|
-
* @property {OnRetryFn} [onRetry]
|
|
69
|
+
* @property {OnRetryFn} [onRetry]
|
|
70
|
+
* - Callback executed before each retry attempt (not the initial request).
|
|
71
|
+
* - If it returns a `Request`, that request replaces the current one for the retry.
|
|
72
|
+
* Useful for regenerating authentication headers (e.g., OAuth 1.0a re-signing).
|
|
73
|
+
* - If it returns `void`, the original request is used as-is.
|
|
65
74
|
* @property {number[]} [retryOn]
|
|
66
75
|
* - Array of HTTP status codes that should trigger a retry.
|
|
67
76
|
* - Defaults to 5xx, 429, and 408 errors.
|