100 lines
2.4 KiB
TypeScript
100 lines
2.4 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { getPrisma } from '@/lib/db';
|
|
import { comparePassword, signJwt } from '@/lib/auth';
|
|
|
|
export async function POST(req: NextRequest) {
|
|
try {
|
|
const { username, password } = await req.json();
|
|
|
|
if (!username || !password) {
|
|
return NextResponse.json(
|
|
{ error: 'Username and password are required' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Run lookup as ADMIN to bypass RLS since the user is not authenticated yet
|
|
const prismaAdmin = getPrisma({
|
|
userId: 0,
|
|
username: 'login_system',
|
|
email: 'system@estelar.com',
|
|
role: 'ADMIN',
|
|
hotelId: 0,
|
|
regionId: 0
|
|
});
|
|
|
|
const user = await prismaAdmin.user.findUnique({
|
|
where: { username },
|
|
include: { hotel: true }
|
|
});
|
|
|
|
if (!user || user.status !== 'ACTIVE') {
|
|
return NextResponse.json(
|
|
{ error: 'Invalid credentials or inactive user' },
|
|
{ status: 401 }
|
|
);
|
|
}
|
|
|
|
const passwordMatch = await comparePassword(password, user.passwordHash);
|
|
if (!passwordMatch) {
|
|
return NextResponse.json(
|
|
{ error: 'Invalid credentials' },
|
|
{ status: 401 }
|
|
);
|
|
}
|
|
|
|
// Create session payload
|
|
const sessionPayload = {
|
|
userId: user.id,
|
|
username: user.username,
|
|
email: user.email,
|
|
role: user.role,
|
|
hotelId: user.hotelId,
|
|
regionId: user.hotel.regionId
|
|
};
|
|
|
|
// Sign JWT
|
|
const token = signJwt(sessionPayload);
|
|
|
|
// Set cookie
|
|
const response = NextResponse.json({
|
|
user: {
|
|
id: user.id,
|
|
username: user.username,
|
|
email: user.email,
|
|
role: user.role,
|
|
hotelId: user.hotelId,
|
|
area: user.area
|
|
}
|
|
});
|
|
|
|
response.cookies.set({
|
|
name: 'session',
|
|
value: token,
|
|
httpOnly: true,
|
|
secure: process.env.NODE_ENV === 'production',
|
|
sameSite: 'lax',
|
|
path: '/',
|
|
maxAge: 86400 // 1 day
|
|
});
|
|
|
|
// Record login audit log
|
|
await prismaAdmin.auditLog.create({
|
|
data: {
|
|
userId: user.id,
|
|
action: 'LOGIN',
|
|
targetTable: 'users',
|
|
targetId: user.id,
|
|
ipAddress: req.headers.get('x-forwarded-for') || '127.0.0.1'
|
|
}
|
|
});
|
|
|
|
return response;
|
|
} catch (err) {
|
|
console.error('Login error:', err);
|
|
return NextResponse.json(
|
|
{ error: 'Internal server error' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|