@propelauth/nextjs 0.0.118 → 0.0.119

Sign up to get free protection for your applications and to get access to all the features.
@@ -67,8 +67,9 @@ function toLoginMethod(snake_case) {
67
67
 
68
68
  // src/user.ts
69
69
  var UserFromToken = class {
70
- constructor(userId, email, orgIdToOrgMemberInfo, firstName, lastName, username, legacyUserId, impersonatorUserId, properties, loginMethod) {
70
+ constructor(userId, email, orgIdToOrgMemberInfo, firstName, lastName, username, legacyUserId, impersonatorUserId, properties, activeOrgId, loginMethod) {
71
71
  this.userId = userId;
72
+ this.activeOrgId = activeOrgId;
72
73
  this.orgIdToOrgMemberInfo = orgIdToOrgMemberInfo;
73
74
  this.email = email;
74
75
  this.firstName = firstName;
@@ -79,6 +80,15 @@ var UserFromToken = class {
79
80
  this.properties = properties;
80
81
  this.loginMethod = loginMethod;
81
82
  }
83
+ getActiveOrg() {
84
+ if (!this.activeOrgId || !this.orgIdToOrgMemberInfo) {
85
+ return void 0;
86
+ }
87
+ return this.orgIdToOrgMemberInfo[this.activeOrgId];
88
+ }
89
+ getActiveOrgId() {
90
+ return this.activeOrgId;
91
+ }
82
92
  getOrg(orgId) {
83
93
  if (!this.orgIdToOrgMemberInfo) {
84
94
  return void 0;
@@ -123,9 +133,35 @@ var UserFromToken = class {
123
133
  obj.legacyUserId,
124
134
  obj.impersonatorUserId,
125
135
  obj.properties,
136
+ obj.activeOrgId,
126
137
  obj.loginMethod
127
138
  );
128
139
  }
140
+ static fromJwtPayload(payload) {
141
+ let activeOrgId;
142
+ let orgIdToOrgMemberInfo;
143
+ if (payload.org_member_info) {
144
+ activeOrgId = payload.org_member_info.org_id;
145
+ orgIdToOrgMemberInfo = toOrgIdToOrgMemberInfo({ [activeOrgId]: payload.org_member_info });
146
+ } else {
147
+ activeOrgId = void 0;
148
+ orgIdToOrgMemberInfo = toOrgIdToOrgMemberInfo(payload.org_id_to_org_member_info);
149
+ }
150
+ const loginMethod = toLoginMethod(payload.login_method);
151
+ return new UserFromToken(
152
+ payload.user_id,
153
+ payload.email,
154
+ orgIdToOrgMemberInfo,
155
+ payload.first_name,
156
+ payload.last_name,
157
+ payload.username,
158
+ payload.legacy_user_id,
159
+ payload.impersonatorUserId,
160
+ payload.properties,
161
+ activeOrgId,
162
+ loginMethod
163
+ );
164
+ }
129
165
  };
130
166
  var OrgMemberInfo = class {
131
167
  constructor(orgId, orgName, orgMetadata, urlSafeOrgName, userAssignedRole, userInheritedRolesPlusCurrentRole, userPermissions) {
@@ -174,18 +210,7 @@ var OrgMemberInfo = class {
174
210
  }
175
211
  };
176
212
  function toUser(snake_case) {
177
- return new UserFromToken(
178
- snake_case.user_id,
179
- snake_case.email,
180
- toOrgIdToOrgMemberInfo(snake_case.org_id_to_org_member_info),
181
- snake_case.first_name,
182
- snake_case.last_name,
183
- snake_case.username,
184
- snake_case.legacy_user_id,
185
- snake_case.impersonatorUserId,
186
- snake_case.properties,
187
- toLoginMethod(snake_case.login_method)
188
- );
213
+ return UserFromToken.fromJwtPayload(snake_case);
189
214
  }
190
215
  function toOrgIdToOrgMemberInfo(snake_case) {
191
216
  if (snake_case === void 0) {
@@ -257,12 +282,17 @@ function getVerifierKey() {
257
282
  }
258
283
  return verifierKey.replace(/\\n/g, "\n");
259
284
  }
260
- function refreshTokenWithAccessAndRefreshToken(refreshToken) {
285
+ function refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId) {
261
286
  return __async(this, null, function* () {
262
287
  const body = {
263
288
  refresh_token: refreshToken
264
289
  };
265
- const url = `${getAuthUrlOrigin()}/api/backend/v1/refresh_token`;
290
+ const queryParams = new URLSearchParams();
291
+ if (activeOrgId) {
292
+ queryParams.set("with_active_org_support", "true");
293
+ queryParams.set("active_org_id", activeOrgId);
294
+ }
295
+ const url = `${getAuthUrlOrigin()}/api/backend/v1/refresh_token?${queryParams.toString()}`;
266
296
  const response = yield fetch(url, {
267
297
  method: "POST",
268
298
  body: JSON.stringify(body),
@@ -274,10 +304,7 @@ function refreshTokenWithAccessAndRefreshToken(refreshToken) {
274
304
  if (response.ok) {
275
305
  const data = yield response.json();
276
306
  const newRefreshToken = data.refresh_token;
277
- const {
278
- access_token: accessToken,
279
- expires_at_seconds: expiresAtSeconds
280
- } = data.access_token;
307
+ const { access_token: accessToken, expires_at_seconds: expiresAtSeconds } = data.access_token;
281
308
  return {
282
309
  refreshToken: newRefreshToken,
283
310
  accessToken,
@@ -338,6 +365,9 @@ function validateAccessToken(accessToken) {
338
365
  });
339
366
  }
340
367
 
368
+ // src/shared.ts
369
+ var ACTIVE_ORG_ID_COOKIE_NAME = "__pa_org_id";
370
+
341
371
  // src/server/app-router.ts
342
372
  function getUserOrRedirect() {
343
373
  return __async(this, null, function* () {
@@ -352,8 +382,7 @@ function getUserOrRedirect() {
352
382
  }
353
383
  function getUser() {
354
384
  return __async(this, null, function* () {
355
- var _a;
356
- const accessToken = headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || ((_a = cookies().get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value);
385
+ const accessToken = getAccessToken();
357
386
  if (accessToken) {
358
387
  const user = yield validateAccessTokenOrUndefined(accessToken);
359
388
  if (user) {
@@ -364,14 +393,12 @@ function getUser() {
364
393
  });
365
394
  }
366
395
  function getAccessToken() {
367
- return __async(this, null, function* () {
368
- var _a;
369
- return headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || ((_a = cookies().get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value);
370
- });
396
+ var _a;
397
+ return headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || ((_a = cookies().get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value);
371
398
  }
372
399
  function authMiddleware(req) {
373
400
  return __async(this, null, function* () {
374
- var _a, _b;
401
+ var _a, _b, _c;
375
402
  if (req.headers.has(CUSTOM_HEADER_FOR_ACCESS_TOKEN)) {
376
403
  throw new Error(`${CUSTOM_HEADER_FOR_ACCESS_TOKEN} is set which is for internal use only`);
377
404
  } else if (req.nextUrl.pathname === CALLBACK_PATH || req.nextUrl.pathname === LOGOUT_PATH || req.nextUrl.pathname === USERINFO_PATH) {
@@ -379,6 +406,7 @@ function authMiddleware(req) {
379
406
  }
380
407
  const accessToken = (_a = req.cookies.get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
381
408
  const refreshToken = (_b = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _b.value;
409
+ const activeOrgId = (_c = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _c.value;
382
410
  if (accessToken) {
383
411
  const user = yield validateAccessTokenOrUndefined(accessToken);
384
412
  if (user) {
@@ -386,7 +414,7 @@ function authMiddleware(req) {
386
414
  }
387
415
  }
388
416
  if (refreshToken) {
389
- const response = yield refreshTokenWithAccessAndRefreshToken(refreshToken);
417
+ const response = yield refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId);
390
418
  if (response.error === "unexpected") {
391
419
  throw new Error("Unexpected error while refreshing access token");
392
420
  } else if (response.error === "unauthorized") {
@@ -447,7 +475,7 @@ function getRouteHandlers(args) {
447
475
  }
448
476
  function callbackGetHandler(req) {
449
477
  return __async(this, null, function* () {
450
- var _a, _b;
478
+ var _a, _b, _c;
451
479
  const oauthState = (_a = req.cookies.get(STATE_COOKIE_NAME)) == null ? void 0 : _a.value;
452
480
  if (!oauthState || oauthState.length !== 64) {
453
481
  return new Response(null, { status: 302, headers: { Location: LOGIN_PATH } });
@@ -483,6 +511,49 @@ function getRouteHandlers(args) {
483
511
  console.error("postLoginRedirectPathFn returned undefined");
484
512
  return new Response("Unexpected error", { status: 500 });
485
513
  }
514
+ const currentActiveOrgId = (_c = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _c.value;
515
+ const user = yield validateAccessToken(accessToken);
516
+ const isUserInCurrentActiveOrg = !!currentActiveOrgId && !!user.getOrg(currentActiveOrgId);
517
+ let activeOrgId = void 0;
518
+ if (isUserInCurrentActiveOrg) {
519
+ activeOrgId = currentActiveOrgId;
520
+ } else if (args == null ? void 0 : args.getDefaultActiveOrgId) {
521
+ activeOrgId = args.getDefaultActiveOrgId(req, user);
522
+ }
523
+ if (activeOrgId) {
524
+ const response2 = yield refreshTokenWithAccessAndRefreshToken(data.refresh_token, activeOrgId);
525
+ if (response2.error === "unexpected") {
526
+ throw new Error("Unexpected error while setting active org");
527
+ } else if (response2.error === "unauthorized") {
528
+ console.error(
529
+ "Unauthorized error while setting active org. Your user may not have access to this org"
530
+ );
531
+ return new Response("Unauthorized", { status: 401 });
532
+ } else {
533
+ const headers3 = new Headers();
534
+ headers3.append("Location", returnToPath);
535
+ headers3.append(
536
+ "Set-Cookie",
537
+ `${ACCESS_TOKEN_COOKIE_NAME}=${response2.accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
538
+ );
539
+ headers3.append(
540
+ "Set-Cookie",
541
+ `${REFRESH_TOKEN_COOKIE_NAME}=${response2.refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
542
+ );
543
+ headers3.append(
544
+ "Set-Cookie",
545
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=${activeOrgId}; Path=/; HttpOnly; Secure; SameSite=Lax`
546
+ );
547
+ headers3.append(
548
+ "Set-Cookie",
549
+ `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
550
+ );
551
+ return new Response(null, {
552
+ status: 302,
553
+ headers: headers3
554
+ });
555
+ }
556
+ }
486
557
  const headers2 = new Headers();
487
558
  headers2.append("Location", returnToPath);
488
559
  headers2.append(
@@ -493,6 +564,10 @@ function getRouteHandlers(args) {
493
564
  "Set-Cookie",
494
565
  `${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`
495
566
  );
567
+ headers2.append(
568
+ "Set-Cookie",
569
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
570
+ );
496
571
  headers2.append(
497
572
  "Set-Cookie",
498
573
  `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
@@ -513,10 +588,11 @@ function getRouteHandlers(args) {
513
588
  }
514
589
  function userinfoGetHandler(req) {
515
590
  return __async(this, null, function* () {
516
- var _a;
591
+ var _a, _b;
517
592
  const oldRefreshToken = (_a = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
593
+ const activeOrgId = (_b = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _b.value;
518
594
  if (oldRefreshToken) {
519
- const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken);
595
+ const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken, activeOrgId);
520
596
  if (refreshResponse.error === "unexpected") {
521
597
  throw new Error("Unexpected error while refreshing access token");
522
598
  } else if (refreshResponse.error === "unauthorized") {
@@ -529,6 +605,10 @@ function getRouteHandlers(args) {
529
605
  "Set-Cookie",
530
606
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
531
607
  );
608
+ headers3.append(
609
+ "Set-Cookie",
610
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
611
+ );
532
612
  return new Response("Unauthorized", { status: 401, headers: headers3 });
533
613
  }
534
614
  const refreshToken = refreshResponse.refreshToken;
@@ -547,7 +627,8 @@ function getRouteHandlers(args) {
547
627
  const jsonResponse = {
548
628
  userinfo: data,
549
629
  accessToken,
550
- impersonatorUserId: userFromToken.impersonatorUserId
630
+ impersonatorUserId: userFromToken.impersonatorUserId,
631
+ activeOrgId
551
632
  };
552
633
  const headers3 = new Headers();
553
634
  headers3.append(
@@ -573,6 +654,10 @@ function getRouteHandlers(args) {
573
654
  "Set-Cookie",
574
655
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
575
656
  );
657
+ headers3.append(
658
+ "Set-Cookie",
659
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
660
+ );
576
661
  return new Response(null, {
577
662
  status: 401,
578
663
  headers: headers3
@@ -584,12 +669,13 @@ function getRouteHandlers(args) {
584
669
  const headers2 = new Headers();
585
670
  headers2.append("Set-Cookie", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
586
671
  headers2.append("Set-Cookie", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
672
+ headers2.append("Set-Cookie", `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
587
673
  return new Response(null, { status: 401 });
588
674
  });
589
675
  }
590
676
  function logoutGetHandler(req) {
591
677
  return __async(this, null, function* () {
592
- var _a;
678
+ var _a, _b;
593
679
  const path = (args == null ? void 0 : args.postLoginRedirectPathFn) ? args.postLoginRedirectPathFn(req) : "/";
594
680
  if (!path) {
595
681
  console.error("postLoginPathFn returned undefined");
@@ -607,12 +693,17 @@ function getRouteHandlers(args) {
607
693
  "Set-Cookie",
608
694
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
609
695
  );
696
+ headers2.append(
697
+ "Set-Cookie",
698
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
699
+ );
610
700
  return new Response(null, {
611
701
  status: 302,
612
702
  headers: headers2
613
703
  });
614
704
  }
615
- const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(refreshToken);
705
+ const activeOrgId = (_b = req.cookies.get(ACTIVE_ORG_ID_COOKIE_NAME)) == null ? void 0 : _b.value;
706
+ const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId);
616
707
  if (refreshResponse.error === "unexpected") {
617
708
  console.error("Unexpected error while refreshing access token");
618
709
  return new Response("Unexpected error", { status: 500 });
@@ -627,6 +718,10 @@ function getRouteHandlers(args) {
627
718
  "Set-Cookie",
628
719
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
629
720
  );
721
+ headers2.append(
722
+ "Set-Cookie",
723
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
724
+ );
630
725
  return new Response(null, {
631
726
  status: 302,
632
727
  headers: headers2
@@ -655,6 +750,10 @@ function getRouteHandlers(args) {
655
750
  "Set-Cookie",
656
751
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
657
752
  );
753
+ headers3.append(
754
+ "Set-Cookie",
755
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
756
+ );
658
757
  return new Response(null, { status: 200, headers: headers3 });
659
758
  }
660
759
  const authUrlOrigin = getAuthUrlOrigin();
@@ -679,9 +778,78 @@ function getRouteHandlers(args) {
679
778
  const headers2 = new Headers();
680
779
  headers2.append("Set-Cookie", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
681
780
  headers2.append("Set-Cookie", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
781
+ headers2.append("Set-Cookie", `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
682
782
  return new Response(null, { status: 200, headers: headers2 });
683
783
  });
684
784
  }
785
+ function setActiveOrgHandler(req) {
786
+ return __async(this, null, function* () {
787
+ var _a;
788
+ const oldRefreshToken = (_a = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
789
+ const activeOrgId = req.nextUrl.searchParams.get("active_org_id");
790
+ if (!oldRefreshToken) {
791
+ const headers2 = new Headers();
792
+ headers2.append(
793
+ "Set-Cookie",
794
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
795
+ );
796
+ return new Response(null, { status: 401, headers: headers2 });
797
+ }
798
+ if (!activeOrgId) {
799
+ return new Response(null, { status: 400 });
800
+ }
801
+ const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken, activeOrgId);
802
+ if (refreshResponse.error === "unexpected") {
803
+ throw new Error("Unexpected error while setting active org id");
804
+ } else if (refreshResponse.error === "unauthorized") {
805
+ return new Response("Unauthorized", { status: 401 });
806
+ }
807
+ const refreshToken = refreshResponse.refreshToken;
808
+ const accessToken = refreshResponse.accessToken;
809
+ const authUrlOrigin = getAuthUrlOrigin();
810
+ const path = `${authUrlOrigin}/propelauth/oauth/userinfo`;
811
+ const response = yield fetch(path, {
812
+ headers: {
813
+ "Content-Type": "application/json",
814
+ Authorization: "Bearer " + accessToken
815
+ }
816
+ });
817
+ if (response.ok) {
818
+ const userFromToken = yield validateAccessToken(accessToken);
819
+ const data = yield response.json();
820
+ const jsonResponse = {
821
+ userinfo: data,
822
+ accessToken,
823
+ impersonatorUserId: userFromToken.impersonatorUserId,
824
+ activeOrgId
825
+ };
826
+ const headers2 = new Headers();
827
+ headers2.append(
828
+ "Set-Cookie",
829
+ `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
830
+ );
831
+ headers2.append(
832
+ "Set-Cookie",
833
+ `${REFRESH_TOKEN_COOKIE_NAME}=${refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
834
+ );
835
+ headers2.append(
836
+ "Set-Cookie",
837
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=${activeOrgId}; Path=/; HttpOnly; Secure; SameSite=Lax`
838
+ );
839
+ headers2.append("Content-Type", "application/json");
840
+ return new Response(JSON.stringify(jsonResponse), {
841
+ status: 200,
842
+ headers: headers2
843
+ });
844
+ } else if (response.status === 401) {
845
+ return new Response(null, {
846
+ status: 401
847
+ });
848
+ } else {
849
+ return new Response(null, { status: 500 });
850
+ }
851
+ });
852
+ }
685
853
  function getRouteHandler(req, { params }) {
686
854
  if (params.slug === "login") {
687
855
  return loginGetHandler(req);
@@ -700,6 +868,8 @@ function getRouteHandlers(args) {
700
868
  function postRouteHandler(req, { params }) {
701
869
  if (params.slug === "logout") {
702
870
  return logoutPostHandler(req);
871
+ } else if (params.slug === "set-active-org") {
872
+ return setActiveOrgHandler(req);
703
873
  } else {
704
874
  return new Response("", { status: 404 });
705
875
  }