| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- // app/api/auth/login/route.js
- import bcrypt from "bcryptjs";
- import User from "@/models/user";
- import { getDb } from "@/lib/db";
- import { createSession } from "@/lib/auth/session";
- /**
- * POST /api/auth/login
- *
- * Body (JSON):
- * {
- * "username": "example.user",
- * "password": "plain-text-password"
- * }
- */
- export async function POST(request) {
- try {
- let body;
- try {
- body = await request.json();
- } catch {
- return jsonResponse({ error: "Invalid request body" }, 400);
- }
- if (!body || typeof body !== "object") {
- return jsonResponse({ error: "Invalid request body" }, 400);
- }
- const { username, password } = body;
- if (
- typeof username !== "string" ||
- typeof password !== "string" ||
- !username.trim() ||
- !password.trim()
- ) {
- return jsonResponse({ error: "Missing username or password" }, 400);
- }
- const normalizedUsername = username.trim().toLowerCase();
- // Ensure DB (Mongoose) connection is established before using models.
- await getDb();
- const user = await User.findOne({ username: normalizedUsername }).exec();
- if (!user) {
- return jsonResponse({ error: "Invalid credentials" }, 401);
- }
- // Defensive: never let missing/invalid passwordHash crash the endpoint.
- if (typeof user.passwordHash !== "string" || !user.passwordHash) {
- return jsonResponse({ error: "Invalid credentials" }, 401);
- }
- const passwordMatches = await bcrypt.compare(password, user.passwordHash);
- if (!passwordMatches) {
- return jsonResponse({ error: "Invalid credentials" }, 401);
- }
- await createSession({
- userId: user._id.toString(),
- role: user.role,
- branchId: user.branchId ?? null,
- });
- return jsonResponse({ ok: true }, 200);
- } catch (error) {
- console.error("Login error:", error);
- return jsonResponse({ error: "Internal server error" }, 500);
- }
- }
- function jsonResponse(data, status = 200) {
- return new Response(JSON.stringify(data), {
- status,
- headers: {
- "Content-Type": "application/json",
- },
- });
- }
|