Add session management

This commit is contained in:
2025-01-03 12:32:43 +05:30
parent 83786e2994
commit 14c9b0210c
12 changed files with 341 additions and 16 deletions

64
src/auth/auth.route.ts Normal file
View File

@@ -0,0 +1,64 @@
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { getUserByEmail, updateUser } from "../user/user.service";
import { createSession, getSession } from "./auth.service";
export async function authRoutes(fastify: FastifyInstance) {
fastify.get(
"/microsoft/token",
{},
async (req: FastifyRequest, res: FastifyReply) => {
try {
const { token } =
await fastify.microsoftOauth.getAccessTokenFromAuthorizationCodeFlow(
req
);
const user = (await fastify.microsoftOauth.userinfo(token)) as {
givenname: string;
familyname: string;
email: string;
picture: string;
};
const userInDb = await getUserByEmail(user.email);
if (userInDb == null)
return res.code(401).send({ error: "not_allowed" });
await updateUser(userInDb.pid, {
firstName: user.givenname,
lastName: user.familyname,
email: user.email,
avatar: user.picture,
});
const session = await createSession(
userInDb.id,
req.ip,
req.headers["user-agent"]
);
return res.code(201).send({ session_token: session.sid });
} catch (err) {
//@ts-ignore
if (err.data) {
//@ts-ignore
fastify.log.warn(err.data.payload);
return res.code(400).send();
} else {
return err;
}
}
}
);
fastify.delete("/logout", {}, async (req, res) => {
if (!req.headers.authorization) return res.code(200).send();
const auth = req.headers.authorization.split(" ")[1];
const sessionInDb = await getSession(auth);
if (sessionInDb === null) return res.code(200).send();
await sessionInDb.deleteOne();
return res.code(200).send();
});
}

20
src/auth/auth.schema.ts Normal file
View File

@@ -0,0 +1,20 @@
import mongoose from "mongoose";
export const sessionModel = mongoose.model(
"session",
new mongoose.Schema({
sid: {
type: String,
unique: true,
required: true,
},
user: { type: mongoose.Types.ObjectId, ref: "user" },
ip: String,
userAgent: String,
createdAt: Date,
expiresAt: {
type: Date,
required: true,
},
})
);

24
src/auth/auth.service.ts Normal file
View File

@@ -0,0 +1,24 @@
import { generateToken } from "../utils/id";
import { sessionModel } from "./auth.schema";
export async function createSession(userId: string, ip?: string, ua?: string) {
const allUserSessions = await sessionModel.find({ user: userId });
for (const session of allUserSessions) {
await session.deleteOne();
}
const newSession = await sessionModel.create({
sid: await generateToken(),
user: userId,
ip: ip,
userAgent: ua,
createdAt: new Date(),
expiresAt: new Date(Date.now() + 3600 * 24 * 30 * 1000),
});
return newSession;
}
export async function getSession(sessionId: string) {
return await sessionModel.findOne({ sid: sessionId }).populate("user");
}