@propelauth/nextjs 0.0.111 → 0.0.112-beta.1

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.
@@ -83,8 +83,9 @@ var import_server = require("next/server.js");
83
83
 
84
84
  // src/user.ts
85
85
  var UserFromToken = class {
86
- constructor(userId, email, orgIdToOrgMemberInfo, firstName, lastName, username, legacyUserId, impersonatorUserId, properties) {
86
+ constructor(userId, email, orgIdToOrgMemberInfo, firstName, lastName, username, legacyUserId, impersonatorUserId, properties, activeOrgId) {
87
87
  this.userId = userId;
88
+ this.activeOrgId = activeOrgId;
88
89
  this.orgIdToOrgMemberInfo = orgIdToOrgMemberInfo;
89
90
  this.email = email;
90
91
  this.firstName = firstName;
@@ -94,6 +95,15 @@ var UserFromToken = class {
94
95
  this.impersonatorUserId = impersonatorUserId;
95
96
  this.properties = properties;
96
97
  }
98
+ getActiveOrg() {
99
+ if (!this.activeOrgId || !this.orgIdToOrgMemberInfo) {
100
+ return void 0;
101
+ }
102
+ return this.orgIdToOrgMemberInfo[this.activeOrgId];
103
+ }
104
+ getActiveOrgId() {
105
+ return this.activeOrgId;
106
+ }
97
107
  getOrg(orgId) {
98
108
  if (!this.orgIdToOrgMemberInfo) {
99
109
  return void 0;
@@ -126,9 +136,7 @@ var UserFromToken = class {
126
136
  const obj = JSON.parse(json);
127
137
  const orgIdToOrgMemberInfo = {};
128
138
  for (const orgId in obj.orgIdToOrgMemberInfo) {
129
- orgIdToOrgMemberInfo[orgId] = OrgMemberInfo.fromJSON(
130
- JSON.stringify(obj.orgIdToOrgMemberInfo[orgId])
131
- );
139
+ orgIdToOrgMemberInfo[orgId] = OrgMemberInfo.fromJSON(JSON.stringify(obj.orgIdToOrgMemberInfo[orgId]));
132
140
  }
133
141
  return new UserFromToken(
134
142
  obj.userId,
@@ -142,6 +150,29 @@ var UserFromToken = class {
142
150
  obj.properties
143
151
  );
144
152
  }
153
+ static fromJwtPayload(payload) {
154
+ let activeOrgId;
155
+ let orgIdToOrgMemberInfo;
156
+ if (payload.org_member_info) {
157
+ activeOrgId = payload.org_member_info.org_id;
158
+ orgIdToOrgMemberInfo = toOrgIdToOrgMemberInfo({ [activeOrgId]: payload.org_member_info });
159
+ } else {
160
+ activeOrgId = void 0;
161
+ orgIdToOrgMemberInfo = toOrgIdToOrgMemberInfo(payload.org_id_to_org_member_info);
162
+ }
163
+ return new UserFromToken(
164
+ payload.user_id,
165
+ payload.email,
166
+ orgIdToOrgMemberInfo,
167
+ payload.first_name,
168
+ payload.last_name,
169
+ payload.username,
170
+ payload.legacy_user_id,
171
+ payload.impersonatorUserId,
172
+ payload.properties,
173
+ activeOrgId
174
+ );
175
+ }
145
176
  };
146
177
  var OrgMemberInfo = class {
147
178
  constructor(orgId, orgName, orgMetadata, urlSafeOrgName, userAssignedRole, userInheritedRolesPlusCurrentRole, userPermissions) {
@@ -190,17 +221,7 @@ var OrgMemberInfo = class {
190
221
  }
191
222
  };
192
223
  function toUser(snake_case) {
193
- return new UserFromToken(
194
- snake_case.user_id,
195
- snake_case.email,
196
- toOrgIdToOrgMemberInfo(snake_case.org_id_to_org_member_info),
197
- snake_case.first_name,
198
- snake_case.last_name,
199
- snake_case.username,
200
- snake_case.legacy_user_id,
201
- snake_case.impersonatorUserId,
202
- snake_case.properties
203
- );
224
+ return UserFromToken.fromJwtPayload(snake_case);
204
225
  }
205
226
  function toOrgIdToOrgMemberInfo(snake_case) {
206
227
  if (snake_case === void 0) {
@@ -272,12 +293,17 @@ function getVerifierKey() {
272
293
  }
273
294
  return verifierKey.replace(/\\n/g, "\n");
274
295
  }
275
- function refreshTokenWithAccessAndRefreshToken(refreshToken) {
296
+ function refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId) {
276
297
  return __async(this, null, function* () {
277
298
  const body = {
278
299
  refresh_token: refreshToken
279
300
  };
280
- const url = `${getAuthUrlOrigin()}/api/backend/v1/refresh_token`;
301
+ const queryParams = new URLSearchParams();
302
+ if (activeOrgId) {
303
+ queryParams.set("with_active_org_support", "true");
304
+ queryParams.set("active_org_id", activeOrgId);
305
+ }
306
+ const url = `${getAuthUrlOrigin()}/api/backend/v1/refresh_token?${queryParams.toString()}`;
281
307
  const response = yield fetch(url, {
282
308
  method: "POST",
283
309
  body: JSON.stringify(body),
@@ -289,10 +315,7 @@ function refreshTokenWithAccessAndRefreshToken(refreshToken) {
289
315
  if (response.ok) {
290
316
  const data = yield response.json();
291
317
  const newRefreshToken = data.refresh_token;
292
- const {
293
- access_token: accessToken,
294
- expires_at_seconds: expiresAtSeconds
295
- } = data.access_token;
318
+ const { access_token: accessToken, expires_at_seconds: expiresAtSeconds } = data.access_token;
296
319
  return {
297
320
  refreshToken: newRefreshToken,
298
321
  accessToken,
@@ -353,6 +376,9 @@ function validateAccessToken(accessToken) {
353
376
  });
354
377
  }
355
378
 
379
+ // src/shared.ts
380
+ var ACTIVE_ORG_ID_COOKIE_NAME = "__pa_org_id";
381
+
356
382
  // src/server/app-router.ts
357
383
  function getUserOrRedirect() {
358
384
  return __async(this, null, function* () {
@@ -367,8 +393,7 @@ function getUserOrRedirect() {
367
393
  }
368
394
  function getUser() {
369
395
  return __async(this, null, function* () {
370
- var _a;
371
- const accessToken = (0, import_headers.headers)().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || ((_a = (0, import_headers.cookies)().get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value);
396
+ const accessToken = getAccessToken();
372
397
  if (accessToken) {
373
398
  const user = yield validateAccessTokenOrUndefined(accessToken);
374
399
  if (user) {
@@ -379,14 +404,12 @@ function getUser() {
379
404
  });
380
405
  }
381
406
  function getAccessToken() {
382
- return __async(this, null, function* () {
383
- var _a;
384
- return (0, import_headers.headers)().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || ((_a = (0, import_headers.cookies)().get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value);
385
- });
407
+ var _a;
408
+ return (0, import_headers.headers)().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || ((_a = (0, import_headers.cookies)().get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value);
386
409
  }
387
410
  function authMiddleware(req) {
388
411
  return __async(this, null, function* () {
389
- var _a, _b;
412
+ var _a, _b, _c;
390
413
  if (req.headers.has(CUSTOM_HEADER_FOR_ACCESS_TOKEN)) {
391
414
  throw new Error(`${CUSTOM_HEADER_FOR_ACCESS_TOKEN} is set which is for internal use only`);
392
415
  } else if (req.nextUrl.pathname === CALLBACK_PATH || req.nextUrl.pathname === LOGOUT_PATH || req.nextUrl.pathname === USERINFO_PATH) {
@@ -394,6 +417,7 @@ function authMiddleware(req) {
394
417
  }
395
418
  const accessToken = (_a = req.cookies.get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
396
419
  const refreshToken = (_b = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _b.value;
420
+ const activeOrgId = (_c = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _c.value;
397
421
  if (accessToken) {
398
422
  const user = yield validateAccessTokenOrUndefined(accessToken);
399
423
  if (user) {
@@ -401,7 +425,7 @@ function authMiddleware(req) {
401
425
  }
402
426
  }
403
427
  if (refreshToken) {
404
- const response = yield refreshTokenWithAccessAndRefreshToken(refreshToken);
428
+ const response = yield refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId);
405
429
  if (response.error === "unexpected") {
406
430
  throw new Error("Unexpected error while refreshing access token");
407
431
  } else if (response.error === "unauthorized") {
@@ -462,7 +486,7 @@ function getRouteHandlers(args) {
462
486
  }
463
487
  function callbackGetHandler(req) {
464
488
  return __async(this, null, function* () {
465
- var _a, _b;
489
+ var _a, _b, _c;
466
490
  const oauthState = (_a = req.cookies.get(STATE_COOKIE_NAME)) == null ? void 0 : _a.value;
467
491
  if (!oauthState || oauthState.length !== 64) {
468
492
  return new Response(null, { status: 302, headers: { Location: LOGIN_PATH } });
@@ -498,6 +522,49 @@ function getRouteHandlers(args) {
498
522
  console.error("postLoginRedirectPathFn returned undefined");
499
523
  return new Response("Unexpected error", { status: 500 });
500
524
  }
525
+ const currentActiveOrgId = (_c = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _c.value;
526
+ const user = yield validateAccessToken(accessToken);
527
+ const isUserInCurrentActiveOrg = !!currentActiveOrgId && !!user.getOrg(currentActiveOrgId);
528
+ let activeOrgId = void 0;
529
+ if (isUserInCurrentActiveOrg) {
530
+ activeOrgId = currentActiveOrgId;
531
+ } else if (args == null ? void 0 : args.getDefaultActiveOrgId) {
532
+ activeOrgId = args.getDefaultActiveOrgId(req, user);
533
+ }
534
+ if (activeOrgId) {
535
+ const response2 = yield refreshTokenWithAccessAndRefreshToken(data.refresh_token, activeOrgId);
536
+ if (response2.error === "unexpected") {
537
+ throw new Error("Unexpected error while setting active org");
538
+ } else if (response2.error === "unauthorized") {
539
+ console.error(
540
+ "Unauthorized error while setting active org. Your user may not have access to this org"
541
+ );
542
+ return new Response("Unauthorized", { status: 401 });
543
+ } else {
544
+ const headers3 = new Headers();
545
+ headers3.append("Location", returnToPath);
546
+ headers3.append(
547
+ "Set-Cookie",
548
+ `${ACCESS_TOKEN_COOKIE_NAME}=${response2.accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
549
+ );
550
+ headers3.append(
551
+ "Set-Cookie",
552
+ `${REFRESH_TOKEN_COOKIE_NAME}=${response2.refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
553
+ );
554
+ headers3.append(
555
+ "Set-Cookie",
556
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=${activeOrgId}; Path=/; HttpOnly; Secure; SameSite=Lax`
557
+ );
558
+ headers3.append(
559
+ "Set-Cookie",
560
+ `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
561
+ );
562
+ return new Response(null, {
563
+ status: 302,
564
+ headers: headers3
565
+ });
566
+ }
567
+ }
501
568
  const headers2 = new Headers();
502
569
  headers2.append("Location", returnToPath);
503
570
  headers2.append(
@@ -508,6 +575,10 @@ function getRouteHandlers(args) {
508
575
  "Set-Cookie",
509
576
  `${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`
510
577
  );
578
+ headers2.append(
579
+ "Set-Cookie",
580
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
581
+ );
511
582
  headers2.append(
512
583
  "Set-Cookie",
513
584
  `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
@@ -528,10 +599,11 @@ function getRouteHandlers(args) {
528
599
  }
529
600
  function userinfoGetHandler(req) {
530
601
  return __async(this, null, function* () {
531
- var _a;
602
+ var _a, _b;
532
603
  const oldRefreshToken = (_a = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
604
+ const activeOrgId = (_b = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _b.value;
533
605
  if (oldRefreshToken) {
534
- const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken);
606
+ const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken, activeOrgId);
535
607
  if (refreshResponse.error === "unexpected") {
536
608
  throw new Error("Unexpected error while refreshing access token");
537
609
  } else if (refreshResponse.error === "unauthorized") {
@@ -544,6 +616,10 @@ function getRouteHandlers(args) {
544
616
  "Set-Cookie",
545
617
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
546
618
  );
619
+ headers3.append(
620
+ "Set-Cookie",
621
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
622
+ );
547
623
  return new Response("Unauthorized", { status: 401, headers: headers3 });
548
624
  }
549
625
  const refreshToken = refreshResponse.refreshToken;
@@ -562,7 +638,8 @@ function getRouteHandlers(args) {
562
638
  const jsonResponse = {
563
639
  userinfo: data,
564
640
  accessToken,
565
- impersonatorUserId: userFromToken.impersonatorUserId
641
+ impersonatorUserId: userFromToken.impersonatorUserId,
642
+ activeOrgId
566
643
  };
567
644
  const headers3 = new Headers();
568
645
  headers3.append(
@@ -588,6 +665,10 @@ function getRouteHandlers(args) {
588
665
  "Set-Cookie",
589
666
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
590
667
  );
668
+ headers3.append(
669
+ "Set-Cookie",
670
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
671
+ );
591
672
  return new Response(null, {
592
673
  status: 401,
593
674
  headers: headers3
@@ -599,12 +680,13 @@ function getRouteHandlers(args) {
599
680
  const headers2 = new Headers();
600
681
  headers2.append("Set-Cookie", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
601
682
  headers2.append("Set-Cookie", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
683
+ headers2.append("Set-Cookie", `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
602
684
  return new Response(null, { status: 401 });
603
685
  });
604
686
  }
605
687
  function logoutGetHandler(req) {
606
688
  return __async(this, null, function* () {
607
- var _a;
689
+ var _a, _b;
608
690
  const path = (args == null ? void 0 : args.postLoginRedirectPathFn) ? args.postLoginRedirectPathFn(req) : "/";
609
691
  if (!path) {
610
692
  console.error("postLoginPathFn returned undefined");
@@ -622,12 +704,17 @@ function getRouteHandlers(args) {
622
704
  "Set-Cookie",
623
705
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
624
706
  );
707
+ headers2.append(
708
+ "Set-Cookie",
709
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
710
+ );
625
711
  return new Response(null, {
626
712
  status: 302,
627
713
  headers: headers2
628
714
  });
629
715
  }
630
- const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(refreshToken);
716
+ const activeOrgId = (_b = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _b.value;
717
+ const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId);
631
718
  if (refreshResponse.error === "unexpected") {
632
719
  console.error("Unexpected error while refreshing access token");
633
720
  return new Response("Unexpected error", { status: 500 });
@@ -642,6 +729,10 @@ function getRouteHandlers(args) {
642
729
  "Set-Cookie",
643
730
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
644
731
  );
732
+ headers2.append(
733
+ "Set-Cookie",
734
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
735
+ );
645
736
  return new Response(null, {
646
737
  status: 302,
647
738
  headers: headers2
@@ -670,6 +761,10 @@ function getRouteHandlers(args) {
670
761
  "Set-Cookie",
671
762
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
672
763
  );
764
+ headers3.append(
765
+ "Set-Cookie",
766
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
767
+ );
673
768
  return new Response(null, { status: 200, headers: headers3 });
674
769
  }
675
770
  const authUrlOrigin = getAuthUrlOrigin();
@@ -694,9 +789,78 @@ function getRouteHandlers(args) {
694
789
  const headers2 = new Headers();
695
790
  headers2.append("Set-Cookie", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
696
791
  headers2.append("Set-Cookie", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
792
+ headers2.append("Set-Cookie", `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
697
793
  return new Response(null, { status: 200, headers: headers2 });
698
794
  });
699
795
  }
796
+ function setActiveOrgHandler(req) {
797
+ return __async(this, null, function* () {
798
+ var _a;
799
+ const oldRefreshToken = (_a = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
800
+ const activeOrgId = req.nextUrl.searchParams.get("active_org_id");
801
+ if (!oldRefreshToken) {
802
+ const headers2 = new Headers();
803
+ headers2.append(
804
+ "Set-Cookie",
805
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
806
+ );
807
+ return new Response(null, { status: 401, headers: headers2 });
808
+ }
809
+ if (!activeOrgId) {
810
+ return new Response(null, { status: 400 });
811
+ }
812
+ const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken, activeOrgId);
813
+ if (refreshResponse.error === "unexpected") {
814
+ throw new Error("Unexpected error while setting active org id");
815
+ } else if (refreshResponse.error === "unauthorized") {
816
+ return new Response("Unauthorized", { status: 401 });
817
+ }
818
+ const refreshToken = refreshResponse.refreshToken;
819
+ const accessToken = refreshResponse.accessToken;
820
+ const authUrlOrigin = getAuthUrlOrigin();
821
+ const path = `${authUrlOrigin}/propelauth/oauth/userinfo`;
822
+ const response = yield fetch(path, {
823
+ headers: {
824
+ "Content-Type": "application/json",
825
+ Authorization: "Bearer " + accessToken
826
+ }
827
+ });
828
+ if (response.ok) {
829
+ const userFromToken = yield validateAccessToken(accessToken);
830
+ const data = yield response.json();
831
+ const jsonResponse = {
832
+ userinfo: data,
833
+ accessToken,
834
+ impersonatorUserId: userFromToken.impersonatorUserId,
835
+ activeOrgId
836
+ };
837
+ const headers2 = new Headers();
838
+ headers2.append(
839
+ "Set-Cookie",
840
+ `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
841
+ );
842
+ headers2.append(
843
+ "Set-Cookie",
844
+ `${REFRESH_TOKEN_COOKIE_NAME}=${refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
845
+ );
846
+ headers2.append(
847
+ "Set-Cookie",
848
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=${activeOrgId}; Path=/; HttpOnly; Secure; SameSite=Lax`
849
+ );
850
+ headers2.append("Content-Type", "application/json");
851
+ return new Response(JSON.stringify(jsonResponse), {
852
+ status: 200,
853
+ headers: headers2
854
+ });
855
+ } else if (response.status === 401) {
856
+ return new Response(null, {
857
+ status: 401
858
+ });
859
+ } else {
860
+ return new Response(null, { status: 500 });
861
+ }
862
+ });
863
+ }
700
864
  function getRouteHandler(req, { params }) {
701
865
  if (params.slug === "login") {
702
866
  return loginGetHandler(req);
@@ -715,6 +879,8 @@ function getRouteHandlers(args) {
715
879
  function postRouteHandler(req, { params }) {
716
880
  if (params.slug === "logout") {
717
881
  return logoutPostHandler(req);
882
+ } else if (params.slug === "set-active-org") {
883
+ return setActiveOrgHandler(req);
718
884
  } else {
719
885
  return new Response("", { status: 404 });
720
886
  }