diff --git a/src/api.ts b/src/api.ts index 80ab5a8..77f803b 100644 --- a/src/api.ts +++ b/src/api.ts @@ -4,22 +4,22 @@ import jsonRefParser, {JSONSchema} from '@apidevtools/json-schema-ref-parser'; import oasParser from '@apidevtools/swagger-parser'; -// modified from https://github.com/scottie1984/swagger-ui-express -// usage: app.use('/api-doc', api.serve(), api.setup()); -// the paths property can be split using allOf -// further route documentation can be included in the x-doc property +// Modified from https://github.com/scottie1984/swagger-ui-express +// Usage: app.use('/api-doc', api.serve(), api.setup()); +// The paths property can be split using allOf +// Further route documentation can be included in the x-doc property export default function api () { - // generate apiDoc + // Generate apiDoc let apiDoc: JSONSchema = {}; - jsonRefParser.bundle('api/api.yaml', (err, doc) => { // parse yaml + jsonRefParser.bundle('api/api.yaml', (err, doc) => { // Parse yaml if (err) throw err; apiDoc = doc; apiDoc.servers.splice(process.env.NODE_ENV === 'production', 1); - apiDoc.paths = apiDoc.paths.allOf.reduce((s, e) => Object.assign(s, e)); // bundle routes + apiDoc.paths = apiDoc.paths.allOf.reduce((s, e) => Object.assign(s, e)); // Bundle routes apiDoc = resolveXDoc(apiDoc); - oasParser.validate(apiDoc, (err, api) => { // validate oas schema + oasParser.validate(apiDoc, (err, api) => { // Validate oas schema if (err) { console.error(err); } @@ -30,7 +30,7 @@ export default function api () { }); return [ - (req, res, next) => { // serve init js and apiDoc file + (req, res, next) => { // Serve init js and apiDoc file switch (req.url) { case '/swagger-ui-init.js': res.set('Content-Type', 'application/javascript'); @@ -43,21 +43,21 @@ export default function api () { default: next(); } - }, // serve swagger files + }, // Serve swagger files express.static(swaggerUi.getAbsoluteFSPath(), {index: false}), - (req, res) => { // serve html file as default + (req, res) => { // Serve html file as default res.send(htmlTplString); } ]; } -function resolveXDoc (doc) { // resolve x-doc properties recursively +function resolveXDoc (doc) { // Resolve x-doc properties recursively Object.keys(doc).forEach(key => { - if (doc[key] !== null && doc[key].hasOwnProperty('x-doc')) { // add x-doc to description, is styled via css + if (doc[key] !== null && doc[key].hasOwnProperty('x-doc')) { // Add x-doc to description, is styled via css doc[key].description += '
docs' + doc[key]['x-doc'] + '
'; } - else if (typeof doc[key] === 'object' && doc[key] !== null) { // go deeper into recursion + else if (typeof doc[key] === 'object' && doc[key] !== null) { // Go deeper into recursion doc[key] = resolveXDoc(doc[key]); } }); @@ -65,9 +65,9 @@ function resolveXDoc (doc) { // resolve x-doc properties recursively } -// templates +// Templates -// noinspection LongLine +// Noinspection LongLine const htmlTplString = ` diff --git a/src/db.ts b/src/db.ts index b82151d..5c44fa5 100644 --- a/src/db.ts +++ b/src/db.ts @@ -5,29 +5,29 @@ import ChangelogModel from './models/changelog'; import cron from 'node-cron'; -// database urls, prod db url is retrieved automatically +// Database urls, prod db url is retrieved automatically const TESTING_URL = 'mongodb://localhost/dfopdb_test'; const DEV_URL = 'mongodb://localhost/dfopdb'; const debugging = true; -const changelogKeepDays = 30; // days to keep the changelog +const changelogKeepDays = 30; // Days to keep the changelog if (process.env.NODE_ENV !== 'production' && debugging) { - mongoose.set('debug', true); // enable mongoose debug + mongoose.set('debug', true); // Enable mongoose debug } export default class db { - private static state = { // db object and current mode (test, dev, prod) + private static state = { // Db object and current mode (test, dev, prod) db: null, mode: null, }; - // set mode to test for unit/integration tests, otherwise skip parameters. done is also only needed for testing + // Set mode to test for unit/integration tests, otherwise skip parameters. done is also only needed for testing static connect (mode = '', done: Function = () => {}) { - if (this.state.db) return done(); // db is already connected + if (this.state.db) return done(); // Db is already connected - // find right connection url + // Find right connection url let connectionString: string = ""; - if (mode === 'test') { // testing + if (mode === 'test') { // Testing connectionString = TESTING_URL; this.state.mode = 'test'; } @@ -45,7 +45,7 @@ export default class db { this.state.mode = 'dev'; } - // connect to db + // Connect to db mongoose.connect(connectionString, { useNewUrlParser: true, useUnifiedTopology: true, @@ -55,19 +55,19 @@ export default class db { if (err) done(err); }); mongoose.connection.on('error', console.error.bind(console, 'connection error:')); - mongoose.connection.on('connected', () => { // evaluation connection behaviour on prod + mongoose.connection.on('connected', () => { // Evaluation connection behaviour on prod if (process.env.NODE_ENV !== 'test') { // Do not interfere with testing console.info('Database connected'); } }); - mongoose.connection.on('disconnected', () => { // reset state on disconnect + mongoose.connection.on('disconnected', () => { // Reset state on disconnect if (process.env.NODE_ENV !== 'test') { // Do not interfere with testing console.info('Database disconnected'); - // this.state.db = 0; // prod database connects and disconnects automatically + // This.state.db = 0; // prod database connects and disconnects automatically } }); - process.on('SIGINT', () => { // close connection when app is terminated - if (!this.state.db) { // database still connected + process.on('SIGINT', () => { // Close connection when app is terminated + if (!this.state.db) { // Database still connected mongoose.connection.close(() => { console.info('Mongoose default connection disconnected through app termination'); process.exit(0); @@ -81,9 +81,9 @@ export default class db { done(); }); - if (mode !== 'test') { // clear old changelog regularly + if (mode !== 'test') { // Clear old changelog regularly cron.schedule('0 0 * * *', () => { - ChangelogModel.deleteMany({_id: {$lt: // id from time + ChangelogModel.deleteMany({_id: {$lt: // Id from time Math.floor(new Date().getTime() / 1000 - changelogKeepDays * 24 * 60 * 60).toString(16) + '0000000000000000' }}).lean().exec(err => { if (err) console.error(err); @@ -104,18 +104,18 @@ export default class db { return this.state; } - // drop all collections of connected db (only dev and test for safety reasons) + // Drop all collections of connected db (only dev and test for safety reasons) static drop (done: Function = () => {}) { - if (!this.state.db || this.state.mode === 'prod') return done(); // no db connection or prod db - this.state.db.db.listCollections().toArray((err, collections) => { // get list of all collections - if (collections.length === 0) { // there are no collections to drop + if (!this.state.db || this.state.mode === 'prod') return done(); // No db connection or prod db + this.state.db.db.listCollections().toArray((err, collections) => { // Get list of all collections + if (collections.length === 0) { // There are no collections to drop return done(); } else { - let dropCounter = 0; // count number of dropped collections to know when to return done() - collections.forEach(collection => { // drop each collection + let dropCounter = 0; // Count number of dropped collections to know when to return done() + collections.forEach(collection => { // Drop each collection this.state.db.dropCollection(collection.name, () => { - if (++ dropCounter >= collections.length) { // all collections dropped + if (++ dropCounter >= collections.length) { // All collections dropped done(); } }); @@ -124,21 +124,21 @@ export default class db { }); } - static loadJson (json, done: Function = () => {}) { // insert given JSON data into db, uses core mongodb methods - // no db connection or nothing to load + static loadJson (json, done: Function = () => {}) { // Insert given JSON data into db, uses core mongodb methods + // No db connection or nothing to load if (!this.state.db || !json.hasOwnProperty('collections') || json.collections.length === 0) { return done(); } - let loadCounter = 0; // count number of loaded collections to know when to return done() - Object.keys(json.collections).forEach(collectionName => { // create each collection + let loadCounter = 0; // Count number of loaded collections to know when to return done() + Object.keys(json.collections).forEach(collectionName => { // Create each collection json.collections[collectionName] = this.oidResolve(json.collections[collectionName]); this.state.db.createCollection(collectionName, (err, collection) => { if (err) { console.error(err); } - collection.insertMany(json.collections[collectionName], () => { // insert JSON data - if (++ loadCounter >= Object.keys(json.collections).length) { // all collections loaded + collection.insertMany(json.collections[collectionName], () => { // Insert JSON data + if (++ loadCounter >= Object.keys(json.collections).length) { // All collections loaded done(); } }); @@ -146,11 +146,11 @@ export default class db { }); } - // changelog entry, expects (req, this (from query helper)) or (req, collection, conditions, data) + // Changelog entry, expects (req, this (from query helper)) or (req, collection, conditions, data) static log(req, thisOrCollection, conditions = null, data = null) { if (! (conditions || data)) { // (req, this) - data = thisOrCollection._update ? _.cloneDeep(thisOrCollection._update) : {}; // replace undefined with {} - // replace keys with a leading $ + data = thisOrCollection._update ? _.cloneDeep(thisOrCollection._update) : {}; // Replace undefined with {} + // Replace keys with a leading $ Object.keys(data).forEach(key => { if (key[0] === '$') { data[key.substr(1)] = data[key]; @@ -180,19 +180,19 @@ export default class db { } } - private static oidResolve (object: any) { // resolve $oid fields to actual ObjectIds recursively + private static oidResolve (object: any) { // Resolve $oid fields to actual ObjectIds recursively Object.keys(object).forEach(key => { - if (object[key] !== null && object[key].hasOwnProperty('$oid')) { // found oid, replace + if (object[key] !== null && object[key].hasOwnProperty('$oid')) { // Found oid, replace object[key] = mongoose.Types.ObjectId(object[key].$oid); } - else if (typeof object[key] === 'object' && object[key] !== null) { // deeper into recursion + else if (typeof object[key] === 'object' && object[key] !== null) { // Deeper into recursion object[key] = this.oidResolve(object[key]); } }); return object; } - private static logEscape(obj) { // replace MongoDB control characters in keys + private static logEscape(obj) { // Replace MongoDB control characters in keys if (Object(obj) === obj && Object.keys(obj).length > 0) { Object.keys(obj).forEach(key => { const safeKey = key.replace(/[$.]/g, ''); diff --git a/src/globals.ts b/src/globals.ts index 037f25f..3ee99fb 100644 --- a/src/globals.ts +++ b/src/globals.ts @@ -1,8 +1,8 @@ -// globals for required names in the database. change values here to rename these properties -// the keys are the terms used internally, the values can be changed to other terms used in database and output +// Globals for required names in the database. change values here to rename these properties +// The keys are the terms used internally, the values can be changed to other terms used in database and output const globals = { - levels: { // access levels, sorted asc by rights + levels: { // Access levels, sorted asc by rights predict: 'predict', read: 'read', write: 'write', @@ -10,13 +10,13 @@ const globals = { admin: 'admin' }, - status: { // names of the document statuses + status: { // Names of the document statuses del: 'deleted', new: 'new', val: 'validated', }, - spectrum: { // names of required spectrum fields + spectrum: { // Names of required spectrum fields spectrum: 'spectrum', dpt: 'dpt' } diff --git a/src/helpers/authorize.ts b/src/helpers/authorize.ts index 82573c8..a83a972 100644 --- a/src/helpers/authorize.ts +++ b/src/helpers/authorize.ts @@ -4,22 +4,22 @@ import UserModel from '../models/user'; import globals from '../globals'; -// appends req.auth(res, ['levels'], method = 'all') -// which returns sends error message and returns false if unauthorized, otherwise true -// req.authDetails returns eg. {methods: ['basic'], username: 'johndoe', level: 'write'} +// Appends req.auth(res, ['levels'], method = 'all') +// Which returns sends error message and returns false if unauthorized, otherwise true +// Req.authDetails returns eg. {methods: ['basic'], username: 'johndoe', level: 'write'} module.exports = async (req, res, next) => { - let givenMethod = ''; // authorization method given by client, basic taken preferred - let user = {name: '', level: '', id: '', location: '', models: []}; // user object + let givenMethod = ''; // Authorization method given by client, basic taken preferred + let user = {name: '', level: '', id: '', location: '', models: []}; // User object - // test authentications + // Test authentications const userBasic = await basic(req, next); - if (userBasic) { // basic available + if (userBasic) { // Basic available givenMethod = 'basic'; user = userBasic; } - else { // if basic not available, test key + else { // If basic not available, test key const userKey = await key(req, next); if (userKey) { givenMethod = 'key'; @@ -28,8 +28,8 @@ module.exports = async (req, res, next) => { } req.auth = (res, levels, method = 'all') => { - if (givenMethod === method || (method === 'all' && givenMethod !== '')) { // method is available - if (levels.indexOf(user.level) > -1) { // level is available + if (givenMethod === method || (method === 'all' && givenMethod !== '')) { // Method is available + if (levels.indexOf(user.level) > -1) { // Level is available return true; } else { @@ -56,16 +56,16 @@ module.exports = async (req, res, next) => { } -function basic (req, next): any { // checks basic auth and returns changed user object +function basic (req, next): any { // Checks basic auth and returns changed user object return new Promise(resolve => { const auth = basicAuth(req); - if (auth !== undefined) { // basic auth available - UserModel.find({name: auth.name, status: globals.status.new}).lean().exec( (err, data: any) => { // find user + if (auth !== undefined) { // Basic auth available + UserModel.find({name: auth.name, status: globals.status.new}).lean().exec( (err, data: any) => { // Find user if (err) return next(err); - if (data.length === 1) { // one user found - bcrypt.compare(auth.pass, data[0].pass, (err, res) => { // check password + if (data.length === 1) { // One user found + bcrypt.compare(auth.pass, data[0].pass, (err, res) => { // Check password if (err) return next(err); - if (res === true) { // password correct + if (res === true) { // Password correct resolve({ level: Object.entries(globals.levels).find(e => e[1] === data[0].level)[0], name: data[0].name, @@ -90,12 +90,12 @@ function basic (req, next): any { // checks basic auth and returns changed user }); } -function key (req, next): any { // checks API key and returns changed user object +function key (req, next): any { // Checks API key and returns changed user object return new Promise(resolve => { - if (req.query.key !== undefined) { // key available - UserModel.find({key: req.query.key, status: globals.status.new}).lean().exec( (err, data: any) => { // find user + if (req.query.key !== undefined) { // Key available + UserModel.find({key: req.query.key, status: globals.status.new}).lean().exec( (err, data: any) => { // Find user if (err) return next(err); - if (data.length === 1) { // one user found + if (data.length === 1) { // One user found resolve({ level: Object.entries(globals.levels).find(e => e[1] === data[0].level)[0], name: data[0].name, @@ -104,7 +104,7 @@ function key (req, next): any { // checks API key and returns changed user obje models: data[0].models }); if (!/^\/api/m.test(req.url)){ - delete req.query.key; // delete query parameter to avoid interference with later validation + delete req.query.key; // Delete query parameter to avoid interference with later validation } } else { diff --git a/src/helpers/csv.ts b/src/helpers/csv.ts index d5b16ab..eb9e13e 100644 --- a/src/helpers/csv.ts +++ b/src/helpers/csv.ts @@ -1,7 +1,7 @@ import {parseAsync} from 'json2csv'; import flatten from './flatten'; -export default function csv(input: any[], f: (err, data) => void) { // parse JSON to CSV +export default function csv(input: any[], f: (err, data) => void) { // Parse JSON to CSV parseAsync(input.map(e => flatten(e)), {includeEmptyRows: true}) .then(csv => f(null, csv)) .catch(err => f(err, null)); diff --git a/src/helpers/flatten.ts b/src/helpers/flatten.ts index 54c07c8..463a29f 100644 --- a/src/helpers/flatten.ts +++ b/src/helpers/flatten.ts @@ -1,12 +1,12 @@ import globals from '../globals'; -export default function flatten (data, keepArray = false) { // flatten object: {a: {b: true}} -> {a.b: true} +export default function flatten (data, keepArray = false) { // Flatten object: {a: {b: true}} -> {a.b: true} const result = {}; function recurse (cur, prop) { - if (Object(cur) !== cur || Object.keys(cur).length === 0) { // simple value + if (Object(cur) !== cur || Object.keys(cur).length === 0) { // Simple value result[prop] = cur; } - else if (prop === `${globals.spectrum.spectrum}.${globals.spectrum.dpt}`) { // convert spectrum for ML + else if (prop === `${globals.spectrum.spectrum}.${globals.spectrum.dpt}`) { // Convert spectrum for ML result[prop + '.labels'] = cur.map(e => parseFloat(e[0])); result[prop + '.values'] = cur.map(e => parseFloat(e[1])); } @@ -14,8 +14,8 @@ export default function flatten (data, keepArray = false) { // flatten object: if (keepArray) { result[prop] = cur; } - else { // array to string - if (cur.length && (Object(cur[0]) !== cur || Object.keys(cur[0]).length === 0)) { // array of non-objects + else { // Array to string + if (cur.length && (Object(cur[0]) !== cur || Object.keys(cur[0]).length === 0)) { // Array of non-objects result[prop] = '[' + cur.join(', ') + ']'; } else { @@ -27,7 +27,7 @@ export default function flatten (data, keepArray = false) { // flatten object: } } } - else { // object + else { // Object let isEmpty = true; for (let p in cur) { isEmpty = false; diff --git a/src/helpers/mail.ts b/src/helpers/mail.ts index 1fdf01e..9aa0671 100644 --- a/src/helpers/mail.ts +++ b/src/helpers/mail.ts @@ -1,36 +1,36 @@ import axios from 'axios'; -// sends an email using the BIC service +// Sends an email using the BIC service export default class Mail{ - static readonly address = 'definma@bosch-iot.com'; // email address - static uri: string; // mail API URI - static auth = {username: '', password: ''}; // mail API credentials - static mailPass: string; // mail API generates password + static readonly address = 'definma@bosch-iot.com'; // Email address + static uri: string; // Mail API URI + static auth = {username: '', password: ''}; // Mail API credentials + static mailPass: string; // Mail API generates password static init() { - if (process.env.NODE_ENV === 'production') { // only send mails in production + if (process.env.NODE_ENV === 'production') { // Only send mails in production this.mailPass = Array(64).fill(0).map(() => Math.floor(Math.random() * 10)).join(''); this.uri = JSON.parse(process.env.VCAP_SERVICES).Mail[0].credentials.uri; this.auth.username = JSON.parse(process.env.VCAP_SERVICES).Mail[0].credentials.username; this.auth.password = JSON.parse(process.env.VCAP_SERVICES).Mail[0].credentials.password; - axios({ // get registered mail addresses + axios({ // Get registered mail addresses method: 'get', url: this.uri + '/management/userDomainMapping', auth: this.auth }).then(res => { return new Promise(async (resolve, reject) => { try { - if (res.data.addresses.indexOf(this.address) < 0) { // mail address not registered - if (res.data.addresses.length) { // delete wrong registered mail address + if (res.data.addresses.indexOf(this.address) < 0) { // Mail address not registered + if (res.data.addresses.length) { // Delete wrong registered mail address await axios({ method: 'delete', url: this.uri + '/management/mailAddresses/' + res.data.addresses[0], auth: this.auth }); } - await axios({ // register right mail address + await axios({ // Register right mail address method: 'post', url: this.uri + '/management/mailAddresses/' + this.address, auth: this.auth @@ -43,22 +43,22 @@ export default class Mail{ } }); }).then(() => { - return axios({ // set new mail password + return axios({ // Set new mail password method: 'put', url: this.uri + '/management/mailAddresses/' + this.address + '/password/' + this.mailPass, auth: this.auth }); - }).then(() => { // init done successfully + }).then(() => { // Init done successfully console.info('Mail service established successfully'); - }).catch(err => { // somewhere an error occurred + }).catch(err => { // Somewhere an error occurred console.error(`Mail init error: ${err.request.method} ${err.request.path}: ${err.response.status}`, err.response.data); }); } } - static send (mailAddress, subject, content, f: (x?) => void = () => {}) { // callback executed empty or with error - if (process.env.NODE_ENV === 'production') { // only send mails in production + static send (mailAddress, subject, content, f: (x?) => void = () => {}) { // Callback executed empty or with error + if (process.env.NODE_ENV === 'production') { // Only send mails in production axios({ method: 'post', url: this.uri + '/email', @@ -81,7 +81,7 @@ export default class Mail{ f(err); }); } - else { // dev dummy replacement + else { // Dev dummy replacement console.info('Sending mail to ' + mailAddress + ': -- ' + subject + ' -- ' + content); f(); } diff --git a/src/index.ts b/src/index.ts index f64e847..d01d1aa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,24 +9,24 @@ import db from './db'; import Mail from './helpers/mail'; -// tell if server is running in debug or production environment +// Tell if server is running in debug or production environment console.info(process.env.NODE_ENV === 'production' ? '===== PRODUCTION =====' : process.env.NODE_ENV === 'test' ? '' :'===== DEVELOPMENT ====='); -// mongodb connection +// Mongodb connection db.connect(); -// mail service +// Mail service Mail.init(); -// create Express app +// Create Express app const app = express(); -// get port from environment, defaults to 3000 +// Get port from environment, defaults to 3000 const port = process.env.PORT || 3000; -// security headers +// Security headers const defaultHeaderConfig = { contentSecurityPolicy: { directives: { @@ -43,7 +43,7 @@ const defaultHeaderConfig = { refererPolicy: true }; app.use(helmet(defaultHeaderConfig)); -// special CSP header for api-doc +// Special CSP header for api-doc app.use('/api-doc', helmet.contentSecurityPolicy({ ...defaultHeaderConfig, directives: { @@ -54,7 +54,7 @@ app.use('/api-doc', helmet.contentSecurityPolicy({ imgSrc: [`'self'`, 'data:'] } })); -// special CSP header for the intro-presentation +// Special CSP header for the intro-presentation app.use(/\/static\/intro-presentation\/(index.html)?/, helmet.contentSecurityPolicy({ ...defaultHeaderConfig, directives: { @@ -64,7 +64,7 @@ app.use(/\/static\/intro-presentation\/(index.html)?/, helmet.contentSecurityPol imgSrc: [`'self'`] } })); -// special CSP header for the bosch-logo.svg +// Special CSP header for the bosch-logo.svg app.use('/static/*.svg', helmet.contentSecurityPolicy({ ...defaultHeaderConfig, directives: { @@ -72,8 +72,8 @@ app.use('/static/*.svg', helmet.contentSecurityPolicy({ } })); -// middleware -app.use(compression()); // compress responses +// Middleware +app.use(compression()); // Compress responses app.use(express.json({ limit: '5mb'})); app.use(express.urlencoded({ extended: false, limit: '5mb' })); app.use(bodyParser.json()); @@ -81,11 +81,11 @@ app.use(contentFilter({ urlBlackList: ['$', '&&', '||'], bodyBlackList: ['$', '{', '&&', '||'], appendFound: true -})); // filter URL query attacks -app.use((err, req, res, ignore) => { // bodyParser error handling +})); // Filter URL query attacks +app.use((err, req, res, ignore) => { // BodyParser error handling res.status(400).send({status: 'Invalid JSON body'}); }); -app.use((req, res, next) => { // no database connection error +app.use((req, res, next) => { // No database connection error if (db.getState().db) { next(); } @@ -95,12 +95,12 @@ app.use((req, res, next) => { // no database connection error } }); app.use(cors()); // CORS headers -app.use(require('./helpers/authorize')); // handle authentication +app.use(require('./helpers/authorize')); // Handle authentication -// redirect /api routes for Angular proxy in development +// Redirect /api routes for Angular proxy in development if (process.env.NODE_ENV !== 'production') { app.use('/api/:url([^]+)', (req, res) => { - if (/help\//.test(req.params.url)) { // encode URI again for help route + if (/help\//.test(req.params.url)) { // Encode URI again for help route req.params.url = 'help/' + encodeURIComponent(req.params.url.replace('help/', '')); } req.url = '/' + req.params.url; @@ -109,7 +109,7 @@ if (process.env.NODE_ENV !== 'production') { } -// require routes +// Require routes app.use('/', require('./routes/root')); app.use('/', require('./routes/sample')); app.use('/', require('./routes/material')); @@ -119,7 +119,7 @@ app.use('/', require('./routes/model')); app.use('/', require('./routes/user')); app.use('/', require('./routes/help')); -// static files +// Static files app.use('/static', express.static('static')); // Swagger UI @@ -129,13 +129,13 @@ app.use((req, res) => { // 404 error handling res.status(404).json({status: 'Not found'}); }); -app.use((err, req, res, ignore) => { // internal server error handling +app.use((err, req, res, ignore) => { // Internal server error handling console.error(err); res.status(500).json({status: 'Internal server error'}); }); -// hook up server to port +// Hook up server to port const server = app.listen(port, () => { console.info(process.env.NODE_ENV === 'test' ? '' : `Listening on http://localhost:${port}`); }); diff --git a/src/models/condition_template.ts b/src/models/condition_template.ts index ab80dfa..7748276 100644 --- a/src/models/condition_template.ts +++ b/src/models/condition_template.ts @@ -9,9 +9,9 @@ const ConditionTemplateSchema = new mongoose.Schema({ name: String, range: mongoose.Schema.Types.Mixed } ,{ _id : false })] -}, {minimize: false}); // to allow empty objects +}, {minimize: false}); // To allow empty objects -// changelog query helper +// Changelog query helper ConditionTemplateSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/help.ts b/src/models/help.ts index da5ee6d..77a3a3b 100644 --- a/src/models/help.ts +++ b/src/models/help.ts @@ -7,7 +7,7 @@ const HelpSchema = new mongoose.Schema({ text: String }, {minimize: false}); -// changelog query helper +// Changelog query helper HelpSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/material.ts b/src/models/material.ts index b36b51d..74c8c36 100644 --- a/src/models/material.ts +++ b/src/models/material.ts @@ -12,7 +12,7 @@ const MaterialSchema = new mongoose.Schema({ status: String }, {minimize: false}); -// changelog query helper +// Changelog query helper MaterialSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/material_groups.ts b/src/models/material_groups.ts index 6aba0e6..aeb608c 100644 --- a/src/models/material_groups.ts +++ b/src/models/material_groups.ts @@ -5,7 +5,7 @@ const MaterialGroupsSchema = new mongoose.Schema({ name: {type: String, index: {unique: true}} }); -// changelog query helper +// Changelog query helper MaterialGroupsSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/material_suppliers.ts b/src/models/material_suppliers.ts index 24cb102..5cb770c 100644 --- a/src/models/material_suppliers.ts +++ b/src/models/material_suppliers.ts @@ -5,7 +5,7 @@ const MaterialSuppliersSchema = new mongoose.Schema({ name: {type: String, index: {unique: true}} }); -// changelog query helper +// Changelog query helper MaterialSuppliersSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/material_template.ts b/src/models/material_template.ts index 3e75797..39ba13c 100644 --- a/src/models/material_template.ts +++ b/src/models/material_template.ts @@ -9,9 +9,9 @@ const MaterialTemplateSchema = new mongoose.Schema({ name: String, range: mongoose.Schema.Types.Mixed } ,{ _id : false })] -}, {minimize: false}); // to allow empty objects +}, {minimize: false}); // To allow empty objects -// changelog query helper +// Changelog query helper MaterialTemplateSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/measurement.ts b/src/models/measurement.ts index 55706fe..5304474 100644 --- a/src/models/measurement.ts +++ b/src/models/measurement.ts @@ -12,7 +12,7 @@ const MeasurementSchema = new mongoose.Schema({ status: String }, {minimize: false}); -// changelog query helper +// Changelog query helper MeasurementSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/measurement_template.ts b/src/models/measurement_template.ts index 19228c1..6c5ff18 100644 --- a/src/models/measurement_template.ts +++ b/src/models/measurement_template.ts @@ -9,9 +9,9 @@ const MeasurementTemplateSchema = new mongoose.Schema({ name: String, range: mongoose.Schema.Types.Mixed } ,{ _id : false })] -}, {minimize: false}); // to allow empty objects +}, {minimize: false}); // To allow empty objects -// changelog query helper +// Changelog query helper MeasurementTemplateSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/model.ts b/src/models/model.ts index 2059c98..d9e9339 100644 --- a/src/models/model.ts +++ b/src/models/model.ts @@ -10,7 +10,7 @@ const ModelSchema = new mongoose.Schema({ } ,{ _id : true })] }); -// changelog query helper +// Changelog query helper ModelSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/note.ts b/src/models/note.ts index 8df74a4..f626078 100644 --- a/src/models/note.ts +++ b/src/models/note.ts @@ -10,7 +10,7 @@ const NoteSchema = new mongoose.Schema({ custom_fields: mongoose.Schema.Types.Mixed }); -// changelog query helper +// Changelog query helper NoteSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/note_field.ts b/src/models/note_field.ts index 715e924..7495b42 100644 --- a/src/models/note_field.ts +++ b/src/models/note_field.ts @@ -6,7 +6,7 @@ const NoteFieldSchema = new mongoose.Schema({ qty: Number }); -// changelog query helper +// Changelog query helper NoteFieldSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/sample.ts b/src/models/sample.ts index 10df124..7dff559 100644 --- a/src/models/sample.ts +++ b/src/models/sample.ts @@ -17,7 +17,7 @@ const SampleSchema = new mongoose.Schema({ status: String }, {minimize: false}); -// changelog query helper +// Changelog query helper SampleSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/models/user.ts b/src/models/user.ts index d546bd2..a70791b 100644 --- a/src/models/user.ts +++ b/src/models/user.ts @@ -14,7 +14,7 @@ const UserSchema = new mongoose.Schema({ status: String }); -// changelog query helper +// Changelog query helper UserSchema.query.log = function > (req) { db.log(req, this); return this; diff --git a/src/routes/help.ts b/src/routes/help.ts index 9c56d81..12342dd 100644 --- a/src/routes/help.ts +++ b/src/routes/help.ts @@ -16,7 +16,7 @@ router.get('/help/:key', (req, res, next) => { if (!data) { return res.status(404).json({status: 'Not found'}); } - if (data.level !== 'none') { // check level + if (data.level !== 'none') { // Check level if (!req.auth(res, Object.values(globals.levels).slice(Object.values(globals.levels).findIndex(e => e === data.level)) , 'basic')) return; diff --git a/src/routes/material.ts b/src/routes/material.ts index de97245..11db596 100644 --- a/src/routes/material.ts +++ b/src/routes/material.ts @@ -29,7 +29,7 @@ router.get('/materials', (req, res, next) => { .lean().exec((err, data) => { if (err) return next(err); - // validate all and filter null values from validation errors + // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => MaterialValidate.output(e, true)))); }); }); @@ -41,7 +41,7 @@ router.get(`/materials/:state(${globals.status.new}|${globals.status.del})`, (re .lean().exec((err, data) => { if (err) return next(err); - // validate all and filter null values from validation errors + // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => MaterialValidate.output(e)))); }); }); @@ -56,7 +56,7 @@ router.get('/material/' + IdValidate.parameter(), (req, res, next) => { return res.status(404).json({status: 'Not found'}); } - // deleted materials only available for dev/admin + // Deleted materials only available for dev/admin if (data.status === globals.status.del && !req.auth(res, ['dev', 'admin'], 'all')) return; res.json(MaterialValidate.output(data)); }); @@ -91,9 +91,9 @@ router.put('/material/' + IdValidate.parameter(), (req, res, next) => { materialData.properties.material_template.toString() !== material.properties.material_template)) return; } - // check for changes + // Check for changes if (!_.isEqual(_.pick(IdValidate.stringify(materialData), _.keys(material)), IdValidate.stringify(material))) { - material.status = globals.status.new; // set status to new + material.status = globals.status.new; // Set status to new } await MaterialModel.findByIdAndUpdate(req.params.id, material, {new: true}) @@ -107,7 +107,7 @@ router.put('/material/' + IdValidate.parameter(), (req, res, next) => { router.delete('/material/' + IdValidate.parameter(), (req, res, next) => { if (!req.auth(res, ['write', 'dev', 'admin'], 'basic')) return; - // check if there are still samples referencing this material + // Check if there are still samples referencing this material SampleModel.find({'material_id': new mongoose.Types.ObjectId(req.params.id), status: {$ne: globals.status.del}}) .lean().exec((err, data) => { if (err) return next(err); @@ -152,7 +152,7 @@ router.post('/material/new', async (req, res, next) => { if (!material) return; if (!await propertiesCheck(material.properties, 'new', res, next)) return; - material.status = globals.status.new; // set status to new + material.status = globals.status.new; // Set status to new await new MaterialModel(material).save(async (err, data) => { if (err) return next(err); db.log(req, 'materials', {_id: data._id}, data.toObject()); @@ -168,7 +168,7 @@ router.get('/material/groups', (req, res, next) => { MaterialGroupModel.find().lean().exec((err, data: any) => { if (err) return next(err); - // validate all and filter null values from validation errors + // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => MaterialValidate.outputGroups(e.name)))); }); }); @@ -179,7 +179,7 @@ router.get('/material/suppliers', (req, res, next) => { MaterialSupplierModel.find().lean().exec((err, data: any) => { if (err) return next(err); - // validate all and filter null values from validation errors + // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => MaterialValidate.outputSuppliers(e.name)))); }); }); @@ -188,10 +188,10 @@ router.get('/material/suppliers', (req, res, next) => { module.exports = router; -async function nameCheck (material, res, next) { // check if name was already taken +async function nameCheck (material, res, next) { // Check if name was already taken const materialData = await MaterialModel.findOne({name: material.name}).lean().exec().catch(err => next(err)) as any; if (materialData instanceof Error) return false; -if (materialData) { // could not find material_id +if (materialData) { // Could not find material_id res.status(400).json({status: 'Material name already taken'}); return false; } @@ -222,32 +222,32 @@ async function supplierResolve (material, req, next) { return material; } -// validate material properties, returns false if invalid, otherwise template data +// Validate material properties, returns false if invalid, otherwise template data async function propertiesCheck (properties, param, res, next, checkVersion = true) { - if (!properties.material_template || !IdValidate.valid(properties.material_template)) { // template id not found + if (!properties.material_template || !IdValidate.valid(properties.material_template)) { // Template id not found res.status(400).json({status: 'Material template not available'}); return false; } const materialData = await MaterialTemplateModel.findById(properties.material_template) .lean().exec().catch(err => next(err)) as any; if (materialData instanceof Error) return false; - if (!materialData) { // template not found + if (!materialData) { // Template not found res.status(400).json({status: 'Material template not available'}); return false; } if (checkVersion) { - // get all template versions and check if given is latest + // Get all template versions and check if given is latest const materialVersions = await MaterialTemplateModel.find({first_id: materialData.first_id}).sort({version: -1}) .lean().exec().catch(err => next(err)) as any; if (materialVersions instanceof Error) return false; - if (properties.material_template !== materialVersions[0]._id.toString()) { // template not latest + if (properties.material_template !== materialVersions[0]._id.toString()) { // Template not latest res.status(400).json({status: 'Old template version not allowed'}); return false; } } - // validate parameters + // Validate parameters const {error, value} = ParametersValidate .input(_.omit(properties, 'material_template'), materialData.parameters, param); if (error) {res400(error, res); return false;} @@ -257,7 +257,7 @@ async function propertiesCheck (properties, param, res, next, checkVersion = tru return materialData; } -function setStatus (status, req, res, next) { // set measurement status +function setStatus (status, req, res, next) { // Set measurement status MaterialModel.findByIdAndUpdate(req.params.id, {status: status}).log(req).lean().exec((err, data) => { if (err) return next(err); diff --git a/src/routes/measurement.ts b/src/routes/measurement.ts index 863a067..458c95f 100644 --- a/src/routes/measurement.ts +++ b/src/routes/measurement.ts @@ -23,7 +23,7 @@ router.get('/measurement/' + IdValidate.parameter(), (req, res, next) => { if (!data) { return res.status(404).json({status: 'Not found'}); } - // deleted measurements only available for dev/admin + // Deleted measurements only available for dev/admin if (data.status === globals.status.del && !req.auth(res, ['dev', 'admin'], 'all')) return; res.json(MeasurementValidate.output(data, req)); @@ -45,16 +45,16 @@ router.put('/measurement/' + IdValidate.parameter(), async (req, res, next) => { return res.status(403).json({status: 'Forbidden'}); } - // add properties needed for sampleIdCheck + // Add properties needed for sampleIdCheck measurement.measurement_template = data.measurement_template; measurement.sample_id = data.sample_id; if (!await sampleIdCheck(measurement, req, res, next)) return; -// check for changes -if (measurement.values) { // fill not changed values from database +// Check for changes +if (measurement.values) { // Fill not changed values from database measurement.values = _.assign({}, data.values, measurement.values); if (!_.isEqual(measurement.values, data.values)) { - measurement.status = globals.status.new; // set status to new + measurement.status = globals.status.new; // Set status to new } } @@ -130,35 +130,35 @@ router.post('/measurement/new', async (req, res, next) => { module.exports = router; -// validate sample_id, returns false if invalid or user has no access for this sample +// Validate sample_id, returns false if invalid or user has no access for this sample async function sampleIdCheck (measurement, req, res, next) { const sampleData = await SampleModel.findById(measurement.sample_id) .lean().exec().catch(err => {next(err); return false;}) as any; - if (!sampleData) { // sample_id not found + if (!sampleData) { // Sample_id not found res.status(400).json({status: 'Sample id not available'}); return false } - // sample does not belong to user + // Sample does not belong to user return !(sampleData.user_id.toString() !== req.authDetails.id && !req.auth(res, ['dev', 'admin'], 'basic')); } -// validate measurement_template and values, returns values, true if values are {} or false if invalid, -// param for 'new'/'change' +// Validate measurement_template and values, returns values, true if values are {} or false if invalid, +// Param for 'new'/'change' async function templateCheck (measurement, param, res, next) { const templateData = await MeasurementTemplateModel.findById(measurement.measurement_template) .lean().exec().catch(err => {next(err); return false;}) as any; - if (!templateData) { // template not found + if (!templateData) { // Template not found res.status(400).json({status: 'Measurement template not available'}); return false } - // fill not given values for new measurements + // Fill not given values for new measurements if (param === 'new') { - // get all template versions and check if given is latest + // Get all template versions and check if given is latest const templateVersions = await MeasurementTemplateModel.find({first_id: templateData.first_id}).sort({version: -1}) .lean().exec().catch(err => next(err)) as any; if (templateVersions instanceof Error) return false; - if (measurement.measurement_template !== templateVersions[0]._id.toString()) { // template not latest + if (measurement.measurement_template !== templateVersions[0]._id.toString()) { // Template not latest res.status(400).json({status: 'Old template version not allowed'}); return false; } @@ -167,20 +167,20 @@ async function templateCheck (measurement, param, res, next) { res.status(400).json({status: 'At least one value is required'}); return false } - const fillValues = {}; // initialize not given values with null + const fillValues = {}; // Initialize not given values with null templateData.parameters.forEach(parameter => { fillValues[parameter.name] = null; }); measurement.values = _.assign({}, fillValues, measurement.values); } - // validate values + // Validate values const {error, value} = ParametersValidate.input(measurement.values, templateData.parameters, 'null'); if (error) {res400(error, res); return false;} return value || true; } -function setStatus (status, req, res, next) { // set measurement status +function setStatus (status, req, res, next) { // Set measurement status MeasurementModel.findByIdAndUpdate(req.params.id, {status: status}).log(req).lean().exec((err, data) => { if (err) return next(err); diff --git a/src/routes/model.ts b/src/routes/model.ts index 89a3f85..63cacfb 100644 --- a/src/routes/model.ts +++ b/src/routes/model.ts @@ -16,7 +16,7 @@ router.get('/model/groups', (req, res, next) => { if (!req.auth(res, ['predict', 'read', 'write', 'dev', 'admin'], 'basic')) return; let conditions: any = [{}, {}]; - if (['dev', 'admin'].indexOf(req.authDetails.level) < 0) { // if not dev or admin, user has to possess model rights + if (['dev', 'admin'].indexOf(req.authDetails.level) < 0) { // If not dev or admin, user has to possess model rights conditions = [ {'models._id': {$in: req.authDetails.models.map(e => mongoose.Types.ObjectId(e))}}, {group: true, 'models.$': true} @@ -25,7 +25,7 @@ router.get('/model/groups', (req, res, next) => { ModelModel.find(...conditions).lean().exec((err, data) => { if (err) return next(err); - // validate all and filter null values from validation errors + // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => ModelValidate.output(e)))); }); }); @@ -39,8 +39,8 @@ router.post('/model/:group', (req, res, next) => { ModelModel.findOne({group: req.params.group}).lean().exec((err, data) => { if (err) return next(err); - if (data) { // group exists - if (data.models.find(e => e.name === model.name)) { // name exists, overwrite + if (data) { // Group exists + if (data.models.find(e => e.name === model.name)) { // Name exists, overwrite ModelModel.findOneAndUpdate( {$and: [{group: req.params.group}, {'models.name': model.name}]}, {'models.$': model}, @@ -49,7 +49,7 @@ router.post('/model/:group', (req, res, next) => { res.json({status: 'OK'}) }); } - else { // create new + else { // Create new ModelModel.findOneAndUpdate( {group: req.params.group}, {$push: {models: model as never}} @@ -59,7 +59,7 @@ router.post('/model/:group', (req, res, next) => { }); } } - else { // create new group + else { // Create new group new ModelModel({group: req.params.group, models: [model]}).save((err, data) => { if (err) return next(err); db.log(req, 'models', {_id: data._id}, data.toObject()); @@ -78,11 +78,11 @@ router.delete('/model/:group(((?!file)[^\\/]+?))/:name', (req, res, next) => { if (!data || !data.models.find(e => e.name === req.params.name)) { return res.status(404).json({status: 'Not found'}); } - // delete all references in user.models + // Delete all references in user.models UserModel.updateMany({}, {$pull: {models: data.models.find(e => e.name === req.params.name)._id as never}}, { multi: true }).log(req).lean().exec(err => { if (err) return next(err); - if (data.models.length > 1) { // only remove model + if (data.models.length > 1) { // Only remove model ModelModel.findOneAndUpdate( {group: req.params.group}, {$pull: {models: data.models.find(e => e.name === req.params.name) as never}} @@ -91,7 +91,7 @@ router.delete('/model/:group(((?!file)[^\\/]+?))/:name', (req, res, next) => { res.json({status: 'OK'}) }); } - else { // remove document + else { // Remove document ModelModel.findOneAndDelete({group: req.params.group}).log(req).lean().exec(err => { if (err) return next(err); res.json({status: 'OK'}) @@ -152,7 +152,7 @@ router.delete('/model/file/:name', (req, res, next) => { router.get('/model/authorized/:url', (req, res, next) => { if (!req.auth(res, ['predict', 'read', 'write', 'dev', 'admin'], 'basic')) return; - if (['dev', 'admin'].indexOf(req.authDetails.level) < 0) { // if not dev or admin, user has to possess model rights + if (['dev', 'admin'].indexOf(req.authDetails.level) < 0) { // If not dev or admin, user has to possess model rights ModelModel.findOne({models: { $elemMatch: { url: decodeURIComponent(req.params.url), '_id': {$in: req.authDetails.models.map(e => mongoose.Types.ObjectId(e))} diff --git a/src/routes/root.spec.ts b/src/routes/root.spec.ts index d38546c..00b7144 100644 --- a/src/routes/root.spec.ts +++ b/src/routes/root.spec.ts @@ -208,7 +208,7 @@ describe('/', () => { }); }); - // describe('A not connected database', () => { // RUN AS LAST OR RECONNECT DATABASE!! + // Describe('A not connected database', () => { // RUN AS LAST OR RECONNECT DATABASE!! // it('resolves to an 500 error', done => { // db.disconnect(() => { // TestHelper.request(server, done, { @@ -223,7 +223,7 @@ describe('/', () => { describe('The /api/{url} redirect', () => { let server; - let counter = 0; // count number of current test method + let counter = 0; // Count number of current test method before(done => { process.env.port = '2999'; db.connect('test', done); @@ -246,7 +246,7 @@ describe('The /api/{url} redirect', () => { res: {status: 'Authorization successful', method: 'basic', level: 'admin', user_id: '000000000000000000000003'} }); }); - // it('is disabled in production', done => { + // It('is disabled in production', done => { // TestHelper.request(server, done, { // method: 'get', // url: '/api/authorized', diff --git a/src/routes/root.ts b/src/routes/root.ts index 86b76af..c243297 100644 --- a/src/routes/root.ts +++ b/src/routes/root.ts @@ -37,7 +37,7 @@ router.get('/changelog/:id/:page?/:pagesize?', (req, res, next) => { .lean().exec((err, data) => { if (err) return next(err); - // validate all and filter null values from validation errors + // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => RootValidate.changelogOutput(e)))); }); }); diff --git a/src/routes/sample.spec.ts b/src/routes/sample.spec.ts index 38ccfe3..d169116 100644 --- a/src/routes/sample.spec.ts +++ b/src/routes/sample.spec.ts @@ -1460,7 +1460,7 @@ describe('/sample', () => { }).end((err, res) => { if (err) return done(err); should(res.body).be.eql({status: 'OK'}); - setTimeout(() => { // background action takes some time before we can check + setTimeout(() => { // Background action takes some time before we can check NoteModel.findById('500000000000000000000003').lean().exec((err, data: any) => { if (err) return done(err); should(data).have.property('sample_references').with.lengthOf(1); diff --git a/src/routes/sample.ts b/src/routes/sample.ts index 8d47279..5ff8880 100644 --- a/src/routes/sample.ts +++ b/src/routes/sample.ts @@ -29,22 +29,22 @@ router.get('/samples', async (req, res, next) => { const {error, value: filters} = SampleValidate.query(req.query, ['dev', 'admin'].indexOf(req.authDetails.level) >= 0); if (error) return res400(error, res); - // spectral data and csv not allowed for read/write users + // Spectral data and csv not allowed for read/write users if ((filters.fields.find(e => e.indexOf('.' + globals.spectrum.dpt) >= 0) || filters.output !== 'json') && !req.auth(res, ['dev', 'admin'], 'all')) return; - // evaluate sort parameter from 'color-asc' to ['color', 1] + // Evaluate sort parameter from 'color-asc' to ['color', 1] filters.sort = filters.sort.split('-'); - filters.sort[0] = filters.sort[0] === 'added' ? '_id' : filters.sort[0]; // route added sorting criteria to _id + filters.sort[0] = filters.sort[0] === 'added' ? '_id' : filters.sort[0]; // Route added sorting criteria to _id filters.sort[1] = filters.sort[1] === 'desc' ? -1 : 1; - if (!filters['to-page']) { // set to-page default + if (!filters['to-page']) { // Set to-page default filters['to-page'] = 0; } const addedFilter = filters.filters.find(e => e.field === 'added'); - if (addedFilter) { // convert added filter to object id + if (addedFilter) { // Convert added filter to object id filters.filters.splice(filters.filters.findIndex(e => e.field === 'added'), 1); if (addedFilter.mode === 'in') { - const v = []; // query value + const v = []; // Query value addedFilter.values.forEach(value => { const date = [new Date(value).setHours(0,0,0,0), new Date(value).setHours(23,59,59,999)]; v.push({$and: [{ _id: { '$gte': dateToOId(date[0])}}, { _id: { '$lte': dateToOId(date[1])}}]}); @@ -53,7 +53,7 @@ router.get('/samples', async (req, res, next) => { } else if (addedFilter.mode === 'nin') { addedFilter.values = addedFilter.values.sort(); - const v = []; // query value + const v = []; // Query value for (let i = 0; i <= addedFilter.values.length; i ++) { v[i] = {$and: []}; @@ -69,19 +69,19 @@ router.get('/samples', async (req, res, next) => { filters.filters.push({mode: 'or', field: '_id', values: v}); } else { - // start and end of day + // Start and end of day const date = [new Date(addedFilter.values[0]).setHours(0,0,0,0), new Date(addedFilter.values[0]).setHours(23,59,59,999)]; - if (addedFilter.mode === 'lt') { // lt start + if (addedFilter.mode === 'lt') { // Lt start filters.filters.push({mode: 'lt', field: '_id', values: [dateToOId(date[0])]}); } - if (addedFilter.mode === 'eq' || addedFilter.mode === 'lte') { // lte end + if (addedFilter.mode === 'eq' || addedFilter.mode === 'lte') { // Lte end filters.filters.push({mode: 'lte', field: '_id', values: [dateToOId(date[1])]}); } - if (addedFilter.mode === 'gt') { // gt end + if (addedFilter.mode === 'gt') { // Gt end filters.filters.push({mode: 'gt', field: '_id', values: [dateToOId(date[1])]}); } - if (addedFilter.mode === 'eq' || addedFilter.mode === 'gte') { // gte start + if (addedFilter.mode === 'eq' || addedFilter.mode === 'gte') { // Gte start filters.filters.push({mode: 'gte', field: '_id', values: [dateToOId(date[0])]}); } if (addedFilter.mode === 'ne') { @@ -98,7 +98,7 @@ router.get('/samples', async (req, res, next) => { let queryPtr = query; queryPtr.push({$match: {$and: []}}); - if (filters.sort[0].indexOf('measurements.') >= 0) { // sorting with measurements as starting collection + if (filters.sort[0].indexOf('measurements.') >= 0) { // Sorting with measurements as starting collection collection = MeasurementModel; const [,measurementName, measurementParam] = filters.sort[0].split('.'); const measurementTemplates = await MeasurementTemplateModel.find({name: measurementName}) @@ -108,7 +108,7 @@ router.get('/samples', async (req, res, next) => { return res.status(400).json({status: 'Invalid body format', details: filters.sort[0] + ' not found'}); } let sortStartValue = null; - if (filters['from-id']) { // from-id specified, fetch values for sorting + if (filters['from-id']) { // From-id specified, fetch values for sorting const fromSample = await MeasurementModel.findOne({sample_id: mongoose.Types.ObjectId(filters['from-id'])}) .lean().exec().catch(err => {next(err);}); if (fromSample instanceof Error) return; @@ -117,29 +117,29 @@ router.get('/samples', async (req, res, next) => { } sortStartValue = fromSample.values[measurementParam]; } - // find measurements to sort + // Find measurements to sort queryPtr[0].$match.$and.push({measurement_template: {$in: measurementTemplates.map(e => e._id)}}); - if (filters.filters.find(e => e.field === filters.sort[0])) { // sorted measurement should also be filtered + if (filters.filters.find(e => e.field === filters.sort[0])) { // Sorted measurement should also be filtered queryPtr[0].$match.$and.push(...filterQueries(filters.filters.filter(e => e.field === filters.sort[0]) .map(e => {e.field = 'values.' + e.field.split('.')[2]; return e; }))); } queryPtr.push( - ...sortQuery(filters, ['values.' + measurementParam, 'sample_id'], sortStartValue), // sort measurements - {$replaceRoot: {newRoot: {measurement: '$$ROOT'}}}, // fetch samples and restructure them to fit sample structure + ...sortQuery(filters, ['values.' + measurementParam, 'sample_id'], sortStartValue), // Sort measurements + {$replaceRoot: {newRoot: {measurement: '$$ROOT'}}}, // Fetch samples and restructure them to fit sample structure {$lookup: {from: 'samples', localField: 'measurement.sample_id', foreignField: '_id', as: 'sample'}}, - {$match: statusQuery(filters, 'sample.status')}, // filter out wrong status once samples were added - {$addFields: {['sample.' + measurementName]: '$measurement.values'}}, // more restructuring + {$match: statusQuery(filters, 'sample.status')}, // Filter out wrong status once samples were added + {$addFields: {['sample.' + measurementName]: '$measurement.values'}}, // More restructuring {$replaceRoot: {newRoot: {$mergeObjects: [{$arrayElemAt: ['$sample', 0]}, {}]}}} ); } - else { // sorting with samples as starting collection + else { // Sorting with samples as starting collection collection = SampleModel; queryPtr[0].$match.$and.push(statusQuery(filters, 'status')); - // sorting for sample keys + // Sorting for sample keys if (SampleValidate.sampleKeys.indexOf(filters.sort[0]) >= 0 || /condition\./.test(filters.sort[0])) { let sortStartValue = null; - if (filters['from-id']) { // from-id specified + if (filters['from-id']) { // From-id specified const fromSample = await SampleModel.findById(filters['from-id']).lean().exec().catch(err => { next(err); }); @@ -151,28 +151,28 @@ router.get('/samples', async (req, res, next) => { } queryPtr.push(...sortQuery(filters, [filters.sort[0], '_id'], sortStartValue)); } - else { // add sort key to list to add field later + else { // Add sort key to list to add field later sortFilterKeys.push(filters.sort[0]); } } addFilterQueries(queryPtr, filters.filters.filter( e => (SampleValidate.sampleKeys.indexOf(e.field) >= 0) || /condition\./.test(e.field)) - ); // sample filters + ); // Sample filters - let materialQuery = []; // put material query together separate first to reuse for first-id + let materialQuery = []; // Put material query together separate first to reuse for first-id let materialAdded = false; if (sortFilterKeys.find(e => /material\./.test(e))) { // add material fields materialAdded = true; - materialQuery.push( // add material properties + materialQuery.push( // Add material properties {$lookup: {from: 'materials', localField: 'material_id', foreignField: '_id', as: 'material'}}, {$addFields: {material: {$arrayElemAt: ['$material', 0]}}} ); const baseMFilters = sortFilterKeys.filter(e => /material\./.test(e)) .filter(e => ['material.supplier', 'material.group', 'material.number'].indexOf(e) < 0); - // base material filters + // Base material filters addFilterQueries(materialQuery, filters.filters.filter(e => baseMFilters.indexOf(e.field) >= 0)); - if (sortFilterKeys.find(e => e === 'material.supplier')) { // add supplier if needed + if (sortFilterKeys.find(e => e === 'material.supplier')) { // Add supplier if needed materialQuery.push( {$lookup: { from: 'material_suppliers', localField: 'material.supplier_id', foreignField: '_id', as: 'material.supplier'} @@ -180,7 +180,7 @@ router.get('/samples', async (req, res, next) => { {$addFields: {'material.supplier': {$arrayElemAt: ['$material.supplier.name', 0]}}} ); } - if (sortFilterKeys.find(e => e === 'material.group')) { // add group if needed + if (sortFilterKeys.find(e => e === 'material.group')) { // Add group if needed materialQuery.push( {$lookup: { from: 'material_groups', localField: 'material.group_id', foreignField: '_id', as: 'material.group' } @@ -190,12 +190,12 @@ router.get('/samples', async (req, res, next) => { } const specialMFilters = sortFilterKeys.filter(e => /material\./.test(e)) .filter(e => ['material.supplier', 'material.group', 'material.number'].indexOf(e) >= 0); - // base material filters + // Base material filters addFilterQueries(materialQuery, filters.filters.filter(e => specialMFilters.indexOf(e.field) >= 0)); queryPtr.push(...materialQuery); - if (/material\./.test(filters.sort[0])) { // sort by material key + if (/material\./.test(filters.sort[0])) { // Sort by material key let sortStartValue = null; - if (filters['from-id']) { // from-id specified + if (filters['from-id']) { // From-id specified const fromSample = await SampleModel.aggregate( [{$match: {_id: mongoose.Types.ObjectId(filters['from-id'])}}, ...materialQuery] ).exec().catch(err => {next(err);}); @@ -215,7 +215,7 @@ router.get('/samples', async (req, res, next) => { } } - if (sortFilterKeys.find(e => e === 'measurements')) { // filter for samples without measurements + if (sortFilterKeys.find(e => e === 'measurements')) { // Filter for samples without measurements queryPtr.push({$lookup: { from: 'measurements', let: {sId: '$_id'}, pipeline: [{$match:{$expr:{$and:[{$eq:['$sample_id','$$sId']}]}}}, {$project: {_id: true}}], @@ -225,7 +225,7 @@ router.get('/samples', async (req, res, next) => { ); } const measurementFilterFields = _.uniq(sortFilterKeys.filter(e => /measurements\./.test(e)) - .map(e => e.split('.')[1])); // filter measurement names and remove duplicates from parameters + .map(e => e.split('.')[1])); // Filter measurement names and remove duplicates from parameters if (sortFilterKeys.find(e => /measurements\./.test(e))) { // add measurement fields const measurementTemplates = await MeasurementTemplateModel.find({name: {$in: measurementFilterFields}}) .lean().exec().catch(err => {next(err);}); @@ -238,7 +238,7 @@ router.get('/samples', async (req, res, next) => { {$in: ['$measurement_template', measurementTemplates.map(e => mongoose.Types.ObjectId(e._id))]} ]}}} ]; - if (measurementFilterFields.indexOf(globals.spectrum.spectrum) >= 0) { // filter out dpts + if (measurementFilterFields.indexOf(globals.spectrum.spectrum) >= 0) { // Filter out dpts pipeline.push( {$project: {['values.' + globals.spectrum.dpt]: false}}, {$addFields: {'values._id': '$_id'}} @@ -264,7 +264,7 @@ router.get('/samples', async (req, res, next) => { addFilterQueries(queryPtr, filters.filters .filter(e => sortFilterKeys.filter(e => /measurements\./.test(e)).indexOf(e.field) >= 0) .map(e => {e.field = e.field.replace('measurements.', ''); return e; }) - ); // measurement filters + ); // Measurement filters } if (sortFilterKeys.find(e => e === 'notes.comment')) { @@ -272,18 +272,18 @@ router.get('/samples', async (req, res, next) => { addFilterQueries(queryPtr, filters.filters.filter(e => e.field === 'notes.comment')); } - // count total number of items before $skip and $limit, only works when from-id is not specified and spectra are not - // included + // Count total number of items before $skip and $limit, only works when from-id is not specified and spectra are not + // Included if (!filters.fields.find(e => e.indexOf(globals.spectrum.spectrum + '.' + globals.spectrum.dpt) >= 0) && !filters['from-id'] ) { queryPtr.push({$facet: {count: [{$count: 'count'}], samples: []}}); - queryPtr = queryPtr[queryPtr.length - 1].$facet.samples; // add rest of aggregation pipeline into $facet + queryPtr = queryPtr[queryPtr.length - 1].$facet.samples; // Add rest of aggregation pipeline into $facet } - // paging + // Paging if (filters['to-page']) { - // number to skip, if going back pages, one page has to be skipped less but on sample more + // Number to skip, if going back pages, one page has to be skipped less but on sample more queryPtr.push({$skip: Math.abs(filters['to-page'] + Number(filters['to-page'] < 0)) * filters['page-size'] + Number(filters['to-page'] < 0)}) } @@ -291,22 +291,22 @@ router.get('/samples', async (req, res, next) => { queryPtr.push({$limit: filters['page-size']}); } - const fieldsToAdd = filters.fields.filter(e => // fields to add - sortFilterKeys.indexOf(e) < 0 // field was not in filter - && e !== filters.sort[0] // field was not in sort + const fieldsToAdd = filters.fields.filter(e => // Fields to add + sortFilterKeys.indexOf(e) < 0 // Field was not in filter + && e !== filters.sort[0] // Field was not in sort ); - if (fieldsToAdd.find(e => /^notes(\..+|$)/m.test(e))) { // add notes + if (fieldsToAdd.find(e => /^notes(\..+|$)/m.test(e))) { // Add notes addNotes(queryPtr); } - if (fieldsToAdd.find(e => /material\./.test(e)) && !materialAdded) { // add material, was not added already + if (fieldsToAdd.find(e => /material\./.test(e)) && !materialAdded) { // Add material, was not added already queryPtr.push( {$lookup: {from: 'materials', localField: 'material_id', foreignField: '_id', as: 'material'}}, {$addFields: {material: { $arrayElemAt: ['$material', 0]}}} ); } - if (fieldsToAdd.indexOf('material.supplier') >= 0) { // add supplier if needed + if (fieldsToAdd.indexOf('material.supplier') >= 0) { // Add supplier if needed queryPtr.push( {$lookup: { from: 'material_suppliers', localField: 'material.supplier_id', foreignField: '_id', as: 'material.supplier' @@ -314,7 +314,7 @@ router.get('/samples', async (req, res, next) => { {$addFields: {'material.supplier': {$arrayElemAt: ['$material.supplier.name', 0]}}} ); } - if (fieldsToAdd.indexOf('material.group') >= 0) { // add group if needed + if (fieldsToAdd.indexOf('material.group') >= 0) { // Add group if needed queryPtr.push( {$lookup: { from: 'material_groups', localField: 'material.group_id', foreignField: '_id', as: 'material.group' @@ -325,17 +325,17 @@ router.get('/samples', async (req, res, next) => { let measurementFieldsFields: string[] = _.uniq( fieldsToAdd.filter(e => /measurements\./.test(e)).map(e => e.split('.')[1]) - ); // filter measurement names and remove duplicates from parameters - if (fieldsToAdd.find(e => /measurements\./.test(e))) { // add measurement fields + ); // Filter measurement names and remove duplicates from parameters + if (fieldsToAdd.find(e => /measurements\./.test(e))) { // Add measurement fields const measurementTemplates = await MeasurementTemplateModel.find({name: {$in: measurementFieldsFields}}) .lean().exec().catch(err => {next(err);}); if (measurementTemplates instanceof Error) return; if (measurementTemplates.length < measurementFieldsFields.length) { return res.status(400).json({status: 'Invalid body format', details: 'Measurement key not found'}); } - // use different lookup methods with and without dpt for the best performance - if (fieldsToAdd.find(e => new RegExp('measurements\\.' + globals.spectrum.spectrum).test(e))) { // with dpt - // spectrum was already used for filters + // Use different lookup methods with and without dpt for the best performance + if (fieldsToAdd.find(e => new RegExp('measurements\\.' + globals.spectrum.spectrum).test(e))) { // With dpt + // Spectrum was already used for filters if (sortFilterKeys.find(e => new RegExp('measurements\\.' + globals.spectrum.spectrum).test(e))) { queryPtr.push( {$lookup: {from: 'measurements', localField: 'spectrum._id', foreignField: '_id', as: 'measurements'}} @@ -380,11 +380,11 @@ router.get('/samples', async (req, res, next) => { const projection = filters.fields.map(e => e.replace('measurements.', '')) .reduce((s, e) => {s[e] = true; return s; }, {}); - if (filters.fields.indexOf('_id') < 0 && filters.fields.indexOf('added') < 0) { // disable _id explicitly + if (filters.fields.indexOf('_id') < 0 && filters.fields.indexOf('added') < 0) { // Disable _id explicitly projection._id = false; } queryPtr.push({$project: projection}); - // use streaming when including spectrum files + // Use streaming when including spectrum files if (!fieldsToAdd.find(e => e.indexOf(globals.spectrum.spectrum + '.' + globals.spectrum.dpt) >= 0)) { collection.aggregate(query).allowDiskUse(true).exec((err, data) => { if (err) return next(err); @@ -393,7 +393,7 @@ router.get('/samples', async (req, res, next) => { res.header('Access-Control-Expose-Headers', 'x-total-items'); data = data[0].samples; } - if (filters.fields.indexOf('added') >= 0) { // add added date + if (filters.fields.indexOf('added') >= 0) { // Add added date data.map(e => { e.added = e._id.getTimestamp(); if (filters.fields.indexOf('_id') < 0) { @@ -409,7 +409,7 @@ router.get('/samples', async (req, res, next) => { [filters.sort[0].split('.')[1], ...measurementFilterFields, ...measurementFieldsFields] ); - if (filters.output === 'csv') { // output as csv + if (filters.output === 'csv') { // Output as csv csv(_.compact(data.map(e => SampleValidate.output(e, 'refs', measurementFields))), (err, data) => { if (err) return next(err); res.set('Content-Type', 'text/csv'); @@ -420,7 +420,7 @@ router.get('/samples', async (req, res, next) => { else if (filters.output === 'flatten') { res.json(_.compact(data.map(e => flatten(SampleValidate.output(e, 'refs', measurementFields), true)))); } - else { // validate all and filter null values from validation errors + else { // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => SampleValidate.output(e, 'refs', measurementFields)))); } }); @@ -431,7 +431,7 @@ router.get('/samples', async (req, res, next) => { let count = 0; const stream = collection.aggregate(query).allowDiskUse(true).cursor().exec(); stream.on('data', data => { - if (filters.fields.indexOf('added') >= 0) { // add added date + if (filters.fields.indexOf('added') >= 0) { // Add added date data.added = data._id.getTimestamp(); if (filters.fields.indexOf('_id') < 0) { delete data._id; @@ -457,7 +457,7 @@ router.get(`/samples/:state(${globals.status.new}|${globals.status.del})`, (req, SampleModel.find({status: req.params.state}).lean().exec((err, data) => { if (err) return next(err); - // validate all and filter null values from validation errors + // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => SampleValidate.output(e)))); }); }); @@ -487,7 +487,7 @@ router.put('/sample/' + IdValidate.parameter(), (req, res, next) => { const {error, value: sample} = SampleValidate.input(req.body, 'change'); if (error) return res400(error, res); - SampleModel.findById(req.params.id).lean().exec(async (err, sampleData: any) => { // check if id exists + SampleModel.findById(req.params.id).lean().exec(async (err, sampleData: any) => { // Check if id exists if (err) return next(err); if (!sampleData) { return res.status(404).json({status: 'Not found'}); @@ -496,12 +496,12 @@ router.put('/sample/' + IdValidate.parameter(), (req, res, next) => { return res.status(403).json({status: 'Forbidden'}); } - // only dev and admin are allowed to edit other user's data + // Only dev and admin are allowed to edit other user's data if (sampleData.user_id.toString() !== req.authDetails.id && !req.auth(res, ['dev', 'admin'], 'basic')) return; if (sample.hasOwnProperty('material_id')) { if (!await materialCheck(sample, res, next)) return; } - // do not execute check if condition is and was empty + // Do not execute check if condition is and was empty if (sample.hasOwnProperty('condition') && !(_.isEmpty(sample.condition) && _.isEmpty(sampleData.condition))) { sample.condition = await conditionCheck(sample.condition, 'change', res, next, !(sampleData.condition.condition_template && @@ -511,35 +511,35 @@ router.put('/sample/' + IdValidate.parameter(), (req, res, next) => { if (sample.hasOwnProperty('notes')) { let newNotes = true; - if (sampleData.note_id !== null) { // old notes data exists + if (sampleData.note_id !== null) { // Old notes data exists const data = await NoteModel.findById(sampleData.note_id).lean().exec().catch(err => {next(err);}) as any; if (data instanceof Error) return; - // check if notes were changed + // Check if notes were changed newNotes = !_.isEqual(_.pick(IdValidate.stringify(data), _.keys(sample.notes)), sample.notes); if (newNotes) { - if (data.hasOwnProperty('custom_fields')) { // update note_fields + if (data.hasOwnProperty('custom_fields')) { // Update note_fields customFieldsChange(Object.keys(data.custom_fields), -1, req); } - await NoteModel.findByIdAndDelete(sampleData.note_id).log(req).lean().exec(err => { // delete old notes + await NoteModel.findByIdAndDelete(sampleData.note_id).log(req).lean().exec(err => { // Delete old notes if (err) return console.error(err); }); } } - if (_.keys(sample.notes).length > 0 && newNotes) { // save new notes + if (_.keys(sample.notes).length > 0 && newNotes) { // Save new notes if (!await sampleRefCheck(sample, res, next)) return; - // new custom_fields + // New custom_fields if (sample.notes.hasOwnProperty('custom_fields') && Object.keys(sample.notes.custom_fields).length > 0) { customFieldsChange(Object.keys(sample.notes.custom_fields), 1, req); } - let data = await new NoteModel(sample.notes).save().catch(err => { return next(err)}); // save new notes + let data = await new NoteModel(sample.notes).save().catch(err => { return next(err)}); // Save new notes db.log(req, 'notes', {_id: data._id}, data.toObject()); delete sample.notes; sample.note_id = data._id; } } - // check for changes + // Check for changes if (!_.isEqual(_.pick(IdValidate.stringify(sampleData), _.keys(sample)), _.omit(sample, ['notes']))) { sample.status = globals.status.new; } @@ -555,28 +555,28 @@ router.put('/sample/' + IdValidate.parameter(), (req, res, next) => { router.delete('/sample/' + IdValidate.parameter(), (req, res, next) => { if (!req.auth(res, ['write', 'dev', 'admin'], 'basic')) return; - SampleModel.findById(req.params.id).lean().exec(async (err, sampleData: any) => { // check if id exists + SampleModel.findById(req.params.id).lean().exec(async (err, sampleData: any) => { // Check if id exists if (err) return next(err); if (!sampleData) { return res.status(404).json({status: 'Not found'}); } - // only dev and admin are allowed to edit other user's data + // Only dev and admin are allowed to edit other user's data if (sampleData.user_id.toString() !== req.authDetails.id && !req.auth(res, ['dev', 'admin'], 'basic')) return; - // set sample status + // Set sample status await SampleModel.findByIdAndUpdate(req.params.id, {status:'deleted'}).log(req).lean().exec(err => { if (err) return next(err); - // set status of associated measurements also to deleted + // Set status of associated measurements also to deleted MeasurementModel.updateMany({sample_id: mongoose.Types.ObjectId(req.params.id)}, {status: globals.status.del}) .log(req).lean().exec(err => { if (err) return next(err); - if (sampleData.note_id !== null) { // handle notes - NoteModel.findById(sampleData.note_id).lean().exec((err, data: any) => { // find notes to update note_fields + if (sampleData.note_id !== null) { // Handle notes + NoteModel.findById(sampleData.note_id).lean().exec((err, data: any) => { // Find notes to update note_fields if (err) return next(err); - if (data.hasOwnProperty('custom_fields')) { // update note_fields + if (data.hasOwnProperty('custom_fields')) { // Update note_fields customFieldsChange(Object.keys(data.custom_fields), -1, req); } res.json({status: 'OK'}); @@ -615,7 +615,7 @@ router.put('/sample/validate/' + IdValidate.parameter(), (req, res, next) => { router.post('/sample/new', async (req, res, next) => { if (!req.auth(res, ['write', 'dev', 'admin'], 'basic')) return; - if (!req.body.hasOwnProperty('condition')) { // add empty condition if not specified + if (!req.body.hasOwnProperty('condition')) { // Add empty condition if not specified req.body.condition = {}; } @@ -626,17 +626,17 @@ router.post('/sample/new', async (req, res, next) => { if (!await materialCheck(sample, res, next)) return; if (!await sampleRefCheck(sample, res, next)) return; - // new custom_fields + // New custom_fields if (sample.notes.hasOwnProperty('custom_fields') && Object.keys(sample.notes.custom_fields).length > 0) { customFieldsChange(Object.keys(sample.notes.custom_fields), 1, req); } - if (!_.isEmpty(sample.condition)) { // do not execute check if condition is empty + if (!_.isEmpty(sample.condition)) { // Do not execute check if condition is empty sample.condition = await conditionCheck(sample.condition, 'change', res, next); if (!sample.condition) return; } - sample.status = globals.status.new; // set status to new + sample.status = globals.status.new; // Set status to new if (sample.hasOwnProperty('number')) { if (!await numberCheck(sample, res, next)) return; } @@ -645,7 +645,7 @@ router.post('/sample/new', async (req, res, next) => { } if (!sample.number) return; - await new NoteModel(sample.notes).save((err, data) => { // save notes + await new NoteModel(sample.notes).save((err, data) => { // Save notes if (err) return next(err); db.log(req, 'notes', {_id: data._id}, data.toObject()); delete sample.notes; @@ -665,7 +665,7 @@ router.get('/sample/notes/fields', (req, res, next) => { NoteFieldModel.find({}).lean().exec((err, data) => { if (err) return next(err); - // validate all and filter null values from validation errors + // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => NoteFieldValidate.output(e)))); }) }); @@ -673,10 +673,10 @@ router.get('/sample/notes/fields', (req, res, next) => { module.exports = router; -// store the highest generated number for each location to avoid duplicate numbers +// Store the highest generated number for each location to avoid duplicate numbers const numberBuffer: {[location: string]: number} = {}; -// generate number in format Location32, returns false on error +// Generate number in format Location32, returns false on error async function numberGenerate (sample, req, res, next) { const sampleData = await SampleModel .aggregate([ @@ -705,50 +705,50 @@ async function numberGenerate (sample, req, res, next) { async function numberCheck(sample, res, next) { const sampleData = await SampleModel.findOne({number: sample.number}) .lean().exec().catch(err => {next(err); return false;}); - if (sampleData) { // found entry with sample number + if (sampleData) { // Found entry with sample number res.status(400).json({status: 'Sample number already taken'}); return false } return true; } -// validate material_id and color, returns false if invalid +// Validate material_id and color, returns false if invalid async function materialCheck (sample, res, next) { const materialData = await MaterialModel.findById(sample.material_id).lean().exec().catch(err => next(err)) as any; if (materialData instanceof Error) return false; - if (!materialData) { // could not find material_id + if (!materialData) { // Could not find material_id res.status(400).json({status: 'Material not available'}); return false; } return true; } -// validate treatment template, returns false if invalid, otherwise template data +// Validate treatment template, returns false if invalid, otherwise template data async function conditionCheck (condition, param, res, next, checkVersion = true) { - if (!condition.condition_template || !IdValidate.valid(condition.condition_template)) { // template id not found + if (!condition.condition_template || !IdValidate.valid(condition.condition_template)) { // Template id not found res.status(400).json({status: 'Condition template not available'}); return false; } const conditionData = await ConditionTemplateModel.findById(condition.condition_template) .lean().exec().catch(err => next(err)) as any; if (conditionData instanceof Error) return false; - if (!conditionData) { // template not found + if (!conditionData) { // Template not found res.status(400).json({status: 'Condition template not available'}); return false; } if (checkVersion) { - // get all template versions and check if given is latest + // Get all template versions and check if given is latest const conditionVersions = await ConditionTemplateModel.find({first_id: conditionData.first_id}) .sort({version: -1}).lean().exec().catch(err => next(err)) as any; if (conditionVersions instanceof Error) return false; - if (condition.condition_template !== conditionVersions[0]._id.toString()) { // template not latest + if (condition.condition_template !== conditionVersions[0]._id.toString()) { // Template not latest res.status(400).json({status: 'Old template version not allowed'}); return false; } } - // validate parameters + // Validate parameters const {error, value} = ParametersValidate.input(_.omit(condition, 'condition_template'), conditionData.parameters, param); if (error) {res400(error, res); return false;} @@ -756,11 +756,11 @@ async function conditionCheck (condition, param, res, next, checkVersion = true) return value; } -function sampleRefCheck (sample, res, next) { // validate sample_references, resolves false for invalid reference +function sampleRefCheck (sample, res, next) { // Validate sample_references, resolves false for invalid reference return new Promise(resolve => { - // there are sample_references + // There are sample_references if (sample.notes.hasOwnProperty('sample_references') && sample.notes.sample_references.length > 0) { - let referencesCount = sample.notes.sample_references.length; // count to keep track of running async operations + let referencesCount = sample.notes.sample_references.length; // Count to keep track of running async operations sample.notes.sample_references.forEach(reference => { SampleModel.findById(reference.sample_id).lean().exec((err, data) => { @@ -770,7 +770,7 @@ function sampleRefCheck (sample, res, next) { // validate sample_references, re return resolve(false); } referencesCount --; - if (referencesCount <= 0) { // all async requests done + if (referencesCount <= 0) { // All async requests done resolve(true); } }); @@ -782,18 +782,18 @@ function sampleRefCheck (sample, res, next) { // validate sample_references, re }); } -function customFieldsChange (fields, amount, req) { // update custom_fields and respective quantities +function customFieldsChange (fields, amount, req) { // Update custom_fields and respective quantities fields.forEach(field => { NoteFieldModel.findOneAndUpdate({name: field}, {$inc: {qty: amount}} as any, {new: true}) - .log(req).lean().exec((err, data: any) => { // check if field exists + .log(req).lean().exec((err, data: any) => { // Check if field exists if (err) return console.error(err); - if (!data) { // new field + if (!data) { // New field new NoteFieldModel({name: field, qty: 1}).save((err, data) => { if (err) return console.error(err); db.log(req, 'note_fields', {_id: data._id}, data.toObject()); }) } - else if (data.qty <= 0) { // delete document if field is not used anymore + else if (data.qty <= 0) { // Delete document if field is not used anymore NoteFieldModel.findOneAndDelete({name: field}).log(req).lean().exec(err => { if (err) return console.error(err); }); @@ -802,10 +802,10 @@ function customFieldsChange (fields, amount, req) { // update custom_fields and }); } -function sortQuery(filters, sortKeys, sortStartValue) { // sortKeys = ['primary key', 'secondary key'] - if (filters['from-id']) { // from-id specified - const ssv = sortStartValue !== undefined; // if value is not given, match for existence - if ((filters['to-page'] === 0 && filters.sort[1] === 1) || (filters.sort[1] * filters['to-page'] > 0)) { // asc +function sortQuery(filters, sortKeys, sortStartValue) { // SortKeys = ['primary key', 'secondary key'] + if (filters['from-id']) { // From-id specified + const ssv = sortStartValue !== undefined; // If value is not given, match for existence + if ((filters['to-page'] === 0 && filters.sort[1] === 1) || (filters.sort[1] * filters['to-page'] > 0)) { // Asc return [ {$match: {$or: [ {[sortKeys[0]]: ssv ? {$gt: sortStartValue} : {$exists: true}}, @@ -828,8 +828,8 @@ function sortQuery(filters, sortKeys, sortStartValue) { // sortKeys = ['primary {$sort: {[sortKeys[0]]: -1, _id: -1}} ]; } - } else { // sort from beginning - return [{$sort: {[sortKeys[0]]: filters.sort[1], [sortKeys[1]]: filters.sort[1]}}]; // set _id as secondary sort + } else { // Sort from beginning + return [{$sort: {[sortKeys[0]]: filters.sort[1], [sortKeys[1]]: filters.sort[1]}}]; // Set _id as secondary sort } } @@ -837,7 +837,7 @@ function statusQuery(filters, field) { return {$or: filters.status.map(e => ({[field]: e}))}; } -function addFilterQueries (queryPtr, filters) { // returns array of match queries from given filters +function addFilterQueries (queryPtr, filters) { // Returns array of match queries from given filters if (filters.length) { queryPtr.push({$match: {$and: filterQueries(filters)}}); } @@ -845,21 +845,21 @@ function addFilterQueries (queryPtr, filters) { // returns array of match queri function filterQueries (filters) { return filters.map(e => { - if (e.mode === 'or') { // allow or queries (needed for $ne added) + if (e.mode === 'or') { // Allow or queries (needed for $ne added) return {['$' + e.mode]: e.values}; } else if (e.mode === 'stringin') { return {[e.field]: {['$in']: [new RegExp(e.values[0])]}}; } else { - // add filter criteria as {field: {$mode: value}}, only use first value when mode is not in/nin + // Add filter criteria as {field: {$mode: value}}, only use first value when mode is not in/nin return {[e.field]: {['$' + e.mode]: (e.mode.indexOf('in') >= 0 ? e.values : e.values[0])}}; } }); } -// add measurements as property [template.name], if one result, array is reduced to direct values. All given templates -// must have the same name +// Add measurements as property [template.name], if one result, array is reduced to direct values. All given templates +// Must have the same name function addMeasurements(queryPtr, templates) { queryPtr.push( {$addFields: {[templates[0].name]: {$let: {vars: { @@ -880,7 +880,7 @@ function addMeasurements(queryPtr, templates) { ); } -function addNotes(queryPtr) { // add note fields with default, if no notes are found +function addNotes(queryPtr) { // Add note fields with default, if no notes are found queryPtr.push( {$lookup: {from: 'notes', localField: 'note_id', foreignField: '_id', as: 'notes'}}, {$addFields: {notes: {$cond: [ @@ -891,7 +891,7 @@ function addNotes(queryPtr) { // add note fields with default, if no notes are ); } -function dateToOId (date) { // convert date to ObjectId +function dateToOId (date) { // Convert date to ObjectId return mongoose.Types.ObjectId(Math.floor(date / 1000).toString(16) + '0000000000000000'); } @@ -902,9 +902,9 @@ async function sampleReturn (sampleData, req, res, next) { if (sampleData instanceof Error) return; sampleData = sampleData.toObject(); - // deleted samples only available for dev/admin + // Deleted samples only available for dev/admin if (sampleData.status === globals.status.del && !req.auth(res, ['dev', 'admin'], 'all')) return; - sampleData.material = sampleData.material_id; // map data to right keys + sampleData.material = sampleData.material_id; // Map data to right keys sampleData.material.group = sampleData.material.group_id.name; sampleData.material.supplier = sampleData.material.supplier_id.name; sampleData.user = sampleData.user_id.name; @@ -912,7 +912,7 @@ async function sampleReturn (sampleData, req, res, next) { MeasurementModel.find({sample_id: sampleData._id, status: {$ne: 'deleted'}}) .lean().exec((err, data) => { sampleData.measurements = data; - if (['dev', 'admin'].indexOf(req.authDetails.level) < 0) { // strip dpt values if not dev or admin + if (['dev', 'admin'].indexOf(req.authDetails.level) < 0) { // Strip dpt values if not dev or admin sampleData.measurements.forEach(measurement => { if (measurement.values[globals.spectrum.dpt]) { delete measurement.values[globals.spectrum.dpt]; diff --git a/src/routes/template.spec.ts b/src/routes/template.spec.ts index 6b38e75..f9ebfbf 100644 --- a/src/routes/template.spec.ts +++ b/src/routes/template.spec.ts @@ -590,7 +590,7 @@ describe('/template', () => { }); }); }); - // other methods should be covered by condition tests + // Other methods should be covered by condition tests }); describe('/template/material', () => { @@ -656,6 +656,6 @@ describe('/template', () => { }); }); }); - // other methods should be covered by condition tests + // Other methods should be covered by condition tests }); }); diff --git a/src/routes/template.ts b/src/routes/template.ts index d8966f9..3a5abf6 100644 --- a/src/routes/template.ts +++ b/src/routes/template.ts @@ -20,10 +20,10 @@ const router = express.Router(); router.get('/template/:collection(measurements|conditions|materials)', (req, res, next) => { if (!req.auth(res, ['read', 'write', 'dev', 'admin'], 'basic')) return; - req.params.collection = req.params.collection.replace(/s$/g, ''); // remove trailing s + req.params.collection = req.params.collection.replace(/s$/g, ''); // Remove trailing s model(req).find({}).lean().exec((err, data) => { if (err) next (err); - // validate all and filter null values from validation errors + // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => TemplateValidate.output(e)))); }); }); @@ -49,13 +49,13 @@ router.put('/template/:collection(measurement|condition|material)/' + IdValidate const {error, value: template} = TemplateValidate.input(req.body, 'change'); if (error) return res400(error, res); - // find given template + // Find given template const templateRef = await model(req).findById(req.params.id).lean().exec().catch(err => {next(err);}) as any; if (templateRef instanceof Error) return; if (!templateRef) { return res.status(404).json({status: 'Not found'}); } - // find latest version + // Find latest version const templateData = await model(req).findOne({first_id: templateRef.first_id}).sort({version: -1}) .lean().exec().catch(err => {next(err);}) as any; if (templateData instanceof Error) return; @@ -63,8 +63,8 @@ router.put('/template/:collection(measurement|condition|material)/' + IdValidate return res.status(404).json({status: 'Not found'}); } - if (!_.isEqual(_.pick(templateData, _.keys(template)), template)) { // data was changed - if (!template.parameters || _.isEqual(templateData.parameters, template.parameters)) { // only name was changed + if (!_.isEqual(_.pick(templateData, _.keys(template)), template)) { // Data was changed + if (!template.parameters || _.isEqual(templateData.parameters, template.parameters)) { // Only name was changed model(req).findByIdAndUpdate(req.params.id, {name: template.name}, {new: true}) .log(req).lean().exec((err, data) => { if (err) next (err); @@ -72,15 +72,15 @@ router.put('/template/:collection(measurement|condition|material)/' + IdValidate }); } else if (template.parameters.filter((e, i) => _.isEqual(e.range, templateData.parameters[i].range)).length - === templateData.parameters.length) { // only names changed - const changedParameterNames = template.parameters.map((e, i) => ( // list of new names + === templateData.parameters.length) { // Only names changed + const changedParameterNames = template.parameters.map((e, i) => ( // List of new names {name: e.name, index: i, oldName: templateData.parameters[i].name} )).filter(e => e.name !== e.oldName); - // custom mappings for different collections - let targetModel; // model of the collection where the template is used - let pathPrefix; // path to the parameters in use - let templatePath; // complete path of the template property + // Custom mappings for different collections + let targetModel; // Model of the collection where the template is used + let pathPrefix; // Path to the parameters in use + let templatePath; // Complete path of the template property switch (req.params.collection) { case 'condition': targetModel = SampleModel; @@ -116,8 +116,8 @@ router.put('/template/:collection(measurement|condition|material)/' + IdValidate }); } else { - template.version = templateData.version + 1; // increase version - // save new template, fill with old properties + template.version = templateData.version + 1; // Increase version + // Save new template, fill with old properties await new (model(req))(_.assign({}, _.omit(templateData, ['_id', '__v']), template)).save((err, data) => { if (err) next (err); db.log(req, req.params.collection + '_templates', {_id: data._id}, data.toObject()); @@ -136,9 +136,9 @@ router.put('/template/:collection(measurement|condition|material)/' + IdValidate const {error, value: template} = TemplateValidate.input(req.body, 'new'); if (error) return res400(error, res); - template._id = mongoose.Types.ObjectId(); // set reference to itself for first version of template + template._id = mongoose.Types.ObjectId(); // Set reference to itself for first version of template template.first_id = template._id; - template.version = 1; // set template version + template.version = 1; // Set template version await new (model(req))(template).save((err, data) => { if (err) next (err); db.log(req, req.params.collection + '_templates', {_id: data._id}, data.toObject()); @@ -149,7 +149,7 @@ router.put('/template/:collection(measurement|condition|material)/' + IdValidate module.exports = router; - function model (req) { // return right template model + function model (req) { // Return right template model switch (req.params.collection) { case 'condition': return ConditionTemplateModel case 'measurement': return MeasurementTemplateModel diff --git a/src/routes/user.ts b/src/routes/user.ts index 0238713..4a5c9d5 100644 --- a/src/routes/user.ts +++ b/src/routes/user.ts @@ -18,12 +18,12 @@ router.get('/users', (req, res) => { if (!req.auth(res, ['admin'], 'basic')) return; UserModel.find({}).lean().exec( (err, data:any) => { - // validate all and filter null values from validation errors + // Validate all and filter null values from validation errors res.json(_.compact(data.map(e => UserValidate.output(e, 'admin')))); }); }); -// this path matches /user, /user/ and /user/xxx, but not /user/key or user/new. +// This path matches /user, /user/ and /user/xxx, but not /user/key or user/new. // See https://forbeslindesay.github.io/express-route-tester/ for the generated regex router.get('/user:username([/](?!key|new).?*|/?)', (req, res, next) => { if (!req.auth(res, ['predict', 'read', 'write', 'dev', 'admin'], 'basic')) return; @@ -33,7 +33,7 @@ router.get('/user:username([/](?!key|new).?*|/?)', (req, res, next) => { UserModel.findOne({name: username}).lean().exec( (err, data:any) => { if (err) return next(err); if (data) { - res.json(UserValidate.output(data)); // validate all and filter null values from validation errors + res.json(UserValidate.output(data)); // Validate all and filter null values from validation errors } else { res.status(404).json({status: 'Not found'}); @@ -41,7 +41,7 @@ router.get('/user:username([/](?!key|new).?*|/?)', (req, res, next) => { }); }); -// this path matches /user, /user/ and /user/xxx, but not /user/key or user/new +// This path matches /user, /user/ and /user/xxx, but not /user/key or user/new router.put('/user:username([/](?!key|new|restore).?*|/?)', async (req, res, next) => { if (!req.auth(res, ['predict', 'read', 'write', 'dev', 'admin'], 'basic')) return; @@ -56,7 +56,7 @@ router.put('/user:username([/](?!key|new|restore).?*|/?)', async (req, res, next user.pass = bcrypt.hashSync(user.pass, 10); } - // check that user does not already exist if new name was specified + // Check that user does not already exist if new name was specified if (user.hasOwnProperty('name') && user.name !== username) { if (!await usernameCheck(user.name, res, next)) return; } @@ -65,13 +65,13 @@ router.put('/user:username([/](?!key|new|restore).?*|/?)', async (req, res, next if (!await modelsCheck(user.models, res, next)) return; } - // get current mail address to compare to given address + // Get current mail address to compare to given address const oldUserData = await UserModel.findOne({name: username}).lean().exec().catch(err => next(err)); await UserModel.findOneAndUpdate({name: username}, user, {new: true}).log(req).lean().exec( (err, data:any) => { if (err) return next(err); if (data) { - if (data.email !== oldUserData.email) { // mail address was changed, send notice to old address + if (data.email !== oldUserData.email) { // Mail address was changed, send notice to old address Mail.send(oldUserData.email, 'Email change in your DeFinMa database account', 'Hi,

