1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-08-02 03:35:18 +02:00
AdventureLog/src/routes/setup/+page.server.ts

133 lines
3.5 KiB
TypeScript

// routes/signup/+page.server.ts
import { lucia } from "$lib/server/auth";
import { fail, redirect } from "@sveltejs/kit";
import { generateId } from "lucia";
import { Argon2id } from "oslo/password";
import { db } from "$lib/db/db.server";
import type { DatabaseUser } from "$lib/server/auth";
import type { Actions } from "./$types";
import { userTable } from "$lib/db/schema";
import { eq, sql } from "drizzle-orm";
import { insertData } from "$lib/db/insertData";
export const actions: Actions = {
default: async (event) => {
const formData = await event.request.formData();
const formUsername = formData.get("username");
let username = formUsername?.toString().toLocaleLowerCase();
if (typeof formUsername !== "string") {
return fail(400, {
message: "Invalid username",
});
}
const password = formData.get("password");
const firstName = formData.get("first_name");
const lastName = formData.get("last_name");
// username must be between 4 ~ 31 characters, and only consists of lowercase letters, 0-9, -, and _
// keep in mind some database (e.g. mysql) are case insensitive
// check all to make sure all fields are provided
if (!username || !password || !firstName || !lastName) {
return fail(400, {
message: "All fields are required",
});
}
if (
typeof username !== "string" ||
username.length < 3 ||
username.length > 31 ||
!/^[a-z0-9_-]+$/.test(username)
) {
return fail(400, {
message: "Invalid username",
});
}
if (
typeof password !== "string" ||
password.length < 6 ||
password.length > 255
) {
return fail(400, {
message: "Invalid password",
});
}
if (
typeof firstName !== "string" ||
firstName.length < 1 ||
firstName.length > 255
) {
return fail(400, {
message: "Invalid first name",
});
}
if (
typeof lastName !== "string" ||
lastName.length < 1 ||
lastName.length > 255
) {
return fail(400, {
message: "Invalid last name",
});
}
const userId = generateId(15);
const hashedPassword = await new Argon2id().hash(password);
const usernameTaken = await db
.select()
.from(userTable)
.where(eq(userTable.username, username))
.limit(1)
.then((results) => results[0] as unknown as DatabaseUser | undefined);
if (usernameTaken) {
return fail(400, {
message: "Username already taken",
});
}
let adminUser = await db
.select()
.from(userTable)
.where(eq(userTable.role, "admin"))
.execute();
if (adminUser != null && adminUser.length > 0) {
return fail(400, {
message: "Admin user already exists",
});
}
await db
.insert(userTable)
.values({
id: userId,
username: username,
first_name: firstName,
last_name: lastName,
hashed_password: hashedPassword,
signup_date: new Date(),
role: "admin",
last_login: new Date(),
} as DatabaseUser)
.execute();
// inserts the data needed for all of the pre defined adventures and world travel regions
await insertData(event);
const session: any = await lucia.createSession(userId, {});
const sessionCookie: any = lucia.createSessionCookie(session.id);
event.cookies.set(sessionCookie.name, sessionCookie.value, {
path: ".",
...sessionCookie.attributes,
});
redirect(302, "/");
},
};