login/logout + some middleware stuff

This commit is contained in:
Erik 2022-11-13 21:12:50 +02:00
parent 426b22489b
commit 9779fb7e9d
Signed by: Navy.gif
GPG Key ID: 811EC0CD80E7E5FB
6 changed files with 54 additions and 15 deletions

View File

@ -28,7 +28,7 @@ class LoginEndpoint extends ApiEndpoint {
if (!body) return res.status(400).send('Missing body');
const { code } = body;
if (!user._otpSecret) return res.status(400).send('2FA not initialised');
if (!user._2fa) return res.status(400).send('2FA already enabled');
if (!user._2fa) return res.status(400).send('2FA not enabled');
if (!authenticator.check(code, user._otpSecret)) return res.status(400).send('Wrong code');
session.verified = true;
@ -49,15 +49,6 @@ class LoginEndpoint extends ApiEndpoint {
}
loggedIn (req, res, next) {
if (req.user) return res.redirect('/home');
next();
}
fail (req, res) {
res.status(401).send('Login failed');
}
}
module.exports = LoginEndpoint;

View File

@ -0,0 +1,28 @@
const { ApiEndpoint } = require("../../interfaces");
class LogoutEndpoint extends ApiEndpoint {
constructor (server) {
super(server, {
name: 'logout',
path: '/logout'
});
this.methods = [
[ 'post', this.logout.bind(this), server.authenticator.authenticate ]
];
}
logout (req, res) {
req.session.destroy();
res.clearCookie(this.server.authenticator.cookieName);
res.end();
}
}
module.exports = LogoutEndpoint;

View File

@ -29,8 +29,11 @@ class Endpoint {
init () {
for (const [ method, cb, mw = [] ] of this.methods) {
// eslint-disable-next-line prefer-const
for (let [ method, cb, mw = [] ] of this.methods) {
if (typeof method !== 'string') throw new Error(`Invalid method parameter type in Endpoint ${this.name} major path`);
if (typeof mw === 'function') mw = [ mw ];
if (!(mw instanceof Array)) throw new Error('Invalid middleware type, expecting array of functions or function');
this.server.app[method](this.path, ...this.middleware, ...mw, cb);
}

View File

@ -26,7 +26,7 @@ class Authenticator {
* }
* @memberof Authenticator
*/
constructor (server, users, { mongo, secret, cookie = { } }) {
constructor (server, users, { mongo, secret, name, cookie = { } }) {
if (!(users instanceof AbstractUserDatabase)) Util.fatal(new Error(`Expecting user database to be an instance inheriting AbstractUserDatabase`));
this.userdb = users;
@ -34,11 +34,13 @@ class Authenticator {
if (!mongo) Util.fatal(new Error('Missing mongo client for session store'));
this.logger = server.createLogger(this);
this.cookieName = name;
cookie = { maxAge: 0.5 * 24 * 60 * 60 * 1000, secure: false, ...cookie };
cookie.secure = cookie.secure && process.env.NODE_ENV !== 'development';
server.app.use(session({
cookie,
name,
store: MongoStore.create({ client: mongo.client, dbName: mongo.database, touchAfter: 600 }),
secret,
resave: false,
@ -133,8 +135,8 @@ class Authenticator {
const segments = authHeader.split(' ');
const key = segments[segments.length - 1];
const user = await this.userdb.matchToken(key);
if (user) req.user = user;
const application = await this.userdb.matchToken(key);
if (application) req.user = application;
else {
res.status(401).send('Unknown identity');
return false;

View File

@ -0,0 +1,14 @@
class UtilityMiddleware {
constructor () {
throw new Error('Utility class, may not be instantiated.');
}
static requireBody (req, res, next) {
if (!req.body && [ 'post', 'put', 'patch' ].includes(req.method.toLowerCase())) return res.status(400).send('Missing body');
next();
}
}
module.exports = UtilityMiddleware;

View File

@ -1,3 +1,4 @@
module.exports = {
Authenticator: require('./Authenticator')
Authenticator: require('./Authenticator'),
UtilMiddleware: require('./Util'),
};