@flavoai/fastfold
Version:
Flavo frontend package
70 lines • 2.15 kB
JavaScript
import bcrypt from 'bcryptjs';
const BCRYPT_ROUNDS = 10;
const BCRYPT_PREFIX_RE = /^\$2[aby]\$/;
export const SENSITIVE_FIELD_PATTERNS = [
/password/i,
/secret/i,
/token/i,
/api_?key/i,
/private_?key/i,
/credential/i,
/auth_token/i,
/refresh_token/i,
/access_token/i,
];
export function isSensitiveFieldName(fieldName) {
return SENSITIVE_FIELD_PATTERNS.some((p) => p.test(fieldName));
}
/**
* Scan a Drizzle table definition and return the set of JS property names
* that match sensitive-field patterns.
*/
export function getSensitiveFields(table) {
const fields = new Set();
if (!table)
return fields;
for (const [propertyName, value] of Object.entries(table)) {
if (propertyName === '_' || propertyName === 'name' || !value)
continue;
const column = value;
if (column &&
typeof column === 'object' &&
(column.dataType || column.columnType || column.config)) {
if (isSensitiveFieldName(propertyName)) {
fields.add(propertyName);
}
}
}
return fields;
}
/**
* Hash every sensitive field in `data` using bcrypt.
* Already-hashed values (bcrypt prefix) are left untouched.
* Returns a new object -- the original is not mutated.
*/
export function hashSensitiveFields(data, sensitiveFields) {
const result = { ...data };
for (const field of sensitiveFields) {
const value = result[field];
if (value == null || typeof value !== 'string' || value.length === 0)
continue;
if (BCRYPT_PREFIX_RE.test(value))
continue;
result[field] = bcrypt.hashSync(value, BCRYPT_ROUNDS);
}
return result;
}
/**
* Replace every sensitive field value with "[REDACTED]".
* Returns a shallow copy -- the original is not mutated.
*/
export function redactSensitiveFields(record, sensitiveFields) {
const result = { ...record };
for (const field of sensitiveFields) {
if (field in result) {
result[field] = '[REDACTED]';
}
}
return result;
}
//# sourceMappingURL=sensitive.js.map