28 lines
1.2 KiB
TypeScript
28 lines
1.2 KiB
TypeScript
import { z } from 'zod';
|
|
import { db } from '../../utils/db';
|
|
import { createSession, verifyPassword } from '../../utils/auth';
|
|
import { recordAudit } from '../../utils/audit';
|
|
|
|
const schema = z.object({ email: z.string().email(), password: z.string().min(1) });
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const parsed = schema.safeParse(await readBody(event).catch(() => ({})));
|
|
if (!parsed.success) throw createError({ statusCode: 400, statusMessage: 'Email and password are required.' });
|
|
|
|
const email = parsed.data.email.toLowerCase();
|
|
const user = await db.user.findUnique({ where: { email } });
|
|
if (!user || !(await verifyPassword(parsed.data.password, user.passwordHash))) {
|
|
throw createError({ statusCode: 401, statusMessage: 'Invalid email or password.' });
|
|
}
|
|
|
|
await db.subscription.upsert({
|
|
where: { userId: user.id },
|
|
update: {},
|
|
create: { userId: user.id, plan: 'free', status: 'active', provider: 'mock' },
|
|
});
|
|
await createSession(event, user.id);
|
|
await recordAudit({ actorId: user.id, action: 'user.login', target: user.email });
|
|
|
|
return { user: { id: user.id, email: user.email, name: user.name, role: user.role } };
|
|
});
|