@outfoxx/sunday 2.0.0-beta.19 → 2.0.0-beta.21
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/README.md +89 -14
- package/build/authentication-adapter.d.ts +21 -0
- package/build/authentication-adapter.js +74 -0
- package/build/authentication-adapter.js.map +1 -0
- package/build/bearer-token-rejection-adapter.d.ts +6 -0
- package/build/bearer-token-rejection-adapter.js +25 -0
- package/build/bearer-token-rejection-adapter.js.map +1 -0
- package/build/fetch-copy.js +2 -1
- package/build/fetch-copy.js.map +1 -1
- package/build/fetch-event-source.d.ts +1 -1
- package/build/fetch-event-source.js +1 -5
- package/build/fetch-event-source.js.map +1 -1
- package/build/fetch-transport.d.ts +4 -6
- package/build/fetch-transport.js +5 -11
- package/build/fetch-transport.js.map +1 -1
- package/build/header-token-adapters.d.ts +28 -0
- package/build/header-token-adapters.js +121 -0
- package/build/header-token-adapters.js.map +1 -0
- package/build/index.d.ts +8 -2
- package/build/index.js +7 -1
- package/build/index.js.map +1 -1
- package/build/request-adapters-compat.d.ts +6 -0
- package/build/request-adapters-compat.js +19 -0
- package/build/request-adapters-compat.js.map +1 -0
- package/build/request-adapters.d.ts +0 -27
- package/build/request-adapters.js +3 -106
- package/build/request-adapters.js.map +1 -1
- package/build/request-context.d.ts +4 -0
- package/build/request-context.js +29 -0
- package/build/request-context.js.map +1 -0
- package/build/request-execution.d.ts +2 -7
- package/build/request-execution.js +25 -53
- package/build/request-execution.js.map +1 -1
- package/build/request-security-bindings.d.ts +5 -0
- package/build/request-security-bindings.js +30 -0
- package/build/request-security-bindings.js.map +1 -0
- package/build/request-security.d.ts +2 -4
- package/build/request-security.js +2 -11
- package/build/request-security.js.map +1 -1
- package/build/standard-authentication-adapter.d.ts +18 -0
- package/build/standard-authentication-adapter.js +58 -0
- package/build/standard-authentication-adapter.js.map +1 -0
- package/build/token-provider.d.ts +2 -1
- package/build/token-provider.js +2 -2
- package/build/token-provider.js.map +1 -1
- package/package.json +7 -2
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { TokenManager } from './token-manager.js';
|
|
15
|
+
import { TokenProviderError } from './token-provider.js';
|
|
16
|
+
import { copyRequest } from './fetch-copy.js';
|
|
17
|
+
import { hasInvalidBearerChallenge } from './request-security.js';
|
|
18
|
+
export class HeaderTokenAuthorizingAdapter {
|
|
19
|
+
header = 'Authorization';
|
|
20
|
+
tokenHeaderType = 'Bearer';
|
|
21
|
+
applyToken(request, accessToken) {
|
|
22
|
+
const headers = new Headers(request.headers);
|
|
23
|
+
headers.set(this.header, `${this.tokenHeaderType} ${accessToken}`);
|
|
24
|
+
return copyRequest(request, { headers });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class StaticHeaderTokenAuthorizingAdapter extends HeaderTokenAuthorizingAdapter {
|
|
28
|
+
accessToken;
|
|
29
|
+
constructor(accessToken) {
|
|
30
|
+
super();
|
|
31
|
+
this.accessToken = accessToken;
|
|
32
|
+
}
|
|
33
|
+
async adapt(request) {
|
|
34
|
+
return this.applyToken(request, this.accessToken);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Optional caching authorization adapter; install its response capability explicitly for feedback. */
|
|
38
|
+
export class RefreshingHeaderTokenAuthorizingAdapter extends HeaderTokenAuthorizingAdapter {
|
|
39
|
+
manager;
|
|
40
|
+
tokens;
|
|
41
|
+
lease;
|
|
42
|
+
constructor(refresh) {
|
|
43
|
+
super();
|
|
44
|
+
this.manager = new TokenManager({
|
|
45
|
+
identity: 'header-token-adapter',
|
|
46
|
+
configure: () => ({ clientIdentity: 'header-token-adapter' }),
|
|
47
|
+
acquire: async (_request, signal) => {
|
|
48
|
+
try {
|
|
49
|
+
const authorization = await refresh(signal);
|
|
50
|
+
return {
|
|
51
|
+
accessToken: authorization.token,
|
|
52
|
+
expiresAt: authorization.expires.getTime(),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
throw new RefreshFailure(error);
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
}, {
|
|
60
|
+
expirySkewMs: 0,
|
|
61
|
+
// One store slot, owned exclusively by this manager; no parallel adapter cache.
|
|
62
|
+
store: {
|
|
63
|
+
load: async () => this.tokens,
|
|
64
|
+
save: async (_key, tokens) => {
|
|
65
|
+
this.tokens = tokens;
|
|
66
|
+
},
|
|
67
|
+
remove: async () => {
|
|
68
|
+
this.tokens = undefined;
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/** Reports the manager's current expiry state without starting a refresh. */
|
|
74
|
+
shouldRefresh() {
|
|
75
|
+
return !this.tokens || this.tokens.expiresAt <= Date.now();
|
|
76
|
+
}
|
|
77
|
+
async adapt(value, request) {
|
|
78
|
+
if (request) {
|
|
79
|
+
const response = value;
|
|
80
|
+
const lease = this.lease;
|
|
81
|
+
if (lease &&
|
|
82
|
+
response.status === 401 &&
|
|
83
|
+
hasInvalidBearerChallenge(response.headers.get('WWW-Authenticate') ?? '') &&
|
|
84
|
+
request.headers.get(this.header) ===
|
|
85
|
+
`${this.tokenHeaderType} ${lease.tokens.accessToken}`) {
|
|
86
|
+
await lease.invalidate?.();
|
|
87
|
+
}
|
|
88
|
+
return response;
|
|
89
|
+
}
|
|
90
|
+
request = value;
|
|
91
|
+
try {
|
|
92
|
+
const lease = await this.manager.credentials({
|
|
93
|
+
scheme: 'header-token',
|
|
94
|
+
provider: 'header-token',
|
|
95
|
+
flow: 'external',
|
|
96
|
+
scopes: [],
|
|
97
|
+
transport: {
|
|
98
|
+
location: 'header',
|
|
99
|
+
name: this.header,
|
|
100
|
+
prefix: this.tokenHeaderType,
|
|
101
|
+
},
|
|
102
|
+
}, request.signal);
|
|
103
|
+
request.signal.throwIfAborted();
|
|
104
|
+
this.lease = lease;
|
|
105
|
+
return this.applyToken(request, lease.tokens.accessToken);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
if (error instanceof RefreshFailure)
|
|
109
|
+
throw error.cause;
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// TokenManager sanitizes provider errors; this adapter retains its application-error contract.
|
|
115
|
+
class RefreshFailure extends TokenProviderError {
|
|
116
|
+
constructor(cause) {
|
|
117
|
+
super();
|
|
118
|
+
this.cause = cause;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=header-token-adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header-token-adapters.js","sourceRoot":"","sources":["../src/header-token-adapters.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
CHANGED
|
@@ -26,8 +26,9 @@ export * from './date-time-types.js';
|
|
|
26
26
|
export * from './streaming-body.js';
|
|
27
27
|
export * from './operation-response.js';
|
|
28
28
|
export * from './operation.js';
|
|
29
|
-
export { HeaderTokenAuthorizingAdapter, StaticHeaderTokenAuthorizingAdapter, RefreshingHeaderTokenAuthorizingAdapter,
|
|
30
|
-
export
|
|
29
|
+
export { HeaderTokenAuthorizingAdapter, StaticHeaderTokenAuthorizingAdapter, RefreshingHeaderTokenAuthorizingAdapter, } from './header-token-adapters.js';
|
|
30
|
+
export { RequestAdapters, chainRequestAdapters } from './request-adapters.js';
|
|
31
|
+
export type { TokenAuthorization } from './header-token-adapters.js';
|
|
31
32
|
export * from './util/errors.js';
|
|
32
33
|
export * from './util/nullify.js';
|
|
33
34
|
export * from './security-binding.js';
|
|
@@ -42,3 +43,8 @@ export * from './response-adapters.js';
|
|
|
42
43
|
export * from './request-cancellation-error.js';
|
|
43
44
|
export * from './fetch-copy.js';
|
|
44
45
|
export * from './request-body.js';
|
|
46
|
+
export { requestSecurityBindings } from './request-security-bindings.js';
|
|
47
|
+
export { AuthenticationAdapter, authenticationAdapters, } from './authentication-adapter.js';
|
|
48
|
+
export { requestContext } from './request-context.js';
|
|
49
|
+
export { BearerTokenRejectionAdapter } from './bearer-token-rejection-adapter.js';
|
|
50
|
+
export { StandardAuthenticationAdapter, standardTransportFromSettings, } from './standard-authentication-adapter.js';
|
package/build/index.js
CHANGED
|
@@ -39,7 +39,8 @@ export * from './date-time-types.js';
|
|
|
39
39
|
export * from './streaming-body.js';
|
|
40
40
|
export * from './operation-response.js';
|
|
41
41
|
export * from './operation.js';
|
|
42
|
-
export { HeaderTokenAuthorizingAdapter, StaticHeaderTokenAuthorizingAdapter, RefreshingHeaderTokenAuthorizingAdapter,
|
|
42
|
+
export { HeaderTokenAuthorizingAdapter, StaticHeaderTokenAuthorizingAdapter, RefreshingHeaderTokenAuthorizingAdapter, } from './header-token-adapters.js';
|
|
43
|
+
export { RequestAdapters, chainRequestAdapters } from './request-adapters.js';
|
|
43
44
|
// Select exports from util
|
|
44
45
|
export * from './util/errors.js';
|
|
45
46
|
export * from './util/nullify.js';
|
|
@@ -55,4 +56,9 @@ export * from './response-adapters.js';
|
|
|
55
56
|
export * from './request-cancellation-error.js';
|
|
56
57
|
export * from './fetch-copy.js';
|
|
57
58
|
export * from './request-body.js';
|
|
59
|
+
export { requestSecurityBindings } from './request-security-bindings.js';
|
|
60
|
+
export { AuthenticationAdapter, authenticationAdapters, } from './authentication-adapter.js';
|
|
61
|
+
export { requestContext } from './request-context.js';
|
|
62
|
+
export { BearerTokenRejectionAdapter } from './bearer-token-rejection-adapter.js';
|
|
63
|
+
export { StandardAuthenticationAdapter, standardTransportFromSettings, } from './standard-authentication-adapter.js';
|
|
58
64
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,2CAA2C,CAAC;AAC1D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,6BAA6B,EAC7B,mCAAmC,EACnC,uCAAuC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,2CAA2C,CAAC;AAC1D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,6BAA6B,EAC7B,mCAAmC,EACnC,uCAAuC,GACxC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG9E,2BAA2B;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAElC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,iCAAiC,CAAC;AAEhD,cAAc,+BAA+B,CAAC;AAE9C,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AAErC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,iBAAiB,CAAC;AAEhC,cAAc,mBAAmB,CAAC;AAElC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAElF,OAAO,EACL,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,sCAAsC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Compatibility entry point for the original public request-adapters subpath.
|
|
2
|
+
* Internal transports import the token-independent chain module directly.
|
|
3
|
+
*/
|
|
4
|
+
export * from './request-adapters.js';
|
|
5
|
+
export { HeaderTokenAuthorizingAdapter, StaticHeaderTokenAuthorizingAdapter, RefreshingHeaderTokenAuthorizingAdapter, } from './header-token-adapters.js';
|
|
6
|
+
export type { TokenAuthorization } from './header-token-adapters.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
/** Compatibility entry point for the original public request-adapters subpath.
|
|
15
|
+
* Internal transports import the token-independent chain module directly.
|
|
16
|
+
*/
|
|
17
|
+
export * from './request-adapters.js';
|
|
18
|
+
export { HeaderTokenAuthorizingAdapter, StaticHeaderTokenAuthorizingAdapter, RefreshingHeaderTokenAuthorizingAdapter, } from './header-token-adapters.js';
|
|
19
|
+
//# sourceMappingURL=request-adapters-compat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-adapters-compat.js","sourceRoot":"","sources":["../src/request-adapters-compat.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;;GAEG;AACH,cAAc,uBAAuB,CAAC;AACtC,OAAO,EACL,6BAA6B,EAC7B,mCAAmC,EACnC,uCAAuC,GACxC,MAAM,4BAA4B,CAAC"}
|
|
@@ -1,31 +1,4 @@
|
|
|
1
1
|
import { RequestAdapter } from './request-adapter.js';
|
|
2
|
-
import { ResponseAdapter } from './response-adapter.js';
|
|
3
|
-
export declare abstract class HeaderTokenAuthorizingAdapter implements RequestAdapter {
|
|
4
|
-
header: string;
|
|
5
|
-
tokenHeaderType: string;
|
|
6
|
-
applyToken(request: Request, accessToken: string): Request;
|
|
7
|
-
abstract adapt(request: Request): Promise<Request>;
|
|
8
|
-
}
|
|
9
|
-
export declare class StaticHeaderTokenAuthorizingAdapter extends HeaderTokenAuthorizingAdapter {
|
|
10
|
-
private readonly accessToken;
|
|
11
|
-
constructor(accessToken: string);
|
|
12
|
-
adapt(request: Request): Promise<Request>;
|
|
13
|
-
}
|
|
14
|
-
export interface TokenAuthorization {
|
|
15
|
-
token: string;
|
|
16
|
-
expires: Date;
|
|
17
|
-
}
|
|
18
|
-
/** Optional caching authorization adapter; install its response capability explicitly for feedback. */
|
|
19
|
-
export declare class RefreshingHeaderTokenAuthorizingAdapter extends HeaderTokenAuthorizingAdapter implements ResponseAdapter {
|
|
20
|
-
private readonly manager;
|
|
21
|
-
private tokens?;
|
|
22
|
-
private lease?;
|
|
23
|
-
constructor(refresh: (signal: AbortSignal) => Promise<TokenAuthorization>);
|
|
24
|
-
/** Reports the manager's current expiry state without starting a refresh. */
|
|
25
|
-
shouldRefresh(): boolean;
|
|
26
|
-
adapt(request: Request): Promise<Request>;
|
|
27
|
-
adapt(response: Response, request: Request): Promise<Response>;
|
|
28
|
-
}
|
|
29
2
|
/** Flat, ordered composition; adapters may be ordinary objects with an adapt method. */
|
|
30
3
|
export declare class RequestAdapters implements RequestAdapter {
|
|
31
4
|
readonly adapters: readonly RequestAdapter[];
|
|
@@ -11,115 +11,10 @@
|
|
|
11
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
|
+
import { inheritRequestContext } from './request-context.js';
|
|
14
15
|
import { bodyReads } from './util/owned-body.js';
|
|
15
|
-
import { TokenManager } from './token-manager.js';
|
|
16
|
-
import { TokenProviderError } from './token-provider.js';
|
|
17
16
|
import { copyRequest } from './fetch-copy.js';
|
|
18
|
-
import { hasInvalidBearerChallenge } from './request-security.js';
|
|
19
17
|
import { withAbort, discardBody } from './util/abort.js';
|
|
20
|
-
export class HeaderTokenAuthorizingAdapter {
|
|
21
|
-
header = 'Authorization';
|
|
22
|
-
tokenHeaderType = 'Bearer';
|
|
23
|
-
applyToken(request, accessToken) {
|
|
24
|
-
const headers = new Headers(request.headers);
|
|
25
|
-
headers.set(this.header, `${this.tokenHeaderType} ${accessToken}`);
|
|
26
|
-
return copyRequest(request, { headers });
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
export class StaticHeaderTokenAuthorizingAdapter extends HeaderTokenAuthorizingAdapter {
|
|
30
|
-
accessToken;
|
|
31
|
-
constructor(accessToken) {
|
|
32
|
-
super();
|
|
33
|
-
this.accessToken = accessToken;
|
|
34
|
-
}
|
|
35
|
-
async adapt(request) {
|
|
36
|
-
return this.applyToken(request, this.accessToken);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
/** Optional caching authorization adapter; install its response capability explicitly for feedback. */
|
|
40
|
-
export class RefreshingHeaderTokenAuthorizingAdapter extends HeaderTokenAuthorizingAdapter {
|
|
41
|
-
manager;
|
|
42
|
-
tokens;
|
|
43
|
-
lease;
|
|
44
|
-
constructor(refresh) {
|
|
45
|
-
super();
|
|
46
|
-
this.manager = new TokenManager({
|
|
47
|
-
identity: 'header-token-adapter',
|
|
48
|
-
configure: () => ({ clientIdentity: 'header-token-adapter' }),
|
|
49
|
-
acquire: async (_request, signal) => {
|
|
50
|
-
try {
|
|
51
|
-
const authorization = await refresh(signal);
|
|
52
|
-
return {
|
|
53
|
-
accessToken: authorization.token,
|
|
54
|
-
expiresAt: authorization.expires.getTime(),
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
throw new RefreshFailure(error);
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
}, {
|
|
62
|
-
expirySkewMs: 0,
|
|
63
|
-
// One store slot, owned exclusively by this manager; no parallel adapter cache.
|
|
64
|
-
store: {
|
|
65
|
-
load: async () => this.tokens,
|
|
66
|
-
save: async (_key, tokens) => {
|
|
67
|
-
this.tokens = tokens;
|
|
68
|
-
},
|
|
69
|
-
remove: async () => {
|
|
70
|
-
this.tokens = undefined;
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
/** Reports the manager's current expiry state without starting a refresh. */
|
|
76
|
-
shouldRefresh() {
|
|
77
|
-
return !this.tokens || this.tokens.expiresAt <= Date.now();
|
|
78
|
-
}
|
|
79
|
-
async adapt(value, request) {
|
|
80
|
-
if (request) {
|
|
81
|
-
const response = value;
|
|
82
|
-
const lease = this.lease;
|
|
83
|
-
if (lease &&
|
|
84
|
-
response.status === 401 &&
|
|
85
|
-
hasInvalidBearerChallenge(response.headers.get('WWW-Authenticate') ?? '') &&
|
|
86
|
-
request.headers.get(this.header) ===
|
|
87
|
-
`${this.tokenHeaderType} ${lease.tokens.accessToken}`) {
|
|
88
|
-
await lease.invalidate?.();
|
|
89
|
-
}
|
|
90
|
-
return response;
|
|
91
|
-
}
|
|
92
|
-
request = value;
|
|
93
|
-
try {
|
|
94
|
-
const lease = await this.manager.credentials({
|
|
95
|
-
scheme: 'header-token',
|
|
96
|
-
provider: 'header-token',
|
|
97
|
-
flow: 'external',
|
|
98
|
-
scopes: [],
|
|
99
|
-
transport: {
|
|
100
|
-
location: 'header',
|
|
101
|
-
name: this.header,
|
|
102
|
-
prefix: this.tokenHeaderType,
|
|
103
|
-
},
|
|
104
|
-
}, request.signal);
|
|
105
|
-
request.signal.throwIfAborted();
|
|
106
|
-
this.lease = lease;
|
|
107
|
-
return this.applyToken(request, lease.tokens.accessToken);
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
if (error instanceof RefreshFailure)
|
|
111
|
-
throw error.cause;
|
|
112
|
-
throw error;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
// TokenManager sanitizes provider errors; this adapter retains its application-error contract.
|
|
117
|
-
class RefreshFailure extends TokenProviderError {
|
|
118
|
-
constructor(cause) {
|
|
119
|
-
super();
|
|
120
|
-
this.cause = cause;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
18
|
/** Flat, ordered composition; adapters may be ordinary objects with an adapt method. */
|
|
124
19
|
export class RequestAdapters {
|
|
125
20
|
adapters;
|
|
@@ -140,7 +35,9 @@ export async function adaptRequest(adapters, request, observeSignal = () => { })
|
|
|
140
35
|
try {
|
|
141
36
|
bodyReads(request);
|
|
142
37
|
for (const adapter of adapters) {
|
|
38
|
+
const original = request;
|
|
143
39
|
request = await withAbort(() => adapter.adapt(request), signal, discardBody);
|
|
40
|
+
inheritRequestContext(original, request);
|
|
144
41
|
if (request.signal !== signal)
|
|
145
42
|
request = copyRequest(request, {
|
|
146
43
|
signal: AbortSignal.any([signal, request.signal]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-adapters.js","sourceRoot":"","sources":["../src/request-adapters.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"request-adapters.js","sourceRoot":"","sources":["../src/request-adapters.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEzD,wFAAwF;AACxF,MAAM,OAAO,eAAe;IACjB,QAAQ,CAA4B;IAE7C,YAAY,GAAG,QAAmC;QAChD,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAC3B,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC3B,OAAO,YAAY,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAClE,CACF,CAAC;IACJ,CAAC;IAED,4DAA4D;IAC5D,OAAO,CAAC,GAAG,IAA+B;QACxC,OAAO,IAAI,eAAe,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAgB;QAC1B,OAAO,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;CACF;AAED,qGAAqG;AACrG,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAmC,EACnC,OAAgB,EAChB,gBAA+C,GAAG,EAAE,GAAE,CAAC;IAEvD,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC5B,IAAI,CAAC;QACH,SAAS,CAAC,OAAO,CAAC,CAAC;QACnB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC;YACzB,OAAO,GAAG,MAAM,SAAS,CACvB,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAC5B,MAAM,EACN,WAAW,CACZ,CAAC;YACF,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACzC,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;gBAC3B,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE;oBAC7B,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;iBAClD,CAAC,CAAC;YACL,SAAS,CAAC,OAAO,CAAC,CAAC;YACnB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YACxB,aAAa,CAAC,MAAM,CAAC,CAAC;YACtB,MAAM,CAAC,cAAc,EAAE,CAAC;QAC1B,CAAC;QACD,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,oBAAoB,CAClC,GAAG,QAAmC;IAEtC,OAAO,IAAI,eAAe,CAAC,GAAG,QAAQ,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Application-owned metadata retained across Sunday request copies and adapter replacements. */
|
|
2
|
+
export declare function requestContext(request: Request): Map<symbol, unknown>;
|
|
3
|
+
/** @internal Preserve metadata while allowing an adapter to replace its own entries. */
|
|
4
|
+
export declare function inheritRequestContext(source: Request, target: Request): Request;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
const contexts = new WeakMap();
|
|
15
|
+
/** Application-owned metadata retained across Sunday request copies and adapter replacements. */
|
|
16
|
+
export function requestContext(request) {
|
|
17
|
+
let context = contexts.get(request);
|
|
18
|
+
if (!context) {
|
|
19
|
+
context = new Map();
|
|
20
|
+
contexts.set(request, context);
|
|
21
|
+
}
|
|
22
|
+
return context;
|
|
23
|
+
}
|
|
24
|
+
/** @internal Preserve metadata while allowing an adapter to replace its own entries. */
|
|
25
|
+
export function inheritRequestContext(source, target) {
|
|
26
|
+
contexts.set(target, new Map([...requestContext(source), ...requestContext(target)]));
|
|
27
|
+
return target;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=request-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../src/request-context.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAiC,CAAC;AAE9D,iGAAiG;AACjG,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,IAAI,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QACpB,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,qBAAqB,CACnC,MAAe,EACf,MAAe;IAEf,QAAQ,CAAC,GAAG,CACV,MAAM,EACN,IAAI,GAAG,CAAC,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAChE,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import { RequestAdapter } from './request-adapter.js';
|
|
2
2
|
import { ResponseAdapter } from './response-adapter.js';
|
|
3
3
|
import { SecurityBinding } from './security-binding.js';
|
|
4
|
-
import { TokenProvider } from './token-provider.js';
|
|
5
4
|
/** @internal Shared configuration; receipts, cancellation, and retry state belong to each invocation. */
|
|
6
5
|
export declare class RequestExecution {
|
|
7
|
-
private readonly providers;
|
|
8
|
-
private readonly maxBufferedRequestBytes?;
|
|
9
6
|
private readonly requests;
|
|
10
7
|
private readonly responses;
|
|
11
|
-
constructor(
|
|
8
|
+
constructor(requestAdapter?: RequestAdapter, responseAdapter?: ResponseAdapter);
|
|
12
9
|
/** Materializes once; the consumer owns the resulting native request and its execution. */
|
|
13
10
|
export(request: Request, bindings: readonly SecurityBinding[]): Promise<Request>;
|
|
14
11
|
/** Executes one logical operation, including the caller's body consumption when provided. */
|
|
15
|
-
execute<T>(prepared: Request, bindings: readonly SecurityBinding[],
|
|
16
|
-
recovered: boolean;
|
|
17
|
-
}, consume: (response: Response, request: Request) => T | Promise<T>, observeSignal?: (signal: AbortSignal) => void): Promise<T>;
|
|
12
|
+
execute<T>(prepared: Request, bindings: readonly SecurityBinding[], consume: (response: Response, request: Request) => T | Promise<T>, observeSignal?: (signal: AbortSignal) => void): Promise<T>;
|
|
18
13
|
}
|
|
@@ -15,27 +15,22 @@ import { nativeFetch } from './util/native-fetch.js';
|
|
|
15
15
|
import { copyRequest } from './fetch-copy.js';
|
|
16
16
|
import { RequestAdapters, adaptRequest } from './request-adapters.js';
|
|
17
17
|
import { ResponseAdapters, adaptResponse } from './response-adapters.js';
|
|
18
|
+
import { setRequestSecurityBindings } from './request-security-bindings.js';
|
|
18
19
|
import { requestFailure } from './request-cancellation-error.js';
|
|
19
|
-
import { authorizeRequest, canRecoverAuthentication, isBodylessRequest, rejectCredentials, redactSecurityResponse, } from './request-security.js';
|
|
20
20
|
import { discardBody, withAbort } from './util/abort.js';
|
|
21
21
|
/** @internal Shared configuration; receipts, cancellation, and retry state belong to each invocation. */
|
|
22
22
|
export class RequestExecution {
|
|
23
|
-
providers;
|
|
24
|
-
maxBufferedRequestBytes;
|
|
25
23
|
requests;
|
|
26
24
|
responses;
|
|
27
|
-
constructor(
|
|
28
|
-
this.providers = providers;
|
|
29
|
-
this.maxBufferedRequestBytes = maxBufferedRequestBytes;
|
|
25
|
+
constructor(requestAdapter, responseAdapter) {
|
|
30
26
|
this.requests = new RequestAdapters(...(requestAdapter ? [requestAdapter] : []));
|
|
31
27
|
this.responses = new ResponseAdapters(...(responseAdapter ? [responseAdapter] : []));
|
|
32
28
|
}
|
|
33
29
|
/** Materializes once; the consumer owns the resulting native request and its execution. */
|
|
34
30
|
async export(request, bindings) {
|
|
35
31
|
try {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return await this.requests.adapt(request);
|
|
32
|
+
setRequestSecurityBindings(request, bindings);
|
|
33
|
+
return setRequestSecurityBindings(await this.requests.adapt(request), []);
|
|
39
34
|
}
|
|
40
35
|
catch (error) {
|
|
41
36
|
discardBody(request, error);
|
|
@@ -43,57 +38,34 @@ export class RequestExecution {
|
|
|
43
38
|
}
|
|
44
39
|
}
|
|
45
40
|
/** Executes one logical operation, including the caller's body consumption when provided. */
|
|
46
|
-
async execute(prepared, bindings,
|
|
41
|
+
async execute(prepared, bindings, consume, observeSignal = () => { }) {
|
|
47
42
|
const controller = new AbortController();
|
|
48
43
|
let signal = prepared.signal;
|
|
49
44
|
observeSignal(signal);
|
|
50
45
|
let sent = prepared;
|
|
51
46
|
let response;
|
|
52
47
|
try {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
sent
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
});
|
|
66
|
-
// Fetch does not expose intermediate redirect responses in browsers. Credentialed calls
|
|
67
|
-
// must return the redirect instead of forwarding credentials beyond their selected origin.
|
|
68
|
-
if (bindings.length ||
|
|
69
|
-
sent.headers.has('Authorization') ||
|
|
70
|
-
sent.headers.has('Cookie')) {
|
|
71
|
-
sent = copyRequest(sent, { redirect: 'manual', credentials: 'omit' });
|
|
72
|
-
}
|
|
73
|
-
const request = sent;
|
|
74
|
-
response = await withAbort(
|
|
75
|
-
// Keep cleanup cancellation separate from caller/adapter cancellation so an ordinary
|
|
76
|
-
// network failure remains eligible for the event source's reconnect policy.
|
|
77
|
-
() => nativeFetch(request, AbortSignal.any([request.signal, controller.signal])), request.signal, discardBody);
|
|
78
|
-
if (authorized) {
|
|
79
|
-
authorized = { ...authorized, request };
|
|
80
|
-
const original = response;
|
|
81
|
-
const receipts = authorized;
|
|
82
|
-
await withAbort(() => rejectCredentials(receipts, original), request.signal);
|
|
83
|
-
response = redactSecurityResponse(response, bindings);
|
|
84
|
-
}
|
|
85
|
-
response = await adaptResponse(this.responses.adapters, response, request, true);
|
|
86
|
-
if (!budget.recovered &&
|
|
87
|
-
isBodylessRequest(prepared) &&
|
|
88
|
-
canRecoverAuthentication(request, response)) {
|
|
89
|
-
budget.recovered = true;
|
|
90
|
-
discardBody(response);
|
|
91
|
-
response = undefined;
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
const accepted = response;
|
|
95
|
-
return await withAbort(() => consume(accepted, request), request.signal);
|
|
48
|
+
signal.throwIfAborted();
|
|
49
|
+
sent = setRequestSecurityBindings(copyRequest(prepared, { signal }), bindings);
|
|
50
|
+
sent = await adaptRequest(this.requests.adapters, sent, (effective) => {
|
|
51
|
+
signal = effective;
|
|
52
|
+
observeSignal(signal);
|
|
53
|
+
});
|
|
54
|
+
// Fetch does not expose intermediate redirect responses in browsers. Credentialed calls
|
|
55
|
+
// must return the redirect instead of forwarding credentials beyond their selected origin.
|
|
56
|
+
if (bindings.length ||
|
|
57
|
+
sent.headers.has('Authorization') ||
|
|
58
|
+
sent.headers.has('Cookie')) {
|
|
59
|
+
sent = copyRequest(sent, { redirect: 'manual', credentials: 'omit' });
|
|
96
60
|
}
|
|
61
|
+
const request = sent;
|
|
62
|
+
response = await withAbort(
|
|
63
|
+
// Keep cleanup cancellation separate from caller/adapter cancellation so an ordinary
|
|
64
|
+
// network failure remains eligible for the event source's reconnect policy.
|
|
65
|
+
() => nativeFetch(request, AbortSignal.any([request.signal, controller.signal])), request.signal, discardBody);
|
|
66
|
+
response = await adaptResponse(this.responses.adapters, response, request, true);
|
|
67
|
+
const accepted = response;
|
|
68
|
+
return await withAbort(() => consume(accepted, request), request.signal);
|
|
97
69
|
}
|
|
98
70
|
catch (error) {
|
|
99
71
|
const failure = requestFailure(error, signal);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-execution.js","sourceRoot":"","sources":["../src/request-execution.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"request-execution.js","sourceRoot":"","sources":["../src/request-execution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SecurityBinding } from './security-binding.js';
|
|
2
|
+
/** Returns operation security metadata for application-owned HTTP adapters, without token state. */
|
|
3
|
+
export declare function requestSecurityBindings(request: Request): readonly SecurityBinding[];
|
|
4
|
+
/** @internal Snapshots metadata without adding wire headers or credential receipts. */
|
|
5
|
+
export declare function setRequestSecurityBindings(request: Request, values: readonly SecurityBinding[]): Request;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { requestContext } from './request-context.js';
|
|
15
|
+
const bindings = Symbol('operationSecurityBindings');
|
|
16
|
+
const empty = Object.freeze([]);
|
|
17
|
+
/** Returns operation security metadata for application-owned HTTP adapters, without token state. */
|
|
18
|
+
export function requestSecurityBindings(request) {
|
|
19
|
+
return (requestContext(request).get(bindings) ?? empty);
|
|
20
|
+
}
|
|
21
|
+
/** @internal Snapshots metadata without adding wire headers or credential receipts. */
|
|
22
|
+
export function setRequestSecurityBindings(request, values) {
|
|
23
|
+
requestContext(request).set(bindings, Object.freeze(values.map((value) => Object.freeze({
|
|
24
|
+
...value,
|
|
25
|
+
scopes: Object.freeze([...value.scopes]),
|
|
26
|
+
transport: Object.freeze({ ...value.transport }),
|
|
27
|
+
}))));
|
|
28
|
+
return request;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=request-security-bindings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-security-bindings.js","sourceRoot":"","sources":["../src/request-security-bindings.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAIjC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,QAAQ,GAAG,MAAM,CAAC,2BAA2B,CAAC,CAAC;AACrD,MAAM,KAAK,GAA+B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAE5D,oGAAoG;AACpG,MAAM,UAAU,uBAAuB,CACrC,OAAgB;IAEhB,OAAO,CACJ,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAEvB,IAAI,KAAK,CACxB,CAAC;AACJ,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,0BAA0B,CACxC,OAAgB,EAChB,MAAkC;IAElC,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,CACzB,QAAQ,EACR,MAAM,CAAC,MAAM,CACX,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACnB,MAAM,CAAC,MAAM,CAAC;QACZ,GAAG,KAAK;QACR,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QACxC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;KACjD,CAAC,CACH,CACF,CACF,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC"}
|