Files
Aseret_Bank/backend/src/middleware/dataMasking.ts
2026-02-09 21:51:31 -08:00

55 lines
1.4 KiB
TypeScript

import { Request, Response, NextFunction } from 'express';
export function maskPII(data: any): any {
if (typeof data === 'string') {
// Mask email
if (data.includes('@')) {
const [local, domain] = data.split('@');
return `${local.substring(0, 2)}***@${domain}`;
}
// Mask phone
if (/^\d{10,}$/.test(data.replace(/\D/g, ''))) {
const cleaned = data.replace(/\D/g, '');
return `***-***-${cleaned.slice(-4)}`;
}
// Mask SSN
if (/^\d{3}-\d{2}-\d{4}$/.test(data)) {
return `***-**-${data.slice(-4)}`;
}
}
if (Array.isArray(data)) {
return data.map(item => maskPII(item));
}
if (data && typeof data === 'object') {
const masked: any = {};
const sensitiveFields = ['ssn', 'taxId', 'accountNumber', 'routingNumber', 'creditCard', 'cvv'];
for (const [key, value] of Object.entries(data)) {
if (sensitiveFields.includes(key.toLowerCase())) {
masked[key] = '***';
} else {
masked[key] = maskPII(value);
}
}
return masked;
}
return data;
}
export function maskDataInResponse(req: Request, res: Response, next: NextFunction): void {
const originalJson = res.json.bind(res);
res.json = function (data: any) {
// Only mask in non-production or for non-admin users
if (process.env.NODE_ENV !== 'production' || (req as any).userRole !== 'ADMIN') {
data = maskPII(data);
}
return originalJson(data);
};
next();
}