Your email address of your DeFinMa account was changed to ' + data.mail + '

If you actually did this, just delete this email.' + @@ -87,7 +87,7 @@ router.put('/user:username([/](?!key|new|restore).?*|/?)', async (req, res, next }); }); -// this path matches /user, /user/ and /user/xxx, but not /user/key or user/new. +// This path matches /user, /user/ and /user/xxx, but not /user/key or user/new. // See https://forbeslindesay.github.io/express-route-tester/ for the generated regex router.delete('/user:username([/](?!key|new).?*|/?)', (req, res, next) => { if (!req.auth(res, ['predict', 'read', 'write', 'dev', 'admin'], 'basic')) return; @@ -132,19 +132,19 @@ router.get('/user/key', (req, res, next) => { router.post('/user/new', async (req, res, next) => { if (!req.auth(res, ['admin'], 'basic')) return; - // validate input + // Validate input const {error, value: user} = UserValidate.input(req.body, 'new'); if (error) return res400(error, res); - // check that user does not already exist + // Check that user does not already exist if (!await usernameCheck(user.name, res, next)) return; if (!await modelsCheck(user.models, res, next)) return; - user.key = mongoose.Types.ObjectId(); // use object id as unique API key + user.key = mongoose.Types.ObjectId(); // Use object id as unique API key user.status = globals.status.new; - bcrypt.hash(user.pass, 10, (err, hash) => { // password hashing + bcrypt.hash(user.pass, 10, (err, hash) => { // Password hashing user.pass = hash; - new UserModel(user).save((err, data) => { // store user + new UserModel(user).save((err, data) => { // Store user if (err) return next(err); db.log(req, 'users', {_id: data._id}, data.toObject()); res.json(UserValidate.output(data.toObject())); @@ -153,18 +153,18 @@ router.post('/user/new', async (req, res, next) => { }); router.post('/user/passreset', (req, res, next) => { - // check if user/email combo exists + // Check if user/email combo exists UserModel.find({name: req.body.name, email: req.body.email}).lean().exec( (err, data: any) => { if (err) return next(err); - if (data.length === 1) { // it exists - const newPass = Math.random().toString(36).substring(2); // generate temporary password - bcrypt.hash(newPass, 10, (err, hash) => { // password hashing + if (data.length === 1) { // It exists + const newPass = Math.random().toString(36).substring(2); // Generate temporary password + bcrypt.hash(newPass, 10, (err, hash) => { // Password hashing if (err) return next(err); - UserModel.findByIdAndUpdate(data[0]._id, {pass: hash}).log(req).exec(err => { // write new password + UserModel.findByIdAndUpdate(data[0]._id, {pass: hash}).log(req).exec(err => { // Write new password if (err) return next(err); - // send email + // Send email Mail.send(data[0].email, 'Your new password for the DeFinMa database', 'Hi,

