diff --git a/config/default.json b/config/default.json index 4acd176..a3b3dd1 100644 --- a/config/default.json +++ b/config/default.json @@ -1,7 +1,10 @@ { - "host" : "localhost:8000", - "login_path" : "localhost:8000/dev_login", - "secret" : "secretsecret", - "admin_key" : "adminadmin", - "log_level" : "info" + "log_level" : "info", + "login_path" : "/dev/login", + "jwt_secret" : "secretsecret", + "admin" : { + "user" : "admin", + "pass" : "password", + "key" : "adminadminadmin" + } } \ No newline at end of file diff --git a/server/admin.api.js b/server/admin.api.js index 8e4376c..cbf7808 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -1,85 +1,32 @@ const _ = require('lodash'); -const auth = require('basic-auth'); -const HomebrewModel = require('./homebrew.model.js').model; const router = require('express').Router(); - - -const mw = { - adminOnly : (req, res, next)=>{ - if(req.query && req.query.admin_key == process.env.ADMIN_KEY) return next(); - return res.status(401).send('Access denied'); - } -}; - -process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin'; -process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password'; -process.env.ADMIN_KEY = process.env.ADMIN_KEY || 'admin_key'; - - - -//Removes all empty brews that are older than 3 days and that are shorter than a tweet -router.get('/api/invalid', mw.adminOnly, (req, res)=>{ - const invalidBrewQuery = HomebrewModel.find({ - '$where' : "this.text.length < 140", - createdAt: { - $lt: Moment().subtract(3, 'days').toDate() - } - }); - - if(req.query.do_it){ - invalidBrewQuery.remove().exec((err, objs)=>{ - refreshCount(); - return res.send(200); - }) - }else{ - invalidBrewQuery.exec((err, objs)=>{ - if(err) console.log(err); - return res.json({ - count : objs.length - }) - }) - } -}); - -router.get('/admin/lookup/:id', mw.adminOnly, (req, res, next) => { - //search for mathcing edit id - //search for matching share id - // search for partial match - - HomebrewModel.findOne({ $or:[ - {editId : { "$regex": req.params.id, "$options": "i" }}, - {shareId : { "$regex": req.params.id, "$options": "i" }}, - ]}).exec((err, brew) => { - return res.json(brew); - }); -}); - - - -//Admin route - -const render = require('vitreum/steps/render'); +const vitreumRender = require('vitreum/steps/render'); const templateFn = require('../client/template.js'); -router.get('/admin', function(req, res){ - const credentials = auth(req) - if (!credentials || credentials.name !== process.env.ADMIN_USER || credentials.pass !== process.env.ADMIN_PASS) { - res.setHeader('WWW-Authenticate', 'Basic realm="example"') - return res.status(401).send('Access denied') - } - render('admin', templateFn, { - url: req.originalUrl, - admin_key : process.env.ADMIN_KEY, +const config = require('nconf'); + +const mw = require('./middleware.js'); +const BrewData = require('./brew.data.js'); + +router.get('/admin', mw.adminLogin, (req, res) => { + return vitreumRender('admin', templateFn, { + url : req.originalUrl, + admin_key : config.get('admin"key') }) .then((page) => { return res.send(page) }) - .catch((err) => { - console.log(err); - return res.sendStatus(500); - }); + .catch(next); }); - - +//Removes all empty brews that are older than 3 days and that are shorter than a tweet +router.del('/admin/invalid', mw.adminOnly, (req, res)=>{ + BrewData.removeInvalid(!!req.query.do_it) + .then((removedCount) => { + return res.join({ + count : removedCount + }); + }) + .catch(next); +}); module.exports = router; \ No newline at end of file diff --git a/server/app.js b/server/app.js index 0ad6559..12b59ec 100644 --- a/server/app.js +++ b/server/app.js @@ -1,3 +1,4 @@ +const config = require('nconf'); const express = require("express"); const app = express(); @@ -13,10 +14,13 @@ app.use(mw.admin); //Routes -app.use(require('./brew.api.js')); app.use(require('./interface.routes.js')); +app.use(require('./brew.api.js')); //app.use(require('./admin.api.js')); +if(config.get('NODE_ENV') !== 'staging' && config.get('NODE_ENV') !== 'production'){ + app.use(require('./dev.routes.js')); +} //Error Handler app.use(require('./error.js').expressHandler); diff --git a/server/brew.data.js b/server/brew.data.js index 003205e..2eeae00 100644 --- a/server/brew.data.js +++ b/server/brew.data.js @@ -90,6 +90,21 @@ const BrewData = { return BrewData.get({ editId }); }, + //Removes all empty brews that are older than 3 days and that are shorter than a tweet + removeInvalid : (force = false) => { + const invalidBrewQuery = Brew.find({ + '$where' : "this.text.length < 140", + createdAt: { + $lt: Moment().subtract(3, 'days').toDate() + } + }); + if(force) return invalidBrewQuery.remove().exec(); + return invalidBrewQuery.exec() + .then((objs) => { + return objs.length; + }); + }, + search : (query, req={}) => { //defaults with page and count //returns a non-text version of brews diff --git a/server/dev.routes.js b/server/dev.routes.js new file mode 100644 index 0000000..acbee9d --- /dev/null +++ b/server/dev.routes.js @@ -0,0 +1,12 @@ +const router = require('express').Router(); + + + + + + + + + + +module.exports = router; \ No newline at end of file diff --git a/server/error.js b/server/error.js index 7fd3772..a85bd0b 100644 --- a/server/error.js +++ b/server/error.js @@ -3,6 +3,7 @@ const Error = require('egads').extend('Server Error', 500, 'Generic Server Error Error.noBrew = Error.extend('Can not find a brew with that id', 404, 'No Brew Found'); Error.noAuth = Error.extend('You can not access this route', 401, 'Unauthorized'); +Error.noAdmin = Error.extend('You need admin credentials to access this route', 401, 'Unauthorized'); Error.expressHandler = (err, req, res, next) => { diff --git a/server/middleware.js b/server/middleware.js index 970f4af..4f72236 100644 --- a/server/middleware.js +++ b/server/middleware.js @@ -1,5 +1,6 @@ const _ = require('lodash'); const jwt = require('jwt-simple'); +const auth = require('basic-auth'); const config = require('nconf'); const Error = require('./error.js'); @@ -9,13 +10,13 @@ const Middleware = { account : (req, res, next) => { if(req.cookies && req.cookies.nc_session){ try{ - req.account = jwt.decode(req.cookies.nc_session, config.get('secret')); + req.account = jwt.decode(req.cookies.nc_session, config.get('jwt_secret')); }catch(e){} } return next(); }, admin : (req, res, next) => { - if(req.query.admin_key === config.get('admin_key')){ + if(req.query.admin_key === config.get('admin:key')){ req.admin = true; } return next(); @@ -31,6 +32,15 @@ const Middleware = { if(req.admin) return next(); return next(Error.noAuth()); }, + adminLogin : (req, res, next) => { + const creds = auth(req); + if(!creds + || creds.name !== config.get('admin:user') + || creds.pass !== config.get('admin:pass')){ + return next(Error.noAdmin()); + } + return next(); + }, //Loaders diff --git a/test/api.test.js b/test/api.test.js index 93e353c..822683c 100644 --- a/test/api.test.js +++ b/test/api.test.js @@ -24,7 +24,7 @@ describe('Brew API', () => { before('Connect DB', DB.connect); before('Clear DB', BrewData.removeAll); before('Create session token', () => { - session_token = jwt.encode(test_user, config.get('secret')); + session_token = jwt.encode(test_user, config.get('jwt_secret')); }); before('Create brew', ()=>{ return BrewData.create(storedBrew) diff --git a/test/middleware.test.js b/test/middleware.test.js index 8bee892..88a9fad 100644 --- a/test/middleware.test.js +++ b/test/middleware.test.js @@ -14,6 +14,9 @@ const requestHandler = (req, res) => { return res.status(200).json(_.pick(req, ['brew', 'account', 'admin', 'params', 'query', 'body'])); }; + +console.log(config.get('admin:key')); + const test_user = { username : 'cool guy' }; @@ -23,7 +26,7 @@ describe('Middleware', () => { let session_token = ''; before('create session token', () => { - session_token = jwt.encode(test_user, config.get('secret')); + session_token = jwt.encode(test_user, config.get('jwt_secret')); }); beforeEach('setup test server', ()=>{ app = require('express')(); @@ -102,7 +105,7 @@ describe('Middleware', () => { it('should detect when you use the admin key', () => { app.use(mw.admin); app.use(requestHandler) - return request(app).get(`/?admin_key=${config.get('admin_key')}`) + return request(app).get(`/?admin_key=${config.get('admin:key')}`) .send() .expect(200) .then((res) => { @@ -113,12 +116,30 @@ describe('Middleware', () => { it('should block you if you are not an admin', ()=>{ app.use(mw.admin); app.use(mw.adminOnly); - app.get('/', (req, res) => { return res.status(200).send(); }); + app.get(requestHandler); app.use(Error.expressHandler); return request(app).get(`/?admin_key=BADKEY`) .send() .expect(401); }); + + it('should let your through witch basic auth', () => { + app.use(mw.adminLogin); + app.use(requestHandler); + return request(app).get('/') + .auth(config.get('admin:user'), config.get('admin:pass')) + .send() + .expect(200); + }); + it('should block you if basic auth is wrong', () => { + app.use(mw.adminAuth); + app.use(requestHandler); + app.use(Error.expressHandler); + return request(app).get('/') + .auth('baduser', 'badpassword') + .send() + .expect(401); + }); }); });