authscape 1.0.708 → 1.0.710

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.
@@ -1,4 +1,4 @@
1
- import React, {useState, useRef, useEffect} from 'react';
1
+ import React, { useState, useRef, useEffect } from 'react';
2
2
  import { ToastContainer, toast } from 'react-toastify';
3
3
  import { ThemeProvider } from '@mui/material/styles';
4
4
  import Head from "next/head";
@@ -7,545 +7,196 @@ import axios from 'axios';
7
7
  import querystring from "query-string";
8
8
  import Router from 'next/router';
9
9
  import GA4React from 'ga-4-react';
10
- import { create } from 'zustand'
10
+ import { create } from 'zustand';
11
11
  import { clarity } from 'react-microsoft-clarity';
12
12
  import { authService } from 'authscape';
13
13
 
14
- export function AuthScapeApp ({Component, layout, loadingLayout, pageProps, muiTheme = {}, store={}, enforceLoggedIn = false, enableAuth = true, enableConsentDialog = false}) {
15
-
16
- const [frontEndLoadedState, setFrontEndLoadedState] = useState(false);
17
- const [concentState, setConcentState] = useState(false);
18
-
19
- const [isLoadingShow, setIsLoadingShow] = useState(false);
20
-
21
- const [signedInUserState, setSignedInUserState] = useState(null);
22
-
23
- const loadingAuth = useRef(false);
24
- const frontEndLoaded = useRef(false);
25
- const signedInUser = useRef(null);
26
- const queryCodeUsed = useRef(null);
27
-
28
- const ga4React = useRef(null);
29
-
30
- const searchParams = useSearchParams();
31
- const queryRef = searchParams.get('ref');
32
- const queryCode = searchParams.get('code');
33
-
34
- const pathname = usePathname();
35
-
36
- const handleConsentAccepted = (prefs) => {
37
- console.log("Consent accepted:", prefs);
38
- setConcentState(prefs);
39
- };
40
-
41
- const handleConsentRejected = () => {
42
- console.log("Consent rejected");
43
- setConcentState(null);
44
- // disable analytics scripts, etc.
45
- };
46
-
47
- const signInValidator = async (queryCode) => {
48
-
49
- if (queryCodeUsed.current != queryCode)
50
- {
51
- queryCodeUsed.current = queryCode;
52
- }
53
- else
54
- {
55
- return;
56
- }
57
-
58
- let codeVerifier = window.localStorage.getItem("verifier");
59
- if (queryCode != null && codeVerifier != null)
60
- {
61
- const headers = {'Content-Type': 'application/x-www-form-urlencoded'}
62
-
63
- let queryString = querystring.stringify({
64
- code: queryCode,
65
- grant_type: "authorization_code",
66
- redirect_uri: window.location.origin + "/signin-oidc",
67
- client_id: process.env.client_id,
68
- client_secret: process.env.client_secret,
69
- code_verifier: codeVerifier
70
- });
71
-
72
- try
73
- {
74
- let response = await axios.post(process.env.authorityUri + '/connect/token', queryString, {
75
- headers: headers
76
- });
77
-
78
- let domainHost = window.location.hostname.split('.').slice(-2).join('.');
79
- window.localStorage.removeItem("verifier");
80
-
81
- await setCookie('access_token', response.data.access_token, {
82
- maxAge: 60 * 60 * 24 * 365, // 1 year,
83
- path: '/',
84
- domain: domainHost,
85
- secure: true
86
- });
87
-
88
- await setCookie('expires_in', response.data.expires_in, {
89
- maxAge: 60 * 60 * 24 * 365, // 1 year,
90
- path: '/',
91
- domain: domainHost,
92
- secure: true
93
- });
94
-
95
- await setCookie('refresh_token', response.data.refresh_token, {
96
- maxAge: 60 * 60 * 24 * 365, // 1 year,
97
- path: '/',
98
- domain: domainHost,
99
- secure: true
100
- });
101
-
102
- // await setCookie(null, "access_token", response.data.access_token,
103
- // {
104
- // maxAge: 2147483647,
105
- // path: '/',
106
- // domain: domainHost,
107
- // secure: true
108
- // });
109
-
110
- // await setCookie(null, "expires_in", response.data.expires_in,
111
- // {
112
- // maxAge: 2147483647,
113
- // path: '/',
114
- // domain: domainHost,
115
- // secure: true
116
- // });
117
-
118
- // await setCookie(null, "refresh_token", response.data.refresh_token,
119
- // {
120
- // maxAge: 2147483647,
121
- // path: '/',
122
- // domain: domainHost,
123
- // secure: true
124
- // });
125
-
126
-
127
- let redirectUri = localStorage.getItem("redirectUri")
128
- localStorage.clear();
129
- if (redirectUri != null)
130
- {
131
- window.location.href = redirectUri;
132
- }
133
- else
134
- {
135
- window.location.href = "/";
136
- }
137
- }
138
- catch(exp)
139
- {
140
- //alert(exp)
141
- }
142
- }
14
+ export function AuthScapeApp({
15
+ Component,
16
+ layout,
17
+ loadingLayout,
18
+ pageProps,
19
+ muiTheme = {},
20
+ store = {},
21
+ enforceLoggedIn = false,
22
+ enableAuth = true
23
+ }) {
24
+ const [frontEndLoadedState, setFrontEndLoadedState] = useState(false);
25
+ const [isLoadingShow, setIsLoadingShow] = useState(false);
26
+ const [signedInUserState, setSignedInUserState] = useState(null);
27
+
28
+ const loadingAuth = useRef(false);
29
+ const signedInUser = useRef(null);
30
+ const queryCodeUsed = useRef(null);
31
+ const ga4React = useRef(null);
32
+
33
+ const searchParams = useSearchParams();
34
+ const queryCode = searchParams.get('code');
35
+ const pathname = usePathname();
36
+
37
+ // ---------- PKCE Sign-in ----------
38
+ const signInValidator = async (queryCode) => {
39
+ if (queryCodeUsed.current === queryCode) return;
40
+ queryCodeUsed.current = queryCode;
41
+
42
+ const codeVerifier = window.localStorage.getItem("verifier");
43
+ if (!queryCode || !codeVerifier) return;
44
+
45
+ const headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
46
+
47
+ const queryString = querystring.stringify({
48
+ code: queryCode,
49
+ grant_type: "authorization_code",
50
+ redirect_uri: window.location.origin + "/signin-oidc",
51
+ client_id: process.env.client_id,
52
+ client_secret: process.env.client_secret,
53
+ code_verifier: codeVerifier
54
+ });
55
+
56
+ try {
57
+ const response = await axios.post(process.env.authorityUri + '/connect/token', queryString, { headers });
58
+ const domainHost = window.location.hostname.split('.').slice(-2).join('.');
59
+
60
+ window.localStorage.removeItem("verifier");
61
+
62
+ await setCookie('access_token', response.data.access_token, {
63
+ maxAge: 60 * 60 * 24 * 365,
64
+ path: '/',
65
+ domain: domainHost,
66
+ secure: true
67
+ });
68
+ await setCookie('expires_in', response.data.expires_in, {
69
+ maxAge: 60 * 60 * 24 * 365,
70
+ path: '/',
71
+ domain: domainHost,
72
+ secure: true
73
+ });
74
+ await setCookie('refresh_token', response.data.refresh_token, {
75
+ maxAge: 60 * 60 * 24 * 365,
76
+ path: '/',
77
+ domain: domainHost,
78
+ secure: true
79
+ });
80
+
81
+ const redirectUri = localStorage.getItem("redirectUri");
82
+ localStorage.clear();
83
+ window.location.href = redirectUri || "/";
84
+ } catch (exp) {
85
+ console.error("PKCE sign-in failed", exp);
143
86
  }
144
-
145
- async function initGA(G) {
146
- if (!GA4React.isInitialized() && G && process.browser) {
147
- ga4React.current = new GA4React(G, { debug_mode: !process.env.production });
148
-
149
- try {
150
-
151
- await ga4React.current.initialize();
152
-
153
- } catch (error) {
154
- console.error(error);
155
- }
156
- }
87
+ };
88
+
89
+ // ---------- GA + Clarity ----------
90
+ async function initGA(G) {
91
+ if (!GA4React.isInitialized() && G && typeof window !== "undefined") {
92
+ ga4React.current = new GA4React(G, { debug_mode: !process.env.production });
93
+ try {
94
+ await ga4React.current.initialize();
95
+ } catch (error) {
96
+ console.error(error);
97
+ }
157
98
  }
99
+ }
158
100
 
159
- const logEvent = (category, action, label) => {
160
-
161
- if (ga4React != null && ga4React.current != null && ga4React != "")
162
- {
163
- ga4React.current.event(action, label, category);
164
- }
165
-
166
- if (process.env.enableDatabaseAnalytics == "true")
167
- {
168
- let userId = null;
169
- let locationId = null;
170
- let companyId = null;
171
-
172
- var host = window.location.protocol + "//" + window.location.host;
173
-
174
- if (signedInUser.current != null)
175
- {
176
- userId = signedInUser.current.id;
177
- locationId = signedInUser.current.locationId;
178
- companyId = signedInUser.current.companyId;
179
- }
180
-
181
- apiService().post("/Analytics/Event", {
182
- userId: userId,
183
- locationId: locationId,
184
- companyId: companyId,
185
- uri: window.location.pathname,
186
- category: category,
187
- action: action,
188
- label: label,
189
- host: host
190
- });
191
- }
192
- }
193
-
194
- const databaseDrivenPageView = (pathName) => {
195
-
196
- if (process.env.enableDatabaseAnalytics == "true")
197
- {
198
- let userId = null;
199
- let locationId = null;
200
- let companyId = null;
201
-
202
- var host = window.location.protocol + "//" + window.location.host;
203
-
204
- if (signedInUser.current != null)
205
- {
206
- userId = signedInUser.current.id;
207
- locationId = signedInUser.current.locationId;
208
- companyId = signedInUser.current.companyId;
209
- }
210
-
211
- if (pathName == "/signin-oidc")
212
- {
213
- return;
214
- }
215
-
216
- apiService().post("/Analytics/PageView", {
217
- userId: userId,
218
- locationId: locationId,
219
- companyId: companyId,
220
- uri: pathName,
221
- host: host
222
- });
223
-
224
- }
101
+ const logEvent = (category, action, label) => {
102
+ if (ga4React.current) {
103
+ ga4React.current.event(action, label, category);
225
104
  }
226
-
227
- useEffect(() => {
228
-
229
- let enableAnalytics = false;
230
- const stored = localStorage.getItem("gdpr-consent");
231
- if (stored) {
232
- const prefs = JSON.parse(stored);
233
- if (prefs.analytics)
234
- {
235
- enableAnalytics = true;
236
- }
237
- }
238
-
239
- if ((frontEndLoadedState && !enableConsentDialog) || (frontEndLoadedState && enableConsentDialog && enableAnalytics))
240
- {
241
-
242
- console.log("Analytics are working now!");
243
-
244
- if (pageProps.googleAnalytics4Code != null)
245
- {
246
- initGA(pageProps.googleAnalytics4Code);
247
- }
248
- else if (process.env.googleAnalytics4 != "")
249
- {
250
- initGA(process.env.googleAnalytics4);
251
- }
252
-
253
- if (pageProps.microsoftClarityCode != null)
254
- {
255
- clarity.init(pageProps.microsoftClarityCode);
256
-
257
- if (signedInUser.current != null && clarity.hasStarted())
258
- {
259
- clarity.identify('USER_ID', { userProperty: signedInUser.current.id.toString() });
260
- }
261
- }
262
- else if (process.env.microsoftClarityTrackingCode != "") // if there isn't a private label tracking code use the one built in the app
263
- {
264
- clarity.init(process.env.microsoftClarityTrackingCode);
265
-
266
- if (signedInUser.current != null && clarity.hasStarted())
267
- {
268
- clarity.identify('USER_ID', { userProperty: signedInUser.current.id.toString() });
269
- }
270
- }
271
-
272
- databaseDrivenPageView(window.location.pathname);
273
- Router.events.on('routeChangeComplete', () => {
274
-
275
- if (ga4React != null && ga4React != "")
276
- {
277
- try
278
- {
279
- ga4React.current.pageview(window.location.pathname);
280
- }
281
- catch(exp) {}
282
- }
283
-
284
- databaseDrivenPageView(window.location.pathname);
285
- });
286
-
287
- if (pageProps.hubspotTrackingCode != null && pageProps.hubspotTrackingCode != "")
288
- {
289
- const script = document.createElement("script");
290
- script.src = pageProps.hubspotTrackingCode;
291
- script.async = true;
292
- script.defer = true;
293
- script.id = "hs-script-loader";
294
- document.body.appendChild(script);
295
- }
296
- }
297
- else
298
- {
299
- console.log("No Analytics for you!");
300
- }
301
-
302
- }, [frontEndLoadedState, concentState]);
303
-
304
- const validateUserSignedIn = async () => {
305
-
306
- loadingAuth.current = true;
307
-
308
- if (enableAuth)
309
- {
310
- let usr = await apiService().GetCurrentUser();
311
- if (usr != null)
312
- {
313
- signedInUser.current = usr;
314
- }
315
- }
316
-
105
+ };
106
+
107
+ const databaseDrivenPageView = (pathName) => {
108
+ if (process.env.enableDatabaseAnalytics !== "true") return;
109
+ if (pathName === "/signin-oidc") return;
110
+
111
+ const host = window.location.protocol + "//" + window.location.host;
112
+
113
+ apiService().post("/Analytics/PageView", {
114
+ userId: signedInUser.current?.id,
115
+ locationId: signedInUser.current?.locationId,
116
+ companyId: signedInUser.current?.companyId,
117
+ uri: pathName,
118
+ host
119
+ });
120
+ };
121
+
122
+ // ---------- Auth + Tracking Init ----------
123
+ useEffect(() => {
124
+ if (queryCode) {
125
+ signInValidator(queryCode);
126
+ } else if (!loadingAuth.current) {
127
+ loadingAuth.current = true;
128
+ if (enableAuth) {
129
+ apiService().GetCurrentUser().then((usr) => {
130
+ signedInUser.current = usr;
131
+ setSignedInUserState(usr);
132
+ setFrontEndLoadedState(true);
133
+ });
134
+ } else {
317
135
  setFrontEndLoadedState(true);
318
- frontEndLoaded.current = true;
319
- setSignedInUserState(signedInUser.current);
320
- }
321
-
322
- if (queryCode != null)
323
- {
324
- signInValidator(queryCode);
325
- }
326
- else
327
- {
328
- if (!loadingAuth.current)
329
- {
330
- validateUserSignedIn();
331
- }
136
+ }
332
137
  }
138
+ }, [queryCode, enableAuth]);
333
139
 
334
- useEffect(() => {
140
+ // ---------- Analytics Init ----------
141
+ useEffect(() => {
142
+ if (!frontEndLoadedState) return;
335
143
 
336
- if (signedInUserState == null && enforceLoggedIn && pathname != "/signin-oidc" && frontEndLoadedState == true)
337
- {
338
- authService().login();
339
- }
340
-
341
- }, [signedInUserState, enforceLoggedIn, frontEndLoadedState]);
342
-
343
-
344
- const setIsLoading = (isLoading) => {
345
- setIsLoadingShow(isLoading);
346
- }
347
-
348
- const logPurchase = (transactionId, amount, tax, items) => {
349
-
350
- if (ga4React != null && ga4React != "")
351
- {
352
- ga4React.current.gtag("event", "purchase", {
353
- transaction_id: transactionId,
354
- value: amount,
355
- tax: tax,
356
- currency: "USD",
357
- items: items
358
- });
359
- }
144
+ if (pageProps.googleAnalytics4Code) {
145
+ initGA(pageProps.googleAnalytics4Code);
146
+ } else if (process.env.googleAnalytics4) {
147
+ initGA(process.env.googleAnalytics4);
360
148
  }
361
149
 
362
- const setToastMessage = (message, options = null) => {
363
-
364
- if (options != null)
365
- {
366
- toast(message, options);
367
- }
368
- else
369
- {
370
- toast(message);
371
- }
150
+ if (pageProps.microsoftClarityCode) {
151
+ clarity.init(pageProps.microsoftClarityCode);
152
+ } else if (process.env.microsoftClarityTrackingCode) {
153
+ clarity.init(process.env.microsoftClarityTrackingCode);
372
154
  }
373
155
 
374
- const setInfoToastMessage = (message, options = null) => {
375
- if (options != null)
376
- {
377
- toast.info(message, options);
378
- }
379
- else
380
- {
381
- toast.info(message);
382
- }
383
- }
156
+ databaseDrivenPageView(window.location.pathname);
384
157
 
385
- const setSuccessToastMessage = (message, options = null) => {
386
- if (options != null)
387
- {
388
- toast.success(message, options);
389
- }
390
- else
391
- {
392
- toast.success(message);
393
- }
394
- }
158
+ Router.events.on('routeChangeComplete', (url) => {
159
+ ga4React.current?.pageview(url);
160
+ databaseDrivenPageView(url);
161
+ });
162
+ }, [frontEndLoadedState]);
395
163
 
396
- const setWarnToastMessage = (message, options = null) => {
397
- if (options != null)
398
- {
399
- toast.warn(message, options);
400
- }
401
- else
402
- {
403
- toast.warn(message);
404
- }
164
+ // ---------- Enforce Login ----------
165
+ useEffect(() => {
166
+ if (enforceLoggedIn && pathname !== "/signin-oidc" && frontEndLoadedState && !signedInUserState) {
167
+ authService().login();
405
168
  }
406
-
407
- const setErrorToastMessage = (message, options = null) => {
408
- if (options != null)
409
- {
410
- toast.error(message, options);
411
- }
412
- else
413
- {
414
- toast.error(message);
415
- }
416
- }
417
-
418
-
419
- const GetSignedInUser = () => {
420
-
421
- if (signedInUser != null)
422
- {
423
- let _signedInUser = signedInUser.current;
424
-
425
- if (_signedInUser != null)
426
- {
427
- _signedInUser.hasRole = function(name) {
428
-
429
- if (_signedInUser.roles != null)
430
- {
431
- if (_signedInUser.roles.find(r => r.name === name) != null)
432
- {
433
- return true;
434
- }
435
- else
436
- {
437
- return false;
438
- }
439
- }
440
- };
441
-
442
- _signedInUser.hasRoleId = function(id) {
443
-
444
- if (_signedInUser.roles != null)
445
- {
446
- if (_signedInUser.roles.find(r => r.id === id) != null)
447
- {
448
- return true;
449
- }
450
- else
451
- {
452
- return false;
453
- }
454
- }
455
- };
456
-
457
- _signedInUser.hasPermission = function(name) {
458
-
459
- if (_signedInUser.permissions != null)
460
- {
461
- if (_signedInUser.permissions.find(r => r === name) != null)
462
- {
463
- return true;
464
- }
465
- else
466
- {
467
- return false;
468
- }
469
- }
470
- };
471
- }
472
-
473
- return _signedInUser;
474
- }
475
- else
476
- {
477
- return null;
478
- }
479
- }
480
-
481
-
482
- const useStore = create((set) => (store));
483
-
484
- return (
485
- <>
486
- <Head>
487
- <meta name="viewport" content="width=device-width, initial-scale=0.86, maximum-scale=5.0, minimum-scale=0.86"></meta>
488
-
489
- {/* {(pageProps != null && pageProps.oemCompanyId != null) ?
490
- <>
491
- <link
492
- href={process.env.apiUri + "/api/PrivateLabel/GetDataFromRecord?oemCompanyId=" + pageProps.oemCompanyId}
493
- rel="stylesheet"
494
- />
495
- </>
496
- :
497
- <>
498
- <link rel="icon" href="/favicon.ico" />
499
- </>
500
- } */}
501
-
502
- </Head>
503
-
504
- {enableConsentDialog &&
505
- <GDPRConsentDialog
506
- onAccept={handleConsentAccepted}
507
- onReject={handleConsentRejected}
508
- enableAnalytics={true}
509
- enableMarketing={false}
510
- // additionalPrivacyFeatures={[
511
- // {id: "danceParty", title: "Dance Party", description: "Hello world this is about the feature", checked: true },
512
- // {id: "frog", title: "Able to see Frogs", description: "Frogs will appear on your screen", checked: true }
513
- // ]}
514
- />
515
- }
516
-
517
- <ThemeProvider theme={muiTheme}>
518
- {frontEndLoadedState != null && frontEndLoadedState && pathname != "/signin-oidc" &&
519
- <>
520
- {layout != null && layout({
521
- children: <Component {...pageProps} currentUser={GetSignedInUser()} loadedUser={frontEndLoadedState} setIsLoading={setIsLoading} logEvent={logEvent} logPurchase={logPurchase} store={useStore} setToastMessage={setToastMessage} setInfoToastMessage={setInfoToastMessage} setSuccessToastMessage={setSuccessToastMessage} setWarnToastMessage={setWarnToastMessage} setErrorToastMessage={setErrorToastMessage} />,
522
- currentUser: GetSignedInUser(),
523
- logEvent: logEvent,
524
- setIsLoading: setIsLoading,
525
- toast: toast,
526
- store: useStore,
527
- setToastMessage: setToastMessage,
528
- pageProps: pageProps,
529
- setInfoToastMessage: setInfoToastMessage,
530
- setSuccessToastMessage: setSuccessToastMessage,
531
- setWarnToastMessage: setWarnToastMessage,
532
- setErrorToastMessage: setErrorToastMessage
533
- })}
534
-
535
- {layout == null &&
536
- <Component {...pageProps} currentUser={GetSignedInUser()} loadedUser={frontEndLoadedState} setIsLoading={setIsLoading} logEvent={logEvent} logPurchase={logPurchase} store={useStore} setToastMessage={setToastMessage} setInfoToastMessage={setInfoToastMessage} setSuccessToastMessage={setSuccessToastMessage} setWarnToastMessage={setWarnToastMessage} setErrorToastMessage={setErrorToastMessage} />
537
- }
538
- </>
539
- }
540
- <ToastContainer />
541
-
542
- </ThemeProvider>
543
-
544
- {loadingLayout &&
545
- <>
546
- {loadingLayout(isLoadingShow)}
547
- </>
548
- }
549
- </>
550
- )
551
- }
169
+ }, [signedInUserState, enforceLoggedIn, frontEndLoadedState, pathname]);
170
+
171
+ const GetSignedInUser = () => signedInUser.current;
172
+
173
+ const useStore = create((set) => (store));
174
+
175
+ // ---------- Render ----------
176
+ const pageContent = layout
177
+ ? layout({
178
+ children: <Component {...pageProps} currentUser={GetSignedInUser()} loadedUser={frontEndLoadedState} setIsLoading={setIsLoadingShow} logEvent={logEvent} store={useStore} toast={toast} />,
179
+ currentUser: GetSignedInUser(),
180
+ setIsLoading: setIsLoadingShow,
181
+ logEvent,
182
+ toast,
183
+ store: useStore,
184
+ pageProps
185
+ })
186
+ : <Component {...pageProps} currentUser={GetSignedInUser()} loadedUser={frontEndLoadedState} setIsLoading={setIsLoadingShow} logEvent={logEvent} store={useStore} toast={toast} />;
187
+
188
+ return (
189
+ <>
190
+ <Head>
191
+ <meta name="viewport" content="width=device-width, initial-scale=0.86, maximum-scale=5.0, minimum-scale=0.86" />
192
+ </Head>
193
+
194
+ <ThemeProvider theme={muiTheme}>
195
+ {pageContent}
196
+ <ToastContainer />
197
+ </ThemeProvider>
198
+
199
+ {loadingLayout && loadingLayout(isLoadingShow)}
200
+ </>
201
+ );
202
+ }