Base Project Files
This commit is contained in:
34
models/config.js
Normal file
34
models/config.js
Normal file
@@ -0,0 +1,34 @@
|
||||
"use strict";
|
||||
|
||||
var fs = require('fs'),
|
||||
yaml = require('js-yaml'),
|
||||
_ = require('lodash');
|
||||
|
||||
/**
|
||||
* Load Application Configuration
|
||||
*
|
||||
* @param {String} confPath Path to the configuration file
|
||||
* @return {Object} Application Configuration
|
||||
*/
|
||||
module.exports = (confPath) => {
|
||||
|
||||
var appconfig = {};
|
||||
|
||||
try {
|
||||
appconfig = yaml.safeLoad(fs.readFileSync(confPath, 'utf8'));
|
||||
} catch (ex) {
|
||||
winston.error(ex);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return _.defaultsDeep(appconfig, {
|
||||
title: "Requarks Wiki",
|
||||
host: "http://localhost",
|
||||
port: process.env.PORT,
|
||||
db: "mongodb://localhost/wiki",
|
||||
redis: null,
|
||||
sessionSecret: null,
|
||||
admin: null
|
||||
});
|
||||
|
||||
};
|
158
models/db/user.js
Normal file
158
models/db/user.js
Normal file
@@ -0,0 +1,158 @@
|
||||
"use strict";
|
||||
|
||||
var modb = require('mongoose');
|
||||
var bcrypt = require('bcryptjs-then');
|
||||
var Promise = require('bluebird');
|
||||
var _ = require('lodash');
|
||||
|
||||
/**
|
||||
* User Schema
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var userSchema = modb.Schema({
|
||||
|
||||
email: {
|
||||
type: String,
|
||||
required: true,
|
||||
index: true,
|
||||
minlength: 6
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
firstName: {
|
||||
type: String,
|
||||
required: true,
|
||||
minlength: 1
|
||||
},
|
||||
lastName: {
|
||||
type: String,
|
||||
required: true,
|
||||
minlength: 1
|
||||
},
|
||||
timezone: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: 'UTC'
|
||||
},
|
||||
lang: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: 'en'
|
||||
},
|
||||
rights: [{
|
||||
type: String,
|
||||
required: true
|
||||
}]
|
||||
|
||||
},
|
||||
{
|
||||
timestamps: {}
|
||||
});
|
||||
|
||||
/**
|
||||
* VIRTUAL - Full Name
|
||||
*/
|
||||
userSchema.virtual('fullName').get(function() {
|
||||
return this.firstName + ' ' + this.lastName;
|
||||
});
|
||||
|
||||
/**
|
||||
* INSTANCE - Validate password against hash
|
||||
*
|
||||
* @param {string} uPassword The user password
|
||||
* @return {Promise<Boolean>} Promise with valid / invalid boolean
|
||||
*/
|
||||
userSchema.methods.validatePassword = function(uPassword) {
|
||||
let self = this;
|
||||
return bcrypt.compare(uPassword, self.password);
|
||||
};
|
||||
|
||||
/**
|
||||
* MODEL - Generate hash from password
|
||||
*
|
||||
* @param {string} uPassword The user password
|
||||
* @return {Promise<String>} Promise with generated hash
|
||||
*/
|
||||
userSchema.statics.generateHash = function(uPassword) {
|
||||
return bcrypt.hash(uPassword, 10);
|
||||
};
|
||||
|
||||
/**
|
||||
* MODEL - Create a new user
|
||||
*
|
||||
* @param {Object} nUserData User data
|
||||
* @return {Promise} Promise of the create operation
|
||||
*/
|
||||
userSchema.statics.new = function(nUserData) {
|
||||
|
||||
let self = this;
|
||||
|
||||
return self.generateHash(nUserData.password).then((passhash) => {
|
||||
return this.create({
|
||||
_id: db.ObjectId(),
|
||||
email: nUserData.email,
|
||||
firstName: nUserData.firstName,
|
||||
lastName: nUserData.lastName,
|
||||
password: passhash,
|
||||
rights: ['admin']
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* MODEL - Edit a user
|
||||
*
|
||||
* @param {String} userId The user identifier
|
||||
* @param {Object} data The user data
|
||||
* @return {Promise} Promise of the update operation
|
||||
*/
|
||||
userSchema.statics.edit = function(userId, data) {
|
||||
|
||||
let self = this;
|
||||
|
||||
// Change basic info
|
||||
|
||||
let fdata = {
|
||||
email: data.email,
|
||||
firstName: data.firstName,
|
||||
lastName: data.lastName,
|
||||
timezone: data.timezone,
|
||||
lang: data.lang,
|
||||
rights: data.rights
|
||||
};
|
||||
let waitTask = null;
|
||||
|
||||
// Change password?
|
||||
|
||||
if(!_.isEmpty(data.password) && _.trim(data.password) !== '********') {
|
||||
waitTask = self.generateHash(data.password).then((passhash) => {
|
||||
fdata.password = passhash;
|
||||
return fdata;
|
||||
});
|
||||
} else {
|
||||
waitTask = Promise.resolve(fdata);
|
||||
}
|
||||
|
||||
// Update user
|
||||
|
||||
return waitTask.then((udata) => {
|
||||
return this.findByIdAndUpdate(userId, udata, { runValidators: true });
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* MODEL - Delete a user
|
||||
*
|
||||
* @param {String} userId The user ID
|
||||
* @return {Promise} Promise of the delete operation
|
||||
*/
|
||||
userSchema.statics.erase = function(userId) {
|
||||
return this.findByIdAndRemove(userId);
|
||||
};
|
||||
|
||||
module.exports = modb.model('User', userSchema);
|
53
models/mongodb.js
Normal file
53
models/mongodb.js
Normal file
@@ -0,0 +1,53 @@
|
||||
"use strict";
|
||||
|
||||
var modb = require('mongoose'),
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
_ = require('lodash');
|
||||
|
||||
/**
|
||||
* MongoDB module
|
||||
*
|
||||
* @param {Object} appconfig Application config
|
||||
* @return {Object} Mongoose instance
|
||||
*/
|
||||
module.exports = function(appconfig) {
|
||||
|
||||
modb.Promise = require('bluebird');
|
||||
|
||||
let dbModels = {};
|
||||
let dbModelsPath = path.join(ROOTPATH, 'models/db');
|
||||
|
||||
// Event handlers
|
||||
|
||||
modb.connection.on('error', (err) => {
|
||||
winston.error('Failed to connect to MongoDB instance.');
|
||||
});
|
||||
modb.connection.once('open', function() {
|
||||
winston.log('Connected to MongoDB instance.');
|
||||
});
|
||||
|
||||
// Store connection handle
|
||||
|
||||
dbModels.connection = modb.connection;
|
||||
dbModels.ObjectId = modb.Types.ObjectId;
|
||||
|
||||
// Load Models
|
||||
|
||||
fs
|
||||
.readdirSync(dbModelsPath)
|
||||
.filter(function(file) {
|
||||
return (file.indexOf(".") !== 0);
|
||||
})
|
||||
.forEach(function(file) {
|
||||
let modelName = _.upperFirst(_.split(file,'.')[0]);
|
||||
dbModels[modelName] = require(path.join(dbModelsPath, file));
|
||||
});
|
||||
|
||||
// Connect
|
||||
|
||||
dbModels.connectPromise = modb.connect(appconfig.db);
|
||||
|
||||
return dbModels;
|
||||
|
||||
};
|
41
models/redis.js
Normal file
41
models/redis.js
Normal file
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
|
||||
var Redis = require('ioredis'),
|
||||
_ = require('lodash');
|
||||
|
||||
/**
|
||||
* Redis module
|
||||
*
|
||||
* @param {Object} appconfig Application config
|
||||
* @return {Redis} Redis instance
|
||||
*/
|
||||
module.exports = (appconfig) => {
|
||||
|
||||
let rd = null;
|
||||
|
||||
if(_.isArray(appconfig.redis)) {
|
||||
rd = new Redis.Cluster(appconfig.redis, {
|
||||
scaleReads: 'master',
|
||||
redisOptions: {
|
||||
lazyConnect: false
|
||||
}
|
||||
});
|
||||
} else {
|
||||
rd = new Redis(_.defaultsDeep(appconfig.redis), {
|
||||
lazyConnect: false
|
||||
});
|
||||
}
|
||||
|
||||
// Handle connection errors
|
||||
|
||||
rd.on('error', (err) => {
|
||||
winston.error('Failed to connect to Redis instance(s). [err-1]');
|
||||
});
|
||||
|
||||
rd.on('node error', (err) => {
|
||||
winston.error('Failed to connect to Redis instance(s). [err-2]');
|
||||
});
|
||||
|
||||
return rd;
|
||||
|
||||
};
|
Reference in New Issue
Block a user