diff options
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/Access.js | 129 | ||||
-rw-r--r-- | app/models/Project.js | 75 | ||||
-rw-r--r-- | app/models/User.js | 182 | ||||
-rw-r--r-- | app/models/pPost.js | 78 |
4 files changed, 464 insertions, 0 deletions
diff --git a/app/models/Access.js b/app/models/Access.js new file mode 100644 index 0000000..b9570e6 --- /dev/null +++ b/app/models/Access.js @@ -0,0 +1,129 @@ + +/** + * Module dependencies + */ + +var mongoose = require('mongoose') + , Schema = mongoose.Schema; + + +/** + * Schema + * + * Permissions: + * 3 = normal + * 6 = admin + * 9 = owner + * These permissions are set in steps of three, in case + * we need to add more permissions later. + */ + +var AccessSchema = new Schema({ + user: { type: Schema.ObjectId, ref: 'User' }, + creator: { type: Schema.ObjectId, ref: 'User' }, + project: { type: Schema.ObjectId, ref: 'Project' }, + permissions: { type: Number, default: '3' }, + randomToken: { type: String }, + created: { type: Date, default: Date.now }, + updated: { type: Date, default: Date.now } +}); + + +// the four validations below only apply if you are signing up traditionally + +AccessSchema.methods = { + + /** + * Generate random access token for Remember Me function + * + * @param {Number} length + * @return {String} + * @api public + */ + + generateRandomToken: function(length) { + if (typeof(length) === undefined) length = 16; // default length of token + var chars = '_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' + , token = ''; + for (var i = 0; i < length; i++) { + var x = Math.floor(Math.random() * chars.length); + token += chars.charAt(x); + } + console.log('token ' + token); + return token; + } + +} + +AccessSchema.statics = { + + /** + * Load ALL accesses for a single user + * + * @param {ObjectId} id + * @param {Function} callback + * @api private + */ + + loadUser: function(id, callback) { + this.find({ user: id }) + .populate('project') + .sort({ 'created': -1 }) // sort by date + .exec(callback); + }, + + + /** + * Load all users associated with a project + * + * @param {ObjectId} project + * @param {Function} callback + * @api private + */ + + loadProject: function(project, callback) { + this.find({ project: project }) + .populate({path: 'user', select: '_id name'}) + .sort({ 'created': 1 }) // sort by date + .exec(callback); + }, + + + /** + * Load all users associated with several projects + * + * @param {Arrau[ObjectId]} projects + * @param {Function} callback + * @api private + */ + + loadProjects: function(projects, callback) { + this.find({ project: { $in: projects } }) + .populate({ path: 'user', select: '_id name' }) + .sort({ 'created': -1 }) + .exec(callback); + }, + + + /** + * Check to see if user has access to a particular project + * + * @param {ObjectId} user + * @param {ObjectId} project + * @param {Number} permissisons + * @param {Function} callback + * @api private + */ + + checkAccess: function(user, project, permissions, callback) { + if (typeof(permissions) === 'undefined') permissions = 0; + console.log('inni checkPermissions!') + this.findOne({ user: user }) + .where('project').equals(project) + .where('permissions').gte(permissions) + .exec(callback); + } + +} + +mongoose.model('Access', AccessSchema); diff --git a/app/models/Project.js b/app/models/Project.js new file mode 100644 index 0000000..ba0e8e7 --- /dev/null +++ b/app/models/Project.js @@ -0,0 +1,75 @@ + +/** + * Module dependencies + */ + +var mongoose = require('mongoose') + , Schema = mongoose.Schema; + +var ProjectSchema = new Schema({ + user: { type: Schema.ObjectId, ref: 'User' }, + name: { type: String, default: '', trim: true }, + description: {type: String, default: '', trim: true }, + currency: { type: String, default: 'kr', trim: true }, + public: { type: String, default: 'invite-only' }, + created: { type: Date, default: Date.now }, + updated: { type: Date, default: Date.now }, + shortURL: { type: String, unique: true } +}); + +// the four validations below only apply if you are signing up traditionally + +ProjectSchema.path('name').validate(function(name) { + // if you're authenticated by any of the oauth strategies (facebook, twitter), don't validate + return name.length; +}, 'Project name cannot be blank'); + + +ProjectSchema.pre('save', function(next) { + if (this.shortURL !== undefined) return next(); + var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + this.shortURL = ''; + for (var i = 0; i < 6; i++) { + var x = Math.floor(Math.random() * chars.length); + this.shortURL += chars.charAt(x); + } + console.log('SHORT: ' + this.shortURL); + next(); +}); + + + +ProjectSchema.statics = { + + /** + * Find project by id + * + * @param {ObjectId} id + * @param {Function} callback + * @api private + */ + + load: function(id, callback) { + this.findOne({ _id: id }) + .populate('user') + .exec(callback); + }, + + + /** + * Find project my shortURL + * + * @param {shortURL} shortURL + * @param {Function} callback + * @api private + */ + + loadShort : function(shortURL, callback) { + this.findOne({ shortURL: shortURL }) + .populate('user') + .exec(callback); + } + +} + +mongoose.model('Project', ProjectSchema); diff --git a/app/models/User.js b/app/models/User.js new file mode 100644 index 0000000..0dc38f3 --- /dev/null +++ b/app/models/User.js @@ -0,0 +1,182 @@ + +/** + * Module dependencies + */ + +var mongoose = require('mongoose') + , Schema = mongoose.Schema + , crypto = require('crypto') + , authTypes = ['facebook', 'twitter']; + + +/** + * User schema + * + * statuscodes: + * 1: invited + * 2: unconfirmed + * 3: active + * 4: paying user + */ + +var UserSchema = new Schema({ + name: String, + email: { type: String, unique: true }, + username: String, + provider: String, + hashed_password: String, + salt: String, + accessToken: String, + facebook: {}, + twitter: {}, + status: { type: Number, default: 2 }, + randomToken: String, + created: { type: Date, default: Date.now }, + updated: { type: Date, default: Date.now } +}); + + +/** + * Virtuals + */ + +UserSchema + .virtual('password') + .set(function(password) { + this._password = password + this.salt = this.makeSalt() + this.hashed_password = this.encryptPassword(password) + }).get(function() { return this._password }); + + +/** + * Validations + */ + +var validatePrecenceOf = function(value) { + return value && value.length; +} + +// the four validations below only apply if you are signing up traditionally + +UserSchema.path('name').validate(function(name) { + // if you're authenticated by any of the oauth strategies (facebook, twitter), don't validate + if(authTypes.indexOf(this.provider) !== -1 || this.status === 1) return true; + return name.length; +}, 'Name cannot be blank'); + +UserSchema.path('email').validate(function(email) { + if(authTypes.indexOf(this.provider) !== -1) return true; + return email.length; +}, 'Email cannot be blank'); + +UserSchema.path('username').validate(function(username) { + if(authTypes.indexOf(this.provider) !== -1 || this.status === 1) return true; + return username.length; +}, 'Username cannot be blank'); + +UserSchema.path('hashed_password').validate(function(hashed_password) { + if(authTypes.indexOf(this.provider) !== -1) return true; + return hashed_password.length; +}, 'Password cannot be blank'); + + +/** + * Pre-save hook + */ + +UserSchema.pre('save', function(next) { + if (!this.isNew || this.status === 1) return next(); + + this.updated = Date.now(); + next(); + +}); + + +/** + * Methods + */ + +UserSchema.methods = { + + /** + * Authenticate - check if passwords are the same + * + * @param {String} plainText + * @return {Bolean} + * @api public + */ + + authenticate: function(plainText) { + return this.encryptPassword(plainText) === this.hashed_password; + }, + + + /** + * Make salt + * + * @return {String} + * @api public + */ + + makeSalt: function() { + return Math.round((new Date().valueOf() * Math.random())) + ''; + }, + + + /** + * Encrypt password + * + * @param {String} password + * @return {String} + * @api public + */ + + encryptPassword: function(password) { + if (!password) return ''; + return crypto.createHmac('sha1', this.salt).update(password).digest('hex'); + }, + + + /** + * Generate random access token for Remember Me function + * + * @param {Number} length + * @param {Boolean} noDate + * @return {String} + * @api public + */ + + generateRandomToken: function(length, noDate) { + if (typeof(length) === undefined) length = 16; // default length of token + var chars = '_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' + , token = noDate ? '' : new Date().getTime() + '_'; + for (var i = 0; i < length; i++) { + var x = Math.floor(Math.random() * chars.length); + token += chars.charAt(x); + } + return token; + } +} + +UserSchema.statics = { + + /** + * Load user from their email address + * + * @param {String} email + * @param {Function} callback + * @api private + */ + + loadUser: function(email, callback) { + this.findOne({ email: email }) + .exec(callback); + } + +} + +mongoose.model('User', UserSchema); + + diff --git a/app/models/pPost.js b/app/models/pPost.js new file mode 100644 index 0000000..1f53984 --- /dev/null +++ b/app/models/pPost.js @@ -0,0 +1,78 @@ + +/** + * Module dependencies + */ + +var mongoose = require('mongoose') + , Schema = mongoose.Schema; + +var pPostSchema = new Schema({ + user: { type: Schema.ObjectId, ref: 'User' }, + for: { type: Schema.ObjectId, ref: 'User' }, + project: { type: Schema.ObjectId, ref: 'Project' }, + what: { type: String, default: '', trim: true }, + comment: { type: String, default: '', trim: true }, + participants: [], + value: { type: Number, defailt: 0 }, + file: { type: String, default: '', trim: true }, + currency: { type: String, default: 'kr', trim: true }, + created: { type: Date, default: Date.now }, + updated: { type: Date, default: Date.now }, + when: { type: Date, default: Date.now } +}); + + + + +pPostSchema.statics = { + + /** + * Find post by id + * + * @param {ObjectId} id + * @param {Function} callback + * @api private + */ + + load: function(id, callback) { + this.findOne({ _id: id }) + .populate({ path: 'user', select: '_id, name'}) + .exec(callback); + }, + + + /** + * Find all posts that belong to a project, by project id + * + * @param {ObjectId} project + * @param {Function} callback + * @api private + */ + + loadProject: function(project, callback) { + this.find({ project: project }) + .populate('user') + .sort({ 'when': -1, 'created': -1 }) + .exec(callback); + }, + + + /** + * Find last ten posts belonging projects a user is part of, by project ids + * + * @param {Array[ObjectId]} projects + * @param {Function} callback + * @api private + */ + + loadByProjects: function(projects, callback) { + this.find({ project: { $in: projects } }) + .populate({ path: 'user', select: '_id name' }) + .populate({ path: 'project', select: 'name shortURL' }) + .sort({ 'when': -1, 'created': -1 }) + .exec(callback); + } + +} + +mongoose.model('pPost', pPostSchema); |