csv only for dev/admin, mail change notice
This commit is contained in:
		@@ -40,12 +40,6 @@
 | 
				
			|||||||
        schema:
 | 
					        schema:
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
        example: color-asc
 | 
					        example: color-asc
 | 
				
			||||||
      - name: csv
 | 
					 | 
				
			||||||
        description: output as csv
 | 
					 | 
				
			||||||
        in: query
 | 
					 | 
				
			||||||
        schema:
 | 
					 | 
				
			||||||
          type: boolean
 | 
					 | 
				
			||||||
        example: false
 | 
					 | 
				
			||||||
      - name: fields[]
 | 
					      - name: fields[]
 | 
				
			||||||
        description: "the fields to include in the output as array, defaults to ['_id', 'number', 'type',
 | 
					        description: "the fields to include in the output as array, defaults to ['_id', 'number', 'type',
 | 
				
			||||||
        'batch', 'material_id', 'color', 'condition', 'note_id', 'user_id', 'added']"
 | 
					        'batch', 'material_id', 'color', 'condition', 'note_id', 'user_id', 'added']"
 | 
				
			||||||
@@ -57,7 +51,8 @@
 | 
				
			|||||||
        example: ['number', 'batch']
 | 
					        example: ['number', 'batch']
 | 
				
			||||||
      - name: filters[]
 | 
					      - name: filters[]
 | 
				
			||||||
        description: "the filters to apply as an array of URIComponent encoded objects in the form {mode:
 | 
					        description: "the filters to apply as an array of URIComponent encoded objects in the form {mode:
 | 
				
			||||||
        'eq/ne/lt/lte/gt/gte/in/nin/stringin', field: 'material.m', values: ['15']} using encodeURIComponent(JSON.stringify({}))"
 | 
					        'eq/ne/lt/lte/gt/gte/in/nin/stringin', field: 'material.m', values: ['15']} using
 | 
				
			||||||
 | 
					        encodeURIComponent(JSON.stringify({}))"
 | 
				
			||||||
        in: query
 | 
					        in: query
 | 
				
			||||||
        schema:
 | 
					        schema:
 | 
				
			||||||
         type: array
 | 
					         type: array
 | 
				
			||||||
@@ -66,6 +61,12 @@
 | 
				
			|||||||
        example: '["%7B%22mode%22%3A%22eq%22%2C%22field%22%3A%22material.m%22%2C%22values%22%3A%5B%2215%22%5D%7D",
 | 
					        example: '["%7B%22mode%22%3A%22eq%22%2C%22field%22%3A%22material.m%22%2C%22values%22%3A%5B%2215%22%5D%7D",
 | 
				
			||||||
        "%7B%22mode%22%3A%22isin%22%2C%22field%22%3A%22material.supplier%22%2C%22values%22%3A%5B%22BASF%22%2C%22DSM%22
 | 
					        "%7B%22mode%22%3A%22isin%22%2C%22field%22%3A%22material.supplier%22%2C%22values%22%3A%5B%22BASF%22%2C%22DSM%22
 | 
				
			||||||
        %5D%7D"]'
 | 
					        %5D%7D"]'
 | 
				
			||||||
 | 
					      - name: csv
 | 
				
			||||||
 | 
					        description: output as csv, only available for dev and admin
 | 
				
			||||||
 | 
					        in: query
 | 
				
			||||||
 | 
					        schema:
 | 
				
			||||||
 | 
					          type: boolean
 | 
				
			||||||
 | 
					        example: false
 | 
				
			||||||
    responses:
 | 
					    responses:
 | 
				
			||||||
      200:
 | 
					      200:
 | 
				
			||||||
        description: samples overview (output depends on the fields specified)<br>
 | 
					        description: samples overview (output depends on the fields specified)<br>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,8 +7,6 @@ import TestHelper from "../test/helper";
 | 
				
			|||||||
import mongoose from 'mongoose';
 | 
					import mongoose from 'mongoose';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: allowed types: tension rod, part, granulate, other
 | 
					 | 
				
			||||||
