From 78e261bd65e49a5fe5c03eeaedffd18c23914631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Dubigny?= Date: Tue, 19 Nov 2024 19:57:19 +0100 Subject: [PATCH] Dependabot/npm and yarn/openid client 6.1.3 (#36) * chore(deps): bump openid-client from 5.7.0 to 6.1.3 Bumps [openid-client](https://github.com/panva/openid-client) from 5.7.0 to 6.1.3. - [Release notes](https://github.com/panva/openid-client/releases) - [Changelog](https://github.com/panva/openid-client/blob/main/CHANGELOG.md) - [Commits](https://github.com/panva/openid-client/compare/v5.7.0...v6.1.3) --- updated-dependencies: - dependency-name: openid-client dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * chore: update to openid-client v6 * refactor: more readablity with lodash * fix: setup node in ci * add log error for token * log session * do not log session * add log config * add log protocol and origin * try enabling trust proxy * delete logs --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Benoit Serrano --- .github/workflows/ci.yml | 4 ++ index.js | 117 ++++++++++++++++++++++----------------- package-lock.json | 109 +++++++++++++----------------------- package.json | 3 +- views/index.ejs | 2 +- 5 files changed, 109 insertions(+), 126 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a553871..b51950c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + cache: "npm" + node-version-file: package.json - run: npm ci - name: Cypress run uses: cypress-io/github-action@v6 diff --git a/index.js b/index.js index 7547668..0df427c 100644 --- a/index.js +++ b/index.js @@ -1,15 +1,12 @@ import "dotenv/config"; import express from "express"; -import { Issuer } from "openid-client"; +import * as client from "openid-client"; import session from "express-session"; import morgan from "morgan"; -import * as crypto from "crypto"; import bodyParser from "body-parser"; +import { chain, isObject } from "lodash-es"; const port = parseInt(process.env.PORT, 10) || 3000; -const origin = `${process.env.HOST}`; -const redirectUri = `${origin}${process.env.CALLBACK_URL}`; - const app = express(); app.set("view engine", "ejs"); @@ -20,33 +17,38 @@ app.use( rolling: true, }), ); +app.enable('trust proxy'); app.use(morgan("combined")); -const removeNullValues = (obj) => Object.entries(obj).reduce((a,[k,v]) => (v ? (a[k]=v, a) : a), {}) - -const getMcpClient = async () => { - const mcpIssuer = await Issuer.discover(process.env.PC_PROVIDER); - - return new mcpIssuer.Client({ - client_id: process.env.PC_CLIENT_ID, - client_secret: process.env.PC_CLIENT_SECRET, - redirect_uris: [redirectUri], - response_types: ["code"], - id_token_signed_response_alg: process.env.PC_ID_TOKEN_SIGNED_RESPONSE_ALG, - userinfo_signed_response_alg: - process.env.PC_USERINFO_SIGNED_RESPONSE_ALG || null, - }); +const objToUrlParams = (obj) => + new URLSearchParams( + chain(obj) + .omitBy((v) => !v) + .mapValues((o) => (isObject(o) ? JSON.stringify(o) : o)) + .value(), + ); + +const getCurrentUrl = (req) => + new URL(`${req.protocol}://${req.get("host")}${req.originalUrl}`); + +const getProviderConfig = async () => { + return await client.discovery( + new URL(process.env.PC_PROVIDER), + process.env.PC_CLIENT_ID, + { + client_secret: process.env.PC_CLIENT_SECRET, + id_token_signed_response_alg: process.env.PC_ID_TOKEN_SIGNED_RESPONSE_ALG, + userinfo_signed_response_alg: + process.env.PC_USERINFO_SIGNED_RESPONSE_ALG || null, + }, + ); }; -const acr_values = process.env.ACR_VALUES - ? process.env.ACR_VALUES.split(",") - : null; -const login_hint = process.env.LOGIN_HINT || null; -const scope = process.env.PC_SCOPES; const AUTHORIZATION_DEFAULT_PARAMS = { - scope, - login_hint, - acr_values, + redirect_uri: `${process.env.HOST}${process.env.CALLBACK_URL}`, + scope: process.env.PC_SCOPES, + login_hint: process.env.LOGIN_HINT || null, + acr_values: process.env.ACR_VALUES ? process.env.ACR_VALUES.split(",") : null, claims: { id_token: { amr: { @@ -75,19 +77,22 @@ app.get("/", async (req, res, next) => { const getAuthorizationControllerFactory = (extraParams) => { return async (req, res, next) => { try { - const client = await getMcpClient(); - const nonce = crypto.randomBytes(16).toString("hex"); - const state = crypto.randomBytes(16).toString("hex"); + const config = await getProviderConfig(); + const nonce = client.randomNonce(); + const state = client.randomState(); req.session.state = state; req.session.nonce = nonce; - const redirectUrl = client.authorizationUrl(removeNullValues({ - nonce, - state, - ...AUTHORIZATION_DEFAULT_PARAMS, - ...extraParams, - })); + const redirectUrl = client.buildAuthorizationUrl( + config, + objToUrlParams({ + nonce, + state, + ...AUTHORIZATION_DEFAULT_PARAMS, + ...extraParams, + }), + ); res.redirect(redirectUrl); } catch (e) { @@ -143,7 +148,7 @@ app.post( "/custom-connection", bodyParser.urlencoded({ extended: false }), (req, res, next) => { - const customParams = JSON.parse(req.body['custom-params']) + const customParams = JSON.parse(req.body["custom-params"]); return getAuthorizationControllerFactory(customParams)(req, res, next); }, @@ -151,21 +156,27 @@ app.post( app.get(process.env.CALLBACK_URL, async (req, res, next) => { try { - const client = await getMcpClient(); - const params = client.callbackParams(req); - const tokenSet = await client.callback(redirectUri, params, { - nonce: req.session.nonce, - state: req.session.state, + const config = await getProviderConfig(); + const currentUrl = getCurrentUrl(req); + const tokens = await client.authorizationCodeGrant(config, currentUrl, { + expectedNonce: req.session.nonce, + expectedState: req.session.state, }); req.session.nonce = null; req.session.state = null; - req.session.userinfo = await client.userinfo(tokenSet.access_token); - req.session.idtoken = tokenSet.claims(); - req.session.id_token_hint = tokenSet.id_token; - req.session.oauth2token = tokenSet; + const claims = tokens.claims(); + req.session.userinfo = await client.fetchUserInfo( + config, + tokens.access_token, + claims.sub, + ); + req.session.idtoken = claims; + req.session.id_token_hint = tokens.id_token; + req.session.oauth2token = tokens; res.redirect("/"); } catch (e) { + console.error(e) next(e); } }); @@ -174,11 +185,14 @@ app.post("/logout", async (req, res, next) => { try { const id_token_hint = req.session.id_token_hint; req.session.destroy(); - const client = await getMcpClient(); - const redirectUrl = client.endSessionUrl({ - post_logout_redirect_uri: `${origin}/`, - id_token_hint, - }); + const config = await getProviderConfig(); + const redirectUrl = client.buildEndSessionUrl( + config, + objToUrlParams({ + post_logout_redirect_uri: `${process.env.HOST}/`, + id_token_hint, + }), + ); res.redirect(redirectUrl); } catch (e) { @@ -188,5 +202,4 @@ app.post("/logout", async (req, res, next) => { app.listen(port, () => { console.log(`App listening on port ${port}`); - console.log(process.env); }); diff --git a/package-lock.json b/package-lock.json index b240a09..b4b7530 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,8 +14,9 @@ "ejs": "^3.1.10", "express": "^4.21.1", "express-session": "^1.18.1", + "lodash-es": "^4.17.21", "morgan": "^1.10.0", - "openid-client": "^5.7.0" + "openid-client": "^6.1.3" }, "devDependencies": { "prettier": "^3.3.3" @@ -597,23 +598,17 @@ } }, "node_modules/jose": { - "version": "4.15.9", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", - "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "version": "5.9.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.9.6.tgz", + "integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==", "funding": { "url": "https://github.com/sponsors/panva" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "node_modules/media-typer": { "version": "0.3.0", @@ -719,12 +714,12 @@ "node": ">= 0.6" } }, - "node_modules/object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "engines": { - "node": ">= 6" + "node_modules/oauth4webapi": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.1.2.tgz", + "integrity": "sha512-KQZkNU+xn02lWrFu5Vjqg9E81yPtDSxUZorRHlLWVoojD+H/0GFbH59kcnz5Thdjj7c4/mYMBPj/mhvGe/kKXA==", + "funding": { + "url": "https://github.com/sponsors/panva" } }, "node_modules/object-inspect": { @@ -738,14 +733,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/oidc-token-hash": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", - "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==", - "engines": { - "node": "^10.13.0 || >=12.0.0" - } - }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -766,14 +753,12 @@ } }, "node_modules/openid-client": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.0.tgz", - "integrity": "sha512-4GCCGZt1i2kTHpwvaC/sCpTpQqDnBzDzuJcJMbH+y1Q5qI8U8RBvoSh28svarXszZHR5BAMXbJPX1PGPRE3VOA==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.1.3.tgz", + "integrity": "sha512-74sc0bR4ptfwCwMheLPaJHTQnds+97Yu6O8eQgoO3MRcd53xkfKyl3gNAsRsYSYoO+AVG3eCgnRMjRkZ6n2RYw==", "dependencies": { - "jose": "^4.15.9", - "lru-cache": "^6.0.0", - "object-hash": "^2.2.0", - "oidc-token-hash": "^5.0.3" + "jose": "^5.9.6", + "oauth4webapi": "^3.1.1" }, "funding": { "url": "https://github.com/sponsors/panva" @@ -1048,11 +1033,6 @@ "engines": { "node": ">= 0.8" } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } }, "dependencies": { @@ -1487,17 +1467,14 @@ } }, "jose": { - "version": "4.15.9", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", - "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==" - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } + "version": "5.9.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.9.6.tgz", + "integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==" + }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "media-typer": { "version": "0.3.0", @@ -1572,21 +1549,16 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" + "oauth4webapi": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.1.2.tgz", + "integrity": "sha512-KQZkNU+xn02lWrFu5Vjqg9E81yPtDSxUZorRHlLWVoojD+H/0GFbH59kcnz5Thdjj7c4/mYMBPj/mhvGe/kKXA==" }, "object-inspect": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" }, - "oidc-token-hash": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", - "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==" - }, "on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -1601,14 +1573,12 @@ "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" }, "openid-client": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.0.tgz", - "integrity": "sha512-4GCCGZt1i2kTHpwvaC/sCpTpQqDnBzDzuJcJMbH+y1Q5qI8U8RBvoSh28svarXszZHR5BAMXbJPX1PGPRE3VOA==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.1.3.tgz", + "integrity": "sha512-74sc0bR4ptfwCwMheLPaJHTQnds+97Yu6O8eQgoO3MRcd53xkfKyl3gNAsRsYSYoO+AVG3eCgnRMjRkZ6n2RYw==", "requires": { - "jose": "^4.15.9", - "lru-cache": "^6.0.0", - "object-hash": "^2.2.0", - "oidc-token-hash": "^5.0.3" + "jose": "^5.9.6", + "oauth4webapi": "^3.1.1" } }, "parseurl": { @@ -1796,11 +1766,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } } diff --git a/package.json b/package.json index b9dda26..9c794db 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,9 @@ "ejs": "^3.1.10", "express": "^4.21.1", "express-session": "^1.18.1", + "lodash-es": "^4.17.21", "morgan": "^1.10.0", - "openid-client": "^5.7.0" + "openid-client": "^6.1.3" }, "devDependencies": { "prettier": "^3.3.3" diff --git a/views/index.ejs b/views/index.ejs index 4278b02..6ad19b5 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -101,7 +101,7 @@

La liste des paramètres utilisables est disponible dans la