@propelauth/nextjs 0.0.115 → 0.0.119

Sign up to get free protection for your applications and to get access to all the features.
@@ -40,10 +40,36 @@ import { redirect } from "next/navigation.js";
40
40
  import { cookies, headers } from "next/headers.js";
41
41
  import { NextResponse } from "next/server.js";
42
42
 
43
+ // src/loginMethod.ts
44
+ function toLoginMethod(snake_case) {
45
+ if (!snake_case) {
46
+ return { loginMethod: "unknown" };
47
+ }
48
+ switch (snake_case.login_method) {
49
+ case "password":
50
+ return { loginMethod: "password" };
51
+ case "magic_link":
52
+ return { loginMethod: "magic_link" };
53
+ case "social_sso":
54
+ return { loginMethod: "social_sso", provider: snake_case.provider };
55
+ case "email_confirmation_link":
56
+ return { loginMethod: "email_confirmation_link" };
57
+ case "saml_sso":
58
+ return { loginMethod: "saml_sso", provider: snake_case.provider, orgId: snake_case.org_id };
59
+ case "impersonation":
60
+ return { loginMethod: "impersonation" };
61
+ case "generated_from_backend_api":
62
+ return { loginMethod: "generated_from_backend_api" };
63
+ default:
64
+ return { loginMethod: "unknown" };
65
+ }
66
+ }
67
+
43
68
  // src/user.ts
