mirror of https://github.com/Requarks/wiki.git
11 changed files with 140 additions and 295 deletions
Split View
Diff Options
-
6.gitignore
-
18config.sample.yml
-
12controllers/auth.js
-
37models/auth.js
-
153models/db/user.js
-
35models/localdata.js
-
60models/loki.js
-
53models/mongodb.js
-
41models/redis.js
-
11package.json
-
9server.js
@ -1,158 +1,9 @@ |
|||
"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({ |
|||
module.exports = { |
|||
|
|||
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); |
|||
}; |
@ -0,0 +1,35 @@ |
|||
"use strict"; |
|||
|
|||
var fs = require('fs'), |
|||
_ = require('lodash'); |
|||
|
|||
/** |
|||
* Local Data Storage |
|||
* |
|||
* @param {Object} appconfig The application configuration |
|||
*/ |
|||
module.exports = (appconfig) => { |
|||
|
|||
// Create DB folder
|
|||
|
|||
try { |
|||
fs.mkdirSync(appconfig.datadir.db); |
|||
} catch (err) { |
|||
if(err.code !== 'EEXIST') { |
|||
winston.error(err); |
|||
process.exit(1); |
|||
} |
|||
} |
|||
|
|||
// Create Uploads folder
|
|||
|
|||
try { |
|||
fs.mkdirSync(appconfig.datadir.uploads); |
|||
} catch (err) { |
|||
if(err.code !== 'EEXIST') { |
|||
winston.error(err); |
|||
process.exit(1); |
|||
} |
|||
} |
|||
|
|||
}; |
@ -0,0 +1,60 @@ |
|||
"use strict"; |
|||
|
|||
var loki = require('lokijs'), |
|||
fs = require("fs"), |
|||
path = require("path"), |
|||
Promise = require('bluebird'), |
|||
_ = require('lodash'); |
|||
|
|||
/** |
|||
* Loki.js module |
|||
* |
|||
* @param {Object} appconfig Application config |
|||
* @return {Object} LokiJS instance |
|||
*/ |
|||
module.exports = function(appconfig) { |
|||
|
|||
let dbReadyResolve; |
|||
let dbReady = new Promise((resolve, reject) => { |
|||
dbReadyResolve = resolve; |
|||
}); |
|||
|
|||
// Initialize Loki.js
|
|||
|
|||
let dbModel = { |
|||
Store: new loki(path.join(appconfig.datadir.db, 'app.db'), { |
|||
env: 'NODEJS', |
|||
autosave: true, |
|||
autosaveInterval: 5000 |
|||
}), |
|||
Models: {}, |
|||
onReady: dbReady |
|||
}; |
|||
|
|||
// Load Models
|
|||
|
|||
let dbModelsPath = path.join(ROOTPATH, 'models/db'); |
|||
|
|||
dbModel.Store.loadDatabase({}, () => { |
|||
|
|||
fs |
|||
.readdirSync(dbModelsPath) |
|||
.filter(function(file) { |
|||
return (file.indexOf(".") !== 0); |
|||
}) |
|||
.forEach(function(file) { |
|||
let modelName = _.upperFirst(_.split(file,'.')[0]); |
|||
dbModel.Models[modelName] = require(path.join(dbModelsPath, file)); |
|||
dbModel[modelName] = dbModel.Store.getCollection(modelName); |
|||
if(!dbModel[modelName]) { |
|||
dbModel[modelName] = dbModel.Store.addCollection(modelName); |
|||
} |
|||
}); |
|||
|
|||
dbReadyResolve(); |
|||
|
|||
}); |
|||
|
|||
return dbModel; |
|||
|
|||
}; |
@ -1,53 +0,0 @@ |
|||
"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; |
|||
|
|||
}; |
@ -1,41 +0,0 @@ |
|||
"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; |
|||
|
|||
}; |
Write
Preview
Loading…
Cancel
Save