web module
This commit is contained in:
parent
329fc1c14f
commit
a62bb80478
23
bin/web/app/routes/main.js
Normal file
23
bin/web/app/routes/main.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
var express = require('express');
|
||||||
|
var route = express.Router();
|
||||||
|
|
||||||
|
|
||||||
|
route.use((req, res, next) => {
|
||||||
|
if(!req.session || !req.session.user) {
|
||||||
|
if(!req.path.startsWith('/api')) {
|
||||||
|
let path = (global['gds'].cfg.web.rootUrl+'/auth');
|
||||||
|
|
||||||
|
if(global['gds'].cfg.web.doubleSlashCheck) path = path.replace(/\/+/g, "/");
|
||||||
|
|
||||||
|
res.redirect(path);
|
||||||
|
} else {
|
||||||
|
res.redirect('/auth'+req.path);
|
||||||
|
}
|
||||||
|
} else next();
|
||||||
|
});
|
||||||
|
|
||||||
|
route.get('/', (req, res) => {
|
||||||
|
res.status(202).end('test');
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = route;
|
0
bin/web/app/views/index.pug
Normal file
0
bin/web/app/views/index.pug
Normal file
51
bin/web/auth/routes/api.js
Normal file
51
bin/web/auth/routes/api.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
var express = require('express');
|
||||||
|
var route = express.Router();
|
||||||
|
|
||||||
|
route.get('/register', (req, res) => {
|
||||||
|
if(!global['gds'].cfg.web.registration) {
|
||||||
|
return res.type('json').status(400).end(JSON.stringify({status: 400, message: "msg.auth.registration.deactivated"}));
|
||||||
|
}
|
||||||
|
// TODO: register
|
||||||
|
});
|
||||||
|
|
||||||
|
route.get('/login', (req, res) => {
|
||||||
|
// TODO: login
|
||||||
|
let a = global['modules'].sso.createAuthentication({
|
||||||
|
url: global['gds'].cfg.sso.authenticator,
|
||||||
|
appId: global['gds'].cfg.sso.appId
|
||||||
|
})
|
||||||
|
console.log(a);
|
||||||
|
res.end('login');
|
||||||
|
});
|
||||||
|
|
||||||
|
route.post('/authenticate', (req, res) => {
|
||||||
|
// TODO: authenticate
|
||||||
|
});
|
||||||
|
|
||||||
|
route.get('/logout', (req, res) => {
|
||||||
|
if(!req.session.user) {
|
||||||
|
return res.type('json').end(JSON.stringify({
|
||||||
|
status: 401,
|
||||||
|
message: 'msg.auth.login.required'
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
res.clearCookie('RememberMe');
|
||||||
|
req.session.destroy();
|
||||||
|
return res.type('json').end(JSON.stringify({
|
||||||
|
status: 200,
|
||||||
|
message: 'msg.auth.logout.successful'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(global['gds'].debug) {
|
||||||
|
// DEBUG info
|
||||||
|
route.get('/info', (req, res) => {
|
||||||
|
let obj = {};
|
||||||
|
if(req.session) obj.session = req.session;
|
||||||
|
if(req.cookies) obj.cookie = req.cookies;
|
||||||
|
res.type('json').end(JSON.stringify(obj));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = route;
|
8
bin/web/auth/routes/main.js
Normal file
8
bin/web/auth/routes/main.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
var express = require('express');
|
||||||
|
var route = express.Router();
|
||||||
|
|
||||||
|
|
||||||
|
route.use('/api', require(global['__dirname']+'/bin/web/auth/routes/api'));
|
||||||
|
route.use('/', require(global['__dirname']+'/bin/web/auth/routes/static'));
|
||||||
|
|
||||||
|
module.exports = route;
|
23
bin/web/auth/routes/static.js
Normal file
23
bin/web/auth/routes/static.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
var express = require('express');
|
||||||
|
var route = express.Router();
|
||||||
|
|
||||||
|
|
||||||
|
route.all('/', function(req, res, next) {
|
||||||
|
// TODO: show login page or dashboard
|
||||||
|
// res.end('login or dashboard');
|
||||||
|
res.render('auth/views/index');
|
||||||
|
});
|
||||||
|
|
||||||
|
route.all('/*', (req, res, next) => {
|
||||||
|
// passthrough to next route
|
||||||
|
if(req.path.startsWith('/api'))
|
||||||
|
return next();
|
||||||
|
|
||||||
|
// TODO: try to login
|
||||||
|
// TODO: role-based authorization
|
||||||
|
// TODO: show login page or page
|
||||||
|
|
||||||
|
res.end('500 - LEL');
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = route;
|
66
bin/web/auth/views/index.pug
Normal file
66
bin/web/auth/views/index.pug
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
//- variables
|
||||||
|
- var appName = global['gds'].cfg.app.name || "SSObaseApp";
|
||||||
|
- var title = "Dashboard";
|
||||||
|
|
||||||
|
mixin navItem(name, id, symbol, href)
|
||||||
|
li(title=name, id=id)
|
||||||
|
a(href=href)
|
||||||
|
i.fa-fw(class=symbol)
|
||||||
|
span= name
|
||||||
|
|
||||||
|
doctype(html)
|
||||||
|
html(lang='en')
|
||||||
|
head
|
||||||
|
meta(charset="utf-8")
|
||||||
|
meta(http-equiv="X-UA-Compatible", content="IE=edge")
|
||||||
|
meta(name="viewport", content="width=device-width, initial-scale=1, shrink-to-fit=no")
|
||||||
|
|
||||||
|
meta(name="author", content="Ruben Meyer")
|
||||||
|
meta(name="description" content="auth.rxbn.de")
|
||||||
|
if(title)
|
||||||
|
title=""+appName+" - "+title
|
||||||
|
else
|
||||||
|
title=appName
|
||||||
|
|
||||||
|
block css
|
||||||
|
//- UIkit CSS
|
||||||
|
link(href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.5/css/uikit.min.css", rel="stylesheet")
|
||||||
|
|
||||||
|
//- Custom Stylesheet
|
||||||
|
link(href="/res/css/stylesheet.css", rel="stylesheet")
|
||||||
|
|
||||||
|
//- Custom fonts for this template
|
||||||
|
link(href="https://use.fontawesome.com/releases/v5.1.1/css/all.css" integrity="sha384-O8whS3fhG2OnA5Kas0Y9l3cfpmYjapjI0E4theH4iuMD+pLhbf6JI0jIMfYcK3yZ", crossorigin="anonymous", rel="stylesheet")
|
||||||
|
body
|
||||||
|
//- Navigation
|
||||||
|
nav(uk-navbar).uk-navbar-container
|
||||||
|
.uk-navbar-left.uk-margin-left
|
||||||
|
ul.uk-navbar-nav
|
||||||
|
li(title=appName)
|
||||||
|
a(href="/", style="text-transform: unset")
|
||||||
|
span=appName
|
||||||
|
.uk-navbar-right.uk-margin-right
|
||||||
|
ul.uk-navbar-nav
|
||||||
|
+navItem("Register", "register", "fas fa-user-plus", "/api/register")
|
||||||
|
+navItem("Login", "login", "far fa-arrow-alt-circle-right", "/api/login")
|
||||||
|
div
|
||||||
|
.uk-flex.uk-margin-medium-top.uk-margin-medium-bottom
|
||||||
|
div(class="uk-width-auto uk-width-1-4@s")
|
||||||
|
.uk-flex.uk-flex-auto.uk-flex-column.uk-flex-center.uk-margin-left.uk-margin-right
|
||||||
|
h1 Please login
|
||||||
|
p You need to be logged in to use this service
|
||||||
|
a(href="/api/login").uk-button.uk-button-default Login
|
||||||
|
div(class="uk-width-auto uk-width-1-4@s")
|
||||||
|
footer
|
||||||
|
.uk-text-center
|
||||||
|
small Copyright © <a href="https://www.rxbn.de/">Ruben Meyer</a> 2019
|
||||||
|
|
||||||
|
block scripts
|
||||||
|
//- UIkit JS
|
||||||
|
script(src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.5/js/uikit.min.js")
|
||||||
|
script(src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.5/js/uikit-icons.min.js")
|
||||||
|
|
||||||
|
//- Custom scripts for this template
|
||||||
|
script(src="/res/js/locales.js")
|
||||||
|
script(src="/res/js/custom.js")
|
||||||
|
|
138
bin/web/module.js
Normal file
138
bin/web/module.js
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
// init
|
||||||
|
var methods = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* start web server
|
||||||
|
* @author Ruben Meyer
|
||||||
|
* @return {Void}
|
||||||
|
*/
|
||||||
|
methods.start = () => {
|
||||||
|
// init express framework
|
||||||
|
let express = require('express');
|
||||||
|
let session_handler = require('express-session');
|
||||||
|
|
||||||
|
// utilities
|
||||||
|
let fs = require('fs');
|
||||||
|
let path = require('path');
|
||||||
|
let mime = require('mime-types');
|
||||||
|
|
||||||
|
// app variable
|
||||||
|
let app = express();
|
||||||
|
app.set('view engine', 'pug'); // page engine
|
||||||
|
app.set('views', global['__dirname']+'/bin/web');
|
||||||
|
|
||||||
|
let bp = require('body-parser'); // POST Body parser
|
||||||
|
let cp = require('cookie-parser'); // Cookie handler
|
||||||
|
|
||||||
|
// Access Control Headers
|
||||||
|
app.use( (req, res, next) => {
|
||||||
|
res.set({
|
||||||
|
'X-Powered-By': global['gds'].cfg
|
||||||
|
});
|
||||||
|
res.header("Access-Control-Allow-Origin", "*");
|
||||||
|
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
// BodyParser & CookieParser
|
||||||
|
app.use(bp.json());
|
||||||
|
app.use(bp.urlencoded({
|
||||||
|
extended: true
|
||||||
|
}));
|
||||||
|
app.use(cp(global['gds'].cfg.web.cookieKey));
|
||||||
|
|
||||||
|
// Pretty print
|
||||||
|
app.locals.pretty = true;
|
||||||
|
|
||||||
|
// Sessions
|
||||||
|
session_options = {
|
||||||
|
secret: global['gds'].cfg.web.sessionKey,
|
||||||
|
resave: false,
|
||||||
|
saveUninitialized: false, cookie: {}};
|
||||||
|
if(app.get('env') === 'production') {
|
||||||
|
session_options.cookie.secure = true;
|
||||||
|
}
|
||||||
|
app.use(session_handler(session_options));
|
||||||
|
|
||||||
|
//static files
|
||||||
|
app.use('/res', (req, res, next) => {
|
||||||
|
if(typeof global['gds'].cache.web == 'undefined') global['gds'].cache.web = {};
|
||||||
|
|
||||||
|
let dir = global['__dirname'] + '/res/web';
|
||||||
|
|
||||||
|
|
||||||
|
if(!req.session || !req.session.user) dir += '/auth';
|
||||||
|
else dir += '/app';
|
||||||
|
|
||||||
|
let joined_path = path.join(dir, /^[^?]+/.exec(req.url)[0]);
|
||||||
|
|
||||||
|
// path already cached; not exist
|
||||||
|
if(global['gds'].cache.web[joined_path] == false) {
|
||||||
|
res.status(404).end();
|
||||||
|
// path already cached; exist
|
||||||
|
} else if(global['gds'].cache.web[joined_path] == true){
|
||||||
|
let contentType = mime.contentType(path.extname(joined_path));
|
||||||
|
res.setHeader('Content-Type', contentType);
|
||||||
|
fs.createReadStream(joined_path).pipe(res);
|
||||||
|
// check path
|
||||||
|
} else {
|
||||||
|
fs.exists(joined_path, (exists) => {
|
||||||
|
global['gds'].cache.web[joined_path] = exists;
|
||||||
|
if(exists) {
|
||||||
|
let contentType = mime.contentType(path.extname(joined_path));
|
||||||
|
res.setHeader('Content-Type', contentType);
|
||||||
|
|
||||||
|
fs.createReadStream(joined_path).pipe(res);
|
||||||
|
} else {
|
||||||
|
res.status(404).end();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// web routes
|
||||||
|
app.use('/auth', require(global['__dirname']+'/bin/web/auth/routes/main'));
|
||||||
|
app.use('/', require(global['__dirname']+'/bin/web/app/routes/main'));
|
||||||
|
|
||||||
|
// start server
|
||||||
|
app.listen(global['gds'].cfg.web.port, () => {
|
||||||
|
global['modules'].logs.log("Server is listening on port: "+global['gds'].cfg.web.port);
|
||||||
|
});
|
||||||
|
|
||||||
|
// DEBUG OUTPUT: list all routes with HTTP method
|
||||||
|
setTimeout(function () {
|
||||||
|
function print (path, layer) {
|
||||||
|
if (layer.route) {
|
||||||
|
layer.route.stack.forEach(print.bind(null, path.concat(split(layer.route.path))))
|
||||||
|
} else if (layer.name === 'router' && layer.handle.stack) {
|
||||||
|
layer.handle.stack.forEach(print.bind(null, path.concat(split(layer.regexp))))
|
||||||
|
} else if (layer.method) {
|
||||||
|
console.log('%s /%s',
|
||||||
|
layer.method.toUpperCase(),
|
||||||
|
path.concat(split(layer.regexp)).filter(Boolean).join('/')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function split (thing) {
|
||||||
|
if (typeof thing === 'string') {
|
||||||
|
return thing.split('/')
|
||||||
|
} else if (thing.fast_slash) {
|
||||||
|
return ''
|
||||||
|
} else {
|
||||||
|
var match = thing.toString()
|
||||||
|
.replace('\\/?', '')
|
||||||
|
.replace('(?=\\/|$)', '$')
|
||||||
|
.match(/^\/\^((?:\\[.*+?^${}()|[\]\\\/]|[^.*+?^${}()|[\]\\\/])*)\$\//)
|
||||||
|
|
||||||
|
return match
|
||||||
|
? match[1].replace(/\\(.)/g, '$1').split('/')
|
||||||
|
: '<complex:' + thing.toString() + '>'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app._router.stack.forEach(print.bind(null, []))
|
||||||
|
}, 1500);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = methods;
|
8
res/web/auth/css/stylesheet.css
Normal file
8
res/web/auth/css/stylesheet.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.uk-navbar a i {
|
||||||
|
margin-right: .2em;
|
||||||
|
transition: all .1s cubic-bezier(0.65, 0.05, 0.36, 1);
|
||||||
|
}
|
||||||
|
.uk-navbar a:hover i {
|
||||||
|
margin-top: .1em;
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user