@teleporthq/teleport-plugin-next-workflows 0.43.22 → 0.43.26

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.
@@ -966,11 +966,28 @@ function hasSessionCookie(request) {
966
966
  return false;
967
967
  }
968
968
 
969
+ // Where to send an authenticated user who lacks the required role. Normally the
970
+ // home page ("you don't have access, here's the public site"). But when "/" is
971
+ // itself a protected page (e.g. an admin dashboard published at the root), a
972
+ // redirect to "/" re-enters this middleware and loops forever — so fall back to
973
+ // the sign-in page (with a callbackUrl) in that case.
974
+ function roleDeniedRedirect(request, pathname) {
975
+ if (pathname !== '/' && !protectedRoutes['/']) {
976
+ return NextResponse.redirect(new URL('/', request.url));
977
+ }
978
+ var deniedUrl = new URL('${signInRoute}', request.url);
979
+ deniedUrl.searchParams.set('callbackUrl', pathname);
980
+ return NextResponse.redirect(deniedUrl);
981
+ }
982
+
969
983
  async function middleware(request) {
970
984
  const pathname = request.nextUrl.pathname;
971
985
 
972
986
  for (let i = 0; i < authRoutes.length; i++) {
973
- if (pathname.startsWith(authRoutes[i])) {
987
+ // Segment-safe: an auth route like "/sign-in" must not bypass protection on
988
+ // a same-prefix page such as "/sign-in-offers". Mirrors the protectedRoutes
989
+ // matching below.
990
+ if (pathname === authRoutes[i] || pathname.startsWith(authRoutes[i] + '/')) {
974
991
  return NextResponse.next();
975
992
  }
976
993
  }
@@ -1044,7 +1061,7 @@ async function middleware(request) {
1044
1061
  }
1045
1062
  var userRole = getUserRoleFromToken(sessionUser);
1046
1063
  if (userRole == null || allowedRoles.indexOf(userRole) < 0) {
1047
- return NextResponse.redirect(new URL('/', request.url));
1064
+ return roleDeniedRedirect(request, pathname);
1048
1065
  }
1049
1066
  }
1050
1067
 
@@ -1053,7 +1070,12 @@ async function middleware(request) {
1053
1070
 
1054
1071
  export default middleware;
1055
1072
  export const config = {
1056
- matcher: ['/((?!api|_next/static|_next/image|favicon\\\\.ico).*)'],
1073
+ // The bare '/' entry is required so middleware also runs on the home page:
1074
+ // Next.js does NOT run the second (negative-lookahead) matcher for the root
1075
+ // path, which would leave a page published at "/" (e.g. a protected dashboard)
1076
+ // publicly reachable. '/' compiles to ^/$ and covers exactly the home route;
1077
+ // the second entry covers every deeper path.
1078
+ matcher: ['/', '/((?!api|_next/static|_next/image|favicon\\\\.ico).*)'],
1057
1079
  };
1058
1080
  `
1059
1081
  }