@opentdf/sdk 0.13.0-beta.122 → 0.13.0-beta.124
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 +60 -10
- package/dist/cjs/src/access/access-rpc.js +6 -5
- package/dist/cjs/src/access.js +18 -5
- package/dist/cjs/src/auth/interceptors.js +186 -0
- package/dist/cjs/src/auth/token-providers.js +247 -0
- package/dist/cjs/src/index.js +10 -2
- package/dist/cjs/src/opentdf.js +40 -32
- package/dist/cjs/src/platform.js +3 -46
- package/dist/cjs/src/policy/api.js +9 -5
- package/dist/cjs/src/policy/discovery.js +10 -9
- package/dist/cjs/tdf3/src/client/index.js +35 -17
- package/dist/cjs/tdf3/src/tdf.js +8 -7
- package/dist/types/src/access/access-rpc.d.ts +3 -3
- package/dist/types/src/access/access-rpc.d.ts.map +1 -1
- package/dist/types/src/access.d.ts +3 -3
- package/dist/types/src/access.d.ts.map +1 -1
- package/dist/types/src/auth/interceptors.d.ts +99 -0
- package/dist/types/src/auth/interceptors.d.ts.map +1 -0
- package/dist/types/src/auth/token-providers.d.ts +100 -0
- package/dist/types/src/auth/token-providers.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/opentdf.d.ts +18 -15
- package/dist/types/src/opentdf.d.ts.map +1 -1
- package/dist/types/src/platform.d.ts +6 -3
- package/dist/types/src/platform.d.ts.map +1 -1
- package/dist/types/src/policy/api.d.ts +3 -3
- package/dist/types/src/policy/api.d.ts.map +1 -1
- package/dist/types/src/policy/discovery.d.ts +5 -5
- package/dist/types/src/policy/discovery.d.ts.map +1 -1
- package/dist/types/tdf3/src/client/index.d.ts +10 -1
- package/dist/types/tdf3/src/client/index.d.ts.map +1 -1
- package/dist/types/tdf3/src/tdf.d.ts +5 -2
- package/dist/types/tdf3/src/tdf.d.ts.map +1 -1
- package/dist/web/src/access/access-rpc.js +6 -5
- package/dist/web/src/access.js +18 -5
- package/dist/web/src/auth/interceptors.js +142 -0
- package/dist/web/src/auth/token-providers.js +242 -0
- package/dist/web/src/index.js +3 -1
- package/dist/web/src/opentdf.js +40 -32
- package/dist/web/src/platform.js +3 -46
- package/dist/web/src/policy/api.js +9 -5
- package/dist/web/src/policy/discovery.js +10 -9
- package/dist/web/tdf3/src/client/index.js +35 -17
- package/dist/web/tdf3/src/tdf.js +8 -7
- package/package.json +1 -1
- package/src/access/access-rpc.ts +5 -5
- package/src/access.ts +29 -13
- package/src/auth/interceptors.ts +197 -0
- package/src/auth/token-providers.ts +303 -0
- package/src/index.ts +18 -0
- package/src/opentdf.ts +54 -34
- package/src/platform.ts +8 -52
- package/src/policy/api.ts +8 -5
- package/src/policy/discovery.ts +9 -9
- package/tdf3/src/client/index.ts +46 -17
- package/tdf3/src/tdf.ts +14 -11
package/dist/web/src/access.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveAuthConfig } from './auth/interceptors.js';
|
|
1
2
|
import { getPlatformUrlFromKasEndpoint, validateSecureUrl } from './utils.js';
|
|
2
3
|
import { base64 } from './encodings/index.js';
|
|
3
4
|
import { fetchKasBasePubKey, fetchKeyAccessServers as fetchKeyAccessServersRpc, } from './access/access-rpc.js';
|
|
@@ -14,9 +15,16 @@ import { fetchKasPubKey as fetchKasPubKeyLegacy } from './access/access-fetch.js
|
|
|
14
15
|
* @param fulfillableObligationFQNs client-configured list of obligation value FQNs that can be fulfilled in this PEP
|
|
15
16
|
* @param clientVersion
|
|
16
17
|
*/
|
|
17
|
-
export async function fetchWrappedKey(url, signedRequestToken,
|
|
18
|
+
export async function fetchWrappedKey(url, signedRequestToken, auth, fulfillableObligationFQNs) {
|
|
18
19
|
const platformUrl = getPlatformUrlFromKasEndpoint(url);
|
|
19
|
-
|
|
20
|
+
const { interceptors, authProvider } = resolveAuthConfig(auth);
|
|
21
|
+
const rpcCall = () => fetchWrappedKeysRpc(platformUrl, signedRequestToken, { interceptors }, rewrapAdditionalContextHeader(fulfillableObligationFQNs));
|
|
22
|
+
// When no AuthProvider is available, skip the legacy fallback so the real
|
|
23
|
+
// RPC error propagates instead of being masked by tryPromisesUntilFirstSuccess.
|
|
24
|
+
if (!authProvider) {
|
|
25
|
+
return await rpcCall();
|
|
26
|
+
}
|
|
27
|
+
return await tryPromisesUntilFirstSuccess(rpcCall,
|
|
20
28
|
// We intentionally do not provide the rewrap additional context to legacy requests destined for older platforms.
|
|
21
29
|
// Platforms new enough to have knowledge of obligations will be handling RPC requests successfully.
|
|
22
30
|
() => fetchWrappedKeysLegacy(url, { signedRequestToken }, authProvider));
|
|
@@ -91,8 +99,13 @@ export const publicKeyAlgorithmToJwa = (a) => {
|
|
|
91
99
|
* @param authProvider The authentication provider to use for the request.
|
|
92
100
|
* @returns A promise that resolves to an OriginAllowList.
|
|
93
101
|
*/
|
|
94
|
-
export async function fetchKeyAccessServers(platformUrl,
|
|
95
|
-
|
|
102
|
+
export async function fetchKeyAccessServers(platformUrl, auth) {
|
|
103
|
+
const { interceptors, authProvider } = resolveAuthConfig(auth);
|
|
104
|
+
const rpcCall = () => fetchKeyAccessServersRpc(platformUrl, { interceptors });
|
|
105
|
+
if (!authProvider) {
|
|
106
|
+
return await rpcCall();
|
|
107
|
+
}
|
|
108
|
+
return await tryPromisesUntilFirstSuccess(rpcCall, () => fetchKeyAccessServersLegacy(platformUrl, authProvider));
|
|
96
109
|
}
|
|
97
110
|
/**
|
|
98
111
|
* Fetch the EC (secp256r1) public key for a KAS endpoint.
|
|
@@ -172,4 +185,4 @@ async function tryPromisesUntilFirstSuccess(first, second) {
|
|
|
172
185
|
}
|
|
173
186
|
}
|
|
174
187
|
}
|
|
175
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
188
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FjY2Vzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQW1CLGlCQUFpQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFNUUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLGlCQUFpQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzlFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUU5QyxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLHFCQUFxQixJQUFJLHdCQUF3QixHQUNsRCxNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFBRSxxQkFBcUIsSUFBSSwyQkFBMkIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hHLE9BQU8sRUFBRSxlQUFlLElBQUksbUJBQW1CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRixPQUFPLEVBQUUsZUFBZSxJQUFJLHNCQUFzQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckYsT0FBTyxFQUFFLGNBQWMsSUFBSSxpQkFBaUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdFLE9BQU8sRUFBRSxjQUFjLElBQUksb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQWVsRjs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxlQUFlLENBQ25DLEdBQVcsRUFDWCxrQkFBMEIsRUFDMUIsSUFBZ0IsRUFDaEIseUJBQW1DO0lBRW5DLE1BQU0sV0FBVyxHQUFHLDZCQUE2QixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFL0QsTUFBTSxPQUFPLEdBQUcsR0FBRyxFQUFFLENBQ25CLG1CQUFtQixDQUNqQixXQUFXLEVBQ1gsa0JBQWtCLEVBQ2xCLEVBQUUsWUFBWSxFQUFFLEVB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
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import * as DefaultCryptoService from '../../tdf3/src/crypto/index.js';
|
|
2
|
+
import DPoP from './dpop.js';
|
|
3
|
+
import { base64 } from '../encodings/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a simple bearer-token interceptor.
|
|
6
|
+
* Calls `tokenProvider()` per-request and sets the `Authorization` header.
|
|
7
|
+
*
|
|
8
|
+
* @param tokenProvider Function returning a valid access token.
|
|
9
|
+
* @returns A Connect RPC Interceptor.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const opentdf = new OpenTDF({
|
|
14
|
+
* interceptors: [authTokenInterceptor(() => myAuth.getAccessToken())],
|
|
15
|
+
* platformUrl: '/api',
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export function authTokenInterceptor(tokenProvider) {
|
|
20
|
+
return (next) => async (req) => {
|
|
21
|
+
const token = await tokenProvider();
|
|
22
|
+
req.header.set('Authorization', `Bearer ${token}`);
|
|
23
|
+
return next(req);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Creates a DPoP-aware auth interceptor.
|
|
28
|
+
* Per-request: gets token, generates DPoP proof JWT, sets Authorization + DPoP + X-VirtruPubKey headers.
|
|
29
|
+
* Exposes `dpopKeys` for TDF request body signing.
|
|
30
|
+
*
|
|
31
|
+
* @param options DPoP interceptor configuration.
|
|
32
|
+
* @returns A DPoP interceptor with an exposed `dpopKeys` promise.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const dpopInterceptor = authTokenDPoPInterceptor({
|
|
37
|
+
* tokenProvider: () => myAuth.getAccessToken(),
|
|
38
|
+
* });
|
|
39
|
+
* const opentdf = new OpenTDF({
|
|
40
|
+
* interceptors: [dpopInterceptor],
|
|
41
|
+
* dpopKeys: dpopInterceptor.dpopKeys,
|
|
42
|
+
* platformUrl: '/api',
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export function authTokenDPoPInterceptor(options) {
|
|
47
|
+
const cryptoService = options.cryptoService ?? DefaultCryptoService;
|
|
48
|
+
const dpopKeysPromise = options.dpopKeys
|
|
49
|
+
? Promise.resolve(options.dpopKeys)
|
|
50
|
+
: cryptoService.generateSigningKeyPair();
|
|
51
|
+
const interceptor = (next) => async (req) => {
|
|
52
|
+
const [token, keys] = await Promise.all([options.tokenProvider(), dpopKeysPromise]);
|
|
53
|
+
const url = new URL(req.url);
|
|
54
|
+
const httpUri = `${url.origin}${url.pathname}`;
|
|
55
|
+
// Generate DPoP proof JWT for this request
|
|
56
|
+
const dpopProof = await DPoP(keys, cryptoService, httpUri, 'POST');
|
|
57
|
+
// Export public key PEM for X-VirtruPubKey header
|
|
58
|
+
const publicKeyPem = await cryptoService.exportPublicKeyPem(keys.publicKey);
|
|
59
|
+
req.header.set('Authorization', `Bearer ${token}`);
|
|
60
|
+
req.header.set('DPoP', dpopProof);
|
|
61
|
+
req.header.set('X-VirtruPubKey', base64.encode(publicKeyPem));
|
|
62
|
+
return next(req);
|
|
63
|
+
};
|
|
64
|
+
// Attach dpopKeys to the interceptor function
|
|
65
|
+
const dpopInterceptor = interceptor;
|
|
66
|
+
Object.defineProperty(dpopInterceptor, 'dpopKeys', {
|
|
67
|
+
value: dpopKeysPromise,
|
|
68
|
+
writable: false,
|
|
69
|
+
enumerable: true,
|
|
70
|
+
});
|
|
71
|
+
return dpopInterceptor;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Creates an interceptor that bridges an existing AuthProvider to the Interceptor pattern.
|
|
75
|
+
* Use this for backwards compatibility when migrating from AuthProvider to interceptors.
|
|
76
|
+
*
|
|
77
|
+
* @param authProvider The legacy AuthProvider to bridge.
|
|
78
|
+
* @returns A Connect RPC Interceptor.
|
|
79
|
+
*/
|
|
80
|
+
export function authProviderInterceptor(authProvider) {
|
|
81
|
+
return (next) => async (req) => {
|
|
82
|
+
const url = new URL(req.url);
|
|
83
|
+
const pathOnly = url.pathname;
|
|
84
|
+
// Signs only the path of the url in the request
|
|
85
|
+
let token;
|
|
86
|
+
try {
|
|
87
|
+
token = await authProvider.withCreds({
|
|
88
|
+
url: pathOnly,
|
|
89
|
+
method: 'POST',
|
|
90
|
+
// Start with any headers Connect already has
|
|
91
|
+
headers: {
|
|
92
|
+
...Object.fromEntries(req.header.entries()),
|
|
93
|
+
'Content-Type': 'application/json',
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
99
|
+
if (msg.includes('public key') || msg.includes('updateClientPublicKey')) {
|
|
100
|
+
throw new Error('PlatformClient: DPoP key binding is not complete. ' +
|
|
101
|
+
'If you are using OpenTDF with PlatformClient, create OpenTDF first and ' +
|
|
102
|
+
'`await client.ready` before constructing PlatformClient. ' +
|
|
103
|
+
`Original error: ${msg}`);
|
|
104
|
+
}
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
Object.entries(token.headers).forEach(([key, value]) => {
|
|
108
|
+
req.header.set(key, value);
|
|
109
|
+
});
|
|
110
|
+
return await next(req);
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Type guard for AuthConfig with interceptors.
|
|
115
|
+
*/
|
|
116
|
+
export function isInterceptorConfig(auth) {
|
|
117
|
+
return 'interceptors' in auth && Array.isArray(auth.interceptors);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Resolves an AuthConfig into interceptors for use with PlatformClient.
|
|
121
|
+
* If the config is an AuthProvider, it is bridged via authProviderInterceptor.
|
|
122
|
+
*/
|
|
123
|
+
export function resolveInterceptors(auth) {
|
|
124
|
+
if (isInterceptorConfig(auth)) {
|
|
125
|
+
return auth.interceptors;
|
|
126
|
+
}
|
|
127
|
+
return [authProviderInterceptor(auth)];
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Resolves an AuthConfig into both interceptors and an optional AuthProvider.
|
|
131
|
+
* The AuthProvider is available for legacy code paths that need withCreds().
|
|
132
|
+
*/
|
|
133
|
+
export function resolveAuthConfig(auth) {
|
|
134
|
+
if (isInterceptorConfig(auth)) {
|
|
135
|
+
return { interceptors: auth.interceptors };
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
interceptors: [authProviderInterceptor(auth)],
|
|
139
|
+
authProvider: auth,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJjZXB0b3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2F1dGgvaW50ZXJjZXB0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sS0FBSyxvQkFBb0IsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN2RSxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFFN0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBNkIvQzs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxhQUE0QjtJQUMvRCxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUU7UUFDN0IsTUFBTSxLQUFLLEdBQUcsTUFBTSxhQUFhLEVBQUUsQ0FBQztRQUNwQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxlQUFlLEVBQUUsVUFBVSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ25ELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ25CLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sVUFBVSx3QkFBd0IsQ0FBQyxPQUErQjtJQUN0RSxNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsYUFBYSxJQUFJLG9CQUFvQixDQUFDO0lBQ3BFLE1BQU0sZUFBZSxHQUFxQixPQUFPLENBQUMsUUFBUTtRQUN4RCxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ25DLENBQUMsQ0FBQyxhQUFhLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztJQUUzQyxNQUFNLFdBQVcsR0FBZ0IsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUN2RCxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLE1B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
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { ConfigurationError, TdfError } from '../errors.js';
|
|
2
|
+
import { rstrip } from '../utils.js';
|
|
3
|
+
function resolveTokenEndpoint(oidcOrigin, override) {
|
|
4
|
+
if (override?.trim())
|
|
5
|
+
return override;
|
|
6
|
+
const base = oidcOrigin?.trim();
|
|
7
|
+
if (!base) {
|
|
8
|
+
throw new ConfigurationError('oidcOrigin or oidcTokenEndpoint is required');
|
|
9
|
+
}
|
|
10
|
+
return `${rstrip(base, '/')}/protocol/openid-connect/token`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Decode a JWT's exp claim without verifying the signature.
|
|
14
|
+
* Returns the expiration time in seconds since epoch, or undefined if not present.
|
|
15
|
+
*/
|
|
16
|
+
function getJwtExpiration(token) {
|
|
17
|
+
try {
|
|
18
|
+
const parts = token.split('.');
|
|
19
|
+
if (parts.length !== 3)
|
|
20
|
+
return undefined;
|
|
21
|
+
// Base64url decode the payload
|
|
22
|
+
const payload = parts[1].replace(/-/g, '+').replace(/_/g, '/');
|
|
23
|
+
const padded = payload + '='.repeat((4 - (payload.length % 4)) % 4);
|
|
24
|
+
const decoded = JSON.parse(atob(padded));
|
|
25
|
+
return typeof decoded.exp === 'number' ? decoded.exp : undefined;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Compute the absolute expiry (seconds since epoch) for a token response.
|
|
33
|
+
* Prefers `expires_in` from the token response, falls back to the JWT `exp` claim.
|
|
34
|
+
*/
|
|
35
|
+
function resolveTokenExpiry(accessToken, expiresIn) {
|
|
36
|
+
if (typeof expiresIn === 'number') {
|
|
37
|
+
return Date.now() / 1000 + expiresIn;
|
|
38
|
+
}
|
|
39
|
+
return getJwtExpiration(accessToken);
|
|
40
|
+
}
|
|
41
|
+
function isTokenExpired(expiry, bufferSeconds = 30) {
|
|
42
|
+
if (expiry === undefined)
|
|
43
|
+
return true;
|
|
44
|
+
return Date.now() / 1000 >= expiry - bufferSeconds;
|
|
45
|
+
}
|
|
46
|
+
async function fetchToken(tokenEndpoint, body) {
|
|
47
|
+
const response = await fetch(tokenEndpoint, {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
headers: {
|
|
50
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
51
|
+
Accept: 'application/json',
|
|
52
|
+
},
|
|
53
|
+
body: new URLSearchParams(body).toString(),
|
|
54
|
+
});
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
const text = await response.text();
|
|
57
|
+
throw new TdfError(`Token request failed: POST [${tokenEndpoint}] => ${response.status} ${response.statusText}: ${text}`);
|
|
58
|
+
}
|
|
59
|
+
return (await response.json());
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Creates a TokenProvider that obtains tokens via the OAuth2 client credentials grant.
|
|
63
|
+
* Tokens are cached and automatically refreshed when expired.
|
|
64
|
+
*
|
|
65
|
+
* **Not for browser use.** Client secrets must not be exposed in client-side code.
|
|
66
|
+
* Use this only in server-side (Node.js/Deno) environments.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const client = new OpenTDF({
|
|
71
|
+
* interceptors: [authTokenInterceptor(clientCredentialsTokenProvider({
|
|
72
|
+
* clientId: 'opentdf',
|
|
73
|
+
* clientSecret: 'secret',
|
|
74
|
+
* oidcOrigin: 'http://localhost:8080/auth/realms/opentdf',
|
|
75
|
+
* }))],
|
|
76
|
+
* platformUrl: 'http://localhost:8080',
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export function clientCredentialsTokenProvider(options) {
|
|
81
|
+
if (!options.clientId || !options.clientSecret) {
|
|
82
|
+
throw new ConfigurationError('clientId and clientSecret are required');
|
|
83
|
+
}
|
|
84
|
+
const tokenEndpoint = resolveTokenEndpoint(options.oidcOrigin, options.oidcTokenEndpoint);
|
|
85
|
+
let cachedToken;
|
|
86
|
+
let cachedExpiry;
|
|
87
|
+
let inFlight;
|
|
88
|
+
return async () => {
|
|
89
|
+
if (cachedToken && !isTokenExpired(cachedExpiry)) {
|
|
90
|
+
return cachedToken;
|
|
91
|
+
}
|
|
92
|
+
if (!inFlight) {
|
|
93
|
+
inFlight = (async () => {
|
|
94
|
+
try {
|
|
95
|
+
const resp = await fetchToken(tokenEndpoint, {
|
|
96
|
+
grant_type: 'client_credentials',
|
|
97
|
+
client_id: options.clientId,
|
|
98
|
+
client_secret: options.clientSecret,
|
|
99
|
+
});
|
|
100
|
+
cachedToken = resp.access_token;
|
|
101
|
+
cachedExpiry = resolveTokenExpiry(resp.access_token, resp.expires_in);
|
|
102
|
+
return cachedToken;
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
inFlight = undefined;
|
|
106
|
+
}
|
|
107
|
+
})();
|
|
108
|
+
}
|
|
109
|
+
return inFlight;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Creates a TokenProvider that uses a refresh token to obtain access tokens.
|
|
114
|
+
* On the first call, exchanges the refresh token. Subsequent calls use the
|
|
115
|
+
* latest refresh token from the IdP response.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* const client = new OpenTDF({
|
|
120
|
+
* interceptors: [authTokenInterceptor(refreshTokenProvider({
|
|
121
|
+
* clientId: 'my-app',
|
|
122
|
+
* refreshToken: 'refresh-token-from-login',
|
|
123
|
+
* oidcOrigin: 'http://localhost:8080/auth/realms/opentdf',
|
|
124
|
+
* }))],
|
|
125
|
+
* platformUrl: 'http://localhost:8080',
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export function refreshTokenProvider(options) {
|
|
130
|
+
if (!options.clientId || !options.refreshToken) {
|
|
131
|
+
throw new ConfigurationError('clientId and refreshToken are required');
|
|
132
|
+
}
|
|
133
|
+
const tokenEndpoint = resolveTokenEndpoint(options.oidcOrigin, options.oidcTokenEndpoint);
|
|
134
|
+
let currentRefreshToken = options.refreshToken;
|
|
135
|
+
let cachedToken;
|
|
136
|
+
let cachedExpiry;
|
|
137
|
+
let inFlight;
|
|
138
|
+
return async () => {
|
|
139
|
+
if (cachedToken && !isTokenExpired(cachedExpiry)) {
|
|
140
|
+
return cachedToken;
|
|
141
|
+
}
|
|
142
|
+
if (!inFlight) {
|
|
143
|
+
inFlight = (async () => {
|
|
144
|
+
try {
|
|
145
|
+
const resp = await fetchToken(tokenEndpoint, {
|
|
146
|
+
grant_type: 'refresh_token',
|
|
147
|
+
refresh_token: currentRefreshToken,
|
|
148
|
+
client_id: options.clientId,
|
|
149
|
+
});
|
|
150
|
+
cachedToken = resp.access_token;
|
|
151
|
+
cachedExpiry = resolveTokenExpiry(resp.access_token, resp.expires_in);
|
|
152
|
+
if (resp.refresh_token) {
|
|
153
|
+
currentRefreshToken = resp.refresh_token;
|
|
154
|
+
}
|
|
155
|
+
return cachedToken;
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
inFlight = undefined;
|
|
159
|
+
}
|
|
160
|
+
})();
|
|
161
|
+
}
|
|
162
|
+
return inFlight;
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Creates a TokenProvider that exchanges an external JWT for a platform token
|
|
167
|
+
* via RFC 8693 token exchange. After the initial exchange, uses the refresh
|
|
168
|
+
* token for subsequent calls.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* const client = new OpenTDF({
|
|
173
|
+
* interceptors: [authTokenInterceptor(externalJwtTokenProvider({
|
|
174
|
+
* clientId: 'my-app',
|
|
175
|
+
* externalJwt: 'eyJhbGciOi...',
|
|
176
|
+
* oidcOrigin: 'http://localhost:8080/auth/realms/opentdf',
|
|
177
|
+
* }))],
|
|
178
|
+
* platformUrl: 'http://localhost:8080',
|
|
179
|
+
* });
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export function externalJwtTokenProvider(options) {
|
|
183
|
+
if (!options.clientId || !options.externalJwt) {
|
|
184
|
+
throw new ConfigurationError('clientId and externalJwt are required');
|
|
185
|
+
}
|
|
186
|
+
const tokenEndpoint = resolveTokenEndpoint(options.oidcOrigin, options.oidcTokenEndpoint);
|
|
187
|
+
let cachedToken;
|
|
188
|
+
let cachedExpiry;
|
|
189
|
+
let currentRefreshToken;
|
|
190
|
+
let initialExchangeDone = false;
|
|
191
|
+
let inFlight;
|
|
192
|
+
return async () => {
|
|
193
|
+
if (cachedToken && !isTokenExpired(cachedExpiry)) {
|
|
194
|
+
return cachedToken;
|
|
195
|
+
}
|
|
196
|
+
if (!inFlight) {
|
|
197
|
+
inFlight = (async () => {
|
|
198
|
+
try {
|
|
199
|
+
let resp;
|
|
200
|
+
if (!initialExchangeDone) {
|
|
201
|
+
resp = await fetchToken(tokenEndpoint, {
|
|
202
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
|
|
203
|
+
subject_token: options.externalJwt,
|
|
204
|
+
subject_token_type: 'urn:ietf:params:oauth:token-type:jwt',
|
|
205
|
+
audience: options.clientId,
|
|
206
|
+
client_id: options.clientId,
|
|
207
|
+
});
|
|
208
|
+
initialExchangeDone = true;
|
|
209
|
+
}
|
|
210
|
+
else if (currentRefreshToken) {
|
|
211
|
+
resp = await fetchToken(tokenEndpoint, {
|
|
212
|
+
grant_type: 'refresh_token',
|
|
213
|
+
refresh_token: currentRefreshToken,
|
|
214
|
+
client_id: options.clientId,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
// Re-exchange the original JWT if no refresh token available
|
|
219
|
+
resp = await fetchToken(tokenEndpoint, {
|
|
220
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
|
|
221
|
+
subject_token: options.externalJwt,
|
|
222
|
+
subject_token_type: 'urn:ietf:params:oauth:token-type:jwt',
|
|
223
|
+
audience: options.clientId,
|
|
224
|
+
client_id: options.clientId,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
cachedToken = resp.access_token;
|
|
228
|
+
cachedExpiry = resolveTokenExpiry(resp.access_token, resp.expires_in);
|
|
229
|
+
if (resp.refresh_token) {
|
|
230
|
+
currentRefreshToken = resp.refresh_token;
|
|
231
|
+
}
|
|
232
|
+
return cachedToken;
|
|
233
|
+
}
|
|
234
|
+
finally {
|
|
235
|
+
inFlight = undefined;
|
|
236
|
+
}
|
|
237
|
+
})();
|
|
238
|
+
}
|
|
239
|
+
return inFlight;
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tcHJvdmlkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2F1dGgvdG9rZW4tcHJvdmlkZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxRQUFRLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDNUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQXFEckMsU0FBUyxvQkFBb0IsQ0FBQyxVQUFrQixFQUFFLFFBQWlCO0lBQ2pFLElBQUksUUFBUSxFQUFFLElBQUksRUFBRTtRQUFFLE9BQU8sUUFBUSxDQUFDO0lBQ3RDLE1BQU0sSUFBSSxHQUFHLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUNoQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVixNQUFNLElBQUksa0JBQWtCLENBQUMsNkNBQTZDLENBQUMsQ0FBQztJQUM5RSxDQUFDO0lBQ0QsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLGdDQUFnQyxDQUFDO0FBQzlELENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLGdCQUFnQixDQUFDLEtBQWE7SUFDckMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQixJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU8sU0FBUyxDQUFDO1FBQ3pDLCtCQUErQjtRQUMvQixNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sTUFBTSxHQUFHLE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0s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
|
package/dist/web/src/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { HttpRequest, withHeaders } from './auth/auth.js';
|
|
2
2
|
export * as AuthProviders from './auth/providers.js';
|
|
3
|
+
export { authTokenInterceptor, authTokenDPoPInterceptor, authProviderInterceptor, } from './auth/interceptors.js';
|
|
4
|
+
export { clientCredentialsTokenProvider, refreshTokenProvider, externalJwtTokenProvider, } from './auth/token-providers.js';
|
|
3
5
|
export { attributeFQNsAsValues } from './policy/api.js';
|
|
4
6
|
export { listAttributes, validateAttributes, attributeExists, attributeValueExists, } from './policy/discovery.js';
|
|
5
7
|
export { version, clientType, tdfSpecVersion } from './version.js';
|
|
@@ -8,4 +10,4 @@ export * from './opentdf.js';
|
|
|
8
10
|
export { TdfError, PermissionDeniedError, IntegrityError, InvalidFileError, DecryptError, NetworkError, AttributeValidationError, AttributeNotFoundError, ConfigurationError, } from './errors.js';
|
|
9
11
|
export * from './seekable.js';
|
|
10
12
|
export * from '../tdf3/src/models/index.js';
|
|
11
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFzQyxXQUFXLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUYsT0FBTyxLQUFLLGFBQWEsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLHdCQUF3QixFQUN4Qix1QkFBdUIsR0FNeEIsTUFBTSx3QkFBd0IsQ0FBQztBQUNoQyxPQUFPLEVBQ0wsOEJBQThCLEVBQzlCLG9CQUFvQixFQUNwQix3QkFBd0IsR0FJekIsTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RCxPQUFPLEVBQ0wsY0FBYyxFQUNkLGtCQUFrQixFQUNsQixlQUFlLEVBQ2Ysb0JBQW9CLEdBQ3JCLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxjQUFjLEVBQXFELE1BQU0sZUFBZSxDQUFDO0FBQ2xHLGNBQWMsY0FBYyxDQUFDO0FBQzdCLE9BQU8sRUFDTCxRQUFRLEVBQ1IscUJBQXFCLEVBQ3JCLGNBQWMsRUFDZCxnQkFBZ0IsRUFDaEIsWUFBWSxFQUNaLFlBQVksRUFDWix3QkFBd0IsRUFDeEIsc0JBQXNCLEVBQ3RCLGtCQUFrQixHQUNuQixNQUFNLGFBQWEsQ0FBQztBQUNyQixjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLDZCQUE2QixDQUFDIn0=
|