juntekim.com/stripe_to_invoice/app/api/auth/callback/route.ts
2025-12-31 00:02:22 +00:00

53 lines
1.3 KiB
TypeScript

// app/api/auth/callback/route.ts
import { NextResponse } from "next/server";
import { cookies } from "next/headers";
import { db } from "@/lib/db";
import { loginTokens } from "@/lib/schema";
import { and, eq, gt, isNull } from "drizzle-orm";
import { hashToken } from "@/lib/auth/tokens";
export async function POST(req: Request) {
const { token } = await req.json();
if (!token) {
return NextResponse.json({ error: "Missing token" }, { status: 400 });
}
const tokenHash = hashToken(token);
const loginToken = await db
.select()
.from(loginTokens)
.where(
and(
eq(loginTokens.tokenHash, tokenHash),
isNull(loginTokens.usedAt),
gt(loginTokens.expiresAt, new Date())
)
)
.limit(1)
.then((rows) => rows[0]);
if (!loginToken) {
return NextResponse.json(
{ error: "Invalid or expired token" },
{ status: 401 }
);
}
// ✅ mark token as used
await db
.update(loginTokens)
.set({ usedAt: new Date() })
.where(eq(loginTokens.id, loginToken.id));
// ✅ FIX: cookies() is async in Next 15+
const cookieStore = await cookies();
cookieStore.set("session", loginToken.userId, {
httpOnly: true,
sameSite: "lax",
path: "/",
});
return NextResponse.json({ ok: true });
}