diff --git a/.gitignore b/.gitignore index bca129da..540959f5 100755 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ app/tests/coverage/ config/sslcerts/*.pem access.log public/dist/ +uploads/ # Sublime editor # ============== diff --git a/app/controllers/forms.server.controller.js b/app/controllers/forms.server.controller.js index e9e6568d..a3d2c4ff 100644 --- a/app/controllers/forms.server.controller.js +++ b/app/controllers/forms.server.controller.js @@ -8,29 +8,27 @@ var mongoose = require('mongoose'), Form = mongoose.model('Form'), FormSubmission = mongoose.model('FormSubmission'), pdfFiller = require( 'pdffiller' ), - PDFParser = require('pdf2json/pdfparser'), config = require('../../config/config'), fs = require('fs-extra'), async = require('async'), + path = require('path'), _ = require('lodash'); /** - * Create a new form manually + * Create a new form */ exports.create = function(req, res) { var form = new Form(req.body); form.admin = req.user; form.save(function(err) { - if (err) { console.log(err); - return res.status(400).send({ + res.status(400).send({ message: errorHandler.getErrorMessage(err) }); } else { - - return res.json(form); + res.json(form); } }); }; @@ -38,23 +36,29 @@ exports.create = function(req, res) { /** * Upload PDF */ -exports.uploadPDF = function(req, res) { - var parser = new PDFParser(), - pdfFile = req.files.file; +exports.uploadPDF = function(files, user, cb) { + var _user = JSON.parse(''+user); + console.log(_user.username); + console.log(config.tmpUploadPath); +<<<<<<< HEAD // console.log(pdfFile); var form = Form.findById(req.body.form._id); // console.log(req.files); +======= + if(files) { + + console.log('inside uploadPDF'); + console.log(files.file[0]); + var pdfFile = files.file[0]; +>>>>>>> dev_working - if (req.files) { - if (pdfFile.size === 0) { - return res.status(400).send({ - message: 'Hey, first would you select a file?' - }); + throw new Error('Files uploaded are EMPTY'); } fs.exists(pdfFile.path, function(exists) { +<<<<<<< HEAD console.log(pdfFile.path); fs.open(pdfFile.path,'r',function(err,fd){ @@ -65,12 +69,40 @@ exports.uploadPDF = function(req, res) { } return res.status(200); }); - }); - } +======= + //If file exists move to user's tmp directory + if(exists) { + + var newDestination = path.join(config.tmpUploadPath, _user.username); + var stat = null; + try { + stat = fs.statSync(newDestination); + } catch (err) { + fs.mkdirSync(newDestination); + } + if (stat && !stat.isDirectory()) { + console.log('Directory cannot be created'); + throw new Error('Directory cannot be created because an inode of a different type exists at "' + newDestination + '"'); + } + + fs.move(pdfFile.path, path.join(newDestination, pdfFile.name), function (err) { + if (err) { + throw new Error(err.message); + } + pdfFile.path = path.join(newDestination, pdfFile.name); + + return cb(pdfFile); + }); + + } else { + throw new Error('Did NOT get your file!'); + } +>>>>>>> dev_working + }); + }else { + throw new Error('File NOT uploaded'); + } - return res.status(400).send({ - message: 'FILE NOT UPLOADED' - }); }; /** @@ -95,9 +127,9 @@ exports.createSubmission = function(req, res) { submission.form_fields = req.body.form_fields; submission.title = req.body.title; submission.timeElapsed = req.body.timeElapsed; + console.log(req.body); // submission.ipAddr = req.headers['x-forwarded-for'] || req.connection.remoteAddress; - if (form.isGenerated){ fdfTemplate = form.convertToFDF(); } else { @@ -108,28 +140,22 @@ exports.createSubmission = function(req, res) { } } - fdfData = pdfFiller.fillFdfTemplate(fdfTemplate, submission.form_fields, null); - - submission.fdfData = fdfData; - - //Create new file - // pdfFiller.fillForm( form.pdf.path, config.pdfUploadPath+form.title+'/'+form.title+'_'+Date.now()+'_submission.pdf', fdfData, function() { - // console.log('\n\n\n fdfData'); - // console.log(fdfData); - // console.log('\n\n\n :\n'); - // console.log(req.body); + if(form.autofillPDFs){ + fdfData = pdfFiller.fillFdfTemplate(fdfTemplate, submission.form_fields, null); + submission.fdfData = fdfData; + } submission.save(function(err){ if (err) { console.error(err); - return res.status(400).send({ + res.status(400).send({ message: errorHandler.getErrorMessage(err) }); } else { - return res.status(200); + console.log('Form Submission CREATED'); + res.status(200).send('Form submission successfully saved'); } }); - // }); }; @@ -139,13 +165,15 @@ exports.createSubmission = function(req, res) { exports.listSubmissions = function(req, res) { var _form = req.form; - FormSubmission.find({ form: req.form }).exec(function(err, submissions) { + FormSubmission.find({ form: req.form }).populate('admin', 'form').exec(function(err, submissions) { if (err) { - return res.status(400).send({ + console.log(err); + res.status(500).send({ message: errorHandler.getErrorMessage(err) }); } else { - return res.json(submissions); + console.log('hello'); + res.json(submissions); } }); }; @@ -163,12 +191,12 @@ exports.update = function(req, res) { form.save(function(err) { if (err) { console.log(err); - return res.status(400).send({ + res.status(400).send({ message: errorHandler.getErrorMessage(err) }); } else { console.log('updated form'); - return res.json(form); + res.json(form); } }); }; @@ -178,31 +206,41 @@ exports.update = function(req, res) { */ exports.delete = function(req, res) { var form = req.form; - - form.remove(function(err) { + console.log('deleting form'); + Form.remove({_id: form._id}, function(err) { if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) + res.status(500).send({ + message: err.message }); } else { - return res.status(200); - // res.json(form); + console.log('Form successfully deleted'); + res.status(200).send('Form successfully deleted'); } }); }; /** +<<<<<<< HEAD * Get List of Forms */ exports.list = function(req, res) { Form.find().sort('-created').populate('admin').exec(function(err, forms) { +======= + * Get All of Users' Forms + */ +exports.list = function(req, res) { + //Allow 'admin' user to view all forms + var searchObj = {admin: req.user}; + if(req.user.isAdmin()) searchObj = {}; + + Form.find({}).sort('-created').populate('admin').exec(function(err, forms) { +>>>>>>> dev_working if (err) { - return res.status(400).send({ + res.status(400).send({ message: errorHandler.getErrorMessage(err) }); } else { - console.log(forms); - return res.json(forms); + res.json(forms); } }); }; @@ -214,26 +252,48 @@ exports.list = function(req, res) { exports.formByID = function(req, res, next, id) { if (!mongoose.Types.ObjectId.isValid(id)) { - return res.status(400).send({ + res.status(400).send({ message: 'Form is invalid' }); } Form.findById(id).populate('admin').exec(function(err, form) { - if (err) return next(err); - if (!form) { - return res.status(404).send({ + if (err) { + return next(err); + } else if (!form || form === null) { + res.status(404).send({ message: 'Form not found' }); } + else { + if(!form.admin){ + form.admin = req.user; + form.save(function(err) { + if (err) { + console.log(err); + res.status(400).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + //Remove sensitive information from User object + form.admin.password = null; + form.admin.created = null; + form.admin.salt = null; - //Remove sensitive information from User object - form.admin.password = null; - form.admin.created = null; - form.admin.salt = null; + req.form = form; + next(); + } + }); + } - req.form = form; - next(); + //Remove sensitive information from User object + form.admin.password = null; + form.admin.created = null; + form.admin.salt = null; + + req.form = form; + next(); + } }); }; @@ -243,14 +303,9 @@ exports.formByID = function(req, res, next, id) { exports.hasAuthorization = function(req, res, next) { var form = req.form; - - // console.log('\n\n\nreq.form:\n'); - // console.log(form); - // console.log('req.user.id: '+req.user.id); - - if (req.form.admin.id !== req.user.id) { - return res.status(403).send({ - message: 'User is not authorized' + if (req.form.admin.id !== req.user.id && req.user.roles.indexOf('admin') === -1) { + res.status(403).send({ + message: 'User '+req.user.username+' is not authorized' }); } next(); diff --git a/app/controllers/users/users.authorization.server.controller.js b/app/controllers/users/users.authorization.server.controller.js index 1fc88a21..56aa35bc 100755 --- a/app/controllers/users/users.authorization.server.controller.js +++ b/app/controllers/users/users.authorization.server.controller.js @@ -23,7 +23,6 @@ exports.userByID = function(req, res, next, id) { * Require login routing middleware */ exports.requiresLogin = function(req, res, next) { - if (!req.isAuthenticated()) { return res.status(401).send({ message: 'User is not logged in' diff --git a/app/models/article.server.model.js b/app/models/article.server.model.js deleted file mode 100755 index f2b89db8..00000000 --- a/app/models/article.server.model.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict'; - -/** - * Module dependencies. - */ -var mongoose = require('mongoose'), - Schema = mongoose.Schema; - -/** - * Article Schema - */ -var ArticleSchema = new Schema({ - created: { - type: Date, - default: Date.now - }, - title: { - type: String, - default: '', - trim: true, - required: 'Title cannot be blank' - }, - content: { - type: String, - default: '', - trim: true - }, - user: { - type: Schema.ObjectId, - ref: 'User' - } -}); - -mongoose.model('Article', ArticleSchema); diff --git a/app/models/form.server.model.js b/app/models/form.server.model.js index bb271e85..3099f7af 100644 --- a/app/models/form.server.model.js +++ b/app/models/form.server.model.js @@ -10,9 +10,8 @@ var mongoose = require('mongoose'), _ = require('lodash'), config = require('../../config/config'), path = require('path'), - fs = require('fs-extra'); - -var Field = mongoose.model('Field', FieldSchema); + fs = require('fs-extra'), + Field = mongoose.model('Field', FieldSchema); /** @@ -23,11 +22,10 @@ var FormSchema = new Schema({ type: Date, default: Date.now }, - // type: { - // type: String, - // default: 'template', - // enum: ['submission', 'template'] - // }, + lastModified: { + type: Date, + default: Date.now + }, title: { type: String, default: '', @@ -39,7 +37,7 @@ var FormSchema = new Schema({ type: String, default: '', }, - form_fields: [Schema.Types.Mixed], + form_fields: [{type: Schema.Types.Mixed}], submissions: [{ type: Schema.Types.ObjectId, @@ -57,20 +55,36 @@ var FormSchema = new Schema({ pdfFieldMap: { type: Schema.Types.Mixed }, + hideFooter: { + type: Boolean, + default: true, + }, isGenerated: { type: Boolean, default: false, }, + isLive: { + type: Boolean, + default: true, + }, autofillPDFs: { type: Boolean, default: false, }, }); +<<<<<<< HEAD //Move PDF to permanent location after new PDF is uploaded +======= +//Update lastModified everytime we save +FormSchema.pre('save', function (next) { + this.lastModified = Date.now(); + next(); +}); + +//Move PDF to permanent location after new template is uploaded +>>>>>>> dev_working FormSchema.pre('save', function (next) { - // console.log(this.pdf); - // debugger; if(this.pdf && this.isModified('pdf')){ console.log('Relocating PDF'); @@ -111,15 +125,31 @@ FormSchema.pre('save', function (next) { } }); +//Delete template PDF of current Form +FormSchema.pre('remove', function (next) { + if(this.pdf){ + //Delete template form + fs.unlink(this.pdf.path, function(err){ + if (err) throw err; + console.log('successfully deleted', this.pdf.path); + }); + } +}); + //Autogenerate FORM from PDF if 'isGenerated' flag is 'true' FormSchema.pre('save', function (next) { - var field; + var field, _form_fields; if(this.isGenerated && this.pdf){ var _typeConvMap = { + 'Multiline': 'textarea', 'Text': 'textfield', - 'Button': 'checkbox' + 'Button': 'checkbox', + 'Choice': 'radio', + 'Password': 'password', + 'FileSelect': 'filefield', + 'Radio': 'radio' }; var that = this; @@ -137,14 +167,27 @@ FormSchema.pre('save', function (next) { field.fieldType = _typeConvMap[ field.fieldType+'' ]; } +<<<<<<< HEAD //Set field defaults field.created = Date.now(); +======= +>>>>>>> dev_working field.fieldValue = ''; + field.created = Date.now(); field.required = true; - field.disabled = false; + field.disabled = false; // field = new Field(field); - // field.save() + // field.save(function(err) { + // if (err) { + // console.error(err.message); + // throw new Error(err.message); + // }); + // } else { + // _form_fields[i] = this; + // } + // }); + _form_fields[i] = field; } console.log('NEW FORM_FIELDS: '); @@ -183,5 +226,4 @@ FormSchema.methods.convertToFDF = function (cb) { return jsonObj; }; - mongoose.model('Form', FormSchema); diff --git a/app/models/form_field.server.model.js b/app/models/form_field.server.model.js index d3725aa6..0487a49d 100644 --- a/app/models/form_field.server.model.js +++ b/app/models/form_field.server.model.js @@ -11,17 +11,22 @@ function validateFormFieldType(value) { if (!value || typeof myVar !== 'string' ) { return false; } var validTypes = [ - 'textfield', - 'email', - 'url', - 'textarea', - 'checkbox', - 'date', - 'dropdown', - 'hidden', - 'password', - 'radio' - ]; + 'textfield', + 'textarea', + 'statement', + 'email', + 'legal', + 'url', + 'number', + 'filefield', + 'radio', + 'checkbox', + 'date', + 'dropdown', + 'hidden', + 'password' + ]; + if (validTypes.indexOf(value) > -1) { return true; } @@ -49,7 +54,7 @@ var FormFieldSchema = new Schema({ }, required: { type: Boolean, - default: false, + default: true, }, disabled: { type: Boolean, diff --git a/app/models/form_submission.server.model.js b/app/models/form_submission.server.model.js index 5457d043..0419da52 100644 --- a/app/models/form_submission.server.model.js +++ b/app/models/form_submission.server.model.js @@ -11,6 +11,8 @@ var mongoose = require('mongoose'), config = require('../../config/config'), path = require('path'), Form = mongoose.model('Form'), + FieldSchema = require('./form_field.server.model.js'), + Field = mongoose.model('Field', FieldSchema), fs = require('fs-extra'); /** @@ -30,7 +32,7 @@ var FormSubmissionSchema = new Schema({ type: Schema.Types.ObjectId, ref: 'User', }, - form_fields: [Schema.Types.Mixed], + form_fields: [{type: Schema.Types.Mixed}], form: { type: Schema.Types.ObjectId, ref: 'Form', @@ -83,10 +85,10 @@ FormSubmissionSchema.pre('save', function (next) { Form.findById(that.form, function(err, _form){ if(err) next( new Error(err.mesasge) ); - // that.title = _form.title; + that.title = _form.title; // console.log(_form); - if(true){ //_form.autofillPDFs){ + if(_form.autofillPDFs){ dest_filename = _form.title.trim()+'_submission_'+Date.now()+'.pdf'; dest_path = path.join(config.pdfUploadPath, dest_filename); @@ -95,7 +97,6 @@ FormSubmissionSchema.pre('save', function (next) { // console.log('autofillPDFs check'); - pdfFiller.fillForm(_form.pdf.path, dest_path, this.fdfData, function(err){ console.log('fdfData: \n'); console.log(that.fdfData); @@ -111,13 +112,11 @@ FormSubmissionSchema.pre('save', function (next) { next(); }); } else { - next(); } }); - }); mongoose.model('FormSubmission', FormSubmissionSchema); \ No newline at end of file diff --git a/app/models/user.server.model.js b/app/models/user.server.model.js index c59c9da8..b815c6b9 100755 --- a/app/models/user.server.model.js +++ b/app/models/user.server.model.js @@ -144,4 +144,16 @@ UserSchema.statics.findUniqueUsername = function(username, suffix, callback) { }); }; +/** + * Function to check if user has Admin priviledges + */ +UserSchema.methods.isAdmin = function() { + + if(this.roles.indexOf('admin') !== -1){ + return true; + } + return false; +}; + + mongoose.model('User', UserSchema); diff --git a/app/routes/forms.server.routes.js b/app/routes/forms.server.routes.js index 3c1327e9..e0e0d2e5 100644 --- a/app/routes/forms.server.routes.js +++ b/app/routes/forms.server.routes.js @@ -12,14 +12,21 @@ module.exports = function(app) { .post(users.requiresLogin, forms.uploadPDF); app.route('/forms') - .get(forms.list) + .get(users.requiresLogin, forms.list) .post(users.requiresLogin, forms.create); + app.route('/forms/:formId/submissions') + .get(forms.listSubmissions); + app.route('/forms/:formId') .get(forms.read) .post(forms.createSubmission) .put(users.requiresLogin, forms.hasAuthorization, forms.update) +<<<<<<< HEAD .delete(users.requiresLogin, forms.hasAuthorization,forms.delete); +======= + .delete(users.requiresLogin, forms.hasAuthorization, forms.delete); +>>>>>>> dev_working // Finish by binding the form middleware app.param('formId', forms.formByID); diff --git a/app/routes/users.server.routes.js b/app/routes/users.server.routes.js index 02d966a6..90f47a7a 100755 --- a/app/routes/users.server.routes.js +++ b/app/routes/users.server.routes.js @@ -10,9 +10,15 @@ module.exports = function(app) { var users = require('../../app/controllers/users.server.controller'); // Setting up the users profile api +<<<<<<< HEAD app.route('/users/me').get(users.me); app.route('/users').put(users.requiresLogin, users.update); app.route('/users/accounts').delete(users.removeOAuthProvider); +======= + app.route('/users/me').get(users.requiresLogin, users.me); + app.route('/users').put(users.requiresLogin, users.update); + app.route('/users/accounts').delete(users.requiresLogin, users.removeOAuthProvider); +>>>>>>> dev_working // Setting up the users password api app.route('/users/password').post(users.requiresLogin, users.changePassword); diff --git a/app/views/index.server.view.html b/app/views/index.server.view.html index 7e60893b..515f440a 100755 --- a/app/views/index.server.view.html +++ b/app/views/index.server.view.html @@ -1,5 +1,5 @@ {% extends 'layout.server.view.html' %} {% block content %} - + {% endblock %} diff --git a/app/views/layout.server.view.html b/app/views/layout.server.view.html index 487bff01..ced993bd 100755 --- a/app/views/layout.server.view.html +++ b/app/views/layout.server.view.html @@ -38,6 +38,8 @@ {% for cssFile in cssFiles %} {% endfor %} + + -
+