diff --git a/.env b/.env index 2b45cbc..3c9007f 100644 --- a/.env +++ b/.env @@ -11,3 +11,4 @@ LOGIN_HINT: "" MCP_ID_TOKEN_SIGNED_RESPONSE_ALG: RS256 MCP_USERINFO_SIGNED_RESPONSE_ALG: "" ACR_VALUES: "" +SESSION_SECRET: CeciEstUnFauxSecret diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90c5853..a553871 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,9 @@ name: CI on: push: - pull_request: + branches: + - "**" + - "!master" workflow_dispatch: jobs: diff --git a/agentconnect.env b/agentconnect.env new file mode 100644 index 0000000..f4a4ea5 --- /dev/null +++ b/agentconnect.env @@ -0,0 +1,15 @@ +HOST: http://localhost:3000 +PORT: 3000 +SITE_TITLE: "Bonjour monde !" +STYLESHEET_URL: https://unpkg.com/bamboo.css +CALLBACK_URL: /login-callback +MCP_CLIENT_ID: client_id_localhost:3000 +MCP_CLIENT_SECRET: client_secret_localhost:3000 +MCP_PROVIDER: https://fca.integ01.dev-agentconnect.fr/api/v2 +MCP_SCOPES: "openid given_name usual_name email phone uid siren siret idp_id idp_acr" +LOGIN_HINT: "" +MCP_ID_TOKEN_SIGNED_RESPONSE_ALG: RS256 +MCP_USERINFO_SIGNED_RESPONSE_ALG: RS256 +ACR_VALUES: eidas1 +SESSION_SECRET: CeciEstUnFauxSecret +SHOW_AGENTCONNECT_BUTTON: true diff --git a/e2e/features/connexion.feature b/e2e/features/connexion.feature index afc7050..42706ad 100644 --- a/e2e/features/connexion.feature +++ b/e2e/features/connexion.feature @@ -1,15 +1,15 @@ #language: fr Fonctionnalité: Connexion de user@yopmail.com - - Scénario: Connexion d'un utilisateur + + Scénario: Connexion d'un utilisateur Etant donné que je navigue sur la page Alors je vois "Bonjour monde !" Quand je clique sur le bouton MonComptePro Quand je me connecte en tant que user@yopmail.com sur moncomptepro Et je vois "Votre organisation de rattachement" sur moncomptepro - Et je click sur "Continuer" sur moncomptepro + Et je clique sur "Continuer" sur moncomptepro Alors je suis redirigé sur "/" - Et je vois "Information utilisateur" + Et je vois "Information utilisateur" Et je vois "user@yopmail.com" diff --git a/e2e/features/connexion.ts b/e2e/features/connexion.ts index 6ebf8ea..010e293 100644 --- a/e2e/features/connexion.ts +++ b/e2e/features/connexion.ts @@ -28,7 +28,7 @@ When("je vois {string} sur moncomptepro", (_text: string) => { }); }); -When("je click sur {string} sur moncomptepro", (_text: string) => { +When("je clique sur {string} sur moncomptepro", (_text: string) => { cy.origin(Cypress.env("MCP_PROVIDER"), { args: _text }, (text) => { cy.contains(text).click(); }); diff --git a/index.js b/index.js index e11312a..e268eab 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ import "dotenv/config"; import express from "express"; import { Issuer } from "openid-client"; -import cookieSession from "cookie-session"; +import session from "express-session"; import morgan from "morgan"; import * as crypto from "crypto"; @@ -13,10 +13,11 @@ const app = express(); app.set("view engine", "ejs"); app.use( - cookieSession({ + session({ name: "mcp_session", - keys: ["key1", "key2"], - }) + secret: process.env.SESSION_SECRET, + rolling: true, + }), ); app.use(morgan("combined")); @@ -86,14 +87,14 @@ app.post( "/select-organization", getAuthorizationControllerFactory({ prompt: "select_organization", - }) + }), ); app.post( "/update-userinfo", getAuthorizationControllerFactory({ prompt: "update_userinfo", - }) + }), ); app.post( @@ -103,7 +104,7 @@ app.post( prompt: "login", // alternatively, you can use the 'max_age: 0' // if so, claims parameter is not necessary as auth_time will be returned - }) + }), ); app.get(process.env.CALLBACK_URL, async (req, res, next) => { @@ -120,7 +121,7 @@ app.get(process.env.CALLBACK_URL, async (req, res, next) => { 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; res.redirect("/"); } catch (e) { next(e); @@ -130,7 +131,7 @@ app.get(process.env.CALLBACK_URL, async (req, res, next) => { app.post("/logout", async (req, res, next) => { try { const id_token_hint = req.session.id_token_hint; - req.session = null; + req.session.destroy(); const client = await getMcpClient(); const redirectUrl = client.endSessionUrl({ post_logout_redirect_uri: `${origin}/`, diff --git a/package-lock.json b/package-lock.json index 979f504..35a4832 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,10 @@ "version": "1.0.0", "license": "AGPL-3.0", "dependencies": { - "cookie-session": "^2.1.0", "dotenv": "^16.4.5", "ejs": "^3.1.10", "express": "^4.19.2", + "express-session": "^1.18.0", "morgan": "^1.10.0", "openid-client": "^5.6.5" }, @@ -202,50 +202,11 @@ "node": ">= 0.6" } }, - "node_modules/cookie-session": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-2.1.0.tgz", - "integrity": "sha512-u73BDmR8QLGcs+Lprs0cfbcAPKl2HnPcjpwRXT41sEV4DRJ2+W0vJEEZkG31ofkx+HZflA70siRIjiTdIodmOQ==", - "dependencies": { - "cookies": "0.9.1", - "debug": "3.2.7", - "on-headers": "~1.0.2", - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cookie-session/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/cookie-session/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "node_modules/cookies": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", - "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", - "dependencies": { - "depd": "~2.0.0", - "keygrip": "~1.1.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -398,6 +359,29 @@ "node": ">= 0.10.0" } }, + "node_modules/express-session": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz", + "integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==", + "dependencies": { + "cookie": "0.6.0", + "cookie-signature": "1.0.7", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express-session/node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -611,17 +595,6 @@ "url": "https://github.com/sponsors/panva" } }, - "node_modules/keygrip": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", - "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", - "dependencies": { - "tsscmp": "1.0.6" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -845,6 +818,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -998,14 +979,6 @@ "node": ">=0.6" } }, - "node_modules/tsscmp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", - "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", - "engines": { - "node": ">=0.6.x" - } - }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1018,6 +991,17 @@ "node": ">= 0.6" } }, + "node_modules/uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "dependencies": { + "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1186,46 +1170,11 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" }, - "cookie-session": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-2.1.0.tgz", - "integrity": "sha512-u73BDmR8QLGcs+Lprs0cfbcAPKl2HnPcjpwRXT41sEV4DRJ2+W0vJEEZkG31ofkx+HZflA70siRIjiTdIodmOQ==", - "requires": { - "cookies": "0.9.1", - "debug": "3.2.7", - "on-headers": "~1.0.2", - "safe-buffer": "5.2.1" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "cookies": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", - "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", - "requires": { - "depd": "~2.0.0", - "keygrip": "~1.1.0" - } - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1338,6 +1287,28 @@ "vary": "~1.1.2" } }, + "express-session": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz", + "integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==", + "requires": { + "cookie": "0.6.0", + "cookie-signature": "1.0.7", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" + } + } + }, "filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -1490,14 +1461,6 @@ "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==" }, - "keygrip": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", - "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", - "requires": { - "tsscmp": "1.0.6" - } - }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -1651,6 +1614,11 @@ "side-channel": "^1.0.4" } }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==" + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1762,11 +1730,6 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, - "tsscmp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", - "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==" - }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1776,6 +1739,14 @@ "mime-types": "~2.1.24" } }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index 4000b38..d4e3273 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,10 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "cookie-session": "^2.1.0", "dotenv": "^16.4.5", "ejs": "^3.1.10", "express": "^4.19.2", + "express-session": "^1.18.0", "morgan": "^1.10.0", "openid-client": "^5.6.5" },