44
69
  var UserFromToken = class {
45
- constructor(userId, email, orgIdToOrgMemberInfo, firstName, lastName, username, legacyUserId, impersonatorUserId, properties) {
70
+ constructor(userId, email, orgIdToOrgMemberInfo, firstName, lastName, username, legacyUserId, impersonatorUserId, properties, activeOrgId, loginMethod) {
46
71
  this.userId = userId;
72
+ this.activeOrgId = activeOrgId;
47
73
  this.orgIdToOrgMemberInfo = orgIdToOrgMemberInfo;
48
74
  this.email = email;
49
75
  this.firstName = firstName;
@@ -52,6 +78,16 @@ var UserFromToken = class {
52
78
  this.legacyUserId = legacyUserId;
53
79
  this.impersonatorUserId = impersonatorUserId;
54
80
  this.properties = properties;
81
+ this.loginMethod = loginMethod;
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;
55
91
  }
56
92
  getOrg(orgId) {
57
93
  if (!this.orgIdToOrgMemberInfo) {
@@ -85,9 +121,7 @@ var UserFromToken = class {
85
121
  const obj = JSON.parse(json);
86
122
  const orgIdToOrgMemberInfo = {};
87
123
  for (const orgId in obj.orgIdToOrgMemberInfo) {
88
- orgIdToOrgMemberInfo[orgId] = OrgMemberInfo.fromJSON(
89
- JSON.stringify(obj.orgIdToOrgMemberInfo[orgId])
90
- );
124
+ orgIdToOrgMemberInfo[orgId] = OrgMemberInfo.fromJSON(JSON.stringify(obj.orgIdToOrgMemberInfo[orgId]));
91
125
  }
92
126
  return new UserFromToken(
93
127
  obj.userId,
@@ -98,7 +132,34 @@ var UserFromToken = class {
98
132
  obj.username,
99
133
  obj.legacyUserId,
100
134
  obj.impersonatorUserId,
101
- obj.properties
135
+ obj.properties,
136
+ obj.activeOrgId,
137
+ obj.loginMethod
138
+ );
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
102
163
  );
103
164
  }
104
165
  };
@@ -149,17 +210,7 @@ var OrgMemberInfo = class {
149
210
  }
150
211
  };
151
212
  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
- );
213
+ return UserFromToken.fromJwtPayload(snake_case);
163
214
  }
164
215
  function toOrgIdToOrgMemberInfo(snake_case) {
165
216
  if (snake_case === void 0) {
@@ -231,12 +282,17 @@ function getVerifierKey() {
231
282
  }
232
283
  return verifierKey.replace(/\\n/g, "\n");
233
284
  }
234
- function refreshTokenWithAccessAndRefreshToken(refreshToken) {
285
+ function refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId) {
235
286
  return __async(this, null, function* () {
236
287
  const body = {
237
288
  refresh_token: refreshToken
238
289
  };
239
- 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()}`;
240
296
  const response = yield fetch(url, {
241
297
  method: "POST",
242
298
  body: JSON.stringify(body),
@@ -248,10 +304,7 @@ function refreshTokenWithAccessAndRefreshToken(refreshToken) {
248
304
  if (response.ok) {
249
305
  const data = yield response.json();
250
306
  const newRefreshToken = data.refresh_token;
251
- const {
252
- access_token: accessToken,
253
- expires_at_seconds: expiresAtSeconds
254
- } = data.access_token;
307
+ const { access_token: accessToken, expires_at_seconds: expiresAtSeconds } = data.access_token;
255
308
  return {
256
309
  refreshToken: newRefreshToken,
257
310
  accessToken,
@@ -312,6 +365,9 @@ function validateAccessToken(accessToken) {
312
365
  });
313
366
  }
314
367
 
368
+ // src/shared.ts
369
+ var ACTIVE_ORG_ID_COOKIE_NAME = "__pa_org_id";
370
+
315
371
  // src/server/app-router.ts
316
372
  function getUserOrRedirect() {
317
373
  return __async(this, null, function* () {
@@ -326,8 +382,7 @@ function getUserOrRedirect() {
326
382
  }
327
383
  function getUser() {
328
384
  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);
385
+ const accessToken = getAccessToken();
331
386
  if (accessToken) {
332
387
  const user = yield validateAccessTokenOrUndefined(accessToken);
333
388
  if (user) {
@@ -338,14 +393,12 @@ function getUser() {
338
393
  });
339
394
  }
340
395
  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
- });
396
+ var _a;
397
+ return headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || ((_a = cookies().get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value);
345
398
  }
346
399
  function authMiddleware(req) {
347
400
  return __async(this, null, function* () {
348
- var _a, _b;
401
+ var _a, _b, _c;
349
402
  if (req.headers.has(CUSTOM_HEADER_FOR_ACCESS_TOKEN)) {
350
403
  throw new Error(`${CUSTOM_HEADER_FOR_ACCESS_TOKEN} is set which is for internal use only`);
351
404
  } else if (req.nextUrl.pathname === CALLBACK_PATH || req.nextUrl.pathname === LOGOUT_PATH || req.nextUrl.pathname === USERINFO_PATH) {
@@ -353,6 +406,7 @@ function authMiddleware(req) {
353
406
  }
354
407
  const accessToken = (_a = req.cookies.get(ACCESS_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
355
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;
356
410
  if (accessToken) {
357
411
  const user = yield validateAccessTokenOrUndefined(accessToken);
358
412
  if (user) {
@@ -360,7 +414,7 @@ function authMiddleware(req) {
360
414
  }
361
415
  }
362
416
  if (refreshToken) {
363
- const response = yield refreshTokenWithAccessAndRefreshToken(refreshToken);
417
+ const response = yield refreshTokenWithAccessAndRefreshToken(refreshToken, activeOrgId);
364
418
  if (response.error === "unexpected") {
365
419
  throw new Error("Unexpected error while refreshing access token");
366
420
  } else if (response.error === "unauthorized") {
@@ -421,7 +475,7 @@ function getRouteHandlers(args) {
421
475
  }
422
476
  function callbackGetHandler(req) {
423
477
  return __async(this, null, function* () {
424
- var _a, _b;
478
+ var _a, _b, _c;
425
479
  const oauthState = (_a = req.cookies.get(STATE_COOKIE_NAME)) == null ? void 0 : _a.value;
426
480
  if (!oauthState || oauthState.length !== 64) {
427
481
  return new Response(null, { status: 302, headers: { Location: LOGIN_PATH } });
@@ -457,6 +511,49 @@ function getRouteHandlers(args) {
457
511
  console.error("postLoginRedirectPathFn returned undefined");
458
512
  return new Response("Unexpected error", { status: 500 });
459
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
+ }
460
557
  const headers2 = new Headers();
461
558
  headers2.append("Location", returnToPath);
462
559
  headers2.append(
@@ -467,6 +564,10 @@ function getRouteHandlers(args) {
467
564
  "Set-Cookie",
468
565
  `${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`
469
566
  );
567
+ headers2.append(
568
+ "Set-Cookie",
569
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
570
+ );
470
571
  headers2.append(
471
572
  "Set-Cookie",
472
573
  `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
@@ -487,10 +588,11 @@ function getRouteHandlers(args) {
487
588
  }
488
589
  function userinfoGetHandler(req) {
489
590
  return __async(this, null, function* () {
490
- var _a;
591
+ var _a, _b;
491
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;
492
594
  if (oldRefreshToken) {
493
- const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken);
595
+ const refreshResponse = yield refreshTokenWithAccessAndRefreshToken(oldRefreshToken, activeOrgId);
494
596
  if (refreshResponse.error === "unexpected") {
495
597
  throw new Error("Unexpected error while refreshing access token");
496
598
  } else if (refreshResponse.error === "unauthorized") {
@@ -503,6 +605,10 @@ function getRouteHandlers(args) {
503
605
  "Set-Cookie",
504
606
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
505
607
  );
608
+ headers3.append(
609
+ "Set-Cookie",
610
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
611
+ );
506
612
  return new Response("Unauthorized", { status: 401, headers: headers3 });
507
613
  }
508
614
  const refreshToken = refreshResponse.refreshToken;
@@ -521,7 +627,8 @@ function getRouteHandlers(args) {
521
627
  const jsonResponse = {
522
628
  userinfo: data,
523
629
  accessToken,
524
- impersonatorUserId: userFromToken.impersonatorUserId
630
+ impersonatorUserId: userFromToken.impersonatorUserId,
631
+ activeOrgId
525
632
  };
526
633
  const headers3 = new Headers();
527
634
  headers3.append(
@@ -547,6 +654,10 @@ function getRouteHandlers(args) {
547
654
  "Set-Cookie",
548
655
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
549
656
  );
657
+ headers3.append(
658
+ "Set-Cookie",
659
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
660
+ );
550
661
  return new Response(null, {
551
662
  status: 401,
552
663
  headers: headers3
@@ -558,12 +669,13 @@ function getRouteHandlers(args) {
558
669
  const headers2 = new Headers();
559
670
  headers2.append("Set-Cookie", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
560
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`);
561
673
  return new Response(null, { status: 401 });
562
674
  });
563
675
  }
564
676
  function logoutGetHandler(req) {
565
677
  return __async(this, null, function* () {
566
- var _a;
678
+ var _a, _b;
567
679
  const path = (args == null ? void 0 : args.postLoginRedirectPathFn) ? args.postLoginRedirectPathFn(req) : "/";
568
680
  if (!path) {
569
681
  console.error("postLoginPathFn returned undefined");
@@ -581,12 +693,17 @@ function getRouteHandlers(args) {
581
693
  "Set-Cookie",
582
694
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
583
695
  );
696
+ headers2.append(
697
+ "Set-Cookie",
698
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
699
+ );
584
700
  return new Response(null, {
585
701
  status: 302,
586
702
  headers: headers2
587
703
  });
588
704
  }
589
- 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);
590
707
  if (refreshResponse.error === "unexpected") {
591
708
  console.error("Unexpected error while refreshing access token");
592
709
  return new Response("Unexpected error", { status: 500 });
@@ -601,6 +718,10 @@ function getRouteHandlers(args) {
601
718
  "Set-Cookie",
602
719
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
603
720
  );
721
+ headers2.append(
722
+ "Set-Cookie",
723
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
724
+ );
604
725
  return new Response(null, {
605
726
  status: 302,
606
727
  headers: headers2
@@ -629,6 +750,10 @@ function getRouteHandlers(args) {
629
750
  "Set-Cookie",
630
751
  `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
631
752
  );
753
+ headers3.append(
754
+ "Set-Cookie",
755
+ `${ACTIVE_ORG_ID_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
756
+ );
632
757
  return new Response(null, { status: 200, headers: headers3 });
633
758
  }
634
759
  const authUrlOrigin = getAuthUrlOrigin();
@@ -653,9 +778,78 @@ function getRouteHandlers(args) {
653
778
  const headers2 = new Headers();
654
779
  headers2.append("Set-Cookie", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
655
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`);
656
782
  return new Response(null, { status: 200, headers: headers2 });
657
783
  });
658
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
+ }
659
853
  function getRouteHandler(req, { params }) {
660
854
  if (params.slug === "login") {
661
855
  return loginGetHandler(req);
@@ -674,6 +868,8 @@ function getRouteHandlers(args) {
674
868
  function postRouteHandler(req, { params }) {
675
869
  if (params.slug === "logout") {
676
870
  return logoutPostHandler(req);
871
+ } else if (params.slug === "set-active-org") {
872
+ return setActiveOrgHandler(req);
677
873
  } else {
678
874
  return new Response("", { status: 404 });
679
875
  }