// TODO: filter by conditions and material properties
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('/sample', () => {
 | 
					describe('/sample', () => {
 | 
				
			||||||
  let server;
 | 
					  let server;
 | 
				
			||||||
@@ -451,12 +449,12 @@ describe('/sample', () => {
 | 
				
			|||||||
        res: {status: 'Invalid body format', details: 'Measurement key not found'}
 | 
					        res: {status: 'Invalid body format', details: 'Measurement key not found'}
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    it('returns a correct csv file if specified', done => {
 | 
					    it('returns a correct csv file for admins if specified', done => {
 | 
				
			||||||
      TestHelper.request(server, done, {
 | 
					      TestHelper.request(server, done, {
 | 
				
			||||||
        method: 'get',
 | 
					        method: 'get',
 | 
				
			||||||
        url: '/samples?status[]=new&status[]=validated&page-size=2&csv=true',
 | 
					        url: '/samples?status[]=new&status[]=validated&page-size=2&csv=true',
 | 
				
			||||||
        contentType: /text\/csv/,
 | 
					        contentType: /text\/csv/,
 | 
				
			||||||
        auth: {basic: 'janedoe'},
 | 
					        auth: {basic: 'admin'},
 | 
				
			||||||
        httpStatus: 200
 | 
					        httpStatus: 200
 | 
				
			||||||
      }).end((err, res) => {
 | 
					      }).end((err, res) => {
 | 
				
			||||||
        if (err) return done(err);
 | 
					        if (err) return done(err);
 | 
				
			||||||
@@ -466,6 +464,14 @@ describe('/sample', () => {
 | 
				
			|||||||
        done();
 | 
					        done();
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    it('rejects returning a csv file for a write user', done => {
 | 
				
			||||||
 | 
					      TestHelper.request(server, done, {
 | 
				
			||||||
 | 
					        method: 'get',
 | 
				
			||||||
 | 
					        url: '/samples?status[]=new&status[]=validated&page-size=2&csv=true',
 | 
				
			||||||
 | 
					        auth: {basic: 'janedoe'},
 | 
				
			||||||
 | 
					        httpStatus: 403
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
    it('returns only the fields specified', done => {
 | 
					    it('returns only the fields specified', done => {
 | 
				
			||||||
      TestHelper.request(server, done, {
 | 
					      TestHelper.request(server, done, {
 | 
				
			||||||
        method: 'get',
 | 
					        method: 'get',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,8 +34,8 @@ router.get('/samples', async (req, res, next) => {
 | 
				
			|||||||
  const {error, value: filters} = SampleValidate.query(req.query, ['dev', 'admin'].indexOf(req.authDetails.level) >= 0);
 | 
					  const {error, value: filters} = SampleValidate.query(req.query, ['dev', 'admin'].indexOf(req.authDetails.level) >= 0);
 | 
				
			||||||
  if (error) return res400(error, res);
 | 
					  if (error) return res400(error, res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // spectral data not allowed for read/write users
 | 
					  // spectral data and csv not allowed for read/write users
 | 
				
			||||||
  if (filters.fields.find(e => /\.dpt$/.test(e)) && !req.auth(res, ['dev', 'admin'], 'all')) return;
 | 
					  if ((filters.fields.find(e => /\.dpt$/.test(e)) || filters.csv) && !req.auth(res, ['dev', 'admin'], 'all')) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TODO: find a better place for these
 | 
					  // TODO: find a better place for these
 | 
				
			||||||
  const sampleKeys = ['_id', 'color', 'number', 'type', 'batch', 'added', 'condition', 'material_id', 'note_id',
 | 
					  const sampleKeys = ['_id', 'color', 'number', 'type', 'batch', 'added', 'condition', 'material_id', 'note_id',
 | 
				
			||||||
@@ -195,7 +195,8 @@ router.get('/samples', async (req, res, next) => {
 | 
				
			|||||||
        {$addFields: {'material.group': { $arrayElemAt: ['$material.group.name', 0]}}}
 | 
					        {$addFields: {'material.group': { $arrayElemAt: ['$material.group.name', 0]}}}
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // if (sortFilterKeys.find(e => e === 'material.number')) {  // add material number if needed  // TODO: adapt code to new numbers format
 | 
					    // TODO: adapt code to new numbers format
 | 
				
			||||||
 | 
					    // if (sortFilterKeys.find(e => e === 'material.number')) {  // add material number if needed
 | 
				
			||||||
    //   materialQuery.push(
 | 
					    //   materialQuery.push(
 | 
				
			||||||
    //     {$addFields: {'material.number': { $arrayElemAt: [
 | 
					    //     {$addFields: {'material.number': { $arrayElemAt: [
 | 
				
			||||||
    //       '$material.numbers.number', {$indexOfArray: ['$material.numbers.color', '$color']}
 | 
					    //       '$material.numbers.number', {$indexOfArray: ['$material.numbers.color', '$color']}
 | 
				
			||||||
@@ -478,9 +479,6 @@ router.put('/sample/' + IdValidate.parameter(), (req, res, next) => {
 | 
				
			|||||||
    if (sample.hasOwnProperty('material_id')) {
 | 
					    if (sample.hasOwnProperty('material_id')) {
 | 
				
			||||||
      if (!await materialCheck(sample, res, next)) return;
 | 
					      if (!await materialCheck(sample, res, next)) return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (sample.hasOwnProperty('color')) {
 | 
					 | 
				
			||||||
      if (!await materialCheck(sample, res, next, sampleData.material_id)) 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))) {
 | 
					    if (sample.hasOwnProperty('condition') && !(_.isEmpty(sample.condition) && _.isEmpty(sampleData.condition))) {
 | 
				
			||||||
      if (!await conditionCheck(sample.condition, 'change', res, next,
 | 
					      if (!await conditionCheck(sample.condition, 'change', res, next,
 | 
				
			||||||
@@ -706,8 +704,8 @@ async function numberCheck(sample, res, next) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// validate material_id and color, returns false if invalid
 | 
					// validate material_id and color, returns false if invalid
 | 
				
			||||||
async function materialCheck (sample, res, next, id = sample.material_id) {
 | 
					async function materialCheck (sample, res, next) {
 | 
				
			||||||
  const materialData = await MaterialModel.findById(id).lean().exec().catch(err => next(err)) as any;
 | 
					  const materialData = await MaterialModel.findById(sample.material_id).lean().exec().catch(err => next(err)) as any;
 | 
				
			||||||
  if (materialData instanceof Error) return false;
 | 
					  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'});
 | 
					    res.status(400).json({status: 'Material not available'});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,9 +59,20 @@ router.put('/user:username([/](?!key|new).?*|/?)', async (req, res, next) => {
 | 
				
			|||||||
    if (!await usernameCheck(user.name, res, next)) return;
 | 
					    if (!await usernameCheck(user.name, res, next)) return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // get current mail address to compare to given address
 | 
				
			||||||
 | 
					  const {email: oldMail} = 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) => {
 | 
					  await UserModel.findOneAndUpdate({name: username}, user, {new: true}).log(req).lean().exec(  (err, data:any) => {
 | 
				
			||||||
    if (err) return next(err);
 | 
					    if (err) return next(err);
 | 
				
			||||||
    if (data) {
 | 
					    if (data) {
 | 
				
			||||||
 | 
					      if (data.mail !== oldMail) {  // mail address was changed, send notice to old address
 | 
				
			||||||
 | 
					        Mail.send(oldMail, 'Email change in your DeFinMa database account',
 | 
				
			||||||
 | 
					          'Hi, <br><br> Your email address of your DeFinMa account was changed to ' + data.mail +
 | 
				
			||||||
 | 
					          '<br><br>If you actually did this, just delete this email.' +
 | 
				
			||||||
 | 
					          '<br><br>If you did not change your email, someone might be messing around with your account, ' +
 | 
				
			||||||
 | 
					          'so talk to the sysadmin quickly!<br><br>Have a nice day.' +
 | 
				
			||||||
 | 
					          '<br><br>The DeFinMa team');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      res.json(UserValidate.output(data));
 | 
					      res.json(UserValidate.output(data));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user