feat(01-03): add Edge middleware + internal validate-token API route
- src/middleware.ts: Edge-compatible token validation via fetch() (no Drizzle import) - src/app/api/internal/validate-token/route.ts: Node.js route queries clients.token via Drizzle - Invalid tokens rewrite to /not-found (404); matcher scoped to /c/:path*
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
import { eq } from 'drizzle-orm';
|
||||||
|
import { db } from '@/db';
|
||||||
|
import { clients } from '@/db/schema';
|
||||||
|
|
||||||
|
export async function GET(request: NextRequest) {
|
||||||
|
const token = request.nextUrl.searchParams.get('token');
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return NextResponse.json({ valid: false }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const rows = await db
|
||||||
|
.select({ id: clients.id })
|
||||||
|
.from(clients)
|
||||||
|
.where(eq(clients.token, token))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (rows.length === 0) {
|
||||||
|
return NextResponse.json({ valid: false }, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ valid: true }, { status: 200 });
|
||||||
|
} catch {
|
||||||
|
return NextResponse.json({ valid: false }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
|
||||||
|
export async function middleware(request: NextRequest) {
|
||||||
|
const pathname = request.nextUrl.pathname;
|
||||||
|
|
||||||
|
// Extract token from path: /c/[token]/...
|
||||||
|
const tokenMatch = pathname.match(/^\/c\/([a-zA-Z0-9_-]+)/);
|
||||||
|
if (!tokenMatch) {
|
||||||
|
return NextResponse.rewrite(new URL('/not-found', request.url));
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = tokenMatch[1];
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Call internal Node.js API route — Edge middleware cannot use postgres-js directly
|
||||||
|
// postgres-js requires Node.js net/tls which are unavailable in the Edge runtime
|
||||||
|
const validateUrl = new URL(
|
||||||
|
`/api/internal/validate-token?token=${encodeURIComponent(token)}`,
|
||||||
|
request.url
|
||||||
|
);
|
||||||
|
const res = await fetch(validateUrl.toString());
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
return NextResponse.rewrite(new URL('/not-found', request.url));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.next();
|
||||||
|
} catch {
|
||||||
|
return NextResponse.rewrite(new URL('/not-found', request.url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
matcher: ['/c/:path*'],
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user