You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Fipamo/brain/api/v1/auth.js

236 lines
5.5 KiB
JavaScript

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);
}