authscape 1.0.755 → 1.0.760

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
@@ -76,6 +76,7 @@ function AuthScapeApp(_ref) {
76
76
  var Component = _ref.Component,
77
77
  layout = _ref.layout,
78
78
  loadingLayout = _ref.loadingLayout,
79
+ signInLoadingComponent = _ref.signInLoadingComponent,
79
80
  pageProps = _ref.pageProps,
80
81
  _ref$muiTheme = _ref.muiTheme,
81
82
  muiTheme = _ref$muiTheme === void 0 ? {} : _ref$muiTheme,
@@ -97,6 +98,10 @@ function AuthScapeApp(_ref) {
97
98
  _useState6 = _slicedToArray(_useState5, 2),
98
99
  signedInUserState = _useState6[0],
99
100
  setSignedInUserState = _useState6[1];
101
+ var _useState7 = (0, _react.useState)(false),
102
+ _useState8 = _slicedToArray(_useState7, 2),
103
+ isSigningIn = _useState8[0],
104
+ setIsSigningIn = _useState8[1];
100
105
  var loadingAuth = (0, _react.useRef)(false);
101
106
  var signedInUser = (0, _react.useRef)(null);
102
107
  var queryCodeUsed = (0, _react.useRef)(null);
@@ -105,10 +110,13 @@ function AuthScapeApp(_ref) {
105
110
  var queryCode = searchParams.get("code");
106
111
  var pathname = (0, _navigation.usePathname)();
107
112
 
113
+ // Check if we're on the signin-oidc page
114
+ var isOnSignInPage = pathname === "/signin-oidc";
115
+
108
116
  // ----- PKCE Sign-in (browser-only) -----
109
117
  var signInValidator = /*#__PURE__*/function () {
110
118
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(codeFromQuery) {
111
- var codeVerifier, headers, body, response, domainHost, redirectUri;
119
+ var codeVerifier, headers, body, response, domainHost, redirectUri, usr;
112
120
  return _regeneratorRuntime().wrap(function _callee$(_context) {
113
121
  while (1) switch (_context.prev = _context.next) {
114
122
  case 0:
@@ -125,13 +133,17 @@ function AuthScapeApp(_ref) {
125
133
  }
126
134
  return _context.abrupt("return");
127
135
  case 5:
136
+ setIsSigningIn(true);
128
137
  codeVerifier = window.localStorage.getItem("verifier");
129
138
  if (!(!codeFromQuery || !codeVerifier)) {
130
- _context.next = 8;
139
+ _context.next = 11;
131
140
  break;
132
141
  }
142
+ // No code or verifier - redirect to login
143
+ window.localStorage.clear();
144
+ module.exports.authService().login();
133
145
  return _context.abrupt("return");
134
- case 8:
146
+ case 11:
135
147
  headers = {
136
148
  "Content-Type": "application/x-www-form-urlencoded"
137
149
  };
@@ -143,55 +155,83 @@ function AuthScapeApp(_ref) {
143
155
  client_secret: process.env.client_secret,
144
156
  code_verifier: codeVerifier
145
157
  });
146
- _context.prev = 10;
147
- _context.next = 13;
158
+ _context.prev = 13;
159
+ _context.next = 16;
148
160
  return _axios["default"].post(process.env.authorityUri + "/connect/token", body, {
149
161
  headers: headers
150
162
  });
151
- case 13:
163
+ case 16:
152
164
  response = _context.sent;
153
165
  domainHost = window.location.hostname.split(".").slice(-2).join(".");
154
166
  window.localStorage.removeItem("verifier");
155
167
 
156
168
  // NOTE: replace setCookie below with your implementation if different
157
- _context.next = 18;
169
+ _context.next = 21;
158
170
  return setCookie("access_token", response.data.access_token, {
159
171
  maxAge: 60 * 60 * 24 * 365,
160
172
  path: "/",
161
173
  domain: domainHost,
162
174
  secure: true
163
175
  });
164
- case 18:
165
- _context.next = 20;
176
+ case 21:
177
+ _context.next = 23;
166
178
  return setCookie("expires_in", response.data.expires_in, {
167
179
  maxAge: 60 * 60 * 24 * 365,
168
180
  path: "/",
169
181
  domain: domainHost,
170
182
  secure: true
171
183
  });
172
- case 20:
173
- _context.next = 22;
184
+ case 23:
185
+ _context.next = 25;
174
186
  return setCookie("refresh_token", response.data.refresh_token, {
175
187
  maxAge: 60 * 60 * 24 * 365,
176
188
  path: "/",
177
189
  domain: domainHost,
178
190
  secure: true
179
191
  });
180
- case 22:
181
- redirectUri = window.localStorage.getItem("redirectUri");
192
+ case 25:
193
+ redirectUri = window.localStorage.getItem("redirectUri") || "/";
182
194
  window.localStorage.clear();
183
- window.location.href = redirectUri || "/";
184
- _context.next = 30;
195
+
196
+ // Use history.replaceState to change URL without a page reload, then fetch user
197
+ window.history.replaceState({}, "", redirectUri);
198
+
199
+ // Now load the current user and update state
200
+ _context.prev = 28;
201
+ _context.next = 31;
202
+ return module.exports.apiService().GetCurrentUser();
203
+ case 31:
204
+ usr = _context.sent;
205
+ signedInUser.current = ensureUserHelpers(usr);
206
+ setSignedInUserState(signedInUser.current);
207
+ setFrontEndLoadedState(true);
208
+
209
+ // Trigger a soft navigation using Next.js router
210
+ _router["default"].replace(redirectUri, undefined, {
211
+ shallow: false
212
+ });
213
+ _context.next = 41;
185
214
  break;
186
- case 27:
187
- _context.prev = 27;
188
- _context.t0 = _context["catch"](10);
189
- console.error("PKCE sign-in failed", _context.t0);
190
- case 30:
215
+ case 38:
216
+ _context.prev = 38;
217
+ _context.t0 = _context["catch"](28);
218
+ // If we can't get user, still navigate
219
+ _router["default"].replace(redirectUri);
220
+ case 41:
221
+ _context.next = 48;
222
+ break;
223
+ case 43:
224
+ _context.prev = 43;
225
+ _context.t1 = _context["catch"](13);
226
+ console.error("PKCE sign-in failed", _context.t1);
227
+ // Invalid code - clear storage and redirect to login
228
+ window.localStorage.clear();
229
+ module.exports.authService().login();
230
+ case 48:
191
231
  case "end":
192
232
  return _context.stop();
193
233
  }
194
- }, _callee, null, [[10, 27]]);
234
+ }, _callee, null, [[13, 43], [28, 38]]);
195
235
  }));
