summaryrefslogtreecommitdiff
path: root/app.js
diff options
context:
space:
mode:
Diffstat (limited to 'app.js')
-rw-r--r--app.js1110
1 files changed, 556 insertions, 554 deletions
diff --git a/app.js b/app.js
index 67a62540..c68652bb 100644
--- a/app.js
+++ b/app.js
@@ -1,654 +1,656 @@
-//app
-//external modules
-var express = require('express');
-var toobusy = require('toobusy-js');
-var ejs = require('ejs');
-var passport = require('passport');
-var methodOverride = require('method-override');
-var cookieParser = require('cookie-parser');
-var bodyParser = require('body-parser');
+// app
+// external modules
+var express = require('express')
+var toobusy = require('toobusy-js')
+var ejs = require('ejs')
+var passport = require('passport')
+var methodOverride = require('method-override')
+var cookieParser = require('cookie-parser')
+var bodyParser = require('body-parser')
var compression = require('compression')
-var session = require('express-session');
-var SequelizeStore = require('connect-session-sequelize')(session.Store);
-var fs = require('fs');
-var url = require('url');
-var path = require('path');
-var imgur = require('imgur');
-var formidable = require('formidable');
-var morgan = require('morgan');
-var passportSocketIo = require("passport.socketio");
-var helmet = require('helmet');
-var i18n = require('i18n');
-var flash = require('connect-flash');
-var validator = require('validator');
-
-//core
-var config = require("./lib/config.js");
-var logger = require("./lib/logger.js");
-var auth = require("./lib/auth.js");
-var response = require("./lib/response.js");
-var models = require("./lib/models");
-
-//server setup
+var session = require('express-session')
+var SequelizeStore = require('connect-session-sequelize')(session.Store)
+var fs = require('fs')
+var url = require('url')
+var path = require('path')
+var imgur = require('imgur')
+var formidable = require('formidable')
+var morgan = require('morgan')
+var passportSocketIo = require('passport.socketio')
+var helmet = require('helmet')
+var i18n = require('i18n')
+var flash = require('connect-flash')
+var validator = require('validator')
+
+// core
+var config = require('./lib/config.js')
+var logger = require('./lib/logger.js')
+var auth = require('./lib/auth.js')
+var response = require('./lib/response.js')
+var models = require('./lib/models')
+
+// server setup
+var app = express()
+var server = null
if (config.usessl) {
- var ca = (function () {
- var i, len, results;
- results = [];
- for (i = 0, len = config.sslcapath.length; i < len; i++) {
- results.push(fs.readFileSync(config.sslcapath[i], 'utf8'));
- }
- return results;
- })();
- var options = {
- key: fs.readFileSync(config.sslkeypath, 'utf8'),
- cert: fs.readFileSync(config.sslcertpath, 'utf8'),
- ca: ca,
- dhparam: fs.readFileSync(config.dhparampath, 'utf8'),
- requestCert: false,
- rejectUnauthorized: false
- };
- var app = express();
- var server = require('https').createServer(options, app);
+ var ca = (function () {
+ var i, len, results
+ results = []
+ for (i = 0, len = config.sslcapath.length; i < len; i++) {
+ results.push(fs.readFileSync(config.sslcapath[i], 'utf8'))
+ }
+ return results
+ })()
+ var options = {
+ key: fs.readFileSync(config.sslkeypath, 'utf8'),
+ cert: fs.readFileSync(config.sslcertpath, 'utf8'),
+ ca: ca,
+ dhparam: fs.readFileSync(config.dhparampath, 'utf8'),
+ requestCert: false,
+ rejectUnauthorized: false
+ }
+ server = require('https').createServer(options, app)
} else {
- var app = express();
- var server = require('http').createServer(app);
+ server = require('http').createServer(app)
}
-//logger
+// logger
app.use(morgan('combined', {
- "stream": logger.stream
-}));
+ 'stream': logger.stream
+}))
-//socket io
-var io = require('socket.io')(server);
+// socket io
+var io = require('socket.io')(server)
io.engine.ws = new (require('uws').Server)({
- noServer: true,
- perMessageDeflate: false
-});
+ noServer: true,
+ perMessageDeflate: false
+})
-//others
-var realtime = require("./lib/realtime.js");
+// others
+var realtime = require('./lib/realtime.js')
-//assign socket io to realtime
-realtime.io = io;
+// assign socket io to realtime
+realtime.io = io
-//methodOverride
-app.use(methodOverride('_method'));
-
-// create application/json parser
-var jsonParser = bodyParser.json({
- limit: 1024 * 1024 * 10 // 10 mb
-});
+// methodOverride
+app.use(methodOverride('_method'))
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({
- extended: false,
- limit: 1024 * 1024 * 10 // 10 mb
-});
+ extended: false,
+ limit: 1024 * 1024 * 10 // 10 mb
+})
-//session store
+// session store
var sessionStore = new SequelizeStore({
- db: models.sequelize
-});
+ db: models.sequelize
+})
-//compression
-app.use(compression());
+// compression
+app.use(compression())
// use hsts to tell https users stick to this
app.use(helmet.hsts({
- maxAge: 31536000 * 1000, // 365 days
- includeSubdomains: true,
- preload: true
-}));
+ maxAge: 31536000 * 1000, // 365 days
+ includeSubdomains: true,
+ preload: true
+}))
i18n.configure({
- locales: ['en', 'zh', 'fr', 'de', 'ja', 'es', 'el', 'pt', 'it', 'tr', 'ru', 'nl', 'hr', 'pl', 'uk', 'hi', 'sv', 'eo'],
- cookie: 'locale',
- directory: __dirname + '/locales'
-});
+ locales: ['en', 'zh', 'fr', 'de', 'ja', 'es', 'el', 'pt', 'it', 'tr', 'ru', 'nl', 'hr', 'pl', 'uk', 'hi', 'sv', 'eo'],
+ cookie: 'locale',
+ directory: path.join(__dirname, '/locales')
+})
-app.use(cookieParser());
+app.use(cookieParser())
-app.use(i18n.init);
+app.use(i18n.init)
// routes without sessions
// static files
-app.use('/', express.static(__dirname + '/public', { maxAge: config.staticcachetime }));
+app.use('/', express.static(path.join(__dirname, '/public'), { maxAge: config.staticcachetime }))
-//session
+// session
app.use(session({
- name: config.sessionname,
- secret: config.sessionsecret,
- resave: false, //don't save session if unmodified
- saveUninitialized: true, //always create session to ensure the origin
- rolling: true, // reset maxAge on every response
- cookie: {
- maxAge: config.sessionlife
- },
- store: sessionStore
-}));
+ name: config.sessionname,
+ secret: config.sessionsecret,
+ resave: false, // don't save session if unmodified
+ saveUninitialized: true, // always create session to ensure the origin
+ rolling: true, // reset maxAge on every response
+ cookie: {
+ maxAge: config.sessionlife
+ },
+ store: sessionStore
+}))
// session resumption
-var tlsSessionStore = {};
+var tlsSessionStore = {}
server.on('newSession', function (id, data, cb) {
- tlsSessionStore[id.toString('hex')] = data;
- cb();
-});
+ tlsSessionStore[id.toString('hex')] = data
+ cb()
+})
server.on('resumeSession', function (id, cb) {
- cb(null, tlsSessionStore[id.toString('hex')] || null);
-});
+ cb(null, tlsSessionStore[id.toString('hex')] || null)
+})
-//middleware which blocks requests when we're too busy
+// middleware which blocks requests when we're too busy
app.use(function (req, res, next) {
- if (toobusy()) {
- response.errorServiceUnavailable(res);
- } else {
- next();
- }
-});
+ if (toobusy()) {
+ response.errorServiceUnavailable(res)
+ } else {
+ next()
+ }
+})
-app.use(flash());
+app.use(flash())
-//passport
-app.use(passport.initialize());
-app.use(passport.session());
+// passport
+app.use(passport.initialize())
+app.use(passport.session())
+auth.registerAuthMethod()
-//serialize and deserialize
+// serialize and deserialize
passport.serializeUser(function (user, done) {
- logger.info('serializeUser: ' + user.id);
- return done(null, user.id);
-});
+ logger.info('serializeUser: ' + user.id)
+ return done(null, user.id)
+})
passport.deserializeUser(function (id, done) {
- models.User.findOne({
- where: {
- id: id
- }
- }).then(function (user) {
- logger.info('deserializeUser: ' + user.id);
- return done(null, user);
- }).catch(function (err) {
- logger.error(err);
- return done(err, null);
- });
-});
+ models.User.findOne({
+ where: {
+ id: id
+ }
+ }).then(function (user) {
+ logger.info('deserializeUser: ' + user.id)
+ return done(null, user)
+ }).catch(function (err) {
+ logger.error(err)
+ return done(err, null)
+ })
+})
// check uri is valid before going further
-app.use(function(req, res, next) {
- try {
- decodeURIComponent(req.path);
- } catch (err) {
- logger.error(err);
- return response.errorBadRequest(res);
- }
- next();
-});
+app.use(function (req, res, next) {
+ try {
+ decodeURIComponent(req.path)
+ } catch (err) {
+ logger.error(err)
+ return response.errorBadRequest(res)
+ }
+ next()
+})
// redirect url without trailing slashes
-app.use(function(req, res, next) {
- if ("GET" == req.method && req.path.substr(-1) == '/' && req.path.length > 1) {
- var query = req.url.slice(req.path.length);
- var urlpath = req.path.slice(0, -1);
- var serverurl = config.serverurl;
- if (config.urlpath) serverurl = serverurl.slice(0, -(config.urlpath.length + 1));
- res.redirect(301, serverurl + urlpath + query);
- } else {
- next();
- }
-});
+app.use(function (req, res, next) {
+ if (req.method === 'GET' && req.path.substr(-1) === '/' && req.path.length > 1) {
+ var query = req.url.slice(req.path.length)
+ var urlpath = req.path.slice(0, -1)
+ var serverurl = config.serverurl
+ if (config.urlpath) serverurl = serverurl.slice(0, -(config.urlpath.length + 1))
+ res.redirect(301, serverurl + urlpath + query)
+ } else {
+ next()
+ }
+})
// routes need sessions
-//template files
-app.set('views', __dirname + '/public/views');
-//set render engine
-app.engine('ejs', ejs.renderFile);
-//set view engine
-app.set('view engine', 'ejs');
-//get index
-app.get("/", response.showIndex);
-//get 403 forbidden
-app.get("/403", function (req, res) {
- response.errorForbidden(res);
-});
-//get 404 not found
-app.get("/404", function (req, res) {
- response.errorNotFound(res);
-});
-//get 500 internal error
-app.get("/500", function (req, res) {
- response.errorInternalError(res);
-});
-//get status
-app.get("/status", function (req, res, next) {
- realtime.getStatus(function (data) {
- res.set({
- 'Cache-Control': 'private', // only cache by client
- 'X-Robots-Tag': 'noindex, nofollow' // prevent crawling
- });
- res.send(data);
- });
-});
-//get status
-app.get("/temp", function (req, res) {
- var host = req.get('host');
- if (config.alloworigin.indexOf(host) == -1)
- response.errorForbidden(res);
- else {
- var tempid = req.query.tempid;
- if (!tempid)
- response.errorForbidden(res);
- else {
- models.Temp.findOne({
- where: {
- id: tempid
- }
- }).then(function (temp) {
- if (!temp)
- response.errorNotFound(res);
- else {
- res.header("Access-Control-Allow-Origin", "*");
- res.send({
- temp: temp.data
- });
- temp.destroy().catch(function (err) {
- if (err)
- logger.error('remove temp failed: ' + err);
- });
- }
- }).catch(function (err) {
- logger.error(err);
- return response.errorInternalError(res);
- });
+// template files
+app.set('views', path.join(__dirname, '/public/views'))
+// set render engine
+app.engine('ejs', ejs.renderFile)
+// set view engine
+app.set('view engine', 'ejs')
+// get index
+app.get('/', response.showIndex)
+// get 403 forbidden
+app.get('/403', function (req, res) {
+ response.errorForbidden(res)
+})
+// get 404 not found
+app.get('/404', function (req, res) {
+ response.errorNotFound(res)
+})
+// get 500 internal error
+app.get('/500', function (req, res) {
+ response.errorInternalError(res)
+})
+// get status
+app.get('/status', function (req, res, next) {
+ realtime.getStatus(function (data) {
+ res.set({
+ 'Cache-Control': 'private', // only cache by client
+ 'X-Robots-Tag': 'noindex, nofollow' // prevent crawling
+ })
+ res.send(data)
+ })
+})
+// get status
+app.get('/temp', function (req, res) {
+ var host = req.get('host')
+ if (config.alloworigin.indexOf(host) === -1) {
+ response.errorForbidden(res)
+ } else {
+ var tempid = req.query.tempid
+ if (!tempid) {
+ response.errorForbidden(res)
+ } else {
+ models.Temp.findOne({
+ where: {
+ id: tempid
}
+ }).then(function (temp) {
+ if (!temp) {
+ response.errorNotFound(res)
+ } else {
+ res.header('Access-Control-Allow-Origin', '*')
+ res.send({
+ temp: temp.data
+ })
+ temp.destroy().catch(function (err) {
+ if (err) {
+ logger.error('remove temp failed: ' + err)
+ }
+ })
+ }
+ }).catch(function (err) {
+ logger.error(err)
+ return response.errorInternalError(res)
+ })
}
-});
-//post status
-app.post("/temp", urlencodedParser, function (req, res) {
- var host = req.get('host');
- if (config.alloworigin.indexOf(host) == -1)
- response.errorForbidden(res);
- else {
- var data = req.body.data;
- if (!data)
- response.errorForbidden(res);
- else {
- if (config.debug)
- logger.info('SERVER received temp from [' + host + ']: ' + req.body.data);
- models.Temp.create({
- data: data
- }).then(function (temp) {
- if (temp) {
- res.header("Access-Control-Allow-Origin", "*");
- res.send({
- status: 'ok',
- id: temp.id
- });
- } else
- response.errorInternalError(res);
- }).catch(function (err) {
- logger.error(err);
- return response.errorInternalError(res);
- });
+ }
+})
+// post status
+app.post('/temp', urlencodedParser, function (req, res) {
+ var host = req.get('host')
+ if (config.alloworigin.indexOf(host) === -1) {
+ response.errorForbidden(res)
+ } else {
+ var data = req.body.data
+ if (!data) {
+ response.errorForbidden(res)
+ } else {
+ if (config.debug) {
+ logger.info('SERVER received temp from [' + host + ']: ' + req.body.data)
+ }
+ models.Temp.create({
+ data: data
+ }).then(function (temp) {
+ if (temp) {
+ res.header('Access-Control-Allow-Origin', '*')
+ res.send({
+ status: 'ok',
+ id: temp.id
+ })
+ } else {
+ response.errorInternalError(res)
}
+ }).catch(function (err) {
+ logger.error(err)
+ return response.errorInternalError(res)
+ })
}
-});
+ }
+})
-function setReturnToFromReferer(req) {
- var referer = req.get('referer');
- if (!req.session) req.session = {};
- req.session.returnTo = referer;
+function setReturnToFromReferer (req) {
+ var referer = req.get('referer')
+ if (!req.session) req.session = {}
+ req.session.returnTo = referer
}
-//facebook auth
+// facebook auth
if (config.facebook) {
- app.get('/auth/facebook', function (req, res, next) {
- setReturnToFromReferer(req);
- passport.authenticate('facebook')(req, res, next);
- });
- //facebook auth callback
- app.get('/auth/facebook/callback',
+ app.get('/auth/facebook', function (req, res, next) {
+ setReturnToFromReferer(req)
+ passport.authenticate('facebook')(req, res, next)
+ })
+ // facebook auth callback
+ app.get('/auth/facebook/callback',
passport.authenticate('facebook', {
- successReturnToOrRedirect: config.serverurl + '/',
- failureRedirect: config.serverurl + '/'
- }));
+ successReturnToOrRedirect: config.serverurl + '/',
+ failureRedirect: config.serverurl + '/'
+ }))
}
-//twitter auth
+// twitter auth
if (config.twitter) {
- app.get('/auth/twitter', function (req, res, next) {
- setReturnToFromReferer(req);
- passport.authenticate('twitter')(req, res, next);
- });
- //twitter auth callback
- app.get('/auth/twitter/callback',
+ app.get('/auth/twitter', function (req, res, next) {
+ setReturnToFromReferer(req)
+ passport.authenticate('twitter')(req, res, next)
+ })
+ // twitter auth callback
+ app.get('/auth/twitter/callback',
passport.authenticate('twitter', {
- successReturnToOrRedirect: config.serverurl + '/',
- failureRedirect: config.serverurl + '/'
- }));
+ successReturnToOrRedirect: config.serverurl + '/',
+ failureRedirect: config.serverurl + '/'
+ }))
}
-//github auth
+// github auth
if (config.github) {
- app.get('/auth/github', function (req, res, next) {
- setReturnToFromReferer(req);
- passport.authenticate('github')(req, res, next);
- });
- //github auth callback
- app.get('/auth/github/callback',
+ app.get('/auth/github', function (req, res, next) {
+ setReturnToFromReferer(req)
+ passport.authenticate('github')(req, res, next)
+ })
+ // github auth callback
+ app.get('/auth/github/callback',
passport.authenticate('github', {
- successReturnToOrRedirect: config.serverurl + '/',
- failureRedirect: config.serverurl + '/'
- }));
- //github callback actions
- app.get('/auth/github/callback/:noteId/:action', response.githubActions);
+ successReturnToOrRedirect: config.serverurl + '/',
+ failureRedirect: config.serverurl + '/'
+ }))
+ // github callback actions
+ app.get('/auth/github/callback/:noteId/:action', response.githubActions)
}
-//gitlab auth
+// gitlab auth
if (config.gitlab) {
- app.get('/auth/gitlab', function (req, res, next) {
- setReturnToFromReferer(req);
- passport.authenticate('gitlab')(req, res, next);
- });
- //gitlab auth callback
- app.get('/auth/gitlab/callback',
+ app.get('/auth/gitlab', function (req, res, next) {
+ setReturnToFromReferer(req)
+ passport.authenticate('gitlab')(req, res, next)
+ })
+ // gitlab auth callback
+ app.get('/auth/gitlab/callback',
passport.authenticate('gitlab', {
- successReturnToOrRedirect: config.serverurl + '/',
- failureRedirect: config.serverurl + '/'
- }));
- //gitlab callback actions
- app.get('/auth/gitlab/callback/:noteId/:action', response.gitlabActions);
+ successReturnToOrRedirect: config.serverurl + '/',
+ failureRedirect: config.serverurl + '/'
+ }))
+ // gitlab callback actions
+ app.get('/auth/gitlab/callback/:noteId/:action', response.gitlabActions)
}
-//dropbox auth
+// dropbox auth
if (config.dropbox) {
- app.get('/auth/dropbox', function (req, res, next) {
- setReturnToFromReferer(req);
- passport.authenticate('dropbox-oauth2')(req, res, next);
- });
- //dropbox auth callback
- app.get('/auth/dropbox/callback',
+ app.get('/auth/dropbox', function (req, res, next) {
+ setReturnToFromReferer(req)
+ passport.authenticate('dropbox-oauth2')(req, res, next)
+ })
+ // dropbox auth callback
+ app.get('/auth/dropbox/callback',
passport.authenticate('dropbox-oauth2', {
- successReturnToOrRedirect: config.serverurl + '/',
- failureRedirect: config.serverurl + '/'
- }));
+ successReturnToOrRedirect: config.serverurl + '/',
+ failureRedirect: config.serverurl + '/'
+ }))
}
-//google auth
+// google auth
if (config.google) {
- app.get('/auth/google', function (req, res, next) {
- setReturnToFromReferer(req);
- passport.authenticate('google', { scope: ['profile'] })(req, res, next);
- });
- //google auth callback
- app.get('/auth/google/callback',
+ app.get('/auth/google', function (req, res, next) {
+ setReturnToFromReferer(req)
+ passport.authenticate('google', { scope: ['profile'] })(req, res, next)
+ })
+ // google auth callback
+ app.get('/auth/google/callback',
passport.authenticate('google', {
- successReturnToOrRedirect: config.serverurl + '/',
- failureRedirect: config.serverurl + '/'
- }));
+ successReturnToOrRedirect: config.serverurl + '/',
+ failureRedirect: config.serverurl + '/'
+ }))
}
// ldap auth
if (config.ldap) {
- app.post('/auth/ldap', urlencodedParser, function (req, res, next) {
- if (!req.body.username || !req.body.password) return response.errorBadRequest(res);
- setReturnToFromReferer(req);
- passport.authenticate('ldapauth', {
- successReturnToOrRedirect: config.serverurl + '/',
- failureRedirect: config.serverurl + '/',
- failureFlash: true
- })(req, res, next);
- });
+ app.post('/auth/ldap', urlencodedParser, function (req, res, next) {
+ if (!req.body.username || !req.body.password) return response.errorBadRequest(res)
+ setReturnToFromReferer(req)
+ passport.authenticate('ldapauth', {
+ successReturnToOrRedirect: config.serverurl + '/',
+ failureRedirect: config.serverurl + '/',
+ failureFlash: true
+ })(req, res, next)
+ })
}
// email auth
if (config.email) {
- if (config.allowemailregister)
- app.post('/register', urlencodedParser, function (req, res, next) {
- if (!req.body.email || !req.body.password) return response.errorBadRequest(res);
- if (!validator.isEmail(req.body.email)) return response.errorBadRequest(res);
- models.User.findOrCreate({
- where: {
- email: req.body.email
- },
- defaults: {
- password: req.body.password
- }
- }).spread(function (user, created) {
- if (user) {
- if (created) {
- if (config.debug) logger.info('user registered: ' + user.id);
- req.flash('info', "You've successfully registered, please signin.");
- } else {
- if (config.debug) logger.info('user found: ' + user.id);
- req.flash('error', "This email has been used, please try another one.");
- }
- return res.redirect(config.serverurl + '/');
- }
- req.flash('error', "Failed to register your account, please try again.");
- return res.redirect(config.serverurl + '/');
- }).catch(function (err) {
- logger.error('auth callback failed: ' + err);
- return response.errorInternalError(res);
- });
- });
-
- app.post('/login', urlencodedParser, function (req, res, next) {
- if (!req.body.email || !req.body.password) return response.errorBadRequest(res);
- if (!validator.isEmail(req.body.email)) return response.errorBadRequest(res);
- setReturnToFromReferer(req);
- passport.authenticate('local', {
- successReturnToOrRedirect: config.serverurl + '/',
- failureRedirect: config.serverurl + '/',
- failureFlash: 'Invalid email or password.'
- })(req, res, next);
- });
+ if (config.allowemailregister) {
+ app.post('/register', urlencodedParser, function (req, res, next) {
+ if (!req.body.email || !req.body.password) return response.errorBadRequest(res)
+ if (!validator.isEmail(req.body.email)) return response.errorBadRequest(res)
+ models.User.findOrCreate({
+ where: {
+ email: req.body.email
+ },
+ defaults: {
+ password: req.body.password
+ }
+ }).spread(function (user, created) {
+ if (user) {
+ if (created) {
+ if (config.debug) {
+ logger.info('user registered: ' + user.id)
+ }
+ req.flash('info', "You've successfully registered, please signin.")
+ } else {
+ if (config.debug) {
+ logger.info('user found: ' + user.id)
+ }
+ req.flash('error', 'This email has been used, please try another one.')
+ }
+ return res.redirect(config.serverurl + '/')
+ }
+ req.flash('error', 'Failed to register your account, please try again.')
+ return res.redirect(config.serverurl + '/')
+ }).catch(function (err) {
+ logger.error('auth callback failed: ' + err)
+ return response.errorInternalError(res)
+ })
+ })
+ }
+
+ app.post('/login', urlencodedParser, function (req, res, next) {
+ if (!req.body.email || !req.body.password) return response.errorBadRequest(res)
+ if (!validator.isEmail(req.body.email)) return response.errorBadRequest(res)
+ setReturnToFromReferer(req)
+ passport.authenticate('local', {
+ successReturnToOrRedirect: config.serverurl + '/',
+ failureRedirect: config.serverurl + '/',
+ failureFlash: 'Invalid email or password.'
+ })(req, res, next)
+ })
}
-//logout
+// logout
app.get('/logout', function (req, res) {
- if (config.debug && req.isAuthenticated())
- logger.info('user logout: ' + req.user.id);
- req.logout();
- res.redirect(config.serverurl + '/');
-});
-var history = require("./lib/history.js");
-//get history
-app.get('/history', history.historyGet);
-//post history
-app.post('/history', urlencodedParser, history.historyPost);
-//post history by note id
-app.post('/history/:noteId', urlencodedParser, history.historyPost);
-//delete history
-app.delete('/history', history.historyDelete);
-//delete history by note id
-app.delete('/history/:noteId', history.historyDelete);
-//get me info
+ if (config.debug && req.isAuthenticated()) { logger.info('user logout: ' + req.user.id) }
+ req.logout()
+ res.redirect(config.serverurl + '/')
+})
+var history = require('./lib/history.js')
+// get history
+app.get('/history', history.historyGet)
+// post history
+app.post('/history', urlencodedParser, history.historyPost)
+// post history by note id
+app.post('/history/:noteId', urlencodedParser, history.historyPost)
+// delete history
+app.delete('/history', history.historyDelete)
+// delete history by note id
+app.delete('/history/:noteId', history.historyDelete)
+// get me info
app.get('/me', function (req, res) {
- if (req.isAuthenticated()) {
- models.User.findOne({
- where: {
- id: req.user.id
- }
- }).then(function (user) {
- if (!user)
- return response.errorNotFound(res);
- var profile = models.User.getProfile(user);
- res.send({
- status: 'ok',
- id: req.user.id,
- name: profile.name,
- photo: profile.photo
- });
- }).catch(function (err) {
- logger.error('read me failed: ' + err);
- return response.errorInternalError(res);
- });
- } else {
- res.send({
- status: 'forbidden'
- });
- }
-});
-
-//upload image
+ if (req.isAuthenticated()) {
+ models.User.findOne({
+ where: {
+ id: req.user.id
+ }
+ }).then(function (user) {
+ if (!user) { return response.errorNotFound(res) }
+ var profile = models.User.getProfile(user)
+ res.send({
+ status: 'ok',
+ id: req.user.id,
+ name: profile.name,
+ photo: profile.photo
+ })
+ }).catch(function (err) {
+ logger.error('read me failed: ' + err)
+ return response.errorInternalError(res)
+ })
+ } else {
+ res.send({
+ status: 'forbidden'
+ })
+ }
+})
+
+// upload image
app.post('/uploadimage', function (req, res) {
- var form = new formidable.IncomingForm();
+ var form = new formidable.IncomingForm()
- form.keepExtensions = true;
+ form.keepExtensions = true
- if (config.imageUploadType === 'filesystem') {
- form.uploadDir = "public/uploads";
- }
+ if (config.imageUploadType === 'filesystem') {
+ form.uploadDir = 'public/uploads'
+ }
- form.parse(req, function (err, fields, files) {
- if (err || !files.image || !files.image.path) {
- response.errorForbidden(res);
- } else {
- if (config.debug)
- logger.info('SERVER received uploadimage: ' + JSON.stringify(files.image));
-
- try {
- switch (config.imageUploadType) {
- case 'filesystem':
- res.send({
- link: url.resolve(config.serverurl + '/', files.image.path.match(/^public\/(.+$)/)[1])
- });
-
- break;
-
- case 's3':
- var AWS = require('aws-sdk');
- var awsConfig = new AWS.Config(config.s3);
- var s3 = new AWS.S3(awsConfig);
-
- fs.readFile(files.image.path, function (err, buffer) {
- var params = {
- Bucket: config.s3bucket,
- Key: path.join('uploads', path.basename(files.image.path)),
- Body: buffer
- };
-
- s3.putObject(params, function (err, data) {
- if (err) {
- logger.error(err);
- res.status(500).end('upload image error');
- } else {
- res.send({
- link: `https://s3-${config.s3.region}.amazonaws.com/${config.s3bucket}/${params.Key}`
- });
- }
- });
-
- });
-
- break;
-
- case 'imgur':
- default:
- imgur.setClientId(config.imgur.clientID);
- imgur.uploadFile(files.image.path)
- .then(function (json) {
- if (config.debug)
- logger.info('SERVER uploadimage success: ' + JSON.stringify(json));
- res.send({
- link: json.data.link.replace(/^http:\/\//i, 'https://')
- });
- })
- .catch(function (err) {
- logger.error(err);
- return res.status(500).end('upload image error');
- });
- break;
+ form.parse(req, function (err, fields, files) {
+ if (err || !files.image || !files.image.path) {
+ response.errorForbidden(res)
+ } else {
+ if (config.debug) { logger.info('SERVER received uploadimage: ' + JSON.stringify(files.image)) }
+
+ try {
+ switch (config.imageUploadType) {
+ case 'filesystem':
+ res.send({
+ link: url.resolve(config.serverurl + '/', files.image.path.match(/^public\/(.+$)/)[1])
+ })
+
+ break
+
+ case 's3':
+ var AWS = require('aws-sdk')
+ var awsConfig = new AWS.Config(config.s3)
+ var s3 = new AWS.S3(awsConfig)
+
+ fs.readFile(files.image.path, function (err, buffer) {
+ if (err) {
+ logger.error(err)
+ res.status(500).end('upload image error')
+ return
+ }
+ var params = {
+ Bucket: config.s3bucket,
+ Key: path.join('uploads', path.basename(files.image.path)),
+ Body: buffer
+ }
+
+ s3.putObject(params, function (err, data) {
+ if (err) {
+ logger.error(err)
+ res.status(500).end('upload image error')
+ return
}
- } catch (err) {
- logger.error(err);
- return res.status(500).end('upload image error');
- }
+ res.send({
+ link: `https://s3-${config.s3.region}.amazonaws.com/${config.s3bucket}/${params.Key}`
+ })
+ })
+ })
+ break
+ case 'imgur':
+ default:
+ imgur.setClientId(config.imgur.clientID)
+ imgur.uploadFile(files.image.path)
+ .then(function (json) {
+ if (config.debug) { logger.info('SERVER uploadimage success: ' + JSON.stringify(json)) }
+ res.send({
+ link: json.data.link.replace(/^http:\/\//i, 'https://')
+ })
+ })
+ .catch(function (err) {
+ logger.error(err)
+ return res.status(500).end('upload image error')
+ })
+ break
}
- });
-});
-//get new note
-app.get("/new", response.newNote);
-//get publish note
-app.get("/s/:shortid", response.showPublishNote);
-//publish note actions
-app.get("/s/:shortid/:action", response.publishNoteActions);
-//get publish slide
-app.get("/p/:shortid", response.showPublishSlide);
-//publish slide actions
-app.get("/p/:shortid/:action", response.publishSlideActions);
-//get note by id
-app.get("/:noteId", response.showNote);
-//note actions
-app.get("/:noteId/:action", response.noteActions);
-//note actions with action id
-app.get("/:noteId/:action/:actionId", response.noteActions);
+ } catch (err) {
+ logger.error(err)
+ return res.status(500).end('upload image error')
+ }
+ }
+ })
+})
+// get new note
+app.get('/new', response.newNote)
+// get publish note
+app.get('/s/:shortid', response.showPublishNote)
+// publish note actions
+app.get('/s/:shortid/:action', response.publishNoteActions)
+// get publish slide
+app.get('/p/:shortid', response.showPublishSlide)
+// publish slide actions
+app.get('/p/:shortid/:action', response.publishSlideActions)
+// get note by id
+app.get('/:noteId', response.showNote)
+// note actions
+app.get('/:noteId/:action', response.noteActions)
+// note actions with action id
+app.get('/:noteId/:action/:actionId', response.noteActions)
// response not found if no any route matches
app.get('*', function (req, res) {
- response.errorNotFound(res);
-});
+ response.errorNotFound(res)
+})
-//socket.io secure
-io.use(realtime.secure);
-//socket.io auth
+// socket.io secure
+io.use(realtime.secure)
+// socket.io auth
io.use(passportSocketIo.authorize({
- cookieParser: cookieParser,
- key: config.sessionname,
- secret: config.sessionsecret,
- store: sessionStore,
- success: realtime.onAuthorizeSuccess,
- fail: realtime.onAuthorizeFail
-}));
-//socket.io heartbeat
-io.set('heartbeat interval', config.heartbeatinterval);
-io.set('heartbeat timeout', config.heartbeattimeout);
-//socket.io connection
-io.sockets.on('connection', realtime.connection);
-
-//listen
-function startListen() {
- server.listen(config.port, function () {
- var schema = config.usessl ? 'HTTPS' : 'HTTP';
- logger.info('%s Server listening at port %d', schema, config.port);
- config.maintenance = false;
- });
+ cookieParser: cookieParser,
+ key: config.sessionname,
+ secret: config.sessionsecret,
+ store: sessionStore,
+ success: realtime.onAuthorizeSuccess,
+ fail: realtime.onAuthorizeFail
+}))
+// socket.io heartbeat
+io.set('heartbeat interval', config.heartbeatinterval)
+io.set('heartbeat timeout', config.heartbeattimeout)
+// socket.io connection
+io.sockets.on('connection', realtime.connection)
+
+// listen
+function startListen () {
+ server.listen(config.port, function () {
+ var schema = config.usessl ? 'HTTPS' : 'HTTP'
+ logger.info('%s Server listening at port %d', schema, config.port)
+ config.maintenance = false
+ })
}
// sync db then start listen
models.sequelize.sync().then(function () {
- // check if realtime is ready
- if (realtime.isReady()) {
- models.Revision.checkAllNotesRevision(function (err, notes) {
- if (err) throw new Error(err);
- if (!notes || notes.length <= 0) return startListen();
- });
- } else {
- throw new Error('server still not ready after db synced');
- }
-});
+ // check if realtime is ready
+ if (realtime.isReady()) {
+ models.Revision.checkAllNotesRevision(function (err, notes) {
+ if (err) throw new Error(err)
+ if (!notes || notes.length <= 0) return startListen()
+ })
+ } else {
+ throw new Error('server still not ready after db synced')
+ }
+})
// log uncaught exception
process.on('uncaughtException', function (err) {
- logger.error('An uncaught exception has occured.');
- logger.error(err);
- logger.error('Process will exit now.');
- process.exit(1);
-});
+ logger.error('An uncaught exception has occured.')
+ logger.error(err)
+ logger.error('Process will exit now.')
+ process.exit(1)
+})
// install exit handler
-function handleTermSignals() {
- config.maintenance = true;
- // disconnect all socket.io clients
- Object.keys(io.sockets.sockets).forEach(function (key) {
- var socket = io.sockets.sockets[key];
- // notify client server going into maintenance status
- socket.emit('maintenance');
- setTimeout(function () {
- socket.disconnect(true);
- }, 0);
- });
- var checkCleanTimer = setInterval(function () {
- if (realtime.isReady()) {
- models.Revision.checkAllNotesRevision(function (err, notes) {
- if (err) return logger.error(err);
- if (!notes || notes.length <= 0) {
- clearInterval(checkCleanTimer);
- return process.exit(0);
- }
- });
+function handleTermSignals () {
+ config.maintenance = true
+ // disconnect all socket.io clients
+ Object.keys(io.sockets.sockets).forEach(function (key) {
+ var socket = io.sockets.sockets[key]
+ // notify client server going into maintenance status
+ socket.emit('maintenance')
+ setTimeout(function () {
+ socket.disconnect(true)
+ }, 0)
+ })
+ var checkCleanTimer = setInterval(function () {
+ if (realtime.isReady()) {
+ models.Revision.checkAllNotesRevision(function (err, notes) {
+ if (err) return logger.error(err)
+ if (!notes || notes.length <= 0) {
+ clearInterval(checkCleanTimer)
+ return process.exit(0)
}
- }, 100);
+ })
+ }
+ }, 100)
}
-process.on('SIGINT', handleTermSignals);
-process.on('SIGTERM', handleTermSignals);
+process.on('SIGINT', handleTermSignals)
+process.on('SIGTERM', handleTermSignals)