Adds the foundation for secure cookie-based authentication without changing the authentication flow. This prepares the codebase for moving JWT tokens from Redux state to httpOnly cookies in a follow-up PR. Changes: - Added cookie-parser dependency for HTTP cookie handling - Added cookieParser() middleware to Express application - Created cookieHelpers.js utilities for consistent cookie options - Includes getAuthCookieOptions() for setting secure authentication cookies - Includes getClearAuthCookieOptions() for clearing cookies on logout Infrastructure only - no behavioral changes to authentication flow yet. Files added/modified: - package.json (cookie-parser dependency) - src/app.js (cookieParser middleware) - src/utils/cookieHelpers.js (cookie utilities) Next steps: - Follow-up PR will modify JWT verification to check cookies - Enable secure cookie-based authentication - Add logout functionality to clear httpOnly cookies Risk level: LOW (infrastructure only, no authentication changes)
86 lines
2.1 KiB
JavaScript
86 lines
2.1 KiB
JavaScript
import { JSDOM } from "jsdom";
|
|
import DOMPurify from "isomorphic-dompurify";
|
|
|
|
// Initialize DOMPurify with jsdom
|
|
const window = new JSDOM("").window;
|
|
const purify = DOMPurify(window);
|
|
|
|
/**
|
|
* Sanitizes user input to prevent XSS attacks
|
|
* @param {string} input - The input string to sanitize
|
|
* @param {Object} options - Sanitization options
|
|
* @returns {string} The sanitized string
|
|
*/
|
|
export const sanitizeInput = (input, options = {}) => {
|
|
if (typeof input !== "string") {
|
|
return input;
|
|
}
|
|
|
|
// Default configuration - remove all HTML tags and attributes
|
|
const defaultConfig = {
|
|
ALLOWED_TAGS: [],
|
|
ALLOWED_ATTR: [],
|
|
KEEP_CONTENT: true,
|
|
...options,
|
|
};
|
|
|
|
return purify.sanitize(input, defaultConfig);
|
|
};
|
|
|
|
/**
|
|
* Sanitizes an object recursively
|
|
* @param {Object} obj - The object to sanitize
|
|
* @param {Object} options - Sanitization options
|
|
* @returns {Object} The sanitized object
|
|
*/
|
|
export const sanitizeObject = (obj, options = {}) => {
|
|
if (typeof obj !== "object" || obj === null) {
|
|
return obj;
|
|
}
|
|
|
|
if (Array.isArray(obj)) {
|
|
return obj.map((item) => sanitizeObject(item, options));
|
|
}
|
|
|
|
const sanitized = {};
|
|
for (const [key, value] of Object.entries(obj)) {
|
|
if (typeof value === "string") {
|
|
sanitized[key] = sanitizeInput(value, options);
|
|
} else if (typeof value === "object" && value !== null) {
|
|
sanitized[key] = sanitizeObject(value, options);
|
|
} else {
|
|
sanitized[key] = value;
|
|
}
|
|
}
|
|
|
|
return sanitized;
|
|
};
|
|
|
|
/**
|
|
* Express middleware for sanitizing request body
|
|
* @param {Object} options - Sanitization options
|
|
* @returns {Function} Express middleware function
|
|
*/
|
|
export const sanitizeBody = (options = {}) => {
|
|
return (req, res, next) => {
|
|
if (req.body && typeof req.body === "object") {
|
|
req.body = sanitizeObject(req.body, options);
|
|
}
|
|
next();
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Express middleware for sanitizing query parameters
|
|
* @param {Object} options - Sanitization options
|
|
* @returns {Function} Express middleware function
|
|
*/
|
|
export const sanitizeQuery = (options = {}) => {
|
|
return (req, res, next) => {
|
|
if (req.query && typeof req.query === "object") {
|
|
req.query = sanitizeObject(req.query, options);
|
|
}
|
|
next();
|
|
};
|
|
};
|