Skip to content

Commit

Permalink
refactor: added an alias npm package for Jose v2
Browse files Browse the repository at this point in the history
  • Loading branch information
MahamoudTBS committed Jul 10, 2023
1 parent 2524295 commit af21b27
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 75 deletions.
37 changes: 37 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@
"global-agent": "^3.0.0",
"got": "^11.8.5",
"jose": "^4.8.1",
"jose_v2": "npm:jose@^2.0.6",
"jsonwebtoken": "^9.0.0",
"memcached": "^2.2.2",
"memorystore": "^1.6.6",
"morgan": "^1.9.1",
"ramda": "^0.27.2",
"openid-client": "^5.1.1",
"passport": "^0.6.0",
"passport-dropbox-oauth2": "^1.1.0",
Expand All @@ -58,6 +58,7 @@
"passport-twitter": "git+https://github.com/GluuFederation/passport-twitter.git",
"passport-windowslive": "^1.0.2",
"prom-client": "^14.0.1",
"ramda": "^0.27.2",
"redis": "^3.1.2",
"sha1": "^1.1.1",
"stomp-client": "^0.9.0",
Expand All @@ -77,13 +78,8 @@
"chai-files": "^1.4.0",
"chai-http": "^4.3.0",
"codecov": "^3.8.3",
"eslint": "^8.30.0",
"lint-staged": "^11.2.6",
"nock": "^13.2.9",
"nyc": "^15.1.0",
"rewire": "^6.0.0",
"standard-version": "^9.5.0",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.30.0",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-chai-friendly": "^0.7.1",
"eslint-plugin-import": "^2.26.0",
Expand All @@ -94,8 +90,13 @@
"fakeredis": "^2.0.0",
"git-commit-msg-linter": "^3.1.0",
"husky": "^7.0.4",
"lint-staged": "^11.2.6",
"mocha": "^9.2.2",
"sinon": "^12.0.1"
"nock": "^13.2.9",
"nyc": "^15.1.0",
"rewire": "^6.0.0",
"sinon": "^12.0.1",
"standard-version": "^9.5.0"
},
"repository": {
"type": "git",
Expand Down
86 changes: 19 additions & 67 deletions server/utils/openid-client-helper.js
Original file line number Diff line number Diff line change
@@ -1,110 +1,64 @@
const jose = require('jose')
const { JWK: { generateSync, asKey }, JWKS: { KeyStore } } = require('jose')
const { JWK: { generateSync, asKey }, JWKS: { KeyStore } } = require('jose_v2')
const { Issuer } = require('openid-client')
const path = require('path')
const fs = require('fs')
const fileUtils = require('../utils/file-utils')
const { logger } = require('./logging')
const clientJWKSFilePath = path.join(`${process.cwd()}/server`, 'jwks')
const secretKey = require('./misc').secretKey();
let ks = new KeyStore();
const keysPath = "/run/keyvault/keys/";
const secretKey = require('./misc').secretKey()
let ks = new KeyStore()
const keysPath = '/run/keyvault/keys/'

/**
* generate jwks and store it in file. file name will be like [provider.id].json
* @param {*} provider
* @returns undefined
*/
async function generateJWKS (provider) {
const keyType = generateSync('RSA')
const keyStore = new KeyStore(keyType)
const fileName = path.join(fileUtils.makeDir(clientJWKSFilePath), provider.id + '.json')
if (fs.existsSync(fileName)) {
return
if (!fs.existsSync(fileName)) {
await fileUtils.writeDataToFile(fileName, JSON.stringify(keyStore.toJWKS(true)))
}

const { privateKey, publicKey } = await jose.generateKeyPair('RS256')
const privateJwk = await jose.exportJWK(privateKey)
const publicJwk = await jose.exportJWK(publicKey)
const kid = await jose.calculateJwkThumbprint(publicJwk)
privateJwk.kid = kid
await fileUtils.writeDataToFile(fileName, JSON.stringify({ keys: [privateJwk] }))
}

/**
* get keystore after creating and adding private keys
* @returns keystore
*/
async function getKeystore () {
async function getKeystore () {
logger.log('verbose', 'Importing private keys into the keystore')

fs.readdirSync(keysPath).forEach(file => {
const akeyPath = path.resolve(keysPath, file);
const akeyPath = path.resolve(keysPath, file)
if (fs.lstatSync(akeyPath).isFile()) {
const fileNameRegExp = /(.*?)_(.*?)_(.*?)\.pem/;
const matches = file.match(fileNameRegExp);
const fileNameRegExp = /(.*?)_(.*?)_(.*?)\.pem/
const matches = file.match(fileNameRegExp)

if (matches.length == 4) { // file naming: keydId_use_alg.pem
try {
const keyObj = {
key: fs.readFileSync(akeyPath, 'utf8'),
passphrase: secretKey
}

const opts = {
kid: `${matches[1]}_${matches[2]}_${matches[3]}`,
use: matches[2],
alg: matches[3].toUpperCase()
}

// Create the key and add it to the keystore
const key = asKey(keyObj, opts)
ks.add(key)
} catch (err) {
const msg = 'Private key was not successfully added to the keystore.'
logger.log('error', `${msg} key: ${file}, error: ${err}`)
}
}
}
});

return ks
}

/**
* get keystore after creating and adding private keys
* @returns keystore
*/
async function getKeystore () {
logger.log('verbose', 'Importing private keys into the keystore')

fs.readdirSync(keysPath).forEach(file => {
const akeyPath = path.resolve(keysPath, file);
if (fs.lstatSync(akeyPath).isFile()) {
const fileNameRegExp = /(.*?)_(.*?)_(.*?)\.pem/;
const matches = file.match(fileNameRegExp);

if (matches.length == 4) { // file naming: keydId_use_alg.pem
try {
const keyObj = {
key: fs.readFileSync(akeyPath, 'utf8'),
passphrase: secretKey
}

const opts = {
kid: `${matches[1]}_${matches[2]}_${matches[3]}`,
use: matches[2],
alg: matches[3].toUpperCase()
}

// Create the key and add it to the keystore
const key = asKey(keyObj, opts)
const key = asKey(keyObj, opts)
ks.add(key)
} catch (err) {
const msg = 'Private key was not successfully added to the keystore.'
logger.log('error', `${msg} key: ${file}, error: ${err}`)
}
}
}
});
})

return ks
}
Expand Down Expand Up @@ -139,12 +93,10 @@ async function getClient (provider) {
}

const issuer = await getIssuer(options)

if (options.token_endpoint_auth_method && options.token_endpoint_auth_method === 'private_key_jwt') {
// generate jwks
await generateJWKS(provider)
const jwks = require(path.join(fileUtils.makeDir(clientJWKSFilePath), `${provider.id}.json`))
client = new issuer.Client(options, jwks)
if (options.token_endpoint_auth_method && options.token_endpoint_auth_method === 'private_key_jwt' && options.use_request_object && options.use_request_object.toString() === 'true') {
// getKeystore with private keys
if (ks.size === 0) ks = await getKeystore()
client = new issuer.Client(options, ks.toJWKS(true))
} else {
client = new issuer.Client(options)
}
Expand Down

0 comments on commit af21b27

Please sign in to comment.