# Understanding the Role of middleware.ts in LunaTV: Authentication and Route Protection

> Discover the role of middleware.ts in LunaTV. This Next.js Edge Middleware file secures your app by handling authentication, preventing unauthorized access, and protecting API routes.

- Repository: [MoonTechLab/LunaTV](https://github.com/MoonTechLab/LunaTV)
- Tags: deep-dive
- Published: 2026-09-09

---

**The [`middleware.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/middleware.ts) file in LunaTV acts as a Next.js Edge Middleware gatekeeper that intercepts every incoming request to enforce authentication, skip static assets, and redirect unauthenticated users to login while returning 401 errors for API routes.**

The [`src/middleware.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/middleware.ts) file serves as the central security orchestrator for the MoonTechLab/LunaTV open-source media platform. Running at the Edge before any page or API handler executes, this middleware validates environment configuration, parses authentication cookies, and verifies cryptographic signatures to ensure only authorized users access protected content. It implements a dual-mode authentication system that supports both local password storage and HMAC-based signature verification.

## Skipping Unprotected Static Assets

In [`src/middleware.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/middleware.ts), the `shouldSkipAuth` helper (lines 19-30) maintains application performance by whitelisting paths that never require authentication. This function checks the request pathname against static asset routes including `/_next`, `/favicon.ico`, [`/robots.txt`](https://github.com/MoonTechLab/LunaTV/blob/main//robots.txt), and other public files. When a match occurs, the middleware immediately returns `NextResponse.next()` to allow the request to proceed unchanged, preventing unnecessary authentication overhead for static resources.

## Enforcing Password Configuration

Before processing any authentication logic, the middleware verifies that the `PASSWORD` environment variable is properly configured (lines 15-21). If this variable is missing or empty, every request receives a redirect to the `/warning` page, ensuring the LunaTV instance cannot be accessed in an insecure state. This safety check runs early in the middleware lifecycle to guarantee that administrators explicitly define access credentials before users can interact with the system.

## Extracting Authentication Data

The `getAuthInfoFromCookie` function (line 24) in [`src/lib/auth.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/auth.ts) parses the incoming request cookies to extract authentication context. This helper returns an object containing `username`, `password`, and/or `signature` values depending on the active storage mode. If the middleware cannot locate valid authentication data in the cookies, it immediately triggers the `handleAuthFailure` routine (line 27) to terminate the request with appropriate access controls.

## Supporting Dual Storage Modes

LunaTV's [`middleware.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/middleware.ts) implements two distinct authentication strategies controlled by the `NEXT_PUBLIC_STORAGE_TYPE` environment variable:

### Local-Storage Mode

When `NEXT_PUBLIC_STORAGE_TYPE` is set to `localstorage`, the middleware validates that the password stored in the cookie directly matches `process.env.PASSWORD` (lines 31-35). This mode stores the actual credentials client-side in an encrypted cookie, providing straightforward authentication suitable for trusted local networks.

### Signature-Based Mode

For enhanced security, the signature mode stores only a `username` and HMAC `signature` in the cookie. The middleware uses the Web Crypto API through the `verifySignature` function (lines 38-56) to cryptographically validate the signature against the server-side secret. If the signature verification succeeds, the request proceeds to the protected resource; otherwise, the middleware falls back to `handleAuthFailure`.

## Handling Authentication Failures

The `handleAuthFailure` function (lines 101-116) implements differentiated responses based on the request type. API routes receive a direct `401 Unauthorized` response with appropriate headers, while browser requests are redirected to `/login` with a `redirect` query parameter preserving the original destination URL. This dual-behavior approach ensures that programmatic clients receive machine-readable status codes while human users experience seamless login flows.

## Configuring the Middleware Matcher

The exported `config.matcher` (lines 33-38) defines precise URL patterns that trigger the middleware execution. This configuration explicitly excludes static asset routes, the login page, the warning page, and specific API endpoints from middleware processing. By limiting interception to relevant protected routes, LunaTV maintains optimal performance while ensuring comprehensive security coverage.

## Practical Implementation Examples

Any page placed under the `/dashboard` route automatically inherits middleware protection without additional code:

```typescript
// src/pages/dashboard.tsx
export default function Dashboard() {
  // This component only renders if middleware.ts validates the request
  return <div>Protected LunaTV Dashboard</div>;
}

```

API routes can rely on the same authentication layer. Invalid requests receive `401` responses before reaching the handler:

```typescript
// src/pages/api/secret.ts
export default function handler(req, res) {
  // Execution reaches here only after middleware validation succeeds
  res.json({ secret: 'Luna TV secret data' });
}

```

Configure the authentication mode via environment variables:

```bash

# .env.local

# Option 1: Store password directly in cookie

NEXT_PUBLIC_STORAGE_TYPE=localstorage

# Option 2: Store only HMAC signature

NEXT_PUBLIC_STORAGE_TYPE=signature

```

The login page handles post-authentication redirects by reading the `redirect` query parameter:

```typescript
// src/pages/login.tsx
import { useRouter } from 'next/router';

export default function Login() {
  const router = useRouter();
  const { redirect } = router.query;
  
  const handleSuccess = () => {
    router.push((redirect as string) ?? '/');
  };
  
  return <LoginForm onSuccess={handleSuccess} />;
}

```

## Summary

- **[`src/middleware.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/middleware.ts)** operates as a Next.js Edge Middleware that executes before every page and API request in LunaTV.
- The **`shouldSkipAuth`** function efficiently bypasses static assets like `/_next` and `/favicon.ico` to maintain performance.
- Environment validation ensures the `PASSWORD` variable is configured, redirecting to `/warning` if missing.
- **`getAuthInfoFromCookie`** extracts credentials from cookies, supporting both plaintext password and HMAC signature modes.
- **`verifySignature`** uses the Web Crypto API to validate cryptographic signatures without exposing server secrets.
- **`handleAuthFailure`** returns `401` for APIs and redirects browsers to `/login` with preserved destination URLs.
- The **`config.matcher`** limits middleware execution to relevant routes, excluding public pages and static files.

## Frequently Asked Questions

### How does LunaTV middleware.ts handle unauthenticated API requests differently from page requests?

According to the MoonTechLab/LunaTV source code, the `handleAuthFailure` function (lines 101-116) detects the request type through URL pattern matching. API routes receive a `401 Unauthorized` response with appropriate headers, while standard page requests trigger a redirect to `/login` with a `redirect` query parameter. This differentiation ensures REST clients receive proper HTTP status codes while web users experience a seamless authentication flow.

### What happens if the PASSWORD environment variable is not set in LunaTV?

If `process.env.PASSWORD` is undefined, [`src/middleware.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/middleware.ts) redirects every incoming request to the `/warning` page (lines 15-21). This prevents the LunaTV instance from operating in an insecure state by forcing administrators to configure authentication credentials before granting any access to the application interface or API endpoints.

### Can LunaTV operate without cookies for authentication?

No, the LunaTV middleware fundamentally relies on cookies to transport authentication data. The `getAuthInfoFromCookie` function reads either a stored password or HMAC signature from the request cookies (line 24). Without this cookie data, the middleware cannot validate the session and will always trigger `handleAuthFailure`, making cookie-based authentication mandatory for all protected routes.

### What is the difference between localstorage and signature modes in middleware.ts?

**Local-storage mode** stores the actual password value in the cookie and validates it against `process.env.PASSWORD` (lines 31-35), suitable for trusted local networks. **Signature-based mode** stores only a username and HMAC signature, verified using the Web Crypto API via `verifySignature` (lines 38-56), providing enhanced security by never transmitting the actual password to the client after initial authentication.