import * as bcrypt from "https://deno.land/x/bcrypt@v0.4.1/mod.ts";
import { email } from "https://esm.town/v/std/email";
import { sqlite } from "https://esm.town/v/std/sqlite";
export default async function(req: Request): Promise<Response> {
const body = await req.json();
let { username, password } = body;
if (!username || !password) {
return new Response(JSON.stringify({ error: "Missing username or password" }), { status: 400 });
}
if (password.length > 50) {
return new Response(JSON.stringify({ error: "Password too long" }), { status: 400 });
}
if (username.length > 50) {
return new Response(JSON.stringify({ error: "Username too long" }), { status: 400 });
}
const TABLE_NAME = "lab_login_users_with_times";
const existingUser = await sqlite.execute({
sql: `SELECT * FROM ${TABLE_NAME} WHERE username = ?`,
args: [username],
});
const bannedCharacters = [
" ",
"\t",
"\n",
"\r",
"\u200b",
"\u200d",
"\u200c",
"\u2800",
"",
" ",
];
if (existingUser.rows.length === 0) {
const hashedPassword = await bcrypt.hash(password);
if (bannedCharacters.some(char => username.includes(char))) {
return new Response(JSON.stringify({ error: "username contains banned characters. no spaces, etc..." }), {
status: 400,
});
}
if (username.toLowerCase().includes("todepond")) {
return new Response(JSON.stringify({ error: "no todepond impersonation" }), { status: 400 });
}
await sqlite.execute({
sql: `INSERT INTO ${TABLE_NAME} (username, password) VALUES (?, ?)`,
args: [username, hashedPassword],
});
const newUser = await sqlite.execute({
sql: `SELECT * FROM ${TABLE_NAME} WHERE username = ?`,
args: [username],
});
email({
to: "todepond@gmail.com",
from: "todepond.com@valtown.email",
subject: "New Login user",
text: username,
});
return new Response(JSON.stringify(newUser.rows[0]), { status: 201 });
}
const user = existingUser.rows[0];
const storedPassword = user[2];
const passwordMatch = await bcrypt.compare(password, storedPassword);
if (user[5] === 1) {
return new Response(JSON.stringify({ error: "user is banned" }), { status: 403 });
}
if (passwordMatch) {
return new Response(JSON.stringify(user), { status: 200 });
} else {
return new Response(JSON.stringify({ error: "wrong password" }), { status: 401 });
}
}