Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nayalsaurav/Storx/llms.txt

Use this file to discover all available pages before exploring further.

Storx uses Clerk for all authentication and user session management. Clerk handles account creation, sign-in, password validation, and session tokens. Storx does not store passwords or manage sessions itself — every protected operation validates the Clerk session before proceeding.

How It Works

Middleware Route Protection

Storx protects routes at the Edge using Clerk’s clerkMiddleware in middleware.ts. The middleware runs on every request that matches the configured matcher and enforces the following rules:
middleware.ts
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";

const isPublicRoute = createRouteMatcher(["/", "/signin(.*)", "/signup(.*)"]);

export default clerkMiddleware(async (auth, request) => {
  const user = auth();
  const userId = (await user).userId;
  const url = new URL(request.url);

  if (userId && isPublicRoute(request) && url.pathname !== "/") {
    return NextResponse.redirect(new URL("/dashboard", request.url));
  }

  if (!isPublicRoute(request)) {
    await auth.protect();
  }
});

export const config = {
  matcher: [
    "/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
    "/(api|trpc)(.*)",
  ],
};
The middleware behaviour is:
ScenarioResult
Unauthenticated user → any non-public routeauth.protect() redirects to sign-in
Authenticated user → /signin or /signupRedirected to /dashboard
Authenticated user → / (landing page)Allowed through (no redirect)
Any user → public route (/, /signin(.*), /signup(.*))Allowed through

Setting Up Clerk

1

Create a Clerk application

Go to clerk.com and sign up or log in. Click Create application, give it a name (e.g. Storx), and choose Email + Password as the authentication strategy to match Storx’s sign-in and sign-up forms.
2

Copy your API keys

In the Clerk dashboard, navigate to API Keys. Copy:
  • Publishable key — starts with pk_test_ (development) or pk_live_ (production)
  • Secret key — starts with sk_test_ or sk_live_
3

Add the Clerk variables to .env.local

.env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/signin
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/signup
4

Configure redirect URLs in the Clerk dashboard

In the Clerk dashboard, go to Paths (under Configure) and set:
SettingValue
Sign-in URL/signin
Sign-up URL/signup
After sign-in redirect/dashboard
After sign-up redirect/dashboard
These must match the NEXT_PUBLIC_CLERK_SIGN_IN_URL and NEXT_PUBLIC_CLERK_SIGN_UP_URL values in .env.local.

User ID in API Routes

Every Storx API route that performs a database or storage operation first extracts and validates the userId from the active Clerk session. An absent or invalid session returns 401 immediately:
import { auth } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";

// Inside any API route handler:
const { userId } = await auth();
if (!userId) {
  return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
auth() is imported from @clerk/nextjs/server and is available in any Next.js Route Handler or Server Action. It reads the session token from the incoming request without any additional configuration.

Sign In / Sign Up Pages

Storx renders its own styled sign-in and sign-up forms using Clerk’s React component hooks, mounted at the catch-all routes:
  • /signin/[[...signin]] — renders <SignInForm />
  • /signup/[[...signup]] — renders <SignUpForm />
The [[...signin]] and [[...signup]] catch-all segments are required by Clerk so that its multi-step flows (e.g. email verification, OAuth callbacks) can append sub-paths like /signin/sso-callback without triggering a 404. Both forms use Zod schemas for client-side validation before calling Clerk:
import * as z from "zod";

export const signInSchema = z.object({
  identifier: z
    .email({ error: "Please enter a valid email" })
    .min(1, { error: "Email is required" }),
  password: z
    .string()
    .min(1, { error: "password is required" })
    .min(8, { error: "Password must be atleast 8 characters" }),
});

export type signInSchemaType = z.infer<typeof signInSchema>;
All Storx API routes perform a dual-layer userId check. In addition to validating the Clerk session token, routes that accept a userId in the request body (e.g. file upload, folder creation) compare that value against the session userId. If the two values do not match, the route returns 401 Unauthorized — even if the session itself is valid. This prevents authenticated users from performing actions on behalf of other users.

Build docs developers (and LLMs) love