196
236
  return function signInValidator(_x) {
197
237
  return _ref2.apply(this, arguments);
@@ -321,6 +361,43 @@ function AuthScapeApp(_ref) {
321
361
  });
322
362
 
323
363
  // ----- Render (SSR-safe; always output page so <title> is visible) -----
364
+
365
+ // Default sign-in loading component if none provided
366
+ var defaultSignInLoading = /*#__PURE__*/_react["default"].createElement("div", {
367
+ style: {
368
+ display: 'flex',
369
+ flexDirection: 'column',
370
+ alignItems: 'center',
371
+ justifyContent: 'center',
372
+ height: '100vh',
373
+ width: '100%',
374
+ backgroundColor: '#f5f5f5'
375
+ }
376
+ }, /*#__PURE__*/_react["default"].createElement("div", {
377
+ style: {
378
+ width: '40px',
379
+ height: '40px',
380
+ border: '4px solid #e0e0e0',
381
+ borderTop: '4px solid #3498db',
382
+ borderRadius: '50%',
383
+ animation: 'spin 1s linear infinite'
384
+ }
385
+ }), /*#__PURE__*/_react["default"].createElement("p", {
386
+ style: {
387
+ marginTop: '16px',
388
+ color: '#666'
389
+ }
390
+ }, "Signing in..."), /*#__PURE__*/_react["default"].createElement("style", null, "\n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n "));
391
+
392
+ // Show loading screen when on signin-oidc page
393
+ if (isOnSignInPage || isSigningIn) {
394
+ return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_head["default"], null, /*#__PURE__*/_react["default"].createElement("meta", {
395
+ name: "viewport",
396
+ content: "width=device-width, initial-scale=0.86, maximum-scale=5.0, minimum-scale=0.86"
397
+ })), /*#__PURE__*/_react["default"].createElement(_styles.ThemeProvider, {
398
+ theme: muiTheme
399
+ }, signInLoadingComponent || defaultSignInLoading));
400
+ }
324
401
  var pageContent = layout ? layout({
325
402
  children: /*#__PURE__*/_react["default"].createElement(Component, _extends({}, pageProps, {
326
403
  currentUser: currentUser,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "authscape",
3
- "version": "1.0.755",
3
+ "version": "1.0.760",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -48,7 +48,7 @@
48
48
  "html2canvas": "^1.4.1",
49
49
  "js-cookie": "^3.0.5",
50
50
  "js-file-download": "^0.4.12",
51
- "jspdf": "^3.0.0",
51
+ "jspdf": "^4.0.0",
52
52
  "query-string": "^7.1.1",
53
53
  "react": "^18.2.0",
54
54
  "react-color": "^2.19.3",
package/readme.md CHANGED
@@ -1,103 +1,103 @@
1
- # AuthScape NPM Package
2
-
3
- Complete authentication and user management solution for Next.js applications.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install authscape
9
- ```
10
-
11
- ## Quick Start
12
-
13
- See the main [AuthScape Documentation](https://authscape.com/docs) for complete setup instructions.
14
-
15
- ## Features
16
-
17
- ### Core Features
18
- - OAuth2/PKCE Authentication
19
- - Multi-tenant support
20
- - User management
21
- - Role-based permissions
22
- - Analytics integration (GA4, Microsoft Clarity)
23
- - Material-UI components
24
-
25
- ### Components
26
- - Document Manager
27
- - File Uploader
28
- - Rich Text Editor
29
- - Data Tables
30
- - Stripe Payment Integration
31
- - Google Maps Integration
32
- - And more...
33
-
34
- ## Additional Features
35
-
36
- ### Sitemap Generation (NEW!)
37
-
38
- Automatically generate SEO-friendly sitemaps for your Next.js application.
39
-
40
- **Automatic setup on install:**
41
-
42
- When you run `npm install authscape`, a sitemap is automatically configured at `/sitemap.xml` that syncs with your AuthScape content.
43
-
44
- - Supports both Pages Router and App Router
45
- - Automatically detects your Next.js project structure
46
- - Works with both `pages/` and `src/pages/` layouts
47
- - Works with both `app/` and `src/app/` layouts
48
-
49
- **To disable:** Simply delete the auto-generated file:
50
- - Pages Router: `pages/sitemap.xml.js`
51
- - App Router: `app/sitemap.xml/route.js`
52
-
53
- ## Environment Variables
54
-
55
- Required environment variables in your `.env.local`:
56
-
57
- ```env
58
- apiUri=https://your-authscape-api.com
59
- authorityUri=https://your-auth-server.com
60
- client_id=your-client-id
61
- client_secret=your-client-secret
62
- ```
63
-
64
- Optional analytics:
65
-
66
- ```env
67
- googleAnalytics4=G-XXXXXXXXXX
68
- microsoftClarityTrackingCode=xxxxxxxxxx
69
- enableDatabaseAnalytics=true
70
- ```
71
-
72
- ## Usage Example
73
-
74
- ```javascript
75
- // pages/_app.js
76
- import { AuthScapeApp } from 'authscape';
77
- import 'react-toastify/dist/ReactToastify.css';
78
-
79
- function MyApp({ Component, pageProps }) {
80
- return (
81
- <AuthScapeApp
82
- Component={Component}
83
- pageProps={pageProps}
84
- enforceLoggedIn={false}
85
- enableAuth={true}
86
- />
87
- );
88
- }
89
-
90
- export default MyApp;
91
- ```
92
-
93
- ## Documentation
94
-
95
- - [AuthScape Docs](https://authscape.com/docs) - Complete documentation
96
-
97
- ## Support
98
-
99
- For issues or questions, contact AuthScape support or visit [authscape.com](https://authscape.com).
100
-
101
- ## License
102
-
103
- ISC
1
+ # AuthScape NPM Package
2
+
3
+ Complete authentication and user management solution for Next.js applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install authscape
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ See the main [AuthScape Documentation](https://authscape.com/docs) for complete setup instructions.
14
+
15
+ ## Features
16
+
17
+ ### Core Features
18
+ - OAuth2/PKCE Authentication
19
+ - Multi-tenant support
20
+ - User management
21
+ - Role-based permissions
22
+ - Analytics integration (GA4, Microsoft Clarity)
23
+ - Material-UI components
24
+
25
+ ### Components
26
+ - Document Manager
27
+ - File Uploader
28
+ - Rich Text Editor
29
+ - Data Tables
30
+ - Stripe Payment Integration
31
+ - Google Maps Integration
32
+ - And more...
33
+
34
+ ## Additional Features
35
+
36
+ ### Sitemap Generation (NEW!)
37
+
38
+ Automatically generate SEO-friendly sitemaps for your Next.js application.
39
+
40
+ **Automatic setup on install:**
41
+
42
+ When you run `npm install authscape`, a sitemap is automatically configured at `/sitemap.xml` that syncs with your AuthScape content.
43
+
44
+ - Supports both Pages Router and App Router
45
+ - Automatically detects your Next.js project structure
46
+ - Works with both `pages/` and `src/pages/` layouts
47
+ - Works with both `app/` and `src/app/` layouts
48
+
49
+ **To disable:** Simply delete the auto-generated file:
50
+ - Pages Router: `pages/sitemap.xml.js`
51
+ - App Router: `app/sitemap.xml/route.js`
52
+
53
+ ## Environment Variables
54
+
55
+ Required environment variables in your `.env.local`:
56
+
57
+ ```env
58
+ apiUri=https://your-authscape-api.com
59
+ authorityUri=https://your-auth-server.com
60
+ client_id=your-client-id
61
+ client_secret=your-client-secret
62
+ ```
63
+
64
+ Optional analytics:
65
+
66
+ ```env
67
+ googleAnalytics4=G-XXXXXXXXXX
68
+ microsoftClarityTrackingCode=xxxxxxxxxx
69
+ enableDatabaseAnalytics=true
70
+ ```
71
+
72
+ ## Usage Example
73
+
74
+ ```javascript
75
+ // pages/_app.js
76
+ import { AuthScapeApp } from 'authscape';
77
+ import 'react-toastify/dist/ReactToastify.css';
78
+
79
+ function MyApp({ Component, pageProps }) {
80
+ return (
81
+ <AuthScapeApp
82
+ Component={Component}
83
+ pageProps={pageProps}
84
+ enforceLoggedIn={false}
85
+ enableAuth={true}
86
+ />
87
+ );
88
+ }
89
+
90
+ export default MyApp;
91
+ ```
92
+
93
+ ## Documentation
94
+
95
+ - [AuthScape Docs](https://authscape.com/docs) - Complete documentation
96
+
97
+ ## Support
98
+
99
+ For issues or questions, contact AuthScape support or visit [authscape.com](https://authscape.com).
100
+
101
+ ## License
102
+
103
+ ISC
@@ -60,6 +60,7 @@ export function AuthScapeApp({
60
60
  Component,
61
61
  layout,
62
62
  loadingLayout,
63
+ signInLoadingComponent,
63
64
  pageProps,
64
65
  muiTheme = {},
65
66
  store = {},
@@ -69,6 +70,7 @@ export function AuthScapeApp({
69
70
  const [frontEndLoadedState, setFrontEndLoadedState] = useState(false);
70
71
  const [isLoadingShow, setIsLoadingShow] = useState(false);
71
72
  const [signedInUserState, setSignedInUserState] = useState(null);
73
+ const [isSigningIn, setIsSigningIn] = useState(false);
72
74
 
73
75
  const loadingAuth = useRef(false);
74
76
  const signedInUser = useRef(null);
@@ -79,6 +81,9 @@ export function AuthScapeApp({
79
81
  const queryCode = searchParams.get("code");
80
82
  const pathname = usePathname();
81
83
 
84
+ // Check if we're on the signin-oidc page
85
+ const isOnSignInPage = pathname === "/signin-oidc";
86
+
82
87
  // ----- PKCE Sign-in (browser-only) -----
83
88
  const signInValidator = async (codeFromQuery) => {
84
89
  if (queryCodeUsed.current === codeFromQuery) return;
@@ -86,8 +91,15 @@ export function AuthScapeApp({
86
91
 
87
92
  if (typeof window === "undefined") return;
88
93
 
94
+ setIsSigningIn(true);
95
+
89
96
  const codeVerifier = window.localStorage.getItem("verifier");
90
- if (!codeFromQuery || !codeVerifier) return;
97
+ if (!codeFromQuery || !codeVerifier) {
98
+ // No code or verifier - redirect to login
99
+ window.localStorage.clear();
100
+ module.exports.authService().login();
101
+ return;
102
+ }
91
103
 
92
104
  const headers = { "Content-Type": "application/x-www-form-urlencoded" };
93
105
 
@@ -131,11 +143,30 @@ export function AuthScapeApp({
131
143
  secure: true,
132
144
  });
133
145
 
134
- const redirectUri = window.localStorage.getItem("redirectUri");
146
+ const redirectUri = window.localStorage.getItem("redirectUri") || "/";
135
147
  window.localStorage.clear();
136
- window.location.href = redirectUri || "/";
148
+
149
+ // Use history.replaceState to change URL without a page reload, then fetch user
150
+ window.history.replaceState({}, "", redirectUri);
151
+
152
+ // Now load the current user and update state
153
+ try {
154
+ const usr = await module.exports.apiService().GetCurrentUser();
155
+ signedInUser.current = ensureUserHelpers(usr);
156
+ setSignedInUserState(signedInUser.current);
157
+ setFrontEndLoadedState(true);
158
+
159
+ // Trigger a soft navigation using Next.js router
160
+ Router.replace(redirectUri, undefined, { shallow: false });
161
+ } catch (userErr) {
162
+ // If we can't get user, still navigate
163
+ Router.replace(redirectUri);
164
+ }
137
165
  } catch (exp) {
138
166
  console.error("PKCE sign-in failed", exp);
167
+ // Invalid code - clear storage and redirect to login
168
+ window.localStorage.clear();
169
+ module.exports.authService().login();
139
170
  }
140
171
  };
141
172
 
@@ -246,6 +277,53 @@ export function AuthScapeApp({
246
277
  const useStore = create(() => store);
247
278
 
248
279
  // ----- Render (SSR-safe; always output page so <title> is visible) -----
280
+
281
+ // Default sign-in loading component if none provided
282
+ const defaultSignInLoading = (
283
+ <div style={{
284
+ display: 'flex',
285
+ flexDirection: 'column',
286
+ alignItems: 'center',
287
+ justifyContent: 'center',
288
+ height: '100vh',
289
+ width: '100%',
290
+ backgroundColor: '#f5f5f5'
291
+ }}>
292
+ <div style={{
293
+ width: '40px',
294
+ height: '40px',
295
+ border: '4px solid #e0e0e0',
296
+ borderTop: '4px solid #3498db',
297
+ borderRadius: '50%',
298
+ animation: 'spin 1s linear infinite'
299
+ }} />
300
+ <p style={{ marginTop: '16px', color: '#666' }}>Signing in...</p>
301
+ <style>{`
302
+ @keyframes spin {
303
+ 0% { transform: rotate(0deg); }
304
+ 100% { transform: rotate(360deg); }
305
+ }
306
+ `}</style>
307
+ </div>
308
+ );
309
+
310
+ // Show loading screen when on signin-oidc page
311
+ if (isOnSignInPage || isSigningIn) {
312
+ return (
313
+ <>
314
+ <Head>
315
+ <meta
316
+ name="viewport"
317
+ content="width=device-width, initial-scale=0.86, maximum-scale=5.0, minimum-scale=0.86"
318
+ />
319
+ </Head>
320
+ <ThemeProvider theme={muiTheme}>
321
+ {signInLoadingComponent || defaultSignInLoading}
322
+ </ThemeProvider>
323
+ </>
324
+ );
325
+ }
326
+
249
327
  const pageContent = layout
250
328
  ? layout({
251
329
  children: (