Skip to content

Commit

Permalink
Merge pull request #212 from FlowFuse/httpNodeAuth-token
Browse files Browse the repository at this point in the history
Http node auth token
  • Loading branch information
Steve-Mcl authored Mar 11, 2024
2 parents 3739f00 + eaa5570 commit d51c68c
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 15 deletions.
72 changes: 61 additions & 11 deletions lib/auth/httpAuthMiddleware.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const crypto = require('crypto')
const got = require('got')
const session = require('express-session')
const MemoryStore = require('memorystore')(session)
const { Passport } = require('passport')
Expand All @@ -7,23 +8,61 @@ const { Strategy } = require('./strategy')
let options
let passport
let httpNodeApp
let client
const httpTokenCache = {}

module.exports = {
init (_options) {
options = _options
return (req, res, next) => {
try {
if (req.session.ffSession) {
next()
} else {
req.session.redirectTo = req.originalUrl
passport.authenticate('FlowFuse', { session: false })(req, res, next)
return [
async (req, res, next) => {
try {
if (req.session.ffSession) {
next()
} else if (req.get('Authorization')?.startsWith('Bearer')) {
// We should include the Project ID and the path along with the token
// to be checked to allow scoping tokens
const token = req.get('Authorization').split(' ')[1]
const cacheHit = httpTokenCache[token]
if (cacheHit) {
const age = (Date.now() - cacheHit.age) / 1000
if (age < 300) {
next()
return
}
delete httpTokenCache[token]
}
const query = {
path: req.path
}
try {
await client.get(options.projectId, {
headers: {
authorization: `Bearer ${token}`
},
searchParams: query
})
httpTokenCache[token] = { age: Date.now() }
next()
} catch (err) {
// console.log(err)
const error = new Error('Failed to check token')
error.status = 401
next(error)
}
} else {
req.session.redirectTo = req.originalUrl
passport.authenticate('FlowFuse', { session: false })(req, res, next)
}
} catch (err) {
console.log(err.stack)
throw err
}
} catch (err) {
console.log(err.stack)
throw err
},
(err, req, res, next) => {
res.status(err.status).send()
}
}
]
},

setupAuthRoutes (app) {
Expand Down Expand Up @@ -89,5 +128,16 @@ module.exports = {
res.redirect('/')
}
})

// need to decide on the path here
client = got.extend({
prefixUrl: `${options.forgeURL}/account/check/http`,
headers: {
'user-agent': 'FlowFuse HTTP Node Auth'
},
timeout: {
request: 500
}
})
}
}
3 changes: 2 additions & 1 deletion lib/runtimeSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ function getSettingsFile (settings) {
baseURL: '${settings.baseURL}',
forgeURL: '${settings.forgeURL}',
clientID: '${settings.clientID}',
clientSecret: '${settings.clientSecret}'
clientSecret: '${settings.clientSecret}',
projectId: '${settings.projectID}'
})`
projectSettings.httpNodeMiddleware = 'httpNodeMiddleware: flowforgeAuthMiddleware,'
}
Expand Down
14 changes: 11 additions & 3 deletions test/unit/lib/runtimeSettings_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,18 @@ describe('Runtime Settings', function () {
const settings = await loadSettings(result)
settings.should.not.have.property('httpNodeAuth')
settings.should.have.property('httpNodeMiddleware')
;(typeof settings.httpNodeMiddleware).should.equal('function')
settings.httpNodeMiddleware.should.be.an.Array()
;(typeof settings.httpNodeMiddleware[0]).should.equal('function')
;(typeof settings.httpNodeMiddleware[1]).should.equal('function')
settings.should.have.property('ui')
settings.ui.should.not.have.property('path')
settings.ui.should.have.property('middleware')
;(typeof settings.ui.middleware).should.equal('function')
console.log(settings.ui.middleware)
settings.ui.middleware.should.be.an.Array()
;(typeof settings.ui.middleware[0]).should.equal('function')
;(typeof settings.ui.middleware[1]).should.equal('function')
} catch (err) {
console.log(err)
// Temporary fix as this module will not be found when running in CI
// until we publish the release of the new nr-auth module.
err.toString().should.match(/Cannot find module '@flowfuse\/nr-auth\/middleware'/)
Expand All @@ -283,7 +289,9 @@ describe('Runtime Settings', function () {
settings.should.have.property('ui')
settings.ui.should.have.property('path', '/foo')
settings.ui.should.have.property('middleware')
;(typeof settings.ui.middleware).should.equal('function')
settings.ui.middleware.should.be.an.Array()
;(typeof settings.ui.middleware[0]).should.equal('function')
;(typeof settings.ui.middleware[1]).should.equal('function')
} catch (err) {
// Temporary fix as this module will not be found when running in CI
// until we publish the release of the new nr-auth module.
Expand Down

0 comments on commit d51c68c

Please sign in to comment.