feat: initialize VitePress CMS
This commit is contained in:
96
server/auth.mjs
Normal file
96
server/auth.mjs
Normal file
@@ -0,0 +1,96 @@
|
||||
import { db } from "./db.mjs";
|
||||
import { json, readBody } from "./http.mjs";
|
||||
import { clearSessionCookie, createSession, deleteSession, getSession, parseCookies, sessionCookie } from "./session.mjs";
|
||||
import { verifyPassword } from "./security.mjs";
|
||||
|
||||
function publicUser(user) {
|
||||
if (!user) return null;
|
||||
|
||||
return {
|
||||
id: user.id,
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
avatarUrl: user.avatar_url,
|
||||
role: user.role,
|
||||
};
|
||||
}
|
||||
|
||||
export function getRequestSession(request) {
|
||||
const cookies = parseCookies(request.headers.cookie);
|
||||
const sessionId = cookies.vpc_session;
|
||||
const session = getSession(sessionId);
|
||||
return { sessionId, session };
|
||||
}
|
||||
|
||||
export function requireCmsUser(request, response) {
|
||||
const { session } = getRequestSession(request);
|
||||
|
||||
if (!session?.user?.id) {
|
||||
json(response, 401, { error: "Not signed in" });
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return session.user;
|
||||
}
|
||||
|
||||
async function handleMe(request, response) {
|
||||
const { session } = getRequestSession(request);
|
||||
json(response, 200, { user: session?.user ?? null });
|
||||
}
|
||||
|
||||
async function handleLogin(request, response) {
|
||||
const body = JSON.parse(await readBody(request) || "{}");
|
||||
const email = String(body.email || "").trim().toLowerCase();
|
||||
const password = String(body.password || "");
|
||||
|
||||
if (!email || !password) {
|
||||
json(response, 400, { error: "Email and password are required" });
|
||||
return;
|
||||
}
|
||||
|
||||
const user = db.prepare("SELECT * FROM users WHERE email = ?").get(email);
|
||||
|
||||
if (!user?.password_hash || !verifyPassword(password, user.password_hash)) {
|
||||
json(response, 401, { error: "Invalid email or password" });
|
||||
return;
|
||||
}
|
||||
|
||||
const sessionUser = publicUser(user);
|
||||
const sessionId = createSession({
|
||||
user: sessionUser,
|
||||
});
|
||||
|
||||
json(response, 200, { user: sessionUser }, { "Set-Cookie": sessionCookie(sessionId) });
|
||||
}
|
||||
|
||||
async function handleLogout(request, response) {
|
||||
const { sessionId } = getRequestSession(request);
|
||||
deleteSession(sessionId);
|
||||
json(response, 200, { ok: true }, { "Set-Cookie": clearSessionCookie() });
|
||||
}
|
||||
|
||||
export async function handleAuthApi(request, response, url) {
|
||||
try {
|
||||
if (url.pathname === "/api/auth/me" && request.method === "GET") {
|
||||
await handleMe(request, response);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (url.pathname === "/api/auth/login" && request.method === "POST") {
|
||||
await handleLogin(request, response);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (url.pathname === "/api/auth/logout" && request.method === "POST") {
|
||||
await handleLogout(request, response);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (error) {
|
||||
json(response, 500, {
|
||||
error: error instanceof Error ? error.message : "Unknown auth API error",
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user