@propelauth/nextjs 0.0.71 → 0.0.77
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 +183 -64
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +169 -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 +4 -3
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,162 @@ 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);
|
|
248
370
|
if (!action.user) {
|
|
249
371
|
return {
|
|
250
372
|
loading: false,
|
|
251
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
400
|
+
const [authState, dispatchInner] = (0, import_react2.useReducer)(authStateReducer, initialAuthState);
|
|
270
401
|
const router = (0, import_navigation.useRouter)();
|
|
271
|
-
const dispatch = (0,
|
|
402
|
+
const dispatch = (0, import_react2.useCallback)((action) => {
|
|
272
403
|
dispatchInner(action);
|
|
273
404
|
saveUserToLocalStorage(action.user);
|
|
274
405
|
}, [dispatchInner]);
|
|
275
|
-
(0,
|
|
406
|
+
(0, import_react2.useEffect)(() => {
|
|
276
407
|
if (authState.authChangeDetected) {
|
|
277
408
|
router.refresh();
|
|
278
409
|
}
|
|
279
410
|
}, [authState.authChangeDetected, router]);
|
|
280
|
-
(0,
|
|
411
|
+
(0, import_react2.useEffect)(() => {
|
|
281
412
|
let didCancel = false;
|
|
282
413
|
function refreshAuthInfo2() {
|
|
283
414
|
return __async(this, null, function* () {
|
|
284
|
-
const
|
|
415
|
+
const action = yield apiGetUserInfo();
|
|
285
416
|
if (!didCancel) {
|
|
286
|
-
dispatch(
|
|
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,
|
|
426
|
+
(0, import_react2.useEffect)(() => {
|
|
296
427
|
let didCancel = false;
|
|
297
428
|
function refreshToken() {
|
|
298
429
|
return __async(this, null, function* () {
|
|
299
|
-
const
|
|
430
|
+
const action = yield apiGetUserInfo();
|
|
300
431
|
if (!didCancel) {
|
|
301
|
-
dispatch(
|
|
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,
|
|
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,
|
|
471
|
+
const getAccountPageUrl = (0, import_react2.useCallback)(() => {
|
|
341
472
|
return `${props.authUrl}/account`;
|
|
342
473
|
}, [props.authUrl]);
|
|
343
|
-
const getOrgPageUrl = (0,
|
|
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,
|
|
484
|
+
const getCreateOrgPageUrl = (0, import_react2.useCallback)(() => {
|
|
354
485
|
return `${props.authUrl}/create_org`;
|
|
355
486
|
}, [props.authUrl]);
|
|
356
|
-
const getSetupSAMLPageUrl = (0,
|
|
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
|
|
373
|
-
dispatch(
|
|
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
|
-
|
|
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__ */
|
|
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
|
|
408
|
-
const user = User
|
|
409
|
-
|
|
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,
|