UNPKG

aegis-auth

Version:

A credentials-based auth solution for Next.js (and other Node projects) with IP rate-limiting, account lockouts, and sessions in DB.

111 lines 3.92 kB
import { signSessionToken, verifySessionToken } from "../security"; import { ErrorCodes, } from "../types"; import { validateAndRotateSessionSchema } from "../validations"; import { createSession } from "./createSession"; import { revokeSession } from "./revokeSession"; export async function validateAndRotateSession(context, input) { var _a; const { prisma, config } = context; try { const validatedInput = validateAndRotateSessionSchema.safeParse(input); if (!validatedInput.success) { config.logger.securityEvent("INVALID_INPUT", { route: "validateAndRotateSession", }); return { success: false, status: 400, message: "Invalid input provided", code: ErrorCodes.INVALID_INPUT, }; } const { sessionToken } = validatedInput.data; const tokenHash = await signSessionToken({ sessionToken, config }); const session = (await prisma.session.findUnique({ where: { tokenHash }, })); if (!session) { config.logger.securityEvent("SESSION_NOT_FOUND", { sessionToken, }); return { success: false, status: 404, message: "Session not found", }; } if (session.isRevoked) { config.logger.securityEvent("SESSION_REVOKED", { sessionId: session.id, }); return { success: false, status: 401, message: "Session revoked", }; } const isValidToken = await verifySessionToken({ sessionToken, sessionTokenHash: session.tokenHash, config, }); if (!isValidToken) { config.logger.securityEvent("SESSION_INVALID", { sessionId: session.id, }); return { success: false, status: 401, message: "Session invalid", }; } const now = new Date(); const timeSinceLastUpdate = now.getTime() - session.updatedAt.getTime(); const shouldRotate = config.session.rollingIntervalSeconds > 0 && timeSinceLastUpdate > config.session.rollingIntervalSeconds * 1000; if (shouldRotate) { const newSession = await createSession(context, { userId: session.userId, }); if (!newSession.success || !((_a = newSession.data) === null || _a === void 0 ? void 0 : _a.session)) { return { success: false, status: 500, message: "Failed to create new session", code: ErrorCodes.FAILED_TO_ROLL_SESSION, }; } await revokeSession(context, { sessionToken, }); config.logger.securityEvent("SESSION_ROTATED", { oldSessionId: session.id, }); return { success: true, status: 200, message: "Session rotated", data: { session: newSession.data.session, rolled: true }, }; } return { success: true, status: 200, message: "Session validated", data: { rolled: false }, }; } catch (error) { config.logger.error("Error validating/rotating session", { error, sessionToken: input.sessionToken, }); return { success: false, status: 500, message: "An unexpected error occurred.", code: ErrorCodes.INTERNAL_SERVER_ERROR, }; } } //# sourceMappingURL=validateAndRotateSession.js.map