Base Project Files
This commit is contained in:
		
							
								
								
									
										17
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | # Auto detect text files and perform LF normalization | ||||||
|  | * text=auto | ||||||
|  |  | ||||||
|  | # Custom for Visual Studio | ||||||
|  | *.cs     diff=csharp | ||||||
|  |  | ||||||
|  | # Standard to msysgit | ||||||
|  | *.doc	 diff=astextplain | ||||||
|  | *.DOC	 diff=astextplain | ||||||
|  | *.docx diff=astextplain | ||||||
|  | *.DOCX diff=astextplain | ||||||
|  | *.dot  diff=astextplain | ||||||
|  | *.DOT  diff=astextplain | ||||||
|  | *.pdf  diff=astextplain | ||||||
|  | *.PDF	 diff=astextplain | ||||||
|  | *.rtf	 diff=astextplain | ||||||
|  | *.RTF	 diff=astextplain | ||||||
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -26,6 +26,9 @@ coverage | |||||||
| # Compiled binary addons (http://nodejs.org/api/addons.html) | # Compiled binary addons (http://nodejs.org/api/addons.html) | ||||||
| build/Release | build/Release | ||||||
|  |  | ||||||
|  | # Deployment builds | ||||||
|  | dist | ||||||
|  |  | ||||||
| # Dependency directories | # Dependency directories | ||||||
| node_modules | node_modules | ||||||
| jspm_packages | jspm_packages | ||||||
| @@ -35,3 +38,9 @@ jspm_packages | |||||||
|  |  | ||||||
| # Optional REPL history | # Optional REPL history | ||||||
| .node_repl_history | .node_repl_history | ||||||
|  |  | ||||||
|  | # SublimeText Files | ||||||
|  | *.sublime-workspace | ||||||
|  |  | ||||||
|  | # Config Files | ||||||
|  | config.yml | ||||||
							
								
								
									
										4
									
								
								.snyk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.snyk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | failThreshold: high | ||||||
|  | version: v1.5.2 | ||||||
|  | ignore: {} | ||||||
|  | patch: {} | ||||||
							
								
								
									
										30
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | language: node_js | ||||||
|  | node_js: | ||||||
|  | - '6' | ||||||
|  | - '5' | ||||||
|  | - '4.4' | ||||||
|  | services: | ||||||
|  | - redis-server | ||||||
|  | - mongodb | ||||||
|  | cache: | ||||||
|  |   directories: | ||||||
|  |   - node_modules | ||||||
|  | before_script: | ||||||
|  | - npm install -g snyk | ||||||
|  | before_deploy: | ||||||
|  | - npm install -g gulp | ||||||
|  | - gulp deploy | ||||||
|  | - snyk auth $SNYK_TOKEN | ||||||
|  | - snyk monitor | ||||||
|  | deploy: | ||||||
|  |   provider: releases | ||||||
|  |   file: | ||||||
|  |   - dist/requarks-wiki.zip | ||||||
|  |   - dist/requarks-wiki.tar.gz | ||||||
|  |   skip_cleanup: true | ||||||
|  |   overwrite: true | ||||||
|  |   on: | ||||||
|  |     branch: master | ||||||
|  |     repo: requarks/wiki | ||||||
|  |     tags: true | ||||||
|  |     node: '6' | ||||||
							
								
								
									
										54
									
								
								config.sample.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								config.sample.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | ################################################### | ||||||
