diff --git a/lib/nuts.js b/lib/nuts.js index 1642158b..e7404465 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() @@ -95,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) { @@ -173,7 +183,10 @@ Nuts.prototype.onDownload = function(req, res, next) { }) // Serve downloads - .then(function(version) { + .then(async function(version) { + if (!(await that.checkAuth(req, version))) + return res.sendStatus(403) + var asset; if (filename) { @@ -229,10 +242,13 @@ 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 (!(await that.checkAuth(req, latest))) + return res.sendStatus(403) + var notesSlice = versions.slice(0, -1); if (versions.length === 1) { notesSlice = [versions[0]]; @@ -271,11 +287,14 @@ 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 (!(await that.checkAuth(req, latest))) + return res.sendStatus(403) + // File exists var asset = _.find(latest.platforms, { filename: 'RELEASES' @@ -320,11 +339,13 @@ 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 (!(await that.checkAuth(req, latest))) + return res.sendStatus(403) + res.format({ 'text/plain': function(){ res.send(notes.merge(versions)); @@ -363,14 +384,16 @@ Nuts.prototype.onServeVersionsFeed = function(req, res, next) { }); }) .then(function(versions) { - _.each(versions, function(version) { - feed.addItem({ + _.each(versions, async function(version) { + if (await that.checkAuth(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');