diff --git a/app/controllers/forms.server.controller.js b/app/controllers/forms.server.controller.js
index 6348c1c8..ae20ad36 100644
--- a/app/controllers/forms.server.controller.js
+++ b/app/controllers/forms.server.controller.js
@@ -20,6 +20,10 @@ var mongoose = require('mongoose'),
exports.uploadPDF = function(req, res, next) {
console.log('inside uploadPDF');
+
+ // console.log(req.files.file);
+ // console.log('\n\nProperty Descriptor\n-----------');
+ // console.log(Object.getOwnPropertyDescriptor(req.files.file, 'path'));
if(req.files){
var pdfFile = req.files.file;
var _user = req.user;
@@ -50,7 +54,7 @@ exports.uploadPDF = function(req, res, next) {
}
pdfFile.path = path.join(newDestination, pdfFile.name);
console.log(pdfFile.name + ' uploaded to ' + pdfFile.path);
- res.status(200).send('pdf file successfully uploaded');
+ res.json(pdfFile);
});
} else {
@@ -63,22 +67,46 @@ exports.uploadPDF = function(req, res, next) {
}
};
+
+/**
+ * Delete a forms submissions
+ */
+exports.deleteSubmissions = function(req, res) {
+ console.log(req.body);
+ var submission_id_list = req.body.deleted_submissions,
+ form = req.form;
+
+ FormSubmission.remove({ form: req.form, admin: req.user, _id: {$in: submission_id_list} }, function(err){
+
+ if(err){
+ res.status(400).send({
+ message: errorHandler.getErrorMessage(err)
+ });
+ }
+
+ res.status(200).send('Form submissions successfully deleted');
+ });
+};
/**
* Submit a form entry
*/
exports.createSubmission = function(req, res) {
- var submission = new FormSubmission(),
+ var submission,
form = req.form,
fdfData,
fdfTemplate,
that = this;
+ submission = new FormSubmission({
+ admin: req.user,
+ form_fields: req.body.form_fields,
+ timeElapsed: req.body.timeElapsed
+ });
+
submission.form = form;
- submission.admin = req.user;
- submission.form_fields = req.body.form_fields;
- submission.title = req.body.title;
- submission.timeElapsed = req.body.timeElapsed;
+ submission.pdf = form.pdf;
+ submission.title = form.title;
// submission.ipAddr = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
if(form.autofillPDFs){
@@ -93,42 +121,23 @@ exports.createSubmission = function(req, res) {
});
}
}
- fdfData = pdfFiller.fillFdfTemplate(fdfTemplate, submission.form_fields, null);
+ fdfData = pdfFiller.convFieldJson2FDF(submission.form_fields);
submission.fdfData = fdfData;
+ }else{
+ submission.fdfData = undefined;
}
- async.series([
- function(callback){
- submission.save(function(err){
- if (err) {
- callback(err);
- } else {
- callback(null);
- }
- });
- },
- function(callback){
- //Add submission to Form.submissionns
- form.submissions.push(submission);
-
- form.save(function(err){
- if (err) {
- callback(err);
- } else {
- callback(null);
- }
- });
- },
- ], function(err, results) {
- if(err){
- res.status(400).send({
- message: errorHandler.getErrorMessage(err)
- });
- }
- // console.log(results);
- // console.log(that.form_fields);
- res.status(200).send('Form submission successfully saved');
- });
+ submission.save(function(err){
+
+ if(err){
+ res.status(400).send({
+ message: errorHandler.getErrorMessage(err)
+ });
+ }
+ // console.log(results);
+ // console.log(that.form_fields);
+ res.status(200).send('Form submission successfully saved');
+ });
};
/**
@@ -172,8 +181,8 @@ exports.create = function(req, res) {
var form = new Form(req.body.form);
form.admin = req.user;
- console.log(form);
- console.log(req.user);
+ // console.log(form);
+ // console.log(req.user);
form.save(function(err) {
if (err) {
@@ -182,7 +191,7 @@ exports.create = function(req, res) {
message: errorHandler.getErrorMessage(err)
});
} else {
- res.status(200).send('form created');
+ res.json(form);
}
});
};
@@ -201,13 +210,16 @@ exports.read = function(req, res) {
exports.update = function(req, res) {
console.log('in form.update()');
- console.log(req.body.form.form_fields);
+ // console.log(req.body.form.form_fields);
var form = req.form;
delete req.body.form.__v;
delete req.body.form._id;
delete req.body.form.created;
delete req.body.form.lastModified;
+ delete req.body.form.admin;
+
+ // console.log(form.admin);
//Unless we have 'admin' priviledges, updating form admin is disabled
if(req.user.roles.indexOf('admin') === -1) delete req.body.form.admin;
@@ -216,7 +228,7 @@ exports.update = function(req, res) {
// console.log(req.body.form);
// form.form_fields = req.body.form.form_fields;
- form.save(function(err) {
+ form.save(function(err, form) {
if (err) {
console.log(err);
res.status(400).send({
@@ -224,7 +236,7 @@ exports.update = function(req, res) {
});
} else {
console.log('updated form');
- res.status(200).send('updated form');
+ res.json(form);
}
});
};
@@ -287,6 +299,11 @@ exports.formByID = function(req, res, next, id) {
});
}
else {
+ if(!form.username){
+ form.admin = req.user;
+ }
+ // console.log(creaform.admin);
+
//Remove sensitive information from User object
form.admin.password = null;
form.admin.created = null;
diff --git a/app/controllers/users/users.authentication.server.controller.js b/app/controllers/users/users.authentication.server.controller.js
index b936ccda..a71e71b1 100755
--- a/app/controllers/users/users.authentication.server.controller.js
+++ b/app/controllers/users/users.authentication.server.controller.js
@@ -4,6 +4,7 @@
* Module dependencies.
*/
var _ = require('lodash'),
+ nev = require('email-verification'),
errorHandler = require('../errors.server.controller'),
mongoose = require('mongoose'),
passport = require('passport'),
@@ -11,89 +12,36 @@ var _ = require('lodash'),
config = require('../../../config/config'),
nodemailer = require('nodemailer'),
crypto = require('crypto'),
+ nev = require('email-verification'),
User = mongoose.model('User');
var smtpTransport = nodemailer.createTransport(config.mailer.options);
+// NEV configuration =====================
+nev.configure({
+ persistentUserModel: User,
+ expirationTime: 600, // 10 minutes
-/**
- * Reset password GET from email token
- */
-exports.validateResetToken = function(req, res) {
- User.findOne({
- resetPasswordToken: req.params.token,
- resetPasswordExpires: {
- $gt: Date.now()
- }
- }, function(err, user) {
- if (!user) {
- return res.redirect('/#!/password/reset/invalid');
- }
+ verificationURL: config.baseUrl+'/#!/verify/${URL}',
+ transportOptions: config.mailer.options,
+ verifyMailOptions: {
+ from: config.mailer.from,
+ subject: 'Confirm your account',
+ html: '
Please verify your account by clicking this link. If you are unable to do so, copy and ' +
+ 'paste the following link into your browser:
${URL}
',
+ text: 'Please verify your account by clicking the following link, or by copying and pasting it into your browser: ${URL}'
+ },
- res.redirect('/#!/password/reset/' + req.params.token);
- });
-};
+ confirmMailOptions: {
+ from: config.mailer.from,
+ subject: 'Successfully verified!',
+ html: 'Your account has been successfully verified.
',
+ text: 'Your account has been successfully verified.'
+ },
-/**
- * Send verification email
- */
-var sendVerificationEmail = function(req, res, next) {
- // Init Variables
- var passwordDetails = req.body;
+});
- async.waterfall([
- // Generate random token
- function(done) {
- crypto.randomBytes(20, function(err, buffer) {
- var token = buffer.toString('hex');
- done(err, token);
- });
- },
- function(token, done) {
- // For security measurement we remove the roles from the req.body object
- delete req.body.roles;
-
- // Init Variables
- var user = new User(req.body);
- user.resetPasswordToken = token;
- user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
-
- // Add missing user fields
- user.provider = 'local';
- user.displayName = user.firstName + ' ' + user.lastName;
-
- // Then save the user
- user.save(function(err) {
- done(err, token, user);
- });
- },
- function(token, user, done) {
- res.render('templates/verify-account-email', {
- name: user.displayName,
- url: 'http://' + req.headers.host + '/auth/activate/' + token,
- appName: config.app.title
- }, function(err, emailHTML) {
- done(err, emailHTML, user);
- });
- },
- // If valid email, send reset email using service
- function(emailHTML, user, done) {
- var mailOptions = {
- to: user.email,
- from: config.mailer.from,
- subject: 'Please verify your email',
- html: emailHTML
- };
-
- smtpTransport.sendMail(mailOptions, function(err) {
- done(err, 'done');
- });
- }
- ], function(err) {
- if (err) return next(err);
- res.status(200).send('new user successfully registered');
- });
-};
+nev.generateTempUserModel(User);
/**
* Signup
@@ -104,32 +52,44 @@ exports.signup = function(req, res) {
// Init Variables
var user = new User(req.body);
- var message = null;
// Add missing user fields
user.provider = 'local';
+ user.username = user.email;
user.displayName = user.firstName + ' ' + user.lastName;
- // Then save the user
- user.save(function(err) {
- if (err) {
- return res.status(400).send({
- message: errorHandler.getErrorMessage(err)
- });
- } else {
- // Remove sensitive data before login
- user.password = undefined;
- user.salt = undefined;
- res.status(200).send('new user successfully registered');
+ // Then save the temporary user
+ nev.createTempUser(user, function(newTempUser) {
+ // new user created
+ if (newTempUser) {
+ nev.registerTempUser(newTempUser);
+ res.status(200).send('An email has been sent to you. Please check it to verify your account.');
+ } else {
+ res.status(400).send('Error: Temp user could NOT be created!');
+ }
+ });
+};
- // req.login(user, function(err) {
- // if (err) {
- // res.status(400).send(err);
- // } else {
- // res.status(200).send('new user successfully registered');
- // }
- // });
- }
+exports.validateVerificationToken = function(req, res, next){
+
+ nev.confirmTempUser(req.params.token, function(user) {
+ if (user){
+ res.status(200).send('User successfully verified');
+ }else {
+ // redirect to resend verification email
+ res.status(401).send('Verification token is invalid or has expired');
+ }
+ });
+};
+
+exports.resendVerificationEmail = function(req, res, next){
+ nev.resendVerificationEmail(req.body.email, function(user) {
+ if (user){
+ res.status(200).send('User successfully verified');
+ }else {
+ // user hasn't been found yet
+ res.status(400).send( {message: 'Error: User could NOT be verified'} );
+ }
});
};
diff --git a/app/controllers/users/users.verify.server.controller.js b/app/controllers/users/users.verify.server.controller.js
new file mode 100644
index 00000000..5e1455ad
--- /dev/null
+++ b/app/controllers/users/users.verify.server.controller.js
@@ -0,0 +1,45 @@
+'use strict';
+
+angular.module('users').controller('VerifyController', ['$scope', '$location', '$state', '$rootScope', 'User', 'Auth',
+ function($scope, $location, $state, $rootScope, User, Auth) {
+
+ $scope = $rootScope;
+ $scope.credentials = {};
+ $scope.error = null;
+ $scope.success = null;
+
+ // If user is signed in then redirect back home
+ if ($scope.authentication.isAuthenticated()) $state.go('home');
+
+ $scope.validateVerifyToken = function(){
+ $scope.success = $scope.error = null;
+ User.validateVerifyToken($stateParams.token).then(
+ function(response){
+ // If successful show success message and clear form
+ $scope.success = response.message;
+ $scope.passwordDetails = null;
+ },
+ function(error){
+ $scope.error = error.message || error;
+ $scope.passwordDetails = null;
+ }
+ );
+ }
+
+
+ // Submit forgotten password account id
+ $scope.resendVerifyEmail = function() {
+ User.resendVerifyEmail($scope.email).then(
+ function(response){
+ $scope.success = response.message;
+ $scope.credentials = null;
+ },
+ function(error){
+ $scope.error = error;
+ $scope.credentials = null;
+ }
+ );
+ };
+
+ }
+]);
\ No newline at end of file
diff --git a/app/models/form.server.model.js b/app/models/form.server.model.js
index c31b74a4..aa9d11b2 100644
--- a/app/models/form.server.model.js
+++ b/app/models/form.server.model.js
@@ -12,9 +12,10 @@ var mongoose = require('mongoose'),
config = require('../../config/config'),
path = require('path'),
fs = require('fs-extra'),
- async = require('async');
- var Field = mongoose.model('Field', FieldSchema);
- var FormSubmission = mongoose.model('FormSubmission', FormSubmissionSchema);
+ async = require('async'),
+ Field = mongoose.model('Field', FieldSchema),
+ FormSubmission = mongoose.model('FormSubmission', FormSubmissionSchema),
+ _original;
/**
@@ -33,7 +34,7 @@ var FormSchema = new Schema({
type: String,
trim: true,
unique: true,
- required: 'Title cannot be blank'
+ required: 'Title cannot be blank',
},
language: {
type: String,
@@ -47,10 +48,6 @@ var FormSchema = new Schema({
},
form_fields: {
type: [FieldSchema],
- set: function(form_fields) {
- this._previousFormFields = this.form_fields;
- return form_fields;
- }
},
submissions: [{
@@ -89,10 +86,6 @@ var FormSchema = new Schema({
},
});
-FormSchema.post('init', function() {
- this._original = this.toObject();
-});
-
//Delete template PDF of current Form
FormSchema.pre('remove', function (next) {
if(this.pdf){
@@ -104,6 +97,21 @@ FormSchema.pre('remove', function (next) {
}
});
+//Set _original
+FormSchema.pre('save', function (next) {
+ this.constructor // ≈ mongoose.model('…', FieldSchema).findById
+ .findOne({title: this.title}, function(err, original){
+ if(err) next(err);
+ else {
+ _original = original;
+ next();
+ }
+
+ });
+});
+
+
+
//Update lastModified and created everytime we save
FormSchema.pre('save', function (next) {
var now = new Date();
@@ -114,29 +122,12 @@ FormSchema.pre('save', function (next) {
next();
});
-//Concatenate submission and form's form_fields
-// FormSchema.pre('save', function (next) {
-// if(this.isModified('form_fields')){
-
-// if(this.submissions.length){
-// for(var i=0; i 0){
for(var i = 0; i < needle.length; i++){
- if(haystack.indexOf(needle[i]) <= -1){
+ if(haystack.indexOf(needle[i]) === -1){
deletedIndexes.push(i);
}
}
@@ -144,100 +135,6 @@ function getDeletedIndexes(needle, haystack){
return deletedIndexes;
}
-
-FormSchema.pre('save', function (next) {
- if(this.isModified('form_fields')){
-
- var old_form_fields = this._original.form_fields,
- old_ids = _.pluck(this.form_fields, '_id'),
- new_ids = _.pluck(old_form_fields, '_id'),
- deletedIds = getDeletedIndexes(old_ids, new_ids),
- that = this;
-
- // console.log(deletedIds);
- // console.log('old_ids\n--------');
- // console.log(old_ids);
- // console.log('new_ids\n--------');
- // console.log(new_ids);
-
- //Preserve fields that have at least one submission
- if( deletedIds.length > 0 ){
-
- var modifiedSubmissions;
-
- async.forEachOfSeries(deletedIds, function (deletedIdIndex, key, callback) {
-
- var deleted_id = old_ids[deletedIdIndex];
-
- //Search for submissions with deleted form_field
- FormSubmission.
- find({ form: that, admin: that.admin, form_fields: {$elemMatch: {_id: deleted_id} } }).
- exec(function(err, submissions){
- if(err){
- console.error(err);
- return callback(err);
- }
-
- //Delete field if there are no submission(s) found
- if(submissions.length > 0) {
- //Push old form_field to start of array
- that.form_fields.unshift(old_form_fields[deletedIdIndex]);
- modifiedSubmissions.push.apply(modifiedSubmissions, submissions);
- console.log(modifiedSubmissions);
- }
-
- callback(null, modifiedSubmissions);
- }
- );
- }, function (err, submissions) {
- if(err){
- console.error(err.message);
- next(err);
- }
-
- console.log('preserved deleted fields');
- console.log(submissions);
-
- async.forEachOfSeries(modifiedSubmissions, function (submission, key, callback) {
-
- for(var i = 0; i < deletedIds.length; i++){
- var tmpField = _.find(submission.form_fields, function(field){
- return field._id === deletedIds[i];
- });
-
- var index = submission.form_fields.indexOf(tmpField);
-
- if(tmpField){
- //Delete old form_field
- submission.form_fields.splice(index, 1);
-
- //Move old form_field to start
- submission.form_fields.unshift(tmpField);
- }
- }
-
- submission.save(function (err) {
- if (err) callback(err);
- callback();
- });
-
- }, function (err) {
- if(err){
- console.error(err.message);
- next(err);
- }
-
- next();
- });
-
- });
- }
- }
-
- next();
-
-});
-
//Move PDF to permanent location after new template is uploaded
FormSchema.pre('save', function (next) {
@@ -245,7 +142,7 @@ FormSchema.pre('save', function (next) {
var that = this;
async.series([
function(callback){
- if(that.isModified('pdf')){
+ if(that.isModified('pdf') && that.pdf.path){
var new_filename = that.title.replace(/ /g,'')+'_template.pdf';
@@ -258,21 +155,25 @@ FormSchema.pre('save', function (next) {
fs.mkdirSync(newDestination);
}
if (stat && !stat.isDirectory()) {
- callback( new Error('Directory cannot be created because an inode of a different type exists at "' + config.pdfUploadPath + '"'), null);
+ return callback( new Error('Directory cannot be created because an inode of a different type exists at "' + config.pdfUploadPath + '"'), null);
}
- fs.move(that.pdf.path, path.join(newDestination, new_filename), function (err) {
+ var old_path = that.pdf.path;
+ fs.move(old_path, path.join(newDestination, new_filename), {clobber: true}, function (err) {
if (err) {
console.error(err);
- callback( new Error(err.message), null);
- }
- that.pdf.path = path.join(newDestination, new_filename);
- that.pdf.name = new_filename;
+ callback( new Error(err.message), 'task1');
+ }else {
+ that.pdf.path = path.join(newDestination, new_filename);
+ that.pdf.name = new_filename;
- callback(null,'task1');
+ callback(null,'task1');
+ }
});
+ }else {
+ callback(null,'task1');
}
- callback(null,'task1');
+
},
function(callback){
if(that.isGenerated){
@@ -288,7 +189,7 @@ FormSchema.pre('save', function (next) {
'Radio': 'radio'
};
- // console.log('autogenerating form');
+ console.log('autogenerating form');
// console.log(that.pdf.path);
pdfFiller.generateFieldJson(that.pdf.path, function(err, _form_fields){
@@ -298,6 +199,7 @@ FormSchema.pre('save', function (next) {
callback( new Error('Generated formfields is empty'), null);
}
+ // console.log(_form_fields);
//Map PDF field names to FormField field names
for(var i = 0; i < _form_fields.length; i++){
var field = _form_fields[i];
@@ -315,10 +217,11 @@ FormSchema.pre('save', function (next) {
// console.log('NEW FORM_FIELDS: ');
// console.log(_form_fields);
+ that.form_fields = that.form_fields.concat(_form_fields);
+
// console.log('\n\nOLD FORM_FIELDS: ');
// console.log(that.form_fields);
-
- that.form_fields.concat(_form_fields);
+ that.isGenerated = false;
callback(null, 'task2');
});
}else{
@@ -335,78 +238,151 @@ FormSchema.pre('save', function (next) {
next();
});
+ }else if(_original){
+ if(_original.pdf){
+ fs.remove(_original.pdf.path, function (err) {
+ if(err) next(err);
+ console.log('file at '+_original.pdf.path+' successfully deleted');
+ next();
+ });
+ }
}else{
next();
}
});
-//Autogenerate Form_fields from PDF if 'isGenerated' flag is set
-// FormSchema.pre('save', function (next) {
-// var field, _form_fields;
+FormSchema.pre('save', function (next) {
+ // console.log(this.form_fields);
+
+ // console.log('_original\n------------\n\n');
+ // console.log(_original);
+ // console.log(this.isModified('form_fields') && !!this.form_fields && !!_original);
+ if(this.isModified('form_fields') && this.form_fields && _original){
+
+ var old_form_fields = _original.form_fields,
+ new_ids = _.map(_.pluck(this.form_fields, '_id'), function(id){ return ''+id;}),
+ old_ids = _.map(_.pluck(old_form_fields, '_id'), function(id){ return ''+id;}),
+ deletedIds = getDeletedIndexes(old_ids, new_ids),
+ that = this;
+
+ // console.log('deletedId Indexes\n--------');
+ // console.log(deletedIds);
+ // console.log('old_ids\n--------');
+ // console.log(old_ids);
+ // console.log('new_ids\n--------');
+ // console.log(new_ids);
+
+ //Preserve fields that have at least one submission
+ if( deletedIds.length > 0 ){
+
+ var modifiedSubmissions = [];
+
+ async.forEachOfSeries(deletedIds,
+ function (deletedIdIndex, key, callback) {
+
+ var deleted_id = old_ids[deletedIdIndex];
+
+ //Search for submissions with deleted form_field
+ // if(submissions.length){
+ // submissionsWithDeletedField = _.select(form.submissions, function(submission){
+ // var field = _(submission.form_fields).filter(function(field) { return field._id === deleted_id; })
+ // return !!field;
+ // });
+
+ // //Push old form_field to start of array
+ // if(submissionsWithDeletedField.length){
+ // that.form_fields.unshift(old_form_fields[deletedIdIndex]);
+ // modifiedSubmissions.push.apply(modifiedSubmissions, submissionsWithDeletedField);
+ // console.log(modifiedSubmissions);
+ // }
+
+ // callback(null, modifiedSubmissions);
+ // } else{
+ FormSubmission.
+ find({ form: that._id, admin: that.admin, form_fields: {$elemMatch: {_id: deleted_id} } }).
+ exec(function(err, submissions){
+ if(err){
+ console.error(err);
+ return callback(err);
+ }
+ // console.log(submissions);
-// if(this.pdf){
-// if(this.isGenerated){
-// var _typeConvMap = {
-// 'Multiline': 'textarea',
-// 'Text': 'textfield',
-// 'Button': 'checkbox',
-// 'Choice': 'radio',
-// 'Password': 'password',
-// 'FileSelect': 'filefield',
-// 'Radio': 'radio'
-// };
+ //Delete field if there are no submission(s) found
+ if(submissions.length) {
+ //Push old form_field to start of array
+ // that.form_fields.unshift(old_form_fields[deletedIdIndex]);
+ modifiedSubmissions.push.apply(modifiedSubmissions, submissions);
+ }
-// var that = this;
-// console.log('autogenerating form');
+ callback(null);
+ });
+ // }
+ },
+ function (err) {
+ if(err){
+ console.error(err.message);
+ next(err);
+ }
-// try {
-// pdfFiller.generateFieldJson(this.pdf.path, function(_form_fields){
+ // console.log('modifiedSubmissions\n---------\n\n');
+ // console.log(modifiedSubmissions);
-// //Map PDF field names to FormField field names
-// for(var i = 0; i < _form_fields.length; i++){
-// field = _form_fields[i];
+ // console.log('preserved deleted fields');
+ // console.log(submissions);
-// //Convert types from FDF to 'FormField' types
-// if(_typeConvMap[ field.fieldType+'' ]){
-// field.fieldType = _typeConvMap[ field.fieldType+'' ];
-// }
+ async.forEachOfSeries(modifiedSubmissions, function (submission, key, callback) {
-// field.fieldValue = '';
-// field.created = Date.now();
-// field.required = true;
-// field.disabled = false;
+ for(var i = 0; i < deletedIds.length; i++){
-// // field = new Field(field);
-// // field.save(function(err) {
-// // if (err) {
-// // console.error(err.message);
-// // throw new Error(err.message);
-// // });
-// // } else {
-// // _form_fields[i] = this;
-// // }
-// // });
-// _form_fields[i] = field;
-// }
+ var index = _.findIndex(submission.form_fields, function(field) {
+ var tmp_id = field._id+'';
+ // console.log(tmp_id === old_ids[ deletedIds[i] ]);
+ return tmp_id === old_ids[ deletedIds[i] ];
+ });
-// console.log('NEW FORM_FIELDS: ');
-// console.log(_form_fields);
+ // console.log('index: '+index);
-// console.log('\n\nOLD FORM_FIELDS: ');
-// console.log(that.form_fields);
+ var tmpField = submission.form_fields[index];
-// that.form_fields = _form_fields;
-// next();
-// });
-// } catch(err){
-// next( new Error(err.message) );
-// }
-// }
-// }
+ if(tmpField){
+ // console.log('tmpField\n-------\n\n');
+ // console.log(tmpField);
+ //Delete old form_field
+ submission.form_fields.splice(index, 1);
-// next();
-// });
+ tmpField.deletePreserved = true;
+ //Move old form_field to start
+ submission.form_fields.unshift(tmpField);
+
+ that.form_fields.unshift(tmpField);
+ // console.log('form.form_fields\n--------\n\n');
+ // console.log(that.form_fields);
+ }
+ }
+
+ submission.save(function (err) {
+ if(err) callback(err);
+ else callback(null);
+ });
+ }, function (err) {
+ if(err){
+ console.error(err.message);
+ next(err);
+ }
+ // console.log('form.form_fields\n--------\n\n');
+ // console.log(that.form_fields);
+ next();
+ });
+ }
+ );
+ }else {
+ next();
+ }
+ }else {
+ next();
+ }
+});
FormSchema.methods.generateFDFTemplate = function() {
var _keys = _.pluck(this.form_fields, 'title'),
diff --git a/app/models/form_field.server.model.js b/app/models/form_field.server.model.js
index 796b3293..8a034b40 100644
--- a/app/models/form_field.server.model.js
+++ b/app/models/form_field.server.model.js
@@ -41,14 +41,14 @@ function validateFormFieldType(value) {
* Question Schema
*/
var FormFieldSchema = new Schema({
- created: {
- type: Date,
- default: Date.now
- },
- lastModified: {
- type: Date,
- default: Date.now
- },
+ // created: {
+ // type: Date,
+ // default: Date.now
+ // },
+ // lastModified: {
+ // type: Date,
+ // default: Date.now
+ // },
title: {
type: String,
default: '',
@@ -70,6 +70,11 @@ var FormFieldSchema = new Schema({
type: Boolean,
default: false,
},
+
+ deletePreserved: {
+ type: Boolean,
+ default: false
+ },
fieldType: {
type: String,
required: 'Field type cannot be blank',
diff --git a/app/models/form_submission.server.model.js b/app/models/form_submission.server.model.js
index b9336db2..531abdee 100644
--- a/app/models/form_submission.server.model.js
+++ b/app/models/form_submission.server.model.js
@@ -10,15 +10,15 @@ var mongoose = require('mongoose'),
_ = require('lodash'),
config = require('../../config/config'),
path = require('path'),
- fs = require('fs-extra');
+ fs = require('fs-extra'),
+ FieldSchema = require('./form_field.server.model.js');
/**
* Form Submission Schema
*/
var FormSubmissionSchema = new Schema({
- title: {
- type: String,
- required: true,
+ title:{
+ type: String
},
created: {
type: Date,
@@ -28,17 +28,17 @@ var FormSubmissionSchema = new Schema({
admin: {
type: Schema.Types.ObjectId,
ref: 'User',
+ required: true
},
- form_fields: [{type: Schema.Types.Mixed}],
- form: {
- type: Schema.Types.ObjectId,
- ref: 'Form',
+ form_fields: [Schema.Types.Mixed],//[FieldSchema],
+ form: {
+ type:Schema.Types.ObjectId,
+ ref:'Form',
required: true
},
ipAddr: {
type: String,
- required: false
},
geoLocation: {
type: Schema.Types.Mixed,
@@ -47,6 +47,9 @@ var FormSubmissionSchema = new Schema({
pdfFilePath: {
type: Schema.Types.Mixed,
},
+ pdf: {
+ type: Schema.Types.Mixed,
+ },
fdfData: {
type: Schema.Types.Mixed,
},
@@ -57,62 +60,58 @@ var FormSubmissionSchema = new Schema({
});
-//Check for IP Address of submitting person
-// FormSubmissionSchema.pre('save', function (next){
-// if(this.ipAddr){
-// if(this.ipAddr.modified){
-// satelize.satelize({ip: this.ipAddr}, function(err, geoData){
-// if (err) next( new Error(err.message) );
+//Mongoose Relationship initialization
+// FormSubmissionSchema.plugin(relationship, { relationshipPathName:'form' });
-// this.geoLocation = JSON.parse(geoData);
-// next();
-// });
-// }
-// }
-// console.log('ipAddr check');
-// next();
-// });
+
+//Check for IP Address of submitting person
+FormSubmissionSchema.pre('save', function (next){
+ if(this.ipAddr){
+ if(this.ipAddr.modified){
+ satelize.satelize({ip: this.ipAddr}, function(err, geoData){
+ if (err) next( new Error(err.message) );
+
+ this.geoLocation = JSON.parse(geoData);
+ next();
+ });
+ }
+ }
+ console.log('ipAddr check');
+ next();
+});
//Generate autofilled PDF if flags are set
FormSubmissionSchema.pre('save', function (next) {
- // debugger;
- var fdfData, dest_filename, dest_path;
- var that = this;
- var _form = this.form;
+ var fdfData, dest_filename, dest_path,
+ that = this,
+ _form = this.form;
+ console.log(this.pdf);
- // Form.findById(that.form, function(err, _form){
- // if(err) next( new Error(err.mesasge) );
-
- that.title = _form.title;
- // console.log(_form);
+ if(this.pdf.path){
- if(_form.autofillPDFs){
+ dest_filename = that.title.replace(/ /g,'')+'_submission_'+Date.now()+'.pdf';
+ var __path = this.pdf.path.split('/').slice(0,this.pdf.path.split('/').length-1).join('/');
+ dest_path = path.join(__path, dest_filename);
- dest_filename = _form.title.replace(/ /g,'')+'_submission_'+Date.now()+'.pdf';
- dest_path = path.join(config.pdfUploadPath, dest_filename);
+ that.pdfFilePath = dest_path;
- this.pdfFilePath = dest_path;
+ pdfFiller.fillForm(that.pdf.path, dest_path, that.fdfData, function(err){
+ console.log('fdfData: \n');
+ console.log(that.fdfData);
+ // console.log('_form.pdf.path: '+_form.pdf.path);
+ // console.log('dest_path: '+dest_path);
- pdfFiller.fillForm(_form.pdf.path, dest_path, that.fdfData, function(err){
- console.log('fdfData: \n');
- console.log(that.fdfData);
-
- // console.log('_form.pdf.path: '+_form.pdf.path);
- // console.log('dest_path: '+dest_path);
-
- if(err) {
- console.log('\n err.message: '+err.message);
- next( new Error(err.message) );
- }
- console.log('Field data from Form: '+_form.title.replace(/ /g,'')+' outputed to new PDF: '+dest_path);
- next();
- });
- } else {
+ if(err) {
+ console.log('\n err.message: '+err.message);
+ next( new Error(err.message) );
+ }
+ console.log('Field data from Form: '+that.title.replace(/ /g,'')+' outputed to new PDF: '+dest_path);
next();
- }
-
- // });
+ });
+ } else {
+ next();
+ }
});
diff --git a/app/models/user.server.model.js b/app/models/user.server.model.js
index 2ae755af..e97e385a 100755
--- a/app/models/user.server.model.js
+++ b/app/models/user.server.model.js
@@ -47,14 +47,15 @@ var UserSchema = new Schema({
email: {
type: String,
trim: true,
- default: '',
+ unique: 'Account already exists with email',
+ required: 'Please enter your email',
validate: [validateLocalStrategyProperty, 'Please fill in your email'],
match: [/.+\@.+\..+/, 'Please fill a valid email address']
},
username: {
type: String,
- unique: 'Username already exists',
- required: 'Please fill in a username',
+ unique: true,
+ required: true,
trim: true
},
password: {
@@ -84,21 +85,13 @@ var UserSchema = new Schema({
default: 'english',
required: 'User must have a language'
},
- updated: {
+ lastModified: {
type: Date
},
created: {
type: Date,
default: Date.now
},
-
- /* For account activation */
- activationToken: {
- type: String
- },
- activationTokenExpires: {
- type: Date
- },
/* For reset password */
resetPasswordToken: {
@@ -112,6 +105,9 @@ var UserSchema = new Schema({
//Create folder for user's pdfs
UserSchema.pre('save', function (next) {
+ if(!this.username || this.username !== this.email){
+ this.username = this.email;
+ }
var newDestination = path.join(config.pdfUploadPath, this.username.replace(/ /g,'')),
stat = null;
diff --git a/app/routes/forms.server.routes.js b/app/routes/forms.server.routes.js
index 36a2da37..e4b60589 100644
--- a/app/routes/forms.server.routes.js
+++ b/app/routes/forms.server.routes.js
@@ -22,7 +22,8 @@ module.exports = function(app) {
.delete(users.requiresLogin, forms.hasAuthorization, forms.delete);
app.route('/forms/:formId([a-zA-Z0-9]+)/submissions')
- .get(users.requiresLogin, forms.hasAuthorization, forms.listSubmissions);
+ .get(users.requiresLogin, forms.hasAuthorization, forms.listSubmissions)
+ .delete(users.requiresLogin, forms.hasAuthorization, forms.deleteSubmissions);
// 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 48fb4d6a..a4460461 100755
--- a/app/routes/users.server.routes.js
+++ b/app/routes/users.server.routes.js
@@ -14,9 +14,9 @@ module.exports = function(app) {
app.route('/users').put(users.requiresLogin, users.update);
app.route('/users/accounts').delete(users.requiresLogin, users.removeOAuthProvider);
- // Account activation reset token
- app.route('/auth/reset/:token').get(users.validateResetToken);
- app.route('/auth/reset/:token').post(users.reset);
+ // Setting up the users account verification api
+ app.route('/auth/verify').post(users.resendVerificationEmail);
+ app.route('/auth/verify/:token').get(users.validateVerificationToken);
// Setting up the users password api
app.route('/users/password').post(users.requiresLogin, users.changePassword);
diff --git a/app/tests/article.server.model.test.js b/app/tests/article.server.model.test.js
index b4b76b8a..3b6ad3f2 100755
--- a/app/tests/article.server.model.test.js
+++ b/app/tests/article.server.model.test.js
@@ -1,64 +1,64 @@
-'use strict';
+// 'use strict';
-/**
- * Module dependencies.
- */
-var should = require('should'),
- mongoose = require('mongoose'),
- User = mongoose.model('User'),
- Article = mongoose.model('Article');
+// /**
+// * Module dependencies.
+// */
+// var should = require('should'),
+// mongoose = require('mongoose'),
+// User = mongoose.model('User'),
+// Article = mongoose.model('Article');
-/**
- * Globals
- */
-var user, article;
+// /**
+// * Globals
+// */
+// var user, article;
-/**
- * Unit tests
- */
-describe('Article Model Unit Tests:', function() {
- beforeEach(function(done) {
- user = new User({
- firstName: 'Full',
- lastName: 'Name',
- displayName: 'Full Name',
- email: 'test@test.com',
- username: 'username',
- password: 'password'
- });
+// /**
+// * Unit tests
+// */
+// describe('Article Model Unit Tests:', function() {
+// beforeEach(function(done) {
+// user = new User({
+// firstName: 'Full',
+// lastName: 'Name',
+// displayName: 'Full Name',
+// email: 'test@test.com',
+// username: 'username',
+// password: 'password'
+// });
- user.save(function() {
- article = new Article({
- title: 'Article Title',
- content: 'Article Content',
- user: user
- });
+// user.save(function() {
+// article = new Article({
+// title: 'Article Title',
+// content: 'Article Content',
+// user: user
+// });
- done();
- });
- });
+// done();
+// });
+// });
- describe('Method Save', function() {
- it('should be able to save without problems', function(done) {
- return article.save(function(err) {
- should.not.exist(err);
- done();
- });
- });
+// describe('Method Save', function() {
+// it('should be able to save without problems', function(done) {
+// return article.save(function(err) {
+// should.not.exist(err);
+// done();
+// });
+// });
- it('should be able to show an error when try to save without title', function(done) {
- article.title = '';
+// it('should be able to show an error when try to save without title', function(done) {
+// article.title = '';
- return article.save(function(err) {
- should.exist(err);
- done();
- });
- });
- });
+// return article.save(function(err) {
+// should.exist(err);
+// done();
+// });
+// });
+// });
- afterEach(function(done) {
- Article.remove().exec(function() {
- User.remove().exec(done);
- });
- });
-});
+// afterEach(function(done) {
+// Article.remove().exec(function() {
+// User.remove().exec(done);
+// });
+// });
+// });
diff --git a/app/tests/article.server.routes.test.js b/app/tests/article.server.routes.test.js
index c583c3f3..5dcf929f 100755
--- a/app/tests/article.server.routes.test.js
+++ b/app/tests/article.server.routes.test.js
@@ -1,280 +1,280 @@
-'use strict';
+// 'use strict';
-var should = require('should'),
- request = require('supertest'),
- app = require('../../server'),
- mongoose = require('mongoose'),
- User = mongoose.model('User'),
- Article = mongoose.model('Article'),
- agent = request.agent(app);
+// var should = require('should'),
+// request = require('supertest'),
+// app = require('../../server'),
+// mongoose = require('mongoose'),
+// User = mongoose.model('User'),
+// Article = mongoose.model('Article'),
+// agent = request.agent(app);
-/**
- * Globals
- */
-var credentials, user, article;
+// /**
+// * Globals
+// */
+// var credentials, user, article;
-/**
- * Article routes tests
- */
-describe('Article CRUD tests', function() {
- beforeEach(function(done) {
- // Create user credentials
- credentials = {
- username: 'username',
- password: 'password'
- };
+// /**
+// * Article routes tests
+// */
+// describe('Article CRUD tests', function() {
+// beforeEach(function(done) {
+// // Create user credentials
+// credentials = {
+// username: 'username',
+// password: 'password'
+// };
- // Create a new user
- user = new User({
- firstName: 'Full',
- lastName: 'Name',
- displayName: 'Full Name',
- email: 'test@test.com',
- username: credentials.username,
- password: credentials.password,
- provider: 'local'
- });
+// // Create a new user
+// user = new User({
+// firstName: 'Full',
+// lastName: 'Name',
+// displayName: 'Full Name',
+// email: 'test@test.com',
+// username: credentials.username,
+// password: credentials.password,
+// provider: 'local'
+// });
- // Save a user to the test db and create new article
- user.save(function() {
- article = {
- title: 'Article Title',
- content: 'Article Content'
- };
+// // Save a user to the test db and create new article
+// user.save(function() {
+// article = {
+// title: 'Article Title',
+// content: 'Article Content'
+// };
- done();
- });
- });
+// done();
+// });
+// });
- it('should be able to save an article if logged in', function(done) {
- agent.post('/auth/signin')
- .send(credentials)
- .expect(200)
- .end(function(signinErr, signinRes) {
- // Handle signin error
- if (signinErr) done(signinErr);
+// it('should be able to save an article if logged in', function(done) {
+// agent.post('/auth/signin')
+// .send(credentials)
+// .expect(200)
+// .end(function(signinErr, signinRes) {
+// // Handle signin error
+// if (signinErr) done(signinErr);
- // Get the userId
- var userId = user.id;
+// // Get the userId
+// var userId = user.id;
- // Save a new article
- agent.post('/articles')
- .send(article)
- .expect(200)
- .end(function(articleSaveErr, articleSaveRes) {
- // Handle article save error
- if (articleSaveErr) done(articleSaveErr);
+// // Save a new article
+// agent.post('/articles')
+// .send(article)
+// .expect(200)
+// .end(function(articleSaveErr, articleSaveRes) {
+// // Handle article save error
+// if (articleSaveErr) done(articleSaveErr);
- // Get a list of articles
- agent.get('/articles')
- .end(function(articlesGetErr, articlesGetRes) {
- // Handle article save error
- if (articlesGetErr) done(articlesGetErr);
+// // Get a list of articles
+// agent.get('/articles')
+// .end(function(articlesGetErr, articlesGetRes) {
+// // Handle article save error
+// if (articlesGetErr) done(articlesGetErr);
- // Get articles list
- var articles = articlesGetRes.body;
+// // Get articles list
+// var articles = articlesGetRes.body;
- // Set assertions
- (articles[0].user._id).should.equal(userId);
- (articles[0].title).should.match('Article Title');
+// // Set assertions
+// (articles[0].user._id).should.equal(userId);
+// (articles[0].title).should.match('Article Title');
- // Call the assertion callback
- done();
- });
- });
- });
- });
+// // Call the assertion callback
+// done();
+// });
+// });
+// });
+// });
- it('should not be able to save an article if not logged in', function(done) {
- agent.post('/articles')
- .send(article)
- .expect(401)
- .end(function(articleSaveErr, articleSaveRes) {
- // Call the assertion callback
- done(articleSaveErr);
- });
- });
+// it('should not be able to save an article if not logged in', function(done) {
+// agent.post('/articles')
+// .send(article)
+// .expect(401)
+// .end(function(articleSaveErr, articleSaveRes) {
+// // Call the assertion callback
+// done(articleSaveErr);
+// });
+// });
- it('should not be able to save an article if no title is provided', function(done) {
- // Invalidate title field
- article.title = '';
+// it('should not be able to save an article if no title is provided', function(done) {
+// // Invalidate title field
+// article.title = '';
- agent.post('/auth/signin')
- .send(credentials)
- .expect(200)
- .end(function(signinErr, signinRes) {
- // Handle signin error
- if (signinErr) done(signinErr);
+// agent.post('/auth/signin')
+// .send(credentials)
+// .expect(200)
+// .end(function(signinErr, signinRes) {
+// // Handle signin error
+// if (signinErr) done(signinErr);
- // Get the userId
- var userId = user.id;
+// // Get the userId
+// var userId = user.id;
- // Save a new article
- agent.post('/articles')
- .send(article)
- .expect(400)
- .end(function(articleSaveErr, articleSaveRes) {
- // Set message assertion
- (articleSaveRes.body.message).should.match('Title cannot be blank');
+// // Save a new article
+// agent.post('/articles')
+// .send(article)
+// .expect(400)
+// .end(function(articleSaveErr, articleSaveRes) {
+// // Set message assertion
+// (articleSaveRes.body.message).should.match('Title cannot be blank');
- // Handle article save error
- done(articleSaveErr);
- });
- });
- });
+// // Handle article save error
+// done(articleSaveErr);
+// });
+// });
+// });
- it('should be able to update an article if signed in', function(done) {
- agent.post('/auth/signin')
- .send(credentials)
- .expect(200)
- .end(function(signinErr, signinRes) {
- // Handle signin error
- if (signinErr) done(signinErr);
+// it('should be able to update an article if signed in', function(done) {
+// agent.post('/auth/signin')
+// .send(credentials)
+// .expect(200)
+// .end(function(signinErr, signinRes) {
+// // Handle signin error
+// if (signinErr) done(signinErr);
- // Get the userId
- var userId = user.id;
+// // Get the userId
+// var userId = user.id;
- // Save a new article
- agent.post('/articles')
- .send(article)
- .expect(200)
- .end(function(articleSaveErr, articleSaveRes) {
- // Handle article save error
- if (articleSaveErr) done(articleSaveErr);
+// // Save a new article
+// agent.post('/articles')
+// .send(article)
+// .expect(200)
+// .end(function(articleSaveErr, articleSaveRes) {
+// // Handle article save error
+// if (articleSaveErr) done(articleSaveErr);
- // Update article title
- article.title = 'WHY YOU GOTTA BE SO MEAN?';
+// // Update article title
+// article.title = 'WHY YOU GOTTA BE SO MEAN?';
- // Update an existing article
- agent.put('/articles/' + articleSaveRes.body._id)
- .send(article)
- .expect(200)
- .end(function(articleUpdateErr, articleUpdateRes) {
- // Handle article update error
- if (articleUpdateErr) done(articleUpdateErr);
+// // Update an existing article
+// agent.put('/articles/' + articleSaveRes.body._id)
+// .send(article)
+// .expect(200)
+// .end(function(articleUpdateErr, articleUpdateRes) {
+// // Handle article update error
+// if (articleUpdateErr) done(articleUpdateErr);
- // Set assertions
- (articleUpdateRes.body._id).should.equal(articleSaveRes.body._id);
- (articleUpdateRes.body.title).should.match('WHY YOU GOTTA BE SO MEAN?');
+// // Set assertions
+// (articleUpdateRes.body._id).should.equal(articleSaveRes.body._id);
+// (articleUpdateRes.body.title).should.match('WHY YOU GOTTA BE SO MEAN?');
- // Call the assertion callback
- done();
- });
- });
- });
- });
+// // Call the assertion callback
+// done();
+// });
+// });
+// });
+// });
- it('should be able to get a list of articles if not signed in', function(done) {
- // Create new article model instance
- var articleObj = new Article(article);
+// it('should be able to get a list of articles if not signed in', function(done) {
+// // Create new article model instance
+// var articleObj = new Article(article);
- // Save the article
- articleObj.save(function() {
- // Request articles
- request(app).get('/articles')
- .end(function(req, res) {
- // Set assertion
- res.body.should.be.an.Array.with.lengthOf(1);
+// // Save the article
+// articleObj.save(function() {
+// // Request articles
+// request(app).get('/articles')
+// .end(function(req, res) {
+// // Set assertion
+// res.body.should.be.an.Array.with.lengthOf(1);
- // Call the assertion callback
- done();
- });
+// // Call the assertion callback
+// done();
+// });
- });
- });
+// });
+// });
- it('should be able to get a single article if not signed in', function(done) {
- // Create new article model instance
- var articleObj = new Article(article);
+// it('should be able to get a single article if not signed in', function(done) {
+// // Create new article model instance
+// var articleObj = new Article(article);
- // Save the article
- articleObj.save(function() {
- request(app).get('/articles/' + articleObj._id)
- .end(function(req, res) {
- // Set assertion
- res.body.should.be.an.Object.with.property('title', article.title);
+// // Save the article
+// articleObj.save(function() {
+// request(app).get('/articles/' + articleObj._id)
+// .end(function(req, res) {
+// // Set assertion
+// res.body.should.be.an.Object.with.property('title', article.title);
- // Call the assertion callback
- done();
- });
- });
- });
+// // Call the assertion callback
+// done();
+// });
+// });
+// });
- it('should return proper error for single article which doesnt exist, if not signed in', function(done) {
- request(app).get('/articles/test')
- .end(function(req, res) {
- // Set assertion
- res.body.should.be.an.Object.with.property('message', 'Article is invalid');
+// it('should return proper error for single article which doesnt exist, if not signed in', function(done) {
+// request(app).get('/articles/test')
+// .end(function(req, res) {
+// // Set assertion
+// res.body.should.be.an.Object.with.property('message', 'Article is invalid');
- // Call the assertion callback
- done();
- });
- });
+// // Call the assertion callback
+// done();
+// });
+// });
- it('should be able to delete an article if signed in', function(done) {
- agent.post('/auth/signin')
- .send(credentials)
- .expect(200)
- .end(function(signinErr, signinRes) {
- // Handle signin error
- if (signinErr) done(signinErr);
+// it('should be able to delete an article if signed in', function(done) {
+// agent.post('/auth/signin')
+// .send(credentials)
+// .expect(200)
+// .end(function(signinErr, signinRes) {
+// // Handle signin error
+// if (signinErr) done(signinErr);
- // Get the userId
- var userId = user.id;
+// // Get the userId
+// var userId = user.id;
- // Save a new article
- agent.post('/articles')
- .send(article)
- .expect(200)
- .end(function(articleSaveErr, articleSaveRes) {
- // Handle article save error
- if (articleSaveErr) done(articleSaveErr);
+// // Save a new article
+// agent.post('/articles')
+// .send(article)
+// .expect(200)
+// .end(function(articleSaveErr, articleSaveRes) {
+// // Handle article save error
+// if (articleSaveErr) done(articleSaveErr);
- // Delete an existing article
- agent.delete('/articles/' + articleSaveRes.body._id)
- .send(article)
- .expect(200)
- .end(function(articleDeleteErr, articleDeleteRes) {
- // Handle article error error
- if (articleDeleteErr) done(articleDeleteErr);
+// // Delete an existing article
+// agent.delete('/articles/' + articleSaveRes.body._id)
+// .send(article)
+// .expect(200)
+// .end(function(articleDeleteErr, articleDeleteRes) {
+// // Handle article error error
+// if (articleDeleteErr) done(articleDeleteErr);
- // Set assertions
- (articleDeleteRes.body._id).should.equal(articleSaveRes.body._id);
+// // Set assertions
+// (articleDeleteRes.body._id).should.equal(articleSaveRes.body._id);
- // Call the assertion callback
- done();
- });
- });
- });
- });
+// // Call the assertion callback
+// done();
+// });
+// });
+// });
+// });
- it('should not be able to delete an article if not signed in', function(done) {
- // Set article user
- article.user = user;
+// it('should not be able to delete an article if not signed in', function(done) {
+// // Set article user
+// article.user = user;
- // Create new article model instance
- var articleObj = new Article(article);
+// // Create new article model instance
+// var articleObj = new Article(article);
- // Save the article
- articleObj.save(function() {
- // Try deleting article
- request(app).delete('/articles/' + articleObj._id)
- .expect(401)
- .end(function(articleDeleteErr, articleDeleteRes) {
- // Set message assertion
- (articleDeleteRes.body.message).should.match('User is not logged in');
+// // Save the article
+// articleObj.save(function() {
+// // Try deleting article
+// request(app).delete('/articles/' + articleObj._id)
+// .expect(401)
+// .end(function(articleDeleteErr, articleDeleteRes) {
+// // Set message assertion
+// (articleDeleteRes.body.message).should.match('User is not logged in');
- // Handle article error error
- done(articleDeleteErr);
- });
+// // Handle article error error
+// done(articleDeleteErr);
+// });
- });
- });
+// });
+// });
- afterEach(function(done) {
- User.remove().exec(function() {
- Article.remove().exec(done);
- });
- });
-});
+// afterEach(function(done) {
+// User.remove().exec(function() {
+// Article.remove().exec(done);
+// });
+// });
+// });
diff --git a/app/tests/form.server.model.test.js b/app/tests/form.server.model.test.js
index afc1263d..c8d86e74 100644
--- a/app/tests/form.server.model.test.js
+++ b/app/tests/form.server.model.test.js
@@ -6,13 +6,14 @@
var should = require('should'),
mongoose = require('mongoose'),
User = mongoose.model('User'),
- Form = mongoose.model('Form');
+ Form = mongoose.model('Form'),
+ _ = require('lodash'),
+ FormSubmission = mongoose.model('FormSubmission');
/**
* Globals
*/
-var user, Form,
-FormFDF;
+var user, myForm, mySubmission, FormFDF;
/**
* Unit tests
@@ -29,10 +30,15 @@ describe('Form Model Unit Tests:', function() {
});
user.save(function() {
- Form = new Form({
+ myForm = new Form({
title: 'Form Title',
admin: user,
- form_fields: [{'title':'Short Text2','fieldType':'textfield','fieldValue':'','disabled':false},{'disabled':false,'created':1435952663586,'fieldValue':'','fieldFlags':'0','fieldType':'checkbox','title':'nascar'},{'disabled':false,'created':1435952663586,'fieldValue':'','fieldFlags':'0','fieldType':'checkbox','title':'hockey'}]
+ language: 'english',
+ form_fields: [
+ {'fieldType':'textfield', 'title':'First Name', 'fieldValue': ''},
+ {'fieldType':'checkbox', 'title':'nascar', 'fieldValue': ''},
+ {'fieldType':'checkbox', 'title':'hockey', 'fieldValue': ''}
+ ]
});
done();
@@ -41,38 +47,112 @@ describe('Form Model Unit Tests:', function() {
describe('Method Save', function() {
it('should be able to save without problems', function(done) {
- return Form.save(function(err) {
+ return myForm.save(function(err) {
should.not.exist(err);
done();
});
});
it('should be able to show an error when try to save without title', function(done) {
- Form.title = '';
+ myForm.title = '';
- return Form.save(function(err) {
+ return myForm.save(function(err) {
should.exist(err);
+ should.equal(err.errors.title.message, 'Title cannot be blank');
done();
});
});
});
- describe('Method generateFDFTemplate', function() {
- it('should be able to generate one that is correct', function(done) {
- return Form.generateFDFTemplate(function(err) {
- should.not.exist(err);
+ describe('Test FormField and Submission Logic', function() {
+ var new_form_fields_add1, new_form_fields_del, submission_fields, old_fields;
+
+ before(function(done){
+ new_form_fields_add1 = _.clone(myForm.form_fields);
+ new_form_fields_add1.push(
+ {'fieldType':'textfield', 'title':'Last Name', 'fieldValue': ''}
+ );
+
+ new_form_fields_del = _.clone(myForm.form_fields);
+ new_form_fields_del.splice(0, 1);
+
+ submission_fields = _.clone(myForm.toObject().form_fields);
+ submission_fields[0].fieldValue = 'David';
+ submission_fields[1].fieldValue = true;
+ submission_fields[2].fieldValue = true;
+
+ mySubmission = new FormSubmission({
+ form_fields: submission_fields,
+ admin: user,
+ form: myForm._id,
+ timeElapsed: 17.55
+ });
+
+ mySubmission.save(function(){
done();
});
});
- it('should be able to show an error when try to save without title', function(done) {
- Form.title = '';
-
- return Form.save(function(err) {
- should.exist(err);
+ after(function(done){
+ mySubmission.remove(function(){
done();
});
});
+
+ beforeEach(function(done){
+ old_fields = myForm.toObject().form_fields;
+ // console.log(old_fields);
+ done();
+ });
+
+ it('should preserve deleted form_fields that have submissions without any problems', function(done) {
+
+ var expected_fields = old_fields.slice(1,3).concat(old_fields.slice(0,1));
+
+ // console.log(old_fields);
+
+ myForm.form_fields = new_form_fields_del;
+ return myForm.save(function(err, form) {
+ should.not.exist(err);
+ var actual_fields = form.toObject();
+
+ should.deepEqual(form.toObject().form_fields, expected_fields, 'old form_fields not equal to newly saved form_fields');
+ done();
+ });
+ });
+
+ // it('should delete \'preseved\' form_fields whose submissions have been removed without any problems', function(done) {
+
+ // myForm.form_fields = new_form_fields_del;
+ // myForm.save(function(err, form) {
+ // should.not.exist(err);
+ // (form.form_fields).should.be.eql(old_fields, 'old form_fields not equal to newly saved form_fields');
+
+ // //Remove submission
+ // mySubmission.remove(function(err){
+ // myForm.submissions.should.have.length(0);
+ // myForm.form_fields.should.not.containDeep(old_fields[0]);
+ // });
+ // });
+ // });
+
+ });
+
+ describe('Method generateFDFTemplate', function() {
+ beforeEach(function(done){
+ FormFDF = {
+ 'First Name': '',
+ 'nascar': '',
+ 'hockey': ''
+ };
+ done();
+ });
+
+ it('should be able to generate a FDF template without any problems', function(done) {
+ var fdfTemplate = myForm.generateFDFTemplate();
+ (fdfTemplate).should.be.eql(FormFDF);
+ done();
+ });
});
afterEach(function(done) {
diff --git a/config/env/all.js b/config/env/all.js
index 986863a2..67df6bd9 100755
--- a/config/env/all.js
+++ b/config/env/all.js
@@ -9,6 +9,8 @@ module.exports = {
port: process.env.PORT || 3000,
templateEngine: 'swig',
+ baseUrl: '',
+
//Sentry DSN Client Key
DSN: 'http://db01e03015ce48e2b68240ea8254b17c:5d878e9bb6c6488fbb70fb81295ee700@sentry.polydaic.com/1',
diff --git a/config/env/development.js b/config/env/development.js
index af9f27d9..caea8d69 100755
--- a/config/env/development.js
+++ b/config/env/development.js
@@ -14,7 +14,7 @@ module.exports = {
// Stream defaults to process.stdout
// Uncomment to enable logging to a log on the file system
options: {
- //stream: 'access.log'
+ // stream: 'access.log'
}
},
app: {
@@ -46,12 +46,12 @@ module.exports = {
callbackURL: '/auth/github/callback'
},
mailer: {
- from: process.env.MAILER_FROM || 'MAILER_FROM',
+ from: process.env.MAILER_FROM || 'hi@example.com',
options: {
- service: process.env.MAILER_SERVICE_PROVIDER || 'MAILER_SERVICE_PROVIDER',
+ service: process.env.MAILER_SERVICE_PROVIDER || 'Mandrill',
auth: {
- user: process.env.MAILER_EMAIL_ID || 'MAILER_EMAIL_ID',
- pass: process.env.MAILER_PASSWORD || 'MAILER_PASSWORD'
+ user: process.env.MAILER_EMAIL_ID || 'hackouver@gmail.com',
+ pass: process.env.MAILER_PASSWORD || 'ehOLuSXCBFxLjipRalBxVg'
}
}
}
diff --git a/config/express.js b/config/express.js
index 445d75b7..d7d12769 100755
--- a/config/express.js
+++ b/config/express.js
@@ -32,6 +32,7 @@ module.exports = function(db) {
// Initialize express app
var app = express();
+
// Globbing model files
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
require(path.resolve(modelPath));
@@ -52,7 +53,10 @@ module.exports = function(db) {
// Passing the request url to environment locals
app.use(function(req, res, next) {
- res.locals.url = req.protocol + '://' + req.headers.host + req.url;
+ if(config.baseUrl === ''){
+ config.baseUrl = req.protocol + '://' + req.headers.host;
+ }
+ res.locals.url = req.protocol + '://' + req.headers.host + req.url;
next();
});
@@ -103,7 +107,8 @@ module.exports = function(db) {
app.disable('x-powered-by');
// Setting the app router and static folder
- app.use(express.static(path.resolve('./public')));
+ app.use('/', express.static(path.resolve('./public')));
+ app.use('/uploads', express.static(path.resolve('./uploads')));
var formCtrl = require('../app/controllers/forms.server.controller');
// Setting the pdf upload route and folder
diff --git a/karma.conf.js b/karma.conf.js
index f20106f0..effde2de 100755
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -3,7 +3,12 @@
/**
* Module dependencies.
*/
-var applicationConfiguration = require('./config/config');
+var applicationConfiguration = require('./config/config'),
+ bowerFiles = require('main-bower-files');
+
+var bowerDep = bowerFiles('**/**.js');
+
+console.log(bowerDep);
// Karma configuration
module.exports = function(config) {
@@ -12,7 +17,7 @@ module.exports = function(config) {
frameworks: ['jasmine'],
// List of files / patterns to load in the browser
- files: applicationConfiguration.assets.lib.js.concat(applicationConfiguration.assets.js, applicationConfiguration.assets.tests),
+ files: bowerDep.concat(applicationConfiguration.assets.js, applicationConfiguration.assets.tests),
// Test results reporter to use
// Possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
@@ -39,7 +44,7 @@ module.exports = function(config) {
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
- browsers: ['Chrome'],
+ browsers: ['PhantomJS'],
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000,
diff --git a/package.json b/package.json
index 32e885eb..e3f3fe4c 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"connect-mongo": "~0.4.1",
"consolidate": "~0.10.0",
"cookie-parser": "~1.3.2",
+ "email-verification": "^0.1.9",
"express": "~4.10.1",
"express-session": "~1.9.1",
"forever": "~0.11.0",
@@ -64,6 +65,7 @@
"mocha": ">=1.20.0",
"mongoose": "~3.8.8",
"mongoose-datatable": "^1.0.2",
+ "mongoose-relationship": "^0.1.4",
"morgan": "~1.4.1",
"multer": "~0.1.8",
"nodemailer": "~1.3.0",
diff --git a/public/dist/application.min.css b/public/dist/application.min.css
index aaa3ce7c..5baa926a 100644
--- a/public/dist/application.min.css
+++ b/public/dist/application.min.css
@@ -1 +1 @@
-.navbar-inverse{background-color:#fafafa;border:0}.navbar .navbar-brand{font-size:1.6em;font-weight:900;color:#ff8383}.navbar .navbar-brand:hover,.navbar .navbar-brand:visited{color:#FA787E}.navbar li.dropdown a.dropdown-toggle:hover>*{color:#000}.navbar li.dropdown a.dropdown-toggle>*{color:#d9d9d9}.navbar li.dropdown.open a.dropdown-toggle:hover>*{color:#fff}.navbar .navbar-brand span{text-decoration:underline}.nav.navbar-nav.navbar-right li{padding-right:20px}.content{margin-top:70px}.undecorated-link:hover{text-decoration:none}.ng-cloak,.x-ng-cloak,[data-ng-cloak],[ng-cloak],[ng\:cloak],[x-ng-cloak]{display:none!important}.ng-invalid.ng-dirty{border-color:#FA787E}.ng-valid.ng-dirty{border-color:#78FA89}.browsehappy.jumbotron.hide,body.ng-cloak{display:block}section.hero-section{width:100%}section.hero-section .jumbotron{background-color:transparent;color:#fff}.image-background{position:absolute;top:0;left:0;height:230%;width:100%;z-index:-98;background-image:url(http://yourplaceandmine.ie/wp-content/uploads/2014/09/Daingean-meeting-048_13-1080x675.jpg);background-repeat:no-repeat;background-position:0 50%;background-size:cover}.opacity-background{position:absolute;top:0;left:0;height:230%;width:100%;background-color:rgba(0,0,0,.5);z-index:-97}section.hero-section .jumbotron .signup-btn{background-color:#FA787E;border:none;font-size:2em;padding:.3em .9em;color:#fff;background-color:rgba(250,120,126,.65) #FA787E}.row-height{display:table;table-layout:fixed;height:100%;width:100%}.col-height{display:table-cell;float:none;height:100%}.col-top{vertical-align:top}.col-middle{vertical-align:middle}.col-bottom{vertical-align:bottom}@media (min-width:480px){.row-xs-height{display:table;table-layout:fixed;height:100%;width:100%}.col-xs-height{display:table-cell;float:none;height:100%}.col-xs-top{vertical-align:top}.col-xs-middle{vertical-align:middle}.col-xs-bottom{vertical-align:bottom}}@media (min-width:768px){.row-sm-height{display:table;table-layout:fixed;height:100%;width:100%}.col-sm-height{display:table-cell;float:none;height:100%}.col-sm-top{vertical-align:top}.col-sm-middle{vertical-align:middle}.col-sm-bottom{vertical-align:bottom}}@media (min-width:992px){.row-md-height{display:table;table-layout:fixed;height:100%;width:100%}.col-md-height{display:table-cell;float:none;height:100%}.col-md-top{vertical-align:top}.col-md-middle{vertical-align:middle}.col-md-bottom{vertical-align:bottom}}@media (min-width:1200px){.row-lg-height{display:table;table-layout:fixed;height:100%;width:100%}.col-lg-height{display:table-cell;float:none;height:100%}.col-lg-top{vertical-align:top}.col-lg-middle{vertical-align:middle}.col-lg-bottom{vertical-align:bottom}}form .row.field{padding:1em 0 3em}form .row.field>.field-title{margin-top:.5em;font-size:1.5em}form.submission-form .row.field.statement>.field-title{font-size:1.7em}form.submission-form .row.field.statement>.field-input{font-size:1.2em;color:#ddd}form.submission-form .row.field>.field-input input{width:500px}form.submission-form .row.field .field-input>input:focus{font-size:1em}form .row.field.textfield>.field-input>input{padding:.45em .9em;width:600px}div.config-form>.row{padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);width:90%}div.config-form>.row>.container:nth-of-type(odd){border-right:1px #ddd solid}div.config-form .row>.field-input{padding-top:1.2em;padding-left:.1em}div.config-form .row>.field-input label{padding-left:1.3em;display:block}.admin-form>.page-header{padding-bottom:0;margin-bottom:40px}.admin-form>.page-header h1{margin-bottom:0}.admin-form>.page-header>.col-xs-3{padding-top:1.4em}.admin-form .form-controls .row{padding:5px}.admin-form .page-header{border:none}.admin-form .tab-content{padding-top:3em}.admin-form .panel-heading{background-color:#f1f1f1}.admin-form .panel-heading:hover{background-color:#fff;cursor:pointer}.admin-form .panel-heading a:hover{text-decoration:none}.current-fields .tool-panel>.panel-default:hover{border-color:#9d9d9d;cursor:pointer}.current-fields .tool-panel>.panel-default .panel-heading{background-color:#fff;color:#9d9d9d!important}.current-fields .tool-panel>.panel-default .panel-heading:hover{background-color:#eee;color:#000!important;cursor:pointer}.current-fields .tool-panel>.panel-default .panel-heading a{color:inherit}.current-fields .tool-panel>.panel-default .panel-heading a:hover{text-decoration:none}.admin-form .add-field{background-color:#ddd}.admin-form .add-field .col-xs-6{padding:.25em .4em}.admin-form .add-field .col-xs-6 .panel-heading{border-width:1px;border-style:solid;border-color:#bbb;border-radius:4px}.status-light{padding-left:.6em}.status-light.status-light-off{color:#BE0000}.status-light.status-light-on{color:#3C0}section>section.ng-scope{padding:0 60px 20px}.form-item.row{text-align:center;border-bottom:6px inset #ccc;background-color:#eee;width:180px;height:215px;margin-bottom:45px}.form-item.row.create-new{background-color:#838383;color:#fff}.form-item.row.create-new.new-form{background-color:#ff8383;z-index:11}.form-item.row.create-new.new-form:hover{background-color:#ff6464}.form-item.new-form a.btn{font-size:.95em}.overlay{position:absolute;top:0;left:0;height:193%;width:inherit;background-color:rgba(0,0,0,.5);z-index:10}.form-item.row.create-new:hover,.form-item.row:hover{border-bottom:8px inset #ccc;background-color:#d9d9d9}.form-item.row.create-new:hover{background-color:#515151}.form-item.row>.title-row{position:relative;top:15px;padding-top:3em;padding-bottom:3.65em}.form-item.row>.title-row h4{font-size:1.3em}.form-item.row.create-new>.title-row{padding:0}.form-item.row.create-new>.title-row h4{font-size:7em}.form-item.row>.details-row{margin-top:3.2em}.form-item.row>.details-row small{font-size:.6em}.form-item.row.create-new>.details-row small{font-size:.95em}@media (min-width:992px){.nav-users{position:fixed}}.remove-account-container{display:inline-block;position:relative}.btn-remove-account{top:10px;right:10px;position:absolute}section.auth{margin-top:5em}section.auth>h3{font-size:3em;font-weight:500;color:#777}section.auth.signup-view>h3{font-size:4.4em;padding-bottom:.5em}
\ No newline at end of file
+.navbar-inverse{background-color:#fafafa;border:0}.navbar .navbar-brand{font-size:1.6em;font-weight:900;color:#ff8383}.navbar .navbar-brand:hover,.navbar .navbar-brand:visited{color:#FA787E}.navbar li.dropdown a.dropdown-toggle:hover>*{color:#000}.navbar li.dropdown a.dropdown-toggle>*{color:#d9d9d9}.navbar li.dropdown.open a.dropdown-toggle:hover>*{color:#fff}.navbar .navbar-brand span{text-decoration:underline}.nav.navbar-nav.navbar-right li{padding-right:20px}.content{margin-top:70px}.undecorated-link:hover{text-decoration:none}.ng-cloak,.x-ng-cloak,[data-ng-cloak],[ng-cloak],[ng\:cloak],[x-ng-cloak]{display:none!important}.ng-invalid.ng-dirty{border-color:#FA787E}.ng-valid.ng-dirty{border-color:#78FA89}.browsehappy.jumbotron.hide,body.ng-cloak{display:block}section.hero-section{width:100%}section.hero-section .jumbotron{background-color:transparent;color:#fff}.image-background{position:absolute;top:0;left:0;height:230%;width:100%;z-index:-98;background-image:url(http://yourplaceandmine.ie/wp-content/uploads/2014/09/Daingean-meeting-048_13-1080x675.jpg);background-repeat:no-repeat;background-position:0 50%;background-size:cover}.opacity-background{position:absolute;top:0;left:0;height:230%;width:100%;background-color:rgba(0,0,0,.5);z-index:-97}section.hero-section .jumbotron .signup-btn{background-color:#FA787E;border:none;font-size:2em;padding:.3em .9em;color:#fff;background-color:rgba(250,120,126,.65) #FA787E}.row-height{display:table;table-layout:fixed;height:100%;width:100%}.col-height{display:table-cell;float:none;height:100%}.col-top{vertical-align:top}.col-middle{vertical-align:middle}.col-bottom{vertical-align:bottom}@media (min-width:480px){.row-xs-height{display:table;table-layout:fixed;height:100%;width:100%}.col-xs-height{display:table-cell;float:none;height:100%}.col-xs-top{vertical-align:top}.col-xs-middle{vertical-align:middle}.col-xs-bottom{vertical-align:bottom}}@media (min-width:768px){.row-sm-height{display:table;table-layout:fixed;height:100%;width:100%}.col-sm-height{display:table-cell;float:none;height:100%}.col-sm-top{vertical-align:top}.col-sm-middle{vertical-align:middle}.col-sm-bottom{vertical-align:bottom}}@media (min-width:992px){.row-md-height{display:table;table-layout:fixed;height:100%;width:100%}.col-md-height{display:table-cell;float:none;height:100%}.col-md-top{vertical-align:top}.col-md-middle{vertical-align:middle}.col-md-bottom{vertical-align:bottom}}@media (min-width:1200px){.row-lg-height{display:table;table-layout:fixed;height:100%;width:100%}.col-lg-height{display:table-cell;float:none;height:100%}.col-lg-top{vertical-align:top}.col-lg-middle{vertical-align:middle}.col-lg-bottom{vertical-align:bottom}}.btn{border:1px solid #c6c6c6!important}form .row.field{padding:1em 0 3em}form .row.field>.field-title{margin-top:.5em;font-size:1.5em}form.submission-form .row.field.statement>.field-title{font-size:1.7em}form.submission-form .row.field.statement>.field-input{font-size:1.2em;color:#ddd}form.submission-form .select.radio>.field-input input,form.submission-form .select>.field-input input{width:20%}form.submission-form .select>.field-input .btn{text-align:left;margin-bottom:.7em}form.submission-form .select>.field-input .btn>span{font-size:1.1em}form.submission-form .row.field>.field-input input{width:100%}form.submission-form .row.field .field-input>input:focus{font-size:1em}form .row.field.textfield>.field-input>input{padding:.45em .9em;width:100%;line-height:160%}form .row.field.dropdown>.field-input{height:34px;overflow:hidden}form .row.field.dropdown>.field-input>select{padding:.45em .9em;width:100%;background:0 0;font-size:16px;border:1px solid #ccc;height:34px}div.config-form>.row{padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);width:90%}div.config-form>.row>.container:nth-of-type(odd){border-right:1px #ddd solid}div.config-form .row>.field-input{padding-top:1.2em;padding-left:.1em}div.config-form .row>.field-input label{padding-left:1.3em;display:block}.admin-form>.page-header{padding-bottom:0;margin-bottom:40px}.admin-form>.page-header h1{margin-bottom:0}.admin-form>.page-header>.col-xs-3{padding-top:1.4em}.admin-form .form-controls .row{padding:5px}.admin-form .page-header{border:none}.admin-form .tab-content{padding-top:3em}.admin-form .panel-heading{background-color:#f1f1f1}.admin-form .panel-heading:hover{background-color:#fff;cursor:pointer}.admin-form .panel-heading a:hover{text-decoration:none}.current-fields .tool-panel>.panel-default:hover{border-color:#9d9d9d;cursor:pointer}.current-fields .tool-panel>.panel-default .panel-heading{background-color:#fff;color:#9d9d9d!important}.current-fields .tool-panel>.panel-default .panel-heading:hover{background-color:#eee;color:#000!important;cursor:pointer}.current-fields .tool-panel>.panel-default .panel-heading a{color:inherit}.current-fields .tool-panel>.panel-default .panel-heading a:hover{text-decoration:none}.admin-form .add-field{background-color:#ddd}.admin-form .add-field .col-xs-6{padding:.25em .4em}.admin-form .add-field .col-xs-6 .panel-heading{border-width:1px;border-style:solid;border-color:#bbb;border-radius:4px}.status-light{padding-left:.6em}.status-light.status-light-off{color:#BE0000}.status-light.status-light-on{color:#3C0}section>section.ng-scope{padding:0 60px 20px}.form-item.row{text-align:center;border-bottom:6px inset #ccc;background-color:#eee;width:180px;height:215px;margin-bottom:45px}.form-item.row.create-new{background-color:#838383;color:#fff}.form-item.row.create-new.new-form{background-color:#ff8383;z-index:11}.form-item.row.create-new.new-form:hover{background-color:#ff6464}.form-item.new-form a.btn{font-size:.95em}.overlay{position:absolute;top:0;left:0;height:193%;width:inherit;background-color:rgba(0,0,0,.5);z-index:10}.form-item.row.create-new:hover,.form-item.row:hover{border-bottom:8px inset #ccc;background-color:#d9d9d9}.form-item.row.create-new:hover{background-color:#515151}.form-item.row>.title-row{position:relative;top:15px;padding-top:3em;padding-bottom:3.65em}.form-item.row>.title-row h4{font-size:1.3em}.form-item.row.create-new>.title-row{padding:0}.form-item.row.create-new>.title-row h4{font-size:7em}.form-item.row>.details-row{margin-top:3.2em}.form-item.row>.details-row small{font-size:.6em}.form-item.row.create-new>.details-row small{font-size:.95em}@media (min-width:992px){.nav-users{position:fixed}}.remove-account-container{display:inline-block;position:relative}.btn-remove-account{top:10px;right:10px;position:absolute}section.auth{margin-top:5em}section.auth>h3{font-size:3em;font-weight:500;color:#777}section.auth.signup-view>h3{font-size:4.4em;padding-bottom:.5em}
\ No newline at end of file
diff --git a/public/modules/forms/config/forms.client.config.js b/public/modules/forms/config/forms.client.config.js
index 4086df08..6478eb1d 100644
--- a/public/modules/forms/config/forms.client.config.js
+++ b/public/modules/forms/config/forms.client.config.js
@@ -8,27 +8,30 @@ angular.module('forms').run(['Menus',
}
]).filter('formValidity',
function(){
-
return function(formObj){
- //get keys
- var formKeys = Object.keys(formObj);
+ if(formObj && formObj.form_fields && formObj.visible_form_fields){
+
+ //get keys
+ var formKeys = Object.keys(formObj);
- //we only care about things that don't start with $
- var fieldKeys = formKeys.filter(function(key){
- return key[0] !== '$';
- });
+ //we only care about things that don't start with $
+ var fieldKeys = formKeys.filter(function(key){
+ return key[0] !== '$';
+ });
- var fields = formObj.form_fields;
- // fieldKeys.map(function(key){
- // return formObj[key];
- // });
+ var fields = formObj.form_fields;
+ // fieldKeys.map(function(key){
+ // return formObj[key];
+ // });
- var valid_count = fields.filter(function(field){
- if(typeof field === 'object'){
- return !!(field.fieldValue);
- }
- }).length;
- return valid_count;
+ var valid_count = fields.filter(function(field){
+ if(typeof field === 'object'){
+ return !!(field.fieldValue);
+ }
+ }).length;
+ return valid_count - (formObj.form_fields.length - formObj.visible_form_fields.length);
+ }
+ return 0;
};
}).config(['$provide', function ($provide){
$provide.decorator('accordionDirective', function($delegate) {
diff --git a/public/modules/forms/config/forms.client.routes.js b/public/modules/forms/config/forms.client.routes.js
index a2ebdc1c..5ec819c4 100644
--- a/public/modules/forms/config/forms.client.routes.js
+++ b/public/modules/forms/config/forms.client.routes.js
@@ -10,10 +10,6 @@ angular.module('forms').config(['$stateProvider',
url: '/forms',
templateUrl: 'modules/forms/views/list-forms.client.view.html',
}).
- state('createForm', {
- url: '/forms/create',
- templateUrl: 'modules/forms/views/create-form.client.view.html',
- }).
state('viewForm', {
url: '/forms/:formId/admin',
templateUrl: 'modules/forms/views/view-form.client.view.html',
@@ -27,10 +23,6 @@ angular.module('forms').config(['$stateProvider',
data: {
hideNav: true,
},
- }).
- state('editForm', {
- url: '/forms/:formId/edit',
- templateUrl: 'modules/forms/views/create-form.client.view.html',
});
}
]);
\ No newline at end of file
diff --git a/public/modules/forms/controllers/create-form.client.controller.js b/public/modules/forms/controllers/create-form.client.controller.js
deleted file mode 100644
index d636315c..00000000
--- a/public/modules/forms/controllers/create-form.client.controller.js
+++ /dev/null
@@ -1,122 +0,0 @@
-// 'use strict';
-
-// angular.module('forms').controller('EditFormController', ['$scope', '$state', '$rootScope', 'Upload', '$stateParams', 'FormFields', 'Forms', 'CurrentForm', '$modal', '$location', '$http',
-// function ($scope, $state, $rootScope, Upload, $stateParams, FormFields, Forms, CurrentForm, $modal, $location, $http) {
-// $scope.form = {};
-// $scope.isNewForm = false;
-// $scope.log = '';
-// $scope.pdfLoading = false;
-// var _current_upload = null;
-
-// // Get current form if it exists, or create new one
-// if($stateParams.formId){
-// Forms.get({ formId: $stateParams.formId}, function(form){
-// $scope.form = angular.fromJson(angular.toJson(form));
-// console.log($scope.form);
-// });
-// } else {
-// $scope.form.form_fields = [];
-// $scope.isNewForm = true;
-// }
-
-// //PDF Functions
-// $scope.cancelUpload = function(){
-// _current_upload.abort();
-// $scope.pdfLoading = false;
-// $scope.removePDF();
-// };
-
-// $scope.removePDF = function(){
-// $scope.form.pdf = null;
-// $scope.form.isGenerated = false;
-// $scope.form.autofillPDFs = false;
-
-// console.log('form.pdf: '+$scope.form.pdf+' REMOVED');
-// };
-
-// $scope.uploadPDF = function(files) {
-
-// if (files && files.length) {
-// // for (var i = 0; i < files.length; i++) {
-// var file = files[0];
-// _current_upload = Upload.upload({
-// url: '/upload/pdf',
-// fields: {
-// 'user': $scope.user,
-// 'form': $scope.form
-// },
-// file: file
-// }).progress(function (evt) {
-// var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
-// $scope.log = 'progress: ' + progressPercentage + '% ' +
-// evt.config.file.name + '\n' + $scope.log;
-// $scope.pdfLoading = true;
-// }).success(function (data, status, headers, config) {
-// $scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log;
-// console.log($scope.form.pdf);
-// $scope.form.pdf = angular.fromJson(angular.toJson(data));
-// $scope.pdfLoading = false;
-
-// console.log($scope.log);
-// console.log('$scope.pdf: '+$scope.form.pdf.name);
-// if(!$scope.$$phase){
-// $scope.$apply();
-// }
-// }).error(function(err){
-// $scope.pdfLoading = false;
-// console.log('Error occured during upload.\n');
-// console.log(err);
-// });
-// // }
-// }
-// };
-
-// $rootScope.goToWithId = function(route, id) {
-// $state.go(route, {'formId': id}, {reload: true});
-// };
-
-// // Create new Form
-// $rootScope.createOrUpdate = function() {
-
-// if($scope.isNewForm){
-// // Create new Form object
-// var form = new Forms($scope.form);
-
-// $http.post('/forms', {form: $scope.form})
-// .success(function(data, status, headers){
-// console.log('form created');
-
-// // Clear form fields
-// $scope.form = {};
-// // Redirect after save
-// $scope.goToWithId('viewForm', $scope.form._id);
-// }).error(function(errorResponse){
-// console.log(errorResponse);
-// $scope.error = errorResponse;
-// });
-// } else{
-// $scope.update(function(err){
-// console.log('done updating');
-// });
-// }
-// };
-
-// // Update existing Form
-// $rootScope.update = function(cb) {
-// var form = new Forms($scope.form);
-// console.log('update form');
-// console.log($scope.form);
-
-// $http.put('/forms/'+$scope.form._id, {form: $scope.form})
-// .success(function(data, status, headers){
-// console.log('form updated successfully');
-// $scope.goToWithId('viewForm', $scope.form._id);
-// cb(null);
-// }).error(function(err){
-// console.log('Error occured during form UPDATE.\n');
-// console.log(err);
-// cb(err);
-// });
-// };
-// }
-// ]);
diff --git a/public/modules/forms/controllers/view-form-submission.client.controller.js b/public/modules/forms/controllers/view-form-submission.client.controller.js
index fc45e136..24e74182 100644
--- a/public/modules/forms/controllers/view-form-submission.client.controller.js
+++ b/public/modules/forms/controllers/view-form-submission.client.controller.js
@@ -3,42 +3,34 @@
// submissions controller
angular.module('forms').controller('ViewSubmissionController', ['$scope', '$stateParams', '$state', 'Submissions','$http',
function($scope, $stateParams, $state, Submissions, $http) {
- $scope.submissionId = undefined;
+ $scope.submissionId = undefined;
- // Principal.identity().then(function(user){
- // $scope.authentication.user = user;
- // }).then(function(){
-
+ // Return all form's submissions
+ $scope.findAll = function() {
+ $scope.submissions = Submissions.query({
+ formId: $stateParams.formId
+ });
+ };
- // Return all form's submissions
- $scope.findAll = function() {
- $scope.submissions = Submissions.query({
- formId: $stateParams.formId
- });
- };
+ // Find a specific submission
+ $scope.findOne = function() {
+ $scope.submission = Submissions.get({
+ submissionId: $scope.submissionId,
+ formId: $stateParams.formId
+ });
+ };
- // Find a specific submission
- $scope.findOne = function() {
- $scope.submission = Submissions.get({
- submissionId: $scope.submissionId,
- formId: $stateParams.formId
- });
- };
-
-
- // Remove existing submission
- $scope.remove = function(submission) {
- if (!submission) {
- submission = $scope.submission;
- }
- $http.delete('/forms/'+$stateParams.formId+'/submissions/'+submission._id).
- success(function(data, status, headers){
- console.log('submission deleted successfully');
- alert('submission deleted..');
- });
- };
-
-
- // });
+
+ // Remove existing submission
+ $scope.remove = function(submission) {
+ if (!submission) {
+ submission = $scope.submission;
+ }
+ $http.delete('/forms/'+$stateParams.formId+'/submissions/'+submission._id).
+ success(function(data, status, headers){
+ console.log('submission deleted successfully');
+ alert('submission deleted..');
+ });
+ };
}
]);
\ No newline at end of file
diff --git a/public/modules/forms/controllers/view-form.client.controller.js b/public/modules/forms/controllers/view-form.client.controller.js
index a9344488..b64c7f8a 100644
--- a/public/modules/forms/controllers/view-form.client.controller.js
+++ b/public/modules/forms/controllers/view-form.client.controller.js
@@ -4,9 +4,9 @@
angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope', '$stateParams', '$state', 'Forms', 'CurrentForm','$http',
function($rootScope, $scope, $stateParams, $state, Forms, CurrentForm, $http) {
-
+ $scope = $rootScope;
$scope.myform = CurrentForm.getForm();
- $scope.submissions = undefined;
+ $scope.saveInProgress = false;
$scope.viewSubmissions = false;
$scope.showCreateModal = false;
$scope.table = {
@@ -34,7 +34,7 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
$scope.setForm = function (form) {
- $scope.myForm = form;
+ $scope.myform = form;
};
//Modal functions
@@ -52,6 +52,13 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
/*
* Table Functions
*/
+ $scope.isAtLeastOneChecked = function(){
+ // console.log('isAtLeastOneChecked');
+ for(var i=0; i<$scope.table.rows.length; i++){
+ if($scope.table.rows[i].selected) return true;
+ }
+ return false;
+ };
$scope.toggleAllCheckers = function(){
console.log('toggleAllCheckers');
for(var i=0; i<$scope.table.rows.length; i++){
@@ -60,22 +67,56 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
};
$scope.toggleObjSelection = function($event, description) {
$event.stopPropagation();
- console.log('checkbox clicked');
};
$scope.rowClicked = function(obj) {
- // console.log('row clicked');
obj.selected = !obj.selected;
};
- //show submissions of Form
+ /*
+ * Form Submission Methods
+ */
+ //Delete selected submissions of Form
+ $scope.deleteSelectedSubmissions = function(){
+ // console.log('deleteSelectedSubmissions');
+ var delete_ids = [];
+ // for(var i=0; i<$scope.table.rows.length; i++){
+ // if($scope.table.rows[i].selected){
+ // delete_ids.push($scope.table.rows[i]._id);
+ // }
+ // }
+
+ delete_ids = _.chain($scope.table.rows).filter(function(row){
+ return !!row.selected;
+ }).pluck('_id').value();
+ console.log(delete_ids);
+
+ $http({ url: '/forms/'+$scope.myform._id+'/submissions',
+ method: 'DELETE',
+ data: {deleted_submissions: delete_ids},
+ headers: {"Content-Type": "application/json;charset=utf-8"}
+ }).success(function(data, status, headers){
+ //Remove deleted ids from table
+ for(var i=0; i<$scope.table.rows.length; i++){
+ if($scope.table.rows[i].selected){
+ $scope.table.rows.splice(i, 1);
+ }
+ }
+ })
+ .error(function(err){
+ console.log('Could not delete form submissions.\nError: ');
+ console.log(err);
+ console.error = err;
+ });
+ };
+ //Fetch and display submissions of Form
$scope.showSubmissions = function(){
$scope.viewSubmissions = true;
$http.get('/forms/'+$scope.myform._id+'/submissions')
.success(function(data, status, headers){
- console.log(data[0].form_fields);
+ // console.log(data[0].form_fields);
- var _data = Array();
+ var _data = [];
for(var i=0; i .field-input input {
- width:100%;
- }
- form.submission-form .row.field .field-input > input:focus {
- font-size:1em;
- }
+
+ form.submission-form .select.radio > .field-input input {
+ width:20%;
+ }
+
+
+ form.submission-form .select > .field-input input {
+ width:20%;
+ }
+ form.submission-form .select > .field-input .btn {
+ text-align: left;
+ margin-bottom:0.7em;
+ }
+ form.submission-form .select > .field-input .btn > span {
+ font-size: 1.10em;
+ }
+
+
+ form.submission-form .row.field > .field-input input {
+ width:100%;
+ }
+ form.submission-form .row.field .field-input > input:focus {
+ font-size:1em;
+ }
+
form .row.field.textfield > .field-input > input{
padding:0.45em 0.9em;
width:100%;
@@ -151,8 +170,9 @@ div.config-form > .row {
}
/* Styles for form list view (/forms) */
-section > section.ng-scope {
- padding: 0 60px 20px 60px;
+section > section.public-form {
+ padding: 0 6em 7em 6em;
+
}
.form-item.row {
text-align: center;
diff --git a/public/modules/forms/directives/auto-save.client.directive.js b/public/modules/forms/directives/auto-save.client.directive.js
index 6fbc9711..52b7c8af 100644
--- a/public/modules/forms/directives/auto-save.client.directive.js
+++ b/public/modules/forms/directives/auto-save.client.directive.js
@@ -40,7 +40,7 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
});
$scope.$watch('myform.form_fields', function(newValue, oldValue) {
- // console.log('watchCount: '+$rootScope.watchCount);
+ console.log('watchCount: '+$rootScope.watchCount);
if(difference(oldValue,newValue).length === 0 || oldValue === undefined){
return;
}
@@ -49,9 +49,9 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
// console.log('form_fields changed: '+difference(oldValue,newValue).length );
// console.log('$valid: '+$formCtrl.$valid);
// console.log('finishedRender: '+$scope.finishedRender);
- // console.log('saveInProgress: '+$scope.saveInProgress);
+ console.log('saveInProgress: '+$rootScope.saveInProgress);
- if($scope.finishedRender && ($formCtrl.$dirty || difference(oldValue,newValue).length !== 0) ) {
+ if($scope.finishedRender && ($formCtrl.$dirty || difference(oldValue,newValue).length !== 0) && !$rootScope.saveInProgress) {
$rootScope.watchCount++;
if($rootScope.watchCount === 1) {
@@ -80,6 +80,8 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
});
}
+ }else{
+ return;
}
}, true);
diff --git a/public/modules/forms/directives/change-focus.client.directive.js b/public/modules/forms/directives/change-focus.client.directive.js
index c8116c13..ce86fabc 100644
--- a/public/modules/forms/directives/change-focus.client.directive.js
+++ b/public/modules/forms/directives/change-focus.client.directive.js
@@ -10,16 +10,16 @@ angular.module('forms').directive('changeFocus', function() {
// console.log('aoeuaoeuaoeuaou');
scope.focusUp = function(){
if(!scope.$first) {
- // console.log('aoeuaoeu');
- elem[0].previousElementSibling.find('input').focus();
- }
- scope.apply();
+ console.log('focusUp');
+ elem[0].previousElementSibling.find('input').focus();
+ }
+ scope.apply();
};
scope.focusDown = function(){
if(!scope.$last) {
elem[0].nextElementSibling.focus();
- }
- scope.apply();
+ }
+ scope.apply();
};
//Bind 'focus-down' click event to given dom element
diff --git a/public/modules/forms/directives/configure-form.client.directive.js b/public/modules/forms/directives/configure-form.client.directive.js
index ef3c1c73..ac34201c 100644
--- a/public/modules/forms/directives/configure-form.client.directive.js
+++ b/public/modules/forms/directives/configure-form.client.directive.js
@@ -1,7 +1,7 @@
'use strict';
-angular.module('forms').directive('configureFormDirective', ['$rootScope','$http', '$timeout', 'timeCounter', 'Auth', 'FormFields',
- function ($rootScope, $http, $timeout, timeCounter, Auth, FormFields) {
+angular.module('forms').directive('configureFormDirective', ['$rootScope', '$http', 'Upload', '$timeout', 'timeCounter', 'Auth', 'FormFields',
+ function ($rootScope, $http, Upload, $timeout, timeCounter, Auth, FormFields) {
return {
controller: function($scope){
$scope.log = '';
@@ -39,6 +39,8 @@ angular.module('forms').directive('configureFormDirective', ['$rootScope','$http
if (files && files.length) {
// for (var i = 0; i < files.length; i++) {
var file = files[0];
+ console.log(file);
+
_current_upload = Upload.upload({
url: '/upload/pdf',
fields: {
@@ -53,13 +55,14 @@ angular.module('forms').directive('configureFormDirective', ['$rootScope','$http
$scope.pdfLoading = true;
}).success(function (data, status, headers, config) {
$scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log;
- console.log($scope.myform.pdf);
$scope.myform.pdf = angular.fromJson(angular.toJson(data));
+
+ console.log($scope.myform.pdf);
+
$scope.pdfLoading = false;
console.log($scope.log);
- console.log('$scope.pdf: '+$scope.myform.pdf.name);
- if(!$scope.$$phase){
+ if(!$scope.$$phase && !$scope.$digest){
$scope.$apply();
}
}).error(function(err){
@@ -67,7 +70,6 @@ angular.module('forms').directive('configureFormDirective', ['$rootScope','$http
console.log('Error occured during upload.\n');
console.log(err);
});
- // }
}
};
diff --git a/public/modules/forms/directives/edit-form.client.directive.js b/public/modules/forms/directives/edit-form.client.directive.js
index 689f457a..e89f30b9 100644
--- a/public/modules/forms/directives/edit-form.client.directive.js
+++ b/public/modules/forms/directives/edit-form.client.directive.js
@@ -20,6 +20,8 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
handle: ' .handle'
}
+ console.log($scope.myform);
+
// $scope.draggable = {
// connectWith: ".dropzone",
// start: function (e, ui) {
@@ -87,7 +89,7 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
for(var i = 0; i < $scope.addField.types.length; i++){
// console.log($scope.addField.types[i].name === fieldType);
- if($scope.addField.types[i].name === fieldType){
+ if($scope.addField.types[i].name === fieldType){
$scope.addField.types[i].lastAddedID++;
// console.log($scope.addField.types[i].lastAddedID);
fieldTitle = $scope.addField.types[i].value+$scope.addField.types[i].lastAddedID;
@@ -99,13 +101,13 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
'fieldType' : fieldType,
'fieldValue' : '',
'required' : true,
- 'disabled' : false
+ 'disabled' : false,
};
// put newField into fields array
$scope.myform.form_fields.unshift(newField);
- console.log('\n\n---------\nAdded field CLIENT');
- console.log(Date.now());
+ // console.log('\n\n---------\nAdded field CLIENT');
+ // console.log(Date.now());
// console.log($scope.myform.form_fields.length);
};
diff --git a/public/modules/forms/directives/field.client.directive.js b/public/modules/forms/directives/field.client.directive.js
index caa77296..c94d7947 100644
--- a/public/modules/forms/directives/field.client.directive.js
+++ b/public/modules/forms/directives/field.client.directive.js
@@ -24,7 +24,8 @@ angular.module('forms').directive('fieldDirective', function($http, $compile) {
'dropdown',
'hidden',
'password',
- 'radio'
+ 'radio',
+ 'legal'
];
if (__indexOf.call(supported_fields, type) >= 0) {
return templateUrl += type + '.html';
@@ -32,7 +33,7 @@ angular.module('forms').directive('fieldDirective', function($http, $compile) {
};
var linker = function(scope, element) {
- scope.field.required = scope.required;
+ // scope.field.required = scope.required;
//Set format only if field is a date
if(scope.field.fieldType === 'date'){
diff --git a/public/modules/forms/directives/form.client.directive.js b/public/modules/forms/directives/submit-form.client.directive.js
similarity index 85%
rename from public/modules/forms/directives/form.client.directive.js
rename to public/modules/forms/directives/submit-form.client.directive.js
index aed747bd..3cf2cfac 100644
--- a/public/modules/forms/directives/form.client.directive.js
+++ b/public/modules/forms/directives/submit-form.client.directive.js
@@ -25,16 +25,16 @@ angular.module('forms').directive('formDirective', ['$http', '$timeout', 'timeCo
});
};
- $scope.cancel = function(){
- alert('Form canceled..');
- };
-
$scope.reloadForm = function(){
$scope.form.submitted = false;
+ $scope.form.form_fields = _.chain($scope.form.form_fields).map(function(field){
+ field.fieldValue = '';
+ return field;
+ }).value();
}
},
- templateUrl: './modules/forms/views/directiveViews/form/form.html',
+ templateUrl: './modules/forms/views/directiveViews/form/submit-form.html',
restrict: 'E',
scope: {
form:'='
diff --git a/public/modules/forms/services/forms.client.service.js b/public/modules/forms/services/forms.client.service.js
index 2666a105..5294f3ad 100644
--- a/public/modules/forms/services/forms.client.service.js
+++ b/public/modules/forms/services/forms.client.service.js
@@ -9,6 +9,27 @@ angular.module('forms').factory('Forms', ['$resource',
'query' : {
method: 'GET',
isArray: true,
+ transformResponse: function(data, header) {
+ var forms = angular.fromJson(data);
+ angular.forEach(forms, function(form, idx) {
+ form.visible_form_fields = _.filter(form.form_fields, function(field){
+ return field.deletePreserved === false;
+ }); //<-- replace each item with an instance of the resource object
+ });
+ return forms;
+ }
+ },
+ 'get' : {
+ method: 'GET',
+ transformResponse: function(data, header) {
+ var form = angular.fromJson(data);
+
+ form.visible_form_fields = _.filter(form.form_fields, function(field){
+ return field.deletePreserved === false;
+ }); //<-- replace each item with an instance of the resource object
+ console.log(form);
+ return form;
+ }
},
'update': {
method: 'PUT'
diff --git a/public/modules/forms/views/directiveViews/field/checkbox.html b/public/modules/forms/views/directiveViews/field/checkbox.html
index 012127b2..b5fa2ae0 100755
--- a/public/modules/forms/views/directiveViews/field/checkbox.html
+++ b/public/modules/forms/views/directiveViews/field/checkbox.html
@@ -1,7 +1,7 @@