backend: generating guests

This commit is contained in:
muerwre 2018-11-29 16:18:02 +07:00
parent b6bd300e1b
commit 5025a43dbd
16 changed files with 1380 additions and 167 deletions

49
backend/app.js Normal file
View file

@ -0,0 +1,49 @@
/*
https://habr.com/company/ruvds/blog/321104/
*/
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const lessMiddleware = require('less-middleware');
const logger = require('morgan');
const bodyParser = require('body-parser');
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
const authRouter = require('./routes/auth');
const db = require('./config/db');
const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(lessMiddleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
// app.use('/', indexRouter);
// app.use('/users', usersRouter);
app.use('/auth', authRouter);
// catch 404 and forward to error handler
app.use((req, res, next) => {
next(createError(404));
});
// error handler
app.use((err, req, res, next) => {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;

90
backend/bin/www Executable file
View file

@ -0,0 +1,90 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
const app = require('../app');
const debug = require('debug')('orchid-backend:server');
const http = require('http');
/**
* Get port from environment and store in Express.
*/
const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
const port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
const bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
const addr = server.address();
const bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

28
backend/config/db.js Normal file
View file

@ -0,0 +1,28 @@
const user = 'user';
const password = 'password';
const hostname = 'vault48.org';
const port = 27017;
const db = 'map';
const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
mongoose.connect(`mongodb://${user}:${password}@${hostname}:${port}/${db}`, { });
const database = mongoose.connection;
database.on('error', (err) => { console.error(`Database Connection Error: ${err}`); process.exit(2); });
database.on('connected', () => { console.info('Succesfully connected to MongoDB Database'); });
const Schema = mongoose.Schema;
// Schemas
const User = new Schema({
id: { type: String, required: true },
role: { type: String, required: true },
token: { type: String, required: true },
});
const UserModel = mongoose.model('User', User);
module.exports.UserModel = UserModel;

View file

@ -0,0 +1 @@
body{padding:50px;font:14px "Lucida Grande",Helvetica,Arial,sans-serif}a{color:#00B7FF}

View file

@ -0,0 +1,8 @@
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}

10
backend/routes/auth.js Normal file
View file

@ -0,0 +1,10 @@
const express = require('express');
const createGuest = require('./auth/guest');
const listUsers = require('./auth/list');
const router = express.Router();
router.get('/', listUsers);
router.get('/guest', createGuest);
module.exports = router;

View file

@ -0,0 +1,32 @@
const { genRandomSequence } = require('../../utils/gen');
const { UserModel } = require('../../config/db');
const generateGuestToken = () => {
const id = `guest:${genRandomSequence(32)}`;
return UserModel.find({ id }).then(user => {
if (user.length) return generateGuestToken();
return id;
});
};
const generateUser = id => {
const token = `seq:${genRandomSequence(32)}`;
const role = 'guest';
return { id, token, role };
};
const saveUser = user => {
const model = new UserModel({ ...user });
return model.save();
};
module.exports = (req, res) => (
generateGuestToken()
.then(generateUser)
.then(saveUser)
.then(result => res.send({ success: 'true', type: 'guest', token: result }))
);

View file

@ -0,0 +1,9 @@
const { UserModel } = require('../../config/db');
module.exports = (req, res) => UserModel.find((err, articles) => {
if (!err) return res.send(articles);
res.statusCode = 500;
return res.send({ error: 'Server error' });
});

9
backend/routes/index.js Normal file
View file

@ -0,0 +1,9 @@
const express = require('express');
const router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;

9
backend/routes/users.js Normal file
View file

@ -0,0 +1,9 @@
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;

10
backend/utils/gen.js Normal file
View file

@ -0,0 +1,10 @@
module.exports.genRandomSequence = (length = 16) => {
let sequence = '';
const symbols = 'ABCDEFGHIJKLMOPQRSTUVXYZabcdefghijgmlopqrstuvxyz01234567890'
for (let i = 0; i < length; i += 1) {
sequence += symbols[parseInt(Math.random() * (symbols.length - 1), 10)];
}
return sequence;
};

6
backend/views/error.pug Normal file
View file

@ -0,0 +1,6 @@
extends layout
block content
h1= message
h2= error.status
pre #{error.stack}

5
backend/views/index.pug Normal file
View file

@ -0,0 +1,5 @@
extends layout
block content
h1= title
p Welcome to #{title}

7
backend/views/layout.pug Normal file
View file

@ -0,0 +1,7 @@
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content

1262
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -6,6 +6,8 @@
"main": "./src/js/index.js",
"scripts": {
"start": "NODE_ENV=development webpack-dev-server --mode development --hot --open --inline --progress",
"serve": "node ./backend/bin/www",
"serve-dev": "nodemon ./backend/bin/www",
"build": "NODE_ENV=production webpack --env production --config=webpack.config.js --progress -p",
"profile": "webpack --json > stats.json"
},
@ -48,18 +50,28 @@
"dependencies": {
"axios": "^0.18.0",
"babel-runtime": "^6.26.0",
"bluebird": "^3.5.3",
"body-parser": "^1.18.3",
"classnames": "^2.2.6",
"clean-webpack-plugin": "^0.1.9",
"cookie-parser": "~1.4.3",
"croppr": "^2.3.1",
"debug": "~2.6.9",
"express": "~4.16.0",
"file-saver": "^2.0.0",
"history": "^4.7.2",
"http-errors": "~1.6.2",
"leaflet": "^1.3.4",
"leaflet-editable": "^1.1.0",
"leaflet-geometryutil": "^0.9.0",
"leaflet-routing-machine": "muerwre/leaflet-routing-machine#no-osrm-text",
"less": "^3.8.1",
"less-middleware": "~2.2.1",
"lodash": "^4.17.10",
"mongoose": "^5.3.14",
"morgan": "~1.9.0",
"pt-sans-cyrillic": "0.0.4",
"pug": "2.0.0-beta11",
"raleway-cyrillic": "^4.0.2",
"react": "^16.3.2",
"react-dom": "^16.3.2",