From 9779fb7e9d030301510de5da213d48c69edacadd Mon Sep 17 00:00:00 2001 From: "Navy.gif" Date: Sun, 13 Nov 2022 21:12:50 +0200 Subject: [PATCH] login/logout + some middleware stuff --- src/server/endpoints/api/Login.js | 11 +--------- src/server/endpoints/api/Logout.js | 28 ++++++++++++++++++++++++++ src/server/interfaces/Endpoint.js | 5 ++++- src/server/middleware/Authenticator.js | 8 +++++--- src/server/middleware/Util.js | 14 +++++++++++++ src/server/middleware/index.js | 3 ++- 6 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 src/server/endpoints/api/Logout.js create mode 100644 src/server/middleware/Util.js diff --git a/src/server/endpoints/api/Login.js b/src/server/endpoints/api/Login.js index abb4ac7..ad7e159 100644 --- a/src/server/endpoints/api/Login.js +++ b/src/server/endpoints/api/Login.js @@ -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; \ No newline at end of file diff --git a/src/server/endpoints/api/Logout.js b/src/server/endpoints/api/Logout.js new file mode 100644 index 0000000..54d2a80 --- /dev/null +++ b/src/server/endpoints/api/Logout.js @@ -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; \ No newline at end of file diff --git a/src/server/interfaces/Endpoint.js b/src/server/interfaces/Endpoint.js index 57cc05e..ae12e60 100644 --- a/src/server/interfaces/Endpoint.js +++ b/src/server/interfaces/Endpoint.js @@ -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); } diff --git a/src/server/middleware/Authenticator.js b/src/server/middleware/Authenticator.js index 10ee5ea..88ac4ee 100644 --- a/src/server/middleware/Authenticator.js +++ b/src/server/middleware/Authenticator.js @@ -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; diff --git a/src/server/middleware/Util.js b/src/server/middleware/Util.js new file mode 100644 index 0000000..ce4c6cf --- /dev/null +++ b/src/server/middleware/Util.js @@ -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; \ No newline at end of file diff --git a/src/server/middleware/index.js b/src/server/middleware/index.js index 3044f3e..228a52f 100644 --- a/src/server/middleware/index.js +++ b/src/server/middleware/index.js @@ -1,3 +1,4 @@ module.exports = { - Authenticator: require('./Authenticator') + Authenticator: require('./Authenticator'), + UtilMiddleware: require('./Util'), }; \ No newline at end of file