tracman-server/config/models.js

151 lines
3.8 KiB
JavaScript
Raw Normal View History

2017-04-01 11:03:31 -06:00
'use strict';
2017-04-09 21:40:08 -06:00
const mongoose = require('mongoose'),
unique = require('mongoose-unique-validator'),
bcrypt = require('bcrypt'),
2017-05-06 21:25:32 -06:00
crypto = require('crypto'),
2017-05-08 11:47:53 -06:00
debug = require('debug')('tracman-models');
2017-04-01 11:03:31 -06:00
const userSchema = new mongoose.Schema({
name: {type:String},
2017-04-17 23:18:08 -06:00
email: {type:String, unique:true},
2017-04-18 01:08:57 -06:00
newEmail: String,
emailToken: String,
2017-04-01 11:03:31 -06:00
slug: {type:String, required:true, unique:true},
2017-04-09 21:40:08 -06:00
auth: {
password: String,
passToken: String,
2017-04-18 01:08:57 -06:00
passTokenExpires: Date,
2017-05-08 11:47:53 -06:00
google: String,
facebook: String,
twitter: String,
2017-04-09 21:40:08 -06:00
},
2017-04-01 11:03:31 -06:00
isAdmin: {type:Boolean, required:true, default:false},
isPro: {type:Boolean, required:true, default:false},
created: {type:Date, required:true},
2017-04-01 11:03:31 -06:00
lastLogin: Date,
settings: {
2017-04-17 23:18:08 -06:00
units: {type:String, default:'standard'},
defaultMap: {type:String, default:'road'},
defaultZoom: {type:Number, default:11},
showScale: {type:Boolean, default:false},
showSpeed: {type:Boolean, default:false},
showTemp: {type:Boolean, default:false},
showAlt: {type:Boolean, default:false},
2017-07-20 06:56:01 -06:00
showStreetview: {type:Boolean, default:false},
marker: {type:String, default:'red'}
2017-04-01 11:03:31 -06:00
},
last: {
time: Date,
2017-04-17 23:18:08 -06:00
lat: {type:Number, default:0},
lon: {type:Number, default:0},
dir: {type:Number, default:0},
2017-11-05 11:06:37 -07:00
alt: {type:Number},
2017-04-17 23:18:08 -06:00
spd: {type:Number, default:0}
2017-04-01 11:03:31 -06:00
},
sk32: {type:String, required:true, unique:true}
2017-04-09 21:40:08 -06:00
}).plugin(unique);
/* User methods */ {
2017-04-13 22:45:25 -06:00
2017-04-14 20:10:52 -06:00
//TODO: Return promises instead of taking callbacks
2017-04-26 13:10:07 -06:00
// See https://gist.github.com/7h1b0/5154fda207e68ad1cefc#file-random-js
// For an example
2017-04-14 20:10:52 -06:00
2017-04-18 01:08:57 -06:00
// Create email confirmation token
userSchema.methods.createEmailToken = function(next){ // next(err,token)
2017-05-08 11:47:53 -06:00
debug('user.createEmailToken() called');
2017-04-18 01:08:57 -06:00
var user = this;
2017-04-26 13:10:07 -06:00
crypto.randomBytes(16, (err,buf)=>{
if (err){ next(err,null); }
2017-04-26 20:47:23 -06:00
if (buf){
2017-05-08 11:47:53 -06:00
debug(`Buffer ${buf.toString('hex')} created`);
2017-04-26 13:10:07 -06:00
user.emailToken = buf.toString('hex');
user.save()
.then( ()=>{
return next(null,user.emailToken);
})
.catch( (err)=>{
return next(err,null);
});
2017-04-26 13:10:07 -06:00
}
});
2017-04-18 01:08:57 -06:00
};
2017-04-09 21:40:08 -06:00
// Create password reset token
userSchema.methods.createPassToken = function(next){ // next(err,token,expires)
2017-04-09 21:40:08 -06:00
var user = this;
2017-04-18 01:08:57 -06:00
// Reuse old token, resetting clock
if ( user.auth.passTokenExpires >= Date.now() ){
2017-05-08 11:47:53 -06:00
debug(`Reusing old password token...`);
2017-04-18 01:08:57 -06:00
user.auth.passTokenExpires = Date.now() + 3600000; // 1 hour
2017-04-20 21:07:35 -06:00
user.save()
.then( ()=>{
return next(null,user.auth.passToken,user.auth.passTokenExpires);
2017-04-20 21:07:35 -06:00
})
.catch( (err)=>{
return next(err,null,null);
2017-04-20 21:07:35 -06:00
});
2017-04-18 01:08:57 -06:00
}
// Create new token
else {
2017-05-08 11:47:53 -06:00
debug(`Creating new password token...`);
crypto.randomBytes(16, (err,buf)=>{
if (err){ return next(err,null,null); }
if (buf) {
user.auth.passToken = buf.toString('hex');
user.auth.passTokenExpires = Date.now() + 3600000; // 1 hour
user.save()
.then( ()=>{
2017-05-08 11:47:53 -06:00
debug('successfully saved user in createPassToken');
return next(null,user.auth.passToken,user.auth.passTokenExpires);
})
.catch( (err)=>{
2017-05-08 11:47:53 -06:00
debug('error saving user in createPassToken');
return next(err,null,null);
});
}
});
2017-04-12 11:41:27 -06:00
}
2017-04-18 01:08:57 -06:00
2017-04-09 21:40:08 -06:00
};
2017-04-13 22:45:25 -06:00
// Generate hash for new password and save it to the database
userSchema.methods.generateHashedPassword = function(password,next){
// next(err);
// Delete token
this.auth.passToken = undefined;
this.auth.passTokenExpires = undefined;
// Generate hash
bcrypt.genSalt(8, (err,salt)=>{
if (err){ return next(err); }
bcrypt.hash(password, salt, (err,hash)=>{
if (err){ return next(err); }
this.auth.password = hash;
this.save();
next();
});
});
};
2017-04-09 21:40:08 -06:00
// Check for valid password
2017-04-13 22:45:25 -06:00
userSchema.methods.validPassword = function(password,next){
// next(err,res);
// res = true/false
2017-04-09 21:40:08 -06:00
bcrypt.compare(password, this.auth.password, next);
};
2017-04-13 22:45:25 -06:00
2017-04-09 21:40:08 -06:00
}
2017-04-01 11:03:31 -06:00
module.exports = {
'user': mongoose.model('User', userSchema)
};