Understanding the Role of middleware.ts in LunaTV: Authentication and Route Protection
The 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 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, 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, 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 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 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:
// 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:
// 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:
# .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:
// 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.tsoperates as a Next.js Edge Middleware that executes before every page and API request in LunaTV.- The
shouldSkipAuthfunction efficiently bypasses static assets like/_nextand/favicon.icoto maintain performance. - Environment validation ensures the
PASSWORDvariable is configured, redirecting to/warningif missing. getAuthInfoFromCookieextracts credentials from cookies, supporting both plaintext password and HMAC signature modes.verifySignatureuses the Web Crypto API to validate cryptographic signatures without exposing server secrets.handleAuthFailurereturns401for APIs and redirects browsers to/loginwith preserved destination URLs.- The
config.matcherlimits 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 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →