2022-09-30 15:14:57 -05:00
|
|
|
import { Handlers, PageProps } from "$fresh/server.ts";
|
|
|
|
import { Page } from "../components/Page.tsx";
|
|
|
|
import { PostgresError, query } from "../db.ts";
|
|
|
|
import { hash } from "https://deno.land/x/bcrypt@v0.4.1/mod.ts";
|
|
|
|
|
|
|
|
type UserID = string;
|
|
|
|
|
|
|
|
interface RegistrationError {
|
|
|
|
message: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const handler: Handlers<UserID | RegistrationError | null> = {
|
|
|
|
async POST(request, context) {
|
|
|
|
const formData = (await request.formData());
|
|
|
|
const username = formData.get("username");
|
|
|
|
const password = formData.get("password");
|
2022-10-01 14:03:15 -05:00
|
|
|
if (!username) {
|
|
|
|
return await context.render({ message: "no username provided" });
|
|
|
|
}
|
|
|
|
if (!password) {
|
|
|
|
return await context.render({ message: "no password provided" });
|
|
|
|
}
|
2022-09-30 15:14:57 -05:00
|
|
|
const hashed_password = await hash(password.toString());
|
|
|
|
try {
|
|
|
|
const result = await query<{ id: string }>(
|
|
|
|
`insert into "user" (username, hashed_password) values ($1, $2) returning id`,
|
|
|
|
[username, hashed_password],
|
|
|
|
);
|
|
|
|
console.debug(result);
|
|
|
|
if (!result) throw "insert failed";
|
|
|
|
const { rows: [{ id }] } = result;
|
|
|
|
return await context.render(id);
|
|
|
|
} catch (err) {
|
2022-10-01 14:03:15 -05:00
|
|
|
if (
|
|
|
|
err instanceof PostgresError && err.fields.code == "23505" &&
|
|
|
|
err.fields.constraint == "user_username_key"
|
|
|
|
) {
|
|
|
|
return await context.render({
|
|
|
|
message: `A user with username '${username}' already exists`,
|
|
|
|
});
|
2022-09-30 15:14:57 -05:00
|
|
|
}
|
2022-10-01 14:03:15 -05:00
|
|
|
throw err;
|
2022-09-30 15:14:57 -05:00
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
export default function Register(
|
|
|
|
{ data: userId }: PageProps<UserID | RegistrationError | null>,
|
|
|
|
) {
|
|
|
|
if (typeof userId == "string") {
|
|
|
|
return RegistrationSuccessful(userId);
|
|
|
|
} else {
|
|
|
|
return RegistrationForm(userId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function RegistrationSuccessful(_userId: UserID) {
|
|
|
|
return (
|
|
|
|
<Page>
|
|
|
|
<p>
|
|
|
|
You're all signed up! Let's go <a href="/login">log in</a>!
|
|
|
|
</p>
|
|
|
|
</Page>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function RegistrationForm(props?: RegistrationError | null) {
|
|
|
|
console.log(props);
|
2022-09-29 20:22:30 -05:00
|
|
|
return (
|
2022-09-30 15:14:57 -05:00
|
|
|
<Page>
|
|
|
|
{props != null &&
|
2022-10-01 14:03:15 -05:00
|
|
|
(
|
|
|
|
<p class="text-red-500">
|
|
|
|
<strong>Error</strong>: {props.message}
|
|
|
|
</p>
|
|
|
|
)}
|
2022-09-30 15:14:57 -05:00
|
|
|
<form class="flex flex-col max-w-lg" method="post">
|
|
|
|
<label for="username">Username</label>
|
2022-10-01 14:03:15 -05:00
|
|
|
<input type="text" name="username" />
|
2022-09-30 15:14:57 -05:00
|
|
|
<label for="password">Password</label>
|
2022-10-01 14:03:15 -05:00
|
|
|
<input type="password" name="password" />
|
2022-09-30 15:14:57 -05:00
|
|
|
<input
|
2022-10-01 14:03:15 -05:00
|
|
|
class="bg-blue-800 px-4 p-2 mt-2"
|
2022-09-30 15:14:57 -05:00
|
|
|
type="submit"
|
|
|
|
value="Register"
|
|
|
|
/>
|
|
|
|
</form>
|
|
|
|
</Page>
|
2022-09-29 20:22:30 -05:00
|
|
|
);
|
|
|
|
}
|