|  | # REQUARKS WIKI - CONFIGURATION                   # | ||||||
|  | ################################################### | ||||||
|  |  | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Title of this site | ||||||
|  | # ------------------------------------------------- | ||||||
|  |  | ||||||
|  | title: Wiki | ||||||
|  |  | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Full path to the site, without the trailing slash | ||||||
|  | # ------------------------------------------------- | ||||||
|  |  | ||||||
|  | host: http://localhost | ||||||
|  |  | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Port the server should listen to (80 by default) | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # To use process.env.PORT, comment the line below: | ||||||
|  |  | ||||||
|  | port: 80 | ||||||
|  |  | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # MongoDB Connection String | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Full explanation + examples in the documentation (https://opsstatus.readme.io/) | ||||||
|  |  | ||||||
|  | db: mongodb://localhost/wiki | ||||||
|  |  | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Redis Connection Info | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Full explanation + examples in the documentation (https://opsstatus.readme.io/) | ||||||
|  |  | ||||||
|  | redis: | ||||||
|  |   host: localhost | ||||||
|  |   port: 6379 | ||||||
|  |   db: 0 | ||||||
|  |  | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Secret key to use when encrypting sessions | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Use a long and unique random string (256-bit keys are perfect!) | ||||||
|  |  | ||||||
|  | sessionSecret: 1234567890abcdefghijklmnopqrstuvxyz | ||||||
|  |  | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Administrator email | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # An account will be created using the email specified here. | ||||||
|  | # The password is set to "admin123" by default. Change it immediately upon login!!! | ||||||
|  |  | ||||||
|  | admin: admin@company.com | ||||||
							
								
								
									
										94
									
								
								gulpfile.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								gulpfile.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | var gulp = require("gulp"); | ||||||
|  | var merge = require('merge-stream'); | ||||||
|  | var babel = require("gulp-babel"); | ||||||
|  | var uglify = require('gulp-uglify'); | ||||||
|  | var concat = require('gulp-concat'); | ||||||
|  | var nodemon = require('gulp-nodemon'); | ||||||
|  | var plumber = require('gulp-plumber'); | ||||||
|  | var zip = require('gulp-zip'); | ||||||
|  | var tar = require('gulp-tar'); | ||||||
|  | var gzip = require('gulp-gzip'); | ||||||
|  | var sass = require('gulp-sass'); | ||||||
|  | var cleanCSS = require('gulp-clean-css'); | ||||||
|  | var include = require("gulp-include"); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Paths | ||||||
|  |  * | ||||||
|  |  * @type       {Object} | ||||||
|  |  */ | ||||||
|  | var paths = { | ||||||
|  | 	scriptlibs: { | ||||||
|  |  | ||||||
|  | 	}, | ||||||
|  | 	scriptapps: [ | ||||||
|  | 		'./client/js/components/*.js', | ||||||
|  | 		'./client/js/app.js' | ||||||
|  | 	], | ||||||
|  | 	scriptappswatch: [ | ||||||
|  | 		'./client/js/**/*.js' | ||||||
|  | 	], | ||||||
|  | 	csslibs: [ | ||||||
|  |  | ||||||
|  | 	], | ||||||
|  | 	cssapps: [ | ||||||
|  | 		'./client/css/app.scss' | ||||||
|  | 	], | ||||||
|  | 	cssappswatch: [ | ||||||
|  | 		'./client/css/**/*.scss' | ||||||
|  | 	], | ||||||
|  | 	fonts: [ | ||||||
|  | 		'./node_modules/font-awesome/fonts/*-webfont.*', | ||||||
|  | 		'!./node_modules/font-awesome/fonts/*-webfont.svg' | ||||||
|  | 	], | ||||||
|  | 	deploypackage: [ | ||||||
|  | 		'./**/*', | ||||||
|  | 		'!node_modules', '!node_modules/**', | ||||||
|  | 		'!coverage', '!coverage/**', | ||||||
|  | 		'!client/js', '!client/js/**', | ||||||
|  | 		'!dist', '!dist/**', | ||||||
|  | 		'!tests', '!tests/**', | ||||||
|  | 		'!gulpfile.js', '!inch.json', '!config.json', '!wiki.sublime-project' | ||||||
|  | 	] | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * TASK - Starts server in development mode | ||||||
|  |  */ | ||||||
|  | gulp.task('server', ['scripts', 'css', 'fonts'], function() { | ||||||
|  | 	nodemon({ | ||||||
|  | 		script: './server', | ||||||
|  | 		ignore: ['public/', 'client/', 'tests/'], | ||||||
|  | 		ext: 'js json', | ||||||
|  | 		env: { 'NODE_ENV': 'development' } | ||||||
|  | 	}); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * TASK - Start dev watchers | ||||||
|  |  */ | ||||||
|  | gulp.task('watch', function() { | ||||||
|  | 	gulp.watch([paths.scriptappswatch], ['scripts-app']); | ||||||
|  | 	gulp.watch([paths.cssappswatch], ['css-app']); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * TASK - Starts development server with watchers | ||||||
|  |  */ | ||||||
|  | gulp.task('default', ['watch', 'server']); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * TASK - Creates deployment packages | ||||||
|  |  */ | ||||||
|  | gulp.task('deploy', ['scripts', 'css', 'fonts'], function() { | ||||||
|  | 	var zipStream = gulp.src(paths.deploypackage) | ||||||
|  | 		.pipe(zip('requarks-wiki.zip')) | ||||||
|  | 		.pipe(gulp.dest('dist')); | ||||||
|  |  | ||||||
|  | 	var targzStream = gulp.src(paths.deploypackage) | ||||||
|  | 		.pipe(tar('requarks-wiki.tar')) | ||||||
|  | 		.pipe(gzip()) | ||||||
|  | 		.pipe(gulp.dest('dist')); | ||||||
|  |  | ||||||
|  | 	return merge(zipStream, targzStream); | ||||||
|  | }); | ||||||
							
								
								
									
										10
									
								
								inch.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								inch.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | { | ||||||
|  |   "files": { | ||||||
|  |     "included": [ | ||||||
|  |       "controllers/**/*.js", | ||||||
|  |       "middlewares/**/*.js", | ||||||
|  |       "models/**/*.js", | ||||||
|  |     ], | ||||||
|  |     "excluded": [] | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								locales/en/common.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								locales/en/common.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | { | ||||||
|  | 	"wiki": "Wiki", | ||||||
|  | 	"headers": { | ||||||
|  | 		"overview": "Overview" | ||||||
|  | 	}, | ||||||
|  | 	"footer": { | ||||||
|  | 		"poweredby": "Powered by", | ||||||
|  | 		"home": "Home", | ||||||
|  | 		"admin": "Administration" | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								locales/fr/common.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								locales/fr/common.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | { | ||||||
|  | 	"wiki": "Wiki", | ||||||
|  | 	"headers": { | ||||||
|  | 		"overview": "Vue d'ensemble" | ||||||
|  | 	}, | ||||||
|  | 	"footer": { | ||||||
|  | 		"poweredby": "Propulsé par", | ||||||
|  | 		"home": "Accueil", | ||||||
|  | 		"admin": "Administration" | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								middlewares/auth.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								middlewares/auth.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | var Promise = require('bluebird'), | ||||||
|  | 	moment = require('moment-timezone'); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Authentication middleware | ||||||
|  |  * | ||||||
|  |  * @param      {Express Request}   req     Express Request object | ||||||
|  |  * @param      {Express Response}  res     Express Response object | ||||||
|  |  * @param      {Function}          next    Next callback function | ||||||
|  |  * @return     {any}               void | ||||||
|  |  */ | ||||||
|  | module.exports = (req, res, next) => { | ||||||
|  |  | ||||||
|  | 	// Is user authenticated ? | ||||||
|  |  | ||||||
|  | 	if (!req.isAuthenticated()) { | ||||||
|  | 		return res.redirect('/login'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Set i18n locale | ||||||
|  |  | ||||||
|  | 	req.i18n.changeLanguage(req.user.lang); | ||||||
|  | 	res.locals.userMoment = moment; | ||||||
|  | 	res.locals.userMoment.locale(req.user.lang); | ||||||
|  |  | ||||||
|  | 	// Expose user data | ||||||
|  |  | ||||||
|  | 	res.locals.user = req.user; | ||||||
|  |  | ||||||
|  | 	return next(); | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										28
									
								
								middlewares/security.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								middlewares/security.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | /** | ||||||
|  |  * Security Middleware | ||||||
|  |  * | ||||||
|  |  * @param      {Express Request}   req     Express request object | ||||||
|  |  * @param      {Express Response}  res     Express response object | ||||||
|  |  * @param      {Function}          next    next callback function | ||||||
|  |  * @return     {any}               void | ||||||
|  |  */ | ||||||
|  | module.exports = function(req, res, next) { | ||||||
|  |  | ||||||
|  | 	//-> Disable X-Powered-By | ||||||
|  | 	app.disable('x-powered-by'); | ||||||
|  |  | ||||||
|  | 	//-> Disable Frame Embedding | ||||||
|  | 	res.set('X-Frame-Options', 'deny'); | ||||||
|  |  | ||||||
|  | 	//-> Re-enable XSS Fitler if disabled | ||||||
|  | 	res.set('X-XSS-Protection', '1; mode=block'); | ||||||
|  |  | ||||||
|  | 	//-> Disable MIME-sniffing | ||||||
|  | 	res.set('X-Content-Type-Options', 'nosniff'); | ||||||
|  |  | ||||||
|  | 	//-> Disable IE Compatibility Mode | ||||||
|  | 	res.set('X-UA-Compatible', 'IE=edge'); | ||||||
|  |  | ||||||
|  | 	return next(); | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										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; | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										95
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | { | ||||||
|  |   "name": "wiki", | ||||||
|  |   "version": "1.0.0", | ||||||
|  |   "description": "A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown", | ||||||
|  |   "main": "server.js", | ||||||
|  |   "scripts": { | ||||||
|  |     "start": "node server", | ||||||
|  |     "dev": "gulp", | ||||||
|  |     "test": "snyk test && istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec ./tests/index.js && cat ./coverage/lcov.info | ./node_modules/.bin/codacy-coverage && rm -rf ./coverage" | ||||||
|  |   }, | ||||||
|  |   "repository": { | ||||||
|  |     "type": "git", | ||||||
|  |     "url": "git+https://github.com/Requarks/wiki.git" | ||||||
|  |   }, | ||||||
|  |   "keywords": [ | ||||||
|  |     "wiki", | ||||||
|  |     "wikis", | ||||||
|  |     "docs", | ||||||
|  |     "documentation", | ||||||
|  |     "markdown", | ||||||
|  |     "guides" | ||||||
|  |   ], | ||||||
|  |   "author": "Nicolas Giard", | ||||||
|  |   "license": "AGPL-3.0", | ||||||
|  |   "bugs": { | ||||||
|  |     "url": "https://github.com/Requarks/wiki/issues" | ||||||
|  |   }, | ||||||
|  |   "homepage": "https://github.com/Requarks/wiki#readme", | ||||||
|  |   "engines": { | ||||||
|  |     "node": ">=4.4.5" | ||||||
|  |   }, | ||||||
|  |   "dependencies": { | ||||||
|  |     "auto-load": "^2.1.0", | ||||||
|  |     "bluebird": "^3.4.1", | ||||||
|  |     "body-parser": "^1.15.2", | ||||||
|  |     "compression": "^1.6.2", | ||||||
|  |     "connect-flash": "^0.1.1", | ||||||
|  |     "connect-redis": "^3.1.0", | ||||||
|  |     "cookie-parser": "^1.4.3", | ||||||
|  |     "express": "^4.14.0", | ||||||
|  |     "express-brute": "^0.7.0-beta.0", | ||||||
|  |     "express-brute-redis": "0.0.1", | ||||||
|  |     "express-session": "^1.14.0", | ||||||
|  |     "express-validator": "^2.20.8", | ||||||
|  |     "gridlex": "^2.1.1", | ||||||
|  |     "i18next": "^3.4.1", | ||||||
|  |     "i18next-express-middleware": "^1.0.1", | ||||||
|  |     "i18next-node-fs-backend": "^0.1.2", | ||||||
|  |     "ioredis": "^2.3.0", | ||||||
|  |     "js-yaml": "^3.6.1", | ||||||
|  |     "lodash": "^4.15.0", | ||||||
|  |     "markdown-it": "^7.0.1", | ||||||
|  |     "moment": "^2.14.1", | ||||||
|  |     "moment-timezone": "^0.5.5", | ||||||
|  |     "mongoose": "^4.5.9", | ||||||
|  |     "mongoose-delete": "^0.3.4", | ||||||
|  |     "node-bcrypt": "0.0.1", | ||||||
|  |     "passport": "^0.3.2", | ||||||
|  |     "passport-local": "^1.0.0", | ||||||
|  |     "pug": "^2.0.0-beta5", | ||||||
|  |     "serve-favicon": "^2.3.0", | ||||||
|  |     "simplemde": "^1.11.2", | ||||||
|  |     "validator": "^5.5.0", | ||||||
|  |     "validator-as-promised": "^1.0.2", | ||||||
|  |     "winston": "^2.2.0" | ||||||
|  |   }, | ||||||
|  |   "devDependencies": { | ||||||
|  |     "babel-preset-es2015": "^6.13.2", | ||||||
|  |     "chai": "^3.5.0", | ||||||
|  |     "chai-as-promised": "^5.3.0", | ||||||
|  |     "codacy-coverage": "^2.0.0", | ||||||
|  |     "font-awesome": "^4.6.3", | ||||||
|  |     "gridlex": "^2.1.1", | ||||||
|  |     "gulp": "^3.9.1", | ||||||
|  |     "gulp-babel": "^6.1.2", | ||||||
|  |     "gulp-clean-css": "^2.0.12", | ||||||
|  |     "gulp-concat": "^2.6.0", | ||||||
|  |     "gulp-gzip": "^1.4.0", | ||||||
|  |     "gulp-include": "^2.3.1", | ||||||
|  |     "gulp-nodemon": "^2.1.0", | ||||||
|  |     "gulp-plumber": "^1.1.0", | ||||||
|  |     "gulp-sass": "^2.3.2", | ||||||
|  |     "gulp-tar": "^1.9.0", | ||||||
|  |     "gulp-uglify": "^2.0.0", | ||||||
|  |     "gulp-zip": "^3.2.0", | ||||||
|  |     "istanbul": "^0.4.4", | ||||||
|  |     "jquery": "^3.1.0", | ||||||
|  |     "merge-stream": "^1.0.0", | ||||||
|  |     "mocha": "^3.0.2", | ||||||
|  |     "mocha-lcov-reporter": "^1.2.0", | ||||||
|  |     "nodemon": "^1.10.0", | ||||||
|  |     "snyk": "^1.18.0", | ||||||
|  |     "vue": "^1.0.26" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								server.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								server.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | // =========================================== | ||||||
|  | // REQUARKS WIKI | ||||||
|  | // 1.0.0 | ||||||
|  | // Licensed under AGPLv3 | ||||||
|  | // =========================================== | ||||||
|  |  | ||||||
|  | // ---------------------------------------- | ||||||
|  | // Load modules | ||||||
|  | // ---------------------------------------- | ||||||
|  |  | ||||||
|  | global.winston = require('winston'); | ||||||
|  | winston.info('Requarks Wiki is initializing...'); | ||||||
|  |  | ||||||
|  | global.ROOTPATH = __dirname; | ||||||
|  |  | ||||||
|  | var appconfig = require('./models/config')('./config.yml'); | ||||||
|  | global.db = require('./models/db')(appconfig); | ||||||
|  | global.red = require('./models/redis')(appconfig); | ||||||
							
								
								
									
										11
									
								
								tests/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								tests/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | let path = require('path'), | ||||||
|  | 	 fs = require('fs'); | ||||||
|  |  | ||||||
|  | // ======================================== | ||||||
|  | // Load global modules | ||||||
|  | // ======================================== | ||||||
|  |  | ||||||
|  | global._ = require('lodash'); | ||||||
|  | global.winston = require('winston'); | ||||||
							
								
								
									
										12
									
								
								wiki.sublime-project
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								wiki.sublime-project
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | { | ||||||
|  | 	"folders": | ||||||
|  | 	[ | ||||||
|  | 		{ | ||||||
|  | 			"file_exclude_patterns": | ||||||
|  | 			[ | ||||||
|  | 				"wiki.sublime-project" | ||||||
|  | 			], | ||||||
|  | 			"path": "." | ||||||
|  | 		} | ||||||
|  | 	] | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user