Refactor database utility functions and enhance audit logging
All checks were successful
farmcontrol/farmcontrol-ws/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-ws/pipeline/head This commit looks good
- Removed unnecessary console logging in the `SocketUser` class for cleaner output. - Updated the `distributeNew` function to accept the entire object instead of just the ID, improving flexibility in handling new entries. - Enhanced the `newAuditLog` and `editAuditLog` functions to filter out excluded models and changes, ensuring sensitive data is not logged. - Introduced new utility functions for omitting specific paths and excluded changes from audit logs, enhancing data privacy and integrity.
This commit is contained in:
parent
ccbf2ff388
commit
9416a94a23
@ -143,7 +143,7 @@ export const listObjects = async ({
|
||||
sort,
|
||||
order,
|
||||
project,
|
||||
cached,
|
||||
cached
|
||||
})}`
|
||||
);
|
||||
|
||||
@ -199,7 +199,7 @@ export const listObjects = async ({
|
||||
order,
|
||||
project,
|
||||
cached,
|
||||
length: finalResult.length,
|
||||
length: finalResult.length
|
||||
})}`
|
||||
);
|
||||
return finalResult;
|
||||
@ -221,7 +221,7 @@ export const getObject = async ({
|
||||
`Getting object: ${formatTraceData({
|
||||
model,
|
||||
id,
|
||||
populate,
|
||||
populate
|
||||
})}`
|
||||
);
|
||||
|
||||
@ -259,7 +259,7 @@ export const getObject = async ({
|
||||
`Retreived object from database: ${formatTraceData({
|
||||
model,
|
||||
id,
|
||||
populate,
|
||||
populate
|
||||
})}`
|
||||
);
|
||||
|
||||
@ -394,9 +394,15 @@ export const aggregateRollupsHistory = async ({
|
||||
if (rollup.operation === 'count') {
|
||||
value = matchingObjects.length;
|
||||
} else if (rollup.operation === 'sum') {
|
||||
value = _.sumBy(matchingObjects, obj => _.get(obj, rollup.property) || 0);
|
||||
value = _.sumBy(
|
||||
matchingObjects,
|
||||
obj => _.get(obj, rollup.property) || 0
|
||||
);
|
||||
} else if (rollup.operation === 'avg') {
|
||||
const sum = _.sumBy(matchingObjects, obj => _.get(obj, rollup.property) || 0);
|
||||
const sum = _.sumBy(
|
||||
matchingObjects,
|
||||
obj => _.get(obj, rollup.property) || 0
|
||||
);
|
||||
value = matchingObjects.length ? sum / matchingObjects.length : 0;
|
||||
}
|
||||
|
||||
@ -486,7 +492,9 @@ export const aggregateRollupsHistory = async ({
|
||||
logIndex++;
|
||||
}
|
||||
|
||||
results.push(snapshotRollups(Array.from(workingObjects.values()), bucketDate));
|
||||
results.push(
|
||||
snapshotRollups(Array.from(workingObjects.values()), bucketDate)
|
||||
);
|
||||
}
|
||||
|
||||
return results.reverse();
|
||||
@ -616,7 +624,7 @@ export const newObject = async ({
|
||||
await newAuditLog(newData, created._id, parentType, owner, ownerType);
|
||||
}
|
||||
|
||||
await distributeNew(created._id, parentType);
|
||||
await distributeNew(created, parentType);
|
||||
|
||||
await updateObjectCache({
|
||||
model: model,
|
||||
|
||||
@ -11,6 +11,12 @@ const NOTIFICATION_EXCLUDED_MODELS = [
|
||||
'userNotifier',
|
||||
'auditLog'
|
||||
];
|
||||
const AUDIT_EXCLUDED_MODELS = [
|
||||
'notification',
|
||||
'userNotifier',
|
||||
'marketplaceEvent'
|
||||
];
|
||||
const AUDIT_EXCLUDED_CHANGES = ['state.message'];
|
||||
const SENSITIVE_KEYS = ['secret'];
|
||||
|
||||
function omitSensitive(obj) {
|
||||
@ -24,6 +30,58 @@ function omitSensitive(obj) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function omitPath(obj, path) {
|
||||
if (obj == null || typeof obj !== 'object') return obj;
|
||||
const keys = path.split('.');
|
||||
if (keys.length === 1) {
|
||||
const result = { ...obj };
|
||||
delete result[keys[0]];
|
||||
return result;
|
||||
}
|
||||
const [first, ...rest] = keys;
|
||||
if (
|
||||
obj[first] == null ||
|
||||
typeof obj[first] !== 'object' ||
|
||||
Array.isArray(obj[first])
|
||||
) {
|
||||
return obj;
|
||||
}
|
||||
const nested = obj[first];
|
||||
const leafKey = rest[rest.length - 1];
|
||||
const result = { ...obj };
|
||||
|
||||
if (rest.length === 1) {
|
||||
const nestedKeys = Object.keys(nested);
|
||||
if (nestedKeys.length === 1 && nestedKeys[0] === leafKey) {
|
||||
delete result[first];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const nestedKeys = Object.keys(nested);
|
||||
if (
|
||||
nestedKeys.length > 1 ||
|
||||
(nestedKeys.length === 1 && nestedKeys[0] !== rest[0])
|
||||
) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
const updatedNested = omitPath({ ...nested }, rest.join('.'));
|
||||
if (updatedNested == null || Object.keys(updatedNested).length === 0) {
|
||||
delete result[first];
|
||||
} else {
|
||||
result[first] = updatedNested;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function omitExcludedChanges(obj) {
|
||||
if (obj == null || typeof obj !== 'object') return obj;
|
||||
return AUDIT_EXCLUDED_CHANGES.reduce((acc, path) => omitPath(acc, path), {
|
||||
...obj
|
||||
});
|
||||
}
|
||||
|
||||
let modelsCache = null;
|
||||
|
||||
async function getModelEntryByType(parentType) {
|
||||
@ -391,8 +449,10 @@ function getChangedValues(oldObj, newObj, old = false) {
|
||||
}
|
||||
|
||||
async function newAuditLog(newValue, parentId, parentType, owner, ownerType) {
|
||||
// Filter out createdAt and updatedAt from newValue
|
||||
const filteredNewValue = { ...newValue };
|
||||
if (AUDIT_EXCLUDED_MODELS.includes(parentType)) return;
|
||||
|
||||
// Filter out createdAt, updatedAt, and sensitive fields from newValue
|
||||
const filteredNewValue = omitSensitive({ ...newValue });
|
||||
delete filteredNewValue.createdAt;
|
||||
delete filteredNewValue.updatedAt;
|
||||
const auditLog = new auditLogModel({
|
||||
@ -408,7 +468,7 @@ async function newAuditLog(newValue, parentId, parentType, owner, ownerType) {
|
||||
|
||||
await auditLog.save();
|
||||
|
||||
await distributeNew(auditLog._id, 'auditLog');
|
||||
await distributeNew(auditLog, 'auditLog');
|
||||
}
|
||||
|
||||
async function editAuditLog(
|
||||
@ -422,9 +482,19 @@ async function editAuditLog(
|
||||
if (parentType === 'stockEvent') {
|
||||
return;
|
||||
}
|
||||
const filteredOldValue = omitExcludedChanges(oldValue);
|
||||
const filteredNewValue = omitExcludedChanges(newValue);
|
||||
// Get only the changed values
|
||||
const changedOldValues = getChangedValues(oldValue, newValue, true);
|
||||
const changedNewValues = getChangedValues(oldValue, newValue, false);
|
||||
const changedOldValues = getChangedValues(
|
||||
filteredOldValue,
|
||||
filteredNewValue,
|
||||
true
|
||||
);
|
||||
const changedNewValues = getChangedValues(
|
||||
filteredOldValue,
|
||||
filteredNewValue,
|
||||
false
|
||||
);
|
||||
|
||||
// If no values changed, don't create an audit log
|
||||
if (
|
||||
@ -448,7 +518,7 @@ async function editAuditLog(
|
||||
|
||||
await auditLog.save();
|
||||
|
||||
await distributeNew(auditLog._id, 'auditLog');
|
||||
await distributeNew(auditLog, 'auditLog');
|
||||
}
|
||||
|
||||
async function deleteAuditLog(
|
||||
@ -471,7 +541,7 @@ async function deleteAuditLog(
|
||||
|
||||
await auditLog.save();
|
||||
|
||||
await distributeNew(auditLog._id, 'auditLog');
|
||||
await distributeNew(auditLog, 'auditLog');
|
||||
}
|
||||
|
||||
async function getAuditLogs(idOrIds) {
|
||||
@ -490,8 +560,8 @@ async function distributeStats(value, type) {
|
||||
await natsServer.publish(`${type}s.stats`, value);
|
||||
}
|
||||
|
||||
async function distributeNew(id, type) {
|
||||
await natsServer.publish(`${type}s.new`, id);
|
||||
async function distributeNew(value, type) {
|
||||
await natsServer.publish(`${type}s.new`, value);
|
||||
}
|
||||
|
||||
async function editNotification(
|
||||
|
||||
@ -113,7 +113,6 @@ export class SocketUser {
|
||||
logger.info('User authenticated and valid.');
|
||||
|
||||
this.user = result.user;
|
||||
console.log('user', this.user);
|
||||
this.id = this.user._id.toString();
|
||||
this.authenticated = true;
|
||||
await this.notificationManager.subscribe();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user