UNPKG

nitropage

Version:

A free and open source, extensible visual page builder based on SolidStart.

143 lines (123 loc) 2.98 kB
import { createId } from "@paralleldrive/cuid2"; import { NitroUser } from "@prisma/client"; import { redirect } from "@solidjs/router"; import { useRequestRef } from "../cache"; import { createServer } from "./core/server"; import { useServerConfig } from "../server/config"; import { hashPassword, validatePassword } from "../server/crypto"; import { useDatabase } from "../server/prisma"; export const { handler, Auth, getSession, assertCsrf, signin } = createServer( "np", { config: () => useServerConfig().auth, signin: async function ({ username, password, }: { username: string; password: string; }) { const db = useDatabase(); const user = await db.nitroUser.findFirst({ where: { [username.includes("@") ? "email" : "username"]: username, }, }); if (!user) { return; } const passwordCorrect = await validatePassword(password, user.password); if (!passwordCorrect) { return; } return { id: user.id, user: user.username, }; }, }, ); export const getUser = async ({ assert, }: { assert?: { csrf?: string | true; }; } = {}) => { if (assert?.csrf !== undefined) { await assertCsrf(assert.csrf); } const session = await getSession(); if (!session?.data?.id) { if (assert) { throw new Error("Access denied!"); } return; } const usersRef = useRequestRef<Record<string, Partial<NitroUser>>>( "npUsers", () => ({}), ); const db = useDatabase(); const user = usersRef.current[session.data.id] || (await db.nitroUser.findFirst({ select: { id: true, email: true, createdAt: true, updatedAt: true, username: true, }, where: { id: session.data.id, }, })); if (!user) { if (assert) { throw new Error("Access denied!"); } return; } usersRef.current[session.data.id] = user; return { ...user, csrf: session.csrf, }; }; export const signup = async function (args: { username: string; password: string; email: string; }) { // TODO: allow signup of more users by logged in admins // TODO: add a check to avoid creating duplicate users const db = useDatabase(); const users = await db.nitroUser.count(); if (users > 0) { return false; } const passwordHashed = await hashPassword(args.password); const user = await db.nitroUser.create({ data: { admin: true, username: args.username, email: args.email, password: passwordHashed, }, }); await signin({ username: user.username, password: args.password, }); if (await db.nitroProject.count()) { return; } const firstProject = await db.nitroProject.create({ data: { publicId: createId(), title: "My first project", }, }); throw redirect(`/admin/project/${firstProject.id}`); };