mirror of
https://github.com/fosrl/pangolin.git
synced 2026-06-06 07:38:46 +00:00
Pull the session from badger
This commit is contained in:
102
server/middlewares/verifyUserFromResourceSession.ts
Normal file
102
server/middlewares/verifyUserFromResourceSession.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { Response, NextFunction } from "express";
|
||||
import { db } from "@server/db";
|
||||
import { resourceSessions, users } from "@server/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import createHttpError from "http-errors";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import { getUserOrgRoleIds } from "@server/lib/userOrgRoles";
|
||||
import { getUserSessionWithUser } from "@server/db/queries/verifySessionQueries";
|
||||
import { encodeHexLowerCase } from "@oslojs/encoding";
|
||||
import { sha256 } from "@oslojs/crypto/sha2";
|
||||
import config from "@server/lib/config";
|
||||
import logger from "@server/logger";
|
||||
|
||||
export const verifyUserFromResourceSessionMiddleware = async (
|
||||
req: any,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
) => {
|
||||
if (!req.user) {
|
||||
const sessionCookieName =
|
||||
config.getRawConfig().server.session_cookie_name;
|
||||
|
||||
// Collect all resource session cookies (format: {name}[_s].{timestamp}=token)
|
||||
const cookieHeader: string | undefined = req.headers.cookie;
|
||||
const candidates: { timestamp: number; token: string }[] = [];
|
||||
|
||||
if (cookieHeader) {
|
||||
for (const part of cookieHeader.split(";")) {
|
||||
const trimmed = part.trim();
|
||||
const eqIdx = trimmed.indexOf("=");
|
||||
if (eqIdx === -1) continue;
|
||||
|
||||
const cookieName = trimmed.slice(0, eqIdx).trim();
|
||||
const cookieValue = trimmed.slice(eqIdx + 1).trim();
|
||||
|
||||
// Match both secure (_s.timestamp) and non-secure (.timestamp) variants
|
||||
const securePrefix = `${sessionCookieName}_s.`;
|
||||
const httpPrefix = `${sessionCookieName}.`;
|
||||
|
||||
let timestampStr: string | null = null;
|
||||
if (cookieName.startsWith(securePrefix)) {
|
||||
timestampStr = cookieName.slice(securePrefix.length);
|
||||
} else if (cookieName.startsWith(httpPrefix)) {
|
||||
timestampStr = cookieName.slice(httpPrefix.length);
|
||||
}
|
||||
|
||||
if (timestampStr !== null && /^\d+$/.test(timestampStr)) {
|
||||
candidates.push({
|
||||
timestamp: parseInt(timestampStr, 10),
|
||||
token: cookieValue
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pick the most recently issued session (highest timestamp)
|
||||
candidates.sort((a, b) => b.timestamp - a.timestamp);
|
||||
const best = candidates[0];
|
||||
|
||||
if (best) {
|
||||
try {
|
||||
const sessionId = encodeHexLowerCase(
|
||||
sha256(new TextEncoder().encode(best.token))
|
||||
);
|
||||
|
||||
const [resourceSession] = await db
|
||||
.select()
|
||||
.from(resourceSessions)
|
||||
.where(eq(resourceSessions.sessionId, sessionId))
|
||||
.limit(1);
|
||||
|
||||
if (resourceSession && Date.now() < resourceSession.expiresAt) {
|
||||
if (resourceSession.userSessionId) {
|
||||
const result = await getUserSessionWithUser(
|
||||
resourceSession.userSessionId
|
||||
);
|
||||
|
||||
if (result?.user && result?.session) {
|
||||
req.user = result.user;
|
||||
req.session = result.session;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(
|
||||
"verifyUserFromResourceSessionMiddleware: failed to validate resource session",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Populate userOrgRoleIds if an orgId is available in route params
|
||||
if (req.user && req.params?.orgId && !req.userOrgRoleIds) {
|
||||
req.userOrgRoleIds = await getUserOrgRoleIds(
|
||||
req.user.userId,
|
||||
req.params.orgId
|
||||
);
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
Reference in New Issue
Block a user