mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-08-02 03:35:18 +02:00
133 lines
3.5 KiB
TypeScript
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, "/");
|
|
},
|
|
};
|