AccessToken.methods.authenticate = function(token, next) { var now = new Date(); // Check for a valid possible token if(sanitize.string(token) === undefined) { return false; } // Creation date must be prior to right now. if(date.diff(now, this.creationDate) < 0) { return false; } // Expiration date must be later than now. if(date.diff(this.expirationDate, now) <= 0) { return false; } // Usage must be less than our max usage. if(this.usage >= this.maxUsage) { return false; } // Check if the token matches our token hash. if(next) return bcrypt.compare(token, this.tokenHash, next); // Asynchronous call to compare the possible access token to the encrypted access token. return bcrypt.compareSync(token, this.tokenHash); // Synchronous call to compare the possible access token to the encrypted access token. }
AccessToken.virtual('token').set(function(token) { if(sanitize.string(token) === undefined) token = hash.generateKeySync(24); this.tokenHash = hash.hashKeySync(token, saltRounds); // Synchronous call to create a bcrypt salt & hash, then set that hash as the password. return token; });
User.pre('save', function(next) { var user = this; if(sanitize.string(user.name) === undefined) { return next(new Error('Please enter a valid name.')); } if(sanitize.string(user.password) === undefined) return next(new Error('Please enter a password.')); try { check(this.email).len(6,64).isEmail(); // Check if string is a valid email. } catch (e) { return next(new Error('Please enter a valid email address.')); } return next(); });
AccessToken.methods.update = function(obj, userId, next) { var accessToken = this, isUpdated = false; // Loop through each property in the new object. // Verify each property and update the user object accordingly. for (var key in obj) { switch(key) { // Number Property Types case 'maxUsage': case 'usage': value = sanitize.number(obj[key]); break; // Object ID Property Types case 'user': value = sanitize.objectId(obj[key]); break; // Date Property Types case 'creationDate': case 'expirationDate': value = sanitize.date(obj[key]); break; // Boolean Property Types case 'activated': value = sanitize.boolean(obj[key]); break; // Ignore these, the model update function will // handle them for us. case 'lastUpdated': case 'lastUpdatedBy': break; // String Property Types, handled by default. default: value = sanitize.string(obj[key]); break; } // If the value was valid, then update the access token object. if(value !== undefined) { accessToken[key] = value; isUpdated = true } } // Handle the lastUpdated and lastUpdatedBy attributes // then save the object. model.update(obj, accessToken, userId, isUpdated, next); }
AccessToken.pre('save', function(next) { var accessToken = this; // If there isn't an access token already generated, // then create one. // TODO: See if this is necessary. if(sanitize.string(accessToken.token) === undefined) { accessToken.token = undefined; } return next(); });
User.methods.update = function(obj, userId, next) { if( ! obj) { var err = new Error('Can not update the user object because the parameter is not valid.') if(next !== undefined) { return next(err); } return log.e(err); } var user = this, isUserUpdated = false, isLastUpdated = false, isLastUpdatedBy = false, value = undefined; // Loop through each property in the new object. Verify each property and update the user object accordingly. for (var key in obj) { switch(key) { // Number Property Types case 'failedLoginAttempts': value = sanitize.number(obj[key]); break; // Object ID Property Types case 'lastUpdatedBy': isLastUpdatedBy = true; case 'roles': value = sanitize.objectId(obj[key]); break; // Date Property Types case 'dateCreated': case 'lastLogin': case 'lastUpdated': isLastUpdated = true; value = sanitize.date(obj[key]); break; // Boolean Property Types case 'activated': value = sanitize.boolean(obj[key]); break; // String Property Types, handled by default. default: value = sanitize.string(obj[key]); break; } // If the value was valid, then update the user object. if(value !== undefined) { // Trigger an update to the lastUpdated and lastUpdatedBy property if we are not tracking a login or login attempt. if(key !== "failedLoginAttempts" && key !== "lastLogin") { isUserUpdated = true } // Update the user property with the new value. user[key] = value; } } if( ! isLastUpdated && isUserUpdated) { user['lastUpdated'] = Date.now(); } if( ! isLastUpdatedBy && isUserUpdated) { user['lastUpdatedBy'] = sanitize.objectId(userId); } user.save(function(err, user) { if(! user && ! err) { var err = new Error('There was a problem saving the updated user object.'); } if(err) { if(next !== undefined) { return next(err); } return log.e(err); } if(next !== undefined) return next(undefined, user); }); }