Properly indent all source files
This commit is contained in:
		@@ -2,33 +2,33 @@ import Joi from 'joi';
 | 
			
		||||
import globals from '../../globals';
 | 
			
		||||
 | 
			
		||||
export default class HelpValidate {
 | 
			
		||||
  private static help = {
 | 
			
		||||
    text: Joi.string()
 | 
			
		||||
      .allow('')
 | 
			
		||||
      .max(8192),
 | 
			
		||||
	private static help = {
 | 
			
		||||
		text: Joi.string()
 | 
			
		||||
		.allow('')
 | 
			
		||||
		.max(8192),
 | 
			
		||||
 | 
			
		||||
    level: Joi.string()
 | 
			
		||||
      .valid('none', ...Object.values(globals.levels))
 | 
			
		||||
  }
 | 
			
		||||
		level: Joi.string()
 | 
			
		||||
		.valid('none', ...Object.values(globals.levels))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static input (data) {
 | 
			
		||||
    return Joi.object({
 | 
			
		||||
      text: this.help.text.required(),
 | 
			
		||||
      level: this.help.level.required()
 | 
			
		||||
    }).validate(data);
 | 
			
		||||
  }
 | 
			
		||||
	static input (data) {
 | 
			
		||||
		return Joi.object({
 | 
			
		||||
			text: this.help.text.required(),
 | 
			
		||||
			level: this.help.level.required()
 | 
			
		||||
		}).validate(data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static output (data) {
 | 
			
		||||
    const {value, error} = Joi.object({
 | 
			
		||||
      text: this.help.text,
 | 
			
		||||
      level: this.help.level
 | 
			
		||||
    }).validate(data, {stripUnknown: true});
 | 
			
		||||
    return error !== undefined? null : value;
 | 
			
		||||
  }
 | 
			
		||||
	static output (data) {
 | 
			
		||||
		const {value, error} = Joi.object({
 | 
			
		||||
			text: this.help.text,
 | 
			
		||||
			level: this.help.level
 | 
			
		||||
		}).validate(data, {stripUnknown: true});
 | 
			
		||||
		return error !== undefined? null : value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static params(data) {
 | 
			
		||||
    return Joi.object({
 | 
			
		||||
      key: Joi.string().min(1).max(128)
 | 
			
		||||
    }).validate(data);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	static params(data) {
 | 
			
		||||
		return Joi.object({
 | 
			
		||||
			key: Joi.string().min(1).max(128)
 | 
			
		||||
		}).validate(data);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,33 +1,33 @@
 | 
			
		||||
import Joi from 'joi';
 | 
			
		||||
 | 
			
		||||
export default class IdValidate {
 | 
			
		||||
  private static id = Joi.string()
 | 
			
		||||
    .pattern(new RegExp('[0-9a-f]{24}'))
 | 
			
		||||
    .length(24)
 | 
			
		||||
    .messages({'string.pattern.base': 'Invalid object id'});
 | 
			
		||||
	private static id = Joi.string()
 | 
			
		||||
	.pattern(new RegExp('[0-9a-f]{24}'))
 | 
			
		||||
	.length(24)
 | 
			
		||||
	.messages({'string.pattern.base': 'Invalid object id'});
 | 
			
		||||
 | 
			
		||||
  static get () {  // return joi validation
 | 
			
		||||
    return this.id;
 | 
			
		||||
  }
 | 
			
		||||
	static get () {  // return joi validation
 | 
			
		||||
		return this.id;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static valid (id) {  // validate id
 | 
			
		||||
    return this.id.validate(id).error === undefined;
 | 
			
		||||
  }
 | 
			
		||||
	static valid (id) {  // validate id
 | 
			
		||||
		return this.id.validate(id).error === undefined;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static parameter () {  // :id url parameter
 | 
			
		||||
    return ':id([0-9a-f]{24})';
 | 
			
		||||
  }
 | 
			
		||||
	static parameter () {  // :id url parameter
 | 
			
		||||
		return ':id([0-9a-f]{24})';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static stringify (data) {  // convert all ObjectID objects to plain strings
 | 
			
		||||
    Object.keys(data).forEach(key => {
 | 
			
		||||
      // 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
 | 
			
		||||
        data[key] = this.stringify(data[key]);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    return data;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	static stringify (data) {  // convert all ObjectID objects to plain strings
 | 
			
		||||
		Object.keys(data).forEach(key => {
 | 
			
		||||
			// 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
 | 
			
		||||
				data[key] = this.stringify(data[key]);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		return data;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,99 +4,99 @@ import IdValidate from './id';
 | 
			
		||||
import globals from '../../globals';
 | 
			
		||||
 | 
			
		||||
export default class MaterialValidate {  // validate input for material
 | 
			
		||||
  private static material = {
 | 
			
		||||
    name: Joi.string()
 | 
			
		||||
      .max(128),
 | 
			
		||||
	private static material = {
 | 
			
		||||
		name: Joi.string()
 | 
			
		||||
		.max(128),
 | 
			
		||||
 | 
			
		||||
    supplier: Joi.string()
 | 
			
		||||
      .max(128),
 | 
			
		||||
		supplier: Joi.string()
 | 
			
		||||
		.max(128),
 | 
			
		||||
 | 
			
		||||
    group: Joi.string()
 | 
			
		||||
      .max(128),
 | 
			
		||||
		group: Joi.string()
 | 
			
		||||
		.max(128),
 | 
			
		||||
 | 
			
		||||
    properties: Joi.object(),
 | 
			
		||||
		properties: Joi.object(),
 | 
			
		||||
 | 
			
		||||
    numbers: Joi.array()
 | 
			
		||||
      .items(
 | 
			
		||||
        Joi.string()
 | 
			
		||||
          .max(64)
 | 
			
		||||
      ),
 | 
			
		||||
		numbers: Joi.array()
 | 
			
		||||
		.items(
 | 
			
		||||
			Joi.string()
 | 
			
		||||
			.max(64)
 | 
			
		||||
		),
 | 
			
		||||
 | 
			
		||||
    status: Joi.string()
 | 
			
		||||
      .valid(...Object.values(globals.status))
 | 
			
		||||
  };
 | 
			
		||||
		status: Joi.string()
 | 
			
		||||
		.valid(...Object.values(globals.status))
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
  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(),
 | 
			
		||||
        supplier: this.material.supplier.required(),
 | 
			
		||||
        group: this.material.group.required(),
 | 
			
		||||
        properties: this.material.properties.required(),
 | 
			
		||||
        numbers: this.material.numbers.required()
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else if (param === 'change') {
 | 
			
		||||
      return Joi.object({
 | 
			
		||||
        name: this.material.name,
 | 
			
		||||
        supplier: this.material.supplier,
 | 
			
		||||
        group: this.material.group,
 | 
			
		||||
        properties: this.material.properties,
 | 
			
		||||
        numbers: this.material.numbers
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return{error: 'No parameter specified!', value: {}};
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
	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(),
 | 
			
		||||
				supplier: this.material.supplier.required(),
 | 
			
		||||
				group: this.material.group.required(),
 | 
			
		||||
				properties: this.material.properties.required(),
 | 
			
		||||
				numbers: this.material.numbers.required()
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else if (param === 'change') {
 | 
			
		||||
			return Joi.object({
 | 
			
		||||
				name: this.material.name,
 | 
			
		||||
				supplier: this.material.supplier,
 | 
			
		||||
				group: this.material.group,
 | 
			
		||||
				properties: this.material.properties,
 | 
			
		||||
				numbers: this.material.numbers
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return{error: 'No parameter specified!', value: {}};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
    const validate: any = {
 | 
			
		||||
      _id: IdValidate.get(),
 | 
			
		||||
      name: this.material.name,
 | 
			
		||||
      supplier: this.material.supplier,
 | 
			
		||||
      group: this.material.group,
 | 
			
		||||
      properties: this.material.properties,
 | 
			
		||||
      numbers: this.material.numbers
 | 
			
		||||
    };
 | 
			
		||||
    if (status) {
 | 
			
		||||
      validate.status = this.material.status;
 | 
			
		||||
    }
 | 
			
		||||
    const {value, error} = Joi.object(validate).validate(data, {stripUnknown: true});
 | 
			
		||||
    return error !== undefined? null : value;
 | 
			
		||||
  }
 | 
			
		||||
	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;
 | 
			
		||||
	const validate: any = {
 | 
			
		||||
		_id: IdValidate.get(),
 | 
			
		||||
		name: this.material.name,
 | 
			
		||||
		supplier: this.material.supplier,
 | 
			
		||||
		group: this.material.group,
 | 
			
		||||
		properties: this.material.properties,
 | 
			
		||||
		numbers: this.material.numbers
 | 
			
		||||
	};
 | 
			
		||||
	if (status) {
 | 
			
		||||
		validate.status = this.material.status;
 | 
			
		||||
	}
 | 
			
		||||
	const {value, error} = Joi.object(validate).validate(data, {stripUnknown: true});
 | 
			
		||||
	return error !== undefined? null : value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  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 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
 | 
			
		||||
    const {value, error} = this.material.supplier.validate(data, {stripUnknown: true});
 | 
			
		||||
    return error !== undefined? null : value;
 | 
			
		||||
  }
 | 
			
		||||
	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
 | 
			
		||||
    return Joi.object({
 | 
			
		||||
      _id: IdValidate.get(),
 | 
			
		||||
      name: this.material.name,
 | 
			
		||||
      supplier: this.material.supplier,
 | 
			
		||||
      group: this.material.group,
 | 
			
		||||
      properties: this.material.properties,
 | 
			
		||||
      numbers: this.material.numbers
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
	static outputV() {  // return output validator
 | 
			
		||||
		return Joi.object({
 | 
			
		||||
			_id: IdValidate.get(),
 | 
			
		||||
			name: this.material.name,
 | 
			
		||||
			supplier: this.material.supplier,
 | 
			
		||||
			group: this.material.group,
 | 
			
		||||
			properties: this.material.properties,
 | 
			
		||||
			numbers: this.material.numbers
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static query (data, dev = false) {
 | 
			
		||||
    const acceptedStatuses = [globals.status.val, globals.status.new];
 | 
			
		||||
    if (dev) {  // dev and admin can also access deleted samples
 | 
			
		||||
      acceptedStatuses.push(globals.status.del)
 | 
			
		||||
    }
 | 
			
		||||
    return Joi.object({
 | 
			
		||||
      status: Joi.array().items(Joi.string().valid(...acceptedStatuses)).default([globals.status.val])
 | 
			
		||||
    }).validate(data);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	static query (data, dev = false) {
 | 
			
		||||
		const acceptedStatuses = [globals.status.val, globals.status.new];
 | 
			
		||||
		if (dev) {  // dev and admin can also access deleted samples
 | 
			
		||||
			acceptedStatuses.push(globals.status.del)
 | 
			
		||||
		}
 | 
			
		||||
		return Joi.object({
 | 
			
		||||
			status: Joi.array().items(Joi.string().valid(...acceptedStatuses)).default([globals.status.val])
 | 
			
		||||
		}).validate(data);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,64 +4,64 @@ import IdValidate from './id';
 | 
			
		||||
import globals from '../../globals';
 | 
			
		||||
 | 
			
		||||
export default class MeasurementValidate {
 | 
			
		||||
  private static measurement = {
 | 
			
		||||
    values: Joi.object()
 | 
			
		||||
      .pattern(/.*/, Joi.alternatives()
 | 
			
		||||
        .try(
 | 
			
		||||
          Joi.string().max(128),
 | 
			
		||||
          Joi.number(),
 | 
			
		||||
          Joi.boolean(),
 | 
			
		||||
          Joi.array().items(Joi.array().items(Joi.number())),  // for spectra
 | 
			
		||||
          Joi.array()
 | 
			
		||||
        )
 | 
			
		||||
        .allow(null)
 | 
			
		||||
      )
 | 
			
		||||
  };
 | 
			
		||||
	private static measurement = {
 | 
			
		||||
		values: Joi.object()
 | 
			
		||||
		.pattern(/.*/, Joi.alternatives()
 | 
			
		||||
.try(
 | 
			
		||||
	Joi.string().max(128),
 | 
			
		||||
	Joi.number(),
 | 
			
		||||
	Joi.boolean(),
 | 
			
		||||
	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
 | 
			
		||||
    if (param === 'new') {
 | 
			
		||||
      return Joi.object({
 | 
			
		||||
        sample_id: IdValidate.get().required(),
 | 
			
		||||
        values: this.measurement.values.required(),
 | 
			
		||||
        measurement_template: IdValidate.get().required()
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else if (param === 'change') {
 | 
			
		||||
      return Joi.object({
 | 
			
		||||
        values: this.measurement.values
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return{error: 'No parameter specified!', value: {}};
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
	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(),
 | 
			
		||||
				values: this.measurement.values.required(),
 | 
			
		||||
				measurement_template: IdValidate.get().required()
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else if (param === 'change') {
 | 
			
		||||
			return Joi.object({
 | 
			
		||||
				values: this.measurement.values
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return{error: 'No parameter specified!', value: {}};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  // 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
 | 
			
		||||
    if (['dev', 'admin'].indexOf(req.authDetails.level) < 0 && data.values[globals.spectrum.dpt]) {
 | 
			
		||||
      delete data.values[globals.spectrum.dpt];
 | 
			
		||||
    }
 | 
			
		||||
    const validation: any = {
 | 
			
		||||
      _id: IdValidate.get(),
 | 
			
		||||
      sample_id: IdValidate.get(),
 | 
			
		||||
      values: this.measurement.values,
 | 
			
		||||
      measurement_template: IdValidate.get()
 | 
			
		||||
    };
 | 
			
		||||
    if (status) {
 | 
			
		||||
      validation.status = Joi.string().valid(...Object.values(globals.status));
 | 
			
		||||
    }
 | 
			
		||||
    const {value, error} = Joi.object(validation).validate(data, {stripUnknown: true});
 | 
			
		||||
    return error !== undefined? null : value;
 | 
			
		||||
  }
 | 
			
		||||
	// 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
 | 
			
		||||
		if (['dev', 'admin'].indexOf(req.authDetails.level) < 0 && data.values[globals.spectrum.dpt]) {
 | 
			
		||||
			delete data.values[globals.spectrum.dpt];
 | 
			
		||||
		}
 | 
			
		||||
		const validation: any = {
 | 
			
		||||
			_id: IdValidate.get(),
 | 
			
		||||
			sample_id: IdValidate.get(),
 | 
			
		||||
			values: this.measurement.values,
 | 
			
		||||
			measurement_template: IdValidate.get()
 | 
			
		||||
		};
 | 
			
		||||
		if (status) {
 | 
			
		||||
			validation.status = Joi.string().valid(...Object.values(globals.status));
 | 
			
		||||
		}
 | 
			
		||||
		const {value, error} = Joi.object(validation).validate(data, {stripUnknown: true});
 | 
			
		||||
		return error !== undefined? null : value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static outputV() {  // return output validator
 | 
			
		||||
    return Joi.object({
 | 
			
		||||
      _id: IdValidate.get(),
 | 
			
		||||
      sample_id: IdValidate.get(),
 | 
			
		||||
      values: this.measurement.values,
 | 
			
		||||
      measurement_template: IdValidate.get()
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	static outputV() {  // return output validator
 | 
			
		||||
		return Joi.object({
 | 
			
		||||
			_id: IdValidate.get(),
 | 
			
		||||
			sample_id: IdValidate.get(),
 | 
			
		||||
			values: this.measurement.values,
 | 
			
		||||
			measurement_template: IdValidate.get()
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,40 +3,40 @@ import IdValidate from './id';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default class ModelValidate {  // validate input for model
 | 
			
		||||
  private static model = {
 | 
			
		||||
    group: Joi.string()
 | 
			
		||||
      .disallow('file')
 | 
			
		||||
      .max(128),
 | 
			
		||||
	private static model = {
 | 
			
		||||
		group: Joi.string()
 | 
			
		||||
		.disallow('file')
 | 
			
		||||
		.max(128),
 | 
			
		||||
 | 
			
		||||
    model: Joi.object({
 | 
			
		||||
        name: Joi.string()
 | 
			
		||||
          .max(128)
 | 
			
		||||
          .required(),
 | 
			
		||||
		model: Joi.object({
 | 
			
		||||
			name: Joi.string()
 | 
			
		||||
			.max(128)
 | 
			
		||||
			.required(),
 | 
			
		||||
 | 
			
		||||
        url: Joi.string()
 | 
			
		||||
          .uri()
 | 
			
		||||
          .max(512)
 | 
			
		||||
          .required()
 | 
			
		||||
      })
 | 
			
		||||
  };
 | 
			
		||||
			url: Joi.string()
 | 
			
		||||
			.uri()
 | 
			
		||||
			.max(512)
 | 
			
		||||
			.required()
 | 
			
		||||
		})
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
  static input (data) {  // validate input
 | 
			
		||||
    return this.model.model.required().validate(data);
 | 
			
		||||
  }
 | 
			
		||||
	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
 | 
			
		||||
    data = IdValidate.stringify(data);
 | 
			
		||||
    const {value, error} = Joi.object({
 | 
			
		||||
      group: this.model.group,
 | 
			
		||||
      models: Joi.array().items(this.model.model.append({_id: IdValidate.get()}))
 | 
			
		||||
    }).validate(data, {stripUnknown: true});
 | 
			
		||||
    return error !== undefined? null : value;
 | 
			
		||||
  }
 | 
			
		||||
	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,
 | 
			
		||||
		models: Joi.array().items(this.model.model.append({_id: IdValidate.get()}))
 | 
			
		||||
	}).validate(data, {stripUnknown: true});
 | 
			
		||||
	return error !== undefined? null : value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static fileOutput (data) {
 | 
			
		||||
    return {
 | 
			
		||||
      name: data.name,
 | 
			
		||||
      size: data.data.length
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	static fileOutput (data) {
 | 
			
		||||
		return {
 | 
			
		||||
			name: data.name,
 | 
			
		||||
			size: data.data.length
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,18 @@
 | 
			
		||||
import Joi from 'joi';
 | 
			
		||||
 | 
			
		||||
export default class NoteFieldValidate {
 | 
			
		||||
  private static note_field = {
 | 
			
		||||
    name: Joi.string()
 | 
			
		||||
      .max(128),
 | 
			
		||||
	private static note_field = {
 | 
			
		||||
		name: Joi.string()
 | 
			
		||||
		.max(128),
 | 
			
		||||
 | 
			
		||||
    qty: Joi.number()
 | 
			
		||||
  };
 | 
			
		||||
		qty: Joi.number()
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
    }).validate(data, {stripUnknown: true});
 | 
			
		||||
    return error !== undefined? null : value;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	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
 | 
			
		||||
		}).validate(data, {stripUnknown: true});
 | 
			
		||||
		return error !== undefined? null : value;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,42 +1,42 @@
 | 
			
		||||
import Joi from 'joi';
 | 
			
		||||
 | 
			
		||||
export default class ParametersValidate {
 | 
			
		||||
  // data to validate, parameters from template, param: 'new', 'change', 'null'(null values are allowed)
 | 
			
		||||
  static input (data, parameters, param) {
 | 
			
		||||
    let joiObject = {};
 | 
			
		||||
    parameters.forEach(parameter => {
 | 
			
		||||
      switch (parameter.range.type) {
 | 
			
		||||
        case 'number': joiObject[parameter.name] = Joi.number();
 | 
			
		||||
          break;
 | 
			
		||||
        case 'boolean': joiObject[parameter.name] = Joi.boolean();
 | 
			
		||||
          break;
 | 
			
		||||
        case 'array': joiObject[parameter.name] = Joi.array();
 | 
			
		||||
          break;
 | 
			
		||||
        case 'string': joiObject[parameter.name] = Joi.string().max(128);
 | 
			
		||||
          break;     //  min or max implicitly define the value to be a number
 | 
			
		||||
        default: if (parameter.range.hasOwnProperty('min') || parameter.range.hasOwnProperty('max')) {
 | 
			
		||||
          joiObject[parameter.name] = Joi.number();
 | 
			
		||||
          }
 | 
			
		||||
          else {
 | 
			
		||||
            joiObject[parameter.name] = Joi.string().max(128);
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
      if (parameter.range.hasOwnProperty('min')) {
 | 
			
		||||
        joiObject[parameter.name] = joiObject[parameter.name].min(parameter.range.min)
 | 
			
		||||
      }
 | 
			
		||||
      if (parameter.range.hasOwnProperty('max')) {
 | 
			
		||||
        joiObject[parameter.name] = joiObject[parameter.name].max(parameter.range.max)
 | 
			
		||||
      }
 | 
			
		||||
      if (parameter.range.hasOwnProperty('values')) {
 | 
			
		||||
        joiObject[parameter.name] = joiObject[parameter.name].valid(...parameter.range.values);
 | 
			
		||||
      }
 | 
			
		||||
      if (parameter.range.hasOwnProperty('required') && parameter.range.required) {
 | 
			
		||||
        joiObject[parameter.name] = joiObject[parameter.name].required();
 | 
			
		||||
      }
 | 
			
		||||
      if (param === 'null') {
 | 
			
		||||
        joiObject[parameter.name] = joiObject[parameter.name].allow(null)
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    return Joi.object(joiObject).validate(data);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	// data to validate, parameters from template, param: 'new', 'change', 'null'(null values are allowed)
 | 
			
		||||
	static input (data, parameters, param) {
 | 
			
		||||
		let joiObject = {};
 | 
			
		||||
		parameters.forEach(parameter => {
 | 
			
		||||
			switch (parameter.range.type) {
 | 
			
		||||
				case 'number': joiObject[parameter.name] = Joi.number();
 | 
			
		||||
				break;
 | 
			
		||||
				case 'boolean': joiObject[parameter.name] = Joi.boolean();
 | 
			
		||||
				break;
 | 
			
		||||
				case 'array': joiObject[parameter.name] = Joi.array();
 | 
			
		||||
				break;
 | 
			
		||||
				case 'string': joiObject[parameter.name] = Joi.string().max(128);
 | 
			
		||||
				break;     //  min or max implicitly define the value to be a number
 | 
			
		||||
				default: if (parameter.range.hasOwnProperty('min') || parameter.range.hasOwnProperty('max')) {
 | 
			
		||||
					joiObject[parameter.name] = Joi.number();
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					joiObject[parameter.name] = Joi.string().max(128);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (parameter.range.hasOwnProperty('min')) {
 | 
			
		||||
				joiObject[parameter.name] = joiObject[parameter.name].min(parameter.range.min)
 | 
			
		||||
			}
 | 
			
		||||
			if (parameter.range.hasOwnProperty('max')) {
 | 
			
		||||
				joiObject[parameter.name] = joiObject[parameter.name].max(parameter.range.max)
 | 
			
		||||
			}
 | 
			
		||||
			if (parameter.range.hasOwnProperty('values')) {
 | 
			
		||||
				joiObject[parameter.name] = joiObject[parameter.name].valid(...parameter.range.values);
 | 
			
		||||
			}
 | 
			
		||||
			if (parameter.range.hasOwnProperty('required') && parameter.range.required) {
 | 
			
		||||
				joiObject[parameter.name] = joiObject[parameter.name].required();
 | 
			
		||||
			}
 | 
			
		||||
			if (param === 'null') {
 | 
			
		||||
				joiObject[parameter.name] = joiObject[parameter.name].allow(null)
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		return Joi.object(joiObject).validate(data);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
// 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});
 | 
			
		||||
}
 | 
			
		||||
	res.status(400).json({status: 'Invalid body format', details: error.details[0].message});
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,50 +2,50 @@ import Joi from 'joi';
 | 
			
		||||
import IdValidate from './id';
 | 
			
		||||
 | 
			
		||||
export default class RootValidate {  // validate input for root methods
 | 
			
		||||
  private static changelog = {
 | 
			
		||||
    timestamp: Joi.date()
 | 
			
		||||
      .iso()
 | 
			
		||||
      .min('1970-01-01T00:00:00.000Z'),
 | 
			
		||||
	private static changelog = {
 | 
			
		||||
		timestamp: Joi.date()
 | 
			
		||||
		.iso()
 | 
			
		||||
		.min('1970-01-01T00:00:00.000Z'),
 | 
			
		||||
 | 
			
		||||
    page: Joi.number()
 | 
			
		||||
      .integer()
 | 
			
		||||
      .min(0)
 | 
			
		||||
      .default(0),
 | 
			
		||||
		page: Joi.number()
 | 
			
		||||
		.integer()
 | 
			
		||||
		.min(0)
 | 
			
		||||
		.default(0),
 | 
			
		||||
 | 
			
		||||
    pagesize: Joi.number()
 | 
			
		||||
      .integer()
 | 
			
		||||
      .min(0)
 | 
			
		||||
      .default(25),
 | 
			
		||||
		pagesize: Joi.number()
 | 
			
		||||
		.integer()
 | 
			
		||||
		.min(0)
 | 
			
		||||
		.default(25),
 | 
			
		||||
 | 
			
		||||
    action: Joi.string(),
 | 
			
		||||
		action: Joi.string(),
 | 
			
		||||
 | 
			
		||||
    collection: Joi.string(),
 | 
			
		||||
		collection: Joi.string(),
 | 
			
		||||
 | 
			
		||||
    conditions: Joi.object(),
 | 
			
		||||
		conditions: Joi.object(),
 | 
			
		||||
 | 
			
		||||
    data: Joi.object()
 | 
			
		||||
  };
 | 
			
		||||
		data: Joi.object()
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
  static changelogParams (data) {
 | 
			
		||||
    return Joi.object({
 | 
			
		||||
      id: IdValidate.get(),
 | 
			
		||||
      page: this.changelog.page,
 | 
			
		||||
      pagesize: this.changelog.pagesize
 | 
			
		||||
    }).validate(data);
 | 
			
		||||
  }
 | 
			
		||||
	static changelogParams (data) {
 | 
			
		||||
		return Joi.object({
 | 
			
		||||
			id: IdValidate.get(),
 | 
			
		||||
			page: this.changelog.page,
 | 
			
		||||
			pagesize: this.changelog.pagesize
 | 
			
		||||
		}).validate(data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static changelogOutput (data) {
 | 
			
		||||
    data.date = data._id.getTimestamp();
 | 
			
		||||
    data.collection = data.collection_name;
 | 
			
		||||
    data = IdValidate.stringify(data);
 | 
			
		||||
    const {value, error} = Joi.object({
 | 
			
		||||
      _id: IdValidate.get(),
 | 
			
		||||
      date: this.changelog.timestamp,
 | 
			
		||||
      action: this.changelog.action,
 | 
			
		||||
      collection: this.changelog.collection,
 | 
			
		||||
      conditions: this.changelog.conditions,
 | 
			
		||||
      data: this.changelog.data,
 | 
			
		||||
    }).validate(data, {stripUnknown: true});
 | 
			
		||||
    return error !== undefined? null : value;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	static changelogOutput (data) {
 | 
			
		||||
		data.date = data._id.getTimestamp();
 | 
			
		||||
		data.collection = data.collection_name;
 | 
			
		||||
		data = IdValidate.stringify(data);
 | 
			
		||||
		const {value, error} = Joi.object({
 | 
			
		||||
			_id: IdValidate.get(),
 | 
			
		||||
			date: this.changelog.timestamp,
 | 
			
		||||
			action: this.changelog.action,
 | 
			
		||||
			collection: this.changelog.collection,
 | 
			
		||||
			conditions: this.changelog.conditions,
 | 
			
		||||
			data: this.changelog.data,
 | 
			
		||||
		}).validate(data, {stripUnknown: true});
 | 
			
		||||
		return error !== undefined? null : value;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,273 +8,273 @@ import globals from '../../globals';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default class SampleValidate {
 | 
			
		||||
  private static sample = {
 | 
			
		||||
    number: Joi.string()
 | 
			
		||||
      .max(128),
 | 
			
		||||
	private static sample = {
 | 
			
		||||
		number: Joi.string()
 | 
			
		||||
		.max(128),
 | 
			
		||||
 | 
			
		||||
    color: Joi.string()
 | 
			
		||||
      .max(128)
 | 
			
		||||
      .allow(''),
 | 
			
		||||
		color: Joi.string()
 | 
			
		||||
		.max(128)
 | 
			
		||||
		.allow(''),
 | 
			
		||||
 | 
			
		||||
    type: Joi.string()
 | 
			
		||||
      .valid('as-delivered/raw', 'processed'),
 | 
			
		||||
		type: Joi.string()
 | 
			
		||||
		.valid('as-delivered/raw', 'processed'),
 | 
			
		||||
 | 
			
		||||
    batch: Joi.string()
 | 
			
		||||
      .max(128)
 | 
			
		||||
      .allow(''),
 | 
			
		||||
		batch: Joi.string()
 | 
			
		||||
		.max(128)
 | 
			
		||||
		.allow(''),
 | 
			
		||||
 | 
			
		||||
    condition: Joi.object(),
 | 
			
		||||
		condition: Joi.object(),
 | 
			
		||||
 | 
			
		||||
    notes: Joi.object({
 | 
			
		||||
      comment: Joi.string()
 | 
			
		||||
        .max(512)
 | 
			
		||||
        .allow('')
 | 
			
		||||
        .allow(null),
 | 
			
		||||
		notes: Joi.object({
 | 
			
		||||
			comment: Joi.string()
 | 
			
		||||
			.max(512)
 | 
			
		||||
			.allow('')
 | 
			
		||||
			.allow(null),
 | 
			
		||||
 | 
			
		||||
      sample_references: Joi.array()
 | 
			
		||||
        .items(Joi.object({
 | 
			
		||||
          sample_id: IdValidate.get(),
 | 
			
		||||
			sample_references: Joi.array()
 | 
			
		||||
			.items(Joi.object({
 | 
			
		||||
				sample_id: IdValidate.get(),
 | 
			
		||||
 | 
			
		||||
          relation: Joi.string()
 | 
			
		||||
            .max(128)
 | 
			
		||||
        })),
 | 
			
		||||
				relation: Joi.string()
 | 
			
		||||
				.max(128)
 | 
			
		||||
			})),
 | 
			
		||||
 | 
			
		||||
      custom_fields: Joi.object()
 | 
			
		||||
        .pattern(/.*/, Joi.alternatives()
 | 
			
		||||
          .try(
 | 
			
		||||
            Joi.string().max(128),
 | 
			
		||||
            Joi.number(),
 | 
			
		||||
            Joi.boolean(),
 | 
			
		||||
            Joi.date()
 | 
			
		||||
          )
 | 
			
		||||
        )
 | 
			
		||||
    }),
 | 
			
		||||
			custom_fields: Joi.object()
 | 
			
		||||
			.pattern(/.*/, Joi.alternatives()
 | 
			
		||||
.try(
 | 
			
		||||
	Joi.string().max(128),
 | 
			
		||||
	Joi.number(),
 | 
			
		||||
	Joi.boolean(),
 | 
			
		||||
	Joi.date()
 | 
			
		||||
)
 | 
			
		||||
					)
 | 
			
		||||
		}),
 | 
			
		||||
 | 
			
		||||
    added: Joi.date()
 | 
			
		||||
      .iso()
 | 
			
		||||
      .min('1970-01-01T00:00:00.000Z'),
 | 
			
		||||
		added: Joi.date()
 | 
			
		||||
		.iso()
 | 
			
		||||
		.min('1970-01-01T00:00:00.000Z'),
 | 
			
		||||
 | 
			
		||||
    status: Joi.string()
 | 
			
		||||
      .valid(...Object.values(globals.status))
 | 
			
		||||
  };
 | 
			
		||||
		status: Joi.string()
 | 
			
		||||
		.valid(...Object.values(globals.status))
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
  static readonly sampleKeys = [  // keys which can be found in the sample directly
 | 
			
		||||
    '_id',
 | 
			
		||||
    'color',
 | 
			
		||||
    'number',
 | 
			
		||||
    'type',
 | 
			
		||||
    'batch',
 | 
			
		||||
    'added',
 | 
			
		||||
    'condition',
 | 
			
		||||
    'material_id',
 | 
			
		||||
    'note_id',
 | 
			
		||||
    'user_id'
 | 
			
		||||
  ];
 | 
			
		||||
	static readonly sampleKeys = [  // keys which can be found in the sample directly
 | 
			
		||||
		'_id',
 | 
			
		||||
		'color',
 | 
			
		||||
		'number',
 | 
			
		||||
		'type',
 | 
			
		||||
		'batch',
 | 
			
		||||
		'added',
 | 
			
		||||
		'condition',
 | 
			
		||||
		'material_id',
 | 
			
		||||
		'note_id',
 | 
			
		||||
		'user_id'
 | 
			
		||||
	];
 | 
			
		||||
 | 
			
		||||
  private static sortKeys = [
 | 
			
		||||
    '_id',
 | 
			
		||||
    'color',
 | 
			
		||||
    'number',
 | 
			
		||||
    'type',
 | 
			
		||||
    'batch',
 | 
			
		||||
    'added',
 | 
			
		||||
    'status',
 | 
			
		||||
    'notes.comment',
 | 
			
		||||
    'material.name',
 | 
			
		||||
    'material.supplier',
 | 
			
		||||
    'material.group',
 | 
			
		||||
    'material.properties.*',
 | 
			
		||||
    'condition.*',
 | 
			
		||||
    `measurements.(?!${globals.spectrum.spectrum}.${globals.spectrum.dpt})*`
 | 
			
		||||
  ];
 | 
			
		||||
	private static sortKeys = [
 | 
			
		||||
		'_id',
 | 
			
		||||
		'color',
 | 
			
		||||
		'number',
 | 
			
		||||
		'type',
 | 
			
		||||
		'batch',
 | 
			
		||||
		'added',
 | 
			
		||||
		'status',
 | 
			
		||||
		'notes.comment',
 | 
			
		||||
		'material.name',
 | 
			
		||||
		'material.supplier',
 | 
			
		||||
		'material.group',
 | 
			
		||||
		'material.properties.*',
 | 
			
		||||
		'condition.*',
 | 
			
		||||
		`measurements.(?!${globals.spectrum.spectrum}.${globals.spectrum.dpt})*`
 | 
			
		||||
	];
 | 
			
		||||
 | 
			
		||||
  private static fieldKeys = [
 | 
			
		||||
    ...SampleValidate.sortKeys,
 | 
			
		||||
    'condition',
 | 
			
		||||
    'notes',
 | 
			
		||||
    'material_id',
 | 
			
		||||
    'material',
 | 
			
		||||
    'note_id',
 | 
			
		||||
    'user_id',
 | 
			
		||||
    'material._id',
 | 
			
		||||
    'material.numbers',
 | 
			
		||||
    'measurements',
 | 
			
		||||
    `measurements.${globals.spectrum.spectrum}.${globals.spectrum.dpt}`,
 | 
			
		||||
  ];
 | 
			
		||||
	private static fieldKeys = [
 | 
			
		||||
		...SampleValidate.sortKeys,
 | 
			
		||||
		'condition',
 | 
			
		||||
		'notes',
 | 
			
		||||
		'material_id',
 | 
			
		||||
		'material',
 | 
			
		||||
		'note_id',
 | 
			
		||||
		'user_id',
 | 
			
		||||
		'material._id',
 | 
			
		||||
		'material.numbers',
 | 
			
		||||
		'measurements',
 | 
			
		||||
		`measurements.${globals.spectrum.spectrum}.${globals.spectrum.dpt}`,
 | 
			
		||||
	];
 | 
			
		||||
 | 
			
		||||
  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(),
 | 
			
		||||
        type: this.sample.type.required(),
 | 
			
		||||
        batch: this.sample.batch.required(),
 | 
			
		||||
        condition: this.sample.condition.required(),
 | 
			
		||||
        material_id: IdValidate.get().required(),
 | 
			
		||||
        notes: this.sample.notes.required()
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else if (param === 'change') {
 | 
			
		||||
      return Joi.object({
 | 
			
		||||
        color: this.sample.color,
 | 
			
		||||
        type: this.sample.type,
 | 
			
		||||
        batch: this.sample.batch,
 | 
			
		||||
        condition: this.sample.condition,
 | 
			
		||||
        material_id: IdValidate.get(),
 | 
			
		||||
        notes: this.sample.notes,
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else if (param === 'new-admin') {
 | 
			
		||||
      return Joi.object({
 | 
			
		||||
        number: this.sample.number,
 | 
			
		||||
        color: this.sample.color.required(),
 | 
			
		||||
        type: this.sample.type.required(),
 | 
			
		||||
        batch: this.sample.batch.required(),
 | 
			
		||||
        condition: this.sample.condition.required(),
 | 
			
		||||
        material_id: IdValidate.get().required(),
 | 
			
		||||
        notes: this.sample.notes.required()
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return{error: 'No parameter specified!', value: {}};
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
	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(),
 | 
			
		||||
				type: this.sample.type.required(),
 | 
			
		||||
				batch: this.sample.batch.required(),
 | 
			
		||||
				condition: this.sample.condition.required(),
 | 
			
		||||
				material_id: IdValidate.get().required(),
 | 
			
		||||
				notes: this.sample.notes.required()
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else if (param === 'change') {
 | 
			
		||||
			return Joi.object({
 | 
			
		||||
				color: this.sample.color,
 | 
			
		||||
				type: this.sample.type,
 | 
			
		||||
				batch: this.sample.batch,
 | 
			
		||||
				condition: this.sample.condition,
 | 
			
		||||
				material_id: IdValidate.get(),
 | 
			
		||||
				notes: this.sample.notes,
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else if (param === 'new-admin') {
 | 
			
		||||
			return Joi.object({
 | 
			
		||||
				number: this.sample.number,
 | 
			
		||||
				color: this.sample.color.required(),
 | 
			
		||||
				type: this.sample.type.required(),
 | 
			
		||||
				batch: this.sample.batch.required(),
 | 
			
		||||
				condition: this.sample.condition.required(),
 | 
			
		||||
				material_id: IdValidate.get().required(),
 | 
			
		||||
				notes: this.sample.notes.required()
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return{error: 'No parameter specified!', value: {}};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  // validate output and strip unwanted properties, returns null if not valid
 | 
			
		||||
  static output (data, param = 'refs+added', additionalParams = []) {
 | 
			
		||||
    if (param === 'refs+added') {
 | 
			
		||||
      param = 'refs';
 | 
			
		||||
      data.added = data._id.getTimestamp();
 | 
			
		||||
    }
 | 
			
		||||
    data = IdValidate.stringify(data);
 | 
			
		||||
    let joiObject;
 | 
			
		||||
    if (param === 'refs') {
 | 
			
		||||
      joiObject = {
 | 
			
		||||
        _id: IdValidate.get(),
 | 
			
		||||
        number: this.sample.number,
 | 
			
		||||
        color: this.sample.color,
 | 
			
		||||
        type: this.sample.type,
 | 
			
		||||
        batch: this.sample.batch,
 | 
			
		||||
        condition: this.sample.condition,
 | 
			
		||||
        material_id: IdValidate.get(),
 | 
			
		||||
        material: MaterialValidate.outputV().append({number: Joi.string().max(128).allow('')}),
 | 
			
		||||
        note_id: IdValidate.get().allow(null),
 | 
			
		||||
        notes: this.sample.notes,
 | 
			
		||||
        user_id: IdValidate.get(),
 | 
			
		||||
        added: this.sample.added,
 | 
			
		||||
        status: this.sample.status
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
    else if(param === 'details') {
 | 
			
		||||
      joiObject = {
 | 
			
		||||
        _id: IdValidate.get(),
 | 
			
		||||
        number: this.sample.number,
 | 
			
		||||
        color: this.sample.color,
 | 
			
		||||
        type: this.sample.type,
 | 
			
		||||
        batch: this.sample.batch,
 | 
			
		||||
        condition: this.sample.condition,
 | 
			
		||||
        material: MaterialValidate.outputV(),
 | 
			
		||||
        measurements: Joi.array().items(MeasurementValidate.outputV()),
 | 
			
		||||
        notes: this.sample.notes,
 | 
			
		||||
        user: UserValidate.username(),
 | 
			
		||||
        status: this.sample.status
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    additionalParams.forEach(param => {
 | 
			
		||||
      joiObject[param] = Joi.any();
 | 
			
		||||
    });
 | 
			
		||||
    const {value, error} = Joi.object(joiObject).validate(data, {stripUnknown: true});
 | 
			
		||||
    return error !== undefined? null : value;
 | 
			
		||||
  }
 | 
			
		||||
	// validate output and strip unwanted properties, returns null if not valid
 | 
			
		||||
	static output (data, param = 'refs+added', additionalParams = []) {
 | 
			
		||||
		if (param === 'refs+added') {
 | 
			
		||||
			param = 'refs';
 | 
			
		||||
			data.added = data._id.getTimestamp();
 | 
			
		||||
		}
 | 
			
		||||
		data = IdValidate.stringify(data);
 | 
			
		||||
		let joiObject;
 | 
			
		||||
		if (param === 'refs') {
 | 
			
		||||
			joiObject = {
 | 
			
		||||
				_id: IdValidate.get(),
 | 
			
		||||
				number: this.sample.number,
 | 
			
		||||
				color: this.sample.color,
 | 
			
		||||
				type: this.sample.type,
 | 
			
		||||
				batch: this.sample.batch,
 | 
			
		||||
				condition: this.sample.condition,
 | 
			
		||||
				material_id: IdValidate.get(),
 | 
			
		||||
				material: MaterialValidate.outputV().append({number: Joi.string().max(128).allow('')}),
 | 
			
		||||
				note_id: IdValidate.get().allow(null),
 | 
			
		||||
				notes: this.sample.notes,
 | 
			
		||||
				user_id: IdValidate.get(),
 | 
			
		||||
				added: this.sample.added,
 | 
			
		||||
				status: this.sample.status
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
		else if(param === 'details') {
 | 
			
		||||
			joiObject = {
 | 
			
		||||
				_id: IdValidate.get(),
 | 
			
		||||
				number: this.sample.number,
 | 
			
		||||
				color: this.sample.color,
 | 
			
		||||
				type: this.sample.type,
 | 
			
		||||
				batch: this.sample.batch,
 | 
			
		||||
				condition: this.sample.condition,
 | 
			
		||||
				material: MaterialValidate.outputV(),
 | 
			
		||||
				measurements: Joi.array().items(MeasurementValidate.outputV()),
 | 
			
		||||
				notes: this.sample.notes,
 | 
			
		||||
				user: UserValidate.username(),
 | 
			
		||||
				status: this.sample.status
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		additionalParams.forEach(param => {
 | 
			
		||||
			joiObject[param] = Joi.any();
 | 
			
		||||
		});
 | 
			
		||||
		const {value, error} = Joi.object(joiObject).validate(data, {stripUnknown: true});
 | 
			
		||||
		return error !== undefined? null : value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static query (data, dev = false) {
 | 
			
		||||
    if (data.filters && data.filters.length) {
 | 
			
		||||
      const filterValidation = Joi.array().items(Joi.string()).validate(data.filters);
 | 
			
		||||
      if (filterValidation.error) return filterValidation;
 | 
			
		||||
      try {
 | 
			
		||||
        for (let i in data.filters) {
 | 
			
		||||
          try {
 | 
			
		||||
            data.filters[i] = decodeURIComponent(data.filters[i]);
 | 
			
		||||
          }
 | 
			
		||||
          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
 | 
			
		||||
              return null;
 | 
			
		||||
            }
 | 
			
		||||
            let validator;
 | 
			
		||||
            let field = data.filters[i].field;
 | 
			
		||||
            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(''))
 | 
			
		||||
              });
 | 
			
		||||
              field = field.replace('material.', '').split('.')[0];
 | 
			
		||||
            }
 | 
			
		||||
            else if (/measurements\./.test(field) || /condition\./.test(field)) {
 | 
			
		||||
              validator = Joi.object({
 | 
			
		||||
                value: Joi.alternatives()
 | 
			
		||||
                  .try(
 | 
			
		||||
                    Joi.number(),
 | 
			
		||||
                    Joi.string().max(128).allow(''),
 | 
			
		||||
                    Joi.boolean(),
 | 
			
		||||
                    Joi.array()
 | 
			
		||||
                  )
 | 
			
		||||
                  .allow(null)
 | 
			
		||||
              });
 | 
			
		||||
              field = 'value';
 | 
			
		||||
            }
 | 
			
		||||
            else if (field === 'measurements') {
 | 
			
		||||
              validator = Joi.object({
 | 
			
		||||
                value: Joi.object({}).allow(null).disallow({})
 | 
			
		||||
              });
 | 
			
		||||
              field = 'value';
 | 
			
		||||
            }
 | 
			
		||||
            else if (field === 'notes.comment') {
 | 
			
		||||
              field = 'comment';
 | 
			
		||||
              validator = this.sample.notes
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
              validator = Joi.object(this.sample);
 | 
			
		||||
            }
 | 
			
		||||
            const {value, error} = validator.validate({[field]: e});
 | 
			
		||||
            if (error) throw error;  // reject invalid values
 | 
			
		||||
            return value[field];
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      catch (err) {
 | 
			
		||||
        return {error: {details: [{message: 'Invalid JSON string for filter parameter'}]}, value: null}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    const acceptedStatuses = [globals.status.val, globals.status.new];
 | 
			
		||||
    if (dev) {  // dev and admin can also access deleted samples
 | 
			
		||||
      acceptedStatuses.push(globals.status.del)
 | 
			
		||||
    }
 | 
			
		||||
    return Joi.object({
 | 
			
		||||
      status: Joi.array().items(Joi.string().valid(...acceptedStatuses)).default([globals.status.val]),
 | 
			
		||||
      'from-id': IdValidate.get(),
 | 
			
		||||
      'to-page': Joi.number().integer(),
 | 
			
		||||
      'page-size': Joi.number().integer().min(1),
 | 
			
		||||
      sort: Joi.string().pattern(
 | 
			
		||||
        new RegExp('^(' + this.sortKeys.join('|').replace(/\./g, '\\.').replace(/\*/g, '.+') + ')-(asc|desc)$', 'm')
 | 
			
		||||
      ).default('_id-asc'),
 | 
			
		||||
      output: Joi.string().valid('json', 'flatten', 'csv').default('json'),
 | 
			
		||||
      fields: Joi.array().items(Joi.string().pattern(
 | 
			
		||||
        new RegExp('^(' + this.fieldKeys.join('|').replace(/\./g, '\\.').replace(/\*/g, '.+') + ')$', 'm')
 | 
			
		||||
      )).default(['_id','number','type','batch','material_id','color','condition','note_id','user_id','added'])
 | 
			
		||||
        .messages({'string.pattern.base': 'Invalid field name'}),
 | 
			
		||||
      filters: Joi.array().items(Joi.object({
 | 
			
		||||
        mode: Joi.string().valid('eq', 'ne', 'lt', 'lte', 'gt', 'gte', 'in', 'nin', 'stringin'),
 | 
			
		||||
        field: Joi.string().pattern(
 | 
			
		||||
          new RegExp('^(' + this.fieldKeys.join('|').replace(/\./g, '\\.').replace(/\*/g, '.+') + ')$', 'm')
 | 
			
		||||
        ).messages({'string.pattern.base': 'Invalid filter field name'}),
 | 
			
		||||
        values: Joi.array().items(Joi.alternatives().try(
 | 
			
		||||
          Joi.string().max(128).allow(''), Joi.number(), Joi.boolean(), Joi.date().iso(), Joi.object(), null
 | 
			
		||||
        )).min(1)
 | 
			
		||||
      })).default([])
 | 
			
		||||
    }).with('to-page', 'page-size').validate(data);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	static query (data, dev = false) {
 | 
			
		||||
		if (data.filters && data.filters.length) {
 | 
			
		||||
			const filterValidation = Joi.array().items(Joi.string()).validate(data.filters);
 | 
			
		||||
			if (filterValidation.error) return filterValidation;
 | 
			
		||||
			try {
 | 
			
		||||
				for (let i in data.filters) {
 | 
			
		||||
					try {
 | 
			
		||||
						data.filters[i] = decodeURIComponent(data.filters[i]);
 | 
			
		||||
					}
 | 
			
		||||
					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
 | 
			
		||||
							return null;
 | 
			
		||||
						}
 | 
			
		||||
						let validator;
 | 
			
		||||
						let field = data.filters[i].field;
 | 
			
		||||
						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(''))
 | 
			
		||||
							});
 | 
			
		||||
							field = field.replace('material.', '').split('.')[0];
 | 
			
		||||
						}
 | 
			
		||||
						else if (/measurements\./.test(field) || /condition\./.test(field)) {
 | 
			
		||||
							validator = Joi.object({
 | 
			
		||||
								value: Joi.alternatives()
 | 
			
		||||
								.try(
 | 
			
		||||
									Joi.number(),
 | 
			
		||||
									Joi.string().max(128).allow(''),
 | 
			
		||||
									Joi.boolean(),
 | 
			
		||||
									Joi.array()
 | 
			
		||||
								)
 | 
			
		||||
								.allow(null)
 | 
			
		||||
							});
 | 
			
		||||
							field = 'value';
 | 
			
		||||
						}
 | 
			
		||||
						else if (field === 'measurements') {
 | 
			
		||||
							validator = Joi.object({
 | 
			
		||||
								value: Joi.object({}).allow(null).disallow({})
 | 
			
		||||
							});
 | 
			
		||||
							field = 'value';
 | 
			
		||||
						}
 | 
			
		||||
						else if (field === 'notes.comment') {
 | 
			
		||||
							field = 'comment';
 | 
			
		||||
							validator = this.sample.notes
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							validator = Joi.object(this.sample);
 | 
			
		||||
						}
 | 
			
		||||
						const {value, error} = validator.validate({[field]: e});
 | 
			
		||||
						if (error) throw error;  // reject invalid values
 | 
			
		||||
						return value[field];
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			catch (err) {
 | 
			
		||||
				return {error: {details: [{message: 'Invalid JSON string for filter parameter'}]}, value: null}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		const acceptedStatuses = [globals.status.val, globals.status.new];
 | 
			
		||||
		if (dev) {  // dev and admin can also access deleted samples
 | 
			
		||||
			acceptedStatuses.push(globals.status.del)
 | 
			
		||||
		}
 | 
			
		||||
		return Joi.object({
 | 
			
		||||
			status: Joi.array().items(Joi.string().valid(...acceptedStatuses)).default([globals.status.val]),
 | 
			
		||||
			'from-id': IdValidate.get(),
 | 
			
		||||
			'to-page': Joi.number().integer(),
 | 
			
		||||
			'page-size': Joi.number().integer().min(1),
 | 
			
		||||
			sort: Joi.string().pattern(
 | 
			
		||||
				new RegExp('^(' + this.sortKeys.join('|').replace(/\./g, '\\.').replace(/\*/g, '.+') + ')-(asc|desc)$', 'm')
 | 
			
		||||
			).default('_id-asc'),
 | 
			
		||||
			output: Joi.string().valid('json', 'flatten', 'csv').default('json'),
 | 
			
		||||
			fields: Joi.array().items(Joi.string().pattern(
 | 
			
		||||
				new RegExp('^(' + this.fieldKeys.join('|').replace(/\./g, '\\.').replace(/\*/g, '.+') + ')$', 'm')
 | 
			
		||||
			)).default(['_id','number','type','batch','material_id','color','condition','note_id','user_id','added'])
 | 
			
		||||
			.messages({'string.pattern.base': 'Invalid field name'}),
 | 
			
		||||
			filters: Joi.array().items(Joi.object({
 | 
			
		||||
				mode: Joi.string().valid('eq', 'ne', 'lt', 'lte', 'gt', 'gte', 'in', 'nin', 'stringin'),
 | 
			
		||||
				field: Joi.string().pattern(
 | 
			
		||||
					new RegExp('^(' + this.fieldKeys.join('|').replace(/\./g, '\\.').replace(/\*/g, '.+') + ')$', 'm')
 | 
			
		||||
				).messages({'string.pattern.base': 'Invalid filter field name'}),
 | 
			
		||||
				values: Joi.array().items(Joi.alternatives().try(
 | 
			
		||||
					Joi.string().max(128).allow(''), Joi.number(), Joi.boolean(), Joi.date().iso(), Joi.object(), null
 | 
			
		||||
				)).min(1)
 | 
			
		||||
			})).default([])
 | 
			
		||||
		}).with('to-page', 'page-size').validate(data);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,70 +2,70 @@ import Joi from 'joi';
 | 
			
		||||
import IdValidate from './id';
 | 
			
		||||
 | 
			
		||||
export default class TemplateValidate {
 | 
			
		||||
  private static template = {
 | 
			
		||||
    name: Joi.string()
 | 
			
		||||
      .max(128),
 | 
			
		||||
	private static template = {
 | 
			
		||||
		name: Joi.string()
 | 
			
		||||
		.max(128),
 | 
			
		||||
 | 
			
		||||
    version: Joi.number()
 | 
			
		||||
      .min(1),
 | 
			
		||||
		version: Joi.number()
 | 
			
		||||
		.min(1),
 | 
			
		||||
 | 
			
		||||
    parameters: Joi.array()
 | 
			
		||||
      .items(
 | 
			
		||||
        Joi.object({
 | 
			
		||||
          name: Joi.string()
 | 
			
		||||
            .max(128)
 | 
			
		||||
            .invalid('condition_template', 'material_template')
 | 
			
		||||
            .pattern(/^[^.]+$/)
 | 
			
		||||
            .required()
 | 
			
		||||
            .messages({'string.pattern.base': 'name must not contain a dot'}),
 | 
			
		||||
		parameters: Joi.array()
 | 
			
		||||
		.items(
 | 
			
		||||
			Joi.object({
 | 
			
		||||
				name: Joi.string()
 | 
			
		||||
				.max(128)
 | 
			
		||||
				.invalid('condition_template', 'material_template')
 | 
			
		||||
				.pattern(/^[^.]+$/)
 | 
			
		||||
				.required()
 | 
			
		||||
				.messages({'string.pattern.base': 'name must not contain a dot'}),
 | 
			
		||||
 | 
			
		||||
          range: Joi.object({
 | 
			
		||||
            values: Joi.array()
 | 
			
		||||
              .min(1),
 | 
			
		||||
				range: Joi.object({
 | 
			
		||||
					values: Joi.array()
 | 
			
		||||
					.min(1),
 | 
			
		||||
 | 
			
		||||
            min: Joi.number(),
 | 
			
		||||
					min: Joi.number(),
 | 
			
		||||
 | 
			
		||||
            max: Joi.number(),
 | 
			
		||||
					max: Joi.number(),
 | 
			
		||||
 | 
			
		||||
            type: Joi.string()
 | 
			
		||||
              .valid('string', 'number', 'boolean', 'array'),
 | 
			
		||||
					type: Joi.string()
 | 
			
		||||
					.valid('string', 'number', 'boolean', 'array'),
 | 
			
		||||
 | 
			
		||||
            required: Joi.boolean()
 | 
			
		||||
          })
 | 
			
		||||
            .oxor('values', 'min')
 | 
			
		||||
            .oxor('values', 'max')
 | 
			
		||||
            .required()
 | 
			
		||||
        })
 | 
			
		||||
      )
 | 
			
		||||
  };
 | 
			
		||||
					required: Joi.boolean()
 | 
			
		||||
				})
 | 
			
		||||
				.oxor('values', 'min')
 | 
			
		||||
				.oxor('values', 'max')
 | 
			
		||||
				.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(),
 | 
			
		||||
        parameters: this.template.parameters.required()
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else if (param === 'change') {
 | 
			
		||||
      return Joi.object({
 | 
			
		||||
        name: this.template.name,
 | 
			
		||||
        parameters: this.template.parameters
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return{error: 'No parameter specified!', value: {}};
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
	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(),
 | 
			
		||||
				parameters: this.template.parameters.required()
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else if (param === 'change') {
 | 
			
		||||
			return Joi.object({
 | 
			
		||||
				name: this.template.name,
 | 
			
		||||
				parameters: this.template.parameters
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return{error: 'No parameter specified!', value: {}};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  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(),
 | 
			
		||||
      name: this.template.name,
 | 
			
		||||
      version: this.template.version,
 | 
			
		||||
      first_id: IdValidate.get(),
 | 
			
		||||
      parameters: this.template.parameters
 | 
			
		||||
    }).validate(data, {stripUnknown: true});
 | 
			
		||||
    return error !== undefined? null : value;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
	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(),
 | 
			
		||||
		name: this.template.name,
 | 
			
		||||
		version: this.template.version,
 | 
			
		||||
		first_id: IdValidate.get(),
 | 
			
		||||
		parameters: this.template.parameters
 | 
			
		||||
	}).validate(data, {stripUnknown: true});
 | 
			
		||||
	return error !== undefined? null : value;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,104 +4,104 @@ import globals from '../../globals';
 | 
			
		||||
import IdValidate from './id';
 | 
			
		||||
 | 
			
		||||
export default class UserValidate {  // validate input for user
 | 
			
		||||
  private static user = {
 | 
			
		||||
    name: Joi.string()
 | 
			
		||||
      .lowercase()
 | 
			
		||||
      .pattern(new RegExp('^[a-z0-9-_.]+$'))
 | 
			
		||||
      .max(128)
 | 
			
		||||
      .messages({'string.pattern.base': 'name must only contain a-z0-9_.'}),
 | 
			
		||||
	private static user = {
 | 
			
		||||
		name: Joi.string()
 | 
			
		||||
		.lowercase()
 | 
			
		||||
		.pattern(new RegExp('^[a-z0-9-_.]+$'))
 | 
			
		||||
		.max(128)
 | 
			
		||||
		.messages({'string.pattern.base': 'name must only contain a-z0-9_.'}),
 | 
			
		||||
 | 
			
		||||
    email: Joi.string()
 | 
			
		||||
      .email({minDomainSegments: 2})
 | 
			
		||||
      .lowercase()
 | 
			
		||||
      .max(128),
 | 
			
		||||
		email: Joi.string()
 | 
			
		||||
		.email({minDomainSegments: 2})
 | 
			
		||||
		.lowercase()
 | 
			
		||||
		.max(128),
 | 
			
		||||
 | 
			
		||||
    pass: Joi.string()
 | 
			
		||||
      .min(8)
 | 
			
		||||
      .max(128),
 | 
			
		||||
		pass: Joi.string()
 | 
			
		||||
		.min(8)
 | 
			
		||||
		.max(128),
 | 
			
		||||
 | 
			
		||||
    level: Joi.string()
 | 
			
		||||
      .valid(...Object.values(globals.levels)),
 | 
			
		||||
		level: Joi.string()
 | 
			
		||||
		.valid(...Object.values(globals.levels)),
 | 
			
		||||
 | 
			
		||||
    location: Joi.string()
 | 
			
		||||
      .alphanum()
 | 
			
		||||
      .max(128),
 | 
			
		||||
		location: Joi.string()
 | 
			
		||||
		.alphanum()
 | 
			
		||||
		.max(128),
 | 
			
		||||
 | 
			
		||||
    devices: Joi.array()
 | 
			
		||||
      .items(Joi.string()
 | 
			
		||||
        .allow('')
 | 
			
		||||
        .max(128)
 | 
			
		||||
      ),
 | 
			
		||||
		devices: Joi.array()
 | 
			
		||||
		.items(Joi.string()
 | 
			
		||||
			   .allow('')
 | 
			
		||||
			   .max(128)
 | 
			
		||||
			  ),
 | 
			
		||||
 | 
			
		||||
    models: Joi.array()
 | 
			
		||||
      .items(IdValidate.get()),
 | 
			
		||||
			  models: Joi.array()
 | 
			
		||||
			  .items(IdValidate.get()),
 | 
			
		||||
 | 
			
		||||
    status: Joi.string()
 | 
			
		||||
      .valid(...Object.values(globals.status))
 | 
			
		||||
  };
 | 
			
		||||
			  status: Joi.string()
 | 
			
		||||
			  .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
 | 
			
		||||
    if (param === 'new') {
 | 
			
		||||
      return Joi.object({
 | 
			
		||||
        name: this.user.name.required(),
 | 
			
		||||
        email: this.user.email.required(),
 | 
			
		||||
        pass: this.user.pass.required(),
 | 
			
		||||
        level: this.user.level.required(),
 | 
			
		||||
        location: this.user.location.required(),
 | 
			
		||||
        devices: this.user.devices.required(),
 | 
			
		||||
        models: this.user.models.required()
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else if (param === 'change') {
 | 
			
		||||
      return Joi.object({
 | 
			
		||||
        name: this.user.name,
 | 
			
		||||
        email: this.user.email,
 | 
			
		||||
        pass: this.user.pass,
 | 
			
		||||
        location: this.user.location,
 | 
			
		||||
        devices: this.user.devices
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else if (param === 'changeadmin') {
 | 
			
		||||
      return Joi.object({
 | 
			
		||||
        name: this.user.name,
 | 
			
		||||
        email: this.user.email,
 | 
			
		||||
        pass: this.user.pass,
 | 
			
		||||
        level: this.user.level,
 | 
			
		||||
        location: this.user.location,
 | 
			
		||||
        devices: this.user.devices,
 | 
			
		||||
        models: this.user.models
 | 
			
		||||
      }).validate(data);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return {error: 'No parameter specified!', value: {}};
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
	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(),
 | 
			
		||||
				email: this.user.email.required(),
 | 
			
		||||
				pass: this.user.pass.required(),
 | 
			
		||||
				level: this.user.level.required(),
 | 
			
		||||
				location: this.user.location.required(),
 | 
			
		||||
				devices: this.user.devices.required(),
 | 
			
		||||
				models: this.user.models.required()
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else if (param === 'change') {
 | 
			
		||||
			return Joi.object({
 | 
			
		||||
				name: this.user.name,
 | 
			
		||||
				email: this.user.email,
 | 
			
		||||
				pass: this.user.pass,
 | 
			
		||||
				location: this.user.location,
 | 
			
		||||
				devices: this.user.devices
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else if (param === 'changeadmin') {
 | 
			
		||||
			return Joi.object({
 | 
			
		||||
				name: this.user.name,
 | 
			
		||||
				email: this.user.email,
 | 
			
		||||
				pass: this.user.pass,
 | 
			
		||||
				level: this.user.level,
 | 
			
		||||
				location: this.user.location,
 | 
			
		||||
				devices: this.user.devices,
 | 
			
		||||
				models: this.user.models
 | 
			
		||||
			}).validate(data);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return {error: 'No parameter specified!', value: {}};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  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(),
 | 
			
		||||
      name: this.user.name,
 | 
			
		||||
      email: this.user.email,
 | 
			
		||||
      level: this.user.level,
 | 
			
		||||
      location: this.user.location,
 | 
			
		||||
      devices: this.user.devices,
 | 
			
		||||
      models: this.user.models
 | 
			
		||||
    }
 | 
			
		||||
    if (param === 'admin') {
 | 
			
		||||
      validate.status = this.user.status;
 | 
			
		||||
    }
 | 
			
		||||
    const {value, error} = Joi.object(validate).validate(data, {stripUnknown: true});
 | 
			
		||||
    return error !== undefined? null : value;
 | 
			
		||||
  }
 | 
			
		||||
	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(),
 | 
			
		||||
		name: this.user.name,
 | 
			
		||||
		email: this.user.email,
 | 
			
		||||
		level: this.user.level,
 | 
			
		||||
		location: this.user.location,
 | 
			
		||||
		devices: this.user.devices,
 | 
			
		||||
		models: this.user.models
 | 
			
		||||
	}
 | 
			
		||||
	if (param === 'admin') {
 | 
			
		||||
		validate.status = this.user.status;
 | 
			
		||||
	}
 | 
			
		||||
	const {value, error} = Joi.object(validate).validate(data, {stripUnknown: true});
 | 
			
		||||
	return error !== undefined? null : value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static isSpecialName (name) {  // true if name belongs to special names
 | 
			
		||||
    return this.specialUsernames.indexOf(name) > -1;
 | 
			
		||||
  }
 | 
			
		||||
	static isSpecialName (name) {  // true if name belongs to special names
 | 
			
		||||
		return this.specialUsernames.indexOf(name) > -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  static username() {
 | 
			
		||||
    return this.user.name;
 | 
			
		||||
  }
 | 
			
		||||
	static username() {
 | 
			
		||||
		return this.user.name;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user