auditforge / backend /src /models /vulnerability.js
Kaballas's picture
initialize project structure with essential configurations and components
56b6519
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var customField = {
_id: false,
customField: { type: Schema.Types.ObjectId, ref: 'CustomField' },
text: Schema.Types.Mixed,
};
var VulnerabilityDetails = {
_id: false,
locale: String,
// language: String,
title: { type: String, unique: true, sparse: true },
vulnType: String,
description: String,
observation: String,
remediation: String,
cwes: [String],
references: [String],
customFields: [customField],
};
var VulnerabilitySchema = new Schema(
{
cvssv3: String,
priority: { type: Number, enum: [1, 2, 3, 4] },
remediationComplexity: { type: Number, enum: [1, 2, 3] },
details: [VulnerabilityDetails],
status: { type: Number, enum: [0, 1, 2], default: 1 }, // 0: validated, 1: created, 2: updated,
category: String,
creator: { type: Schema.Types.ObjectId, ref: 'User' },
},
{ timestamps: true },
);
/*
*** Statics ***
*/
// Get all vulnerabilities
VulnerabilitySchema.statics.getAll = () => {
return new Promise((resolve, reject) => {
var query = Vulnerability.find();
query.populate('creator', '-_id username');
query
.exec()
.then(rows => {
resolve(rows);
})
.catch(err => {
reject(err);
});
});
};
// Get all vulnerabilities for download
VulnerabilitySchema.statics.export = () => {
return new Promise((resolve, reject) => {
var query = Vulnerability.find();
query.select(
'details cvssv3 priority remediationComplexity cwes references category -_id',
);
query
.exec()
.then(rows => {
resolve(rows);
})
.catch(err => {
reject(err);
});
});
};
// Create vulnerability
VulnerabilitySchema.statics.create = vulnerabilities => {
return new Promise((resolve, reject) => {
Vulnerability.insertMany(vulnerabilities, { ordered: false })
.then(rows => {
resolve({ created: rows.length, duplicates: 0 });
})
.catch(err => {
if (err.code === 11000) {
if (err.result.nInserted === 0)
reject({
fn: 'BadParameters',
message: 'Vulnerability title already exists',
});
else {
var errorMessages = [];
err.writeErrors.forEach(e =>
errorMessages.push(e.errmsg || 'no errmsg'),
);
resolve({
created: err.result.nInserted,
duplicates: errorMessages,
});
}
} else reject(err);
});
});
};
// Update vulnerability
VulnerabilitySchema.statics.update = (vulnerabilityId, vulnerability) => {
return new Promise((resolve, reject) => {
var VulnerabilityUpdate = mongoose.model('VulnerabilityUpdate');
var query = Vulnerability.findByIdAndUpdate(vulnerabilityId, vulnerability);
query
.exec()
.then(row => {
if (!row)
reject({ fn: 'NotFound', message: 'Vulnerability not found' });
else {
var query = VulnerabilityUpdate.deleteMany({
vulnerability: vulnerabilityId,
});
return query.exec();
}
})
.then(row => {
resolve('Vulnerability updated successfully');
})
.catch(err => {
if (err.code === 11000)
reject({
fn: 'BadParameters',
message: 'Vulnerability title already exists',
});
else reject(err);
});
});
};
// Delete all vulnerabilities
VulnerabilitySchema.statics.deleteAll = () => {
return new Promise((resolve, reject) => {
var query = Vulnerability.deleteMany();
query
.exec()
.then(() => {
resolve('All vulnerabilities deleted successfully');
})
.catch(err => {
reject(err);
});
});
};
// Delete vulnerability
VulnerabilitySchema.statics.delete = vulnerabilityId => {
return new Promise((resolve, reject) => {
var query = Vulnerability.findByIdAndDelete(vulnerabilityId);
query
.exec()
.then(rows => {
if (rows) resolve(rows);
else reject({ fn: 'NotFound', message: 'Vulnerability not found' });
})
.catch(err => {
reject(err);
});
});
};
// Get vulnerabilities by language
VulnerabilitySchema.statics.getAllByLanguage = locale => {
return new Promise((resolve, reject) => {
var query = Vulnerability.find({ 'details.locale': locale });
query.select('details cvssv3 priority remediationComplexity category');
query
.exec()
.then(rows => {
if (rows) {
var result = [];
rows.forEach(row => {
row.details.forEach(detail => {
if (detail.locale === locale && detail.title) {
var temp = {};
temp.cvssv3 = row.cvssv3;
temp.priority = row.priority;
temp.remediationComplexity = row.remediationComplexity;
temp.category = row.category;
temp.detail = detail;
temp._id = row._id;
result.push(temp);
}
});
});
resolve(result);
} else
reject({
fn: 'NotFound',
message: 'Locale with existing title not found',
});
})
.catch(err => {
reject(err);
});
});
};
VulnerabilitySchema.statics.Merge = (vulnIdPrime, vulnIdMerge, locale) => {
return new Promise((resolve, reject) => {
var mergeDetail = null;
var mergeVuln = null;
var primeVuln = null;
var query = Vulnerability.findById(vulnIdMerge);
query
.exec()
.then(row => {
if (!row)
reject({ fn: 'NotFound', message: 'Vulnerability not found' });
else {
mergeVuln = row;
mergeDetail = row.details.find(d => d.locale === locale);
var query = Vulnerability.findById(vulnIdPrime);
return query.exec();
}
})
.then(row => {
if (!row)
reject({ fn: 'NotFound', message: 'Vulnerability not found' });
else {
if (row.details.findIndex(d => d.locale === locale && d.title) !== -1)
reject({
fn: 'BadParameters',
message: 'Language already exists in this vulnerability',
});
else {
primeVuln = row;
var removeIndex = mergeVuln.details
.map(d => d.title)
.indexOf(mergeDetail.title);
mergeVuln.details.splice(removeIndex, 1);
if (mergeVuln.details.length === 0)
return Vulnerability.findByIdAndDelete(mergeVuln._id);
else return mergeVuln.save();
}
}
})
.then(() => {
var detail = {};
detail.locale = mergeDetail.locale;
detail.title = mergeDetail.title;
if (mergeDetail.vulnType) detail.vulnType = mergeDetail.vulnType;
if (mergeDetail.description)
detail.description = mergeDetail.description;
if (mergeDetail.observation)
detail.observation = mergeDetail.observation;
if (mergeDetail.remediation)
detail.remediation = mergeDetail.remediation;
if (mergeDetail.customFields)
detail.customFields = mergeDetail.customFields;
primeVuln.details.push(detail);
return primeVuln.save();
})
.then(() => {
resolve('Vulnerability merge successfull');
})
.catch(err => {
reject(err);
});
});
};
/*
*** Methods ***
*/
var Vulnerability = mongoose.model('Vulnerability', VulnerabilitySchema);
module.exports = Vulnerability;