mirror of https://github.com/Requarks/wiki.git
11 changed files with 140 additions and 295 deletions
Unified 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"; |
"use strict"; |
||||
|
|
||||
var modb = require('mongoose'); |
|
||||
var bcrypt = require('bcryptjs-then'); |
var bcrypt = require('bcryptjs-then'); |
||||
var Promise = require('bluebird'); |
var Promise = require('bluebird'); |
||||
var _ = require('lodash'); |
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