@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.
@@ -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
  }