* Add image dimension check for rank submit/update

* Update server dependencies
* Update gitignore after api package rename
pull/49/head
HardiReady 2019-02-03 11:49:48 +01:00
parent 557d0de60a
commit 68ad467e4d
10 changed files with 578 additions and 294 deletions

6
.gitignore vendored
View File

@ -4,7 +4,7 @@
dist/ dist/
tmp/ tmp/
etc/ etc/
api/apib/documentation.apib server/apib/documentation.apib
# dependencies # dependencies
node_modules node_modules
@ -47,8 +47,8 @@ Thumbs.db
# Internal Data # Internal Data
public/ public/
mongodb-data/ mongodb-data/
api/resource/ server/resource/
api/apib/dredd/data/tmp-resource server/apib/dredd/data/tmp-resource
backup/ backup/
# System # System

View File

@ -3,6 +3,9 @@
// HTTP status codes by name // HTTP status codes by name
const codes = require('../routes/http-codes'); const codes = require('../routes/http-codes');
// library to check image dimensions from file buffer
var sizeOf = require('buffer-image-size');
/** /**
* check if id has valid UUID format * check if id has valid UUID format
* *
@ -22,4 +25,16 @@ const idValidator = (req, res, next) => {
next(); next();
}; };
const imageDimensionValidator = (imageFileBuf, maxWidth, maxHeight) => {
const dimensions = sizeOf(imageFileBuf);
console.log(dimensions.width)
console.log(dimensions.height)
if (dimensions.width > maxWidth || dimensions.height > maxHeight) {
let err = new Error(`Image exceeds maximum dimensions of ${maxWidth}px width and ${maxHeight}px height`);
err.status = codes.wrongrequest;
return err;
}
};
exports.idValidator = idValidator; exports.idValidator = idValidator;
exports.imageDimensionValidator = imageDimensionValidator;

814
server/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -21,24 +21,25 @@
"dependencies": { "dependencies": {
"async": "^2.5.0", "async": "^2.5.0",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"body-parser": "~1.13.2", "body-parser": "^1.18.3",
"buffer-image-size": "^0.6.4",
"cors": "^2.8.4", "cors": "^2.8.4",
"cron": "^1.3.0", "cron": "^1.3.0",
"debug": "^3.1.0", "debug": "^3.1.0",
"express": "^4.16.2", "express": "^4.16.2",
"imagemin": "^5.2.2", "imagemin": "^5.2.2",
"imagemin-pngquant": "^5.0.0", "imagemin-pngquant": "^5.0.0",
"jimp": "^0.2.27", "jimp": "^0.6.0",
"jsonwebtoken": "^7.4.3", "jsonwebtoken": "^7.4.3",
"lodash": "^4.17.4", "lodash": "^4.17.4",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"mongoose": "^5.0.3", "mongoose": "^5.0.3",
"morgan": "~1.6.1", "morgan": "^1.9.1",
"multer": "^1.3.0", "multer": "^1.3.0",
"node-html-parser": "^1.1.10", "node-html-parser": "^1.1.10",
"node-sha1": "^1.0.1", "node-sha1": "^1.0.1",
"q": "^1.5.0", "q": "^1.5.0",
"serve-favicon": "~2.3.0", "serve-favicon": "^2.5.0",
"supports-color": "^5.1.0" "supports-color": "^5.1.0"
}, },
"devDependencies": { "devDependencies": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 794 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -22,6 +22,9 @@ const RankModel = require('../models/rank');
// util // util
const genericGetById = require('./_generic').genericGetById; const genericGetById = require('./_generic').genericGetById;
const imageDimensionValidator = require('../middleware/validators').imageDimensionValidator;
const MAX_IMAGE_WIDTH = 120;
const MAX_IMAGE_HEIGHT = 120;
const ranks = new express.Router(); const ranks = new express.Router();
@ -54,6 +57,13 @@ ranks.route('/')
.post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => { .post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
const rank = new RankModel(req.body); const rank = new RankModel(req.body);
const imageFileBuffer = req.file.buffer;
const err = imageDimensionValidator(imageFileBuffer, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);
if(err) {
return next(err);
}
// timestamp and default are set automatically by Mongoose Schema Validation // timestamp and default are set automatically by Mongoose Schema Validation
rank.save((err) => { rank.save((err) => {
if (err) { if (err) {
@ -62,7 +72,7 @@ ranks.route('/')
} }
res.status(codes.created); res.status(codes.created);
res.locals.items = rank; res.locals.items = rank;
fs.appendFile(resourceLocation + rank._id + '.png', new Buffer(req.file.buffer), fs.appendFile(resourceLocation + rank._id + '.png', new Buffer(imageFileBuffer),
(err) => { (err) => {
next(err); next(err);
}); });
@ -94,10 +104,16 @@ ranks.route('/:id')
req.body.$inc = {__v: 1}; req.body.$inc = {__v: 1};
if (req.file) { if (req.file) {
const imageFileBuffer = req.file.buffer;
const err = imageDimensionValidator(imageFileBuffer, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);
if(err) {
return next(err);
}
const file = resourceLocation + req.params.id + '.png'; const file = resourceLocation + req.params.id + '.png';
fs.unlink(file, (err) => { fs.unlink(file, (err) => {
if (err) next(err); if (err) next(err);
fs.appendFile(file, new Buffer(req.file.buffer), fs.appendFile(file, new Buffer(imageFileBuffer),
(err) => { (err) => {
if (err) next(err); if (err) next(err);
}); });

View File

@ -74,9 +74,9 @@ export class EditRankComponent implements OnInit, OnDestroy {
this.router.navigate(['..'], {relativeTo: this.route}); this.router.navigate(['..'], {relativeTo: this.route});
}); });
} else { } else {
this.translate.get('ranks.submit.field.image').subscribe((fieldNameIMage) => { this.translate.get('ranks.submit.field.image').subscribe((fieldNameImage) => {
this.translate.get('public.error.message.required', this.translate.get('public.error.message.required',
{fieldName: fieldNameIMage}).subscribe((message) => { {fieldName: fieldNameImage}).subscribe((message) => {
this.snackBarService.showError(message, 4000); this.snackBarService.showError(message, 4000);
}) })
}); });
@ -93,6 +93,9 @@ export class EditRankComponent implements OnInit, OnDestroy {
}, 300); }, 300);
fileInput.value = ''; fileInput.value = '';
this.snackBarService.showSuccess('generic.save.success'); this.snackBarService.showSuccess('generic.save.success');
}, error => {
const errorMsg = error._body ? JSON.parse(error._body).error.message : error.error.error.message;
this.snackBarService.showError('Error: '.concat(errorMsg), 15000);
}); });
} }
} }

View File

@ -54,7 +54,6 @@ export class StatisticComponent implements OnInit {
} }
} else if (url.includes('right:war')) { } else if (url.includes('right:war')) {
const id = idFetchPattern.exec(url)[1]; const id = idFetchPattern.exec(url)[1];
console.log(id)
this.campaignService.getCampaignByWarId(id).subscribe((campaign) => { this.campaignService.getCampaignByWarId(id).subscribe((campaign) => {
this.switchCampaign(campaign); this.switchCampaign(campaign);
}); });