Files
gitea-mirror/src/pages/api/auth/login.ts
2025-05-18 09:31:23 +05:30

63 lines
1.6 KiB
TypeScript

import type { APIRoute } from "astro";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
import { db, users } from "@/lib/db";
import { eq } from "drizzle-orm";
const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key";
export const POST: APIRoute = async ({ request }) => {
const { username, password } = await request.json();
if (!username || !password) {
return new Response(
JSON.stringify({ error: "Username and password are required" }),
{
status: 400,
headers: { "Content-Type": "application/json" },
}
);
}
const user = await db
.select()
.from(users)
.where(eq(users.username, username))
.limit(1);
if (!user.length) {
return new Response(
JSON.stringify({ error: "Invalid username or password" }),
{
status: 401,
headers: { "Content-Type": "application/json" },
}
);
}
const isPasswordValid = await bcrypt.compare(password, user[0].password);
if (!isPasswordValid) {
return new Response(
JSON.stringify({ error: "Invalid username or password" }),
{
status: 401,
headers: { "Content-Type": "application/json" },
}
);
}
const { password: _, ...userWithoutPassword } = user[0];
const token = jwt.sign({ id: user[0].id }, JWT_SECRET, { expiresIn: "7d" });
return new Response(JSON.stringify({ token, user: userWithoutPassword }), {
status: 200,
headers: {
"Content-Type": "application/json",
"Set-Cookie": `token=${token}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${
60 * 60 * 24 * 7
}`,
},
});
};