@propelauth/nextjs 0.0.71 → 0.0.77

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  This library provides a simple way to integrate your Next.js application (either AppRouter or Pages) with PropelAuth.
6
6
 
7
- Next.js SSR/AppRouter support is in beta, while in beta, you'll need to reach out to support@propelauth.com to have this enabled for your account.
7
+ Next.js SSR/AppRouter support is currently in beta.
8
8
 
9
9
  ## Installation
10
10
 
@@ -40,7 +40,6 @@ In your `src/app/api/auth/[slug]` directory, create a file called `route.ts` wit
40
40
 
41
41
  ```typescript
42
42
  import {getRouteHandlers} from "@propelauth/nextjs/server/app-router";
43
- import {User} from "@propelauth/nextjs/server";
44
43
  import {NextRequest} from "next/server";
45
44
 
46
45
  // postLoginRedirectPathFn is optional, but if you want to redirect the user to a different page after login, you can do so here.
@@ -55,7 +54,7 @@ export const POST = routeHandlers.postRouteHandler
55
54
 
56
55
  ### 2. Set up AuthProvider
57
56
 
58
- #### AppRouter Version
57
+ #### App Router
59
58
 
60
59
  In your root layout, `src/app/layout.tsx`, add the `AuthProvider`:
61
60
 
@@ -71,7 +70,7 @@ export default async function RootLayout({children}: {children: React.ReactNode}
71
70
  }
72
71
  ```
73
72
 
74
- #### Pages Version
73
+ #### Pages Router
75
74
 
76
75
  In your `_app.tsx` file, add the `AuthProvider`:
77
76
 
@@ -85,7 +84,7 @@ export default function MyApp({Component, pageProps}: AppProps) {
85
84
  }
86
85
  ```
87
86
 
88
- ### 3. Set up middleware (AppRouter only - skip if using Pages)
87
+ ### 3. Set up middleware (App Router only - skip if using Pages)
89
88
 
90
89
  In your `src/middleware.ts` file, add the following:
91
90
 
@@ -108,7 +107,7 @@ export const config = {
108
107
 
109
108
  ## Usage
110
109
 
111
- ### Get the user in Server Components (AppRouter example)
110
+ ### Get the user in Server Components (App Router example)
112
111
 
113
112
  ```tsx
114
113
  import {getUser} from "@propelauth/nextjs/server/app-router";