You requested to reset your password.
Your new password is:

' + newPass + '' + '

If you did not request a password reset, talk to the sysadmin quickly!

Have a nice day.' + @@ -184,9 +184,9 @@ router.post('/user/passreset', (req, res, next) => { module.exports = router; -function getUsername (req, res) { // returns username or false if action is not allowed - req.params.username = req.params[0]; // because of path regex -if (req.params.username !== undefined) { // different username than request user +function getUsername (req, res) { // Returns username or false if action is not allowed + req.params.username = req.params[0]; // Because of path regex +if (req.params.username !== undefined) { // Different username than request user if (!req.auth(res, ['admin'], 'basic')) return false; return req.params.username; } @@ -195,7 +195,7 @@ else { } } -async function usernameCheck (name, res, next) { // check if username is already taken +async function usernameCheck (name, res, next) { // Check if username is already taken const userData = await UserModel.findOne({name: name}).lean().exec().catch(err => next(err)) as any; if (userData instanceof Error) return false; if (userData || UserValidate.isSpecialName(name)) { @@ -205,7 +205,7 @@ if (userData || UserValidate.isSpecialName(name)) { return true; } -async function modelsCheck (models, res, next) { // check if model ids exist, returns false on error +async function modelsCheck (models, res, next) { // Check if model ids exist, returns false on error let result = true; for (let i in models) { const model = await ModelModel.findOne({'models._id': mongoose.Types.ObjectId(models[i])}) diff --git a/src/routes/validate/id.ts b/src/routes/validate/id.ts index 9e85b58..cc0ffb0 100644 --- a/src/routes/validate/id.ts +++ b/src/routes/validate/id.ts @@ -6,11 +6,11 @@ export default class IdValidate { .length(24) .messages({'string.pattern.base': 'Invalid object id'}); - static get () { // return joi validation + static get () { // Return joi validation return this.id; } - static valid (id) { // validate id + static valid (id) { // Validate id return this.id.validate(id).error === undefined; } @@ -18,13 +18,13 @@ export default class IdValidate { return ':id([0-9a-f]{24})'; } - static stringify (data) { // convert all ObjectID objects to plain strings + static stringify (data) { // Convert all ObjectID objects to plain strings Object.keys(data).forEach(key => { - // stringify id + // Stringify id if (data[key] !== null && data[key].hasOwnProperty('_bsontype') && data[key]._bsontype === 'ObjectID') { data[key] = data[key].toString(); } - else if (typeof data[key] === 'object' && data[key] !== null) { // deeper into recursion + else if (typeof data[key] === 'object' && data[key] !== null) { // Deeper into recursion data[key] = this.stringify(data[key]); } }); diff --git a/src/routes/validate/material.ts b/src/routes/validate/material.ts index 7bbb698..bedb111 100644 --- a/src/routes/validate/material.ts +++ b/src/routes/validate/material.ts @@ -3,7 +3,7 @@ import Joi from 'joi'; import IdValidate from './id'; import globals from '../../globals'; -export default class MaterialValidate { // validate input for material +export default class MaterialValidate { // Validate input for material private static material = { name: Joi.string() .max(128), @@ -26,7 +26,7 @@ export default class MaterialValidate { // validate input for material .valid(...Object.values(globals.status)) }; - static input (data, param) { // validate input, set param to 'new' to make all attributes required + static input (data, param) { // Validate input, set param to 'new' to make all attributes required if (param === 'new') { return Joi.object({ name: this.material.name.required(), @@ -50,7 +50,7 @@ export default class MaterialValidate { // validate input for material } } - static output (data, status = false) { // validate output and strip unwanted properties, returns null if not valid + static output (data, status = false) { // Validate output and strip unwanted properties, returns null if not valid data = IdValidate.stringify(data); data.group = data.group_id.name; data.supplier = data.supplier_id.name; @@ -69,17 +69,17 @@ export default class MaterialValidate { // validate input for material return error !== undefined? null : value; } - static outputGroups (data) {// validate groups output and strip unwanted properties, returns null if not valid + static outputGroups (data) {// Validate groups output and strip unwanted properties, returns null if not valid const {value, error} = this.material.group.validate(data, {stripUnknown: true}); return error !== undefined? null : value; } - static outputSuppliers (data) {// validate suppliers output and strip unwanted properties, returns null if not valid + static outputSuppliers (data) {// Validate suppliers output and strip unwanted properties, returns null if not valid const {value, error} = this.material.supplier.validate(data, {stripUnknown: true}); return error !== undefined? null : value; } - static outputV() { // return output validator + static outputV() { // Return output validator return Joi.object({ _id: IdValidate.get(), name: this.material.name, @@ -92,7 +92,7 @@ export default class MaterialValidate { // validate input for material static query (data, dev = false) { const acceptedStatuses = [globals.status.val, globals.status.new]; - if (dev) { // dev and admin can also access deleted samples + if (dev) { // Dev and admin can also access deleted samples acceptedStatuses.push(globals.status.del) } return Joi.object({ diff --git a/src/routes/validate/measurement.ts b/src/routes/validate/measurement.ts index f5a8f60..9119ea8 100644 --- a/src/routes/validate/measurement.ts +++ b/src/routes/validate/measurement.ts @@ -11,14 +11,14 @@ export default class MeasurementValidate { Joi.string().max(128), Joi.number(), Joi.boolean(), - Joi.array().items(Joi.array().items(Joi.number())), // for spectra + Joi.array().items(Joi.array().items(Joi.number())), // For spectra Joi.array() ) .allow(null) ) }; - static input (data, param) { // validate input, set param to 'new' to make all attributes required + static input (data, param) { // Validate input, set param to 'new' to make all attributes required if (param === 'new') { return Joi.object({ sample_id: IdValidate.get().required(), @@ -36,10 +36,10 @@ export default class MeasurementValidate { } } - // validate output and strip unwanted properties, returns null if not valid + // Validate output and strip unwanted properties, returns null if not valid static output (data, req, status = false) { data = IdValidate.stringify(data); - // spectral data not allowed for read/write users + // Spectral data not allowed for read/write users if (['dev', 'admin'].indexOf(req.authDetails.level) < 0 && data.values[globals.spectrum.dpt]) { delete data.values[globals.spectrum.dpt]; } @@ -56,7 +56,7 @@ export default class MeasurementValidate { return error !== undefined? null : value; } - static outputV() { // return output validator + static outputV() { // Return output validator return Joi.object({ _id: IdValidate.get(), sample_id: IdValidate.get(), diff --git a/src/routes/validate/model.ts b/src/routes/validate/model.ts index 7700638..1b02971 100644 --- a/src/routes/validate/model.ts +++ b/src/routes/validate/model.ts @@ -2,7 +2,7 @@ import Joi from 'joi'; import IdValidate from './id'; -export default class ModelValidate { // validate input for model +export default class ModelValidate { // Validate input for model private static model = { group: Joi.string() .disallow('file') @@ -20,11 +20,11 @@ export default class ModelValidate { // validate input for model }) }; - static input (data) { // validate input + static input (data) { // Validate input return this.model.model.required().validate(data); } - static output (data) { // validate output and strip unwanted properties, returns null if not valid + static output (data) { // Validate output and strip unwanted properties, returns null if not valid data = IdValidate.stringify(data); const {value, error} = Joi.object({ group: this.model.group, diff --git a/src/routes/validate/note_field.ts b/src/routes/validate/note_field.ts index ead0a65..ff6c176 100644 --- a/src/routes/validate/note_field.ts +++ b/src/routes/validate/note_field.ts @@ -8,7 +8,7 @@ export default class NoteFieldValidate { qty: Joi.number() }; - static output (data) { // validate output and strip unwanted properties, returns null if not valid + static output (data) { // Validate output and strip unwanted properties, returns null if not valid const {value, error} = Joi.object({ name: this.note_field.name, qty: this.note_field.qty diff --git a/src/routes/validate/parameters.ts b/src/routes/validate/parameters.ts index 6c5bf56..23a6d79 100644 --- a/src/routes/validate/parameters.ts +++ b/src/routes/validate/parameters.ts @@ -1,7 +1,7 @@ import Joi from 'joi'; export default class ParametersValidate { - // data to validate, parameters from template, param: 'new', 'change', 'null'(null values are allowed) + // Data to validate, parameters from template, param: 'new', 'change', 'null'(null values are allowed) static input (data, parameters, param) { let joiObject = {}; parameters.forEach(parameter => { diff --git a/src/routes/validate/res400.ts b/src/routes/validate/res400.ts index d5a2ba4..a89834c 100644 --- a/src/routes/validate/res400.ts +++ b/src/routes/validate/res400.ts @@ -1,4 +1,4 @@ -// respond with 400 and include error details from the joi validation +// Respond with 400 and include error details from the joi validation export default function res400 (error, res) { res.status(400).json({status: 'Invalid body format', details: error.details[0].message}); diff --git a/src/routes/validate/root.ts b/src/routes/validate/root.ts index 144814e..e7a4c90 100644 --- a/src/routes/validate/root.ts +++ b/src/routes/validate/root.ts @@ -1,7 +1,7 @@ import Joi from 'joi'; import IdValidate from './id'; -export default class RootValidate { // validate input for root methods +export default class RootValidate { // Validate input for root methods private static changelog = { timestamp: Joi.date() .iso() diff --git a/src/routes/validate/sample.ts b/src/routes/validate/sample.ts index 6f6b0e2..cbf4f9c 100644 --- a/src/routes/validate/sample.ts +++ b/src/routes/validate/sample.ts @@ -58,7 +58,7 @@ export default class SampleValidate { .valid(...Object.values(globals.status)) }; - static readonly sampleKeys = [ // keys which can be found in the sample directly + static readonly sampleKeys = [ // Keys which can be found in the sample directly '_id', 'color', 'number', @@ -102,7 +102,7 @@ export default class SampleValidate { `measurements.${globals.spectrum.spectrum}.${globals.spectrum.dpt}`, ]; - static input (data, param) { // validate input, set param to 'new' to make all attributes required + static input (data, param) { // Validate input, set param to 'new' to make all attributes required if (param === 'new') { return Joi.object({ color: this.sample.color.required(), @@ -139,7 +139,7 @@ export default class SampleValidate { } } - // validate output and strip unwanted properties, returns null if not valid + // Validate output and strip unwanted properties, returns null if not valid static output (data, param = 'refs+added', additionalParams = []) { if (param === 'refs+added') { param = 'refs'; @@ -200,13 +200,13 @@ export default class SampleValidate { } catch (ignore) {} data.filters[i] = JSON.parse(data.filters[i]); - data.filters[i].values = data.filters[i].values.map(e => { // validate filter values - if (e === null) { // null values are always allowed + data.filters[i].values = data.filters[i].values.map(e => { // Validate filter values + if (e === null) { // Null values are always allowed return null; } let validator; let field = data.filters[i].field; - if (/material\./.test(field)) { // select right validation model + if (/material\./.test(field)) { // Select right validation model validator = MaterialValidate.outputV().append({ number: Joi.string().max(128).allow(''), properties: Joi.alternatives().try(Joi.number(), Joi.string().max(128).allow('')) @@ -240,7 +240,7 @@ export default class SampleValidate { validator = Joi.object(this.sample); } const {value, error} = validator.validate({[field]: e}); - if (error) throw error; // reject invalid values + if (error) throw error; // Reject invalid values return value[field]; }); } @@ -250,7 +250,7 @@ export default class SampleValidate { } } const acceptedStatuses = [globals.status.val, globals.status.new]; - if (dev) { // dev and admin can also access deleted samples + if (dev) { // Dev and admin can also access deleted samples acceptedStatuses.push(globals.status.del) } return Joi.object({ diff --git a/src/routes/validate/template.ts b/src/routes/validate/template.ts index ab84661..f184992 100644 --- a/src/routes/validate/template.ts +++ b/src/routes/validate/template.ts @@ -39,7 +39,7 @@ export default class TemplateValidate { ) }; - static input (data, param) { // validate input, set param to 'new' to make all attributes required + static input (data, param) { // Validate input, set param to 'new' to make all attributes required if (param === 'new') { return Joi.object({ name: this.template.name.required(), @@ -57,7 +57,7 @@ export default class TemplateValidate { } } - static output (data) { // validate output and strip unwanted properties, returns null if not valid + static output (data) { // Validate output and strip unwanted properties, returns null if not valid data = IdValidate.stringify(data); const {value, error} = Joi.object({ _id: IdValidate.get(), diff --git a/src/routes/validate/user.ts b/src/routes/validate/user.ts index 6ada465..8396700 100644 --- a/src/routes/validate/user.ts +++ b/src/routes/validate/user.ts @@ -3,7 +3,7 @@ import globals from '../../globals'; import IdValidate from './id'; -export default class UserValidate { // validate input for user +export default class UserValidate { // Validate input for user private static user = { name: Joi.string() .lowercase() @@ -40,9 +40,9 @@ export default class UserValidate { // validate input for user .valid(...Object.values(globals.status)) }; - private static specialUsernames: string[] = ['admin', 'user', 'key', 'new', 'passreset']; // names a user cannot take + private static specialUsernames: string[] = ['admin', 'user', 'key', 'new', 'passreset']; // Names a user cannot take - static input (data, param) { // validate input, set param to 'new' to make all attributes required + static input (data, param) { // Validate input, set param to 'new' to make all attributes required if (param === 'new') { return Joi.object({ name: this.user.name.required(), @@ -79,7 +79,7 @@ export default class UserValidate { // validate input for user } } - static output (data, param = '') { // validate output and strip unwanted properties, returns null if not valid + static output (data, param = '') { // Validate output and strip unwanted properties, returns null if not valid data = IdValidate.stringify(data); const validate: {[key: string]: object} = { _id: IdValidate.get(), @@ -97,7 +97,7 @@ export default class UserValidate { // validate input for user return error !== undefined? null : value; } - static isSpecialName (name) { // true if name belongs to special names + static isSpecialName (name) { // True if name belongs to special names return this.specialUsernames.indexOf(name) > -1; } diff --git a/src/test/helper.ts b/src/test/helper.ts index 1ef25d0..79ae9c6 100644 --- a/src/test/helper.ts +++ b/src/test/helper.ts @@ -7,7 +7,7 @@ import IdValidate from '../routes/validate/id'; export default class TestHelper { - public static auth = { // test user credentials + public static auth = { // Test user credentials admin: {pass: 'Abc123!#', key: '000000000000000000001003', id: '000000000000000000000003'}, janedoe: {pass: 'Xyz890*)', key: '000000000000000000001002', id: '000000000000000000000002'}, user: {pass: 'Xyz890*)', key: '000000000000000000001001', id: '000000000000000000000001'}, @@ -15,7 +15,7 @@ export default class TestHelper { customer: {pass: 'Xyz890*)', key: '000000000000000000001005', id: '000000000000000000000005'} } - public static res = { // default responses + public static res = { // Default responses 400: {status: 'Bad request'}, 401: {status: 'Unauthorized'}, 403: {status: 'Forbidden'}, @@ -30,27 +30,27 @@ export default class TestHelper { } static beforeEach (server, done) { - // delete cached server code except models as these are needed in the testing files as well + // Delete cached server code except models as these are needed in the testing files as well Object.keys(require.cache).filter(e => /API\\dist\\(?!(models|db|test))/.test(e)).forEach(key => { - delete require.cache[key]; // prevent loading from cache + delete require.cache[key]; // Prevent loading from cache }); server = require('../index'); - db.drop(err => { // reset database + db.drop(err => { // Reset database if (err) return done(err); db.loadJson(require('./db.json'), done); }); return server } - // options in form: {method, url, contentType, auth: {key/basic: 'name' or 'key'/{name, pass}}, httpStatus, req, res, - // default (set to false if you want to dismiss default .end handling)} + // Options in form: {method, url, contentType, auth: {key/basic: 'name' or 'key'/{name, pass}}, httpStatus, req, res, + // Default (set to false if you want to dismiss default .end handling)} static request (server, done, options) { let st = supertest(server); - if (options.hasOwnProperty('auth') && options.auth.hasOwnProperty('key')) { // resolve API key + if (options.hasOwnProperty('auth') && options.auth.hasOwnProperty('key')) { // Resolve API key options.url += '?key=' + (this.auth.hasOwnProperty(options.auth.key)? this.auth[options.auth.key].key : options.auth.key); } - switch (options.method) { // http method + switch (options.method) { // Http method case 'get': st = st.get(options.url) break; @@ -64,16 +64,16 @@ export default class TestHelper { st = st.delete(options.url) break; } - if (options.hasOwnProperty('reqType')) { // request body + if (options.hasOwnProperty('reqType')) { // Request body st = st.type(options.reqType); } - if (options.hasOwnProperty('req')) { // request body + if (options.hasOwnProperty('req')) { // Request body st = st.send(options.req); } - if (options.hasOwnProperty('reqContentType')) { // request body + if (options.hasOwnProperty('reqContentType')) { // Request body st = st.set('Content-Type', options.reqContentType); } - if (options.hasOwnProperty('auth') && options.auth.hasOwnProperty('basic')) { // resolve basic auth + if (options.hasOwnProperty('auth') && options.auth.hasOwnProperty('basic')) { // Resolve basic auth if (this.auth.hasOwnProperty(options.auth.basic)) { st = st.auth(options.auth.basic, this.auth[options.auth.basic].pass) } @@ -87,26 +87,26 @@ export default class TestHelper { else { st = st.expect('Content-type', /json/).expect(options.httpStatus); } - if (options.hasOwnProperty('res')) { // evaluate result + if (options.hasOwnProperty('res')) { // Evaluate result return st.end((err, res) => { if (err) return done (err); should(res.body).be.eql(options.res); done(); }); } - else if (this.res.hasOwnProperty(options.httpStatus) && options.default !== false) { // evaluate default results + else if (this.res.hasOwnProperty(options.httpStatus) && options.default !== false) { // Evaluate default results return st.end((err, res) => { if (err) return done (err); should(res.body).be.eql(this.res[options.httpStatus]); done(); }); } - // check changelog, takes log: {collection, skip, data/(dataAdd, dataIgn)} + // Check changelog, takes log: {collection, skip, data/(dataAdd, dataIgn)} else if (options.hasOwnProperty('log')) { return st.end(err => { if (err) return done (err); ChangelogModel.findOne({}).sort({_id: -1}).skip(options.log.skip? options.log.skip : 0) - .lean().exec((err, data) => { // latest entry + .lean().exec((err, data) => { // Latest entry if (err) return done(err); should(data).have.only.keys('_id', 'action', 'collection_name', 'conditions', 'data', 'user_id', '__v'); should(data).have.property('action', options.method.toUpperCase() + ' ' + options.url); @@ -132,7 +132,7 @@ export default class TestHelper { }); }); } - else { // return object to do .end() manually + else { // Return object to do .end() manually return st; } } diff --git a/src/test/loadDev.ts b/src/test/loadDev.ts index 40bd5c5..a4744ca 100644 --- a/src/test/loadDev.ts +++ b/src/test/loadDev.ts @@ -1,10 +1,10 @@ import db from '../db'; -// script to load test db into dev db for a clean start +// Script to load test db into dev db for a clean start db.connect('dev', () => { console.info('dropping data...'); - db.drop(() => { // reset database + db.drop(() => { // Reset database console.info('loading data...'); db.loadJson(require('./db.json'), () => { console.info('done');