@trimble-oss/trimble-id-react 1.0.1 → 1.0.2-rc1
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 +6 -6
- package/dist/TIDClient/TIDClient.d.ts +0 -5
- package/dist/TIDClient/interfaces.d.ts +7 -0
- package/dist/trimble-id-react.es.js +261 -240
- package/dist/trimble-id-react.umd.js +1 -1
- package/package.json +17 -16
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 function receives an `authState` parameter that contains a `
|
|
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 `returnTo` 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:
|
|
@@ -103,9 +103,9 @@ After wrapping your app with the TIDProvider, you have to configure the TID cred
|
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
```tsx
|
|
106
|
-
const handleRedirect = (authState) => {
|
|
107
|
-
// Use
|
|
108
|
-
const redirectTo = authState.
|
|
106
|
+
const handleRedirect = (authState: AuthState) => {
|
|
107
|
+
// Use returnTo for automatic redirection to original location
|
|
108
|
+
const redirectTo = authState.returnTo || '/dashboard'
|
|
109
109
|
// Navigate to the intended destination
|
|
110
110
|
navigate(redirectTo)
|
|
111
111
|
}
|
|
@@ -150,8 +150,8 @@ const { handleCallback } = useAuth()
|
|
|
150
150
|
// Handle callback and get redirect information
|
|
151
151
|
const authState = await handleCallback()
|
|
152
152
|
|
|
153
|
-
// Use
|
|
154
|
-
const redirectTo = authState.
|
|
153
|
+
// Use returnTo for automatic redirection to original location
|
|
154
|
+
const redirectTo = authState.returnTo || '/dashboard'
|
|
155
155
|
navigate(redirectTo)
|
|
156
156
|
```
|
|
157
157
|
|
|
@@ -90,11 +90,6 @@ export declare class TIDClient {
|
|
|
90
90
|
* @type {string}
|
|
91
91
|
*/
|
|
92
92
|
private readonly redirectUrl;
|
|
93
|
-
/**
|
|
94
|
-
* AnalyticsHttpClient for sending events
|
|
95
|
-
* @type {AnalyticsHttpClient}
|
|
96
|
-
*/
|
|
97
|
-
private readonly analyticshttpclient;
|
|
98
93
|
/**
|
|
99
94
|
* Create a TID client to handle manage all user authentication functions and information
|
|
100
95
|
* @param {CacheManagerOptions} props - TID client configuration
|
|
@@ -51,6 +51,8 @@ export interface TIDUser {
|
|
|
51
51
|
email?: string;
|
|
52
52
|
/** True if the End-User's e-mail address has been verified; otherwise false. */
|
|
53
53
|
email_verified?: boolean;
|
|
54
|
+
/** Account id of the user */
|
|
55
|
+
account_id?: string;
|
|
54
56
|
}
|
|
55
57
|
export interface TIDJWTUser {
|
|
56
58
|
/**
|
|
@@ -172,6 +174,11 @@ export interface TIDJWTUser {
|
|
|
172
174
|
* @type {string}
|
|
173
175
|
*/
|
|
174
176
|
data_region: string;
|
|
177
|
+
/**
|
|
178
|
+
* Account id of the user
|
|
179
|
+
* @type {string}
|
|
180
|
+
*/
|
|
181
|
+
account_id: string;
|
|
175
182
|
}
|
|
176
183
|
export interface AuthState {
|
|
177
184
|
authState: any;
|
|
@@ -1,75 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return e.token = void 0, e.user = void 0, Promise.resolve(void 0);
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
}());
|
|
63
|
-
}
|
|
1
|
+
import { OpenIdEndpointProvider as $, AuthorizationCodeGrantTokenProvider as R, AnalyticsHttpClient as h, BearerTokenHttpClientProvider as B } from "@trimble-oss/trimble-id";
|
|
2
|
+
import * as m from "es-cookie";
|
|
3
|
+
import J from "jwt-decode";
|
|
4
|
+
import { createContext as H, useContext as L, useState as Q, useReducer as X, useRef as q, useMemo as M, useEffect as N, useCallback as y } from "react";
|
|
5
|
+
import { jsx as V, Fragment as z } from "react/jsx-runtime";
|
|
6
|
+
class Y {
|
|
7
|
+
/**
|
|
8
|
+
* This function generate a encapsulation function to store
|
|
9
|
+
* the user and token information in a secure way disabled the
|
|
10
|
+
* access from the outside
|
|
11
|
+
* @see {https://medium.com/javascript-scene/encapsulation-in-javascript-26be60e325b4} Encapsulation
|
|
12
|
+
* @return {CacheStorage} Key for the token
|
|
13
|
+
*/
|
|
14
|
+
generateCache = /* @__PURE__ */ (function() {
|
|
15
|
+
const e = {
|
|
16
|
+
token: void 0,
|
|
17
|
+
user: void 0
|
|
18
|
+
};
|
|
19
|
+
return {
|
|
20
|
+
/**
|
|
21
|
+
* Get token store in cache
|
|
22
|
+
* @return {Promise<TIDAuthToken | undefined>} Token store in memory
|
|
23
|
+
*/
|
|
24
|
+
async getToken() {
|
|
25
|
+
return e.token;
|
|
26
|
+
},
|
|
27
|
+
/**
|
|
28
|
+
* Get user store in cache
|
|
29
|
+
* @return {Promise<TIDUser | undefined>} User store in memory
|
|
30
|
+
*/
|
|
31
|
+
async getUser() {
|
|
32
|
+
return e.user;
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* Store token in cache
|
|
36
|
+
* @param {TIDAuthToken} token - Token that you want to store in cache
|
|
37
|
+
* @return {Promise<void>} Empty promise
|
|
38
|
+
*/
|
|
39
|
+
async storeToken(t) {
|
|
40
|
+
e.token = t;
|
|
41
|
+
},
|
|
42
|
+
/**
|
|
43
|
+
* Store user in cache
|
|
44
|
+
* @param {TIDUser} user - User that you want to store in cache
|
|
45
|
+
* @return {Promise<void>} Empty promise
|
|
46
|
+
*/
|
|
47
|
+
async storeUser(t) {
|
|
48
|
+
e.user = t;
|
|
49
|
+
},
|
|
50
|
+
/**
|
|
51
|
+
* The clear the cache from the storage
|
|
52
|
+
* @return {Promise<void>} Empty promise
|
|
53
|
+
*/
|
|
54
|
+
clear() {
|
|
55
|
+
return e.token = void 0, e.user = void 0, Promise.resolve(void 0);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
})();
|
|
64
59
|
}
|
|
65
|
-
class
|
|
60
|
+
class Z {
|
|
61
|
+
/**
|
|
62
|
+
* Cache option selected
|
|
63
|
+
* @type {CacheStorage}
|
|
64
|
+
*/
|
|
65
|
+
cacheStorage;
|
|
66
66
|
constructor() {
|
|
67
|
-
|
|
68
|
-
* Cache option selected
|
|
69
|
-
* @type {CacheStorage}
|
|
70
|
-
*/
|
|
71
|
-
l(this, "cacheStorage");
|
|
72
|
-
this.cacheStorage = new ee().generateCache;
|
|
67
|
+
this.cacheStorage = new Y().generateCache;
|
|
73
68
|
}
|
|
74
69
|
/**
|
|
75
70
|
* Store token in cache
|
|
@@ -109,41 +104,42 @@ class te {
|
|
|
109
104
|
await this.cacheStorage.clear();
|
|
110
105
|
}
|
|
111
106
|
}
|
|
112
|
-
const x = 5 * 6e4,
|
|
113
|
-
let e =
|
|
114
|
-
if (!
|
|
107
|
+
const x = 5 * 6e4, j = ["code", "state"], A = 600 * 1e3, U = (o) => o.split("?")[0], ee = (o) => o.split("?")[1], b = (o) => {
|
|
108
|
+
let e = o;
|
|
109
|
+
if (!o.startsWith("?"))
|
|
115
110
|
try {
|
|
116
|
-
e = new URL(
|
|
111
|
+
e = new URL(o).search;
|
|
117
112
|
} catch {
|
|
118
113
|
}
|
|
119
114
|
return new URLSearchParams(e);
|
|
120
|
-
},
|
|
115
|
+
}, te = (o = window.location.href, e) => {
|
|
121
116
|
if (e != null) {
|
|
122
|
-
const r = U(e), n = U(
|
|
117
|
+
const r = U(e), n = U(o ?? "");
|
|
123
118
|
if (r !== n)
|
|
124
119
|
return !1;
|
|
125
120
|
}
|
|
126
|
-
const t = b(
|
|
127
|
-
for (const r of
|
|
121
|
+
const t = b(o);
|
|
122
|
+
for (const r of j)
|
|
128
123
|
if (!t.has(r))
|
|
129
124
|
return !1;
|
|
130
125
|
return !0;
|
|
131
|
-
},
|
|
132
|
-
id:
|
|
133
|
-
name: `${
|
|
134
|
-
given_name:
|
|
135
|
-
family_name:
|
|
136
|
-
picture:
|
|
137
|
-
email:
|
|
138
|
-
email_verified:
|
|
139
|
-
|
|
140
|
-
|
|
126
|
+
}, oe = (o) => ({
|
|
127
|
+
id: o.sub,
|
|
128
|
+
name: `${o.given_name} ${o.family_name}`,
|
|
129
|
+
given_name: o.given_name,
|
|
130
|
+
family_name: o.family_name,
|
|
131
|
+
picture: o.picture,
|
|
132
|
+
email: o.email,
|
|
133
|
+
email_verified: o.email_verified,
|
|
134
|
+
...o.account_id && { account_id: o.account_id }
|
|
135
|
+
}), re = "@TID_COOKIE";
|
|
136
|
+
class ne {
|
|
141
137
|
/**
|
|
142
138
|
* Retrieve a cookie from the browser
|
|
143
139
|
* @param {string} key - Key to retrieve the cookies
|
|
144
140
|
*/
|
|
145
141
|
get(e) {
|
|
146
|
-
const t =
|
|
142
|
+
const t = m.get(e);
|
|
147
143
|
if (t == null)
|
|
148
144
|
throw new Error("Cookie not found");
|
|
149
145
|
return JSON.parse(t);
|
|
@@ -163,7 +159,7 @@ class se {
|
|
|
163
159
|
window.location.protocol === "https:" && (n = {
|
|
164
160
|
secure: !0,
|
|
165
161
|
sameSite: "none"
|
|
166
|
-
}), r
|
|
162
|
+
}), r?.expires && (n.expires = r.expires), r?.domain && (n.domain = r.domain), m.set(e, JSON.stringify(t), n);
|
|
167
163
|
}
|
|
168
164
|
/**
|
|
169
165
|
* Remove a cookie from the browser
|
|
@@ -176,26 +172,26 @@ class se {
|
|
|
176
172
|
*/
|
|
177
173
|
remove(e, t) {
|
|
178
174
|
const r = {};
|
|
179
|
-
t
|
|
175
|
+
t?.domain && (r.domain = t.domain), m.remove(e, r);
|
|
180
176
|
}
|
|
181
177
|
}
|
|
182
|
-
class
|
|
178
|
+
class ie {
|
|
179
|
+
/**
|
|
180
|
+
* Cookie full key to store and retrieve the information from cookies
|
|
181
|
+
* @type {string}
|
|
182
|
+
*/
|
|
183
|
+
cookieKey;
|
|
184
|
+
/**
|
|
185
|
+
* Cookie storage. This object contain all functions necessary to retrieve and store tokens using cookies
|
|
186
|
+
* @type {CookiesStorage}
|
|
187
|
+
*/
|
|
188
|
+
cookiesStorage;
|
|
183
189
|
/**
|
|
184
190
|
* Create a cookies manager to extract or save cookies in the browser
|
|
185
191
|
* @param {CookiesManagerOptions} options - Configuration for the managing the cookies
|
|
186
192
|
*/
|
|
187
193
|
constructor(e) {
|
|
188
|
-
|
|
189
|
-
* Cookie full key to store and retrieve the information from cookies
|
|
190
|
-
* @type {string}
|
|
191
|
-
*/
|
|
192
|
-
l(this, "cookieKey");
|
|
193
|
-
/**
|
|
194
|
-
* Cookie storage. This object contain all functions necessary to retrieve and store tokens using cookies
|
|
195
|
-
* @type {CookiesStorage}
|
|
196
|
-
*/
|
|
197
|
-
l(this, "cookiesStorage");
|
|
198
|
-
this.cookieKey = `${oe}.${e.clientId}`, this.cookiesStorage = new se();
|
|
194
|
+
this.cookieKey = `${re}.${e.clientId}`, this.cookiesStorage = new ne();
|
|
199
195
|
}
|
|
200
196
|
/**
|
|
201
197
|
* Store cookies in the browser
|
|
@@ -212,8 +208,7 @@ class ce {
|
|
|
212
208
|
* @return {string | undefined} - State payload from cookies
|
|
213
209
|
*/
|
|
214
210
|
getStatePayload() {
|
|
215
|
-
|
|
216
|
-
return e == null ? void 0 : e.state_payload;
|
|
211
|
+
return this.get()?.state_payload;
|
|
217
212
|
}
|
|
218
213
|
/**
|
|
219
214
|
* Clear state payload from cookies
|
|
@@ -244,66 +239,61 @@ class O extends Error {
|
|
|
244
239
|
}
|
|
245
240
|
class D extends Error {
|
|
246
241
|
}
|
|
247
|
-
class
|
|
242
|
+
class ae extends Error {
|
|
248
243
|
}
|
|
249
|
-
const u = "@trimble-oss/trimble-id-react", g = "1.0.
|
|
244
|
+
const u = "@trimble-oss/trimble-id-react", g = "1.0.2-rc1", se = {
|
|
250
245
|
configurationEndpoint: "",
|
|
251
246
|
clientId: "",
|
|
252
247
|
redirectUrl: "",
|
|
253
248
|
logoutRedirectUrl: "",
|
|
254
249
|
scopes: []
|
|
255
250
|
};
|
|
256
|
-
class
|
|
251
|
+
class ce {
|
|
252
|
+
/**
|
|
253
|
+
* Token provider SDK. This object handles all necessary communication with TID
|
|
254
|
+
* @type {AuthorizationCodeGrantTokenProvider}
|
|
255
|
+
*/
|
|
256
|
+
tokenProvider;
|
|
257
|
+
/**
|
|
258
|
+
* This object manage all caching, and all configurations necessary
|
|
259
|
+
* @type {CacheManager}
|
|
260
|
+
*/
|
|
261
|
+
cacheManager;
|
|
262
|
+
/**
|
|
263
|
+
* This object manage all cookies administration, and all configurations necessary
|
|
264
|
+
* @type {CookiesManager}
|
|
265
|
+
*/
|
|
266
|
+
cookiesManager;
|
|
267
|
+
/**
|
|
268
|
+
* Client id of the application created in trimble developer console
|
|
269
|
+
* @type {string}
|
|
270
|
+
*/
|
|
271
|
+
clientId;
|
|
272
|
+
/**
|
|
273
|
+
* Callback url to redirect the user after the authentication is successful
|
|
274
|
+
* @type {string}
|
|
275
|
+
*/
|
|
276
|
+
redirectUrl;
|
|
257
277
|
/**
|
|
258
278
|
* Create a TID client to handle manage all user authentication functions and information
|
|
259
279
|
* @param {CacheManagerOptions} props - TID client configuration
|
|
260
280
|
*/
|
|
261
281
|
constructor(e) {
|
|
262
|
-
|
|
263
|
-
* Token provider SDK. This object handles all necessary communication with TID
|
|
264
|
-
* @type {AuthorizationCodeGrantTokenProvider}
|
|
265
|
-
*/
|
|
266
|
-
l(this, "tokenProvider");
|
|
267
|
-
/**
|
|
268
|
-
* This object manage all caching, and all configurations necessary
|
|
269
|
-
* @type {CacheManager}
|
|
270
|
-
*/
|
|
271
|
-
l(this, "cacheManager");
|
|
272
|
-
/**
|
|
273
|
-
* This object manage all cookies administration, and all configurations necessary
|
|
274
|
-
* @type {CookiesManager}
|
|
275
|
-
*/
|
|
276
|
-
l(this, "cookiesManager");
|
|
277
|
-
/**
|
|
278
|
-
* Client id of the application created in trimble developer console
|
|
279
|
-
* @type {string}
|
|
280
|
-
*/
|
|
281
|
-
l(this, "clientId");
|
|
282
|
-
/**
|
|
283
|
-
* Callback url to redirect the user after the authentication is successful
|
|
284
|
-
* @type {string}
|
|
285
|
-
*/
|
|
286
|
-
l(this, "redirectUrl");
|
|
287
|
-
/**
|
|
288
|
-
* AnalyticsHttpClient for sending events
|
|
289
|
-
* @type {AnalyticsHttpClient}
|
|
290
|
-
*/
|
|
291
|
-
l(this, "analyticshttpclient");
|
|
292
|
-
const { config: t = de } = e;
|
|
282
|
+
const { config: t = se } = e;
|
|
293
283
|
if (this.redirectUrl = t.redirectUrl, t.configurationEndpoint == null || t.configurationEndpoint == "")
|
|
294
284
|
throw new Error("Configuration endpoint not defined");
|
|
295
285
|
if (t.clientId == null || t.clientId == "")
|
|
296
286
|
throw new Error("Consumer key is not defined");
|
|
297
|
-
this.cookiesManager = new
|
|
287
|
+
this.cookiesManager = new ie({
|
|
298
288
|
clientId: t.clientId
|
|
299
289
|
});
|
|
300
|
-
const r = this.cookiesManager.get(), n = new
|
|
301
|
-
let
|
|
290
|
+
const r = this.cookiesManager.get(), n = new $(t.configurationEndpoint);
|
|
291
|
+
let i = new R(
|
|
302
292
|
n,
|
|
303
293
|
t.clientId,
|
|
304
294
|
t.redirectUrl
|
|
305
295
|
).WithScopes(t.scopes);
|
|
306
|
-
t.logoutRedirectUrl && (
|
|
296
|
+
t.logoutRedirectUrl && (i = i.WithLogoutRedirect(t.logoutRedirectUrl)), r?.code_verifier != null && (i = i.WithProofKeyForCodeExchange(r.code_verifier)), this.tokenProvider = i, this.cacheManager = new Z(), this.clientId = t.clientId, h.sendInitEvent("TIDClient", this.clientId, u, g), this.cleanupExpiredState();
|
|
307
297
|
}
|
|
308
298
|
/**
|
|
309
299
|
* Clean up expired state payloads to prevent storage bloat
|
|
@@ -333,11 +323,11 @@ class he {
|
|
|
333
323
|
* // So it can be handled by the developer
|
|
334
324
|
*/
|
|
335
325
|
async loginWithRedirect(e) {
|
|
336
|
-
|
|
326
|
+
h.sendMethodEvent(this.loginWithRedirect.name, this.clientId, u, g);
|
|
337
327
|
const { onRedirect: t } = e || {}, r = window.location.pathname + window.location.search, n = this.createStatePayload(r);
|
|
338
328
|
this.cookiesManager.save({ state_payload: n });
|
|
339
|
-
const
|
|
340
|
-
this.cookiesManager.save({ code_verifier:
|
|
329
|
+
const i = R.GenerateCodeVerifier();
|
|
330
|
+
this.cookiesManager.save({ code_verifier: i }), this.tokenProvider = this.tokenProvider.WithProofKeyForCodeExchange(i);
|
|
341
331
|
const c = await this.tokenProvider.GetOAuthRedirect(n);
|
|
342
332
|
t != null ? t(c) : window.location.assign(c);
|
|
343
333
|
}
|
|
@@ -356,12 +346,12 @@ class he {
|
|
|
356
346
|
*/
|
|
357
347
|
async handleCallback(e = window.location.href) {
|
|
358
348
|
const t = this.cookiesManager.get();
|
|
359
|
-
if (t == null ||
|
|
360
|
-
throw new
|
|
361
|
-
const r =
|
|
349
|
+
if (t == null || t?.code_verifier == null)
|
|
350
|
+
throw new ae("Code verifier not available");
|
|
351
|
+
const r = ee(e), n = b(e), i = n.get("identity_provider") ?? "", c = n.get("state") ?? "", d = this.validateStatePayload(c);
|
|
362
352
|
if (!d.isValid)
|
|
363
353
|
throw new Error(`State validation failed: ${d.error}`);
|
|
364
|
-
return await this.tokenProvider.ValidateQuery(r), await this.generateToken(
|
|
354
|
+
return await this.tokenProvider.ValidateQuery(r), await this.generateToken(i), {
|
|
365
355
|
authState: c,
|
|
366
356
|
returnTo: d.redirectTo
|
|
367
357
|
};
|
|
@@ -372,10 +362,9 @@ class he {
|
|
|
372
362
|
* @return {Promise<void>} Empty promise
|
|
373
363
|
*/
|
|
374
364
|
async generateToken(e) {
|
|
375
|
-
|
|
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(" ");
|
|
365
|
+
const t = await this.tokenProvider.RetrieveToken(), r = await this.tokenProvider.RetrieveRefreshToken(), n = await this.tokenProvider.RetrieveIdToken(), i = await this.tokenProvider.RetrieveTokenExpiry(), d = new Date(i).getTime(), k = this.tokenProvider?._scopes?.join(" ");
|
|
377
366
|
await this.cacheManager.setToken({
|
|
378
|
-
scope:
|
|
367
|
+
scope: k,
|
|
379
368
|
state: "",
|
|
380
369
|
session_state: "",
|
|
381
370
|
identity_provider: e,
|
|
@@ -385,7 +374,7 @@ class he {
|
|
|
385
374
|
id_token: n,
|
|
386
375
|
expires_at: d
|
|
387
376
|
});
|
|
388
|
-
const v =
|
|
377
|
+
const v = J(n), p = oe(v);
|
|
389
378
|
await this.cacheManager.setUser(p), await this.reloadCodeVerifier();
|
|
390
379
|
}
|
|
391
380
|
async reloadCodeVerifier() {
|
|
@@ -425,13 +414,16 @@ class he {
|
|
|
425
414
|
const t = this.cookiesManager.getStatePayload();
|
|
426
415
|
if (!t)
|
|
427
416
|
return { isValid: !1, error: "No stored state found" };
|
|
428
|
-
const r = atob(e), n = JSON.parse(r),
|
|
417
|
+
const r = atob(e), n = JSON.parse(r), i = atob(t), c = JSON.parse(i);
|
|
429
418
|
if (!n.nonce || !n.timestamp || !n.redirectTo)
|
|
430
419
|
return { isValid: !1, error: "Invalid state payload structure" };
|
|
431
420
|
if (n.nonce !== c.nonce)
|
|
432
421
|
return { isValid: !1, error: "State nonce mismatch" };
|
|
433
|
-
const
|
|
434
|
-
return
|
|
422
|
+
const k = Date.now() - n.timestamp;
|
|
423
|
+
return k > A ? { isValid: !1, error: "State expired - possible replay attack" } : k < 0 ? {
|
|
424
|
+
isValid: !1,
|
|
425
|
+
error: "State timestamp is in the future - possible replay attack"
|
|
426
|
+
} : (this.cookiesManager.clearStatePayload(), {
|
|
435
427
|
isValid: !0,
|
|
436
428
|
redirectTo: n.redirectTo
|
|
437
429
|
});
|
|
@@ -444,7 +436,7 @@ class he {
|
|
|
444
436
|
* @return {Promise<TIDUser | undefined>} User in cache
|
|
445
437
|
*/
|
|
446
438
|
async getUser() {
|
|
447
|
-
return
|
|
439
|
+
return h.sendMethodEvent(this.getUser.name, this.clientId, u, g), await this.cacheManager.getUser();
|
|
448
440
|
}
|
|
449
441
|
/**
|
|
450
442
|
* Gets the access token from cache. If the token already expired,
|
|
@@ -454,46 +446,75 @@ class he {
|
|
|
454
446
|
* @throws {TokenExpiredException} Will throw an exception if the user token expired
|
|
455
447
|
*/
|
|
456
448
|
async getAccessTokenSilently() {
|
|
457
|
-
|
|
449
|
+
h.sendMethodEvent(
|
|
450
|
+
this.getAccessTokenSilently.name,
|
|
451
|
+
this.clientId,
|
|
452
|
+
u,
|
|
453
|
+
g
|
|
454
|
+
);
|
|
458
455
|
let e = await this.cacheManager.getToken();
|
|
459
456
|
if (e == null)
|
|
460
|
-
throw
|
|
457
|
+
throw h.sendExceptionEvent(
|
|
458
|
+
this.getAccessTokenSilently.name,
|
|
459
|
+
"No token available",
|
|
460
|
+
this.clientId,
|
|
461
|
+
u,
|
|
462
|
+
g
|
|
463
|
+
), new D("No token available");
|
|
461
464
|
const t = new Date((/* @__PURE__ */ new Date()).getTime() + x);
|
|
462
|
-
if (
|
|
465
|
+
if (e?.expires_at == null || e?.expires_at < t.getTime()) {
|
|
463
466
|
try {
|
|
464
467
|
await this.tokenProvider.RetrieveToken();
|
|
465
468
|
} catch (r) {
|
|
466
|
-
throw
|
|
469
|
+
throw h.sendExceptionEvent(
|
|
470
|
+
this.getAccessTokenSilently.name,
|
|
471
|
+
r.message,
|
|
472
|
+
this.clientId,
|
|
473
|
+
u,
|
|
474
|
+
g
|
|
475
|
+
), new O(r.message);
|
|
467
476
|
}
|
|
468
|
-
await this.generateToken(
|
|
477
|
+
await this.generateToken(e?.identity_provider ?? ""), e = await this.cacheManager.getToken();
|
|
469
478
|
}
|
|
470
|
-
return
|
|
479
|
+
return e?.access_token || "";
|
|
471
480
|
}
|
|
472
481
|
/**
|
|
473
482
|
* Retrieves token details from the cache, including the access token, ID token, and expiration time.
|
|
474
|
-
* If the token already expired, will try to refresh it using the refresh token.
|
|
483
|
+
* If the token already expired, will try to refresh it using the refresh token.
|
|
475
484
|
* @return {Promise<TokenResponse>} Token response
|
|
476
485
|
* @throws {TokenNotFoundException} Will throw an exception if there are no tokens in cache
|
|
477
486
|
* @throws {TokenExpiredException} Will throw an exception if the user token expired
|
|
478
487
|
*/
|
|
479
488
|
async getTokens() {
|
|
480
|
-
|
|
489
|
+
h.sendMethodEvent(this.getTokens.name, this.clientId, u, g);
|
|
481
490
|
let e = await this.cacheManager.getToken();
|
|
482
491
|
if (e == null)
|
|
483
|
-
throw
|
|
492
|
+
throw h.sendExceptionEvent(
|
|
493
|
+
this.getTokens.name,
|
|
494
|
+
"No token available",
|
|
495
|
+
this.clientId,
|
|
496
|
+
u,
|
|
497
|
+
g
|
|
498
|
+
), new D("No token available");
|
|
484
499
|
const t = new Date((/* @__PURE__ */ new Date()).getTime() + x);
|
|
485
|
-
if (
|
|
500
|
+
if (e?.expires_at == null || e?.expires_at < t.getTime()) {
|
|
486
501
|
try {
|
|
487
502
|
await this.tokenProvider.RetrieveToken();
|
|
488
503
|
} catch (r) {
|
|
489
|
-
throw
|
|
504
|
+
throw h.sendExceptionEvent(
|
|
505
|
+
this.getTokens.name,
|
|
506
|
+
r.message,
|
|
507
|
+
this.clientId,
|
|
508
|
+
u,
|
|
509
|
+
g
|
|
510
|
+
), new O(r.message);
|
|
490
511
|
}
|
|
491
|
-
await this.generateToken(
|
|
512
|
+
await this.generateToken(e?.identity_provider ?? ""), e = await this.cacheManager.getToken();
|
|
492
513
|
}
|
|
493
514
|
return {
|
|
494
|
-
access_token:
|
|
495
|
-
expires_at:
|
|
496
|
-
id_token:
|
|
515
|
+
access_token: e?.access_token || "",
|
|
516
|
+
expires_at: e?.expires_at || 0,
|
|
517
|
+
id_token: e?.id_token || ""
|
|
497
518
|
};
|
|
498
519
|
}
|
|
499
520
|
/**
|
|
@@ -509,7 +530,7 @@ class he {
|
|
|
509
530
|
* // So it can be handled by the developer
|
|
510
531
|
*/
|
|
511
532
|
async logout(e) {
|
|
512
|
-
|
|
533
|
+
h.sendMethodEvent(this.logout.name, this.clientId, u, g);
|
|
513
534
|
const { onRedirect: t, disabledAutoRedirect: r } = e || {};
|
|
514
535
|
this.cacheManager && await this.cacheManager.clear(), this.cookiesManager && this.cookiesManager.clear();
|
|
515
536
|
const n = await this.tokenProvider.GetOAuthLogoutRedirect("state");
|
|
@@ -544,15 +565,15 @@ class he {
|
|
|
544
565
|
const e = await this.cacheManager.getToken();
|
|
545
566
|
if (e == null)
|
|
546
567
|
return;
|
|
547
|
-
const t = e.access_token, r = e.refresh_token || "", n = e.id_token,
|
|
548
|
-
this.tokenProvider = this.tokenProvider.WithAccessToken(t,
|
|
568
|
+
const t = e.access_token, r = e.refresh_token || "", n = e.id_token, i = e.expires_at;
|
|
569
|
+
this.tokenProvider = this.tokenProvider.WithAccessToken(t, i).WithRefreshToken(r).WithIdToken(n);
|
|
549
570
|
}
|
|
550
571
|
/**
|
|
551
572
|
* Get a http bearer token client to use it for another SDK (Ex: Processing framework)
|
|
552
573
|
* @return {any} - BearerTokenHttpClientProvider
|
|
553
574
|
*/
|
|
554
575
|
getBearerTokenHttpClient(e) {
|
|
555
|
-
return new
|
|
576
|
+
return new B(this.tokenProvider, e);
|
|
556
577
|
}
|
|
557
578
|
/**
|
|
558
579
|
* Get the redirect url to TID
|
|
@@ -562,11 +583,11 @@ class he {
|
|
|
562
583
|
return this.redirectUrl;
|
|
563
584
|
}
|
|
564
585
|
}
|
|
565
|
-
const
|
|
586
|
+
const T = H(null), K = () => L(T) ?? {}, de = (o, e) => {
|
|
566
587
|
switch (e.type) {
|
|
567
588
|
case "INIT":
|
|
568
589
|
return {
|
|
569
|
-
...
|
|
590
|
+
...o,
|
|
570
591
|
isLoading: !1,
|
|
571
592
|
isAuthenticated: e.user != null,
|
|
572
593
|
user: e.user,
|
|
@@ -576,7 +597,7 @@ const w = q(null), K = () => L(w) ?? {}, ue = (i, e) => {
|
|
|
576
597
|
case "HANDLE_CALLBACK_COMPLETE":
|
|
577
598
|
case "GET_ACCESS_TOKEN_COMPLETE":
|
|
578
599
|
return {
|
|
579
|
-
...
|
|
600
|
+
...o,
|
|
580
601
|
isLoading: !1,
|
|
581
602
|
isAuthenticated: e.user != null,
|
|
582
603
|
user: e.user,
|
|
@@ -584,134 +605,134 @@ const w = q(null), K = () => L(w) ?? {}, ue = (i, e) => {
|
|
|
584
605
|
};
|
|
585
606
|
case "LOGOUT":
|
|
586
607
|
return {
|
|
587
|
-
...
|
|
608
|
+
...o,
|
|
588
609
|
isAuthenticated: !1,
|
|
589
610
|
user: void 0
|
|
590
611
|
};
|
|
591
612
|
case "ERROR":
|
|
592
613
|
return {
|
|
593
|
-
...
|
|
614
|
+
...o,
|
|
594
615
|
isLoading: !1,
|
|
595
616
|
error: e.error
|
|
596
617
|
};
|
|
597
618
|
}
|
|
598
|
-
},
|
|
619
|
+
}, le = {
|
|
599
620
|
isLoading: !0,
|
|
600
621
|
isAuthenticated: !1
|
|
601
|
-
},
|
|
602
|
-
if (
|
|
622
|
+
}, he = (o) => {
|
|
623
|
+
if (o == null || Object.keys(o).length <= 0)
|
|
603
624
|
return !0;
|
|
604
|
-
const e = Object.keys(
|
|
625
|
+
const e = Object.keys(o);
|
|
605
626
|
for (const t of e)
|
|
606
|
-
if (
|
|
627
|
+
if (o[t] != null && o[t] !== "")
|
|
607
628
|
return !1;
|
|
608
629
|
return !0;
|
|
609
|
-
},
|
|
630
|
+
}, ue = (o) => !he(o.config), ge = (o) => {
|
|
610
631
|
const {
|
|
611
632
|
children: e,
|
|
612
633
|
configurationEndpoint: t,
|
|
613
634
|
clientId: r,
|
|
614
635
|
redirectUrl: n,
|
|
615
|
-
logoutRedirectUrl:
|
|
636
|
+
logoutRedirectUrl: i,
|
|
616
637
|
scopes: c,
|
|
617
638
|
onRedirectCallback: d,
|
|
618
|
-
checkRedirectUrlMatch:
|
|
619
|
-
} =
|
|
620
|
-
if (L(
|
|
639
|
+
checkRedirectUrlMatch: k
|
|
640
|
+
} = o;
|
|
641
|
+
if (L(T) != null)
|
|
621
642
|
throw new Error("TID Provider already defined");
|
|
622
643
|
const p = {
|
|
623
644
|
config: {
|
|
624
645
|
configurationEndpoint: t ?? "",
|
|
625
646
|
clientId: r ?? "",
|
|
626
647
|
redirectUrl: n ?? "",
|
|
627
|
-
logoutRedirectUrl:
|
|
648
|
+
logoutRedirectUrl: i ?? "",
|
|
628
649
|
scopes: c ?? [""]
|
|
629
650
|
}
|
|
630
|
-
}, [a] =
|
|
631
|
-
() =>
|
|
632
|
-
[
|
|
651
|
+
}, [a] = Q(o.tidClient ?? new ce(p)), [w, f] = X(de, le), E = q(!1), W = M(
|
|
652
|
+
() => k ? a.getRedirectUrl() : void 0,
|
|
653
|
+
[k, a]
|
|
633
654
|
);
|
|
634
655
|
N(() => {
|
|
635
|
-
E.current || (
|
|
656
|
+
E.current || (o.tidClient != null && ue({
|
|
636
657
|
config: {
|
|
637
658
|
configurationEndpoint: t,
|
|
638
659
|
clientId: r,
|
|
639
660
|
redirectUrl: n,
|
|
640
|
-
logoutRedirectUrl:
|
|
661
|
+
logoutRedirectUrl: i,
|
|
641
662
|
scopes: c
|
|
642
663
|
}
|
|
643
664
|
}) && console.warn(
|
|
644
665
|
"When TID client is pass as prop, any client configuration property sent directly to the TID Provider component will be ignored"
|
|
645
666
|
), E.current = !0, (async () => {
|
|
646
667
|
try {
|
|
647
|
-
let
|
|
648
|
-
if (
|
|
649
|
-
const
|
|
650
|
-
|
|
668
|
+
let s;
|
|
669
|
+
if (te(void 0, W)) {
|
|
670
|
+
const l = await a.handleCallback();
|
|
671
|
+
s = await a.getUser(), d?.(l);
|
|
651
672
|
} else
|
|
652
|
-
await a.loadUserSession(),
|
|
653
|
-
|
|
654
|
-
} catch (
|
|
655
|
-
let
|
|
656
|
-
typeof
|
|
673
|
+
await a.loadUserSession(), s = await a.getUser();
|
|
674
|
+
f({ type: "INIT", user: s });
|
|
675
|
+
} catch (s) {
|
|
676
|
+
let l = s;
|
|
677
|
+
typeof s == "string" && (l = new Error(s)), f({ type: "ERROR", error: l });
|
|
657
678
|
}
|
|
658
679
|
})());
|
|
659
680
|
}, [a, d]);
|
|
660
|
-
const S =
|
|
661
|
-
const
|
|
662
|
-
return
|
|
681
|
+
const S = y(async () => {
|
|
682
|
+
const s = await a.getAccessTokenSilently(), l = await a.getUser();
|
|
683
|
+
return f({
|
|
663
684
|
type: "GET_ACCESS_TOKEN_COMPLETE",
|
|
664
|
-
user:
|
|
665
|
-
}),
|
|
666
|
-
}, [a]),
|
|
667
|
-
const
|
|
668
|
-
return
|
|
685
|
+
user: l
|
|
686
|
+
}), s;
|
|
687
|
+
}, [a]), _ = y(async () => {
|
|
688
|
+
const s = await a.getTokens(), l = await a.getUser();
|
|
689
|
+
return f({
|
|
669
690
|
type: "GET_TOKENS_COMPLETE",
|
|
670
|
-
user:
|
|
671
|
-
}),
|
|
672
|
-
}, [a]),
|
|
673
|
-
async (
|
|
674
|
-
await a.loginWithRedirect(
|
|
691
|
+
user: l
|
|
692
|
+
}), s;
|
|
693
|
+
}, [a]), P = y(
|
|
694
|
+
async (s) => {
|
|
695
|
+
await a.loginWithRedirect(s);
|
|
675
696
|
},
|
|
676
697
|
[a]
|
|
677
|
-
), C =
|
|
678
|
-
async (
|
|
679
|
-
await a.logout(
|
|
698
|
+
), C = y(
|
|
699
|
+
async (s) => {
|
|
700
|
+
await a.logout(s), s?.disabledAutoRedirect != null && s.disabledAutoRedirect && f({
|
|
680
701
|
type: "LOGOUT"
|
|
681
702
|
});
|
|
682
703
|
},
|
|
683
704
|
[a]
|
|
684
|
-
), I =
|
|
685
|
-
async (
|
|
686
|
-
const
|
|
687
|
-
return
|
|
705
|
+
), I = y(
|
|
706
|
+
async (s) => {
|
|
707
|
+
const l = await a.handleCallback(s), F = await a.getUser();
|
|
708
|
+
return f({
|
|
688
709
|
type: "HANDLE_CALLBACK_COMPLETE",
|
|
689
710
|
user: F
|
|
690
|
-
}),
|
|
711
|
+
}), l;
|
|
691
712
|
},
|
|
692
713
|
[a]
|
|
693
714
|
), G = M(
|
|
694
715
|
() => ({
|
|
695
|
-
...
|
|
716
|
+
...w,
|
|
696
717
|
getAccessTokenSilently: S,
|
|
697
|
-
getTokens:
|
|
698
|
-
loginWithRedirect:
|
|
718
|
+
getTokens: _,
|
|
719
|
+
loginWithRedirect: P,
|
|
699
720
|
handleCallback: I,
|
|
700
721
|
logout: C
|
|
701
722
|
}),
|
|
702
|
-
[
|
|
723
|
+
[w, S, _, P, I, C]
|
|
703
724
|
);
|
|
704
|
-
return /* @__PURE__ */ V(
|
|
705
|
-
},
|
|
725
|
+
return /* @__PURE__ */ V(T.Provider, { value: G, children: e });
|
|
726
|
+
}, me = K, Te = ge, ve = ({ renderComponent: o, loader: e }) => {
|
|
706
727
|
const { isAuthenticated: t, isLoading: r, loginWithRedirect: n } = K();
|
|
707
728
|
return N(() => {
|
|
708
729
|
!r && !t && (async () => await n())();
|
|
709
|
-
}, [r, t, n]), t ?
|
|
730
|
+
}, [r, t, n]), t ? o : e || /* @__PURE__ */ V(z, {});
|
|
710
731
|
};
|
|
711
732
|
export {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
733
|
+
ve as AuthenticationGuard,
|
|
734
|
+
ce as TIDClient,
|
|
735
|
+
T as TIDContext,
|
|
736
|
+
Te as TIDProvider,
|
|
737
|
+
me as useAuth
|
|
717
738
|
};
|
|
@@ -1 +1 @@
|
|
|
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"})});
|
|
1
|
+
(function(d,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):(d=typeof globalThis<"u"?globalThis:d||self,c(d.ReactTID={},d.trimbleId,d.esCookie,d.jwt_decode,d.React,d.jsxRuntime))})(this,(function(d,c,b,K,l,m){"use strict";function W(n){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const t in n)if(t!=="default"){const i=Object.getOwnPropertyDescriptor(n,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:()=>n[t]})}}return e.default=n,Object.freeze(e)}const v=W(b);class G{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 H{cacheStorage;constructor(){this.cacheStorage=new G().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 E=5*6e4,F=["code","state"],S=600*1e3,C=n=>n.split("?")[0],$=n=>n.split("?")[1],P=n=>{let e=n;if(!n.startsWith("?"))try{e=new URL(n).search}catch{}return new URLSearchParams(e)},q=(n=window.location.href,e)=>{if(e!=null){const i=C(e),o=C(n??"");if(i!==o)return!1}const t=P(n);for(const i of F)if(!t.has(i))return!1;return!0},B=n=>({id:n.sub,name:`${n.given_name} ${n.family_name}`,given_name:n.given_name,family_name:n.family_name,picture:n.picture,email:n.email,email_verified:n.email_verified,...n.account_id&&{account_id:n.account_id}}),J="@TID_COOKIE";class j{get(e){const t=v.get(e);if(t==null)throw new Error("Cookie not found");return JSON.parse(t)}set(e,t,i){let o={};window.location.protocol==="https:"&&(o={secure:!0,sameSite:"none"}),i?.expires&&(o.expires=i.expires),i?.domain&&(o.domain=i.domain),v.set(e,JSON.stringify(t),o)}remove(e,t){const i={};t?.domain&&(i.domain=t.domain),v.remove(e,i)}}class z{cookieKey;cookiesStorage;constructor(e){this.cookieKey=`${J}.${e.clientId}`,this.cookiesStorage=new j}save(e){const i={...this.get()||{},...e};this.cookiesStorage.set(this.cookieKey,i,{expires:1})}getStatePayload(){return this.get()?.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 _ extends Error{}class A extends Error{}class Q extends Error{}const h="@trimble-oss/trimble-id-react",g="1.0.2-rc1",X={configurationEndpoint:"",clientId:"",redirectUrl:"",logoutRedirectUrl:"",scopes:[]};class M{tokenProvider;cacheManager;cookiesManager;clientId;redirectUrl;constructor(e){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 z({clientId:t.clientId});const i=this.cookiesManager.get(),o=new c.OpenIdEndpointProvider(t.configurationEndpoint);let r=new c.AuthorizationCodeGrantTokenProvider(o,t.clientId,t.redirectUrl).WithScopes(t.scopes);t.logoutRedirectUrl&&(r=r.WithLogoutRedirect(t.logoutRedirectUrl)),i?.code_verifier!=null&&(r=r.WithProofKeyForCodeExchange(i.code_verifier)),this.tokenProvider=r,this.cacheManager=new H,this.clientId=t.clientId,c.AnalyticsHttpClient.sendInitEvent("TIDClient",this.clientId,h,g),this.cleanupExpiredState()}cleanupExpiredState(){try{const e=this.cookiesManager.getStatePayload();if(e){const t=atob(e),i=JSON.parse(t);Date.now()-i.timestamp>S&&this.cookiesManager.clearStatePayload()}}catch{this.cookiesManager.clearStatePayload()}}async loginWithRedirect(e){c.AnalyticsHttpClient.sendMethodEvent(this.loginWithRedirect.name,this.clientId,h,g);const{onRedirect:t}=e||{},i=window.location.pathname+window.location.search,o=this.createStatePayload(i);this.cookiesManager.save({state_payload:o});const r=c.AuthorizationCodeGrantTokenProvider.GenerateCodeVerifier();this.cookiesManager.save({code_verifier:r}),this.tokenProvider=this.tokenProvider.WithProofKeyForCodeExchange(r);const u=await this.tokenProvider.GetOAuthRedirect(o);t!=null?t(u):window.location.assign(u)}async handleCallback(e=window.location.href){const t=this.cookiesManager.get();if(t==null||t?.code_verifier==null)throw new Q("Code verifier not available");const i=$(e),o=P(e),r=o.get("identity_provider")??"",u=o.get("state")??"",f=this.validateStatePayload(u);if(!f.isValid)throw new Error(`State validation failed: ${f.error}`);return await this.tokenProvider.ValidateQuery(i),await this.generateToken(r),{authState:u,returnTo:f.redirectTo}}async generateToken(e){const t=await this.tokenProvider.RetrieveToken(),i=await this.tokenProvider.RetrieveRefreshToken(),o=await this.tokenProvider.RetrieveIdToken(),r=await this.tokenProvider.RetrieveTokenExpiry(),f=new Date(r).getTime(),y=this.tokenProvider?._scopes?.join(" ");await this.cacheManager.setToken({scope:y,state:"",session_state:"",identity_provider:e,token_type:"bearer",access_token:t,refresh_token:i,id_token:o,expires_at:f});const I=K(o),w=B(I);await this.cacheManager.setUser(w),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(),i=Date.now();return btoa(JSON.stringify({redirectTo:e,timestamp:i,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 i=atob(e),o=JSON.parse(i),r=atob(t),u=JSON.parse(r);if(!o.nonce||!o.timestamp||!o.redirectTo)return{isValid:!1,error:"Invalid state payload structure"};if(o.nonce!==u.nonce)return{isValid:!1,error:"State nonce mismatch"};const y=Date.now()-o.timestamp;return y>S?{isValid:!1,error:"State expired - possible replay attack"}:y<0?{isValid:!1,error:"State timestamp is in the future - possible replay attack"}:(this.cookiesManager.clearStatePayload(),{isValid:!0,redirectTo:o.redirectTo})}catch{return{isValid:!1,error:"Invalid state format"}}}async getUser(){return c.AnalyticsHttpClient.sendMethodEvent(this.getUser.name,this.clientId,h,g),await this.cacheManager.getUser()}async getAccessTokenSilently(){c.AnalyticsHttpClient.sendMethodEvent(this.getAccessTokenSilently.name,this.clientId,h,g);let e=await this.cacheManager.getToken();if(e==null)throw c.AnalyticsHttpClient.sendExceptionEvent(this.getAccessTokenSilently.name,"No token available",this.clientId,h,g),new A("No token available");const t=new Date(new Date().getTime()+E);if(e?.expires_at==null||e?.expires_at<t.getTime()){try{await this.tokenProvider.RetrieveToken()}catch(i){throw c.AnalyticsHttpClient.sendExceptionEvent(this.getAccessTokenSilently.name,i.message,this.clientId,h,g),new _(i.message)}await this.generateToken(e?.identity_provider??""),e=await this.cacheManager.getToken()}return e?.access_token||""}async getTokens(){c.AnalyticsHttpClient.sendMethodEvent(this.getTokens.name,this.clientId,h,g);let e=await this.cacheManager.getToken();if(e==null)throw c.AnalyticsHttpClient.sendExceptionEvent(this.getTokens.name,"No token available",this.clientId,h,g),new A("No token available");const t=new Date(new Date().getTime()+E);if(e?.expires_at==null||e?.expires_at<t.getTime()){try{await this.tokenProvider.RetrieveToken()}catch(i){throw c.AnalyticsHttpClient.sendExceptionEvent(this.getTokens.name,i.message,this.clientId,h,g),new _(i.message)}await this.generateToken(e?.identity_provider??""),e=await this.cacheManager.getToken()}return{access_token:e?.access_token||"",expires_at:e?.expires_at||0,id_token:e?.id_token||""}}async logout(e){c.AnalyticsHttpClient.sendMethodEvent(this.logout.name,this.clientId,h,g);const{onRedirect:t,disabledAutoRedirect:i}=e||{};this.cacheManager&&await this.cacheManager.clear(),this.cookiesManager&&this.cookiesManager.clear();const o=await this.tokenProvider.GetOAuthLogoutRedirect("state");if(t!=null)return t(o);i||window.location.assign(o)}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,i=e.refresh_token||"",o=e.id_token,r=e.expires_at;this.tokenProvider=this.tokenProvider.WithAccessToken(t,r).WithRefreshToken(i).WithIdToken(o)}getBearerTokenHttpClient(e){return new c.BearerTokenHttpClientProvider(this.tokenProvider,e)}getRedirectUrl(){return this.redirectUrl}}const T=l.createContext(null),R=()=>l.useContext(T)??{},Y=(n,e)=>{switch(e.type){case"INIT":return{...n,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{...n,isLoading:!1,isAuthenticated:e.user!=null,user:e.user,error:void 0};case"LOGOUT":return{...n,isAuthenticated:!1,user:void 0};case"ERROR":return{...n,isLoading:!1,error:e.error}}},Z={isLoading:!0,isAuthenticated:!1},ee=n=>{if(n==null||Object.keys(n).length<=0)return!0;const e=Object.keys(n);for(const t of e)if(n[t]!=null&&n[t]!=="")return!1;return!0},te=n=>!ee(n.config),ne=n=>{const{children:e,configurationEndpoint:t,clientId:i,redirectUrl:o,logoutRedirectUrl:r,scopes:u,onRedirectCallback:f,checkRedirectUrlMatch:y}=n;if(l.useContext(T)!=null)throw new Error("TID Provider already defined");const w={config:{configurationEndpoint:t??"",clientId:i??"",redirectUrl:o??"",logoutRedirectUrl:r??"",scopes:u??[""]}},[a]=l.useState(n.tidClient??new M(w)),[x,p]=l.useReducer(Y,Z),O=l.useRef(!1),ae=l.useMemo(()=>y?a.getRedirectUrl():void 0,[y,a]);l.useEffect(()=>{O.current||(n.tidClient!=null&&te({config:{configurationEndpoint:t,clientId:i,redirectUrl:o,logoutRedirectUrl:r,scopes:u}})&&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 s;if(q(void 0,ae)){const k=await a.handleCallback();s=await a.getUser(),f?.(k)}else await a.loadUserSession(),s=await a.getUser();p({type:"INIT",user:s})}catch(s){let k=s;typeof s=="string"&&(k=new Error(s)),p({type:"ERROR",error:k})}})())},[a,f]);const D=l.useCallback(async()=>{const s=await a.getAccessTokenSilently(),k=await a.getUser();return p({type:"GET_ACCESS_TOKEN_COMPLETE",user:k}),s},[a]),U=l.useCallback(async()=>{const s=await a.getTokens(),k=await a.getUser();return p({type:"GET_TOKENS_COMPLETE",user:k}),s},[a]),L=l.useCallback(async s=>{await a.loginWithRedirect(s)},[a]),N=l.useCallback(async s=>{await a.logout(s),s?.disabledAutoRedirect!=null&&s.disabledAutoRedirect&&p({type:"LOGOUT"})},[a]),V=l.useCallback(async s=>{const k=await a.handleCallback(s),ce=await a.getUser();return p({type:"HANDLE_CALLBACK_COMPLETE",user:ce}),k},[a]),se=l.useMemo(()=>({...x,getAccessTokenSilently:D,getTokens:U,loginWithRedirect:L,handleCallback:V,logout:N}),[x,D,U,L,V,N]);return m.jsx(T.Provider,{value:se,children:e})},ie=R,oe=ne,re=({renderComponent:n,loader:e})=>{const{isAuthenticated:t,isLoading:i,loginWithRedirect:o}=R();return l.useEffect(()=>{!i&&!t&&(async()=>await o())()},[i,t,o]),t?n:e||m.jsx(m.Fragment,{})};d.AuthenticationGuard=re,d.TIDClient=M,d.TIDContext=T,d.TIDProvider=oe,d.useAuth=ie,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trimble-oss/trimble-id-react",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.2-rc1",
|
|
5
5
|
"homepage": "https://github.com/trimble-oss/trimble-id-sdk-docs-for-react",
|
|
6
6
|
"author": "Trimble developers <developers@trimble.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"build": "tsc && vite build",
|
|
15
15
|
"test": "jest --coverage",
|
|
16
16
|
"docs": "typedoc --out ./docs/documentation ./src/ --tsconfig ./tsconfig.json",
|
|
17
|
-
"lint": "eslint
|
|
18
|
-
"lint:fix": "eslint --fix
|
|
17
|
+
"lint": "eslint src/",
|
|
18
|
+
"lint:fix": "eslint --fix src/",
|
|
19
19
|
"format": "prettier --write src//**/*.{ts,tsx,css} --config ./.prettierrc",
|
|
20
20
|
"prepare": "husky install"
|
|
21
21
|
},
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"module": "./dist/trimble-id-react.es.js",
|
|
32
32
|
"types": "./dist/index.d.ts",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@trimble-oss/trimble-id": "^0.0
|
|
34
|
+
"@trimble-oss/trimble-id": "^1.0.0",
|
|
35
35
|
"es-cookie": "^1.4.0",
|
|
36
36
|
"husky": "^8.0.3",
|
|
37
37
|
"jwt-decode": "^3.1.2"
|
|
@@ -42,29 +42,30 @@
|
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@babel/preset-env": "^7.22.20",
|
|
45
|
+
"@eslint/js": "^9.37.0",
|
|
45
46
|
"@testing-library/react": "^14.0.0",
|
|
46
47
|
"@types/jest": "^29.5.3",
|
|
47
48
|
"@types/react": "^18.2.15",
|
|
48
49
|
"@types/react-dom": "^18.2.7",
|
|
49
|
-
"@
|
|
50
|
-
"@typescript-eslint/parser": "^6.2.0",
|
|
51
|
-
"@vitejs/plugin-react": "^4.0.3",
|
|
50
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
52
51
|
"babel-jest": "^29.7.0",
|
|
53
|
-
"eslint": "^
|
|
54
|
-
"eslint-config-prettier": "^
|
|
55
|
-
"eslint-plugin-prettier": "^5.
|
|
56
|
-
"eslint-plugin-react": "^7.
|
|
57
|
-
"eslint-plugin-react-hooks": "^
|
|
58
|
-
"eslint-plugin-react-refresh": "^0.4.
|
|
59
|
-
"
|
|
52
|
+
"eslint": "^9.37.0",
|
|
53
|
+
"eslint-config-prettier": "^10.1.8",
|
|
54
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
55
|
+
"eslint-plugin-react": "^7.37.5",
|
|
56
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
57
|
+
"eslint-plugin-react-refresh": "^0.4.26",
|
|
58
|
+
"globals": "^16.2.0",
|
|
59
|
+
"gts": "^7.0.0",
|
|
60
|
+
"typescript-eslint": "^8.46.0",
|
|
60
61
|
"jest": "^29.6.2",
|
|
61
62
|
"jest-environment-jsdom": "^29.6.2",
|
|
62
|
-
"lint-staged": "^
|
|
63
|
+
"lint-staged": "^16.2.7",
|
|
63
64
|
"prettier": "^3.0.0",
|
|
64
65
|
"ts-jest": "^29.1.1",
|
|
65
66
|
"typedoc": "^0.25.2",
|
|
66
67
|
"typescript": "^5.0.2",
|
|
67
|
-
"vite": "^
|
|
68
|
+
"vite": "^7.3.0",
|
|
68
69
|
"vite-plugin-dts": "^1.4.1",
|
|
69
70
|
"vite-plugin-linter": "^1.2.0",
|
|
70
71
|
"vite-tsconfig-paths": "^3.5.0"
|