Files
permit-api/src/auth/auth.route.ts

143 lines
3.5 KiB
TypeScript

import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import {
getUserByEmail,
getUserByToken,
resetUser,
} from "../user/user.service";
import { createSession, deleteSession } from "./auth.service";
import { hash, verify } from "argon2";
import { validatePassword } from "../utils/password";
export async function authRoutes(fastify: FastifyInstance) {
fastify.post(
"/register",
{
schema: {
body: {
type: "object",
required: ["password", "token"],
properties: {
password: { type: "string" },
token: { type: "string" },
},
},
},
},
async (req: FastifyRequest, res: FastifyReply) => {
const { password, token } = req.body as {
password: string;
token: string;
};
try {
const userInDB = await getUserByToken(token);
if (!userInDB) return res.code(404).send({ error: "not found" });
if (new Date() > userInDB.token.expiry)
return res.code(400).send({ error: "link expired" });
if (!validatePassword(password))
return res.code(400).send({
error:
"weak password. Make sure the password has atleast 2 uppercase, 2 lowercase, 2 numeric and 2 special characters",
});
const hashedPassword = await hash(password);
userInDB.passwordHash = hashedPassword;
await userInDB.save();
} catch (err) {
return err;
}
}
);
fastify.post(
"/login",
{
schema: {
body: {
type: "object",
required: ["email", "password"],
properties: {
email: { type: "string" },
password: { type: "string" },
},
},
},
},
async (req: FastifyRequest, res: FastifyReply) => {
const { email, password } = req.body as {
email: string;
password: string;
};
try {
const userInDB = await getUserByEmail(email);
if (!userInDB)
return res.code(401).send({ error: "invalid email or password" });
if (!userInDB.passwordHash)
return res.code(401).send({ error: "invalid email or password" });
const match = await verify(userInDB.passwordHash, password);
if (!match)
return res.code(401).send({ error: "invalid email or password" });
const newSession = await createSession(
userInDB.id,
req.ip,
req.headers["user-agent"]
);
userInDB.lastLogin = new Date();
await userInDB.save();
res.send({ session_token: newSession.sid });
} catch (err) {
return err;
}
}
);
fastify.delete(
"/logout",
{},
async (req: FastifyRequest, res: FastifyReply) => {
if (!req.headers.authorization) return res.code(200).send();
const auth = req.headers.authorization.split(" ")[1];
await deleteSession(auth);
return res.code(200).send();
}
);
fastify.post(
"/reset",
{
schema: {
body: {
type: "object",
properties: {
email: { type: "string" },
},
},
},
},
async (req: FastifyRequest, res: FastifyReply) => {
const { email } = req.body as { email: string };
try {
const userInDB = await getUserByEmail(email);
if (userInDB) {
await resetUser(userInDB.pid);
}
return res.code(200).send();
} catch (err) {
return err;
}
}
);
}