@propelauth/nextjs 0.0.111 → 0.0.112-beta.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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(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
  }