From 4173a65b5296562f474af3f2b1d22c4cfe67192e Mon Sep 17 00:00:00 2001 From: Gianlu Date: Sun, 13 Sep 2020 22:13:20 +0200 Subject: [PATCH 1/4] Added authentication handler --- lib/nuts.js | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/nuts.js b/lib/nuts.js index 1642158b..e1f95406 100644 --- a/lib/nuts.js +++ b/lib/nuts.js @@ -35,7 +35,10 @@ function Nuts(opts) { preFetch: true, // Secret for GitHub webhook - refreshSecret: 'secret' + refreshSecret: 'secret', + + // Authenticator for non-api endpoints + authHandler: undefined }); // .init() is now a memoized version of ._init() @@ -174,6 +177,9 @@ Nuts.prototype.onDownload = function(req, res, next) { // Serve downloads .then(function(version) { + if (this.opts.authHandler && !this.opts.authHandler(req, version)) + return res.sendStatus(403) + var asset; if (filename) { @@ -233,6 +239,9 @@ Nuts.prototype.onUpdate = function(req, res, next) { var latest = _.first(versions); if (!latest || latest.tag == tag) return res.status(204).send('No updates'); + if (this.opts.authHandler && !this.opts.authHandler(req, latest)) + return res.sendStatus(403) + var notesSlice = versions.slice(0, -1); if (versions.length === 1) { notesSlice = [versions[0]]; @@ -276,6 +285,9 @@ Nuts.prototype.onUpdateWin = function(req, res, next) { var latest = _.first(versions); if (!latest) throw new Error("Version not found"); + if (this.opts.authHandler && !this.opts.authHandler(req, latest)) + return res.sendStatus(403) + // File exists var asset = _.find(latest.platforms, { filename: 'RELEASES' @@ -322,9 +334,11 @@ Nuts.prototype.onServeNotes = function(req, res, next) { }) .then(function(versions) { var latest = _.first(versions); - if (!latest) throw new Error('No versions matching'); + if (this.opts.authHandler && !this.opts.authHandler(req, latest)) + return res.sendStatus(403) + res.format({ 'text/plain': function(){ res.send(notes.merge(versions)); @@ -364,13 +378,15 @@ Nuts.prototype.onServeVersionsFeed = function(req, res, next) { }) .then(function(versions) { _.each(versions, function(version) { - feed.addItem({ + if (!this.opts.authHandler || this.opts.authHandler(req, version)) { + feed.addItem({ title: version.tag, - link: urljoin(fullUrl, '/../../../', '/download/version/'+version.tag), + link: urljoin(fullUrl, '/../../../', '/download/version/' + version.tag), description: version.notes, date: version.published_at, author: [] - }); + }); + } }); res.set('Content-Type', 'application/atom+xml; charset=utf-8'); From 532cafb2b42455c409acc03c02ad875e84c18598 Mon Sep 17 00:00:00 2001 From: Gianlu Date: Sun, 13 Sep 2020 22:18:02 +0200 Subject: [PATCH 2/4] Reference opts correctly --- lib/nuts.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/nuts.js b/lib/nuts.js index e1f95406..4cc56af0 100644 --- a/lib/nuts.js +++ b/lib/nuts.js @@ -177,7 +177,7 @@ Nuts.prototype.onDownload = function(req, res, next) { // Serve downloads .then(function(version) { - if (this.opts.authHandler && !this.opts.authHandler(req, version)) + if (that.opts.authHandler && !that.opts.authHandler(req, version)) return res.sendStatus(403) var asset; @@ -239,7 +239,7 @@ Nuts.prototype.onUpdate = function(req, res, next) { var latest = _.first(versions); if (!latest || latest.tag == tag) return res.status(204).send('No updates'); - if (this.opts.authHandler && !this.opts.authHandler(req, latest)) + if (that.opts.authHandler && !that.opts.authHandler(req, latest)) return res.sendStatus(403) var notesSlice = versions.slice(0, -1); @@ -285,7 +285,7 @@ Nuts.prototype.onUpdateWin = function(req, res, next) { var latest = _.first(versions); if (!latest) throw new Error("Version not found"); - if (this.opts.authHandler && !this.opts.authHandler(req, latest)) + if (that.opts.authHandler && !that.opts.authHandler(req, latest)) return res.sendStatus(403) // File exists @@ -336,7 +336,7 @@ Nuts.prototype.onServeNotes = function(req, res, next) { var latest = _.first(versions); if (!latest) throw new Error('No versions matching'); - if (this.opts.authHandler && !this.opts.authHandler(req, latest)) + if (that.opts.authHandler && !that.opts.authHandler(req, latest)) return res.sendStatus(403) res.format({ @@ -378,7 +378,7 @@ Nuts.prototype.onServeVersionsFeed = function(req, res, next) { }) .then(function(versions) { _.each(versions, function(version) { - if (!this.opts.authHandler || this.opts.authHandler(req, version)) { + if (!that.opts.authHandler || that.opts.authHandler(req, version)) { feed.addItem({ title: version.tag, link: urljoin(fullUrl, '/../../../', '/download/version/' + version.tag), From d2e6ea6dd93abb48f863dc2398b7dd94c8e65c56 Mon Sep 17 00:00:00 2001 From: Gianlu Date: Sun, 13 Sep 2020 22:26:07 +0200 Subject: [PATCH 3/4] Properly check if authHandler is set --- lib/nuts.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/nuts.js b/lib/nuts.js index 4cc56af0..3dce29f5 100644 --- a/lib/nuts.js +++ b/lib/nuts.js @@ -177,7 +177,7 @@ Nuts.prototype.onDownload = function(req, res, next) { // Serve downloads .then(function(version) { - if (that.opts.authHandler && !that.opts.authHandler(req, version)) + if (that.opts.authHandler != undefined && !that.opts.authHandler(req, version)) return res.sendStatus(403) var asset; @@ -239,7 +239,7 @@ Nuts.prototype.onUpdate = function(req, res, next) { var latest = _.first(versions); if (!latest || latest.tag == tag) return res.status(204).send('No updates'); - if (that.opts.authHandler && !that.opts.authHandler(req, latest)) + if (that.opts.authHandler != undefined && !that.opts.authHandler(req, latest)) return res.sendStatus(403) var notesSlice = versions.slice(0, -1); @@ -285,7 +285,7 @@ Nuts.prototype.onUpdateWin = function(req, res, next) { var latest = _.first(versions); if (!latest) throw new Error("Version not found"); - if (that.opts.authHandler && !that.opts.authHandler(req, latest)) + if (that.opts.authHandler != undefined && !that.opts.authHandler(req, latest)) return res.sendStatus(403) // File exists @@ -336,7 +336,7 @@ Nuts.prototype.onServeNotes = function(req, res, next) { var latest = _.first(versions); if (!latest) throw new Error('No versions matching'); - if (that.opts.authHandler && !that.opts.authHandler(req, latest)) + if (that.opts.authHandler != undefined && !that.opts.authHandler(req, latest)) return res.sendStatus(403) res.format({ @@ -378,7 +378,7 @@ Nuts.prototype.onServeVersionsFeed = function(req, res, next) { }) .then(function(versions) { _.each(versions, function(version) { - if (!that.opts.authHandler || that.opts.authHandler(req, version)) { + if (that.opts.authHandler == undefined || that.opts.authHandler(req, version)) { feed.addItem({ title: version.tag, link: urljoin(fullUrl, '/../../../', '/download/version/' + version.tag), From 307fabeb7095e2e998e034b60ade4ba45f450d8e Mon Sep 17 00:00:00 2001 From: Gianlu Date: Sun, 13 Sep 2020 22:44:08 +0200 Subject: [PATCH 4/4] Accept promises as authHandler return value --- lib/nuts.js | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/nuts.js b/lib/nuts.js index 3dce29f5..e7404465 100644 --- a/lib/nuts.js +++ b/lib/nuts.js @@ -98,6 +98,13 @@ Nuts.prototype._init = function() { }); } +Nuts.prototype.checkAuth = async function(req, version) { + if (!this.opts.authHandler) + return true + + return await this.opts.authHandler(req, version) +} + // Perform a hook using promised functions Nuts.prototype.performQ = function(name, arg, fn) { @@ -176,8 +183,8 @@ Nuts.prototype.onDownload = function(req, res, next) { }) // Serve downloads - .then(function(version) { - if (that.opts.authHandler != undefined && !that.opts.authHandler(req, version)) + .then(async function(version) { + if (!(await that.checkAuth(req, version))) return res.sendStatus(403) var asset; @@ -235,12 +242,12 @@ Nuts.prototype.onUpdate = function(req, res, next) { channel: channel }); }) - .then(function(versions) { + .then(async function(versions) { var latest = _.first(versions); if (!latest || latest.tag == tag) return res.status(204).send('No updates'); - if (that.opts.authHandler != undefined && !that.opts.authHandler(req, latest)) - return res.sendStatus(403) + if (!(await that.checkAuth(req, latest))) + return res.sendStatus(403) var notesSlice = versions.slice(0, -1); if (versions.length === 1) { @@ -280,13 +287,13 @@ Nuts.prototype.onUpdateWin = function(req, res, next) { channel: channel }); }) - .then(function(versions) { + .then(async function(versions) { // Update needed? var latest = _.first(versions); if (!latest) throw new Error("Version not found"); - if (that.opts.authHandler != undefined && !that.opts.authHandler(req, latest)) - return res.sendStatus(403) + if (!(await that.checkAuth(req, latest))) + return res.sendStatus(403) // File exists var asset = _.find(latest.platforms, { @@ -332,12 +339,12 @@ Nuts.prototype.onServeNotes = function(req, res, next) { channel: '*' }); }) - .then(function(versions) { + .then(async function(versions) { var latest = _.first(versions); if (!latest) throw new Error('No versions matching'); - if (that.opts.authHandler != undefined && !that.opts.authHandler(req, latest)) - return res.sendStatus(403) + if (!(await that.checkAuth(req, latest))) + return res.sendStatus(403) res.format({ 'text/plain': function(){ @@ -377,8 +384,8 @@ Nuts.prototype.onServeVersionsFeed = function(req, res, next) { }); }) .then(function(versions) { - _.each(versions, function(version) { - if (that.opts.authHandler == undefined || that.opts.authHandler(req, version)) { + _.each(versions, async function(version) { + if (await that.checkAuth(req, version)) { feed.addItem({ title: version.tag, link: urljoin(fullUrl, '/../../../', '/download/version/' + version.tag),