← back to ClawCoder
src/middleware.ts
54 lines
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const AUTH_USER = 'Steve'
const AUTH_PASS = 'DWSecure2024!'
const SESSION_COOKIE = 'clawcoder_session'
const SESSION_MAX_AGE = 30 * 24 * 60 * 60 * 1000 // 30 days
const publicPaths = [
'/login',
'/api/',
'/_next',
'/favicon.ico',
]
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl
// Allow public paths
if (publicPaths.some(path => pathname.startsWith(path))) {
return NextResponse.next()
}
// Check Basic Auth header (for API/curl access)
const authHeader = request.headers.get('authorization')
if (authHeader?.startsWith('Basic ')) {
const decoded = Buffer.from(authHeader.slice(6), 'base64').toString()
const [user, pass] = decoded.split(':')
if (user === AUTH_USER && pass === AUTH_PASS) {
return NextResponse.next()
}
}
// Check session cookie (for browser access)
const session = request.cookies.get(SESSION_COOKIE)?.value
if (session) {
try {
const data = JSON.parse(Buffer.from(session, 'base64url').toString())
if (data.authenticated && (Date.now() - data.loginTime) < SESSION_MAX_AGE) {
return NextResponse.next()
}
} catch {}
}
// No valid auth — redirect to login
const loginUrl = new URL('/login', request.url)
loginUrl.searchParams.set('redirect', pathname)
return NextResponse.redirect(loginUrl)
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
}