@propelauth/nextjs 0.0.111 → 0.0.112-beta.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -42,8 +42,9 @@ import { NextResponse } from "next/server.js";
42
42
 
43
43
  // src/user.ts
44
44
  var UserFromToken = class {
45
- constructor(userId, email, orgIdToOrgMemberInfo, firstName, lastName, username, legacyUserId, impersonatorUserId, properties) {
45
+ constructor(userId, email, orgIdToOrgMemberInfo, firstName, lastName, username, legacyUserId, impersonatorUserId, properties, activeOrgId) {
46
46
  this.userId = userId;
47
+ this.activeOrgId = activeOrgId;
47
48
  this.orgIdToOrgMemberInfo = orgIdToOrgMemberInfo;
48
49
  this.email = email;
49
50
  this.firstName = firstName;
@@ -53,6 +54,15 @@ var UserFromToken = class {
53
54
  this.impersonatorUserId = impersonatorUserId;
54
55
  this.properties = properties;
55
56
  }
57
+ getActiveOrg() {
58
+ if (!this.activeOrgId || !this.orgIdToOrgMemberInfo) {
59
+ return void 0;
60
+ }
61
+ return this.orgIdToOrgMemberInfo[this.activeOrgId];
62
+ }
63
+ getActiveOrgId() {
64
+ return this.activeOrgId;
65
+ }
56
66
  getOrg(orgId) {
57
67
  if (!this.orgIdToOrgMemberInfo) {
58
68
  return void 0;
@@ -85,9 +95,7 @@ var UserFromToken = class {
85
95
  const obj = JSON.parse(json);
86
96
  const orgIdToOrgMemberInfo = {};
87
97
  for (const orgId in obj.orgIdToOrgMemberInfo) {
88
- orgIdToOrgMemberInfo[orgId] = OrgMemberInfo.fromJSON(
89
- JSON.stringify(obj.orgIdToOrgMemberInfo[orgId])
90
- );
98
+ orgIdToOrgMemberInfo[orgId] = OrgMemberInfo.fromJSON(JSON.stringify(obj.orgIdToOrgMemberInfo[orgId]));
91
99
  }
92
100
  return new UserFromToken(
93
101
  obj.userId,
@@ -101,6 +109,29 @@ var UserFromToken = class {
101
109
  obj.properties
102
110
  );
103
111
  }
112
+ static fromJwtPayload(payload) {
113
+ let activeOrgId;
114
+ let orgIdToOrgMemberInfo;
115
+ if (payload.org_member_info) {
116
+ activeOrgId = payload.org_member_info.org_id;
117
+ orgIdToOrgMemberInfo = toOrgIdToOrgMemberInfo({ [activeOrgId]: payload.org_member_info });
118
+ } else {
119
+ activeOrgId = void 0;
120
+ orgIdToOrgMemberInfo = toOrgIdToOrgMemberInfo(payload.org_id_to_org_member_info);
121
+ }
122
+ return new UserFromToken(
123
+ payload.user_id,
124
+ payload.email,
125
+ orgIdToOrgMemberInfo,
126
+ payload.first_name,
127
+ payload.last_name,
128
+ payload.username,
129
+ payload.legacy_user_id,
130
+ payload.impersonatorUserId,
131
+ payload.properties,
132
+ activeOrgId
133
+ );
134
+ }
104
135
  };
105
136
  var OrgMemberInfo = class {
106
137
  constructor(orgId, orgName, orgMetadata, urlSafeOrgName, userAssignedRole, userInheritedRolesPlusCurrentRole, userPermissions) {
@@ -149,17 +180,7 @@ var OrgMemberInfo = class {
149
180
  }
150
181
  };
151
182
  function toUser(snake_case) {
152
- return new UserFromToken(
153
- snake_case.user_id,
154
- snake_case.email,
155
- toOrgIdToOrgMemberInfo(snake_case.org_id_to_org_member_info),
156
- snake_case.first_name,
157
- snake_case.last_name,
158
- snake_case.username,
159
- snake_case.legacy_user_id,
160
- snake_case.impersonatorUserId,
161
- snake_case.properties
162
- );
183
+ return UserFromToken.fromJwtPayload(snake_case);
163
184
  }
164
185
  function toOrgIdToOrgMemberInfo(snake_case) {
165
186
  if (snake_case === void 0) {
@@ -231,12 +252,17 @@ function getVerifierKey() {
231
252
  }
232
253
  return verifierKey.replace(/\\n/g, "\n");
233
254
  }
234
- function refreshTokenWithAccessAndRefreshToken(refreshToken) {
255
+ function refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId) {
235
256
  return __async(this, null, function* () {
236
257
  const body = {
237
258
  refresh_token: refreshToken
238
259
  };
239
- const url = `${getAuthUrlOrigin()}/api/backend/v1/refresh_token`;
260
+ const queryParams = new URLSearchParams();
261
+ if (activeOrgId) {
262
+ queryParams.set("with_active_org_support", "true");
263
+ queryParams.set("active_org_id", activeOrgId);
264
+ }
265
+ const url = `${getAuthUrlOrigin()}/api/backend/v1/refresh_token?${queryParams.toString()}`;
240
266
  const response = yield fetch(url, {
241
267
  method: "POST",
242
268
  body: JSON.stringify(body),
@@ -248,10 +274,7 @@ function refreshTokenWithAccessAndRefreshToken(refreshToken) {
248
274
  if (response.ok) {
249
275
  const data = yield response.json();
250
276
  const newRefreshToken = data.refresh_token;
251
- const {
252
- access_token: accessToken,
253
- expires_at_seconds: expiresAtSeconds
254
- } = data.access_token;
277
+ const { access_token: accessToken, expires_at_seconds: expiresAtSeconds } = data.access_token;
255
278
  return {
256
279
  refreshToken: newRefreshToken,
257
280
  accessToken,
@@ -312,6 +335,9 @@ function validateAccessToken(accessToken) {
312
335
  });
313
336
  }
314
337
 
338
+ // src/shared.ts
339
+ var ACTIVE_ORG_ID_COOKIE_NAME = "__pa_org_id";
340
+
315
341
  // src/server/app-router.ts
316
342
  function getUserOrRedirect() {
317
343
  return __async(this, null, function* () {
@@ -326,8 +352,7 @@ function getUserOrRedirect() {
326
352
  }
327
353
  function getUser() {
328
354
  return __async(this, null, function* () {
329
- var _a;
330
- const accessToken = headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || ((_a = cookies().get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value);
355
+ const accessToken = getAccessToken();
331
356
  if (accessToken) {
332
357
  const user = yield validateAccessTokenOrUndefined(accessToken);
333
358
  if (user) {
@@ -338,14 +363,12 @@ function getUser() {
338
363
  });
339
364
  }
340
365
  function getAccessToken() {
341
- return __async(this, null, function* () {
342
- var _a;
343
- return headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || ((_a = cookies().get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value);
344
- });
366
+ var _a;
367
+ return headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || ((_a = cookies().get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value);
345
368
  }
346
369
  function authMiddleware(req) {
347
370
  return __async(this, null, function* () {
348
- var _a, _b;
371
+ var _a, _b, _c;
349
372
  if (req.headers.has(CUSTOM_HEADER_FOR_ACCESS_TOKEN)) {
350
373
  throw new Error(`${CUSTOM_HEADER_FOR_ACCESS_TOKEN} is set which is for internal use only`);
351
374
  } else if (req.nextUrl.pathname === CALLBACK_PATH || req.nextUrl.pathname === LOGOUT_PATH || req.nextUrl.pathname === USERINFO_PATH) {
@@ -353,6 +376,7 @@ function authMiddleware(req) {
353
376
  }
354
377
  const accessToken = (_a = req.cookies.get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
355
378
  const refreshToken = (_b = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _b.value;
379
+ const activeOrgId = (_c = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _c.value;
356
380
  if (accessToken) {
357
381
  const user = yield validateAccessTokenOrUndefined(accessToken);
358
382
  if (user) {
@@ -360,7 +384,7 @@ function authMiddleware(req) {
360
384
  }
361
385
  }
362
386
  if (refreshToken) {
363
- const response = yield refreshTokenWithAccessAndRefreshToken(refreshToken);
387
+ const response = yield refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId);
364
388
  if (response.error === "unexpected") {
365
389
  throw new Error("Unexpected error while refreshing access token");
366
390
  } else if (response.error === "unauthorized") {
@@ -421,7 +445,7 @@ function getRouteHandlers(args) {
421
445
  }
422
446
  function callbackGetHandler(req) {
423
447
  return __async(this, null, function* () {
424
- var _a, _b;
448
+ var _a, _b, _c;
425
449
  const oauthState = (_a = req.cookies.get(STATE_COOKIE_NAME)) == null ? void 0 : _a.value;
426
450
  if (!oauthState || oauthState.length !== 64) {
427
451
  return new Response(null, { status: 302, headers: { Location: LOGIN_PATH } });
@@ -457,6 +481,49 @@ function getRouteHandlers(args) {
457
481
  console.error("postLoginRedirectPathFn returned undefined");
458
482
  return new Response("Unexpected error", { status: 500 });
459
483
  }
484
+ const currentActiveOrgId = (_c = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _c.value;
485
+ const user = yield validateAccessToken(accessToken);
486
+ const isUserInCurrentActiveOrg = !!currentActiveOrgId && !!user.getOrg(currentActiveOrgId);
487
+ let activeOrgId = void 0;
488
+ if (isUserInCurrentActiveOrg) {
489
+ activeOrgId = currentActiveOrgId;
490
+ } else if (args == null ? void 0 : args.getDefaultActiveOrgId) {
491
+ activeOrgId = args.getDefaultActiveOrgId(req, user);
492
+ }
493
+ if (activeOrgId) {
494
+ const response2 = yield refreshTokenWithAccessAndRefreshToken(data.refresh_token, activeOrgId);
495
+ if (response2.error === "unexpected") {
496
+ throw new Error("Unexpected error while setting active org");
497
+ } else if (response2.error === "unauthorized") {
498
+ console.error(
499
+ "Unauthorized error while setting active org. Your user may not have access to this org"
500
+ );
501
+ return new Response("Unauthorized", { status: 401 });
502
+ } else {
503
+ const headers3 = new Headers();
504
+ headers3.append("Location", returnToPath);
505
+ headers3.append(
506
+ "Set-Cookie",
507
+ `${ACCESS_TOKEN_COOKIE_NAME}=${response2.accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
508
+ );
509
+ headers3.append(
510
+ "Set-Cookie",
511
+ `${REFRESH_TOKEN_COOKIE_NAME}=${response2.refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
512
+ );
513
+ headers3.append(
514
+ "Set-Cookie",
515
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=${activeOrgId}; Path=/; HttpOnly; Secure; SameSite=Lax`
516
+ );
517
+ headers3.append(
518
+ "Set-Cookie",
519
+ `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
520
+ );
521
+ return new Response(null, {
522
+ status: 302,
523
+ headers: headers3
524
+ });
525
+ }
526
+ }
460
527
  const headers2 = new Headers();
461
528
  headers2.append("Location", returnToPath);
462
529
  headers2.append(
@@ -467,6 +534,10 @@ function getRouteHandlers(args) {
467
534
  "Set-Cookie",
468
535
  `${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`
469
536
  );
537
+ headers2.append(
538
+ "Set-Cookie",
539
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
540
+ );
470
541
  headers2.append(
471
542
  "Set-Cookie",
472
543
  `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
@@ -487,10 +558,11 @@ function getRouteHandlers(args) {
487
558
  }
488
559
  function userinfoGetHandler(req) {
489
560
  return __async(this, null, function* () {
490
- var _a;
561
+ var _a, _b;
491
562
  const oldRefreshToken = (_a = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
563
+ const activeOrgId = (_b = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _b.value;
492
564
  if (oldRefreshToken) {
493
- const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken);
565
+ const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken, activeOrgId);
494
566
  if (refreshResponse.error === "unexpected") {
495
567
  throw new Error("Unexpected error while refreshing access token");
496
568
  } else if (refreshResponse.error === "unauthorized") {
@@ -503,6 +575,10 @@ function getRouteHandlers(args) {
503
575
  "Set-Cookie",
504
576
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
505
577
  );
578
+ headers3.append(
579
+ "Set-Cookie",
580
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
581
+ );
506
582
  return new Response("Unauthorized", { status: 401, headers: headers3 });
507
583
  }
508
584
  const refreshToken = refreshResponse.refreshToken;
@@ -521,7 +597,8 @@ function getRouteHandlers(args) {
521
597
  const jsonResponse = {
522
598
  userinfo: data,
523
599
  accessToken,
524
- impersonatorUserId: userFromToken.impersonatorUserId
600
+ impersonatorUserId: userFromToken.impersonatorUserId,
601
+ activeOrgId
525
602
  };
526
603
  const headers3 = new Headers();
527
604
  headers3.append(
@@ -547,6 +624,10 @@ function getRouteHandlers(args) {
547
624
  "Set-Cookie",
548
625
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
549
626
  );
627
+ headers3.append(
628
+ "Set-Cookie",
629
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
630
+ );
550
631
  return new Response(null, {
551
632
  status: 401,
552
633
  headers: headers3
@@ -558,12 +639,13 @@ function getRouteHandlers(args) {
558
639
  const headers2 = new Headers();
559
640
  headers2.append("Set-Cookie", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
560
641
  headers2.append("Set-Cookie", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
642
+ headers2.append("Set-Cookie", `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
561
643
  return new Response(null, { status: 401 });
562
644
  });
563
645
  }
564
646
  function logoutGetHandler(req) {
565
647
  return __async(this, null, function* () {
566
- var _a;
648
+ var _a, _b;
567
649
  const path = (args == null ? void 0 : args.postLoginRedirectPathFn) ? args.postLoginRedirectPathFn(req) : "/";
568
650
  if (!path) {
569
651
  console.error("postLoginPathFn returned undefined");
@@ -581,12 +663,17 @@ function getRouteHandlers(args) {
581
663
  "Set-Cookie",
582
664
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
583
665
  );
666
+ headers2.append(
667
+ "Set-Cookie",
668
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
669
+ );
584
670
  return new Response(null, {
585
671
  status: 302,
586
672
  headers: headers2
587
673
  });
588
674
  }
589
- const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(refreshToken);
675
+ const activeOrgId = (_b = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _b.value;
676
+ const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId);
590
677
  if (refreshResponse.error === "unexpected") {
591
678
  console.error("Unexpected error while refreshing access token");
592
679
  return new Response("Unexpected error", { status: 500 });
@@ -601,6 +688,10 @@ function getRouteHandlers(args) {
601
688
  "Set-Cookie",
602
689
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
603
690
  );
691
+ headers2.append(
692
+ "Set-Cookie",
693
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
694
+ );
604
695
  return new Response(null, {
605
696
  status: 302,
606
697
  headers: headers2
@@ -629,6 +720,10 @@ function getRouteHandlers(args) {
629
720
  "Set-Cookie",
630
721
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
631
722
  );
723
+ headers3.append(
724
+ "Set-Cookie",
725
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
726
+ );
632
727
  return new Response(null, { status: 200, headers: headers3 });
633
728
  }
634
729
  const authUrlOrigin = getAuthUrlOrigin();
@@ -653,9 +748,78 @@ function getRouteHandlers(args) {
653
748
  const headers2 = new Headers();
654
749
  headers2.append("Set-Cookie", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
655
750
  headers2.append("Set-Cookie", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
751
+ headers2.append("Set-Cookie", `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
656
752
  return new Response(null, { status: 200, headers: headers2 });
657
753
  });
658
754
  }
755
+ function setActiveOrgHandler(req) {
756
+ return __async(this, null, function* () {
757
+ var _a;
758
+ const oldRefreshToken = (_a = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
759
+ const activeOrgId = req.nextUrl.searchParams.get("active_org_id");
760
+ if (!oldRefreshToken) {
761
+ const headers2 = new Headers();
762
+ headers2.append(
763
+ "Set-Cookie",
764
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
765
+ );
766
+ return new Response(null, { status: 401, headers: headers2 });
767
+ }
768
+ if (!activeOrgId) {
769
+ return new Response(null, { status: 400 });
770
+ }
771
+ const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken, activeOrgId);
772
+ if (refreshResponse.error === "unexpected") {
773
+ throw new Error("Unexpected error while setting active org id");
774
+ } else if (refreshResponse.error === "unauthorized") {
775
+ return new Response("Unauthorized", { status: 401 });
776
+ }
777
+ const refreshToken = refreshResponse.refreshToken;
778
+ const accessToken = refreshResponse.accessToken;
779
+ const authUrlOrigin = getAuthUrlOrigin();
780
+ const path = `${authUrlOrigin}/propelauth/oauth/userinfo`;
781
+ const response = yield fetch(path, {
782
+ headers: {
783
+ "Content-Type": "application/json",
784
+ Authorization: "Bearer " + accessToken
785
+ }
786
+ });
787
+ if (response.ok) {
788
+ const userFromToken = yield validateAccessToken(accessToken);
789
+ const data = yield response.json();
790
+ const jsonResponse = {
791
+ userinfo: data,
792
+ accessToken,
793
+ impersonatorUserId: userFromToken.impersonatorUserId,
794
+ activeOrgId
795
+ };
796
+ const headers2 = new Headers();
797
+ headers2.append(
798
+ "Set-Cookie",
799
+ `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
800
+ );
801
+ headers2.append(
802
+ "Set-Cookie",
803
+ `${REFRESH_TOKEN_COOKIE_NAME}=${refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
804
+ );
805
+ headers2.append(
806
+ "Set-Cookie",
807
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=${activeOrgId}; Path=/; HttpOnly; Secure; SameSite=Lax`
808
+ );
809
+ headers2.append("Content-Type", "application/json");
810
+ return new Response(JSON.stringify(jsonResponse), {
811
+ status: 200,
812
+ headers: headers2
813
+ });
814
+ } else if (response.status === 401) {
815
+ return new Response(null, {
816
+ status: 401
817
+ });
818
+ } else {
819
+ return new Response(null, { status: 500 });
820
+ }
821
+ });
822
+ }
659
823
  function getRouteHandler(req, { params }) {
660
824
  if (params.slug === "login") {
661
825
  return loginGetHandler(req);
@@ -674,6 +838,8 @@ function getRouteHandlers(args) {
674
838
  function postRouteHandler(req, { params }) {
675
839
  if (params.slug === "logout") {
676
840
  return logoutPostHandler(req);
841
+ } else if (params.slug === "set-active-org") {
842
+ return setActiveOrgHandler(req);
677
843
  } else {
678
844
  return new Response("", { status: 404 });
679
845
  }