@@ -125,7 +124,7 @@ const WelcomeMessage = async () => {
125
124
  ```
126
125
 
127
126
  ```tsx
128
- import {getUser} from "@propelauth/nextjs/server/app-router";
127
+ import {getUserOrRedirect} from "@propelauth/nextjs/server/app-router";
129
128
 
130
129
  const WelcomeMessage = async () => {
131
130
  // If the user is not logged in, they will be redirected to the login page
@@ -157,6 +156,21 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
157
156
  }
158
157
  ```
159
158
 
159
+ ### Get the user in API Routes (Pages example)
160
+
161
+ ```ts
162
+ import {NextApiRequest, NextApiResponse} from "next";
163
+ import {getUserFromApiRouteRequest} from "@propelauth/nextjs/server/pages";
164
+
165
+ export default async function handler(req: NextApiRequest, res: NextApiResponse) {
166
+ const user = await getUserFromApiRouteRequest(req, res)
167
+ if (user) {
168
+ res.status(200).json({email: user.email})
169
+ } else {
170
+ res.status(401).json({error: "unauthorized"})
171
+ }
172
+ }
173
+ ```
160
174
 
161
175
  ### Get the user in Client Components
162
176
 
@@ -180,7 +194,7 @@ const WelcomeMessage = () => {
180
194
 
181
195
  ### Checking organization membership / RBAC
182
196
 
183
- Note that this works on both the client and server's `User` object, but the below example is on the server.
197
+ Note that this works on both the client's `User` object or the client/server `UserFromToken` object, but the below example is on the server.
184
198
 
185
199
  If you are curious where the organization information comes from, check out our documentation on [organizations](https://docs.propelauth.com/overview/organizations?utm_source=github&utm_medium=library&utm_campaign=nextjs).
186
200
  The quick answer is:
@@ -254,3 +268,31 @@ export default function AccountAndOrgButtons() {
254
268
  </>
255
269
  }
256
270
  ```
271
+
272
+ ### Using APIs
273
+
274
+ You can use our [APIs](https://docs.propelauth.com/reference/backend-apis/node) like so:
275
+
276
+ ```ts
277
+ import {getPropelAuthApis} from "@propelauth/nextjs/server";
278
+
279
+ const apis = getPropelAuthApis()
280
+ await apis.disableUser(userId)
281
+ ```
282
+
283
+ ### Making a call to an external API
284
+
285
+ PropelAuth also supports backend that are not Next.js. To make an [authenticated request](https://docs.propelauth.com/getting-started/making-authenticated-requests)
286
+ to an external API, you'll need an access token. You can get an access token on the frontend from the `useUser` hook:
287
+
288
+ ```tsx
289
+ import {useUser} from "@propelauth/nextjs/client";
290
+
291
+ const MyComponent = () => {
292
+ const {loading, accessToken} = useUser()
293
+
294
+ // Make a request to an external API with useEffect, useQuery, etc.
295
+ }
296
+ ```
297
+
298
+ Within the App Router, you can also call `getAccessToken` to get the access token.
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- declare class User {
3
+ declare class UserFromToken {
4
4
  userId: string;
5
5
  orgIdToOrgMemberInfo?: OrgIdToOrgMemberInfo;
6
6
  email: string;
@@ -14,7 +14,7 @@ declare class User {
14
14
  getOrgByName(orgName: string): OrgMemberInfo | undefined;
15
15
  getOrgs(): OrgMemberInfo[];
16
16
  isImpersonating(): boolean;
17
- static fromJSON(json: string): User;
17
+ static fromJSON(json: string): UserFromToken;
18
18
  }
19
19
  type OrgIdToOrgMemberInfo = {
20
20
  [orgId: string]: OrgMemberInfo;
@@ -42,30 +42,73 @@ declare class OrgMemberInfo {
42
42
  get permissions(): string[];
43
43
  }
44
44
 
45
- type AuthProviderProps = {
46
- authUrl: string;
47
- children?: React.ReactNode;
48
- };
49
- declare const AuthProvider: (props: AuthProviderProps) => React.JSX.Element;
50
-
45
+ declare class User {
46
+ userId: string;
47
+ email: string;
48
+ emailConfirmed: boolean;
49
+ hasPassword: boolean;
50
+ username?: string;
51
+ firstName?: string;
52
+ lastName?: string;
53
+ pictureUrl?: string;
54
+ orgIdToOrgMemberInfo?: OrgIdToOrgMemberInfo;
55
+ mfaEnabled: boolean;
56
+ canCreateOrgs: boolean;
57
+ updatePasswordRequired: boolean;
58
+ createdAt: number;
59
+ lastActiveAt: number;
60
+ legacyUserId?: string;
61
+ impersonatorUserId?: string;
62
+ constructor({ userId, email, emailConfirmed, hasPassword, username, firstName, lastName, pictureUrl, orgIdToOrgMemberInfo, mfaEnabled, canCreateOrgs, updatePasswordRequired, createdAt, lastActiveAt, legacyUserId, impersonatorUserId, }: {
63
+ userId: string;
64
+ email: string;
65
+ emailConfirmed: boolean;
66
+ hasPassword: boolean;
67
+ username?: string;
68
+ firstName?: string;
69
+ lastName?: string;
70
+ pictureUrl?: string;
71
+ orgIdToOrgMemberInfo?: OrgIdToOrgMemberInfo;
72
+ mfaEnabled: boolean;
73
+ canCreateOrgs: boolean;
74
+ updatePasswordRequired: boolean;
75
+ createdAt: number;
76
+ lastActiveAt: number;
77
+ legacyUserId?: string;
78
+ impersonatorUserId?: string;
79
+ });
80
+ getOrg(orgId: string): OrgMemberInfo | undefined;
81
+ getOrgByName(orgName: string): OrgMemberInfo | undefined;
82
+ getOrgs(): OrgMemberInfo[];
83
+ isImpersonating(): boolean;
84
+ }
51
85
  type UseUserLoading = {
52
86
  loading: true;
53
87
  isLoggedIn: never;
54
88
  user: never;
89
+ accessToken: never;
55
90
  };
56
91
  type UseUserLoggedIn = {
57
92
  loading: false;
58
93
  isLoggedIn: true;
59
94
  user: User;
95
+ accessToken: string;
60
96
  };
61
97
  type UseUserNotLoggedIn = {
62
98
  loading: false;
63
99
  isLoggedIn: false;
64
100
  user: undefined;
101
+ accessToken: undefined;
65
102
  };
66
103
  type UseUser = UseUserLoading | UseUserLoggedIn | UseUserNotLoggedIn;
67
104
  declare function useUser(): UseUser;
68
105
 
106
+ type AuthProviderProps = {
107
+ authUrl: string;
108
+ children?: React.ReactNode;
109
+ };
110
+ declare const AuthProvider: (props: AuthProviderProps) => React.JSX.Element;
111
+
69
112
  declare function useHostedPageUrls(): {
70
113
  getLoginPageUrl: () => string;
71
114
  getSignupPageUrl: () => string;
@@ -92,4 +135,4 @@ declare function RedirectToLogin({ children }: RedirectProps): React.JSX.Element
92
135
 
93
136
  declare function useRefreshAuth(): () => Promise<User | undefined>;
94
137
 
95
- export { AuthProvider, AuthProviderProps, OrgIdToOrgMemberInfo, OrgMemberInfo, RedirectProps, RedirectToLogin, RedirectToSignup, UseUser, UseUserLoading, UseUserLoggedIn, UseUserNotLoggedIn, User, useHostedPageUrls, useLogoutFunction, useRedirectFunctions, useRefreshAuth, useUser };
138
+ export { AuthProvider, AuthProviderProps, OrgIdToOrgMemberInfo, OrgMemberInfo, RedirectProps, RedirectToLogin, RedirectToSignup, UseUser, UseUserLoading, UseUserLoggedIn, UseUserNotLoggedIn, User, UserFromToken, useHostedPageUrls, useLogoutFunction, useRedirectFunctions, useRefreshAuth, useUser };
@@ -56,6 +56,7 @@ __export(client_exports, {
56
56
  RedirectToLogin: () => RedirectToLogin,
57
57
  RedirectToSignup: () => RedirectToSignup,
58
58
  User: () => User,
59
+ UserFromToken: () => UserFromToken,
59
60
  useHostedPageUrls: () => useHostedPageUrls,
60
61
  useLogoutFunction: () => useLogoutFunction,
61
62
  useRedirectFunctions: () => useRedirectFunctions,
@@ -65,7 +66,7 @@ __export(client_exports, {
65
66
  module.exports = __toCommonJS(client_exports);
66
67
 
67
68
  // src/user.ts
68
- var User = class {
69
+ var UserFromToken = class {
69
70
  constructor(userId, email, orgIdToOrgMemberInfo, firstName, lastName, username, legacyUserId, impersonatorUserId) {
70
71
  this.userId = userId;
71
72
  this.orgIdToOrgMemberInfo = orgIdToOrgMemberInfo;
@@ -112,7 +113,7 @@ var User = class {
112
113
  JSON.stringify(obj.orgIdToOrgMemberInfo[orgId])
113
114
  );
114
115
  }
115
- return new User(
116
+ return new UserFromToken(
116
117
  obj.userId,
117
118
  obj.email,
118
119
  orgIdToOrgMemberInfo,
@@ -170,9 +171,30 @@ var OrgMemberInfo = class {
170
171
  return this.userPermissions;
171
172
  }
172
173
  };
174
+ function toOrgIdToOrgMemberInfo(snake_case) {
175
+ if (snake_case === void 0) {
176
+ return void 0;
177
+ }
178
+ const camelCase = {};
179
+ for (const key of Object.keys(snake_case)) {
180
+ const snakeCaseValue = snake_case[key];
181
+ if (snakeCaseValue) {
182
+ camelCase[key] = new OrgMemberInfo(
183
+ snakeCaseValue.org_id,
184
+ snakeCaseValue.org_name,
185
+ snakeCaseValue.org_metadata,
186
+ snakeCaseValue.url_safe_org_name,
187
+ snakeCaseValue.user_role,
188
+ snakeCaseValue.inherited_user_roles_plus_current_role,
189
+ snakeCaseValue.user_permissions
190
+ );
191
+ }
192
+ }
193
+ return camelCase;
194
+ }
173
195
 
174
196
  // src/client/AuthProvider.tsx
175
- var import_react = __toESM(require("react"));
197
+ var import_react2 = __toESM(require("react"));
176
198
 
177
199
  // src/client/utils.ts
178
200
  var USER_INFO_KEY = "__PROPEL_AUTH_USER_INFO";
@@ -237,53 +259,162 @@ function isEqual(a, b) {
237
259
 
238
260
  // src/client/AuthProvider.tsx
239
261
  var import_navigation = require("next/navigation");
240
- var AuthContext = import_react.default.createContext(void 0);
262
+
263
+ // src/client/useUser.tsx
264
+ var import_react = require("react");
265
+ var User = class {
266
+ constructor({
267
+ userId,
268
+ email,
269
+ emailConfirmed,
270
+ hasPassword,
271
+ username,
272
+ firstName,
273
+ lastName,
274
+ pictureUrl,
275
+ orgIdToOrgMemberInfo,
276
+ mfaEnabled,
277
+ canCreateOrgs,
278
+ updatePasswordRequired,
279
+ createdAt,
280
+ lastActiveAt,
281
+ legacyUserId,
282
+ impersonatorUserId
283
+ }) {
284
+ this.userId = userId;
285
+ this.email = email;
286
+ this.emailConfirmed = emailConfirmed;
287
+ this.hasPassword = hasPassword;
288
+ this.username = username;
289
+ this.firstName = firstName;
290
+ this.lastName = lastName;
291
+ this.pictureUrl = pictureUrl;
292
+ this.orgIdToOrgMemberInfo = orgIdToOrgMemberInfo;
293
+ this.mfaEnabled = mfaEnabled;
294
+ this.canCreateOrgs = canCreateOrgs;
295
+ this.updatePasswordRequired = updatePasswordRequired;
296
+ this.createdAt = createdAt;
297
+ this.lastActiveAt = lastActiveAt;
298
+ this.legacyUserId = legacyUserId;
299
+ this.impersonatorUserId = impersonatorUserId;
300
+ }
301
+ getOrg(orgId) {
302
+ var _a;
303
+ return (_a = this.orgIdToOrgMemberInfo) == null ? void 0 : _a[orgId];
304
+ }
305
+ getOrgByName(orgName) {
306
+ if (!this.orgIdToOrgMemberInfo) {
307
+ return void 0;
308
+ }
309
+ const urlSafeOrgName = orgName.toLowerCase().replace(/ /g, "-");
310
+ for (const orgId in this.orgIdToOrgMemberInfo) {
311
+ const orgMemberInfo = this.orgIdToOrgMemberInfo[orgId];
312
+ if (orgMemberInfo.urlSafeOrgName === urlSafeOrgName) {
313
+ return orgMemberInfo;
314
+ }
315
+ }
316
+ return void 0;
317
+ }
318
+ getOrgs() {
319
+ if (!this.orgIdToOrgMemberInfo) {
320
+ return [];
321
+ }
322
+ return Object.values(this.orgIdToOrgMemberInfo);
323
+ }
324
+ isImpersonating() {
325
+ return !!this.impersonatorUserId;
326
+ }
327
+ };
328
+ function useUser() {
329
+ const context = (0, import_react.useContext)(AuthContext);
330
+ if (context === void 0) {
331
+ throw new Error("useUser must be used within an AuthProvider");
332
+ }
333
+ const { loading, userAndAccessToken } = context;
334
+ if (loading) {
335
+ return {
336
+ loading: true,
337
+ isLoggedIn: void 0,
338
+ user: void 0,
339
+ accessToken: void 0
340
+ };
341
+ } else if (userAndAccessToken.user) {
342
+ return {
343
+ loading: false,
344
+ isLoggedIn: true,
345
+ user: userAndAccessToken.user,
346
+ accessToken: userAndAccessToken.accessToken
347
+ };
348
+ } else {
349
+ return {
350
+ loading: false,
351
+ isLoggedIn: false,
352
+ user: void 0,
353
+ accessToken: void 0
354
+ };
355
+ }
356
+ }
357
+
358
+ // src/client/AuthProvider.tsx
359
+ var AuthContext = import_react2.default.createContext(void 0);
241
360
  var initialAuthState = {
242
361
  loading: true,
243
- user: void 0,
362
+ userAndAccessToken: {
363
+ user: void 0,
364
+ accessToken: void 0
365
+ },
244
366
  authChangeDetected: false
245
367
  };
246
368
  function authStateReducer(_state, action) {
247
- const authChangeDetected = !_state.loading && !isEqual(action.user, _state.user);
369
+ const authChangeDetected = !_state.loading && !isEqual(action.user, _state.userAndAccessToken.user);
248
370
  if (!action.user) {
249
371
  return {
250
372
  loading: false,
251
- user: void 0,
373
+ userAndAccessToken: {
374
+ user: void 0,
375
+ accessToken: void 0
376
+ },
252
377
  authChangeDetected
253
378
  };
254
379
  } else if (_state.loading) {
255
380
  return {
256
381
  loading: false,
257
- user: action.user,
382
+ userAndAccessToken: {
383
+ user: action.user,
384
+ accessToken: action.accessToken
385
+ },
258
386
  authChangeDetected
259
387
  };
260
388
  } else {
261
389
  return {
262
390
  loading: false,
263
- user: action.user,
391
+ userAndAccessToken: {
392
+ user: action.user,
393
+ accessToken: action.accessToken
394
+ },
264
395
  authChangeDetected
265
396
  };
266
397
  }
267
398
  }
268
399
  var AuthProvider = (props) => {
269
- const [authState, dispatchInner] = (0, import_react.useReducer)(authStateReducer, initialAuthState);
400
+ const [authState, dispatchInner] = (0, import_react2.useReducer)(authStateReducer, initialAuthState);
270
401
  const router = (0, import_navigation.useRouter)();
271
- const dispatch = (0, import_react.useCallback)((action) => {
402
+ const dispatch = (0, import_react2.useCallback)((action) => {
272
403
  dispatchInner(action);
273
404
  saveUserToLocalStorage(action.user);
274
405
  }, [dispatchInner]);
275
- (0, import_react.useEffect)(() => {
406
+ (0, import_react2.useEffect)(() => {
276
407
  if (authState.authChangeDetected) {
277
408
  router.refresh();
278
409
  }
279
410
  }, [authState.authChangeDetected, router]);
280
- (0, import_react.useEffect)(() => {
411
+ (0, import_react2.useEffect)(() => {
281
412
  let didCancel = false;
282
413
  function refreshAuthInfo2() {
283
414
  return __async(this, null, function* () {
284
- const { user } = yield apiGetUserInfo();
415
+ const action = yield apiGetUserInfo();
285
416
  if (!didCancel) {
286
- dispatch({ user });
417
+ dispatch(action);
287
418
  }
288
419
  });
289
420
  }
@@ -292,19 +423,19 @@ var AuthProvider = (props) => {
292
423
  didCancel = true;
293
424
  };
294
425
  }, []);
295
- (0, import_react.useEffect)(() => {
426
+ (0, import_react2.useEffect)(() => {
296
427
  let didCancel = false;
297
428
  function refreshToken() {
298
429
  return __async(this, null, function* () {
299
- const { user } = yield apiGetUserInfo();
430
+ const action = yield apiGetUserInfo();
300
431
  if (!didCancel) {
301
- dispatch({ user });
432
+ dispatch(action);
302
433
  }
303
434
  });
304
435
  }
305
436
  function onStorageEvent(event) {
306
437
  return __async(this, null, function* () {
307
- if (event.key === USER_INFO_KEY && !doesLocalStorageMatch(event.newValue, authState.user)) {
438
+ if (event.key === USER_INFO_KEY && !doesLocalStorageMatch(event.newValue, authState.userAndAccessToken.user)) {
308
439
  yield refreshToken();
309
440
  }
310
441
  });
@@ -324,8 +455,8 @@ var AuthProvider = (props) => {
324
455
  window.removeEventListener("focus", refreshToken);
325
456
  }
326
457
  };
327
- }, [dispatch, authState.user]);
328
- const logout = (0, import_react.useCallback)(() => __async(void 0, null, function* () {
458
+ }, [dispatch, authState.userAndAccessToken.user]);
459
+ const logout = (0, import_react2.useCallback)(() => __async(void 0, null, function* () {
329
460
  yield fetch("/api/auth/logout", {
330
461
  method: "POST",
331
462
  headers: {
@@ -333,14 +464,14 @@ var AuthProvider = (props) => {
333
464
  },
334
465
  credentials: "include"
335
466
  });
336
- dispatch({ user: void 0 });
467
+ dispatch({ user: void 0, accessToken: void 0 });
337
468
  }), [dispatch]);
338
469
  const getLoginPageUrl = () => "/api/auth/login";
339
470
  const getSignupPageUrl = () => "/api/auth/signup";
340
- const getAccountPageUrl = (0, import_react.useCallback)(() => {
471
+ const getAccountPageUrl = (0, import_react2.useCallback)(() => {
341
472
  return `${props.authUrl}/account`;
342
473
  }, [props.authUrl]);
343
- const getOrgPageUrl = (0, import_react.useCallback)(
474
+ const getOrgPageUrl = (0, import_react2.useCallback)(
344
475
  (orgId) => {
345
476
  if (orgId) {
346
477
  return `${props.authUrl}/org?id=${orgId}`;
@@ -350,10 +481,10 @@ var AuthProvider = (props) => {
350
481
  },
351
482
  [props.authUrl]
352
483
  );
353
- const getCreateOrgPageUrl = (0, import_react.useCallback)(() => {
484
+ const getCreateOrgPageUrl = (0, import_react2.useCallback)(() => {
354
485
  return `${props.authUrl}/create_org`;
355
486
  }, [props.authUrl]);
356
- const getSetupSAMLPageUrl = (0, import_react.useCallback)(
487
+ const getSetupSAMLPageUrl = (0, import_react2.useCallback)(
357
488
  (orgId) => {
358
489
  return `${props.authUrl}/saml?id=${orgId}`;
359
490
  },
@@ -369,13 +500,13 @@ var AuthProvider = (props) => {
369
500
  const redirectToCreateOrgPage = () => redirectTo(getCreateOrgPageUrl());
370
501
  const redirectToSetupSAMLPage = (orgId) => redirectTo(getSetupSAMLPageUrl(orgId));
371
502
  const refreshAuthInfo = () => __async(void 0, null, function* () {
372
- const { user } = yield apiGetUserInfo();
373
- dispatch({ user });
374
- return user;
503
+ const action = yield apiGetUserInfo();
504
+ dispatch(action);
505
+ return action.user;
375
506
  });
376
507
  const value = {
377
508
  loading: authState.loading,
378
- user: authState.user,
509
+ userAndAccessToken: authState.userAndAccessToken,
379
510
  logout,
380
511
  redirectToLoginPage,
381
512
  redirectToSignupPage,
@@ -391,7 +522,7 @@ var AuthProvider = (props) => {
391
522
  getSetupSAMLPageUrl,
392
523
  refreshAuthInfo
393
524
  };
394
- return /* @__PURE__ */ import_react.default.createElement(AuthContext.Provider, { value }, props.children);
525
+ return /* @__PURE__ */ import_react2.default.createElement(AuthContext.Provider, { value }, props.children);
395
526
  };
396
527
  function apiGetUserInfo() {
397
528
  return __async(this, null, function* () {
@@ -404,11 +535,27 @@ function apiGetUserInfo() {
404
535
  credentials: "include"
405
536
  });
406
537
  if (userInfoResponse.ok) {
407
- const userJson = yield userInfoResponse.text();
408
- const user = User.fromJSON(userJson);
409
- return { user };
538
+ const { userinfo, accessToken, impersonatorUserId } = yield userInfoResponse.json();
539
+ const user = new User({
540
+ userId: userinfo.user_id,
541
+ email: userinfo.email,
542
+ emailConfirmed: userinfo.email_confirmed,
543
+ hasPassword: userinfo.has_password,
544
+ username: userinfo.username,
545
+ firstName: userinfo.first_name,
546
+ lastName: userinfo.last_name,
547
+ pictureUrl: userinfo.picture_url,
548
+ orgIdToOrgMemberInfo: toOrgIdToOrgMemberInfo(userinfo.org_id_to_org_info),
549
+ mfaEnabled: userinfo.mfa_enabled,
550
+ canCreateOrgs: userinfo.can_create_orgs,
551
+ updatePasswordRequired: userinfo.update_password_required,
552
+ createdAt: userinfo.created_at,
553
+ lastActiveAt: userinfo.last_active_at,
554
+ impersonatorUserId
555
+ });
556
+ return { user, accessToken };
410
557
  } else if (userInfoResponse.status === 401) {
411
- return { user: void 0 };
558
+ return { user: void 0, accessToken: void 0 };
412
559
  } else {
413
560
  console.log("Failed to refresh token", userInfoResponse);
414
561
  }
@@ -419,35 +566,6 @@ function apiGetUserInfo() {
419
566
  });
420
567
  }
421
568
 
422
- // src/client/useUser.tsx
423
- var import_react2 = require("react");
424
- function useUser() {
425
- const context = (0, import_react2.useContext)(AuthContext);
426
- if (context === void 0) {
427
- throw new Error("useUser must be used within an AuthProvider");
428
- }
429
- const { loading, user } = context;
430
- if (loading) {
431
- return {
432
- loading: true,
433
- isLoggedIn: void 0,
434
- user: void 0
435
- };
436
- } else if (user) {
437
- return {
438
- loading: false,
439
- isLoggedIn: true,
440
- user
441
- };
442
- } else {
443
- return {
444
- loading: false,
445
- isLoggedIn: false,
446
- user: void 0
447
- };
448
- }
449
- }
450
-
451
569
  // src/client/useHostedPageUrls.tsx
452
570
  var import_react3 = require("react");
453
571
  function useHostedPageUrls() {
@@ -538,6 +656,7 @@ function useRefreshAuth() {
538
656
  RedirectToLogin,
539
657
  RedirectToSignup,
540
658
  User,
659
+ UserFromToken,
541
660
  useHostedPageUrls,
542
661
  useLogoutFunction,
543
662
  useRedirectFunctions,