import * as DataEvent from '../../../src/com/events/DataEvent'; import mdparser from 'markdown-yaml-metadata-parser'; const uuidv4 = require('uuid/v4'); const express = require('express'); const router = express.Router(); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); const fs = require('fs-extra'); const _ = require('lodash'); const crypto = require('crypto'); // for setting up new accounts const secret_key = '58d5aeec3c604e2837aef70bc1606f35131ab8fea9731925558f5acfaa00da60'; const moment = require('moment'); /** * Get Auth Status */ router.get('/', function (req, res) { var token = req.headers['x-access-token']; if (!token) return res.status(401).send({ auth: false, message: 'No token provided.' }); jwt.verify(token, 'super-secret-string', function (err, decoded) { if (err) return res.status(500).send({ auth: false, message: 'Failed to authenticate token.' }); res.status(200).send(decoded); }); }); /** * Get Auth Status */ router.get('/status', function (req, res) { if (req.session.user) { let session = req.session; res.json({ type: DataEvent.API_REQUEST_GOOD, message: 'Auth is Good', token: session.hashToken }); } else { res.json({ type: DataEvent.API_REQUEST_LAME, message: 'NOT AUTHORIZED' }); } }); /** * Login Member and return token */ router.post('/login', function (req, res) { fs.readJson('site/folks.json').then(folks => { let found = _.find(folks, { handle: req.body.handle }); if (found) { if (!isValidPassword(found, req.body.password)) { res.json({ type: DataEvent.REQUEST_LAME, message: 'CHECK YOUR PASSWORD' }); } let token = jwt.sign({ id: found.id }, found.key, { expiresIn: 86400 // expires in 24 hours }); let session = req.session; session.user = found; session.token = token; session.hashToken = hashToken(token); res.json({ type: DataEvent.REQUEST_GOOD, message: 'Welcome Back', token: session.hashToken }); } else { res.json({ type: DataEvent.REQUEST_LAME, message: 'Need to see some id, champ.' }); } }); }); /** * Initial Site Setup */ router.post('/init', function (req, res) { let body = req.body; let re = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; // check email if (!re.test(body.new_member_email)) { res.json({ type: DataEvent.API_INIT_LAME, message: 'Need a valid email address' }); } //check handle is being passed if (body.new_member_handle === null || body.new_member_handle === '') { res.json({ type: DataEvent.API_INIT_LAME, message: 'No handle. Kinda need that.' }); } // check password match if ( body.new_member_pass !== body.new_member_pass2 || body.new_member_pass === '' || body.new_member_pass2 === '' ) { res.json({ type: DataEvent.API_INIT_LAME, message: 'Passwords do not match.' }); } if (body.new_member_title === null || body.new_member_title === '') { res.json({ type: DataEvent.API_INIT_LAME, message: 'No title. Gotta call it something.' }); } let key = crypto .createHash('sha256') .update(body.new_member_pass + secret_key) .digest('hex'); // set up config files fs.readJson('site/init/settings-template.json').then(fresh => { fresh.global.title = body.new_member_title; fs.writeJSON('site/settings.json', fresh); }); fs.readJson('site/init/folks-template.json').then(folks => { folks[0].id = 1; folks[0].handle = body.new_member_handle; folks[0].email = body.new_member_email; folks[0].password = bcrypt.hashSync(body.new_member_pass, bcrypt.genSaltSync(10), null); folks[0].key = key; folks[0].role = 'hnic'; folks[0].created = moment(Date.now()).format(); folks[0].updated = moment(Date.now()).format(); fs.writeJSON('site/folks.json', folks); }); fs.writeJson('site/tags.json', { tags: [] }); //set up index file as first page fs.readFile('site/init/index-template.md', { encoding: 'utf8' }).then(file => { let index = mdparser(file); let data = index.metadata; data.uuid = uuidv4(); data.path = moment().format('YYYY') + '/' + moment().format('MM'); data.author = body.new_member_handle; data.created = moment(Date.now()).format(); data.updated = moment(Date.now()).format(); var init = '---\n' + 'id: ' + data.id + '\n' + 'uuid: ' + data.uuid + '\n' + 'title: ' + data.title + '\n' + 'feature: ' + data.feature + '\n' + 'path: ' + moment(Date.now()).format('YYYY') + '/' + moment(Date.now()).format('MM') + '\n' + 'layout: ' + 'index' + '\n' + 'tags: ' + data.tags + '\n' + 'author: ' + body.new_member_handle + '\n' + 'created: ' + moment(Date.now()).format() + '\n' + 'updated: ' + moment(Date.now()).format() + '\n' + 'deleted: ' + 'false' + '\n' + 'menu: ' + data.menu + '\n' + 'featured: ' + data.featured + '\n' + 'published: ' + data.published + '\n' + 'slug: ' + data.slug + '\n' + '---\n' + index.content; fs.ensureDir('content/pages/').then(() => { fs.writeFile('content/pages/index.md', init) .then(() => { //console.log('index file created'); }) .catch(() => { //console.log('ERROR', err); }); }); }); res.json({ type: DataEvent.API_INIT_GOOD, message: 'All Set Up' }); }); //router.post('/logout', function(req, res) {}); module.exports = router; function isValidPassword(user, password) { return bcrypt.compareSync(password, user.password); } function hashToken(token) { return bcrypt.hashSync(token, bcrypt.genSaltSync(10), null); }