import { Elysia, t } from "elysia"; import { jwt } from "@elysiajs/jwt"; import bcrypt from "bcryptjs"; import prisma from "../lib/prisma"; export const authRoute = new Elysia({ prefix: "/auth" }) .use( jwt({ name: "jwt", secret: process.env.JWT_SECRET || "homaroma_secret_2026_scent", exp: "24h", }) ) .post( "/login", async ({ body, jwt, set }) => { const { username, password } = body; // 1. Find user const user = await prisma.user.findUnique({ where: { username }, }); if (!user) { set.status = 401; return { success: false, message: "Invalid credentials" }; } // 2. Check password const isMatch = await bcrypt.compare(password, user.password); if (!isMatch) { set.status = 401; return { success: false, message: "Invalid credentials" }; } // 3. Generate Token const token = await jwt.sign({ id: user.id, username: user.username, role: user.role, }); return { success: true, token, user: { id: user.id, username: user.username, role: user.role, }, }; }, { body: t.Object({ username: t.String(), password: t.String(), }), detail: { summary: "Admin Login", tags: ["auth"], }, } ) .post( "/line", async ({ body, jwt, set }) => { const { lineUserId, displayName, pictureUrl, email, phone } = body; // Upsert Customer const customer = await prisma.customer.upsert({ where: { lineUserId }, update: { displayName, pictureUrl, ...(email && { email }), ...(phone && { phone }), }, create: { lineUserId, displayName, pictureUrl, email, phone, }, }); // Generate Token const token = await jwt.sign({ id: customer.id, lineUserId: customer.lineUserId, role: "CUSTOMER", }); return { success: true, token, customer, }; }, { body: t.Object({ lineUserId: t.String(), displayName: t.Optional(t.String()), pictureUrl: t.Optional(t.String()), email: t.Optional(t.String()), phone: t.Optional(t.String()), }), detail: { summary: "LINE Login for Customers", tags: ["auth"], }, } );