diff --git a/lib/www/server/api/middleware/auth/authentify.js b/lib/www/server/api/middleware/auth/authentify.js new file mode 100644 index 0000000..c7205cd --- /dev/null +++ b/lib/www/server/api/middleware/auth/authentify.js @@ -0,0 +1,61 @@ +const dns = require('dns'); +const { Netmask } = require('netmask'); +const cfg = require('../../../lib/config'); +const jwt = require('../../../lib/jwt'); + +async function authorisedIP (req, res) { + const validIPs = cfg.global.login.ip; + for (const key in validIPs) { + const block = new Netmask(key); + if (block.contains(req.ip)) { + const payload = Object.assign({ + ip: req.ip, + autologin: true + }, validIPs[key]); + jwt.issue(payload, req, res); + } + } + return Promise.resolve(true); +} + +async function authorisedHost (req, res) { + const validHosts = cfg.global.login.host + for (const key in validHosts) { + const ip = await dns.promises.resolve(key); + if (ip == req.ip) { + const payload = Object.assign({ + ip: req.ip, + host: key, + autologin: true + }); + jwt.issue(payload, req, res); + } + } + return true; +} + +async function auth (req, res, next) { + + // Check for a valid JWT (already decoded by a previous + // middleware). + if (req.user) { + next(); + return; + } + + // Check if the IP is known to us + if (await authorisedIP(req, res)) { + next(); + return; + } + + // Check if the hostname is known to us + if (await authorisedHost(req, res)) { + next(); + return; + } + + next({status: 401, message: "Not authorised"}); +} + +module.exports = auth; diff --git a/lib/www/server/api/middleware/auth/index.js b/lib/www/server/api/middleware/auth/index.js index 212e56e..d943af0 100644 --- a/lib/www/server/api/middleware/auth/index.js +++ b/lib/www/server/api/middleware/auth/index.js @@ -1,3 +1,4 @@ exports.jwt = require('./jwt'); // exports.access = require('./access'); +exports.authentify = require('./authentify'); diff --git a/lib/www/server/lib/config.js b/lib/www/server/lib/config.js index 4bdc227..c1a93ce 100644 --- a/lib/www/server/lib/config.js +++ b/lib/www/server/lib/config.js @@ -24,7 +24,10 @@ try { config = { "jwt": { - secret + secret, + options: { + expiresIn: 15*60*1000 + } }, "db": { "user": "postgres", diff --git a/lib/www/server/lib/jwt.js b/lib/www/server/lib/jwt.js new file mode 100644 index 0000000..3adb893 --- /dev/null +++ b/lib/www/server/lib/jwt.js @@ -0,0 +1,22 @@ +const jwt = require('jsonwebtoken'); +const cfg = require('./config'); + +function issue (payload, req, res) { + + console.log("ISSUE", payload, cfg.jwt); + const token = jwt.sign(payload, cfg.jwt.secret, cfg.jwt.options); + + if (req) { + req.user = payload; + } + + if (res) { + res.cookie("JWT", token, {maxAge: cfg.jwt.options.expiresIn || 0}); + } + + return token; +} + +module.exports = { + issue +}; diff --git a/lib/www/server/package-lock.json b/lib/www/server/package-lock.json index 1384cbb..d8c5ec5 100644 --- a/lib/www/server/package-lock.json +++ b/lib/www/server/package-lock.json @@ -366,6 +366,11 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "netmask": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", + "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=" + }, "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", diff --git a/lib/www/server/package.json b/lib/www/server/package.json index 5c9ac43..d66c918 100644 --- a/lib/www/server/package.json +++ b/lib/www/server/package.json @@ -13,6 +13,7 @@ "express": "^4.17.1", "express-jwt": "^6.0.0", "jsonwebtoken": "^8.5.1", + "netmask": "^1.0.6", "node-fetch": "^2.6.1", "pg": "^8.3.3", "ws": "^7.3.1",