@trimble-oss/trimble-id-react 1.0.0 → 1.0.1
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 +26 -2
- package/dist/TIDClient/TIDClient.d.ts +24 -1
- package/dist/TIDClient/constants.d.ts +6 -0
- package/dist/TIDClient/exceptions.d.ts +3 -0
- package/dist/TIDClient/interfaces.d.ts +11 -0
- package/dist/TIDClient/storage/cookies/CookiesManager.d.ts +16 -2
- package/dist/index.d.ts +1 -1
- package/dist/trimble-id-react.es.js +241 -159
- package/dist/trimble-id-react.umd.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ process related to the authentication for you. Configure the SDK by wrapping you
|
|
|
67
67
|
|
|
68
68
|
Here TIDProvider can take two parameters :
|
|
69
69
|
* **tidClient** : TID client instance. You can send an instance of the TID Client if you want to handle the initialization yourself
|
|
70
|
-
* **onRedirectCallback** - When the redirect callback occur this function will be call once the user is login using the TIDClient. This
|
|
70
|
+
* **onRedirectCallback** - When the redirect callback occur this function will be call once the user is login using the TIDClient. This function receives an `authState` parameter that contains a `redirectTo` property with the user's original location before authentication, allowing you to redirect the user back to their intended destination after login.
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
After wrapping your app with the TIDProvider, you have to configure the TID credentials registered in TrimbleCloud console. There are two ways of doing this:
|
|
@@ -102,6 +102,15 @@ After wrapping your app with the TIDProvider, you have to configure the TID cred
|
|
|
102
102
|
</TIDProvider>
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
+
```tsx
|
|
106
|
+
const handleRedirect = (authState) => {
|
|
107
|
+
// Use redirectTo for automatic redirection to original location
|
|
108
|
+
const redirectTo = authState.redirectTo || '/dashboard'
|
|
109
|
+
// Navigate to the intended destination
|
|
110
|
+
navigate(redirectTo)
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
105
114
|
Below are the parameters of TIDClient.
|
|
106
115
|
### 1. TID Client configurations:
|
|
107
116
|
|
|
@@ -131,6 +140,21 @@ const {logout}= useAuth()
|
|
|
131
140
|
await logout()
|
|
132
141
|
```
|
|
133
142
|
|
|
143
|
+
### handleCallback
|
|
144
|
+
|
|
145
|
+
Handle OAuth callback to complete user authentication and returns the auth state with redirect path.
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
const { handleCallback } = useAuth()
|
|
149
|
+
|
|
150
|
+
// Handle callback and get redirect information
|
|
151
|
+
const authState = await handleCallback()
|
|
152
|
+
|
|
153
|
+
// Use redirectTo for automatic redirection to original location
|
|
154
|
+
const redirectTo = authState.redirectTo || '/dashboard'
|
|
155
|
+
navigate(redirectTo)
|
|
156
|
+
```
|
|
157
|
+
|
|
134
158
|
### isAuthenticated
|
|
135
159
|
|
|
136
160
|
True if the user is authenticated.
|
|
@@ -198,7 +222,7 @@ See here for [Sample Code](https://github.com/trimble-oss/trimble-id-sdk-docs-fo
|
|
|
198
222
|
|
|
199
223
|
## Release notes
|
|
200
224
|
|
|
201
|
-
See here for [releases](
|
|
225
|
+
See here for [releases](https://github.com/trimble-oss/trimble-id-sdk-docs-for-react/blob/main/release-notes/CHANGELOG.md)
|
|
202
226
|
|
|
203
227
|
## Raise an issue
|
|
204
228
|
|
|
@@ -100,6 +100,10 @@ export declare class TIDClient {
|
|
|
100
100
|
* @param {CacheManagerOptions} props - TID client configuration
|
|
101
101
|
*/
|
|
102
102
|
constructor(props: TIDClientOptions);
|
|
103
|
+
/**
|
|
104
|
+
* Clean up expired state payloads to prevent storage bloat
|
|
105
|
+
*/
|
|
106
|
+
private cleanupExpiredState;
|
|
103
107
|
/**
|
|
104
108
|
* Redirect the user to TID using the browser
|
|
105
109
|
* @param {LoginWithRedirectOptions} options - Custom configuration for the redirection
|
|
@@ -107,6 +111,7 @@ export declare class TIDClient {
|
|
|
107
111
|
* @example No configuration
|
|
108
112
|
* loginWithRedirect()
|
|
109
113
|
* // Automatically redirects the user to TID with all necessary parameters
|
|
114
|
+
* // After authentication, user will be redirected back to the current page
|
|
110
115
|
* @example Custom redirect
|
|
111
116
|
* loginWithRedirect({onRedirect: (url) => router.navigate(url)})
|
|
112
117
|
* // Redirect calls onRedirect with the log-out url for TID
|
|
@@ -116,8 +121,9 @@ export declare class TIDClient {
|
|
|
116
121
|
/**
|
|
117
122
|
* Authenticated the user using the url callback params
|
|
118
123
|
* @param {string} url - Custom configuration for the redirection
|
|
119
|
-
* @return {Promise<AuthState>} Object contain the state returned from TID
|
|
124
|
+
* @return {Promise<AuthState>} Object contain the state returned from TID and redirect path
|
|
120
125
|
* @throws {CodeVerifierNotFoundException} Will throw an exception if the session doesn't contain the code verifier
|
|
126
|
+
* @throws {Error} Will throw an exception if state validation fails or replay attack is detected
|
|
121
127
|
* @example No configuration
|
|
122
128
|
* handleCallback()
|
|
123
129
|
* // Will automatically take the url from the browser and try to log in the user
|
|
@@ -133,6 +139,23 @@ export declare class TIDClient {
|
|
|
133
139
|
*/
|
|
134
140
|
private generateToken;
|
|
135
141
|
private reloadCodeVerifier;
|
|
142
|
+
/**
|
|
143
|
+
* Create and encode state payload for replay attack protection
|
|
144
|
+
* @param {string} redirectTo - Path to redirect to after authentication
|
|
145
|
+
* @return {string} - Base64 encoded state payload
|
|
146
|
+
*/
|
|
147
|
+
private createStatePayload;
|
|
148
|
+
/**
|
|
149
|
+
* Generate a random nonce for state validation
|
|
150
|
+
* @return {string} - Random nonce
|
|
151
|
+
*/
|
|
152
|
+
private generateNonce;
|
|
153
|
+
/**
|
|
154
|
+
* Validate state payload to prevent replay attacks
|
|
155
|
+
* @param {string} receivedState - State received from OAuth callback
|
|
156
|
+
* @return {StateValidationResult} - Validation result with redirect path if valid
|
|
157
|
+
*/
|
|
158
|
+
private validateStatePayload;
|
|
136
159
|
/**
|
|
137
160
|
* Return the user stored in cache
|
|
138
161
|
* @return {Promise<TIDUser | undefined>} User in cache
|
|
@@ -8,3 +8,9 @@ export declare const CLOCK_SKEW_TIME: number;
|
|
|
8
8
|
* @type {Array<string>}
|
|
9
9
|
*/
|
|
10
10
|
export declare const LIST_PARAMS_REQUIRED: Array<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Maximum time allowed for state parameter to be valid (10 minutes)
|
|
13
|
+
* Used to prevent replay attacks
|
|
14
|
+
* @type {number}
|
|
15
|
+
*/
|
|
16
|
+
export declare const STATE_EXPIRATION_TIME: number;
|
|
@@ -6,3 +6,6 @@ export declare class TokenNotFoundException extends Error {
|
|
|
6
6
|
}
|
|
7
7
|
export declare class CodeVerifierNotFoundException extends Error {
|
|
8
8
|
}
|
|
9
|
+
/** Class representing an OAuth state validation exception for CSRF protection */
|
|
10
|
+
export declare class StateValidationException extends Error {
|
|
11
|
+
}
|
|
@@ -175,4 +175,15 @@ export interface TIDJWTUser {
|
|
|
175
175
|
}
|
|
176
176
|
export interface AuthState {
|
|
177
177
|
authState: any;
|
|
178
|
+
returnTo?: string;
|
|
179
|
+
}
|
|
180
|
+
export interface StatePayload {
|
|
181
|
+
redirectTo: string;
|
|
182
|
+
timestamp: number;
|
|
183
|
+
nonce: string;
|
|
184
|
+
}
|
|
185
|
+
export interface StateValidationResult {
|
|
186
|
+
isValid: boolean;
|
|
187
|
+
redirectTo?: string;
|
|
188
|
+
error?: string;
|
|
178
189
|
}
|
|
@@ -12,6 +12,11 @@ interface CookieValue {
|
|
|
12
12
|
* @type {string}
|
|
13
13
|
*/
|
|
14
14
|
code_verifier: string;
|
|
15
|
+
/**
|
|
16
|
+
* State information used for replay attack protection
|
|
17
|
+
* @type {string}
|
|
18
|
+
*/
|
|
19
|
+
state_payload?: string;
|
|
15
20
|
}
|
|
16
21
|
/** Class to manage cookies */
|
|
17
22
|
export declare class CookiesManager {
|
|
@@ -32,9 +37,18 @@ export declare class CookiesManager {
|
|
|
32
37
|
constructor(options: CookiesManagerOptions);
|
|
33
38
|
/**
|
|
34
39
|
* Store cookies in the browser
|
|
35
|
-
* @param {CookieValue} value - information to store
|
|
40
|
+
* @param {Partial<CookieValue>} value - information to store
|
|
41
|
+
*/
|
|
42
|
+
save(value: Partial<CookieValue>): void;
|
|
43
|
+
/**
|
|
44
|
+
* Retrieve state payload from cookies
|
|
45
|
+
* @return {string | undefined} - State payload from cookies
|
|
46
|
+
*/
|
|
47
|
+
getStatePayload(): string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Clear state payload from cookies
|
|
36
50
|
*/
|
|
37
|
-
|
|
51
|
+
clearStatePayload(): void;
|
|
38
52
|
/**
|
|
39
53
|
* Retrieve cookies in the browser
|
|
40
54
|
* @return {CookieValue | undefined} - Cookies from the browser
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { TIDClient } from './TIDClient';
|
|
2
2
|
export { TIDContext, useAuth, TIDProvider } from './TIDProvider';
|
|
3
3
|
export { AuthenticationGuard } from './AuthenticationGuard/AuthenticationGuard';
|
|
4
|
-
export type { TokenResponse } from './TIDClient';
|
|
4
|
+
export type { TokenResponse, AuthState } from './TIDClient';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
var
|
|
2
|
-
var B = (i, e, t) => e in i ?
|
|
3
|
-
var
|
|
4
|
-
import { OpenIdEndpointProvider as
|
|
5
|
-
import * as
|
|
6
|
-
import
|
|
7
|
-
import { createContext as q, useContext as L, useState as z, useReducer as
|
|
8
|
-
import { jsx as
|
|
9
|
-
class
|
|
1
|
+
var $ = Object.defineProperty;
|
|
2
|
+
var B = (i, e, t) => e in i ? $(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
|
|
3
|
+
var l = (i, e, t) => (B(i, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
|
+
import { OpenIdEndpointProvider as J, AuthorizationCodeGrantTokenProvider as R, AnalyticsHttpClient as H, BearerTokenHttpClientProvider as Q } from "@trimble-oss/trimble-id";
|
|
5
|
+
import * as T from "es-cookie";
|
|
6
|
+
import X from "jwt-decode";
|
|
7
|
+
import { createContext as q, useContext as L, useState as z, useReducer as Y, useRef as Z, useMemo as M, useEffect as N, useCallback as m } from "react";
|
|
8
|
+
import { jsx as V, Fragment as j } from "react/jsx-runtime";
|
|
9
|
+
class ee {
|
|
10
10
|
constructor() {
|
|
11
11
|
/**
|
|
12
12
|
* This function generate a encapsulation function to store
|
|
@@ -15,7 +15,7 @@ class j {
|
|
|
15
15
|
* @see {https://medium.com/javascript-scene/encapsulation-in-javascript-26be60e325b4} Encapsulation
|
|
16
16
|
* @return {CacheStorage} Key for the token
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
l(this, "generateCache", function() {
|
|
19
19
|
const e = {
|
|
20
20
|
token: void 0,
|
|
21
21
|
user: void 0
|
|
@@ -62,14 +62,14 @@ class j {
|
|
|
62
62
|
}());
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
-
class
|
|
65
|
+
class te {
|
|
66
66
|
constructor() {
|
|
67
67
|
/**
|
|
68
68
|
* Cache option selected
|
|
69
69
|
* @type {CacheStorage}
|
|
70
70
|
*/
|
|
71
|
-
|
|
72
|
-
this.cacheStorage = new
|
|
71
|
+
l(this, "cacheStorage");
|
|
72
|
+
this.cacheStorage = new ee().generateCache;
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
75
75
|
* Store token in cache
|
|
@@ -109,7 +109,7 @@ class ee {
|
|
|
109
109
|
await this.cacheStorage.clear();
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
const x = 5 * 6e4,
|
|
112
|
+
const x = 5 * 6e4, ie = ["code", "state"], A = 10 * 60 * 1e3, U = (i) => i.split("?")[0], re = (i) => i.split("?")[1], b = (i) => {
|
|
113
113
|
let e = i;
|
|
114
114
|
if (!i.startsWith("?"))
|
|
115
115
|
try {
|
|
@@ -119,16 +119,16 @@ const x = 5 * 6e4, te = ["code", "state"], A = (i) => i.split("?")[0], ie = (i)
|
|
|
119
119
|
return new URLSearchParams(e);
|
|
120
120
|
}, ne = (i = window.location.href, e) => {
|
|
121
121
|
if (e != null) {
|
|
122
|
-
const
|
|
123
|
-
if (
|
|
122
|
+
const r = U(e), n = U(i ?? "");
|
|
123
|
+
if (r !== n)
|
|
124
124
|
return !1;
|
|
125
125
|
}
|
|
126
126
|
const t = b(i);
|
|
127
|
-
for (const
|
|
128
|
-
if (!t.has(
|
|
127
|
+
for (const r of ie)
|
|
128
|
+
if (!t.has(r))
|
|
129
129
|
return !1;
|
|
130
130
|
return !0;
|
|
131
|
-
},
|
|
131
|
+
}, ae = (i) => ({
|
|
132
132
|
id: i.sub,
|
|
133
133
|
name: `${i.given_name} ${i.family_name}`,
|
|
134
134
|
given_name: i.given_name,
|
|
@@ -136,14 +136,14 @@ const x = 5 * 6e4, te = ["code", "state"], A = (i) => i.split("?")[0], ie = (i)
|
|
|
136
136
|
picture: i.picture,
|
|
137
137
|
email: i.email,
|
|
138
138
|
email_verified: i.email_verified
|
|
139
|
-
}),
|
|
140
|
-
class
|
|
139
|
+
}), oe = "@TID_COOKIE";
|
|
140
|
+
class se {
|
|
141
141
|
/**
|
|
142
142
|
* Retrieve a cookie from the browser
|
|
143
143
|
* @param {string} key - Key to retrieve the cookies
|
|
144
144
|
*/
|
|
145
145
|
get(e) {
|
|
146
|
-
const t =
|
|
146
|
+
const t = T.get(e);
|
|
147
147
|
if (t == null)
|
|
148
148
|
throw new Error("Cookie not found");
|
|
149
149
|
return JSON.parse(t);
|
|
@@ -158,12 +158,12 @@ class oe {
|
|
|
158
158
|
* @example Save cookies with a custom domain
|
|
159
159
|
* cookiesStorage.set('key',{data:{...}},{domain:'https://example.com/subpath'})
|
|
160
160
|
*/
|
|
161
|
-
set(e, t,
|
|
162
|
-
let
|
|
163
|
-
window.location.protocol === "https:" && (
|
|
161
|
+
set(e, t, r) {
|
|
162
|
+
let n = {};
|
|
163
|
+
window.location.protocol === "https:" && (n = {
|
|
164
164
|
secure: !0,
|
|
165
165
|
sameSite: "none"
|
|
166
|
-
}),
|
|
166
|
+
}), r != null && r.expires && (n.expires = r.expires), r != null && r.domain && (n.domain = r.domain), T.set(e, JSON.stringify(t), n);
|
|
167
167
|
}
|
|
168
168
|
/**
|
|
169
169
|
* Remove a cookie from the browser
|
|
@@ -175,11 +175,11 @@ class oe {
|
|
|
175
175
|
* cookiesStorage.remove('key',{domain:'https://example.com/subpath'})
|
|
176
176
|
*/
|
|
177
177
|
remove(e, t) {
|
|
178
|
-
const
|
|
179
|
-
t != null && t.domain && (
|
|
178
|
+
const r = {};
|
|
179
|
+
t != null && t.domain && (r.domain = t.domain), T.remove(e, r);
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
-
class
|
|
182
|
+
class ce {
|
|
183
183
|
/**
|
|
184
184
|
* Create a cookies manager to extract or save cookies in the browser
|
|
185
185
|
* @param {CookiesManagerOptions} options - Configuration for the managing the cookies
|
|
@@ -189,23 +189,39 @@ class ae {
|
|
|
189
189
|
* Cookie full key to store and retrieve the information from cookies
|
|
190
190
|
* @type {string}
|
|
191
191
|
*/
|
|
192
|
-
|
|
192
|
+
l(this, "cookieKey");
|
|
193
193
|
/**
|
|
194
194
|
* Cookie storage. This object contain all functions necessary to retrieve and store tokens using cookies
|
|
195
195
|
* @type {CookiesStorage}
|
|
196
196
|
*/
|
|
197
|
-
|
|
198
|
-
this.cookieKey = `${
|
|
197
|
+
l(this, "cookiesStorage");
|
|
198
|
+
this.cookieKey = `${oe}.${e.clientId}`, this.cookiesStorage = new se();
|
|
199
199
|
}
|
|
200
200
|
/**
|
|
201
201
|
* Store cookies in the browser
|
|
202
|
-
* @param {CookieValue} value - information to store
|
|
202
|
+
* @param {Partial<CookieValue>} value - information to store
|
|
203
203
|
*/
|
|
204
204
|
save(e) {
|
|
205
|
-
this.
|
|
205
|
+
const r = { ...this.get() || {}, ...e };
|
|
206
|
+
this.cookiesStorage.set(this.cookieKey, r, {
|
|
206
207
|
expires: 1
|
|
207
208
|
});
|
|
208
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Retrieve state payload from cookies
|
|
212
|
+
* @return {string | undefined} - State payload from cookies
|
|
213
|
+
*/
|
|
214
|
+
getStatePayload() {
|
|
215
|
+
const e = this.get();
|
|
216
|
+
return e == null ? void 0 : e.state_payload;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Clear state payload from cookies
|
|
220
|
+
*/
|
|
221
|
+
clearStatePayload() {
|
|
222
|
+
const e = this.get();
|
|
223
|
+
e && (delete e.state_payload, this.cookiesStorage.set(this.cookieKey, e, { expires: 1 }));
|
|
224
|
+
}
|
|
209
225
|
/**
|
|
210
226
|
* Retrieve cookies in the browser
|
|
211
227
|
* @return {CookieValue | undefined} - Cookies from the browser
|
|
@@ -224,20 +240,20 @@ class ae {
|
|
|
224
240
|
this.cookiesStorage.remove(this.cookieKey);
|
|
225
241
|
}
|
|
226
242
|
}
|
|
227
|
-
class U extends Error {
|
|
228
|
-
}
|
|
229
243
|
class O extends Error {
|
|
230
244
|
}
|
|
231
|
-
class
|
|
245
|
+
class D extends Error {
|
|
246
|
+
}
|
|
247
|
+
class le extends Error {
|
|
232
248
|
}
|
|
233
|
-
const
|
|
249
|
+
const u = "@trimble-oss/trimble-id-react", g = "1.0.1", de = {
|
|
234
250
|
configurationEndpoint: "",
|
|
235
251
|
clientId: "",
|
|
236
252
|
redirectUrl: "",
|
|
237
253
|
logoutRedirectUrl: "",
|
|
238
254
|
scopes: []
|
|
239
255
|
};
|
|
240
|
-
class
|
|
256
|
+
class he {
|
|
241
257
|
/**
|
|
242
258
|
* Create a TID client to handle manage all user authentication functions and information
|
|
243
259
|
* @param {CacheManagerOptions} props - TID client configuration
|
|
@@ -247,47 +263,61 @@ class de {
|
|
|
247
263
|
* Token provider SDK. This object handles all necessary communication with TID
|
|
248
264
|
* @type {AuthorizationCodeGrantTokenProvider}
|
|
249
265
|
*/
|
|
250
|
-
|
|
266
|
+
l(this, "tokenProvider");
|
|
251
267
|
/**
|
|
252
268
|
* This object manage all caching, and all configurations necessary
|
|
253
269
|
* @type {CacheManager}
|
|
254
270
|
*/
|
|
255
|
-
|
|
271
|
+
l(this, "cacheManager");
|
|
256
272
|
/**
|
|
257
273
|
* This object manage all cookies administration, and all configurations necessary
|
|
258
274
|
* @type {CookiesManager}
|
|
259
275
|
*/
|
|
260
|
-
|
|
276
|
+
l(this, "cookiesManager");
|
|
261
277
|
/**
|
|
262
278
|
* Client id of the application created in trimble developer console
|
|
263
279
|
* @type {string}
|
|
264
280
|
*/
|
|
265
|
-
|
|
281
|
+
l(this, "clientId");
|
|
266
282
|
/**
|
|
267
283
|
* Callback url to redirect the user after the authentication is successful
|
|
268
284
|
* @type {string}
|
|
269
285
|
*/
|
|
270
|
-
|
|
286
|
+
l(this, "redirectUrl");
|
|
271
287
|
/**
|
|
272
288
|
* AnalyticsHttpClient for sending events
|
|
273
289
|
* @type {AnalyticsHttpClient}
|
|
274
290
|
*/
|
|
275
|
-
|
|
276
|
-
const { config: t =
|
|
291
|
+
l(this, "analyticshttpclient");
|
|
292
|
+
const { config: t = de } = e;
|
|
277
293
|
if (this.redirectUrl = t.redirectUrl, t.configurationEndpoint == null || t.configurationEndpoint == "")
|
|
278
294
|
throw new Error("Configuration endpoint not defined");
|
|
279
295
|
if (t.clientId == null || t.clientId == "")
|
|
280
296
|
throw new Error("Consumer key is not defined");
|
|
281
|
-
this.cookiesManager = new
|
|
297
|
+
this.cookiesManager = new ce({
|
|
282
298
|
clientId: t.clientId
|
|
283
299
|
});
|
|
284
|
-
const
|
|
285
|
-
let
|
|
286
|
-
|
|
300
|
+
const r = this.cookiesManager.get(), n = new J(t.configurationEndpoint);
|
|
301
|
+
let s = new R(
|
|
302
|
+
n,
|
|
287
303
|
t.clientId,
|
|
288
304
|
t.redirectUrl
|
|
289
305
|
).WithScopes(t.scopes);
|
|
290
|
-
t.logoutRedirectUrl && (
|
|
306
|
+
t.logoutRedirectUrl && (s = s.WithLogoutRedirect(t.logoutRedirectUrl)), (r == null ? void 0 : r.code_verifier) != null && (s = s.WithProofKeyForCodeExchange(r.code_verifier)), this.tokenProvider = s, this.cacheManager = new te(), this.clientId = t.clientId, this.analyticshttpclient = H, this.analyticshttpclient.sendInitEvent("TIDClient", this.clientId, u, g), this.cleanupExpiredState();
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Clean up expired state payloads to prevent storage bloat
|
|
310
|
+
*/
|
|
311
|
+
cleanupExpiredState() {
|
|
312
|
+
try {
|
|
313
|
+
const e = this.cookiesManager.getStatePayload();
|
|
314
|
+
if (e) {
|
|
315
|
+
const t = atob(e), r = JSON.parse(t);
|
|
316
|
+
Date.now() - r.timestamp > A && this.cookiesManager.clearStatePayload();
|
|
317
|
+
}
|
|
318
|
+
} catch {
|
|
319
|
+
this.cookiesManager.clearStatePayload();
|
|
320
|
+
}
|
|
291
321
|
}
|
|
292
322
|
/**
|
|
293
323
|
* Redirect the user to TID using the browser
|
|
@@ -296,23 +326,27 @@ class de {
|
|
|
296
326
|
* @example No configuration
|
|
297
327
|
* loginWithRedirect()
|
|
298
328
|
* // Automatically redirects the user to TID with all necessary parameters
|
|
329
|
+
* // After authentication, user will be redirected back to the current page
|
|
299
330
|
* @example Custom redirect
|
|
300
331
|
* loginWithRedirect({onRedirect: (url) => router.navigate(url)})
|
|
301
332
|
* // Redirect calls onRedirect with the log-out url for TID
|
|
302
333
|
* // So it can be handled by the developer
|
|
303
334
|
*/
|
|
304
335
|
async loginWithRedirect(e) {
|
|
305
|
-
this.analyticshttpclient.sendMethodEvent(this.loginWithRedirect.name, this.clientId,
|
|
306
|
-
const { onRedirect: t } = e || {}, n =
|
|
307
|
-
this.cookiesManager.save({
|
|
308
|
-
const
|
|
309
|
-
|
|
336
|
+
this.analyticshttpclient.sendMethodEvent(this.loginWithRedirect.name, this.clientId, u, g);
|
|
337
|
+
const { onRedirect: t } = e || {}, r = window.location.pathname + window.location.search, n = this.createStatePayload(r);
|
|
338
|
+
this.cookiesManager.save({ state_payload: n });
|
|
339
|
+
const s = R.GenerateCodeVerifier();
|
|
340
|
+
this.cookiesManager.save({ code_verifier: s }), this.tokenProvider = this.tokenProvider.WithProofKeyForCodeExchange(s);
|
|
341
|
+
const c = await this.tokenProvider.GetOAuthRedirect(n);
|
|
342
|
+
t != null ? t(c) : window.location.assign(c);
|
|
310
343
|
}
|
|
311
344
|
/**
|
|
312
345
|
* Authenticated the user using the url callback params
|
|
313
346
|
* @param {string} url - Custom configuration for the redirection
|
|
314
|
-
* @return {Promise<AuthState>} Object contain the state returned from TID
|
|
347
|
+
* @return {Promise<AuthState>} Object contain the state returned from TID and redirect path
|
|
315
348
|
* @throws {CodeVerifierNotFoundException} Will throw an exception if the session doesn't contain the code verifier
|
|
349
|
+
* @throws {Error} Will throw an exception if state validation fails or replay attack is detected
|
|
316
350
|
* @example No configuration
|
|
317
351
|
* handleCallback()
|
|
318
352
|
* // Will automatically take the url from the browser and try to log in the user
|
|
@@ -323,10 +357,13 @@ class de {
|
|
|
323
357
|
async handleCallback(e = window.location.href) {
|
|
324
358
|
const t = this.cookiesManager.get();
|
|
325
359
|
if (t == null || (t == null ? void 0 : t.code_verifier) == null)
|
|
326
|
-
throw new
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
360
|
+
throw new le("Code verifier not available");
|
|
361
|
+
const r = re(e), n = b(e), s = n.get("identity_provider") ?? "", c = n.get("state") ?? "", d = this.validateStatePayload(c);
|
|
362
|
+
if (!d.isValid)
|
|
363
|
+
throw new Error(`State validation failed: ${d.error}`);
|
|
364
|
+
return await this.tokenProvider.ValidateQuery(r), await this.generateToken(s), {
|
|
365
|
+
authState: c,
|
|
366
|
+
returnTo: d.redirectTo
|
|
330
367
|
};
|
|
331
368
|
}
|
|
332
369
|
/**
|
|
@@ -335,32 +372,79 @@ class de {
|
|
|
335
372
|
* @return {Promise<void>} Empty promise
|
|
336
373
|
*/
|
|
337
374
|
async generateToken(e) {
|
|
338
|
-
var
|
|
339
|
-
const t = await this.tokenProvider.RetrieveToken(),
|
|
375
|
+
var a, k;
|
|
376
|
+
const t = await this.tokenProvider.RetrieveToken(), r = await this.tokenProvider.RetrieveRefreshToken(), n = await this.tokenProvider.RetrieveIdToken(), s = await this.tokenProvider.RetrieveTokenExpiry(), d = new Date(s).getTime(), f = (k = (a = this.tokenProvider) == null ? void 0 : a._scopes) == null ? void 0 : k.join(" ");
|
|
340
377
|
await this.cacheManager.setToken({
|
|
341
|
-
scope:
|
|
378
|
+
scope: f,
|
|
342
379
|
state: "",
|
|
343
380
|
session_state: "",
|
|
344
381
|
identity_provider: e,
|
|
345
382
|
token_type: "bearer",
|
|
346
383
|
access_token: t,
|
|
347
|
-
refresh_token:
|
|
348
|
-
id_token:
|
|
349
|
-
expires_at:
|
|
384
|
+
refresh_token: r,
|
|
385
|
+
id_token: n,
|
|
386
|
+
expires_at: d
|
|
350
387
|
});
|
|
351
|
-
const
|
|
352
|
-
await this.cacheManager.setUser(
|
|
388
|
+
const v = X(n), p = ae(v);
|
|
389
|
+
await this.cacheManager.setUser(p), await this.reloadCodeVerifier();
|
|
353
390
|
}
|
|
354
391
|
async reloadCodeVerifier() {
|
|
355
392
|
const e = await this.tokenProvider.RetrieveCodeVerifier();
|
|
356
393
|
this.cookiesManager.save({ code_verifier: e }), this.tokenProvider = this.tokenProvider.WithProofKeyForCodeExchange(e);
|
|
357
394
|
}
|
|
395
|
+
/**
|
|
396
|
+
* Create and encode state payload for replay attack protection
|
|
397
|
+
* @param {string} redirectTo - Path to redirect to after authentication
|
|
398
|
+
* @return {string} - Base64 encoded state payload
|
|
399
|
+
*/
|
|
400
|
+
createStatePayload(e) {
|
|
401
|
+
const t = this.generateNonce(), r = Date.now();
|
|
402
|
+
return btoa(JSON.stringify({
|
|
403
|
+
redirectTo: e,
|
|
404
|
+
timestamp: r,
|
|
405
|
+
nonce: t
|
|
406
|
+
}));
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Generate a random nonce for state validation
|
|
410
|
+
* @return {string} - Random nonce
|
|
411
|
+
*/
|
|
412
|
+
generateNonce() {
|
|
413
|
+
const e = new Uint8Array(16);
|
|
414
|
+
return crypto.getRandomValues(e), Array.from(e, (t) => t.toString(16).padStart(2, "0")).join("");
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Validate state payload to prevent replay attacks
|
|
418
|
+
* @param {string} receivedState - State received from OAuth callback
|
|
419
|
+
* @return {StateValidationResult} - Validation result with redirect path if valid
|
|
420
|
+
*/
|
|
421
|
+
validateStatePayload(e) {
|
|
422
|
+
try {
|
|
423
|
+
if (!e || e.trim() === "")
|
|
424
|
+
return { isValid: !1, error: "Empty state parameter" };
|
|
425
|
+
const t = this.cookiesManager.getStatePayload();
|
|
426
|
+
if (!t)
|
|
427
|
+
return { isValid: !1, error: "No stored state found" };
|
|
428
|
+
const r = atob(e), n = JSON.parse(r), s = atob(t), c = JSON.parse(s);
|
|
429
|
+
if (!n.nonce || !n.timestamp || !n.redirectTo)
|
|
430
|
+
return { isValid: !1, error: "Invalid state payload structure" };
|
|
431
|
+
if (n.nonce !== c.nonce)
|
|
432
|
+
return { isValid: !1, error: "State nonce mismatch" };
|
|
433
|
+
const f = Date.now() - n.timestamp;
|
|
434
|
+
return f > A ? { isValid: !1, error: "State expired - possible replay attack" } : f < 0 ? { isValid: !1, error: "State timestamp is in the future - possible replay attack" } : (this.cookiesManager.clearStatePayload(), {
|
|
435
|
+
isValid: !0,
|
|
436
|
+
redirectTo: n.redirectTo
|
|
437
|
+
});
|
|
438
|
+
} catch {
|
|
439
|
+
return { isValid: !1, error: "Invalid state format" };
|
|
440
|
+
}
|
|
441
|
+
}
|
|
358
442
|
/**
|
|
359
443
|
* Return the user stored in cache
|
|
360
444
|
* @return {Promise<TIDUser | undefined>} User in cache
|
|
361
445
|
*/
|
|
362
446
|
async getUser() {
|
|
363
|
-
return this.analyticshttpclient.sendMethodEvent(this.getUser.name, this.clientId,
|
|
447
|
+
return this.analyticshttpclient.sendMethodEvent(this.getUser.name, this.clientId, u, g), await this.cacheManager.getUser();
|
|
364
448
|
}
|
|
365
449
|
/**
|
|
366
450
|
* Gets the access token from cache. If the token already expired,
|
|
@@ -370,16 +454,16 @@ class de {
|
|
|
370
454
|
* @throws {TokenExpiredException} Will throw an exception if the user token expired
|
|
371
455
|
*/
|
|
372
456
|
async getAccessTokenSilently() {
|
|
373
|
-
this.analyticshttpclient.sendMethodEvent(this.getAccessTokenSilently.name, this.clientId,
|
|
457
|
+
this.analyticshttpclient.sendMethodEvent(this.getAccessTokenSilently.name, this.clientId, u, g);
|
|
374
458
|
let e = await this.cacheManager.getToken();
|
|
375
459
|
if (e == null)
|
|
376
|
-
throw this.analyticshttpclient.sendExceptionEvent(this.getAccessTokenSilently.name, "No token available", this.clientId,
|
|
460
|
+
throw this.analyticshttpclient.sendExceptionEvent(this.getAccessTokenSilently.name, "No token available", this.clientId, u, g), new D("No token available");
|
|
377
461
|
const t = new Date((/* @__PURE__ */ new Date()).getTime() + x);
|
|
378
462
|
if ((e == null ? void 0 : e.expires_at) == null || (e == null ? void 0 : e.expires_at) < t.getTime()) {
|
|
379
463
|
try {
|
|
380
464
|
await this.tokenProvider.RetrieveToken();
|
|
381
|
-
} catch (
|
|
382
|
-
throw this.analyticshttpclient.sendExceptionEvent(this.getAccessTokenSilently.name,
|
|
465
|
+
} catch (r) {
|
|
466
|
+
throw this.analyticshttpclient.sendExceptionEvent(this.getAccessTokenSilently.name, r.message, this.clientId, u, g), new O(r.message);
|
|
383
467
|
}
|
|
384
468
|
await this.generateToken((e == null ? void 0 : e.identity_provider) ?? ""), e = await this.cacheManager.getToken();
|
|
385
469
|
}
|
|
@@ -393,16 +477,16 @@ class de {
|
|
|
393
477
|
* @throws {TokenExpiredException} Will throw an exception if the user token expired
|
|
394
478
|
*/
|
|
395
479
|
async getTokens() {
|
|
396
|
-
this.analyticshttpclient.sendMethodEvent(this.getTokens.name, this.clientId,
|
|
480
|
+
this.analyticshttpclient.sendMethodEvent(this.getTokens.name, this.clientId, u, g);
|
|
397
481
|
let e = await this.cacheManager.getToken();
|
|
398
482
|
if (e == null)
|
|
399
|
-
throw this.analyticshttpclient.sendExceptionEvent(this.getTokens.name, "No token available", this.clientId,
|
|
483
|
+
throw this.analyticshttpclient.sendExceptionEvent(this.getTokens.name, "No token available", this.clientId, u, g), new D("No token available");
|
|
400
484
|
const t = new Date((/* @__PURE__ */ new Date()).getTime() + x);
|
|
401
485
|
if ((e == null ? void 0 : e.expires_at) == null || (e == null ? void 0 : e.expires_at) < t.getTime()) {
|
|
402
486
|
try {
|
|
403
487
|
await this.tokenProvider.RetrieveToken();
|
|
404
|
-
} catch (
|
|
405
|
-
throw this.analyticshttpclient.sendExceptionEvent(this.getTokens.name,
|
|
488
|
+
} catch (r) {
|
|
489
|
+
throw this.analyticshttpclient.sendExceptionEvent(this.getTokens.name, r.message, this.clientId, u, g), new O(r.message);
|
|
406
490
|
}
|
|
407
491
|
await this.generateToken((e == null ? void 0 : e.identity_provider) ?? ""), e = await this.cacheManager.getToken();
|
|
408
492
|
}
|
|
@@ -425,13 +509,13 @@ class de {
|
|
|
425
509
|
* // So it can be handled by the developer
|
|
426
510
|
*/
|
|
427
511
|
async logout(e) {
|
|
428
|
-
this.analyticshttpclient.sendMethodEvent(this.logout.name, this.clientId,
|
|
429
|
-
const { onRedirect: t, disabledAutoRedirect:
|
|
512
|
+
this.analyticshttpclient.sendMethodEvent(this.logout.name, this.clientId, u, g);
|
|
513
|
+
const { onRedirect: t, disabledAutoRedirect: r } = e || {};
|
|
430
514
|
this.cacheManager && await this.cacheManager.clear(), this.cookiesManager && this.cookiesManager.clear();
|
|
431
|
-
const
|
|
515
|
+
const n = await this.tokenProvider.GetOAuthLogoutRedirect("state");
|
|
432
516
|
if (t != null)
|
|
433
|
-
return t(
|
|
434
|
-
|
|
517
|
+
return t(n);
|
|
518
|
+
r || window.location.assign(n);
|
|
435
519
|
}
|
|
436
520
|
/**
|
|
437
521
|
* Check if the user still has a valid session
|
|
@@ -460,8 +544,8 @@ class de {
|
|
|
460
544
|
const e = await this.cacheManager.getToken();
|
|
461
545
|
if (e == null)
|
|
462
546
|
return;
|
|
463
|
-
const t = e.access_token,
|
|
464
|
-
this.tokenProvider = this.tokenProvider.WithAccessToken(t,
|
|
547
|
+
const t = e.access_token, r = e.refresh_token || "", n = e.id_token, s = e.expires_at;
|
|
548
|
+
this.tokenProvider = this.tokenProvider.WithAccessToken(t, s).WithRefreshToken(r).WithIdToken(n);
|
|
465
549
|
}
|
|
466
550
|
/**
|
|
467
551
|
* Get a http bearer token client to use it for another SDK (Ex: Processing framework)
|
|
@@ -478,7 +562,7 @@ class de {
|
|
|
478
562
|
return this.redirectUrl;
|
|
479
563
|
}
|
|
480
564
|
}
|
|
481
|
-
const
|
|
565
|
+
const w = q(null), K = () => L(w) ?? {}, ue = (i, e) => {
|
|
482
566
|
switch (e.type) {
|
|
483
567
|
case "INIT":
|
|
484
568
|
return {
|
|
@@ -511,10 +595,10 @@ const E = q(null), W = () => L(E) ?? {}, he = (i, e) => {
|
|
|
511
595
|
error: e.error
|
|
512
596
|
};
|
|
513
597
|
}
|
|
514
|
-
},
|
|
598
|
+
}, ge = {
|
|
515
599
|
isLoading: !0,
|
|
516
600
|
isAuthenticated: !1
|
|
517
|
-
},
|
|
601
|
+
}, fe = (i) => {
|
|
518
602
|
if (i == null || Object.keys(i).length <= 0)
|
|
519
603
|
return !0;
|
|
520
604
|
const e = Object.keys(i);
|
|
@@ -522,114 +606,112 @@ const E = q(null), W = () => L(E) ?? {}, he = (i, e) => {
|
|
|
522
606
|
if (i[t] != null && i[t] !== "")
|
|
523
607
|
return !1;
|
|
524
608
|
return !0;
|
|
525
|
-
},
|
|
609
|
+
}, ye = (i) => !fe(i.config), ke = (i) => {
|
|
526
610
|
const {
|
|
527
611
|
children: e,
|
|
528
612
|
configurationEndpoint: t,
|
|
529
|
-
clientId:
|
|
530
|
-
redirectUrl:
|
|
531
|
-
logoutRedirectUrl:
|
|
532
|
-
scopes:
|
|
533
|
-
onRedirectCallback:
|
|
534
|
-
checkRedirectUrlMatch:
|
|
613
|
+
clientId: r,
|
|
614
|
+
redirectUrl: n,
|
|
615
|
+
logoutRedirectUrl: s,
|
|
616
|
+
scopes: c,
|
|
617
|
+
onRedirectCallback: d,
|
|
618
|
+
checkRedirectUrlMatch: f
|
|
535
619
|
} = i;
|
|
536
|
-
if (L(
|
|
620
|
+
if (L(w) != null)
|
|
537
621
|
throw new Error("TID Provider already defined");
|
|
538
|
-
const
|
|
622
|
+
const p = {
|
|
539
623
|
config: {
|
|
540
624
|
configurationEndpoint: t ?? "",
|
|
541
|
-
clientId:
|
|
542
|
-
redirectUrl:
|
|
543
|
-
logoutRedirectUrl:
|
|
544
|
-
scopes:
|
|
625
|
+
clientId: r ?? "",
|
|
626
|
+
redirectUrl: n ?? "",
|
|
627
|
+
logoutRedirectUrl: s ?? "",
|
|
628
|
+
scopes: c ?? [""]
|
|
545
629
|
}
|
|
546
|
-
}, [
|
|
547
|
-
() =>
|
|
548
|
-
[
|
|
630
|
+
}, [a] = z(i.tidClient ?? new he(p)), [k, y] = Y(ue, ge), E = Z(!1), W = M(
|
|
631
|
+
() => f ? a.getRedirectUrl() : void 0,
|
|
632
|
+
[f, a]
|
|
549
633
|
);
|
|
550
|
-
|
|
551
|
-
|
|
634
|
+
N(() => {
|
|
635
|
+
E.current || (i.tidClient != null && ye({
|
|
552
636
|
config: {
|
|
553
637
|
configurationEndpoint: t,
|
|
554
|
-
clientId:
|
|
555
|
-
redirectUrl:
|
|
556
|
-
logoutRedirectUrl:
|
|
557
|
-
scopes:
|
|
638
|
+
clientId: r,
|
|
639
|
+
redirectUrl: n,
|
|
640
|
+
logoutRedirectUrl: s,
|
|
641
|
+
scopes: c
|
|
558
642
|
}
|
|
559
643
|
}) && console.warn(
|
|
560
644
|
"When TID client is pass as prop, any client configuration property sent directly to the TID Provider component will be ignored"
|
|
561
|
-
),
|
|
645
|
+
), E.current = !0, (async () => {
|
|
562
646
|
try {
|
|
563
647
|
let o;
|
|
564
|
-
if (ne(void 0,
|
|
565
|
-
const
|
|
566
|
-
o = await
|
|
648
|
+
if (ne(void 0, W)) {
|
|
649
|
+
const h = await a.handleCallback();
|
|
650
|
+
o = await a.getUser(), d != null && d(h);
|
|
567
651
|
} else
|
|
568
|
-
await
|
|
569
|
-
|
|
652
|
+
await a.loadUserSession(), o = await a.getUser();
|
|
653
|
+
y({ type: "INIT", user: o });
|
|
570
654
|
} catch (o) {
|
|
571
|
-
let
|
|
572
|
-
typeof o == "string" && (
|
|
655
|
+
let h = o;
|
|
656
|
+
typeof o == "string" && (h = new Error(o)), y({ type: "ERROR", error: h });
|
|
573
657
|
}
|
|
574
658
|
})());
|
|
575
|
-
}, [
|
|
576
|
-
const
|
|
577
|
-
const o = await
|
|
578
|
-
return
|
|
659
|
+
}, [a, d]);
|
|
660
|
+
const S = m(async () => {
|
|
661
|
+
const o = await a.getAccessTokenSilently(), h = await a.getUser();
|
|
662
|
+
return y({
|
|
579
663
|
type: "GET_ACCESS_TOKEN_COMPLETE",
|
|
580
|
-
user:
|
|
664
|
+
user: h
|
|
581
665
|
}), o;
|
|
582
|
-
}, [
|
|
583
|
-
const o = await
|
|
584
|
-
return
|
|
666
|
+
}, [a]), P = m(async () => {
|
|
667
|
+
const o = await a.getTokens(), h = await a.getUser();
|
|
668
|
+
return y({
|
|
585
669
|
type: "GET_TOKENS_COMPLETE",
|
|
586
|
-
user:
|
|
670
|
+
user: h
|
|
587
671
|
}), o;
|
|
588
|
-
}, [
|
|
672
|
+
}, [a]), _ = m(
|
|
589
673
|
async (o) => {
|
|
590
|
-
await
|
|
674
|
+
await a.loginWithRedirect(o);
|
|
591
675
|
},
|
|
592
|
-
[
|
|
593
|
-
),
|
|
676
|
+
[a]
|
|
677
|
+
), C = m(
|
|
594
678
|
async (o) => {
|
|
595
|
-
await
|
|
679
|
+
await a.logout(o), (o == null ? void 0 : o.disabledAutoRedirect) != null && o.disabledAutoRedirect && y({
|
|
596
680
|
type: "LOGOUT"
|
|
597
681
|
});
|
|
598
682
|
},
|
|
599
|
-
[
|
|
600
|
-
),
|
|
683
|
+
[a]
|
|
684
|
+
), I = m(
|
|
601
685
|
async (o) => {
|
|
602
|
-
const
|
|
603
|
-
return
|
|
686
|
+
const h = await a.handleCallback(o), F = await a.getUser();
|
|
687
|
+
return y({
|
|
604
688
|
type: "HANDLE_CALLBACK_COMPLETE",
|
|
605
|
-
user:
|
|
606
|
-
}),
|
|
607
|
-
authState: l
|
|
608
|
-
};
|
|
689
|
+
user: F
|
|
690
|
+
}), h;
|
|
609
691
|
},
|
|
610
|
-
[
|
|
692
|
+
[a]
|
|
611
693
|
), G = M(
|
|
612
694
|
() => ({
|
|
613
|
-
...
|
|
614
|
-
getAccessTokenSilently:
|
|
615
|
-
getTokens:
|
|
616
|
-
loginWithRedirect:
|
|
617
|
-
handleCallback:
|
|
618
|
-
logout:
|
|
695
|
+
...k,
|
|
696
|
+
getAccessTokenSilently: S,
|
|
697
|
+
getTokens: P,
|
|
698
|
+
loginWithRedirect: _,
|
|
699
|
+
handleCallback: I,
|
|
700
|
+
logout: C
|
|
619
701
|
}),
|
|
620
|
-
[
|
|
702
|
+
[k, S, P, _, I, C]
|
|
621
703
|
);
|
|
622
|
-
return /* @__PURE__ */
|
|
623
|
-
},
|
|
624
|
-
const { isAuthenticated: t, isLoading:
|
|
625
|
-
return
|
|
626
|
-
!
|
|
627
|
-
}, [
|
|
704
|
+
return /* @__PURE__ */ V(w.Provider, { value: G, children: e });
|
|
705
|
+
}, Ee = K, Se = ke, Pe = ({ renderComponent: i, loader: e }) => {
|
|
706
|
+
const { isAuthenticated: t, isLoading: r, loginWithRedirect: n } = K();
|
|
707
|
+
return N(() => {
|
|
708
|
+
!r && !t && (async () => await n())();
|
|
709
|
+
}, [r, t, n]), t ? i : e || /* @__PURE__ */ V(j, {});
|
|
628
710
|
};
|
|
629
711
|
export {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
712
|
+
Pe as AuthenticationGuard,
|
|
713
|
+
he as TIDClient,
|
|
714
|
+
w as TIDContext,
|
|
715
|
+
Se as TIDProvider,
|
|
716
|
+
Ee as useAuth
|
|
635
717
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(o,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("@trimble-oss/trimble-id"),require("es-cookie"),require("jwt-decode"),require("react"),require("react/jsx-runtime")):typeof define=="function"&&define.amd?define(["exports","@trimble-oss/trimble-id","es-cookie","jwt-decode","react","react/jsx-runtime"],c):(o=typeof globalThis<"u"?globalThis:o||self,c(o.ReactTID={},o.trimbleId,o.esCookie,o.jwt_decode,o.React,o.jsxRuntime))})(this,function(o,c,k,W,l,p){"use strict";var le=Object.defineProperty;var de=(o,c,k)=>c in o?le(o,c,{enumerable:!0,configurable:!0,writable:!0,value:k}):o[c]=k;var h=(o,c,k)=>(de(o,typeof c!="symbol"?c+"":c,k),k);function G(i){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(i){for(const t in i)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(i,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>i[t]})}}return e.default=i,Object.freeze(e)}const C=G(k);class V{constructor(){h(this,"generateCache",function(){const e={token:void 0,user:void 0};return{async getToken(){return e.token},async getUser(){return e.user},async storeToken(t){e.token=t},async storeUser(t){e.user=t},clear(){return e.token=void 0,e.user=void 0,Promise.resolve(void 0)}}}())}}class F{constructor(){h(this,"cacheStorage");this.cacheStorage=new V().generateCache}async setToken(e){await this.cacheStorage.storeToken(e)}async setUser(e){await this.cacheStorage.storeUser(e)}async getUser(){return this.cacheStorage.getUser()}async getToken(){return this.cacheStorage.getToken()}async clear(){await this.cacheStorage.clear()}}const S=5*6e4,j=["code","state"],P=i=>i.split("?")[0],q=i=>i.split("?")[1],I=i=>{let e=i;if(!i.startsWith("?"))try{e=new URL(i).search}catch{}return new URLSearchParams(e)},B=(i=window.location.href,e)=>{if(e!=null){const n=P(e),r=P(i??"");if(n!==r)return!1}const t=I(i);for(const n of j)if(!t.has(n))return!1;return!0},$=i=>({id:i.sub,name:`${i.given_name} ${i.family_name}`,given_name:i.given_name,family_name:i.family_name,picture:i.picture,email:i.email,email_verified:i.email_verified}),H="@TID_COOKIE";class z{get(e){const t=C.get(e);if(t==null)throw new Error("Cookie not found");return JSON.parse(t)}set(e,t,n){let r={};window.location.protocol==="https:"&&(r={secure:!0,sameSite:"none"}),n!=null&&n.expires&&(r.expires=n.expires),n!=null&&n.domain&&(r.domain=n.domain),C.set(e,JSON.stringify(t),r)}remove(e,t){const n={};t!=null&&t.domain&&(n.domain=t.domain),C.remove(e,n)}}class Q{constructor(e){h(this,"cookieKey");h(this,"cookiesStorage");this.cookieKey=`${H}.${e.clientId}`,this.cookiesStorage=new z}save(e){this.cookiesStorage.set(this.cookieKey,e,{expires:1})}get(){try{return this.cookiesStorage.get(this.cookieKey)}catch{return}}clear(){this.cookiesStorage.remove(this.cookieKey)}}class R extends Error{}class M extends Error{}class J extends Error{}const u="@trimble-oss/trimble-id-react",g="1.0.0",X={configurationEndpoint:"",clientId:"",redirectUrl:"",logoutRedirectUrl:"",scopes:[]};class x{constructor(e){h(this,"tokenProvider");h(this,"cacheManager");h(this,"cookiesManager");h(this,"clientId");h(this,"redirectUrl");h(this,"analyticshttpclient");const{config:t=X}=e;if(this.redirectUrl=t.redirectUrl,t.configurationEndpoint==null||t.configurationEndpoint=="")throw new Error("Configuration endpoint not defined");if(t.clientId==null||t.clientId=="")throw new Error("Consumer key is not defined");this.cookiesManager=new Q({clientId:t.clientId});const n=this.cookiesManager.get(),r=new c.OpenIdEndpointProvider(t.configurationEndpoint);let d=new c.AuthorizationCodeGrantTokenProvider(r,t.clientId,t.redirectUrl).WithScopes(t.scopes);t.logoutRedirectUrl&&(d=d.WithLogoutRedirect(t.logoutRedirectUrl)),(n==null?void 0:n.code_verifier)!=null&&(d=d.WithProofKeyForCodeExchange(n.code_verifier)),this.tokenProvider=d,this.cacheManager=new F,this.clientId=t.clientId,this.analyticshttpclient=c.AnalyticsHttpClient,this.analyticshttpclient.sendInitEvent("TIDClient",this.clientId,u,g)}async loginWithRedirect(e){this.analyticshttpclient.sendMethodEvent(this.loginWithRedirect.name,this.clientId,u,g);const{onRedirect:t}=e||{},n=c.AuthorizationCodeGrantTokenProvider.GenerateCodeVerifier();this.cookiesManager.save({code_verifier:n}),this.tokenProvider=this.tokenProvider.WithProofKeyForCodeExchange(n);const r=await this.tokenProvider.GetOAuthRedirect("state");t!=null?t(r):window.location.assign(r)}async handleCallback(e=window.location.href){const t=this.cookiesManager.get();if(t==null||(t==null?void 0:t.code_verifier)==null)throw new J("Code verifier not available");const n=q(e),r=I(e),d=r.get("identity_provider")??"",T=r.get("state")??"";return await this.tokenProvider.ValidateQuery(n),await this.generateToken(d),{authState:T}}async generateToken(e){var s,w;const t=await this.tokenProvider.RetrieveToken(),n=await this.tokenProvider.RetrieveRefreshToken(),r=await this.tokenProvider.RetrieveIdToken(),d=await this.tokenProvider.RetrieveTokenExpiry(),v=new Date(d).getTime(),m=(w=(s=this.tokenProvider)==null?void 0:s._scopes)==null?void 0:w.join(" ");await this.cacheManager.setToken({scope:m,state:"",session_state:"",identity_provider:e,token_type:"bearer",access_token:t,refresh_token:n,id_token:r,expires_at:v});const U=W(r),_=$(U);await this.cacheManager.setUser(_),await this.reloadCodeVerifier()}async reloadCodeVerifier(){const e=await this.tokenProvider.RetrieveCodeVerifier();this.cookiesManager.save({code_verifier:e}),this.tokenProvider=this.tokenProvider.WithProofKeyForCodeExchange(e)}async getUser(){return this.analyticshttpclient.sendMethodEvent(this.getUser.name,this.clientId,u,g),await this.cacheManager.getUser()}async getAccessTokenSilently(){this.analyticshttpclient.sendMethodEvent(this.getAccessTokenSilently.name,this.clientId,u,g);let e=await this.cacheManager.getToken();if(e==null)throw this.analyticshttpclient.sendExceptionEvent(this.getAccessTokenSilently.name,"No token available",this.clientId,u,g),new M("No token available");const t=new Date(new Date().getTime()+S);if((e==null?void 0:e.expires_at)==null||(e==null?void 0:e.expires_at)<t.getTime()){try{await this.tokenProvider.RetrieveToken()}catch(n){throw this.analyticshttpclient.sendExceptionEvent(this.getAccessTokenSilently.name,n.message,this.clientId,u,g),new R(n.message)}await this.generateToken((e==null?void 0:e.identity_provider)??""),e=await this.cacheManager.getToken()}return(e==null?void 0:e.access_token)||""}async getTokens(){this.analyticshttpclient.sendMethodEvent(this.getTokens.name,this.clientId,u,g);let e=await this.cacheManager.getToken();if(e==null)throw this.analyticshttpclient.sendExceptionEvent(this.getTokens.name,"No token available",this.clientId,u,g),new M("No token available");const t=new Date(new Date().getTime()+S);if((e==null?void 0:e.expires_at)==null||(e==null?void 0:e.expires_at)<t.getTime()){try{await this.tokenProvider.RetrieveToken()}catch(n){throw this.analyticshttpclient.sendExceptionEvent(this.getTokens.name,n.message,this.clientId,u,g),new R(n.message)}await this.generateToken((e==null?void 0:e.identity_provider)??""),e=await this.cacheManager.getToken()}return{access_token:(e==null?void 0:e.access_token)||"",expires_at:(e==null?void 0:e.expires_at)||0,id_token:(e==null?void 0:e.id_token)||""}}async logout(e){this.analyticshttpclient.sendMethodEvent(this.logout.name,this.clientId,u,g);const{onRedirect:t,disabledAutoRedirect:n}=e||{};this.cacheManager&&await this.cacheManager.clear(),this.cookiesManager&&this.cookiesManager.clear();const r=await this.tokenProvider.GetOAuthLogoutRedirect("state");if(t!=null)return t(r);n||window.location.assign(r)}async checkSession(){try{await this.getAccessTokenSilently()}catch{return!1}return!0}async loadUserSession(){await this.loadCacheSessionIntoSDK(),await this.checkSession()||await this.cacheManager.clear()}async loadCacheSessionIntoSDK(){const e=await this.cacheManager.getToken();if(e==null)return;const t=e.access_token,n=e.refresh_token||"",r=e.id_token,d=e.expires_at;this.tokenProvider=this.tokenProvider.WithAccessToken(t,d).WithRefreshToken(n).WithIdToken(r)}getBearerTokenHttpClient(e){return new c.BearerTokenHttpClientProvider(this.tokenProvider,e)}getRedirectUrl(){return this.redirectUrl}}const E=l.createContext(null),A=()=>l.useContext(E)??{},Y=(i,e)=>{switch(e.type){case"INIT":return{...i,isLoading:!1,isAuthenticated:e.user!=null,user:e.user,error:void 0};case"GET_TOKENS_COMPLETE":case"HANDLE_CALLBACK_COMPLETE":case"GET_ACCESS_TOKEN_COMPLETE":return{...i,isLoading:!1,isAuthenticated:e.user!=null,user:e.user,error:void 0};case"LOGOUT":return{...i,isAuthenticated:!1,user:void 0};case"ERROR":return{...i,isLoading:!1,error:e.error}}},Z={isLoading:!0,isAuthenticated:!1},ee=i=>{if(i==null||Object.keys(i).length<=0)return!0;const e=Object.keys(i);for(const t of e)if(i[t]!=null&&i[t]!=="")return!1;return!0},te=i=>!ee(i.config),ie=i=>{const{children:e,configurationEndpoint:t,clientId:n,redirectUrl:r,logoutRedirectUrl:d,scopes:T,onRedirectCallback:v,checkRedirectUrlMatch:m}=i;if(l.useContext(E)!=null)throw new Error("TID Provider already defined");const _={config:{configurationEndpoint:t??"",clientId:n??"",redirectUrl:r??"",logoutRedirectUrl:d??"",scopes:T??[""]}},[s]=l.useState(i.tidClient??new x(_)),[w,y]=l.useReducer(Y,Z),O=l.useRef(!1),oe=l.useMemo(()=>m?s.getRedirectUrl():void 0,[m,s]);l.useEffect(()=>{O.current||(i.tidClient!=null&&te({config:{configurationEndpoint:t,clientId:n,redirectUrl:r,logoutRedirectUrl:d,scopes:T}})&&console.warn("When TID client is pass as prop, any client configuration property sent directly to the TID Provider component will be ignored"),O.current=!0,(async()=>{try{let a;if(B(void 0,oe)){const{authState:f}=await s.handleCallback();a=await s.getUser(),v!=null&&v(f)}else await s.loadUserSession(),a=await s.getUser();y({type:"INIT",user:a})}catch(a){let f=a;typeof a=="string"&&(f=new Error(a)),y({type:"ERROR",error:f})}})())},[s,v]);const D=l.useCallback(async()=>{const a=await s.getAccessTokenSilently(),f=await s.getUser();return y({type:"GET_ACCESS_TOKEN_COMPLETE",user:f}),a},[s]),b=l.useCallback(async()=>{const a=await s.getTokens(),f=await s.getUser();return y({type:"GET_TOKENS_COMPLETE",user:f}),a},[s]),L=l.useCallback(async a=>{await s.loginWithRedirect(a)},[s]),K=l.useCallback(async a=>{await s.logout(a),(a==null?void 0:a.disabledAutoRedirect)!=null&&a.disabledAutoRedirect&&y({type:"LOGOUT"})},[s]),N=l.useCallback(async a=>{const{authState:f}=await s.handleCallback(a),ce=await s.getUser();return y({type:"HANDLE_CALLBACK_COMPLETE",user:ce}),{authState:f}},[s]),ae=l.useMemo(()=>({...w,getAccessTokenSilently:D,getTokens:b,loginWithRedirect:L,handleCallback:N,logout:K}),[w,D,b,L,N,K]);return p.jsx(E.Provider,{value:ae,children:e})},ne=A,re=ie,se=({renderComponent:i,loader:e})=>{const{isAuthenticated:t,isLoading:n,loginWithRedirect:r}=A();return l.useEffect(()=>{!n&&!t&&(async()=>await r())()},[n,t,r]),t?i:e||p.jsx(p.Fragment,{})};o.AuthenticationGuard=se,o.TIDClient=x,o.TIDContext=E,o.TIDProvider=re,o.useAuth=ne,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(o,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("@trimble-oss/trimble-id"),require("es-cookie"),require("jwt-decode"),require("react"),require("react/jsx-runtime")):typeof define=="function"&&define.amd?define(["exports","@trimble-oss/trimble-id","es-cookie","jwt-decode","react","react/jsx-runtime"],l):(o=typeof globalThis<"u"?globalThis:o||self,l(o.ReactTID={},o.trimbleId,o.esCookie,o.jwt_decode,o.React,o.jsxRuntime))})(this,function(o,l,p,W,d,E){"use strict";var de=Object.defineProperty;var he=(o,l,p)=>l in o?de(o,l,{enumerable:!0,configurable:!0,writable:!0,value:p}):o[l]=p;var u=(o,l,p)=>(he(o,typeof l!="symbol"?l+"":l,p),p);function G(i){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(i){for(const t in i)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(i,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>i[t]})}}return e.default=i,Object.freeze(e)}const S=G(p);class F{constructor(){u(this,"generateCache",function(){const e={token:void 0,user:void 0};return{async getToken(){return e.token},async getUser(){return e.user},async storeToken(t){e.token=t},async storeUser(t){e.user=t},clear(){return e.token=void 0,e.user=void 0,Promise.resolve(void 0)}}}())}}class j{constructor(){u(this,"cacheStorage");this.cacheStorage=new F().generateCache}async setToken(e){await this.cacheStorage.storeToken(e)}async setUser(e){await this.cacheStorage.storeUser(e)}async getUser(){return this.cacheStorage.getUser()}async getToken(){return this.cacheStorage.getToken()}async clear(){await this.cacheStorage.clear()}}const C=5*6e4,$=["code","state"],_=10*60*1e3,I=i=>i.split("?")[0],q=i=>i.split("?")[1],M=i=>{let e=i;if(!i.startsWith("?"))try{e=new URL(i).search}catch{}return new URLSearchParams(e)},B=(i=window.location.href,e)=>{if(e!=null){const n=I(e),r=I(i??"");if(n!==r)return!1}const t=M(i);for(const n of $)if(!t.has(n))return!1;return!0},J=i=>({id:i.sub,name:`${i.given_name} ${i.family_name}`,given_name:i.given_name,family_name:i.family_name,picture:i.picture,email:i.email,email_verified:i.email_verified}),H="@TID_COOKIE";class z{get(e){const t=S.get(e);if(t==null)throw new Error("Cookie not found");return JSON.parse(t)}set(e,t,n){let r={};window.location.protocol==="https:"&&(r={secure:!0,sameSite:"none"}),n!=null&&n.expires&&(r.expires=n.expires),n!=null&&n.domain&&(r.domain=n.domain),S.set(e,JSON.stringify(t),r)}remove(e,t){const n={};t!=null&&t.domain&&(n.domain=t.domain),S.remove(e,n)}}class Q{constructor(e){u(this,"cookieKey");u(this,"cookiesStorage");this.cookieKey=`${H}.${e.clientId}`,this.cookiesStorage=new z}save(e){const n={...this.get()||{},...e};this.cookiesStorage.set(this.cookieKey,n,{expires:1})}getStatePayload(){const e=this.get();return e==null?void 0:e.state_payload}clearStatePayload(){const e=this.get();e&&(delete e.state_payload,this.cookiesStorage.set(this.cookieKey,e,{expires:1}))}get(){try{return this.cookiesStorage.get(this.cookieKey)}catch{return}}clear(){this.cookiesStorage.remove(this.cookieKey)}}class R extends Error{}class x extends Error{}class X extends Error{}const g="@trimble-oss/trimble-id-react",f="1.0.1",Y={configurationEndpoint:"",clientId:"",redirectUrl:"",logoutRedirectUrl:"",scopes:[]};class A{constructor(e){u(this,"tokenProvider");u(this,"cacheManager");u(this,"cookiesManager");u(this,"clientId");u(this,"redirectUrl");u(this,"analyticshttpclient");const{config:t=Y}=e;if(this.redirectUrl=t.redirectUrl,t.configurationEndpoint==null||t.configurationEndpoint=="")throw new Error("Configuration endpoint not defined");if(t.clientId==null||t.clientId=="")throw new Error("Consumer key is not defined");this.cookiesManager=new Q({clientId:t.clientId});const n=this.cookiesManager.get(),r=new l.OpenIdEndpointProvider(t.configurationEndpoint);let c=new l.AuthorizationCodeGrantTokenProvider(r,t.clientId,t.redirectUrl).WithScopes(t.scopes);t.logoutRedirectUrl&&(c=c.WithLogoutRedirect(t.logoutRedirectUrl)),(n==null?void 0:n.code_verifier)!=null&&(c=c.WithProofKeyForCodeExchange(n.code_verifier)),this.tokenProvider=c,this.cacheManager=new j,this.clientId=t.clientId,this.analyticshttpclient=l.AnalyticsHttpClient,this.analyticshttpclient.sendInitEvent("TIDClient",this.clientId,g,f),this.cleanupExpiredState()}cleanupExpiredState(){try{const e=this.cookiesManager.getStatePayload();if(e){const t=atob(e),n=JSON.parse(t);Date.now()-n.timestamp>_&&this.cookiesManager.clearStatePayload()}}catch{this.cookiesManager.clearStatePayload()}}async loginWithRedirect(e){this.analyticshttpclient.sendMethodEvent(this.loginWithRedirect.name,this.clientId,g,f);const{onRedirect:t}=e||{},n=window.location.pathname+window.location.search,r=this.createStatePayload(n);this.cookiesManager.save({state_payload:r});const c=l.AuthorizationCodeGrantTokenProvider.GenerateCodeVerifier();this.cookiesManager.save({code_verifier:c}),this.tokenProvider=this.tokenProvider.WithProofKeyForCodeExchange(c);const h=await this.tokenProvider.GetOAuthRedirect(r);t!=null?t(h):window.location.assign(h)}async handleCallback(e=window.location.href){const t=this.cookiesManager.get();if(t==null||(t==null?void 0:t.code_verifier)==null)throw new X("Code verifier not available");const n=q(e),r=M(e),c=r.get("identity_provider")??"",h=r.get("state")??"",y=this.validateStatePayload(h);if(!y.isValid)throw new Error(`State validation failed: ${y.error}`);return await this.tokenProvider.ValidateQuery(n),await this.generateToken(c),{authState:h,returnTo:y.redirectTo}}async generateToken(e){var a,v;const t=await this.tokenProvider.RetrieveToken(),n=await this.tokenProvider.RetrieveRefreshToken(),r=await this.tokenProvider.RetrieveIdToken(),c=await this.tokenProvider.RetrieveTokenExpiry(),y=new Date(c).getTime(),T=(v=(a=this.tokenProvider)==null?void 0:a._scopes)==null?void 0:v.join(" ");await this.cacheManager.setToken({scope:T,state:"",session_state:"",identity_provider:e,token_type:"bearer",access_token:t,refresh_token:n,id_token:r,expires_at:y});const U=W(r),P=J(U);await this.cacheManager.setUser(P),await this.reloadCodeVerifier()}async reloadCodeVerifier(){const e=await this.tokenProvider.RetrieveCodeVerifier();this.cookiesManager.save({code_verifier:e}),this.tokenProvider=this.tokenProvider.WithProofKeyForCodeExchange(e)}createStatePayload(e){const t=this.generateNonce(),n=Date.now();return btoa(JSON.stringify({redirectTo:e,timestamp:n,nonce:t}))}generateNonce(){const e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}validateStatePayload(e){try{if(!e||e.trim()==="")return{isValid:!1,error:"Empty state parameter"};const t=this.cookiesManager.getStatePayload();if(!t)return{isValid:!1,error:"No stored state found"};const n=atob(e),r=JSON.parse(n),c=atob(t),h=JSON.parse(c);if(!r.nonce||!r.timestamp||!r.redirectTo)return{isValid:!1,error:"Invalid state payload structure"};if(r.nonce!==h.nonce)return{isValid:!1,error:"State nonce mismatch"};const T=Date.now()-r.timestamp;return T>_?{isValid:!1,error:"State expired - possible replay attack"}:T<0?{isValid:!1,error:"State timestamp is in the future - possible replay attack"}:(this.cookiesManager.clearStatePayload(),{isValid:!0,redirectTo:r.redirectTo})}catch{return{isValid:!1,error:"Invalid state format"}}}async getUser(){return this.analyticshttpclient.sendMethodEvent(this.getUser.name,this.clientId,g,f),await this.cacheManager.getUser()}async getAccessTokenSilently(){this.analyticshttpclient.sendMethodEvent(this.getAccessTokenSilently.name,this.clientId,g,f);let e=await this.cacheManager.getToken();if(e==null)throw this.analyticshttpclient.sendExceptionEvent(this.getAccessTokenSilently.name,"No token available",this.clientId,g,f),new x("No token available");const t=new Date(new Date().getTime()+C);if((e==null?void 0:e.expires_at)==null||(e==null?void 0:e.expires_at)<t.getTime()){try{await this.tokenProvider.RetrieveToken()}catch(n){throw this.analyticshttpclient.sendExceptionEvent(this.getAccessTokenSilently.name,n.message,this.clientId,g,f),new R(n.message)}await this.generateToken((e==null?void 0:e.identity_provider)??""),e=await this.cacheManager.getToken()}return(e==null?void 0:e.access_token)||""}async getTokens(){this.analyticshttpclient.sendMethodEvent(this.getTokens.name,this.clientId,g,f);let e=await this.cacheManager.getToken();if(e==null)throw this.analyticshttpclient.sendExceptionEvent(this.getTokens.name,"No token available",this.clientId,g,f),new x("No token available");const t=new Date(new Date().getTime()+C);if((e==null?void 0:e.expires_at)==null||(e==null?void 0:e.expires_at)<t.getTime()){try{await this.tokenProvider.RetrieveToken()}catch(n){throw this.analyticshttpclient.sendExceptionEvent(this.getTokens.name,n.message,this.clientId,g,f),new R(n.message)}await this.generateToken((e==null?void 0:e.identity_provider)??""),e=await this.cacheManager.getToken()}return{access_token:(e==null?void 0:e.access_token)||"",expires_at:(e==null?void 0:e.expires_at)||0,id_token:(e==null?void 0:e.id_token)||""}}async logout(e){this.analyticshttpclient.sendMethodEvent(this.logout.name,this.clientId,g,f);const{onRedirect:t,disabledAutoRedirect:n}=e||{};this.cacheManager&&await this.cacheManager.clear(),this.cookiesManager&&this.cookiesManager.clear();const r=await this.tokenProvider.GetOAuthLogoutRedirect("state");if(t!=null)return t(r);n||window.location.assign(r)}async checkSession(){try{await this.getAccessTokenSilently()}catch{return!1}return!0}async loadUserSession(){await this.loadCacheSessionIntoSDK(),await this.checkSession()||await this.cacheManager.clear()}async loadCacheSessionIntoSDK(){const e=await this.cacheManager.getToken();if(e==null)return;const t=e.access_token,n=e.refresh_token||"",r=e.id_token,c=e.expires_at;this.tokenProvider=this.tokenProvider.WithAccessToken(t,c).WithRefreshToken(n).WithIdToken(r)}getBearerTokenHttpClient(e){return new l.BearerTokenHttpClientProvider(this.tokenProvider,e)}getRedirectUrl(){return this.redirectUrl}}const w=d.createContext(null),O=()=>d.useContext(w)??{},Z=(i,e)=>{switch(e.type){case"INIT":return{...i,isLoading:!1,isAuthenticated:e.user!=null,user:e.user,error:void 0};case"GET_TOKENS_COMPLETE":case"HANDLE_CALLBACK_COMPLETE":case"GET_ACCESS_TOKEN_COMPLETE":return{...i,isLoading:!1,isAuthenticated:e.user!=null,user:e.user,error:void 0};case"LOGOUT":return{...i,isAuthenticated:!1,user:void 0};case"ERROR":return{...i,isLoading:!1,error:e.error}}},ee={isLoading:!0,isAuthenticated:!1},te=i=>{if(i==null||Object.keys(i).length<=0)return!0;const e=Object.keys(i);for(const t of e)if(i[t]!=null&&i[t]!=="")return!1;return!0},ie=i=>!te(i.config),ne=i=>{const{children:e,configurationEndpoint:t,clientId:n,redirectUrl:r,logoutRedirectUrl:c,scopes:h,onRedirectCallback:y,checkRedirectUrlMatch:T}=i;if(d.useContext(w)!=null)throw new Error("TID Provider already defined");const P={config:{configurationEndpoint:t??"",clientId:n??"",redirectUrl:r??"",logoutRedirectUrl:c??"",scopes:h??[""]}},[a]=d.useState(i.tidClient??new A(P)),[v,m]=d.useReducer(Z,ee),D=d.useRef(!1),se=d.useMemo(()=>T?a.getRedirectUrl():void 0,[T,a]);d.useEffect(()=>{D.current||(i.tidClient!=null&&ie({config:{configurationEndpoint:t,clientId:n,redirectUrl:r,logoutRedirectUrl:c,scopes:h}})&&console.warn("When TID client is pass as prop, any client configuration property sent directly to the TID Provider component will be ignored"),D.current=!0,(async()=>{try{let s;if(B(void 0,se)){const k=await a.handleCallback();s=await a.getUser(),y!=null&&y(k)}else await a.loadUserSession(),s=await a.getUser();m({type:"INIT",user:s})}catch(s){let k=s;typeof s=="string"&&(k=new Error(s)),m({type:"ERROR",error:k})}})())},[a,y]);const b=d.useCallback(async()=>{const s=await a.getAccessTokenSilently(),k=await a.getUser();return m({type:"GET_ACCESS_TOKEN_COMPLETE",user:k}),s},[a]),L=d.useCallback(async()=>{const s=await a.getTokens(),k=await a.getUser();return m({type:"GET_TOKENS_COMPLETE",user:k}),s},[a]),N=d.useCallback(async s=>{await a.loginWithRedirect(s)},[a]),V=d.useCallback(async s=>{await a.logout(s),(s==null?void 0:s.disabledAutoRedirect)!=null&&s.disabledAutoRedirect&&m({type:"LOGOUT"})},[a]),K=d.useCallback(async s=>{const k=await a.handleCallback(s),le=await a.getUser();return m({type:"HANDLE_CALLBACK_COMPLETE",user:le}),k},[a]),ce=d.useMemo(()=>({...v,getAccessTokenSilently:b,getTokens:L,loginWithRedirect:N,handleCallback:K,logout:V}),[v,b,L,N,K,V]);return E.jsx(w.Provider,{value:ce,children:e})},re=O,ae=ne,oe=({renderComponent:i,loader:e})=>{const{isAuthenticated:t,isLoading:n,loginWithRedirect:r}=O();return d.useEffect(()=>{!n&&!t&&(async()=>await r())()},[n,t,r]),t?i:e||E.jsx(E.Fragment,{})};o.AuthenticationGuard=oe,o.TIDClient=A,o.TIDContext=w,o.TIDProvider=ae,o.useAuth=re,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED