Files
homaroma/apps/backend/src/routes/auth.ts
T
2026-09-29 10:13:48 +07:00

159 lines
3.7 KiB
TypeScript

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"],
},
}
)
.post(
"/install-seed",
async ({ body, set }) => {
const { password, pin } = body as { password?: string; pin?: string };
const secret = password || pin;
if (secret !== "66195221") {
set.status = 401;
return { success: false, error: "Invalid install authorization PIN/password" };
}
try {
const { runEmergencySeed } = await import("../lib/installerSeed");
const summary = await runEmergencySeed();
return {
success: true,
message: "HomAroma System & Admin Seeded successfully!",
adminUser: {
username: "admin",
password: "homaroma123",
},
summary,
};
} catch (err) {
console.error("[InstallSeed] Error:", err);
set.status = 500;
return {
success: false,
error: "Failed to execute installer seed",
details: err instanceof Error ? err.message : String(err),
};
}
},
{
body: t.Object({
password: t.Optional(t.String()),
pin: t.Optional(t.String()),
}),
detail: {
summary: "Emergency System & Admin Installer Seed",
tags: ["auth"],
},
}
);