Spaces:
Runtime error
Runtime error
const { isArray } = require('lodash'); | |
module.exports = function (app) { | |
var Response = require('../lib/httpResponse.js'); | |
var acl = require('../lib/auth').acl; | |
var utils = require('../lib/utils'); | |
var Language = require('mongoose').model('Language'); | |
var AuditType = require('mongoose').model('AuditType'); | |
var VulnerabilityType = require('mongoose').model('VulnerabilityType'); | |
var VulnerabilityCategory = require('mongoose').model( | |
'VulnerabilityCategory', | |
); | |
var CustomSection = require('mongoose').model('CustomSection'); | |
var CustomField = require('mongoose').model('CustomField'); | |
var _ = require('lodash'); | |
/* ===== ROLES ===== */ | |
// Get Roles list | |
app.get( | |
'/api/data/roles', | |
acl.hasPermission('roles:read'), | |
function (req, res) { | |
try { | |
var result = Object.keys(acl.roles); | |
Response.Ok(res, result); | |
} catch (error) { | |
Response.Internal(res, error); | |
} | |
}, | |
); | |
/* ===== LANGUAGES ===== */ | |
// Get languages list | |
app.get( | |
'/api/data/languages', | |
acl.hasPermission('languages:read'), | |
function (req, res) { | |
Language.getAll() | |
.then(msg => Response.Ok(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Create language | |
app.post( | |
'/api/data/languages', | |
acl.hasPermission('languages:create'), | |
function (req, res) { | |
if (!req.body.locale || !req.body.language) { | |
Response.BadParameters( | |
res, | |
'Missing required parameters: locale, language', | |
); | |
return; | |
} | |
if ( | |
!utils.validFilename(req.body.language) || | |
!utils.validFilename(req.body.locale) | |
) { | |
Response.BadParameters( | |
res, | |
"language and locale value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
var language = {}; | |
language.locale = req.body.locale; | |
language.language = req.body.language; | |
Language.create(language) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Delete Language | |
app.delete( | |
'/api/data/languages/:locale(*)', | |
acl.hasPermission('languages:delete'), | |
function (req, res) { | |
Language.delete(req.params.locale) | |
.then(msg => { | |
Response.Ok(res, 'Language deleted successfully'); | |
}) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Update Languages | |
app.put( | |
'/api/data/languages', | |
acl.hasPermission('languages:update'), | |
function (req, res) { | |
for (var i = 0; i < req.body.length; i++) { | |
var language = req.body[i]; | |
if (!language.locale || !language.language) { | |
Response.BadParameters( | |
res, | |
'Missing required parameters: locale, language', | |
); | |
return; | |
} | |
if ( | |
!utils.validFilename(language.language) || | |
!utils.validFilename(language.locale) | |
) { | |
Response.BadParameters( | |
res, | |
"language and locale value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
} | |
var languages = []; | |
req.body.forEach(e => { | |
languages.push({ language: e.language, locale: e.locale }); | |
}); | |
Language.updateAll(languages) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
/* ===== AUDIT TYPES ===== */ | |
// Get audit types list | |
app.get( | |
'/api/data/audit-types', | |
acl.hasPermission('audit-types:read'), | |
function (req, res) { | |
AuditType.getAll() | |
.then(msg => Response.Ok(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Create audit type | |
app.post( | |
'/api/data/audit-types', | |
acl.hasPermission('audit-types:create'), | |
function (req, res) { | |
if (!req.body.name || !req.body.templates) { | |
Response.BadParameters( | |
res, | |
'Missing required parameters: name, templates', | |
); | |
return; | |
} | |
if (!utils.validFilename(req.body.name)) { | |
Response.BadParameters( | |
res, | |
"name and locale value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
var auditType = {}; | |
auditType.stage = 'default'; | |
// Required parameters | |
auditType.name = req.body.name; | |
auditType.templates = req.body.templates; | |
// Optional parameters | |
if (req.body.sections) auditType.sections = req.body.sections; | |
if (req.body.hidden) auditType.hidden = req.body.hidden; | |
if ( | |
req.body.stage && | |
(req.body.stage === 'multi' || req.body.stage === 'retest') | |
) | |
auditType.stage = req.body.stage; | |
// Fix hidden sections for multi and retest audits | |
if (auditType.stage === 'multi' || auditType.stage === 'retest') | |
auditType.hidden = ['network']; | |
AuditType.create(auditType) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Delete audit type | |
app.delete( | |
'/api/data/audit-types/:name(*)', | |
acl.hasPermission('audit-types:delete'), | |
function (req, res) { | |
AuditType.delete(req.params.name) | |
.then(msg => { | |
Response.Ok(res, 'Audit type deleted successfully'); | |
}) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Update Audit Types | |
app.put( | |
'/api/data/audit-types', | |
acl.hasPermission('audit-types:update'), | |
function (req, res) { | |
for (var i = 0; i < req.body.length; i++) { | |
var auditType = req.body[i]; | |
if (!auditType.name || !auditType.templates) { | |
Response.BadParameters( | |
res, | |
'Missing required parameters: name, templates', | |
); | |
return; | |
} | |
if (!utils.validFilename(auditType.name)) { | |
Response.BadParameters( | |
res, | |
"name and locale value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
} | |
var auditTypes = []; | |
req.body.forEach(e => { | |
// Fix hidden sections for multi and retest audits | |
if (e.stage === 'multi' || e.stage === 'retest') | |
auditTypes.push({ | |
name: e.name, | |
templates: e.templates, | |
sections: e.sections, | |
hidden: ['network'], | |
stage: e.stage, | |
}); | |
else | |
auditTypes.push({ | |
name: e.name, | |
templates: e.templates, | |
sections: e.sections, | |
hidden: e.hidden, | |
stage: 'default', | |
}); | |
}); | |
AuditType.updateAll(auditTypes) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
/* ===== VULNERABILITY TYPES ===== */ | |
// Get vulnerability types list | |
app.get( | |
'/api/data/vulnerability-types', | |
acl.hasPermission('vulnerability-types:read'), | |
function (req, res) { | |
VulnerabilityType.getAll() | |
.then(msg => Response.Ok(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Create vulnerability type | |
app.post( | |
'/api/data/vulnerability-types', | |
acl.hasPermission('vulnerability-types:create'), | |
function (req, res) { | |
if (!req.body.name || !req.body.locale) { | |
Response.BadParameters( | |
res, | |
'Missing required parameters: name, locale', | |
); | |
return; | |
} | |
if ( | |
!utils.validFilename(req.body.name) || | |
!utils.validFilename(req.body.locale) | |
) { | |
Response.BadParameters( | |
res, | |
"name and locale value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
var vulnType = {}; | |
vulnType.name = req.body.name; | |
vulnType.locale = req.body.locale; | |
VulnerabilityType.create(vulnType) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Delete vulnerability type | |
app.delete( | |
'/api/data/vulnerability-types/:name(*)', | |
acl.hasPermission('vulnerability-types:delete'), | |
function (req, res) { | |
VulnerabilityType.delete(req.params.name) | |
.then(msg => { | |
Response.Ok(res, 'Vulnerability type deleted successfully'); | |
}) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Update Vulnerability Types | |
app.put( | |
'/api/data/vulnerability-types', | |
acl.hasPermission('vulnerability-types:update'), | |
function (req, res) { | |
for (var i = 0; i < req.body.length; i++) { | |
var vulnType = req.body[i]; | |
if (!vulnType.name || !vulnType.locale) { | |
Response.BadParameters( | |
res, | |
'Missing required parameters: name, locale', | |
); | |
return; | |
} | |
if ( | |
!utils.validFilename(vulnType.name) || | |
!utils.validFilename(vulnType.locale) | |
) { | |
Response.BadParameters( | |
res, | |
"name and locale value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
} | |
var vulnTypes = []; | |
req.body.forEach(e => { | |
vulnTypes.push({ name: e.name, locale: e.locale }); | |
}); | |
VulnerabilityType.updateAll(vulnTypes) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
/* ===== VULNERABILITY CATEGORY ===== */ | |
// Get vulnerability category list | |
app.get( | |
'/api/data/vulnerability-categories', | |
acl.hasPermission('vulnerability-categories:read'), | |
function (req, res) { | |
VulnerabilityCategory.getAll() | |
.then(msg => Response.Ok(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Create vulnerability category | |
app.post( | |
'/api/data/vulnerability-categories', | |
acl.hasPermission('vulnerability-categories:create'), | |
function (req, res) { | |
if (!req.body.name) { | |
Response.BadParameters(res, 'Missing required parameters: name'); | |
return; | |
} | |
if (!utils.validFilename(req.body.name)) { | |
Response.BadParameters( | |
res, | |
"name value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
var vulnCat = {}; | |
// Required parameters | |
vulnCat.name = req.body.name; | |
// Optional parameters | |
if (!_.isNil(req.body.sortValue)) vulnCat.sortValue = req.body.sortValue; | |
if (!_.isNil(req.body.sortOrder)) vulnCat.sortOrder = req.body.sortOrder; | |
if (!_.isNil(req.body.sortAuto)) vulnCat.sortAuto = req.body.sortAuto; | |
VulnerabilityCategory.create(vulnCat) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Update Vulnerability Category | |
app.put( | |
'/api/data/vulnerability-categories', | |
acl.hasPermission('vulnerability-categories:update'), | |
function (req, res) { | |
for (var i = 0; i < req.body.length; i++) { | |
var vulnCat = req.body[i]; | |
if (!vulnCat.name) { | |
Response.BadParameters(res, 'Missing required parameters: name'); | |
return; | |
} | |
if (!utils.validFilename(vulnCat.name)) { | |
Response.BadParameters( | |
res, | |
"name value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
} | |
var vulnCategories = []; | |
req.body.forEach(e => { | |
// Required parameters | |
var tmpCat = { name: e.name }; | |
// Optional parameters | |
if (!_.isNil(e.sortValue)) tmpCat.sortValue = e.sortValue; | |
if (!_.isNil(e.sortOrder)) tmpCat.sortOrder = e.sortOrder; | |
if (!_.isNil(e.sortAuto)) tmpCat.sortAuto = e.sortAuto; | |
vulnCategories.push(tmpCat); | |
}); | |
VulnerabilityCategory.updateAll(vulnCategories) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Delete vulnerability category | |
app.delete( | |
'/api/data/vulnerability-categories/:name(*)', | |
acl.hasPermission('vulnerability-categories:delete'), | |
function (req, res) { | |
VulnerabilityCategory.delete(req.params.name) | |
.then(msg => { | |
Response.Ok(res, 'Vulnerability category deleted successfully'); | |
}) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
/* ===== SECTIONS ===== */ | |
// Get sections list | |
app.get( | |
'/api/data/sections', | |
acl.hasPermission('sections:read'), | |
function (req, res) { | |
CustomSection.getAll() | |
.then(msg => Response.Ok(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Create section | |
app.post( | |
'/api/data/sections', | |
acl.hasPermission('sections:create'), | |
function (req, res) { | |
if (!req.body.field || !req.body.name) { | |
Response.BadParameters(res, 'Missing required parameters: field, name'); | |
return; | |
} | |
if ( | |
!utils.validFilename(req.body.field) || | |
!utils.validFilename(req.body.name) | |
) { | |
Response.BadParameters( | |
res, | |
"name and field value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
var section = {}; | |
section.field = req.body.field; | |
section.name = req.body.name; | |
section.locale = req.body.locale; | |
// Optional parameters | |
if (req.body.text) section.text = req.body.text; | |
if (req.body.icon) section.icon = req.body.icon; | |
CustomSection.create(section) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Delete section | |
app.delete( | |
'/api/data/sections/:field/:locale(*)', | |
acl.hasPermission('sections:delete'), | |
function (req, res) { | |
CustomSection.delete(req.params.field, req.params.locale) | |
.then(msg => { | |
Response.Ok(res, 'Section deleted successfully'); | |
}) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Update sections | |
app.put( | |
'/api/data/sections', | |
acl.hasPermission('sections:update'), | |
function (req, res) { | |
for (var i = 0; i < req.body.length; i++) { | |
var section = req.body[i]; | |
if (!section.name || !section.field) { | |
Response.BadParameters( | |
res, | |
'Missing required parameters: name, field', | |
); | |
return; | |
} | |
if ( | |
!utils.validFilename(section.name) || | |
!utils.validFilename(section.field) | |
) { | |
Response.BadParameters( | |
res, | |
"name and field value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
} | |
var sections = []; | |
req.body.forEach(e => { | |
sections.push({ name: e.name, field: e.field, icon: e.icon || '' }); | |
}); | |
CustomSection.updateAll(sections) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
/* ===== CUSTOM FIELDS ===== */ | |
// Get custom fields | |
app.get( | |
'/api/data/custom-fields', | |
acl.hasPermission('custom-fields:read'), | |
function (req, res) { | |
CustomField.getAll() | |
.then(msg => Response.Ok(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Create custom field | |
app.post( | |
'/api/data/custom-fields', | |
acl.hasPermission('custom-fields:create'), | |
function (req, res) { | |
if ( | |
(!req.body.fieldType || !req.body.label || !req.body.display) && | |
req.body.fieldType !== 'space' | |
) { | |
Response.BadParameters( | |
res, | |
'Missing required parameters: fieldType, label, display', | |
); | |
return; | |
} | |
if ( | |
(!utils.validFilename(req.body.fieldType) || | |
!utils.validFilename(req.body.label)) && | |
req.body.fieldType !== 'space' | |
) { | |
Response.BadParameters( | |
res, | |
"name and field value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
var customField = {}; | |
customField.fieldType = req.body.fieldType; | |
customField.label = req.body.label; | |
customField.display = req.body.display; | |
if (req.body.displaySub) customField.displaySub = req.body.displaySub; | |
if (req.body.size) customField.size = req.body.size; | |
if (req.body.offset) customField.offset = req.body.offset; | |
if ( | |
typeof req.body.required === 'boolean' && | |
req.body.fieldType !== 'space' | |
) | |
customField.required = req.body.required; | |
if (req.body.description) customField.description = req.body.description; | |
if (req.body.text) customField.text = req.body.text; | |
if (req.body.options) customField.options = req.body.options; | |
if (typeof req.body.position === 'number') | |
customField.position = req.body.position; | |
CustomField.create(customField) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Update custom fields | |
app.put( | |
'/api/data/custom-fields', | |
acl.hasPermission('custom-fields:update'), | |
function (req, res) { | |
for (var i = 0; i < req.body.length; i++) { | |
var customField = req.body[i]; | |
if ( | |
(!customField.label || !customField._id || !customField.display) && | |
customField.fieldType !== 'space' | |
) { | |
Response.BadParameters( | |
res, | |
'Missing required parameters: _id, label, display', | |
); | |
return; | |
} | |
if ( | |
!utils.validFilename( | |
customField.label || !utils.validFilename(customField.fieldType), | |
) && | |
customField.fieldType !== 'space' | |
) { | |
Response.BadParameters( | |
res, | |
"label and fieldType value must match /^[p{Letter}p{Mark}0-9 []'()_-]+$/iu", | |
); | |
return; | |
} | |
} | |
var customFields = []; | |
req.body.forEach(e => { | |
var field = { _id: e._id, label: e.label, display: e.display }; | |
if (typeof e.size === 'number') field.size = e.size; | |
if (typeof e.offset === 'number') field.offset = e.offset; | |
if (typeof e.required === 'boolean') field.required = e.required; | |
if (!_.isNil(e.description)) field.description = e.description; | |
if (!_.isNil(e.text)) field.text = e.text; | |
if (isArray(e.options)) field.options = e.options; | |
if (typeof e.position === 'number') field.position = e.position; | |
customFields.push(field); | |
}); | |
CustomField.updateAll(customFields) | |
.then(msg => Response.Created(res, msg)) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
// Delete custom field | |
app.delete( | |
'/api/data/custom-fields/:fieldId', | |
acl.hasPermission('custom-fields:delete'), | |
function (req, res) { | |
CustomField.delete(req.params.fieldId) | |
.then(msg => { | |
Response.Ok(res, msg); | |
}) | |
.catch(err => Response.Internal(res, err)); | |
}, | |
); | |
}; | |