forked from atums.world/backend
move all from /api, turn this into backend only ( remove ejs )
This commit is contained in:
parent
8a9499be85
commit
4936ff8978
24 changed files with 14 additions and 98 deletions
166
src/routes/auth/login.ts
Normal file
166
src/routes/auth/login.ts
Normal file
|
@ -0,0 +1,166 @@
|
|||
import {
|
||||
isValidEmail,
|
||||
isValidPassword,
|
||||
isValidUsername,
|
||||
} from "@lib/validators";
|
||||
import { type ReservedSQL, password as bunPassword, sql } from "bun";
|
||||
|
||||
import { sessionManager } from "@/lib/jwt";
|
||||
import { logger } from "@creations.works/logger";
|
||||
|
||||
const routeDef: RouteDef = {
|
||||
method: "POST",
|
||||
accepts: "application/json",
|
||||
returns: "application/json",
|
||||
needsBody: "json",
|
||||
};
|
||||
|
||||
async function handler(
|
||||
request: ExtendedRequest,
|
||||
requestBody: unknown,
|
||||
): Promise<Response> {
|
||||
if (request.session) {
|
||||
if ((request.session as ApiUserSession).is_api) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 403,
|
||||
error: "You cannot log in while using an authorization token",
|
||||
},
|
||||
{ status: 403 },
|
||||
);
|
||||
}
|
||||
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 403,
|
||||
error: "Already logged in",
|
||||
},
|
||||
{ status: 403 },
|
||||
);
|
||||
}
|
||||
|
||||
const { username, email, password } = requestBody as {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
if (!password || (!username && !email)) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 400,
|
||||
error: "Expected username or email, and password",
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const errors: string[] = [];
|
||||
|
||||
const validations: UserValidation[] = [
|
||||
username ? { check: isValidUsername(username), field: "Username" } : null,
|
||||
email ? { check: isValidEmail(email), field: "Email" } : null,
|
||||
password ? { check: isValidPassword(password), field: "Password" } : null,
|
||||
].filter(Boolean) as UserValidation[];
|
||||
|
||||
for (const { check } of validations) {
|
||||
if (!check.valid && check.error) {
|
||||
errors.push(check.error);
|
||||
}
|
||||
}
|
||||
|
||||
if (!username && !email) {
|
||||
errors.push("Either a username or an email is required.");
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 400,
|
||||
errors,
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const reservation: ReservedSQL = await sql.reserve();
|
||||
let user: User | null = null;
|
||||
|
||||
try {
|
||||
[user] = await reservation`
|
||||
SELECT * FROM users
|
||||
WHERE (username = ${username} OR email = ${email})
|
||||
LIMIT 1;
|
||||
`;
|
||||
|
||||
if (!user) {
|
||||
await bunPassword.verify("fake", await bunPassword.hash("fake"));
|
||||
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 401,
|
||||
error: "Invalid username, email, or password",
|
||||
},
|
||||
{ status: 401 },
|
||||
);
|
||||
}
|
||||
|
||||
const passwordMatch: boolean = await bunPassword.verify(
|
||||
password,
|
||||
user.password,
|
||||
);
|
||||
|
||||
if (!passwordMatch) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 401,
|
||||
error: "Invalid username, email, or password",
|
||||
},
|
||||
{ status: 401 },
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(["Error logging in", error as Error]);
|
||||
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 500,
|
||||
error: "An error occurred while logging in",
|
||||
},
|
||||
{ status: 500 },
|
||||
);
|
||||
} finally {
|
||||
if (reservation) reservation.release();
|
||||
}
|
||||
|
||||
const sessionCookie: string = await sessionManager.createSession(
|
||||
{
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
email_verified: user.email_verified,
|
||||
roles: user.roles[0].split(","),
|
||||
avatar: user.avatar,
|
||||
timezone: user.timezone,
|
||||
authorization_token: user.authorization_token,
|
||||
},
|
||||
request.headers.get("User-Agent") || "",
|
||||
);
|
||||
|
||||
return Response.json(
|
||||
{
|
||||
success: true,
|
||||
code: 200,
|
||||
},
|
||||
{ status: 200, headers: { "Set-Cookie": sessionCookie } },
|
||||
);
|
||||
}
|
||||
|
||||
export { handler, routeDef };
|
Loading…
Add table
Add a link
Reference in a new issue