@propelauth/nextjs 0.0.72 → 0.0.80
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 +50 -8
- package/dist/client/index.d.ts +52 -9
- package/dist/client/index.js +184 -64
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +170 -51
- package/dist/client/index.mjs.map +1 -1
- package/dist/server/app-router/index.d.ts +6 -5
- package/dist/server/app-router/index.js +27 -20
- package/dist/server/app-router/index.js.map +1 -1
- package/dist/server/app-router/index.mjs +26 -20
- package/dist/server/app-router/index.mjs.map +1 -1
- package/dist/server/index.d.ts +60 -5
- package/dist/server/index.js +26 -6
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +24 -5
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/pages/index.d.ts +6 -5
- package/dist/server/pages/index.js +41 -4
- package/dist/server/pages/index.js.map +1 -1
- package/dist/server/pages/index.mjs +40 -4
- package/dist/server/pages/index.mjs.map +1 -1
- package/package.json +2 -1
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
|
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
|
-
####
|
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
|
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 (
|
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 (
|
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 {
|
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
|
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.
|
package/dist/client/index.d.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
|
3
|
-
declare class
|
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):
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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 };
|
package/dist/client/index.js
CHANGED
@@ -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
|
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
|
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
|
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,163 @@ function isEqual(a, b) {
|
|
237
259
|
|
238
260
|
// src/client/AuthProvider.tsx
|
239
261
|
var import_navigation = require("next/navigation");
|
240
|
-
|
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
|
-
|
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);
|
370
|
+
console.log("dispatching auth state reducer", { action, _state, authChangeDetected });
|
248
371
|
if (!action.user) {
|
249
372
|
return {
|
250
373
|
loading: false,
|
251
|
-
|
374
|
+
userAndAccessToken: {
|
375
|
+
user: void 0,
|
376
|
+
accessToken: void 0
|
377
|
+
},
|
252
378
|
authChangeDetected
|
253
379
|
};
|
254
380
|
} else if (_state.loading) {
|
255
381
|
return {
|
256
382
|
loading: false,
|
257
|
-
|
383
|
+
userAndAccessToken: {
|
384
|
+
user: action.user,
|
385
|
+
accessToken: action.accessToken
|
386
|
+
},
|
258
387
|
authChangeDetected
|
259
388
|
};
|
260
389
|
} else {
|
261
390
|
return {
|
262
391
|
loading: false,
|
263
|
-
|
392
|
+
userAndAccessToken: {
|
393
|
+
user: action.user,
|
394
|
+
accessToken: action.accessToken
|
395
|
+
},
|
264
396
|
authChangeDetected
|
265
397
|
};
|
266
398
|
}
|
267
399
|
}
|
268
400
|
var AuthProvider = (props) => {
|
269
|
-
const [authState, dispatchInner] = (0,
|
401
|
+
const [authState, dispatchInner] = (0, import_react2.useReducer)(authStateReducer, initialAuthState);
|
270
402
|
const router = (0, import_navigation.useRouter)();
|
271
|
-
const dispatch = (0,
|
403
|
+
const dispatch = (0, import_react2.useCallback)((action) => {
|
272
404
|
dispatchInner(action);
|
273
405
|
saveUserToLocalStorage(action.user);
|
274
406
|
}, [dispatchInner]);
|
275
|
-
(0,
|
407
|
+
(0, import_react2.useEffect)(() => {
|
276
408
|
if (authState.authChangeDetected) {
|
277
409
|
router.refresh();
|
278
410
|
}
|
279
411
|
}, [authState.authChangeDetected, router]);
|
280
|
-
(0,
|
412
|
+
(0, import_react2.useEffect)(() => {
|
281
413
|
let didCancel = false;
|
282
414
|
function refreshAuthInfo2() {
|
283
415
|
return __async(this, null, function* () {
|
284
|
-
const
|
416
|
+
const action = yield apiGetUserInfo();
|
285
417
|
if (!didCancel) {
|
286
|
-
dispatch(
|
418
|
+
dispatch(action);
|
287
419
|
}
|
288
420
|
});
|
289
421
|
}
|
@@ -292,19 +424,19 @@ var AuthProvider = (props) => {
|
|
292
424
|
didCancel = true;
|
293
425
|
};
|
294
426
|
}, []);
|
295
|
-
(0,
|
427
|
+
(0, import_react2.useEffect)(() => {
|
296
428
|
let didCancel = false;
|
297
429
|
function refreshToken() {
|
298
430
|
return __async(this, null, function* () {
|
299
|
-
const
|
431
|
+
const action = yield apiGetUserInfo();
|
300
432
|
if (!didCancel) {
|
301
|
-
dispatch(
|
433
|
+
dispatch(action);
|
302
434
|
}
|
303
435
|
});
|
304
436
|
}
|
305
437
|
function onStorageEvent(event) {
|
306
438
|
return __async(this, null, function* () {
|
307
|
-
if (event.key === USER_INFO_KEY && !doesLocalStorageMatch(event.newValue, authState.user)) {
|
439
|
+
if (event.key === USER_INFO_KEY && !doesLocalStorageMatch(event.newValue, authState.userAndAccessToken.user)) {
|
308
440
|
yield refreshToken();
|
309
441
|
}
|
310
442
|
});
|
@@ -324,8 +456,8 @@ var AuthProvider = (props) => {
|
|
324
456
|
window.removeEventListener("focus", refreshToken);
|
325
457
|
}
|
326
458
|
};
|
327
|
-
}, [dispatch, authState.user]);
|
328
|
-
const logout = (0,
|
459
|
+
}, [dispatch, authState.userAndAccessToken.user]);
|
460
|
+
const logout = (0, import_react2.useCallback)(() => __async(void 0, null, function* () {
|
329
461
|
yield fetch("/api/auth/logout", {
|
330
462
|
method: "POST",
|
331
463
|
headers: {
|
@@ -333,14 +465,14 @@ var AuthProvider = (props) => {
|
|
333
465
|
},
|
334
466
|
credentials: "include"
|
335
467
|
});
|
336
|
-
dispatch({ user: void 0 });
|
468
|
+
dispatch({ user: void 0, accessToken: void 0 });
|
337
469
|
}), [dispatch]);
|
338
470
|
const getLoginPageUrl = () => "/api/auth/login";
|
339
471
|
const getSignupPageUrl = () => "/api/auth/signup";
|
340
|
-
const getAccountPageUrl = (0,
|
472
|
+
const getAccountPageUrl = (0, import_react2.useCallback)(() => {
|
341
473
|
return `${props.authUrl}/account`;
|
342
474
|
}, [props.authUrl]);
|
343
|
-
const getOrgPageUrl = (0,
|
475
|
+
const getOrgPageUrl = (0, import_react2.useCallback)(
|
344
476
|
(orgId) => {
|
345
477
|
if (orgId) {
|
346
478
|
return `${props.authUrl}/org?id=${orgId}`;
|
@@ -350,10 +482,10 @@ var AuthProvider = (props) => {
|
|
350
482
|
},
|
351
483
|
[props.authUrl]
|
352
484
|
);
|
353
|
-
const getCreateOrgPageUrl = (0,
|
485
|
+
const getCreateOrgPageUrl = (0, import_react2.useCallback)(() => {
|
354
486
|
return `${props.authUrl}/create_org`;
|
355
487
|
}, [props.authUrl]);
|
356
|
-
const getSetupSAMLPageUrl = (0,
|
488
|
+
const getSetupSAMLPageUrl = (0, import_react2.useCallback)(
|
357
489
|
(orgId) => {
|
358
490
|
return `${props.authUrl}/saml?id=${orgId}`;
|
359
491
|
},
|
@@ -369,13 +501,13 @@ var AuthProvider = (props) => {
|
|
369
501
|
const redirectToCreateOrgPage = () => redirectTo(getCreateOrgPageUrl());
|
370
502
|
const redirectToSetupSAMLPage = (orgId) => redirectTo(getSetupSAMLPageUrl(orgId));
|
371
503
|
const refreshAuthInfo = () => __async(void 0, null, function* () {
|
372
|
-
const
|
373
|
-
dispatch(
|
374
|
-
return user;
|
504
|
+
const action = yield apiGetUserInfo();
|
505
|
+
dispatch(action);
|
506
|
+
return action.user;
|
375
507
|
});
|
376
508
|
const value = {
|
377
509
|
loading: authState.loading,
|
378
|
-
|
510
|
+
userAndAccessToken: authState.userAndAccessToken,
|
379
511
|
logout,
|
380
512
|
redirectToLoginPage,
|
381
513
|
redirectToSignupPage,
|
@@ -391,7 +523,7 @@ var AuthProvider = (props) => {
|
|
391
523
|
getSetupSAMLPageUrl,
|
392
524
|
refreshAuthInfo
|
393
525
|
};
|
394
|
-
return /* @__PURE__ */
|
526
|
+
return /* @__PURE__ */ import_react2.default.createElement(AuthContext.Provider, { value }, props.children);
|
395
527
|
};
|
396
528
|
function apiGetUserInfo() {
|
397
529
|
return __async(this, null, function* () {
|
@@ -404,11 +536,27 @@ function apiGetUserInfo() {
|
|
404
536
|
credentials: "include"
|
405
537
|
});
|
406
538
|
if (userInfoResponse.ok) {
|
407
|
-
const
|
408
|
-
const user = User
|
409
|
-
|
539
|
+
const { userinfo, accessToken, impersonatorUserId } = yield userInfoResponse.json();
|
540
|
+
const user = new User({
|
541
|
+
userId: userinfo.user_id,
|
542
|
+
email: userinfo.email,
|
543
|
+
emailConfirmed: userinfo.email_confirmed,
|
544
|
+
hasPassword: userinfo.has_password,
|
545
|
+
username: userinfo.username,
|
546
|
+
firstName: userinfo.first_name,
|
547
|
+
lastName: userinfo.last_name,
|
548
|
+
pictureUrl: userinfo.picture_url,
|
549
|
+
orgIdToOrgMemberInfo: toOrgIdToOrgMemberInfo(userinfo.org_id_to_org_info),
|
550
|
+
mfaEnabled: userinfo.mfa_enabled,
|
551
|
+
canCreateOrgs: userinfo.can_create_orgs,
|
552
|
+
updatePasswordRequired: userinfo.update_password_required,
|
553
|
+
createdAt: userinfo.created_at,
|
554
|
+
lastActiveAt: userinfo.last_active_at,
|
555
|
+
impersonatorUserId
|
556
|
+
});
|
557
|
+
return { user, accessToken };
|
410
558
|
} else if (userInfoResponse.status === 401) {
|
411
|
-
return { user: void 0 };
|
559
|
+
return { user: void 0, accessToken: void 0 };
|
412
560
|
} else {
|
413
561
|
console.log("Failed to refresh token", userInfoResponse);
|
414
562
|
}
|
@@ -419,35 +567,6 @@ function apiGetUserInfo() {
|
|
419
567
|
});
|
420
568
|
}
|
421
569
|
|
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
570
|
// src/client/useHostedPageUrls.tsx
|
452
571
|
var import_react3 = require("react");
|
453
572
|
function useHostedPageUrls() {
|
@@ -538,6 +657,7 @@ function useRefreshAuth() {
|
|
538
657
|
RedirectToLogin,
|
539
658
|
RedirectToSignup,
|
540
659
|
User,
|
660
|
+
UserFromToken,
|
541
661
|
useHostedPageUrls,
|
542
662
|
useLogoutFunction,
|
543
663
|
useRedirectFunctions,
|