fixed getAssets bug in config.js

This commit is contained in:
David Baldwynn 2017-04-23 12:55:26 -07:00
commit d303eb7bdf
No known key found for this signature in database
GPG key ID: 15D1C13202224A9B
33 changed files with 290 additions and 618 deletions

View file

@ -1,4 +1,5 @@
language: node_js language: node_js
dist: trusty
sudo: false sudo: false
node_js: node_js:
- "5.0.0" - "5.0.0"
@ -11,11 +12,5 @@ services:
addons: addons:
code_climate: code_climate:
repo_token: 6c3a1b81a09b2338d6f30913c1bcad115026689752cbb499a0a25061cda6fbcf repo_token: 6c3a1b81a09b2338d6f30913c1bcad115026689752cbb499a0a25061cda6fbcf
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.8
- g++-4.8
after_script: after_script:
- grunt coverage - grunt coverage

View file

@ -47,7 +47,7 @@ TellForm 2.0.0
- Add Custom Background and Dropdown Field Images - Add Custom Background and Dropdown Field Images
- Add File Upload Form Field - Add File Upload Form Field
### How to Contribute ## How to Contribute
Please checkout our CONTRIBUTING.md on ways to contribute to TellForm. Please checkout our CONTRIBUTING.md on ways to contribute to TellForm.
@ -198,9 +198,13 @@ Does your company use TellForm? Help keep the project bug-free and feature rich
Love our work and community? [Become a backer](https://opencollective.com/tellform). Love our work and community? [Become a backer](https://opencollective.com/tellform).
<a href="https://opencollective.com/tellform#contributors" target="_blank"><img src="https://opencollective.com/elliot"></a> <a href="https://opencollective.com/elliot" target="_blank">
<img src="https://opencollective.com/proxy/images/?src=https%3A%2F%2Fd1ts43dypk8bqh.cloudfront.net%2Fv1%2Favatars%2F6fd61b2c-62b6-438a-9168-bab7ef1489b8" height= "64">
</a>
<a href="https://opencollective.com/tellform#contributors" target="_blank"><img src="https://opencollective.com/aldrnv"></a> <a href="https://opencollective.com/aldrnv" target="_blank">
<img src="https://opencollective.com/public/images/users/avatar-01.svg" height="64">
</a>
## Contributors ## Contributors

View file

@ -50,7 +50,7 @@ exports.createSubmission = function(req, res) {
var timeElapsed = 0; var timeElapsed = 0;
if(typeof req.body.timeElapsed == "number"){ if(typeof req.body.timeElapsed === "number"){
timeElapsed = req.body.timeElapsed; timeElapsed = req.body.timeElapsed;
} }
var submission = new FormSubmission({ var submission = new FormSubmission({
@ -209,7 +209,7 @@ exports.update = function(req, res) {
delete req.body.form.admin; delete req.body.form.admin;
} }
if(form.analytics == null){ if(form.analytics === null){
form.analytics.visitors = []; form.analytics.visitors = [];
form.analytics.gaCode = ''; form.analytics.gaCode = '';
} }

View file

@ -3,14 +3,10 @@
/** /**
* Module dependencies. * Module dependencies.
*/ */
var _ = require('lodash'), var errorHandler = require('../errors.server.controller'),
errorHandler = require('../errors.server.controller'),
mongoose = require('mongoose'), mongoose = require('mongoose'),
passport = require('passport'), passport = require('passport'),
async = require('async'),
config = require('../../../config/config'), config = require('../../../config/config'),
nodemailer = require('nodemailer'),
crypto = require('crypto'),
User = mongoose.model('User'), User = mongoose.model('User'),
tokgen = require("../../libs/tokenGenerator"); tokgen = require("../../libs/tokenGenerator");
@ -20,9 +16,6 @@ var nev = require('email-verification')(mongoose);
// NEV setup and configuration ================ // NEV setup and configuration ================
var config_nev = function () { var config_nev = function () {
var User = require('../../models/user.server.model');
nev.configure({ nev.configure({
persistentUserModel: User, persistentUserModel: User,
tempUserCollection: config.tempUserCollection, tempUserCollection: config.tempUserCollection,
@ -47,37 +40,35 @@ var config_nev = function () {
verifySendMailCallback: function(err, info) { verifySendMailCallback: function(err, info) {
if (err) { if (err) {
throw err; throw err;
} else {
console.log(info);
} }
} }
}, function(err, options){ }, function(err, options){
if(err) throw err; if(err) {
throw err;
}
}); });
nev.generateTempUserModel(User, function(err){ nev.generateTempUserModel(User, function(err){
if(err) throw err; if(err) {
throw err;
}
}); });
}; };
config_nev(); config_nev();
var smtpTransport = nodemailer.createTransport(config.mailer.options);
exports.validateVerificationToken = function(req, res){ exports.validateVerificationToken = function(req, res){
nev.confirmTempUser(req.params.token, function(err, user) { nev.confirmTempUser(req.params.token, function(err, user) {
if(err) { if(err) {
console.log(errorHandler.getErrorMessage(err));
return res.status(500).send( {message: errorHandler.getErrorMessage(err) } ); return res.status(500).send( {message: errorHandler.getErrorMessage(err) } );
} }
else if (user){ else if (user){
return res.status(200).send('User successfully verified'); return res.status(200).send('User successfully verified');
}else {
// redirect to resend verification email
return res.status(400).send( {message: 'Verification token is invalid or has expired'} );
} }
// redirect to resend verification email
return res.status(400).send( {message: 'Verification token is invalid or has expired'} );
}); });
}; };
@ -114,8 +105,6 @@ exports.signup = function(req, res) {
// Then save the temporary user // Then save the temporary user
nev.createTempUser(user, function (err, existingPersistentUser, newTempUser) { nev.createTempUser(user, function (err, existingPersistentUser, newTempUser) {
if (err) { if (err) {
console.log('Error: ');
console.log(err);
return res.status(400).send({ return res.status(400).send({
message: errorHandler.getErrorMessage(err) message: errorHandler.getErrorMessage(err)
}); });
@ -124,20 +113,17 @@ exports.signup = function(req, res) {
// new user created // new user created
if (newTempUser) { if (newTempUser) {
var URL = newTempUser[nev.options.URLFieldName]; var URL = newTempUser[nev.options.URLFieldName];
nev.sendVerificationEmail(user.email, URL, function (err, info) { nev.sendVerificationEmail(user.email, URL, function (sendEmailErr, info) {
if (err) { if (sendEmailErr) {
return res.status(400).send({ return res.status(400).send({
message: errorHandler.getErrorMessage(err) message: errorHandler.getErrorMessage(err)
}); });
} else {
return res.status(200).send('An email has been sent to you. Please check it to verify your account.');
} }
return res.status(200).send('An email has been sent to you. Please check it to verify your account.');
}); });
} else { }
console.log('Error: User already exists!'); return res.status(400).send({message: 'Error: User already exists!'});
return res.status(400).send({message: 'Error: User already exists!'});
}
}); });
}; };
@ -150,18 +136,17 @@ exports.signin = function(req, res, next) {
res.status(400).send(info); res.status(400).send(info);
} else { } else {
// Remove sensitive data before login // Remove sensitive data before login
user.password = undefined; user.password = null;
user.salt = undefined; user.salt = null;
user.provider = undefined; user.provider = null;
req.login(user, function(err) { req.login(user, function(loginErr) {
if (err) { if (loginErr) {
return res.status(400).send({ return res.status(400).send({
message: errorHandler.getErrorMessage(err) message: errorHandler.getErrorMessage(loginErr)
}); });
} else {
return res.json(user);
} }
return res.json(user);
}); });
} }
})(req, res, next); })(req, res, next);
@ -227,7 +212,7 @@ exports.saveOAuthUserProfile = function(req, providerUserProfile, done) {
var possibleUsername = providerUserProfile.username || ((providerUserProfile.email) ? providerUserProfile.email.split('@')[0] : ''); var possibleUsername = providerUserProfile.username || ((providerUserProfile.email) ? providerUserProfile.email.split('@')[0] : '');
User.findUniqueUsername(possibleUsername, null, function(availableUsername) { User.findUniqueUsername(possibleUsername, null, function(availableUsername) {
user = new User({ var newUser = new User({
firstName: providerUserProfile.firstName, firstName: providerUserProfile.firstName,
lastName: providerUserProfile.lastName, lastName: providerUserProfile.lastName,
username: availableUsername, username: availableUsername,
@ -238,13 +223,12 @@ exports.saveOAuthUserProfile = function(req, providerUserProfile, done) {
}); });
// And save the user // And save the user
user.save(function(err) { newUser.save(function(userSaveErr) {
return done(err, user); return done(userSaveErr, user);
}); });
}); });
} else {
return done(err, user);
} }
return done(err, user);
} }
}); });
} else { } else {
@ -254,7 +238,9 @@ exports.saveOAuthUserProfile = function(req, providerUserProfile, done) {
// Check if user exists, is not signed in using this provider, and doesn't have that provider data already configured // Check if user exists, is not signed in using this provider, and doesn't have that provider data already configured
if (user.provider !== providerUserProfile.provider && (!user.additionalProvidersData || !user.additionalProvidersData[providerUserProfile.provider])) { if (user.provider !== providerUserProfile.provider && (!user.additionalProvidersData || !user.additionalProvidersData[providerUserProfile.provider])) {
// Add the provider data to the additional provider data field // Add the provider data to the additional provider data field
if (!user.additionalProvidersData) user.additionalProvidersData = {}; if (!user.additionalProvidersData) {
user.additionalProvidersData = {};
}
user.additionalProvidersData[providerUserProfile.provider] = providerUserProfile.providerData; user.additionalProvidersData[providerUserProfile.provider] = providerUserProfile.providerData;
// Then tell mongoose that we've updated the additionalProvidersData field // Then tell mongoose that we've updated the additionalProvidersData field
@ -314,8 +300,10 @@ exports.generateAPIKey = function(req, res) {
User.findById(req.user.id) User.findById(req.user.id)
.exec( function(err, user) { .exec( function(err, user) {
if (err) return res.status(400).send(err); if (err) {
return res.status(400).send(err);
}
if (!user) { if (!user) {
return res.status(400).send({ return res.status(400).send({
message: 'User does not Exist' message: 'User does not Exist'
@ -324,10 +312,10 @@ exports.generateAPIKey = function(req, res) {
user.apiKey = tokgen(); user.apiKey = tokgen();
user.save(function(err, _user) { user.save(function(userSaveErr, _user) {
if (err) { if (userSaveErr) {
return res.status(400).send({ return res.status(400).send({
message: errorHandler.getErrorMessage(err) message: errorHandler.getErrorMessage(userSaveErr)
}); });
} }
@ -337,7 +325,6 @@ exports.generateAPIKey = function(req, res) {
delete newUser.passwordHash; delete newUser.passwordHash;
delete newUser.provider; delete newUser.provider;
console.log(newUser);
return res.json(newUser); return res.json(newUser);
}); });

View file

@ -180,7 +180,6 @@ exports.reset = function(req, res, next) {
}); });
} }
], function(err) { ], function(err) {
debugger;
if (err) { if (err) {
res.status(500).send({ res.status(500).send({
message: err.message || err message: err.message || err

View file

@ -5,9 +5,7 @@
*/ */
var _ = require('lodash'), var _ = require('lodash'),
errorHandler = require('../errors.server.controller.js'), errorHandler = require('../errors.server.controller.js'),
mongoose = require('mongoose'), mongoose = require('mongoose');
passport = require('passport'),
User = mongoose.model('User');
/** /**
* Update user details * Update user details
@ -15,7 +13,6 @@ var _ = require('lodash'),
exports.update = function(req, res) { exports.update = function(req, res) {
// Init Variables // Init Variables
var user = req.user; var user = req.user;
var message = null;
// For security measurement we remove the roles from the req.body object // For security measurement we remove the roles from the req.body object
delete req.body.roles; delete req.body.roles;
@ -30,15 +27,15 @@ exports.update = function(req, res) {
return res.status(500).send({ return res.status(500).send({
message: errorHandler.getErrorMessage(err) message: errorHandler.getErrorMessage(err)
}); });
} else { }
req.login(user, function(err) { req.login(user, function(loginErr) {
if (err) { if (err) {
res.status(500).send(err); res.status(500).send(loginErr);
} else { } else {
res.json(user); res.json(user);
} }
}); });
}
}); });
} else { } else {
res.status(401).send({ res.status(401).send({

View file

@ -6,21 +6,15 @@
var mongoose = require('mongoose'), var mongoose = require('mongoose'),
Schema = mongoose.Schema, Schema = mongoose.Schema,
_ = require('lodash'), _ = require('lodash'),
config = require('../../config/config'),
path = require('path'),
mUtilities = require('mongoose-utilities'), mUtilities = require('mongoose-utilities'),
fs = require('fs-extra'),
async = require('async'), async = require('async'),
mkdirp = require('mkdirp'),
Random = require('random-js'), Random = require('random-js'),
mt = Random.engines.mt19937(), mt = Random.engines.mt19937();
util = require('util');
mt.autoSeed(); mt.autoSeed();
//Mongoose Models //Mongoose Models
var FieldSchema = require('./form_field.server.model.js'); var FieldSchema = require('./form_field.server.model.js');
var Field = mongoose.model('Field');
var FormSubmissionSchema = require('./form_submission.server.model.js'), var FormSubmissionSchema = require('./form_submission.server.model.js'),
FormSubmission = mongoose.model('FormSubmission', FormSubmissionSchema); FormSubmission = mongoose.model('FormSubmission', FormSubmissionSchema);
@ -221,7 +215,10 @@ FormSchema.virtual('analytics.fields').get(function () {
var visitors = this.analytics.visitors; var visitors = this.analytics.visitors;
var that = this; var that = this;
if(this.form_fields.length == 0) return null; if(this.form_fields.length == 0) {
return null;
}
for(var i=0; i<this.form_fields.length; i++){ for(var i=0; i<this.form_fields.length; i++){
var field = this.form_fields[i]; var field = this.form_fields[i];
@ -259,7 +256,6 @@ FormSchema.virtual('analytics.fields').get(function () {
} }
var totalViews = dropoffViews+continueViews; var totalViews = dropoffViews+continueViews;
var responses = continueViews;
var continueRate = (continueViews/totalViews*100).toFixed(0); var continueRate = (continueViews/totalViews*100).toFixed(0);
var dropoffRate = (dropoffViews/totalViews*100).toFixed(0); var dropoffRate = (dropoffViews/totalViews*100).toFixed(0);
@ -301,7 +297,6 @@ function getDeletedIndexes(needle, haystack){
FormSchema.pre('save', function (next) { FormSchema.pre('save', function (next) {
var that = this;
switch(this.language){ switch(this.language){
case 'spanish': case 'spanish':
this.language = 'es'; this.language = 'es';
@ -329,7 +324,6 @@ FormSchema.pre('save', function (next) {
that.constructor that.constructor
.findOne({_id: that._id}).exec(function (err, original) { .findOne({_id: that._id}).exec(function (err, original) {
if (err) { if (err) {
console.log(err);
return cb(err); return cb(err);
} else { } else {
_original = original; _original = original;
@ -367,77 +361,68 @@ FormSchema.pre('save', function (next) {
find({ form: that._id, admin: that.admin, form_fields: {$elemMatch: {submissionId: deleted_id} } }). find({ form: that._id, admin: that.admin, form_fields: {$elemMatch: {submissionId: deleted_id} } }).
exec(function(err, submissions){ exec(function(err, submissions){
if(err) { if(err) {
console.error(err);
return cb_id(err); return cb_id(err);
} else { }
//Delete field if there are no submission(s) found
if (submissions.length) { //Delete field if there are no submission(s) found
//Add submissions if (submissions.length) {
modifiedSubmissions.push.apply(modifiedSubmissions, submissions); //Add submissions
} modifiedSubmissions.push.apply(modifiedSubmissions, submissions);
return cb_id(null);
} }
return cb_id(null);
}); });
}, },
function (err) { function (err) {
if(err){ if(err){
console.error(err.message); console.error(err.message);
return cb(err); return cb(err);
} else {
//Iterate through all submissions with modified form_fields
async.forEachOfSeries(modifiedSubmissions, function (submission, key, callback) {
//Iterate through ids of deleted fields
for (var i = 0; i < deletedIds.length; i++) {
var index = _.findIndex(submission.form_fields, function (field) {
var tmp_id = field._id + '';
return tmp_id === old_ids[deletedIds[i]];
});
var deletedField = submission.form_fields[index];
//Hide field if it exists
if (deletedField) {
// console.log('deletedField\n-------\n\n');
// console.log(deletedField);
//Delete old form_field
submission.form_fields.splice(index, 1);
deletedField.deletePreserved = true;
//Move deleted form_field to start
submission.form_fields.unshift(deletedField);
that.form_fields.unshift(deletedField);
// console.log('form.form_fields\n--------\n\n');
// console.log(that.form_fields);
}
}
submission.save(function (err) {
if (err) return callback(err);
else return callback(null);
});
}, function (err) {
if (err) {
console.error(err.message);
return cb(err);
}
else return cb();
});
} }
//Iterate through all submissions with modified form_fields
async.forEachOfSeries(modifiedSubmissions, function (submission, key, callback) {
//Iterate through ids of deleted fields
for (i = 0; i < deletedIds.length; i++) {
var index = _.findIndex(submission.form_fields, function (field) {
var tmp_id = field._id + '';
return tmp_id === old_ids[deletedIds[i]];
});
var deletedField = submission.form_fields[index];
//Hide field if it exists
if (deletedField) {
//Delete old form_field
submission.form_fields.splice(index, 1);
deletedField.deletePreserved = true;
//Move deleted form_field to start
submission.form_fields.unshift(deletedField);
that.form_fields.unshift(deletedField);
}
}
submission.save(function (saveErr) {
return callback(saveErr);
});
}, function (err) {
return cb(err);
});
} }
); );
} }
else return cb(null); return cb(null);
} }
else return cb(null); return cb(null);
}], }],
function(err, results){ function(err, results){
if (err) return next(err); next(err);
return next();
}); });
}); });

View file

@ -5,24 +5,9 @@
*/ */
var mongoose = require('mongoose'), var mongoose = require('mongoose'),
Schema = mongoose.Schema, Schema = mongoose.Schema,
_ = require('lodash'),
config = require('../../config/config'),
path = require('path'),
fs = require('fs-extra'),
mUtilities = require('mongoose-utilities'), mUtilities = require('mongoose-utilities'),
async = require('async'),
FieldSchema = require('./form_field.server.model.js'); FieldSchema = require('./form_field.server.model.js');
// Setter function for form_fields
function formFieldsSetter(form_fields) {
for (var i = 0; i < form_fields.length; i++) {
form_fields[i].isSubmission = true;
form_fields[i].submissionId = form_fields[i]._id;
form_fields[i]._id = new mongoose.mongo.ObjectID();
}
return form_fields;
}
/** /**
* Form Submission Schema * Form Submission Schema
*/ */

View file

@ -52,20 +52,12 @@ var UserSchema = new Schema({
firstName: { firstName: {
type: String, type: String,
trim: true, trim: true,
default: '', default: ''
/*validate: {
validator: validateLocalStrategyProperty,
message: 'Please fill in your first name'
}*/
}, },
lastName: { lastName: {
type: String, type: String,
trim: true, trim: true,
default: '', default: ''
/*validate: {
validator: validateLocalStrategyProperty,
message: 'Please fill in your last name'
}*/
}, },
email: { email: {
type: String, type: String,
@ -149,28 +141,6 @@ UserSchema.plugin(mUtilities.timestamp, {
useVirtual: false useVirtual: false
}); });
UserSchema.pre('save', function (next) {
//Create folder for user's pdfs
if(process.env.NODE_ENV === 'local-development'){
var newDestination = path.join(config.pdfUploadPath, this.username.replace(/ /g,'')),
stat = null;
try {
stat = fs.statSync(newDestination);
} catch (err) {
fs.mkdirSync(newDestination);
}
if (stat && !stat.isDirectory()) {
// console.log('Directory cannot be created');
next( new Error('Directory cannot be created because an inode of a different type exists at "' + newDestination + '"') );
}else{
next();
}
}
next();
});
/** /**
* Hook a pre save method to hash the password * Hook a pre save method to hash the password
*/ */
@ -217,13 +187,12 @@ UserSchema.statics.findUniqueUsername = function(username, suffix, callback) {
}, function(err, user) { }, function(err, user) {
if (!err) { if (!err) {
if (!user) { if (!user) {
callback(possibleUsername); return callback(possibleUsername);
} else { } else {
return _this.findUniqueUsername(username, (suffix || 0) + 1, callback); return _this.findUniqueUsername(username, (suffix || 0) + 1, callback);
} }
} else {
callback(null);
} }
return callback(null);
}); });
}; };

View file

@ -4,7 +4,6 @@
* Module dependencies. * Module dependencies.
*/ */
var mongoose = require('mongoose'), var mongoose = require('mongoose'),
config = require('../../config/config'),
errorHandler = require('../controllers/errors.server.controller'), errorHandler = require('../controllers/errors.server.controller'),
Form = mongoose.model('Form'); Form = mongoose.model('Form');
@ -32,50 +31,45 @@ module.exports = function (io, socket) {
form.analytics.visitors.push(newVisitor); form.analytics.visitors.push(newVisitor);
form.save(function (err) { form.save(function (formSaveErr) {
if (err) { if (err) {
console.log(err); console.error(err);
throw new Error(errorHandler.getErrorMessage(err)); throw new Error(errorHandler.getErrorMessage(formSaveErr));
} }
console.log('\n\nVisitor data successfully added!');
console.log(newVisitor);
delete visitorsData[socket.id]; delete visitorsData[socket.id];
if(cb) cb(); if(cb){
return cb();
}
}); });
}); });
socket.disconnect(0); socket.disconnect(0);
}; };
io.on('connection', function(socket) { io.on('connection', function(current_socket) {
console.log('\n\n\n\n\n CONNECTED SOCKET');
// a user has visited our page - add them to the visitorsData object // a user has visited our page - add them to the visitorsData object
socket.on('form-visitor-data', function(data) { current_socket.on('form-visitor-data', function(data) {
socket.id = data.formId; current_socket.id = data.formId;
visitorsData[socket.id] = data; visitorsData[current_socket.id] = data;
visitorsData[socket.id].isSaved = false; visitorsData[current_socket.id].isSaved = false;
if (data.isSubmitted) { if (data.isSubmitted) {
saveVisitorData(data, function () { saveVisitorData(data, function () {
console.log('\n\n user submitted form'); visitorsData[current_socket.id].isSaved = true;
current_socket.disconnect(0);
}); });
visitorsData[socket.id].isSaved = true;
socket.disconnect(0);
} }
}); });
socket.on('disconnect', function() { current_socket.on('disconnect', function() {
console.log('\n\n\n\n\n DISCONNECTED SOCKET'); var data = visitorsData[current_socket.id];
var data = visitorsData[socket.id];
if(data){ if(data && !data.isSubmitted && !data.isSaved) {
if(!data.isSubmitted && !data.isSaved) { data.isSaved = true;
data.isSaved = true; saveVisitorData(data);
saveVisitorData(data);
}
} }
}); });
}); });

View file

@ -6,16 +6,12 @@
var should = require('should'), var should = require('should'),
mongoose = require('mongoose'), mongoose = require('mongoose'),
User = mongoose.model('User'), User = mongoose.model('User'),
Form = mongoose.model('Form'), Form = mongoose.model('Form');
Field = mongoose.model('Field'),
_ = require('lodash'),
config = require('../../config/config'),
FormSubmission = mongoose.model('FormSubmission');
/** /**
* Globals * Globals
*/ */
var user, myForm, mySubmission; var user, myForm;
/** /**
* Unit tests * Unit tests
@ -34,8 +30,7 @@ describe('Form Model Unit Tests:', function() {
user.save(function(err) { user.save(function(err) {
if(err) { if(err) {
done(err); return done(err);
return;
} }
myForm = new Form({ myForm = new Form({
title: 'Form Title', title: 'Form Title',
@ -75,12 +70,11 @@ describe('Form Model Unit Tests:', function() {
describe('Method Find', function(){ describe('Method Find', function(){
beforeEach(function(done){ beforeEach(function(done){
myForm.save(function(err) { myForm.save(function(err) {
if(err) return done(err); return done(err);
done();
}); });
}); });
it('should be able to findOne my form without problems', function(done) { it('should be able to findOne my form without problems', function(done) {
Form.findOne({title: myForm.title}).exec(function(err,form) { Form.findOne({title: myForm.title}).exec(function(err, form) {
should.not.exist(err); should.not.exist(err);
should.exist(form); should.exist(form);

View file

@ -17,7 +17,7 @@ var should = require('should'),
*/ */
var user, myForm, userSession; var user, myForm, userSession;
// Create user credentials // Create user credentials
var credentials = { var credentials = {
username: 'test1234', username: 'test1234',
email: 'test1234@test.com', email: 'test1234@test.com',
@ -57,14 +57,14 @@ describe('Form Routes Unit tests', function() {
isLive: true isLive: true
}; };
//Initialize Session //Initialize Session
userSession = Session(app); userSession = Session(app);
done(); done();
}); });
}); });
it(' > should not be able to create a Form if not logged in', function(done) { it(' > should not be able to create a Form if not logged in', function(done) {
userSession.post('/forms') userSession.post('/forms')
.send({form: myForm}) .send({form: myForm})
.expect(401) .expect(401)
@ -285,10 +285,10 @@ describe('Form Routes Unit tests', function() {
afterEach(function(done) { afterEach(function(done) {
Form.remove({}).exec(function() { Form.remove({}).exec(function() {
User.remove({}).exec(function() { User.remove({}).exec(function() {
userSession.destroy(); userSession.destroy();
done(); done();
}); });
}); });
}); });
}); });

View file

@ -1,9 +1,7 @@
'use strict'; 'use strict';
var should = require('should'), var should = require('should'),
_ = require('lodash'),
app = require('../../server'), app = require('../../server'),
request = require('supertest'),
Session = require('supertest-session'), Session = require('supertest-session'),
mongoose = require('mongoose'), mongoose = require('mongoose'),
User = mongoose.model('User'), User = mongoose.model('User'),
@ -13,11 +11,7 @@ var should = require('should'),
/** /**
* Globals * Globals
*/ */
var credentials, _User; var credentials, _User, activateToken, userSession;
var _tmpUser, activateToken;
var username, userSession;
username = 'testActiveAccount1.be1e58fb@mailosaur.in';
/** /**
* Form routes tests * Form routes tests
@ -50,7 +44,7 @@ describe('User CRUD tests', function() {
userSession.post('/auth/signup') userSession.post('/auth/signup')
.send(_User) .send(_User)
.expect(200) .expect(200)
.end(function(FormSaveErr, FormSaveRes) { .end(function(FormSaveErr) {
console.log('CREATING USER'); console.log('CREATING USER');
// Handle error // Handle error
should.not.exist(FormSaveErr); should.not.exist(FormSaveErr);
@ -58,7 +52,6 @@ describe('User CRUD tests', function() {
tmpUser.findOne({username: _User.username}, function (err, user) { tmpUser.findOne({username: _User.username}, function (err, user) {
should.not.exist(err); should.not.exist(err);
should.exist(user); should.exist(user);
_tmpUser = user;
_User.username.should.equal(user.username); _User.username.should.equal(user.username);
_User.firstName.should.equal(user.firstName); _User.firstName.should.equal(user.firstName);
@ -69,7 +62,10 @@ describe('User CRUD tests', function() {
.expect(200) .expect(200)
.end(function(VerifyErr, VerifyRes) { .end(function(VerifyErr, VerifyRes) {
// Handle error // Handle error
if (VerifyErr) return done(VerifyErr); if (VerifyErr) {
return done(VerifyErr);
}
(VerifyRes.text).should.equal('User successfully verified'); (VerifyRes.text).should.equal('User successfully verified');
userSession.post('/auth/signin') userSession.post('/auth/signin')
@ -78,7 +74,9 @@ describe('User CRUD tests', function() {
.expect(200) .expect(200)
.end(function(signinErr, signinRes) { .end(function(signinErr, signinRes) {
// Handle signin error // Handle signin error
if (signinErr) return done(signinErr); if (signinErr) {
return done(signinErr);
}
var user = signinRes.body; var user = signinRes.body;
(user.username).should.equal(credentials.username); (user.username).should.equal(credentials.username);
@ -88,7 +86,9 @@ describe('User CRUD tests', function() {
.end(function(signoutErr, signoutRes) { .end(function(signoutErr, signoutRes) {
// Handle signout error // Handle signout error
if (signoutErr) return done(signoutErr); if (signoutErr) {
return done(signoutErr);
}
(signoutRes.text).should.equal('You have successfully logged out.'); (signoutRes.text).should.equal('You have successfully logged out.');
@ -101,12 +101,12 @@ describe('User CRUD tests', function() {
}); });
}); });
afterEach(function(done) { afterEach(function(done) {
User.remove().exec(function () { User.remove().exec(function () {
tmpUser.remove().exec(function(){ tmpUser.remove().exec(function(){
userSession.destroy(); userSession.destroy();
done(); done();
}); });
}); });
}); });

View file

@ -73,17 +73,41 @@ module.exports.getBowerOtherAssets = function() {
}; };
/** /**
* Get the modules JavaScript files * Helper Function for getJavascriptAssets and getFormJavaScriptAssets
*/ */
module.exports.getJavaScriptAssets = function(includeTests) { module.exports._getAssets = function(includeTests, isFormJS){
var output = this.getGlobbedFiles(this.assets.js, 'public/', 'static/'); var unit_tests, js_assets;
if(isFormJS) {
js_assets = this.assets.form_js;
unit_tests = this.assets.form_unit_tests;
} else {
js_assets = this.assets.js;
unit_tests = this.assets.unit_tests;
}
var output = this.getGlobbedFiles(js_assets, 'public/', 'static/');
// To include tests // To include tests
if (includeTests) { if (includeTests) {
output = _.union(output, this.getGlobbedFiles(this.assets.unit_tests)); output = _.union(output, this.getGlobbedFiles(unit_tests));
} }
return output; return output;
}
/**
* Get the modules JavaScript files
*/
module.exports.getJavaScriptAssets = function(includeTests) {
return this._getAssets(includeTests, false);
};
/**
* Get the modules Form JavaScript files
*/
module.exports.getFormJavaScriptAssets = function(includeTests) {
return this._getAssets(includeTests, true);
}; };
/** /**
@ -93,17 +117,3 @@ module.exports.getCSSAssets = function() {
var output = this.getGlobbedFiles(this.assets.css, 'public/', 'static/'); var output = this.getGlobbedFiles(this.assets.css, 'public/', 'static/');
return output; return output;
}; };
/**
* Get the modules Form JavaScript files
*/
module.exports.getFormJavaScriptAssets = function(includeTests) {
var output = this.getGlobbedFiles(this.assets.form_js, 'public/', 'static/');
// To include tests
if (includeTests) {
output = _.union(output, this.getGlobbedFiles(this.assets.form_unit_tests));
}
return output;
};

View file

@ -4,7 +4,6 @@
* Module dependencies. * Module dependencies.
*/ */
var fs = require('fs-extra'), var fs = require('fs-extra'),
http = require('http'),
https = require('https'), https = require('https'),
express = require('express'), express = require('express'),
morgan = require('morgan'), morgan = require('morgan'),
@ -15,7 +14,6 @@ var fs = require('fs-extra'),
methodOverride = require('method-override'), methodOverride = require('method-override'),
cookieParser = require('cookie-parser'), cookieParser = require('cookie-parser'),
helmet = require('helmet'), helmet = require('helmet'),
multer = require('multer'),
passport = require('passport'), passport = require('passport'),
raven = require('raven'), raven = require('raven'),
MongoStore = require('connect-mongo')(session), MongoStore = require('connect-mongo')(session),
@ -24,8 +22,7 @@ var fs = require('fs-extra'),
consolidate = require('consolidate'), consolidate = require('consolidate'),
path = require('path'), path = require('path'),
device = require('express-device'), device = require('express-device'),
client = new raven.Client(config.DSN), client = new raven.Client(config.DSN);
connect = require('connect');
var mongoose = require('mongoose'); var mongoose = require('mongoose');
@ -79,24 +76,25 @@ module.exports = function(db) {
app.locals.cssFiles = config.getCSSAssets(); app.locals.cssFiles = config.getCSSAssets();
app.use(function (req, res, next) { app.use(function (req, res, next) {
var urlPath;
if(!config.subdomainsDisabled) { if(!config.subdomainsDisabled) {
var User = mongoose.model('User'); var User = mongoose.model('User');
var path = '/' + 'subdomain' + '/'; var subdomainPath = '/subdomain/';
var subdomains = req.subdomains; var subdomains = req.subdomains;
var host = req.hostname;
if (subdomains.slice(0, 4).join('.') + '' === '1.0.0.127') { if (subdomains.slice(0, 4).join('.') + '' === '1.0.0.127') {
subdomains = subdomains.slice(4); subdomains = subdomains.slice(4);
} }
// continue if no subdomains // continue if no subdomains
if (!subdomains.length) return next(); if (!subdomains.length) {
return next();
var urlPath = url.parse(req.url).path.split('/'); }
urlPath = url.parse(req.url).path.split('/');
if (urlPath.indexOf('static') > -1) { if (urlPath.indexOf('static') > -1) {
urlPath.splice(1, 1); urlPath.splice(1, 1);
if(process.env.NODE_ENV == 'development'){ if(process.env.NODE_ENV === 'development'){
req.root = req.protocol + '://' + config.baseUrl + ':' + config.port + urlPath.join('/'); req.root = req.protocol + '://' + config.baseUrl + ':' + config.port + urlPath.join('/');
} else { } else {
req.root = req.protocol + '://' + config.baseUrl + urlPath.join('/'); req.root = req.protocol + '://' + config.baseUrl + urlPath.join('/');
@ -114,17 +112,16 @@ module.exports = function(db) {
if (subdomains.indexOf('api') > -1) { if (subdomains.indexOf('api') > -1) {
// rebuild url // rebuild url
path += 'api' + req.url; subdomainPath += 'api' + req.url;
// TODO: check path and query strings are preserved // TODO: check path and query strings are preserved
// reassign url // reassign url
req.url = path; req.url = subdomainPath;
return next(); return next();
} }
User.findOne({username: req.subdomains.reverse()[0]}).exec(function (err, user) { User.findOne({username: req.subdomains.reverse()[0]}).exec(function (err, user) {
if (err) { if (err) {
console.log(err);
req.subdomains = null; req.subdomains = null;
// Error page // Error page
return res.status(404).render('404', { return res.status(404).render('404', {
@ -139,26 +136,23 @@ module.exports = function(db) {
} }
// rebuild url // rebuild url
path += subdomains.join('/') + req.url; subdomainPath += subdomains.join('/') + req.url;
// TODO: check path and query strings are preserved // TODO: check path and query strings are preserved
// reassign url // reassign url
req.url = path; req.url = subdomainPath;
req.userId = user._id; req.userId = user._id;
// Q.E.D. // Q.E.D.
next(); return next();
}); });
} else { } else {
var urlPath = url.parse(req.url).path.split('/'); urlPath = url.parse(req.url).path.split('/');
if (urlPath.indexOf('static') > -1 && urlPath.indexOf('view') === urlPath.indexOf('static')-1) { if (urlPath.indexOf('static') > -1 && urlPath.indexOf('view') === urlPath.indexOf('static')-1) {
urlPath.splice(1, 1); urlPath.splice(1, 1);
req.url = urlPath.join('/'); req.url = urlPath.join('/');
console.log('\n\n\nreq.url: ' + req.url);
return next();
} }
return next(); return next();
@ -293,10 +287,11 @@ module.exports = function(db) {
// Assume 'not found' in the error msgs is a 404. this is somewhat silly, but valid, you can do whatever you like, set properties, use instanceof etc. // Assume 'not found' in the error msgs is a 404. this is somewhat silly, but valid, you can do whatever you like, set properties, use instanceof etc.
app.use(function(err, req, res, next) { app.use(function(err, req, res, next) {
// If the error object doesn't exists // If the error object doesn't exists
if (!err) return next(); if (!err) {
return next();
}
// Log it // Log it
console.error(err.stack);
client.captureError(err); client.captureError(err);
// Error page // Error page

View file

@ -12,7 +12,6 @@ module.exports = function (app, db) {
var io = socketio({ transports: ['websocket', 'polling'] }); var io = socketio({ transports: ['websocket', 'polling'] });
if(config.socketPort){ if(config.socketPort){
console.log("creating websocket server on port: "+config.socketPort);
io = socketio(config.socketPort, { transports: ['websocket', 'polling'] }); io = socketio(config.socketPort, { transports: ['websocket', 'polling'] });
} }

View file

@ -1,73 +1,5 @@
'use strict'; 'use strict';
var spawn = require('child_process').spawn;
var bowerFiles = require('main-bower-files');
var path = require('path');
var minBowerFiles = function(type){
return bowerFiles(type).map( function(path, index, arr) {
var newPath = path.replace(/.([^.]+)$/g, '.min.$1');
return exists( newPath ) ? newPath : path;
});
};
var removeRootDir = function(files, removeRoot, addRoot) {
return files.map(function(file) {
if (addRoot) return file.replace(path.join(process.cwd(), removeRoot), addRoot);
return file.replace(path.join(process.cwd(), removeRoot), '');
});
};
var allBowerFiles = bowerFiles({
filter: function(filePath){
return (filePath.indexOf('js') > 0 && filePath.indexOf('angular-ui-utils') === -1);
}
});
var bowerAllArray = ['public/lib/angular/angular.js',
'public/lib/angular-ui-select/dist/select.js',
'public/lib/v-button/dist/v-button.js',
'public/lib/angular-ui-scroll/dist/ui-scroll.js',
'public/lib/angular-resource/angular-resource.js',
'public/lib/angular-ui-router/release/angular-ui-router.js',
'public/lib/angular-sanitize/angular-sanitize.js',
'public/lib/angular-input-stars/angular-input-stars.js',
'public/lib/ng-file-upload/ng-file-upload.js',
'public/lib/angular-mocks/angular-mocks.js',
'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
'public/lib/angular-ui-scrollpoint/dist/scrollpoint.js',
'public/lib/angular-ui-event/dist/event.js',
'public/lib/angular-ui-mask/dist/mask.js',
'public/lib/angular-ui-validate/dist/validate.js',
'public/lib/angular-ui-indeterminate/dist/indeterminate.js',
'public/lib/angular-ui-uploader/dist/uploader.js',
'public/lib/raven-js/dist/raven.js',
'public/lib/jquery-ui/jquery-ui.js',
'public/lib/lodash/lodash.js',
'public/lib/angular-ui-sortable/sortable.js',
'public/lib/angular-permission/dist/angular-permission.js',
'public/lib/file-saver.js/FileSaver.js',
'public/lib/angular-bootstrap-colorpicker/js/bootstrap-colorpicker-module.js',
'public/lib/angular-ui-router-tabs/src/ui-router-tabs.js',
'public/lib/angular-scroll/angular-scroll.js',
'public/lib/angular-animate/angular-animate.js',
'public/lib/file-saver/FileSaver.js',
'public/lib/html2canvas/build/html2canvas.js',
'public/lib/jspdf/dist/jspdf.min.js',
'public/lib/jspdf-autotable/dist/jspdf.plugin.autotable.js',
'public/lib/angular-translate/angular-translate.js',
'public/lib/deep-diff/index.js',
'public/lib/jsep/build/jsep.js',
'public/lib/clipboard/dist/clipboard.js',
'public/lib/mobile-detect/mobile-detect.js',
'public/lib/angular-strap/dist/angular-strap.js',
'public/lib/angular-strap/dist/angular-strap.tpl.js',
'public/lib/bootstrap/dist/js/bootstrap.js',
'public/lib/angular-ui-utils/index.js',
'public/lib/angular-raven/angular-raven.js',
'public/lib/angular-ui-date/src/date.js',
'public/lib/angular-busy/dist/angular-busy.js',
'public/lib/tableExport.jquery.plugin/tableExport.min.js',
'public/lib/ngclipboard/dist/ngclipboard.js' ];
var bowerArray = ['public/lib/angular/angular.min.js', var bowerArray = ['public/lib/angular/angular.min.js',
'public/lib/angular-scroll/angular-scroll.min.js', 'public/lib/angular-scroll/angular-scroll.min.js',
'public/lib/angular-ui-select/dist/select.min.js', 'public/lib/angular-ui-select/dist/select.min.js',
@ -85,16 +17,6 @@ var bowerArray = ['public/lib/angular/angular.min.js',
'public/lib/mobile-detect/mobile-detect.js', 'public/lib/mobile-detect/mobile-detect.js',
'public/lib/js-yaml/dist/js-yaml.js', 'public/lib/js-yaml/dist/js-yaml.js',
'public/lib/angular-sanitize/angular-sanitize.min.js']; 'public/lib/angular-sanitize/angular-sanitize.min.js'];
/*
'public/lib/bootstrap/dist/js/bootstrap.js',
'public/lib/angular-raven/angular-raven.js',
'public/lib/angular-busy/dist/angular-busy.js'];
*/
module.exports = function(grunt) { module.exports = function(grunt) {
require('jit-grunt')(grunt); require('jit-grunt')(grunt);
@ -407,20 +329,21 @@ module.exports = function(grunt) {
grunt.option('force', true); grunt.option('force', true);
// A Task for loading the configuration object // A Task for loading the configuration object
grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() { /*grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() {
var init = require('./config/init')(); require('./config/init')();
var config = require('./config/config'); var config = require('./config/config');
console.log(config);
grunt.config.set('applicationJavaScriptFiles', config.assets.js); grunt.config.set('applicationJavaScriptFiles', config.assets.js);
grunt.config.set('formApplicationJavaScriptFiles', config.assets.form_js); grunt.config.set('formApplicationJavaScriptFiles', config.assets.form_js);
grunt.config.set('applicationCSSFiles', config.assets.css); grunt.config.set('applicationCSSFiles', config.assets.css);
}); });*/
// Code coverage tasks. // Code coverage tasks.
grunt.registerTask('coveralls', ['env:test','mocha_istanbul:coveralls']); grunt.registerTask('coveralls', ['env:test','mocha_istanbul:coveralls']);
grunt.registerTask('coverage', ['env:test', 'mocha_istanbul:coverage']); grunt.registerTask('coverage', ['env:test', 'mocha_istanbul:coverage']);
grunt.registerTask('coverage:client', ['env:test', 'mocha_istanbul:coverageClient']); grunt.registerTask('coverage:client', ['env:test', 'mocha_istanbul:coverageClient']);
grunt.registerTask('coverage:server', ['env:test', 'mocha_istanbul:coverageServer']); grunt.registerTask('coverage:server', ['env:test', 'mocha_istanbul:coverageServer']);
// Default task(s). // Default task(s).
grunt.registerTask('default', ['lint', 'html2js:main', 'html2js:forms', 'env', 'concurrent:default']); grunt.registerTask('default', ['lint', 'html2js:main', 'html2js:forms', 'env', 'concurrent:default']);

View file

@ -1,7 +1,7 @@
'use strict'; 'use strict';
// Init the application configuration module for AngularJS application // Init the application configuration module for AngularJS application
var ApplicationConfiguration = (function() { (function() {
// Init module configuration options // Init module configuration options
var applicationModuleName = 'NodeForm'; var applicationModuleName = 'NodeForm';
var applicationModuleVendorDependencies = ['duScroll', 'ui.select', 'cgBusy', 'ngSanitize', 'vButton', 'ngResource', 'TellForm.templates', 'ui.router', 'ui.bootstrap', 'ui.utils', 'pascalprecht.translate']; var applicationModuleVendorDependencies = ['duScroll', 'ui.select', 'cgBusy', 'ngSanitize', 'vButton', 'ngResource', 'TellForm.templates', 'ui.router', 'ui.bootstrap', 'ui.utils', 'pascalprecht.translate'];

View file

@ -9,33 +9,6 @@ jsep.addBinaryOp("!begins", 10);
jsep.addBinaryOp("ends", 10); jsep.addBinaryOp("ends", 10);
jsep.addBinaryOp("!ends", 10); jsep.addBinaryOp("!ends", 10);
/**
* Calculate a 32 bit FNV-1a hash
* Found here: https://gist.github.com/vaiorabbit/5657561
* Ref.: http://isthe.com/chongo/tech/comp/fnv/
*
* @param {string} str the input value
* @param {boolean} [asString=false] set to true to return the hash value as
* 8-digit hex string instead of an integer
* @param {integer} [seed] optionally pass the hash of the previous chunk
* @returns {integer | string}
*/
function hashFnv32a(str, asString, seed) {
/*jshint bitwise:false */
var i, l,
hval = (seed === undefined) ? 0x811c9dc5 : seed;
for (i = 0, l = str.length; i < l; i++) {
hval ^= str.charCodeAt(i);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
if( asString ){
// Convert to 8 digit hex string
return ("0000000" + (hval >>> 0).toString(16)).substr(-8);
}
return hval >>> 0;
}
angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCounter', '$filter', '$rootScope', 'SendVisitorData', angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCounter', '$filter', '$rootScope', 'SendVisitorData',
function ($http, TimeCounter, $filter, $rootScope, SendVisitorData) { function ($http, TimeCounter, $filter, $rootScope, SendVisitorData) {
return { return {
@ -136,7 +109,7 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun
if(parse_tree.left.name === 'field'){ if(parse_tree.left.name === 'field'){
left = field.fieldValue; left = field.fieldValue;
right = logicJump.valueB right = logicJump.valueB;
} else { } else {
left = logicJump.valueB; left = logicJump.valueB;
right = field.fieldValue; right = field.fieldValue;
@ -192,9 +165,9 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun
if($scope.selected._id === 'submit_field') { if($scope.selected._id === 'submit_field') {
return $scope.myform.form_fields.length - 1; return $scope.myform.form_fields.length - 1;
} else {
return $scope.selected.index;
} }
return $scope.selected.index;
}; };
$scope.setActiveField = $rootScope.setActiveField = function(field_id, field_index, animateScroll) { $scope.setActiveField = $rootScope.setActiveField = function(field_id, field_index, animateScroll) {
@ -212,7 +185,7 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun
if(!field_index){ if(!field_index){
for(var i=0; i<$scope.myform.visible_form_fields.length; i++){ for(var i=0; i<$scope.myform.visible_form_fields.length; i++){
var currField = $scope.myform.visible_form_fields[i]; var currField = $scope.myform.visible_form_fields[i];
if(field_id == currField._id){ if(field_id === currField._id){
$scope.selected.index = i; $scope.selected.index = i;
break; break;
} }
@ -319,7 +292,7 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun
return { return {
type: deviceType, type: deviceType,
name: window.navigator.platform name: window.navigator.platform
} };
}; };
var getIpAndGeo = function(){ var getIpAndGeo = function(){
@ -364,7 +337,7 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun
setTimeout(function () { setTimeout(function () {
$scope.submitPromise = $http.post('/forms/' + $scope.myform._id, form) $scope.submitPromise = $http.post('/forms/' + $scope.myform._id, form)
.success(function (data, status, headers) { .success(function (data, status) {
$scope.myform.submitted = true; $scope.myform.submitted = true;
$scope.loading = false; $scope.loading = false;
SendVisitorData.send($scope.myform, getActiveField(), _timeElapsed); SendVisitorData.send($scope.myform, getActiveField(), _timeElapsed);
@ -378,7 +351,7 @@ angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCoun
}; };
//Reload our form //Reload our form
$scope.reloadForm(); $scope.reloadForm();
} }
}; };
} }

View file

@ -2,7 +2,7 @@
angular.module('view-form').service('TimeCounter', [ angular.module('view-form').service('TimeCounter', [
function(){ function(){
var _startTime, _endTime = null, that=this; var _startTime, _endTime = null;
this.timeSpent = 0; this.timeSpent = 0;
@ -25,9 +25,8 @@ angular.module('view-form').service('TimeCounter', [
this._startTime = this._endTime = null; this._startTime = this._endTime = null;
return this.timeSpent; return this.timeSpent;
}else{
return new Error('Clock has not been started');
} }
return new Error('Clock has not been started');
}; };
this.clockStarted = function(){ this.clockStarted = function(){

View file

@ -15,22 +15,18 @@ angular.module('core').service('Menus', [
if (user) { if (user) {
if (~this.roles.indexOf('*')) { if (~this.roles.indexOf('*')) {
return true; return true;
} else { }
for (var userRoleIndex in user.roles) { for (var userRoleIndex in user.roles) {
for (var roleIndex in this.roles) { for (var roleIndex in this.roles) {
console.log(this.roles[roleIndex]); if (this.roles[roleIndex] === user.roles[userRoleIndex]) {
console.log( this.roles[roleIndex] === user.roles[userRoleIndex]); return true;
if (this.roles[roleIndex] === user.roles[userRoleIndex]) {
return true;
}
} }
} }
} }
} else { return false;
return this.isPublic;
}
return false; }
return this.isPublic;
}; };
// Validate menu existance // Validate menu existance

View file

@ -2,8 +2,8 @@
angular.module('core').factory('subdomain', ['$location', function ($location) { angular.module('core').factory('subdomain', ['$location', function ($location) {
var host = $location.host(); var host = $location.host();
if (host.indexOf('.') < 0) if (host.indexOf('.') < 0) {
return null; return null;
else }
return host.split('.')[0]; return host.split('.')[0];
}]); }]);

View file

@ -3,8 +3,7 @@
(function() { (function() {
describe('HomeController', function() { describe('HomeController', function() {
//Initialize global variables //Initialize global variables
var scope, var scope;
HomeController;
// Load the main application module // Load the main application module
beforeEach(module(ApplicationConfiguration.applicationModuleName)); beforeEach(module(ApplicationConfiguration.applicationModuleName));
@ -12,7 +11,7 @@
beforeEach(inject(function($controller, $rootScope) { beforeEach(inject(function($controller, $rootScope) {
scope = $rootScope.$new(); scope = $rootScope.$new();
HomeController = $controller('HomeController', { $controller('HomeController', {
$scope: scope $scope: scope
}); });
})); }));

View file

@ -1,139 +0,0 @@
'use strict';
function removeDateFieldsFunc(o) {
var clone = _.clone(o);
function eachObject(v,k){
if(k === 'lastModified' || k === 'created'){
delete clone[k];
}
}
for(var i=0; i<clone.length; i++){
_.each(clone[i], eachObject);
}
return clone;
}
function wait(ms){
var start = new Date().getTime();
var end = start;
while(end < start + ms) {
end = new Date().getTime();
}
}
_.mixin({ removeDateFields : removeDateFieldsFunc });
angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', function($rootScope, $timeout) {
return {
require: ['^form'],
restrict: 'AE',
link: function($scope, $element, $attrs, $ctrls) {
//DAVID: TODO: Do we really need to check if our directive element is ready everytime
angular.element(document).ready(function() {
var $formCtrl = $ctrls[0],
savePromise = null;
$rootScope.finishedRender = false;
$scope.$on('editFormFields Started', function(ngRepeatFinishedEvent) {
$rootScope.finishedRender = false;
});
$scope.$on('editFormFields Finished', function(ngRepeatFinishedEvent) {
$rootScope.finishedRender = true;
});
$scope.anyDirtyAndTouched = function(form){
var propCount = 0;
for(var prop in form) {
if(form.hasOwnProperty(prop) && prop[0] !== '$') {
propCount++;
if(form[prop].$touched && form[prop].$dirty) {
return true;
}
}
}
return false;
};
var debounceSave = function (diffChanges) {
$rootScope[$attrs.autoSaveCallback](true, diffChanges, true, true,
function(err){
if(!err){
$formCtrl.$setPristine();
$formCtrl.$setUntouched();
}else{
console.error('Error form data NOT persisted');
console.error(err);
}
});
};
//Autosave Form when model (specified in $attrs.autoSaveWatch) changes
$scope.$watch($attrs.autoSaveWatch, function(newValue, oldValue) {
if( !newValue || !oldValue ) {
$rootScope.finishedRender = true;
return;
}
newValue = angular.copy(newValue);
oldValue = angular.copy(oldValue);
delete newValue.visible_form_fields;
delete oldValue.visible_form_fields;
newValue.form_fields = _.removeDateFields(newValue.form_fields);
oldValue.form_fields = _.removeDateFields(oldValue.form_fields);
var changedFields = !!DeepDiff.diff(oldValue.form_fields, newValue.form_fields) && DeepDiff.diff(oldValue.form_fields, newValue.form_fields).length > 0;
//If our form's startPage or form fields have not changed, don't autosave form
if(!changedFields){
$rootScope.finishedRender = true;
return;
}
if(oldValue.form_fields.length === 0) {
$rootScope.finishedRender = true;
}
console.log('Autosaving');
console.log('\n\n----------');
console.log('$dirty: '+ $formCtrl.$dirty );
// console.log('changedFieldMap: '+changedFieldMap);
// console.log('finishedRender: '+$rootScope.finishedRender);
// console.log('!saveInProgress: '+!$rootScope.saveInProgress);
// console.log('newValue: '+newValue);
// console.log('oldValue: '+oldValue);
// console.log(oldValue.form_fields);
// console.log(newValue.form_fields);
//Save form ONLY IF rendering is finished, form_fields have been changed AND currently not save in progress
if($rootScope.finishedRender && (changedFields) && !$rootScope.saveInProgress) {
if(savePromise) {
$timeout.cancel(savePromise);
savePromise = null;
}
savePromise = $timeout(function() {
$rootScope.saveInProgress = true;
var _diff = DeepDiff.diff(oldValue, newValue);
debounceSave(_diff);
});
}
//If we are finished rendering then form saving should be finished
else if($rootScope.finishedRender && $rootScope.saveInProgress){
$rootScope.saveInProgress = false;
}
}, true);
});
}
};
}]);

View file

@ -7,7 +7,7 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
restrict: 'E', restrict: 'E',
scope: { scope: {
user:'=', user:'=',
myform: '=' myform: '='
}, },
controller: function($scope){ controller: function($scope){
@ -48,11 +48,13 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
var totalTime = 0; var totalTime = 0;
var numSubmissions = $scope.table.rows.length; var numSubmissions = $scope.table.rows.length;
for(var i=0; i<$scope.table.rows.length; i++){ for(i=0; i<$scope.table.rows.length; i++){
totalTime += $scope.table.rows[i].timeElapsed; totalTime += $scope.table.rows[i].timeElapsed;
} }
if(numSubmissions == 0) return 0; if(numSubmissions === 0) {
return 0;
}
return (totalTime/numSubmissions).toFixed(0); return (totalTime/numSubmissions).toFixed(0);
})(); })();
@ -77,7 +79,7 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
if($scope.myform.analytics && $scope.myform.analytics.visitors) { if($scope.myform.analytics && $scope.myform.analytics.visitors) {
var visitors = $scope.myform.analytics.visitors; var visitors = $scope.myform.analytics.visitors;
for (var i = 0; i < visitors.length; i++) { for (i = 0; i < visitors.length; i++) {
var visitor = visitors[i]; var visitor = visitors[i];
var deviceType = visitor.deviceType; var deviceType = visitor.deviceType;
@ -86,12 +88,18 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
stats[deviceType].total_time = stats[deviceType].total_time + visitor.timeElapsed; stats[deviceType].total_time = stats[deviceType].total_time + visitor.timeElapsed;
stats[deviceType].average_time = (stats[deviceType].total_time / stats[deviceType].visits).toFixed(0); stats[deviceType].average_time = (stats[deviceType].total_time / stats[deviceType].visits).toFixed(0);
if(!stats[deviceType].average_time) stats[deviceType].average_time = 0; if(!stats[deviceType].average_time) {
stats[deviceType].average_time = 0;
if (visitor.isSubmitted) stats[deviceType].responses++; }
if (visitor.isSubmitted) {
stats[deviceType].responses++;
}
stats[deviceType].completion = (stats[deviceType].responses / stats[deviceType].visits).toFixed(0); stats[deviceType].completion = (stats[deviceType].responses / stats[deviceType].visits).toFixed(0);
if(!stats[deviceType].completion) stats[deviceType].completion = 0; if(!stats[deviceType].completion) {
stats[deviceType].completion = 0;
}
} }
} }

View file

@ -1,4 +1,4 @@
<form class="row container" name="editForm" ><!--auto-save-form auto-save-watch="myform" auto-save-callback="update">--> <form class="row container" name="editForm" >
<!-- Edit EndPage Modal Dialog Template --> <!-- Edit EndPage Modal Dialog Template -->
<script type="text/ng-template" id="editEndPageModal.html" class="edit-endpage-modal"> <script type="text/ng-template" id="editEndPageModal.html" class="edit-endpage-modal">

View file

@ -1,6 +1,6 @@
'use strict'; 'use strict';
angular.module('forms').directive('onFinishRender', function ($rootScope, $timeout) { angular.module('forms').directive('onFinishRender', function ($rootScope) {
return { return {
restrict: 'A', restrict: 'A',
link: function (scope, element, attrs) { link: function (scope, element, attrs) {
@ -16,9 +16,8 @@ angular.module('forms').directive('onFinishRender', function ($rootScope, $timeo
scope.$evalAsync(function () { scope.$evalAsync(function () {
$rootScope.$broadcast(broadcastMessage+' Started'); $rootScope.$broadcast(broadcastMessage+' Started');
}); });
}else if(scope.$last) { } else if(scope.$last) {
scope.$evalAsync(function () { scope.$evalAsync(function () {
// console.log(broadcastMessage+'Finished');
$rootScope.$broadcast(broadcastMessage+' Finished'); $rootScope.$broadcast(broadcastMessage+' Finished');
}); });
} }

View file

@ -1,14 +1,11 @@
(function () { (function () {
'use strict'; 'use strict';
// Create the Socket.io wrapper service
angular
.module('forms')
.factory('Socket', Socket);
Socket.$inject = ['$timeout', '$window'];
function Socket($timeout, $window) { function Socket($timeout, $window) {
var service;
// Connect to Socket.io server // Connect to Socket.io server
function connect(url) { function connect(url) {
service.socket = io(url, {'transports': ['websocket', 'polling']}); service.socket = io(url, {'transports': ['websocket', 'polling']});
@ -39,7 +36,7 @@
} }
} }
var service = { service = {
connect: connect, connect: connect,
emit: emit, emit: emit,
on: on, on: on,
@ -61,4 +58,11 @@
return service; return service;
} }
// Create the Socket.io wrapper service
angular.module('forms')
.factory('Socket', Socket);
Socket.$inject = ['$timeout', '$window'];
}()); }());

View file

@ -1,7 +1,7 @@
(function () { (function () {
"use strict"; "use strict";
function SendVisitorData(Socket, $state) { function SendVisitorData() {
// Create a controller method for sending visitor data // Create a controller method for sending visitor data
function send(form, lastActiveIndex) { function send(form, lastActiveIndex) {
@ -60,7 +60,7 @@
.module('forms') .module('forms')
.factory('SendVisitorData', SendVisitorData); .factory('SendVisitorData', SendVisitorData);
SendVisitorData.$inject = ['Socket', '$state', '$http']; SendVisitorData.$inject = [];
}()); }());

View file

@ -4,12 +4,9 @@
// Forms Controller Spec // Forms Controller Spec
describe('ListForms Controller Tests', function() { describe('ListForms Controller Tests', function() {
// Initialize global variables // Initialize global variables
var ListFormsController, var createListFormsController,
createListFormsController,
scope, scope,
$httpBackend, $httpBackend,
$stateParams,
$location,
$state; $state;
var sampleForm = { var sampleForm = {
@ -93,7 +90,7 @@
// The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_).
// This allows us to inject a service but then attach it to a variable // This allows us to inject a service but then attach it to a variable
// with the same name as the service. // with the same name as the service.
beforeEach(inject(function($controller, $rootScope, _$state_, _$location_, _$stateParams_, _$httpBackend_, CurrentForm, Forms) { beforeEach(inject(function($controller, $rootScope, _$state_, _$location_, _$stateParams_, _$httpBackend_, CurrentForm) {
// Set a new global scope // Set a new global scope
scope = $rootScope.$new(); scope = $rootScope.$new();
@ -115,7 +112,7 @@
}; };
})); }));
it('$scope.findAll() should query all User\'s Forms', inject(function(Forms) { it('$scope.findAll() should query all User\'s Forms', inject(function() {
var controller = createListFormsController(); var controller = createListFormsController();
@ -130,7 +127,7 @@
expect( scope.myforms ).toEqualData(sampleFormList); expect( scope.myforms ).toEqualData(sampleFormList);
})); }));
it('$scope.duplicateForm() should duplicate a Form', inject(function(Forms) { it('$scope.duplicateForm() should duplicate a Form', inject(function() {
var dupSampleForm = sampleFormList[2], var dupSampleForm = sampleFormList[2],
dupSampleForm_index = 3, dupSampleForm_index = 3,
@ -160,7 +157,7 @@
expect( scope.myforms[dupSampleForm_index] ).toEqualData(dupSampleForm); expect( scope.myforms[dupSampleForm_index] ).toEqualData(dupSampleForm);
})); }));
it('$scope.removeForm() should remove a Form', inject(function(Forms) { it('$scope.removeForm() should remove a Form', inject(function() {
var delIndex = 0, var delIndex = 0,
delSampleForm = sampleFormList[delIndex], delSampleForm = sampleFormList[delIndex],
@ -191,7 +188,7 @@
expect( scope.myforms[0] ).not.toEqualData(delSampleForm); expect( scope.myforms[0] ).not.toEqualData(delSampleForm);
})); }));
it('$scope.createNewForm() should create a new Form', inject(function(Forms) { it('$scope.createNewForm() should create a new Form', inject(function() {
var newForm = _.clone(sampleForm); var newForm = _.clone(sampleForm);
newForm.name = 'Test Form5'; newForm.name = 'Test Form5';

View file

@ -21,7 +21,7 @@
scope.myfields = FormFields.types; scope.myfields = FormFields.types;
var e = $compile('<div><div ng-repeat="item in myfields" on-finish-render="editFormFields">{{item.name}}</div></div>')(scope); $compile('<div><div ng-repeat="item in myfields" on-finish-render="editFormFields">{{item.name}}</div></div>')(scope);
scope.$digest(); scope.$digest();
//run code to test //run code to test
@ -34,7 +34,7 @@
// console.log(FormFields.types); // console.log(FormFields.types);
scope.myfields = FormFields.types; scope.myfields = FormFields.types;
var e = $compile('<div><div ng-repeat="item in myfields" on-finish-render>{{item.name}}</div></div>')(scope); $compile('<div><div ng-repeat="item in myfields" on-finish-render>{{item.name}}</div></div>')(scope);
scope.$digest(); scope.$digest();
//run code to test //run code to test
@ -43,4 +43,4 @@
})); }));
}); });
}()); }());

View file

@ -5,8 +5,7 @@
*/ */
process.env.NODE_ENV = 'production'; process.env.NODE_ENV = 'production';
var init = require('../config/init')(), var config = require('../config/config'),
config = require('../config/config'),
mongoose = require('mongoose'), mongoose = require('mongoose'),
inquirer = require('inquirer'), inquirer = require('inquirer'),
envfile = require('envfile'), envfile = require('envfile'),
@ -26,7 +25,7 @@ mongoose.connection.on('error', function(err) {
}); });
// Init the express application // Init the express application
var app = require('../config/express')(db); require('../config/express')(db);
// Bootstrap passport config // Bootstrap passport config
require('../config/passport')(); require('../config/passport')();
@ -73,7 +72,7 @@ var nodemailer_providers = [
var bool_options = [ var bool_options = [
"TRUE", "TRUE",
"FALSE" "FALSE"
] ];
var questions = [ var questions = [
{ {
@ -193,7 +192,6 @@ if(!fs.existsSync('./\.env')) {
inquirer.prompt(questions.slice(1)).then(function (answers) { inquirer.prompt(questions.slice(1)).then(function (answers) {
answers['NODE_ENV'] = 'production'; answers['NODE_ENV'] = 'production';
answers['SIGNUP_DISABLED'] = false ? answers['SIGNUP_DISABLED'] === false : true;
var email = answers['email']; var email = answers['email'];
var username = answers['username']; var username = answers['username'];
@ -202,8 +200,10 @@ if(!fs.existsSync('./\.env')) {
delete answers['password']; delete answers['password'];
envfile.stringify(answers, function (err, str) { envfile.stringify(answers, function (err, str) {
fs.outputFile('./\.env', str, function (err) { fs.outputFile('./\.env', str, function (fileErr) {
if (err) return console.error(chalk.red(err)); if (fileErr) {
return console.error(chalk.red(fileErr));
}
console.log(chalk.green('Successfully created .env file')); console.log(chalk.green('Successfully created .env file'));
}); });
user = new User({ user = new User({
@ -216,12 +216,13 @@ if(!fs.existsSync('./\.env')) {
roles: ['admin', 'user'] roles: ['admin', 'user']
}); });
user.save(function (err) { user.save(function (userSaveErr) {
if (err) return console.error(chalk.red(err)); if (err) {
return console.error(chalk.red(userSaveErr));
}
console.log(chalk.green('Successfully created user')); console.log(chalk.green('Successfully created user'));
delete email;
delete pass;
console.log(chalk.green('Have fun using TellForm!')); console.log(chalk.green('Have fun using TellForm!'));
process.exit(1); process.exit(1);
}); });
@ -231,7 +232,7 @@ if(!fs.existsSync('./\.env')) {
console.log(chalk.green('Have fun using TellForm!')); console.log(chalk.green('Have fun using TellForm!'));
} }
}); });
}else{ } else {
console.log(chalk.red('You already have a .env file')); console.log(chalk.red('You already have a .env file'));
process.exit(1); process.exit(1);
} }

View file

@ -10,8 +10,7 @@ if ((process.env.NODE_ENV || 'development') === 'development') {
require('events').EventEmitter.prototype._maxListeners = 0; require('events').EventEmitter.prototype._maxListeners = 0;
var init = require('./config/init')(), var config = require('./config/config'),
config = require('./config/config'),
mongoose = require('mongoose'), mongoose = require('mongoose'),
chalk = require('chalk'); chalk = require('chalk');