authscape 1.0.712 → 1.0.714

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/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
 
3
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
@@ -30,6 +29,50 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
30
29
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
31
30
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
32
31
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
32
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
33
+ // ---- optional: import your cookie util if not global ----
34
+ // import { setCookie } from "cookies-next";
35
+ // import { apiService } from "@/services/api"; // wherever yours lives
36
+
37
+ // Decorate a user object with role/permission helpers (idempotent)
38
+ function ensureUserHelpers(u) {
39
+ if (!u || _typeof(u) !== "object") return u;
40
+
41
+ // Avoid redefining on every call
42
+ if (typeof u.hasRole === "function" && typeof u.hasRoleId === "function" && typeof u.hasPermission === "function") {
43
+ return u;
44
+ }
45
+ var rolesArr = Array.isArray(u.roles) ? u.roles : [];
46
+ var permsArr = Array.isArray(u.permissions) ? u.permissions : [];
47
+
48
+ // defineProperty keeps them non-enumerable
49
+ Object.defineProperty(u, "hasRole", {
50
+ value: function hasRole(name) {
51
+ if (!name) return false;
52
+ return rolesArr.some(function (r) {
53
+ return (r === null || r === void 0 ? void 0 : r.name) === name;
54
+ });
55
+ },
56
+ writable: false
57
+ });
58
+ Object.defineProperty(u, "hasRoleId", {
59
+ value: function hasRoleId(id) {
60
+ if (id === undefined || id === null) return false;
61
+ return rolesArr.some(function (r) {
62
+ return (r === null || r === void 0 ? void 0 : r.id) === id;
63
+ });
64
+ },
65
+ writable: false
66
+ });
67
+ Object.defineProperty(u, "hasPermission", {
68
+ value: function hasPermission(name) {
69
+ if (!name) return false;
70
+ return permsArr.includes(name);
71
+ },
72
+ writable: false
73
+ });
74
+ return u;
75
+ }
33
76
  function AuthScapeApp(_ref) {
34
77
  var Component = _ref.Component,
35
78
  layout = _ref.layout,
@@ -63,20 +106,20 @@ function AuthScapeApp(_ref) {
63
106
  var queryCode = searchParams.get("code");
64
107
  var pathname = (0, _navigation.usePathname)();
65
108
 
66
- // ---------- PKCE Sign-in ----------
109
+ // ----- PKCE Sign-in (browser-only) -----
67
110
  var signInValidator = /*#__PURE__*/function () {
68
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(queryCode) {
69
- var codeVerifier, headers, queryString, response, domainHost, redirectUri;
111
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(codeFromQuery) {
112
+ var codeVerifier, headers, body, response, domainHost, redirectUri;
70
113
  return _regeneratorRuntime().wrap(function _callee$(_context) {
71
114
  while (1) switch (_context.prev = _context.next) {
72
115
  case 0:
73
- if (!(queryCodeUsed.current === queryCode)) {
116
+ if (!(queryCodeUsed.current === codeFromQuery)) {
74
117
  _context.next = 2;
75
118
  break;
76
119
  }
77
120
  return _context.abrupt("return");
78
121
  case 2:
79
- queryCodeUsed.current = queryCode;
122
+ queryCodeUsed.current = codeFromQuery;
80
123
  if (!(typeof window === "undefined")) {
81
124
  _context.next = 5;
82
125
  break;
@@ -84,7 +127,7 @@ function AuthScapeApp(_ref) {
84
127
  return _context.abrupt("return");
85
128
  case 5:
86
129
  codeVerifier = window.localStorage.getItem("verifier");
87
- if (!(!queryCode || !codeVerifier)) {
130
+ if (!(!codeFromQuery || !codeVerifier)) {
88
131
  _context.next = 8;
89
132
  break;
90
133
  }
@@ -93,8 +136,8 @@ function AuthScapeApp(_ref) {
93
136
  headers = {
94
137
  "Content-Type": "application/x-www-form-urlencoded"
95
138
  };
96
- queryString = _queryString["default"].stringify({
97
- code: queryCode,
139
+ body = _queryString["default"].stringify({
140
+ code: codeFromQuery,
98
141
  grant_type: "authorization_code",
99
142
  redirect_uri: window.location.origin + "/signin-oidc",
100
143
  client_id: process.env.client_id,
@@ -103,13 +146,15 @@ function AuthScapeApp(_ref) {
103
146
  });
104
147
  _context.prev = 10;
105
148
  _context.next = 13;
106
- return _axios["default"].post(process.env.authorityUri + "/connect/token", queryString, {
149
+ return _axios["default"].post(process.env.authorityUri + "/connect/token", body, {
107
150
  headers: headers
108
151
  });
109
152
  case 13:
110
153
  response = _context.sent;
111
154
  domainHost = window.location.hostname.split(".").slice(-2).join(".");
112
155
  window.localStorage.removeItem("verifier");
156
+
157
+ // NOTE: replace setCookie below with your implementation if different
113
158
  _context.next = 18;
114
159
  return setCookie("access_token", response.data.access_token, {
115
160
  maxAge: 60 * 60 * 24 * 365,
@@ -134,8 +179,8 @@ function AuthScapeApp(_ref) {
134
179
  secure: true
135
180
  });
136
181
  case 22:
137
- redirectUri = localStorage.getItem("redirectUri");
138
- localStorage.clear();
182
+ redirectUri = window.localStorage.getItem("redirectUri");
183
+ window.localStorage.clear();
139
184
  window.location.href = redirectUri || "/";
140
185
  _context.next = 30;
141
186
  break;
@@ -154,7 +199,7 @@ function AuthScapeApp(_ref) {
154
199
  };
155
200
  }();
156
201
 
157
- // ---------- GA + Clarity ----------
202
+ // ----- GA + Clarity -----
158
203
  function initGA(_x2) {
159
204
  return _initGA.apply(this, arguments);
160
205
  }
@@ -189,9 +234,8 @@ function AuthScapeApp(_ref) {
189
234
  return _initGA.apply(this, arguments);
190
235
  }
191
236
  var logEvent = function logEvent(category, action, label) {
192
- if (ga4React.current) {
193
- ga4React.current.event(action, label, category);
194
- }
237
+ if (ga4React.current) ga4React.current.event(action, label, category);
238
+ // your DB analytics can go here if desired
195
239
  };
196
240
  var databaseDrivenPageView = function databaseDrivenPageView(pathName) {
197
241
  var _signedInUser$current, _signedInUser$current2, _signedInUser$current3;
@@ -208,16 +252,23 @@ function AuthScapeApp(_ref) {
208
252
  });
209
253
  };
210
254
 
211
- // ---------- Auth Init ----------
255
+ // ----- Auth init (runs once) -----
212
256
  (0, _react.useEffect)(function () {
213
257
  if (queryCode) {
214
258
  signInValidator(queryCode);
215
- } else if (!loadingAuth.current) {
259
+ return;
260
+ }
261
+ if (!loadingAuth.current) {
216
262
  loadingAuth.current = true;
217
263
  if (enableAuth) {
218
264
  apiService().GetCurrentUser().then(function (usr) {
219
- signedInUser.current = usr;
220
- setSignedInUserState(usr);
265
+ signedInUser.current = ensureUserHelpers(usr);
266
+ setSignedInUserState(signedInUser.current);
267
+ setFrontEndLoadedState(true);
268
+ })["catch"](function () {
269
+ // no user / anonymous
270
+ signedInUser.current = null;
271
+ setSignedInUserState(null);
221
272
  setFrontEndLoadedState(true);
222
273
  });
223
274
  } else {
@@ -226,7 +277,7 @@ function AuthScapeApp(_ref) {
226
277
  }
227
278
  }, [queryCode, enableAuth]);
228
279
 
229
- // ---------- Analytics Init ----------
280
+ // ----- Analytics init -----
230
281
  (0, _react.useEffect)(function () {
231
282
  if (!frontEndLoadedState || typeof window === "undefined") return;
232
283
  if (pageProps.googleAnalytics4Code) {
@@ -240,44 +291,50 @@ function AuthScapeApp(_ref) {
240
291
  _reactMicrosoftClarity.clarity.init(process.env.microsoftClarityTrackingCode);
241
292
  }
242
293
  databaseDrivenPageView(window.location.pathname);
243
- _router["default"].events.on("routeChangeComplete", function (url) {
294
+ var handler = function handler(url) {
244
295
  var _ga4React$current;
245
296
  (_ga4React$current = ga4React.current) === null || _ga4React$current === void 0 || _ga4React$current.pageview(url);
246
297
  databaseDrivenPageView(url);
247
- });
248
- }, [frontEndLoadedState]);
298
+ };
299
+ _router["default"].events.on("routeChangeComplete", handler);
300
+ return function () {
301
+ return _router["default"].events.off("routeChangeComplete", handler);
302
+ };
303
+ }, [frontEndLoadedState, pageProps.googleAnalytics4Code, pageProps.microsoftClarityCode]);
249
304
 
250
- // ---------- Enforce Login ----------
305
+ // ----- Enforce login (client) -----
251
306
  (0, _react.useEffect)(function () {
252
307
  if (enforceLoggedIn && pathname !== "/signin-oidc" && frontEndLoadedState && !signedInUserState) {
253
308
  (0, _authscape.authService)().login();
254
309
  }
255
310
  }, [signedInUserState, enforceLoggedIn, frontEndLoadedState, pathname]);
256
- var GetSignedInUser = function GetSignedInUser() {
257
- return signedInUser.current;
258
- };
259
- var useStore = (0, _zustand.create)(function (set) {
311
+
312
+ // Stable getter for current user (with helpers)
313
+ var currentUser = (0, _react.useMemo)(function () {
314
+ return ensureUserHelpers(signedInUser.current);
315
+ }, [signedInUserState]);
316
+ var useStore = (0, _zustand.create)(function () {
260
317
  return store;
261
318
  });
262
319
 
263
- // ---------- Render ----------
320
+ // ----- Render (SSR-safe; always output page so <title> is visible) -----
264
321
  var pageContent = layout ? layout({
265
322
  children: /*#__PURE__*/_react["default"].createElement(Component, _extends({}, pageProps, {
266
- currentUser: GetSignedInUser(),
323
+ currentUser: currentUser,
267
324
  loadedUser: frontEndLoadedState,
268
325
  setIsLoading: setIsLoadingShow,
269
326
  logEvent: logEvent,
270
327
  store: useStore,
271
328
  toast: _reactToastify.toast
272
329
  })),
273
- currentUser: GetSignedInUser(),
330
+ currentUser: currentUser,
274
331
  setIsLoading: setIsLoadingShow,
275
332
  logEvent: logEvent,
276
333
  toast: _reactToastify.toast,
277
334
  store: useStore,
278
335
  pageProps: pageProps
279
336
  }) : /*#__PURE__*/_react["default"].createElement(Component, _extends({}, pageProps, {
280
- currentUser: GetSignedInUser(),
337
+ currentUser: currentUser,
281
338
  loadedUser: frontEndLoadedState,
282
339
  setIsLoading: setIsLoadingShow,
283
340
  logEvent: logEvent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "authscape",
3
- "version": "1.0.712",
3
+ "version": "1.0.714",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,4 +1,4 @@
1
- import React, { useState, useRef, useEffect } from "react";
1
+ import React, { useState, useRef, useEffect, useMemo } 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";
@@ -11,6 +11,52 @@ import { create } from "zustand";
11
11
  import { clarity } from "react-microsoft-clarity";
12
12
  import { authService } from "authscape";
13
13
 
14
+ // ---- optional: import your cookie util if not global ----
15
+ // import { setCookie } from "cookies-next";
16
+ // import { apiService } from "@/services/api"; // wherever yours lives
17
+
18
+ // Decorate a user object with role/permission helpers (idempotent)
19
+ function ensureUserHelpers(u) {
20
+ if (!u || typeof u !== "object") return u;
21
+
22
+ // Avoid redefining on every call
23
+ if (typeof u.hasRole === "function" &&
24
+ typeof u.hasRoleId === "function" &&
25
+ typeof u.hasPermission === "function") {
26
+ return u;
27
+ }
28
+
29
+ const rolesArr = Array.isArray(u.roles) ? u.roles : [];
30
+ const permsArr = Array.isArray(u.permissions) ? u.permissions : [];
31
+
32
+ // defineProperty keeps them non-enumerable
33
+ Object.defineProperty(u, "hasRole", {
34
+ value: function hasRole(name) {
35
+ if (!name) return false;
36
+ return rolesArr.some(r => r?.name === name);
37
+ },
38
+ writable: false
39
+ });
40
+
41
+ Object.defineProperty(u, "hasRoleId", {
42
+ value: function hasRoleId(id) {
43
+ if (id === undefined || id === null) return false;
44
+ return rolesArr.some(r => r?.id === id);
45
+ },
46
+ writable: false
47
+ });
48
+
49
+ Object.defineProperty(u, "hasPermission", {
50
+ value: function hasPermission(name) {
51
+ if (!name) return false;
52
+ return permsArr.includes(name);
53
+ },
54
+ writable: false
55
+ });
56
+
57
+ return u;
58
+ }
59
+
14
60
  export function AuthScapeApp({
15
61
  Component,
16
62
  layout,
@@ -34,20 +80,20 @@ export function AuthScapeApp({
34
80
  const queryCode = searchParams.get("code");
35
81
  const pathname = usePathname();
36
82
 
37
- // ---------- PKCE Sign-in ----------
38
- const signInValidator = async (queryCode) => {
39
- if (queryCodeUsed.current === queryCode) return;
40
- queryCodeUsed.current = queryCode;
83
+ // ----- PKCE Sign-in (browser-only) -----
84
+ const signInValidator = async (codeFromQuery) => {
85
+ if (queryCodeUsed.current === codeFromQuery) return;
86
+ queryCodeUsed.current = codeFromQuery;
41
87
 
42
88
  if (typeof window === "undefined") return;
43
89
 
44
90
  const codeVerifier = window.localStorage.getItem("verifier");
45
- if (!queryCode || !codeVerifier) return;
91
+ if (!codeFromQuery || !codeVerifier) return;
46
92
 
47
93
  const headers = { "Content-Type": "application/x-www-form-urlencoded" };
48
94
 
49
- const queryString = querystring.stringify({
50
- code: queryCode,
95
+ const body = querystring.stringify({
96
+ code: codeFromQuery,
51
97
  grant_type: "authorization_code",
52
98
  redirect_uri: window.location.origin + "/signin-oidc",
53
99
  client_id: process.env.client_id,
@@ -58,17 +104,15 @@ export function AuthScapeApp({
58
104
  try {
59
105
  const response = await axios.post(
60
106
  process.env.authorityUri + "/connect/token",
61
- queryString,
107
+ body,
62
108
  { headers }
63
109
  );
64
110
 
65
- const domainHost = window.location.hostname
66
- .split(".")
67
- .slice(-2)
68
- .join(".");
111
+ const domainHost = window.location.hostname.split(".").slice(-2).join(".");
69
112
 
70
113
  window.localStorage.removeItem("verifier");
71
114
 
115
+ // NOTE: replace setCookie below with your implementation if different
72
116
  await setCookie("access_token", response.data.access_token, {
73
117
  maxAge: 60 * 60 * 24 * 365,
74
118
  path: "/",
@@ -88,24 +132,18 @@ export function AuthScapeApp({
88
132
  secure: true,
89
133
  });
90
134
 
91
- const redirectUri = localStorage.getItem("redirectUri");
92
- localStorage.clear();
135
+ const redirectUri = window.localStorage.getItem("redirectUri");
136
+ window.localStorage.clear();
93
137
  window.location.href = redirectUri || "/";
94
138
  } catch (exp) {
95
139
  console.error("PKCE sign-in failed", exp);
96
140
  }
97
141
  };
98
142
 
99
- // ---------- GA + Clarity ----------
143
+ // ----- GA + Clarity -----
100
144
  async function initGA(G) {
101
- if (
102
- typeof window !== "undefined" &&
103
- !GA4React.isInitialized() &&
104
- G
105
- ) {
106
- ga4React.current = new GA4React(G, {
107
- debug_mode: !process.env.production,
108
- });
145
+ if (typeof window !== "undefined" && !GA4React.isInitialized() && G) {
146
+ ga4React.current = new GA4React(G, { debug_mode: !process.env.production });
109
147
  try {
110
148
  await ga4React.current.initialize();
111
149
  } catch (error) {
@@ -115,9 +153,8 @@ export function AuthScapeApp({
115
153
  }
116
154
 
117
155
  const logEvent = (category, action, label) => {
118
- if (ga4React.current) {
119
- ga4React.current.event(action, label, category);
120
- }
156
+ if (ga4React.current) ga4React.current.event(action, label, category);
157
+ // your DB analytics can go here if desired
121
158
  };
122
159
 
123
160
  const databaseDrivenPageView = (pathName) => {
@@ -136,16 +173,25 @@ export function AuthScapeApp({
136
173
  });
137
174
  };
138
175
 
139
- // ---------- Auth Init ----------
176
+ // ----- Auth init (runs once) -----
140
177
  useEffect(() => {
141
178
  if (queryCode) {
142
179
  signInValidator(queryCode);
143
- } else if (!loadingAuth.current) {
180
+ return;
181
+ }
182
+
183
+ if (!loadingAuth.current) {
144
184
  loadingAuth.current = true;
185
+
145
186
  if (enableAuth) {
146
187
  apiService().GetCurrentUser().then((usr) => {
147
- signedInUser.current = usr;
148
- setSignedInUserState(usr);
188
+ signedInUser.current = ensureUserHelpers(usr);
189
+ setSignedInUserState(signedInUser.current);
190
+ setFrontEndLoadedState(true);
191
+ }).catch(() => {
192
+ // no user / anonymous
193
+ signedInUser.current = null;
194
+ setSignedInUserState(null);
149
195
  setFrontEndLoadedState(true);
150
196
  });
151
197
  } else {
@@ -154,7 +200,7 @@ export function AuthScapeApp({
154
200
  }
155
201
  }, [queryCode, enableAuth]);
156
202
 
157
- // ---------- Analytics Init ----------
203
+ // ----- Analytics init -----
158
204
  useEffect(() => {
159
205
  if (!frontEndLoadedState || typeof window === "undefined") return;
160
206
 
@@ -172,13 +218,15 @@ export function AuthScapeApp({
172
218
 
173
219
  databaseDrivenPageView(window.location.pathname);
174
220
 
175
- Router.events.on("routeChangeComplete", (url) => {
221
+ const handler = (url) => {
176
222
  ga4React.current?.pageview(url);
177
223
  databaseDrivenPageView(url);
178
- });
179
- }, [frontEndLoadedState]);
224
+ };
225
+ Router.events.on("routeChangeComplete", handler);
226
+ return () => Router.events.off("routeChangeComplete", handler);
227
+ }, [frontEndLoadedState, pageProps.googleAnalytics4Code, pageProps.microsoftClarityCode]);
180
228
 
181
- // ---------- Enforce Login ----------
229
+ // ----- Enforce login (client) -----
182
230
  useEffect(() => {
183
231
  if (
184
232
  enforceLoggedIn &&
@@ -190,16 +238,18 @@ export function AuthScapeApp({
190
238
  }
191
239
  }, [signedInUserState, enforceLoggedIn, frontEndLoadedState, pathname]);
192
240
 
193
- const GetSignedInUser = () => signedInUser.current;
194
- const useStore = create((set) => store);
241
+ // Stable getter for current user (with helpers)
242
+ const currentUser = useMemo(() => ensureUserHelpers(signedInUser.current), [signedInUserState]);
243
+
244
+ const useStore = create(() => store);
195
245
 
196
- // ---------- Render ----------
246
+ // ----- Render (SSR-safe; always output page so <title> is visible) -----
197
247
  const pageContent = layout
198
248
  ? layout({
199
249
  children: (
200
250
  <Component
201
251
  {...pageProps}
202
- currentUser={GetSignedInUser()}
252
+ currentUser={currentUser}
203
253
  loadedUser={frontEndLoadedState}
204
254
  setIsLoading={setIsLoadingShow}
205
255
  logEvent={logEvent}
@@ -207,7 +257,7 @@ export function AuthScapeApp({
207
257
  toast={toast}
208
258
  />
209
259
  ),
210
- currentUser: GetSignedInUser(),
260
+ currentUser,
211
261
  setIsLoading: setIsLoadingShow,
212
262
  logEvent,
213
263
  toast,
@@ -217,7 +267,7 @@ export function AuthScapeApp({
217
267
  : (
218
268
  <Component
219
269
  {...pageProps}
220
- currentUser={GetSignedInUser()}
270
+ currentUser={currentUser}
221
271
  loadedUser={frontEndLoadedState}
222
272
  setIsLoading={setIsLoadingShow}
223
273
  logEvent={logEvent}