From e475a571faefe3ca769cefa523e9f031c68b5cb2 Mon Sep 17 00:00:00 2001 From: Markus Grigull <web@grigull.me> Date: Sat, 4 Feb 2017 15:34:55 +0100 Subject: [PATCH] Add file upload route and model Allow empty widget name --- .gitignore | 1 + models/file.js | 24 ++++++++++++++++ models/user.js | 3 +- models/widget.js | 2 +- package.json | 3 +- routes/files.js | 36 +++++++++++++++++++++++ routes/upload.js | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ server.js | 6 ++++ 8 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 models/file.js create mode 100644 routes/files.js create mode 100644 routes/upload.js diff --git a/.gitignore b/.gitignore index adac2d0..b9ec202 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # NodeJS node_modules/ npm-debug.log +public/* # OS X .DS_Store diff --git a/models/file.js b/models/file.js new file mode 100644 index 0000000..aaeaf6f --- /dev/null +++ b/models/file.js @@ -0,0 +1,24 @@ +/** + * File: file.js + * Author: Markus Grigull <mgrigull@eonerc.rwth-aachen.de> + * Date: 25.01.2017 + * Copyright: 2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + **********************************************************************************/ + +// include +var mongoose = require('mongoose'); + +var Schema = mongoose.Schema; + +// file model +var fileSchema = new Schema({ + name: { type: String }, + path: { type: String, required: true }, + type: { type: String }, + user: { type: Schema.Types.ObjectId, ref: 'User', required: true }, + date: { type: Date, default: Date.now } +}); + +module.exports = mongoose.model('File', fileSchema); diff --git a/models/user.js b/models/user.js index f4abbbf..70b646a 100644 --- a/models/user.js +++ b/models/user.js @@ -23,7 +23,8 @@ var userSchema = new Schema({ role: { type: String, required: true, default: 'user' }, projects: [{ type: Schema.Types.ObjectId, ref: 'Project', default: [] }], mail: { type: String, default: "" }, - simulations: [{ type: Schema.Types.ObjectId, ref: 'Simulation', default: [] }] + simulations: [{ type: Schema.Types.ObjectId, ref: 'Simulation', default: [] }], + files: [{type: Schema.Types.ObjectId, ref: 'File', default: [] }] }); userSchema.methods.verifyPassword = function(password, callback) { diff --git a/models/widget.js b/models/widget.js index 3ee75fe..a6857f8 100644 --- a/models/widget.js +++ b/models/widget.js @@ -14,7 +14,7 @@ var Schema = mongoose.Schema; // widget model var widgetSchema = new Schema({ - name: { type: String, required: true }, + name: { type: String }, widgetData: { type: Schema.Types.Mixed, default: {} }, width: { type: Number, required: true }, height: { type: Number, required: true }, diff --git a/package.json b/package.json index 43afcca..4fd505f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "VILLASweb-backend", - "version": "0.1.0", + "version": "0.1.1", "private": true, "main": "server.js", "dependencies": { @@ -8,6 +8,7 @@ "body-parser": "^1.15.2", "cors": "^2.7.1", "express": "^4.14.0", + "formidable": "^1.0.17", "jsonwebtoken": "^7.0.1", "mongoose": "^4.5.1", "morgan": "^1.7.0" diff --git a/routes/files.js b/routes/files.js new file mode 100644 index 0000000..c4aea8c --- /dev/null +++ b/routes/files.js @@ -0,0 +1,36 @@ +/** + * File: files.js + * Author: Markus Grigull <mgrigull@eonerc.rwth-aachen.de> + * Date: 25.01.2017 + * Copyright: 2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + **********************************************************************************/ + +// include +var express = require('express'); + +var auth = require('../auth'); + +// models +var File = require('../models/file'); +var User = require('../models/user'); + +// create router +var router = express.Router(); + +// all file routes need authentication +router.use('/files', auth.validateToken); + +// routes +router.get('/files/:id', function(req, res) { + File.findOne({ _id: req.params.id }, function(err, file) { + if (err) { + return res.status(400).send(err); + } + + res.send({ file: file }); + }); +}); + +module.exports = router; diff --git a/routes/upload.js b/routes/upload.js new file mode 100644 index 0000000..8492212 --- /dev/null +++ b/routes/upload.js @@ -0,0 +1,74 @@ +/** + * File: upload.js + * Author: Markus Grigull <mgrigull@eonerc.rwth-aachen.de> + * Date: 05.12.2016 + * Copyright: 2016, Institute for Automation of Complex Power Systems, EONERC + * This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential. + * Unauthorized copying of this file, via any medium is strictly prohibited. + **********************************************************************************/ + +// include +var express = require('express'); +var path = require('path'); +var formidable = require('formidable'); +var fs = require('fs'); + +var auth = require('../auth'); + +var User = require('../models/user'); +var File = require('../models/file'); + +// create router +var router = express.Router(); + +// serve public files +router.use(express.static(path.join(__dirname, '../public'))); + +// routes +router.post('/upload', auth.validateToken, function(req, res) { + // create form object + var form = new formidable.IncomingForm(); + form.uploadDir = path.join(__dirname, '../public'); + + // register events + form.on('file', function(field, file) { + fs.rename(file.path, path.join(form.uploadDir, req.decoded._doc._id + '_' + file.name)); + + // find user + User.findOne({ _id: req.decoded._doc._id }, function(err, user) { + if (err) { + console.log(err); + } + + // create file object + var fileObj = new File({ name: file.name, path: 'public/' + user._id + '_' + file.name, user: user._id }); + fileObj.save(function(err) { + if (err) { + console.log(err); + } + + user.files.push(fileObj._id); + + user.save(function(err) { + if (err) { + console.log(err); + } + }); + }); + }); + }); + + form.on('error', function(error) { + console.log('Error uploading file: ' + error); + res.status(403).send({ success: false, message: 'Error uploading file: ' + error }); + }); + + form.on('end', function() { + res.send({ success: true, message: 'File uploaded' }); + }); + + // handle the request + form.parse(req); +}); + +module.exports = router; diff --git a/server.js b/server.js index bb6d838..5d66b8d 100644 --- a/server.js +++ b/server.js @@ -24,6 +24,8 @@ var widgets = require('./routes/widgets'); var simulations = require('./routes/simulations'); var simulationModels = require('./routes/simulationModels'); var simulators = require('./routes/simulators'); +var upload = require('./routes/upload'); +var files = require('./routes/files'); var User = require('./models/user'); @@ -47,6 +49,10 @@ app.use('/api/v1', widgets); app.use('/api/v1', simulations); app.use('/api/v1', simulationModels); app.use('/api/v1', simulators); +app.use('/api/v1', upload); +app.use('/api/v1', files); + +app.use('/public', express.static(__dirname + '/public')); // catch 404 and forward to error handler app.use(function(req, res, next) { -- GitLab