Skip to content
Snippets Groups Projects
Commit e039c4f2 authored by Xiao Gui's avatar Xiao Gui
Browse files

feat: when refresh token is set, allow for refresh and access token

parent 9388b09c
No related branches found
No related tags found
No related merge requests found
......@@ -23,6 +23,7 @@ module.exports = async (app) => {
discoveryUrl,
redirectUri,
cb,
scope: 'openid offline_access',
clientConfig: {
redirect_uris: [ redirectUri ],
response_types: [ 'code' ]
......
......@@ -7,6 +7,11 @@ module.exports = async (app) => {
app.use(passport.session())
passport.serializeUser((user, done) => {
const { tokenset, rest } = user
console.log({
tokenset,
rest
})
objStoreDb.set(user.id, user)
done(null, user.id)
})
......
......@@ -7,7 +7,7 @@ const defaultCb = (tokenset, {id, ...rest}, done) => {
})
}
exports.configureAuth = async ({ discoveryUrl, clientId, clientSecret, redirectUri, clientConfig = {}, cb = defaultCb }) => {
exports.configureAuth = async ({ discoveryUrl, clientId, clientSecret, redirectUri, clientConfig = {}, cb = defaultCb, scope = 'openid' }) => {
if (!discoveryUrl)
throw new Error('discoveryUrl must be defined!')
......@@ -30,10 +30,14 @@ exports.configureAuth = async ({ discoveryUrl, clientId, clientSecret, redirectU
const oidcStrategy = new Strategy({
client,
redirect_uri: redirectUri
params: {
scope
},
}, cb)
return {
oidcStrategy
oidcStrategy,
issuer,
client
}
}
\ No newline at end of file
const { configureAuth } = require('./oidc')
const jwtDecode = require('jwt-decode')
const HOSTNAME = process.env.HOSTNAME || 'http://localhost:3000'
const clientId = process.env.HBP_CLIENTID || 'no hbp id'
const clientSecret = process.env.HBP_CLIENTSECRET || 'no hbp client secret'
const discoveryUrl = 'https://services.humanbrainproject.eu/oidc'
const redirectUri = `${HOSTNAME}/hbp-oidc/cb`
let REFRESH_TOKEN = process.env.REFRESH_TOKEN || null
const CLIENT_NOT_INIT = `Client is not initialised.`
const REFRESH_TOKEN_MISSING = `refresh token is missing`
let __client
let __publicAccessToken
const refreshToken = async () => {
if (!__client)
throw new Error(CLIENT_NOT_INIT)
if (!REFRESH_TOKEN)
throw new Error(REFRESH_TOKEN_MISSING)
const tokenset = await __client.refresh(REFRESH_TOKEN)
const {access_token: accessToken, refresh_token: refreshToken, id_token: idToken} = tokenset
if (refreshToken !== REFRESH_TOKEN) {
REFRESH_TOKEN = refreshToken
}
__publicAccessToken = accessToken
return true
}
const getPublicAccessToken = async () => {
if (!__client)
throw new Error(CLIENT_NOT_INIT)
if (!__publicAccessToken) {
await refreshToken()
}
const decoded = jwtDecode(__publicAccessToken)
const { exp } = decoded
if (!exp || isNaN(exp) || (exp * 1000 - Date.now() < 0)) {
await refreshToken()
}
return __publicAccessToken
}
module.exports = async () => {
const { client } = await configureAuth({
clientId,
clientSecret,
discoveryUrl,
redirectUri,
clientConfig: {
redirect_uris: [ redirectUri ],
response_types: [ 'code' ]
}
})
__client = client
return {
getPublicAccessToken: async () => await getPublicAccessToken()
}
}
\ No newline at end of file
const mocha = require('mocha')
const chai = require('chai')
const assert = chai.assert
const chaiAsPromised = require('chai-as-promised')
chai.use(chaiAsPromised)
const expect = chai.expect
const should = chai.should()
describe('mocha.js', () => {
it('mocha works properly', () => {
assert(true)
})
})
describe('chai-as-promised.js', () => {
it('resolving promise is resolved', () => {
return Promise.resolve(2 + 2).should.eventually.equal(4)
})
it('rejecting promise is rejected', () => {
return Promise.reject('no reason').should.be.rejected
})
})
describe('util.js with env', (done) => {
it('when client id and client secret and refresh token is set, util should not throw', async () => {
const util = require('./util')
const { getPublicAccessToken } = await util()
return getPublicAccessToken().should.be.fulfilled
})
})
\ No newline at end of file
const mocha = require('mocha')
const chai = require('chai')
const assert = chai.assert
const chaiAsPromised = require('chai-as-promised')
chai.use(chaiAsPromised)
const expect = chai.expect
const should = chai.should()
describe('mocha.js', () => {
it('mocha works properly', () => {
assert(true)
})
})
describe('chai-as-promised.js', () => {
it('resolving promise is resolved', () => {
return Promise.resolve(2 + 2).should.eventually.equal(4)
})
it('rejecting promise is rejected', () => {
return Promise.reject('no reason').should.be.rejected
})
})
describe('util.js without env', (done) => {
const util = require('./util')
it('even when no env is set, it should fulfill', () => {
const getUtil = util()
return getUtil.should.be.fulfilled
})
it('if env is not set, getPublicToken method should fail', async () => {
const utilObj = await util()
const { getPublicAccessToken } = utilObj
return getPublicAccessToken().should.be.rejected
})
})
\ No newline at end of file
......@@ -3,17 +3,36 @@ const request = require('request')
const path = require('path')
const { getPreviewFile, hasPreview } = require('./supplements/previewFile')
const kgQueryUtil = require('./../auth/util')
let cachedData = null
let otherQueryResult = null
const queryUrl = process.env.KG_DATASET_QUERY_URL || `https://kg.humanbrainproject.org/query/minds/core/dataset/v1.0.0/interactiveViewerKgQuery/instances?size=450&vocab=https%3A%2F%2Fschema.hbp.eu%2FmyQuery%2F`
const timeout = process.env.TIMEOUT || 5000
let getPublicAccessToken
try {
const { getPublicAccessToken: getPublic } = await kgQueryUtil()
getPublicAccessToken = getPublic
} catch (e) {
console.log('kgQueryUtil error', e)
}
const fetchDatasetFromKg = (arg) => new Promise((resolve, reject) => {
const accessToken = arg && arg.user && arg.user.tokenset && arg.user.tokenset.access_token
const option = accessToken || process.env.ACCESS_TOKEN
let publicAccessToken
if (!accessToken && getPublicAccessToken) {
try {
publicAccessToken = await getPublicAccessToken()
} catch (e) {
console.log('getPublicAccessToken Error', e)
}
}
const option = accessToken || publicAccessToken || process.env.ACCESS_TOKEN
? {
auth: {
'bearer': accessToken || process.env.ACCESS_TOKEN
'bearer': accessToken || publicAccessToken || process.env.ACCESS_TOKEN
}
}
: {}
......
......@@ -4,7 +4,10 @@
"description": "",
"main": "index.js",
"scripts": {
"start": "node server.js"
"start": "node server.js",
"test": "npm run testEnv && npm run testNoEnv",
"testEnv": "node -r dotenv/config ./node_modules/.bin/mocha ./test/mocha.test.js",
"testNoEnv": "node ./node_modules/.bin/mocha ./test/mocha.test.noenv.js"
},
"keywords": [],
"author": "",
......@@ -12,13 +15,17 @@
"dependencies": {
"express": "^4.16.4",
"express-session": "^1.15.6",
"jwt-decode": "^2.2.0",
"memorystore": "^1.6.1",
"openid-client": "^2.4.5",
"passport": "^0.4.0",
"request": "^2.88.0"
},
"devDependencies": {
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"cors": "^2.8.5",
"dotenv": "^6.2.0"
"dotenv": "^6.2.0",
"mocha": "^6.1.4"
}
}
require('../auth/util.spec')
\ No newline at end of file
require("../auth/util_noenv.spec")
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment