All Docs
FeaturesAgentOS WorkUpdated March 13, 2026

Behind the Fix: Making Invite & Pricing Pages Publicly Accessible

Behind the Fix: Making Invite & Pricing Pages Publicly Accessible

Release v1.0.84


What Changed

In v1.0.84 we corrected a subtle but impactful bug in the Next.js middleware route matcher. Two pages that should be publicly accessible — /pricing and /invite/[token] — were inadvertently protected behind authentication.


The Problem

Next.js middleware uses a matcher config to decide which routes it intercepts. Our middleware enforces authentication for all matched routes, so anything in the matcher list requires a signed-in session.

The previous matcher pattern was:

// src/middleware.ts
export const config = {
  matcher: ['/((?!api/auth|_next/static|_next/image|favicon.ico|sign-in|sign-up|^$).+)'],
};

At first glance, the ^$ anchor looks like it excludes the root path /. In practice, the outer .+ (match one or more characters) already prevented / from matching — but that same .+ also meant that any non-empty path not explicitly listed in the lookahead would be intercepted, including /pricing and /invite/abc123.

Why This Mattered

RouteExpected behaviourActual behaviour (pre-fix)
/pricingPublicly viewableRedirected to sign-in
/invite/[token]Publicly viewable; auth required only to acceptRedirected to sign-in
/sign-inPublicPublic (correct)
/PublicPublic (correct)

The /invite/[token] case was the most disruptive: new users receiving an invitation email would be immediately bounced to the sign-in page before they could even see what they were being invited to. This broke the invite acceptance flow for users who did not yet have an account.


The Fix

The matcher pattern was updated to explicitly exclude both invite and pricing from middleware interception:

// src/middleware.ts (v1.0.84)
export const config = {
  matcher: ['/((?!api/auth|_next/static|_next/image|favicon.ico|sign-in|sign-up|invite|pricing).*)'],
};

Two changes were made:

  1. Added invite and pricing to the negative lookahead so those path prefixes bypass the authentication middleware entirely.
  2. Replaced .+ with .* — this makes the outer group match zero or more characters, cleanly handling the root path / without the now-redundant ^$ anchor.

How Invite Authentication Still Works

Making /invite/[token] publicly accessible at the middleware level does not mean anyone can accept an invitation without signing in. Authentication for the acceptance action is enforced inside the invite component itself:

  • Viewing the invite page — no sign-in required. Users can see who invited them and what workspace they are joining.
  • Accepting the invite — the component checks for an active session and redirects to sign-in (or sign-up) if one is not present, preserving the invite token so the flow completes after authentication.

This is the correct pattern: public visibility, protected action.


Upgrade Notes

  • No database migrations required.
  • No API changes.
  • No configuration changes needed for self-hosted deployments.
  • If you have customised src/middleware.ts locally, apply the same lookahead and .* changes to your fork.