From 4b3240acc25c8c504a54e7158e4b0742c88d6e1b Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Thu, 23 May 2024 11:46:46 +0200 Subject: [PATCH 01/19] upgrade DSFR --- package-lock.json | 20 +++--- package.json | 2 +- static/css/custom.css | 19 +++--- views/dashboard.ejs | 2 +- views/landing.ejs | 2 +- views/partials/dark-mode-modale.ejs | 81 +++++++++++++++-------- views/partials/dark-mode-switch.ejs | 8 ++- views/partials/footer.ejs | 4 +- views/partials/header.ejs | 9 +-- views/partials/notificationError.ejs | 2 +- views/partials/notificationInfo.ejs | 2 +- views/partials/notificationSuccess.ejs | 2 +- views/partials/unsafeAnnouncementInfo.ejs | 2 +- 13 files changed, 92 insertions(+), 63 deletions(-) diff --git a/package-lock.json b/package-lock.json index 12cd1bdd..f718c3e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "conferences", - "version": "1.6.1", + "version": "1.6.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "conferences", - "version": "1.6.1", + "version": "1.6.2", "license": "MIT", "dependencies": { - "@gouvfr/dsfr": "^1.0.0-rc1.0", + "@gouvfr/dsfr": "^1.11.2", "@sentry/node": "^6.2.2", "chart.js": "^2.9.4", "connect-flash": "^0.1.1", @@ -242,11 +242,11 @@ } }, "node_modules/@gouvfr/dsfr": { - "version": "1.0.0-rc1.0", - "resolved": "https://registry.npmjs.org/@gouvfr/dsfr/-/dsfr-1.0.0-rc1.0.tgz", - "integrity": "sha512-mXfun0FzqeSgfyti6SsdPQHSpNsQBOJNkzZtvoN8KfaUGP3asupaMXe2CbRgrkV3ogqM0n/vToWjYjLzBwPxuQ==", + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@gouvfr/dsfr/-/dsfr-1.11.2.tgz", + "integrity": "sha512-S7idT4rCCw6M1pqxJS8y4nUSq/Rus+Kucoifmv0CrZD/eoBA34HWqWYzR9GIxvtAX/TQ1XC7Hz+54THtVzMeqQ==", "engines": { - "node": ">=12.13.0" + "node": ">=18.16.1" } }, "node_modules/@jridgewell/gen-mapping": { @@ -6266,9 +6266,9 @@ } }, "@gouvfr/dsfr": { - "version": "1.0.0-rc1.0", - "resolved": "https://registry.npmjs.org/@gouvfr/dsfr/-/dsfr-1.0.0-rc1.0.tgz", - "integrity": "sha512-mXfun0FzqeSgfyti6SsdPQHSpNsQBOJNkzZtvoN8KfaUGP3asupaMXe2CbRgrkV3ogqM0n/vToWjYjLzBwPxuQ==" + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@gouvfr/dsfr/-/dsfr-1.11.2.tgz", + "integrity": "sha512-S7idT4rCCw6M1pqxJS8y4nUSq/Rus+Kucoifmv0CrZD/eoBA34HWqWYzR9GIxvtAX/TQ1XC7Hz+54THtVzMeqQ==" }, "@jridgewell/gen-mapping": { "version": "0.3.3", diff --git a/package.json b/package.json index 85ef893c..f0e21983 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/betagouv/conferences#readme", "dependencies": { - "@gouvfr/dsfr": "^1.0.0-rc1.0", + "@gouvfr/dsfr": "^1.11.2", "@sentry/node": "^6.2.2", "chart.js": "^2.9.4", "connect-flash": "^0.1.1", diff --git a/static/css/custom.css b/static/css/custom.css index 8f8ed467..65c790ac 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -10,14 +10,17 @@ margin-bottom: 56px !important; /* fr-mb-7w */ } -/* Todo : use callouts from the design system instead of home-made paragraphs ? */ +.bandeau-principal { + background-color: var(--background-contrast-grey); +} + .error-text { - color: var(--error); + color: var(--text-default-error); } .cell--info { - background-color: var(--info); + background-color: var(--background-alt-blue-france); } .notification--error { @@ -29,17 +32,11 @@ } .notification--info { - --scheme-border: var(--info); + --scheme-border: var(--background-alt-blue-france); } .notification--success { - --scheme-border: var(--success); -} - - -.fr-bg--alt { - background-color: var(--bf500); - color: var(--g100); + --scheme-border: var(--background-flat-success); } .text-center { diff --git a/views/dashboard.ejs b/views/dashboard.ejs index dd6ce410..bf9cae9a 100644 --- a/views/dashboard.ejs +++ b/views/dashboard.ejs @@ -6,7 +6,7 @@ Tableau de bord de votre conférence

-
+

diff --git a/views/landing.ejs b/views/landing.ejs index 72e29630..52d019ad 100644 --- a/views/landing.ejs +++ b/views/landing.ejs @@ -79,7 +79,7 @@
-
+

Collaborez à distance facilement

diff --git a/views/partials/dark-mode-modale.ejs b/views/partials/dark-mode-modale.ejs index c8b1afe9..9c6e41f9 100644 --- a/views/partials/dark-mode-modale.ejs +++ b/views/partials/dark-mode-modale.ejs @@ -1,36 +1,61 @@ -
-
-
-
-
- -
-
-

- Paramètres d’affichage -

-
-
- Choisissez un thème pour personnaliser l’apparence - du site. -
-
- - +
+
+
+
+
+ +
+
+

Paramètres d’affichage

+
+
+ Choisissez un thème pour personnaliser l’apparence du site. +
+
+ + +
+ +
+
+
+
+
+ + +
+ +
+
-
- - +
+
+ + +
+ +
+
-
-
+
+
-
- + diff --git a/views/partials/dark-mode-switch.ejs b/views/partials/dark-mode-switch.ejs index 39ef4909..5f6e0bad 100644 --- a/views/partials/dark-mode-switch.ejs +++ b/views/partials/dark-mode-switch.ejs @@ -1 +1,7 @@ - \ No newline at end of file + diff --git a/views/partials/footer.ejs b/views/partials/footer.ejs index 0ec241f6..08f7e5c2 100644 --- a/views/partials/footer.ejs +++ b/views/partials/footer.ejs @@ -1,5 +1,5 @@ - - + + <% if (locals.rizomoURI !== undefined) { %> <% } %> diff --git a/views/partials/header.ejs b/views/partials/header.ejs index c471c9f8..a9a50399 100644 --- a/views/partials/header.ejs +++ b/views/partials/header.ejs @@ -1,5 +1,5 @@ - + @@ -12,8 +12,9 @@ <% } %> - + + @@ -52,7 +53,7 @@
- \ No newline at end of file + diff --git a/views/partials/notificationError.ejs b/views/partials/notificationError.ejs index ff5cae8a..9d23385a 100644 --- a/views/partials/notificationError.ejs +++ b/views/partials/notificationError.ejs @@ -1,4 +1,4 @@ -
+
<% if (error.message) { %>

<%= error.message %>

<% if (error.withContactLink) { %> diff --git a/views/partials/notificationInfo.ejs b/views/partials/notificationInfo.ejs index a21c025f..73358297 100644 --- a/views/partials/notificationInfo.ejs +++ b/views/partials/notificationInfo.ejs @@ -1,4 +1,4 @@ -
+

<%= info %>

diff --git a/views/partials/notificationSuccess.ejs b/views/partials/notificationSuccess.ejs index ce80fd2a..9e1faf9e 100644 --- a/views/partials/notificationSuccess.ejs +++ b/views/partials/notificationSuccess.ejs @@ -1,3 +1,3 @@ -
+

<%= success %>

diff --git a/views/partials/unsafeAnnouncementInfo.ejs b/views/partials/unsafeAnnouncementInfo.ejs index 8b4ed89e..ec3f715f 100644 --- a/views/partials/unsafeAnnouncementInfo.ejs +++ b/views/partials/unsafeAnnouncementInfo.ejs @@ -2,6 +2,6 @@ Use this template to display info messages containing HTML. WARNING : this template does not escape HTML, so be sure that no user-provided data is displayed in it, to avoid injection attacks. (google "server side template injection" to learn about it) --> -
+

<%- info %>

From bc20e901c29aafbe5716e0fef187a93558ff79af Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Thu, 23 May 2024 15:05:08 +0200 Subject: [PATCH 02/19] add bandeau information --- views/landing.ejs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/views/landing.ejs b/views/landing.ejs index 52d019ad..91b88412 100644 --- a/views/landing.ejs +++ b/views/landing.ejs @@ -1,6 +1,15 @@ <%- include('partials/header') -%>
+
+
+
+

+ Audioconf change de mode d'authentification au 30/05/2024 pour Agent Connect ! +

+
+
+
From 880cb4801afcd64194b9dab28c3d8b380dfad762 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Thu, 23 May 2024 15:17:59 +0200 Subject: [PATCH 03/19] change date MEP --- views/landing.ejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/landing.ejs b/views/landing.ejs index 91b88412..a13ef463 100644 --- a/views/landing.ejs +++ b/views/landing.ejs @@ -5,7 +5,7 @@

- Audioconf change de mode d'authentification au 30/05/2024 pour Agent Connect ! + Audioconf change de mode d'authentification au 27/05/2024 pour Agent Connect !

From fdbfaf66fe93a82431f0ce8a40d10601581e88a1 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Mon, 29 Apr 2024 18:04:04 +0200 Subject: [PATCH 04/19] add acr_values and alg params --- config.js | 3 +++ lib/oidcAuth.js | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/config.js b/config.js index d68a3ad8..4c6da8de 100644 --- a/config.js +++ b/config.js @@ -112,6 +112,9 @@ config.STATS_EXTERNAL_DASHBOARD_URL = process.env.STATS_EXTERNAL_DASHBOARD_URL config.OIDC_PROVIDER_URL = process.env.OIDC_PROVIDER_URL config.OIDC_CLIENT_ID = process.env.OIDC_CLIENT_ID config.OIDC_CLIENT_SECRET = process.env.OIDC_CLIENT_SECRET +config.OIDC_ACR_VALUES = process.env.OIDC_ACR_VALUES +config.OIDC_ID_TOKEN_SIGNED_ALG = process.env.OIDC_ID_TOKEN_SIGNED_ALG +config.OIDC_USER_INFO_SIGNED_ALG = process.env.OIDC_USER_INFO_SIGNED_ALG config.RIZOMO_URI = process.env.RIZOMO_URI diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index 62498a63..08264a10 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -24,8 +24,9 @@ module.exports.getClient = async () => { client_secret: config.OIDC_CLIENT_SECRET, redirect_uris: [config.HOSTNAME_WITH_PROTOCOL + urlCallback], response_types: ["code"], - // id_token_signed_response_alg (default "RS256") - // token_endpoint_auth_method (default "client_secret_basic") + id_token_signed_response_alg: config.OIDC_ID_TOKEN_SIGNED_ALG, + userinfo_signed_response_alg: config.OIDC_USER_INFO_SIGNED_ALG, + // token_endpoint_auth_method (default "client_secret_basic") }) return client @@ -51,6 +52,7 @@ module.exports.startAuth = async (email, conferenceDurationInMinutes, conference const redirectUrl = client.authorizationUrl({ scope: "openid", state, + acr_values: config.OIDC_ACR_VALUES, /* todo add this back code_challenge, code_challenge_method: 'S256', From b410e83eb85f218f56a572c3f1a6f54492297491 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Mon, 29 Apr 2024 18:11:31 +0200 Subject: [PATCH 05/19] add uid and email to scope --- lib/oidcAuth.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index 08264a10..89fc0f31 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -50,7 +50,7 @@ module.exports.startAuth = async (email, conferenceDurationInMinutes, conference const nonce = generators.random(128) const redirectUrl = client.authorizationUrl({ - scope: "openid", + scope: "openid uid email", state, acr_values: config.OIDC_ACR_VALUES, /* todo add this back From c87410bbc22acd0294ea0f1c7ac161362396f057 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Tue, 30 Apr 2024 16:32:24 +0200 Subject: [PATCH 06/19] do not send login hint --- lib/oidcAuth.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index 89fc0f31..0f2d0b3c 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -58,7 +58,7 @@ module.exports.startAuth = async (email, conferenceDurationInMinutes, conference code_challenge_method: 'S256', */ nonce, - login_hint: email + // login_hint: email }) // todo write test : null nonce fails From b007b00298633ac0b04cbfbb4925341782ada9b0 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Tue, 30 Apr 2024 16:47:23 +0200 Subject: [PATCH 07/19] add logs claims and userinfo --- lib/oidcAuth.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index 0f2d0b3c..4c6ae9ad 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -106,6 +106,11 @@ module.exports.finishAuth = async (req) => { } ) const claims = tokenSet.claims() + console.log(`CLAIMS : ${JSON.stringify(claims)}`) + const userinfo = await client.userinfo(tokenSet) + console.log(`USERINFO : ${JSON.stringify(userinfo)}`) + + const email = claims.preferred_username return { From ceeb4a289d1fb5864d0dea4a628f3f1ea66221b1 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Tue, 30 Apr 2024 17:01:29 +0200 Subject: [PATCH 08/19] use email from user info --- lib/oidcAuth.js | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index 4c6ae9ad..cdf006d4 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -96,23 +96,31 @@ module.exports.finishAuth = async (req) => { return { error: "L'identification a échoué. Entrez votre adresse mail ci-dessous pour recommencer." } } - const tokenSet = await client.callback( - config.HOSTNAME_WITH_PROTOCOL + urlCallback, - params, - { - state: request.state, - nonce: request.nonce - // todo code_verifier: req.session.code_verifier - } - ) - const claims = tokenSet.claims() - console.log(`CLAIMS : ${JSON.stringify(claims)}`) - const userinfo = await client.userinfo(tokenSet) - console.log(`USERINFO : ${JSON.stringify(userinfo)}`) + let tokenSet + try { + tokenSet = await client.callback( + config.HOSTNAME_WITH_PROTOCOL + urlCallback, + params, + { + state: request.state, + nonce: request.nonce + // todo code_verifier: req.session.code_verifier + } + ) + } catch(error){ + console.error("error when requesting token from OIDC", error) + return { error: "L'identification a échoué. Entrez votre adresse mail ci-dessous pour recommencer." } + } + let userinfo + try { + userinfo = await client.userinfo(tokenSet) + } catch(error){ + console.error("error when requesting userinfo from OIDC", error) + return { error: "L'identification a échoué. Entrez votre adresse mail ci-dessous pour recommencer." } + } + const email = userinfo.email - const email = claims.preferred_username - return { email, durationInMinutes: request.durationInMinutes, From 925528ad153a753e45d931938e29dea3c454485a Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Thu, 23 May 2024 16:30:00 +0200 Subject: [PATCH 09/19] delete magic link implementation --- .env.sample | 1 - config.js | 1 - controllers/createConfController.js | 7 +- controllers/startAuthController.js | 10 +- lib/magicLinkAuth.js | 84 ----------------- lib/oidcAuth.js | 4 +- test/createConfControllerTest.js | 36 ------- test/magicLinkAuthTest.js | 139 ---------------------------- test/oidcAuthTest.js | 5 - test/startAuthControllerTest.js | 68 -------------- views/landing.ejs | 13 ++- 11 files changed, 15 insertions(+), 353 deletions(-) delete mode 100644 lib/magicLinkAuth.js delete mode 100644 test/magicLinkAuthTest.js diff --git a/.env.sample b/.env.sample index 81c2e8e7..2bb8b60d 100644 --- a/.env.sample +++ b/.env.sample @@ -67,7 +67,6 @@ AFTER_MEETING_SURVEY_URL=https://startupdetat.typeform.com/to/CQhQfpVU ENCRYPT_SECRET=un_secret_avec_exactement_64_bit # Use OIDC auth instead of audioconf's magiclink auth -#FEATURE_OIDC=true #OIDC_PROVIDER_URL= #OIDC_CLIENT_ID= #OIDC_CLIENT_SECRET= diff --git a/config.js b/config.js index 4c6da8de..76c9e8c6 100644 --- a/config.js +++ b/config.js @@ -102,7 +102,6 @@ config.FEATURE_JOB_COMPUTE_STATS = process.env.FEATURE_JOB_COMPUTE_STATS === "tr config.FEATURE_JOB_ANONYMIZE_EMAILS = process.env.FEATURE_JOB_ANONYMIZE_EMAILS === "true" || false config.FEATURE_JOB_CALLS_STATS = process.env.FEATURE_JOB_CALLS_STATS === "true" || false config.FEATURE_WEB_ACCESS = process.env.FEATURE_WEB_ACCESS === "true" || false -config.FEATURE_OIDC = process.env.FEATURE_OIDC === "true" || false config.ANNOUNCEMENTS = process.env.ANNOUNCEMENTS ? process.env.ANNOUNCEMENTS.split("|") : [] diff --git a/controllers/createConfController.js b/controllers/createConfController.js index 9bc328cf..5de8eeca 100644 --- a/controllers/createConfController.js +++ b/controllers/createConfController.js @@ -5,7 +5,6 @@ const config = require("../config") const db = require("../lib/db") const emailer = require("../lib/emailer") const format = require("../lib/format") -const magicLinkAuth = require("../lib/magicLinkAuth") const oidcAuth = require("../lib/oidcAuth") const urls = require("../urls") const { isAcceptedEmail } = require("../lib/emailChecker") @@ -45,9 +44,7 @@ const createConfWithDay = async (email, conferenceDay, userTimezoneOffset) => { } module.exports.createConf = async (req, res) => { - const confData = await (config.FEATURE_OIDC ? - oidcAuth.finishAuth(req) : - magicLinkAuth.finishAuth(req)) + const confData = await oidcAuth.finishAuth(req) const { email, durationInMinutes, conferenceDay, userTimezoneOffset } = confData @@ -146,4 +143,4 @@ module.exports.cancelConf = async (req, res) => { function shouldSendWebAccessMail(email) { return isAcceptedEmail(email, config.EMAIL_WEB_ACCESS_WHITELIST) && config.FEATURE_WEB_ACCESS -} \ No newline at end of file +} diff --git a/controllers/startAuthController.js b/controllers/startAuthController.js index 0446421e..7768574d 100644 --- a/controllers/startAuthController.js +++ b/controllers/startAuthController.js @@ -1,22 +1,14 @@ -const config = require("../config.js") -const magicLinkAuth = require("../lib/magicLinkAuth") const oidcAuth = require("../lib/oidcAuth") - module.exports.startAuth = async (req, res) => { const userTimezoneOffset = req.body.userTimezoneOffset - const email = req.body.email const conferenceDurationInMinutes = req.body.durationInMinutes const conferenceDayString = req.body.day if (typeof conferenceDayString === 'undefined' && typeof conferenceDurationInMinutes === 'undefined') { throw new Error('Both conferenceDayString and conferenceDurationInMinutes are undefined. This should not happen.') } - const authRequest = await ( - config.FEATURE_OIDC ? - oidcAuth.startAuth(email, conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset) : - magicLinkAuth.startAuth(email, conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset) - ) + const authRequest = await oidcAuth.startAuth(conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset) if (authRequest.error) { console.log("Error in authentication", authRequest.error) diff --git a/lib/magicLinkAuth.js b/lib/magicLinkAuth.js deleted file mode 100644 index 1b6b8faa..00000000 --- a/lib/magicLinkAuth.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Usage : - * const authRequest = startAuth(email, conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset) - * - * If fail - * authRequest == { error: "error message"} - * - * If success - * authRequest == { redirectUrl : "" } - */ -const url = require("url") - -const config = require("../config") -const crypto = require("crypto") -const emailer = require("./emailer") -const { isAcceptedEmail, isValidEmail } = require("./emailChecker") -const urls = require("../urls") -const format = require("../lib/format") -const db = require("../lib/db") - -const generateToken = () => { - return crypto.randomBytes(256).toString("base64") -} - - -module.exports.startAuth = async (email, conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset) => { - if (!isValidEmail(email)) { - return { error: "Adresse mail invalide. Avez vous bien tapé votre adresse mail ? Vous pouvez réessayer." } - } - - if (!isAcceptedEmail(email, config.EMAIL_WHITELIST)) { - return { error: "Cette adresse mail ne correspond pas à une agence de l'État. Si vous appartenez à un service de l'État mais votre adresse mail n'est pas reconnue par AudioConf, contactez-nous pour que nous la rajoutions!" } - } - - const token = generateToken() - const tokenExpirationDate = new Date() - tokenExpirationDate.setMinutes(tokenExpirationDate.getMinutes() + config.TOKEN_DURATION_IN_MINUTES) - - const validationUrl = `${config.HOSTNAME_WITH_PROTOCOL}${urls.createConf}?token=${encodeURIComponent(token)}` - - try { - await emailer.sendEmailValidationEmail(email, tokenExpirationDate, validationUrl) - } catch(err) { - console.log("Erreur sur la création de token", err) - return { error : "Une erreur interne s'est produite, nous n'avons pas pu créer votre conférence." } - } - - const redirectUrl = url.format({ - pathname: urls.validationEmailSent, - query: { - email: email - }, - }) - - try { - await db.insertToken(email, token, tokenExpirationDate, conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset) - console.log(`Login token créé pour ${format.hashForLogs(email)}, il expire à ${tokenExpirationDate}`) - } catch(err) { - console.log("Error when inserting authrequest token in DB", err) - return { error: "Une erreur interne s'est produite, nous n'avons pas pu créer votre conférence." } - } - - return { redirectUrl } -} - -module.exports.finishAuth = async (req) => { - const token = req.query.token - - const confDatas = await db.getToken(token) - - const isTokenValid = confDatas.length === 1 - if (!isTokenValid) { - // todo use propoer error codes ? - return { error: "Ce lien de confirmation ne marche plus, il a expiré. Entrez votre adresse mail ci-dessous pour recommencer." } - } - - const confData = confDatas[0] - return { - email: confData.email, - durationInMinutes: confData.durationInMinutes, - conferenceDay: confData.conferenceDay, - userTimezoneOffset: confData.userTimezoneOffset, - } -} diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index cdf006d4..fddd8df9 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -32,7 +32,7 @@ module.exports.getClient = async () => { return client } -module.exports.startAuth = async (email, conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset) => { +module.exports.startAuth = async (conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset) => { const client = await this.getClient() /* todo : store the code_verifier in DB. We don't use it for now. @@ -64,7 +64,7 @@ module.exports.startAuth = async (email, conferenceDurationInMinutes, conference // todo write test : null nonce fails try { await db.insertOidcRequest(state, nonce, conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset) - console.log(`OIDC request créé pour ${format.hashForLogs(email)}`) + console.log(`OIDC request créé pour state ${state}`) } catch(err) { console.log("Error when inserting authrequest token in DB", err) return { error: "Une erreur interne s'est produite, nous n'avons pas pu créer votre conférence." } diff --git a/test/createConfControllerTest.js b/test/createConfControllerTest.js index 8308354b..31dfa21e 100644 --- a/test/createConfControllerTest.js +++ b/test/createConfControllerTest.js @@ -6,7 +6,6 @@ const app = require("../index") const conferences = require("../lib/conferences") const db = require("../lib/db") const emailer = require("../lib/emailer") -const magicLinkAuth = require("../lib/magicLinkAuth") const oidcAuth = require("../lib/oidcAuth") const urls = require("../urls") const { encrypt } = require("../lib/crypto") @@ -20,11 +19,9 @@ describe("createConfController", function() { let insertConfStub let sendWebAccessEmailStub - let oidcFlagBackupValue let webAccessFlagBackupValue beforeEach(function(done) { - oidcFlagBackupValue = config.FEATURE_OIDC webAccessFlagBackupValue = config.FEATURE_WEB_ACCESS config.FEATURE_WEB_ACCESS = true @@ -37,7 +34,6 @@ describe("createConfController", function() { }) afterEach(function(done) { - config.FEATURE_OIDC = oidcFlagBackupValue config.FEATURE_WEB_ACCESS = webAccessFlagBackupValue createConfStub.restore() @@ -47,42 +43,10 @@ describe("createConfController", function() { done() }) - describe("using magicLinkAuth", () => { - let magicLinkFinishAuthStub - - beforeEach(function() { - config.FEATURE_OIDC = false - magicLinkFinishAuthStub = sinon.stub(magicLinkAuth, "finishAuth") - }) - - afterEach(function() { - magicLinkFinishAuthStub.restore() - }) - - it("should create conf and send email", function(done) { - shouldCreateConfAndSendEmail(done, magicLinkFinishAuthStub) - }) - - it("should redirect when finishAuth has failed", function(done) { - shouldRedirectWhenFinishAuthHasFailed(done, magicLinkFinishAuthStub) - }) - - it("should redirect when conf was not created", function(done) { - shouldRedirectWhenConfWasNotCreated(done, magicLinkFinishAuthStub) - }) - - it("should redirect when email was not sent", function(done) { - shouldRedirectWhenEmailWasNotSent(done, magicLinkFinishAuthStub) - }) - - }) - - describe("using OIDC auth", () => { let oidcFinishAuthStub beforeEach(function() { - config.FEATURE_OIDC = true oidcFinishAuthStub = sinon.stub(oidcAuth, "finishAuth") }) diff --git a/test/magicLinkAuthTest.js b/test/magicLinkAuthTest.js deleted file mode 100644 index e20228cc..00000000 --- a/test/magicLinkAuthTest.js +++ /dev/null @@ -1,139 +0,0 @@ -const { expect } = require("chai") - -const config = require("../config") -const db = require("../lib/db") -const emailer = require("../lib/emailer") -const sinon = require("sinon") -const url = require("url") -const utils = require("./utils") - -const magicLinkAuth = require("../lib/magicLinkAuth") - -describe("magicLinkAuth", function() { - let sendEmailStub - let dbStub - let EMAIL_WHITELIST_BCK - - beforeEach(function(done) { - EMAIL_WHITELIST_BCK = config.EMAIL_WHITELIST - config.EMAIL_WHITELIST = [ /.*@(.*\.|)beta\.gouv\.fr/, /.*@(.*\.|)numerique\.gouv\.fr/ ] - done() - }) - - afterEach(function(done) { - config.EMAIL_WHITELIST = EMAIL_WHITELIST_BCK - done() - }) - - describe("unit tests", () => { - beforeEach(function(done) { - sendEmailStub = sinon.stub(emailer, "sendEmailValidationEmail") - dbStub = sinon.stub(db, "insertToken") - done() - }) - - afterEach(function(done) { - sendEmailStub.restore() - dbStub.restore() - done() - }) - - it("should refuse invalid email", async function() { - const email = "bad.email" - const request = await magicLinkAuth.startAuth(email) - - expect(request).to.have.own.property("error") - sinon.assert.notCalled(sendEmailStub) - sinon.assert.notCalled(dbStub) - }) - - it("should refuse email that is not in EMAIL_WHITELIST", async function() { - const email = "bad.email@not.betagouv.fr" - const request = await magicLinkAuth.startAuth(email) - - expect(request).to.have.own.property("error") - expect(request).not.to.have.own.property("redirectUrl") - sinon.assert.notCalled(sendEmailStub) - sinon.assert.notCalled(dbStub) - }) - - it("should send email and record the auth token in db", async function() { - const email = "good.email@beta.gouv.fr" - const conferenceDayString = "2022-05-25" - const userTimezoneOffset = 120 - sendEmailStub.returns(Promise.resolve()) - dbStub.returns(Promise.resolve()) - - const request = await magicLinkAuth.startAuth( - email, - undefined, //conferenceDurationInMinutes, - conferenceDayString, - userTimezoneOffset, - ) - - expect(request).to.have.own.property("redirectUrl") - expect(request).not.to.have.own.property("error") - expect(request.redirectUrl).to.contain(email.replace("@", "%40")) - sinon.assert.calledOnce(sendEmailStub) - sinon.assert.calledWith(sendEmailStub.getCall(0), - email - ) - sinon.assert.calledOnce(dbStub) - sinon.assert.calledWith(dbStub.getCall(0), - email, - sinon.match.string, // token, - sinon.match.date, // tokenExpirationDate, - undefined, // conferenceDurationInMinutes, - conferenceDayString, - userTimezoneOffset - ) - - // check token is present in email - const magicLink = sendEmailStub.getCall(0).args[2] - const token = dbStub.getCall(0).args[1] - expect(magicLink).to.contain(encodeURIComponent(token)) - }) - }) - - describe("end to end test", () => { - beforeEach(async function() { - sendEmailStub = sinon.stub(emailer, "sendEmailValidationEmail") - // don't stub DB, use real one - await utils.reinitializeDB() - }) - - afterEach(function(done) { - sendEmailStub.restore() - done() - }) - - after(async () => { - await utils.reinitializeDB() - }) - - it("should run the whole auth flow", async () => { - const email = "good.email@beta.gouv.fr" - const conferenceDayString = "2022-05-25" - const userTimezoneOffset = 120 - sendEmailStub.returns(Promise.resolve()) - - await magicLinkAuth.startAuth( - email, - undefined, //conferenceDurationInMinutes, - conferenceDayString, - userTimezoneOffset, - ) - - // The magicLink that was emailed : - const magicLink = sendEmailStub.getCall(0).args[2] - - // Simulate : The user clicks the magic link - const fakeRequest = url.parse(magicLink, true) - const confData = await magicLinkAuth.finishAuth(fakeRequest) - - expect(confData.email).to.equal(email) - expect(confData.conferenceDay).to.equal(conferenceDayString) - expect(confData.userTimezoneOffset).to.equal(userTimezoneOffset) - }) - }) -}) diff --git a/test/oidcAuthTest.js b/test/oidcAuthTest.js index 6e8433b2..b4595a73 100644 --- a/test/oidcAuthTest.js +++ b/test/oidcAuthTest.js @@ -24,12 +24,10 @@ describe("oidcAuth", function() { })) insertOidcRequestStub.returns(Promise.resolve()) - const email = "good.email@beta.gouv.fr" const conferenceDayString = "2022-05-25" const userTimezoneOffset = 60 await oidcAuth.startAuth( - email, undefined, //conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset, @@ -54,12 +52,10 @@ describe("oidcAuth", function() { })) insertOidcRequestStub.returns(Promise.resolve()) - const email = "good.email@beta.gouv.fr" const conferenceDayString = "2022-05-25" const userTimezoneOffset = 60 const request = await oidcAuth.startAuth( - email, undefined, //conferenceDurationInMinutes, conferenceDayString, userTimezoneOffset, @@ -68,7 +64,6 @@ describe("oidcAuth", function() { expect(request.redirectUrl).to.equal(redirectUrl) sinon.assert.calledWith(authorizationUrlStub.getCall(0), { - login_hint: email, scope: "openid", state: sinon.match.string, nonce: sinon.match.string, diff --git a/test/startAuthControllerTest.js b/test/startAuthControllerTest.js index 2d3c9e01..8f0f57c9 100644 --- a/test/startAuthControllerTest.js +++ b/test/startAuthControllerTest.js @@ -1,81 +1,16 @@ const app = require("../index") const chai = require("chai") -const magicLinkAuth = require("../lib/magicLinkAuth") const oidcAuth = require("../lib/oidcAuth") const sinon = require("sinon") const urls = require("../urls") -const config = require("../config") describe("startAuthController", function() { - let featureFlagValue - - beforeEach(function(done) { - featureFlagValue = config.FEATURE_OIDC - done() - }) - - afterEach(function(done) { - config.FEATURE_OIDC = featureFlagValue - done() - }) - - describe("using magicLinkAuth", function() { - let magicLinkAuthStub - - beforeEach(function() { - magicLinkAuthStub = sinon.stub(magicLinkAuth, "startAuth") - config.FEATURE_OIDC = false - }) - - afterEach(function() { - magicLinkAuthStub.restore() - }) - - - it("should redirect to landing page if startAuth failed", function(done) { - magicLinkAuthStub.returns(Promise.resolve({ error: "something went wrong"})) - - chai.request(app) - .post(urls.startAuth) - .redirects(0) // block redirects, we don't want to test them - .type("form") - .send({ - email: "email", - day: "2020-12-09", - }) - .end((err, res) => { - res.should.redirectTo(urls.landing) - done() - }) - }) - - it("should redirect to redirectUrl if startAuth succeeded", function(done) { - const redirectUrl = "/my-redirect-url" - - magicLinkAuthStub.returns(Promise.resolve({ redirectUrl })) - - chai.request(app) - .post(urls.startAuth) - .redirects(0) // block redirects, we don't want to test them - .type("form") - .send({ - email: "me@email.com", - day: "2020-12-09", - }) - .end((err, res) => { - res.should.redirectTo(redirectUrl) - done() - }) - }) - - }) describe("using oidcAuth", function() { let oidcClientStub beforeEach(function() { oidcClientStub = sinon.stub(oidcAuth, "startAuth") - config.FEATURE_OIDC = true }) afterEach(function() { @@ -83,8 +18,6 @@ describe("startAuthController", function() { }) it("should redirect to landing page if startAuth failed", function(done) { - config.FEATURE_OIDC = true - oidcClientStub.returns(Promise.resolve({ error: "something went wrong"})) chai.request(app) @@ -102,7 +35,6 @@ describe("startAuthController", function() { }) it("should redirect to redirectUrl if startAuth succeeded", function(done) { - config.FEATURE_OIDC = true const redirectUrl = "/my-redirect-url" oidcClientStub.returns(Promise.resolve({ redirectUrl })) diff --git a/views/landing.ejs b/views/landing.ejs index a13ef463..4fd298a8 100644 --- a/views/landing.ejs +++ b/views/landing.ejs @@ -70,9 +70,16 @@ -
- -
+ +
+ +

+ Qu’est-ce que AgentConnect ? +

+

From b85964acc6a2aa363d8cee7a40e436fe8fde7be4 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Thu, 23 May 2024 16:35:19 +0200 Subject: [PATCH 10/19] delete asking for mail adress in landing --- lib/oidcAuth.js | 1 - views/landing.ejs | 4 ---- 2 files changed, 5 deletions(-) diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index fddd8df9..bafda4b8 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -12,7 +12,6 @@ const { generators, Issuer } = require("openid-client") const config = require("../config.js") const urls = require("../urls") const db = require("../lib/db") -const format = require("../lib/format") const urlCallback = urls.createConf diff --git a/views/landing.ejs b/views/landing.ejs index 4fd298a8..19ccc545 100644 --- a/views/landing.ejs +++ b/views/landing.ejs @@ -41,10 +41,6 @@ <% } %>

-
- - -
<% if(FEATURE_RESERVATIONS) { %>
From c243e84d91e076ed1302b7829e9690bf638f1b14 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Tue, 28 May 2024 16:43:39 +0200 Subject: [PATCH 11/19] add button logout --- .env.sample | 1 + config.js | 1 + controllers/{startAuthController.js => userController.js} | 5 +++++ index.js | 7 +++++-- lib/oidcAuth.js | 2 ++ test/startAuthControllerTest.js | 2 +- urls.js | 1 + views/partials/header.ejs | 3 +++ 8 files changed, 19 insertions(+), 3 deletions(-) rename controllers/{startAuthController.js => userController.js} (88%) diff --git a/.env.sample b/.env.sample index 2bb8b60d..4e52f74d 100644 --- a/.env.sample +++ b/.env.sample @@ -68,6 +68,7 @@ ENCRYPT_SECRET=un_secret_avec_exactement_64_bit # Use OIDC auth instead of audioconf's magiclink auth #OIDC_PROVIDER_URL= +#OIDC_PROVIDER_LOGOUT_URL= #OIDC_CLIENT_ID= #OIDC_CLIENT_SECRET= diff --git a/config.js b/config.js index 76c9e8c6..cfad6243 100644 --- a/config.js +++ b/config.js @@ -109,6 +109,7 @@ config.STATS_EXTERNAL_DASHBOARD_URL = process.env.STATS_EXTERNAL_DASHBOARD_URL config.OIDC_PROVIDER_URL = process.env.OIDC_PROVIDER_URL +config.OIDC_PROVIDER_LOGOUT_URL = process.env.OIDC_PROVIDER_LOGOUT_URL config.OIDC_CLIENT_ID = process.env.OIDC_CLIENT_ID config.OIDC_CLIENT_SECRET = process.env.OIDC_CLIENT_SECRET config.OIDC_ACR_VALUES = process.env.OIDC_ACR_VALUES diff --git a/controllers/startAuthController.js b/controllers/userController.js similarity index 88% rename from controllers/startAuthController.js rename to controllers/userController.js index 7768574d..2a91f6bc 100644 --- a/controllers/startAuthController.js +++ b/controllers/userController.js @@ -18,3 +18,8 @@ module.exports.startAuth = async (req, res) => { res.redirect(authRequest.redirectUrl) } + +module.exports.logout = async(req, res) => { + console.log(req.session) + return res.redirect(`/`) +} diff --git a/index.js b/index.js index 2c383627..1294d37f 100644 --- a/index.js +++ b/index.js @@ -13,7 +13,7 @@ const dashboardController = require("./controllers/dashboardController") const format = require("./lib/format") const createConfController = require("./controllers/createConfController") const landingController = require("./controllers/landingController") -const startAuthController = require("./controllers/startAuthController") +const userController = require("./controllers/userController") const statusController = require("./controllers/statusController") const stats = require("./lib/stats") const urls = require("./urls") @@ -75,7 +75,8 @@ app.use(function(req, res, next){ app.get(urls.landing, landingController.getLanding) -app.post(urls.startAuth, startAuthController.startAuth) +app.post(urls.startAuth, userController.startAuth) +app.post(urls.logout, userController.logout) app.get(urls.validationEmailSent, (req, res) => { res.render("validationEmailSent", { @@ -139,6 +140,8 @@ app.get(urls.faq, (req, res) => { }) }) +app.get(urls.logout, userController.logout) + app.get(urls.status, statusController.getStatus) app.use(Sentry.Handlers.errorHandler()) diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index bafda4b8..62471e55 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -119,6 +119,8 @@ module.exports.finishAuth = async (req) => { return { error: "L'identification a échoué. Entrez votre adresse mail ci-dessous pour recommencer." } } const email = userinfo.email + + req.session.id_token_hint = tokenSet.id_token return { email, diff --git a/test/startAuthControllerTest.js b/test/startAuthControllerTest.js index 8f0f57c9..1b341049 100644 --- a/test/startAuthControllerTest.js +++ b/test/startAuthControllerTest.js @@ -4,7 +4,7 @@ const oidcAuth = require("../lib/oidcAuth") const sinon = require("sinon") const urls = require("../urls") -describe("startAuthController", function() { +describe("userController", function() { describe("using oidcAuth", function() { let oidcClientStub diff --git a/urls.js b/urls.js index 070b091d..7906aaa5 100644 --- a/urls.js +++ b/urls.js @@ -14,4 +14,5 @@ module.exports = { participantAction: '/dashboard/:participantId/:action', dashboard: '/dashboard', status: '/api/status', + logout: '/api/logout' } diff --git a/views/partials/header.ejs b/views/partials/header.ejs index a9a50399..abe567b6 100644 --- a/views/partials/header.ejs +++ b/views/partials/header.ejs @@ -59,6 +59,9 @@
  • <%- include('dark-mode-switch') -%>
  • +
    From 1daf23ed85cfd2b7cd2942563e26e92f055f3fbf Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Tue, 28 May 2024 16:58:37 +0200 Subject: [PATCH 12/19] add logout route implementation --- controllers/userController.js | 12 ++++++++++-- lib/oidcAuth.js | 8 +++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/controllers/userController.js b/controllers/userController.js index 2a91f6bc..2fe4c9fc 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -1,4 +1,5 @@ const oidcAuth = require("../lib/oidcAuth") +const urls = require("../urls") module.exports.startAuth = async (req, res) => { const userTimezoneOffset = req.body.userTimezoneOffset @@ -20,6 +21,13 @@ module.exports.startAuth = async (req, res) => { } module.exports.logout = async(req, res) => { - console.log(req.session) - return res.redirect(`/`) + const user = req.session.user + if(!user){ + return res.redirect(urls.landing) + } + const {id_token_hint, state} = user + req.session.destroy() + + const logoutUrl = oidcAuth.getLogoutUrl({id_token_hint, state}) + return res.redirect(logoutUrl) } diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index 62471e55..54e30213 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -119,8 +119,9 @@ module.exports.finishAuth = async (req) => { return { error: "L'identification a échoué. Entrez votre adresse mail ci-dessous pour recommencer." } } const email = userinfo.email + const user = {id_token: tokenSet.id_token, state: request.state} - req.session.id_token_hint = tokenSet.id_token + req.session.user = user return { email, @@ -130,3 +131,8 @@ module.exports.finishAuth = async (req) => { } } +module.exports.getLogoutUrl = async({state, id_token_hint}) => { + const client = await this.getClient() + + return client.endSessionUrl({id_token_hint,post_logout_redirect_uri: urls.landing,state}) +} From afa3e4bb036c928c5aea055383ec03b777237cf8 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Tue, 28 May 2024 17:04:01 +0200 Subject: [PATCH 13/19] add await logout url --- controllers/userController.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/controllers/userController.js b/controllers/userController.js index 2fe4c9fc..d4c28f4c 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -20,14 +20,17 @@ module.exports.startAuth = async (req, res) => { res.redirect(authRequest.redirectUrl) } -module.exports.logout = async(req, res) => { +module.exports.logout = async (req, res) => { const user = req.session.user + console.log("USER") + console.log(user) if(!user){ return res.redirect(urls.landing) } const {id_token_hint, state} = user req.session.destroy() - const logoutUrl = oidcAuth.getLogoutUrl({id_token_hint, state}) + const logoutUrl = await oidcAuth.getLogoutUrl({id_token_hint, state}) + console.log("LOGOUT", logoutUrl) return res.redirect(logoutUrl) } From 26631a268e8b8f1fa3ca623f769164f8121281ff Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Tue, 28 May 2024 17:26:12 +0200 Subject: [PATCH 14/19] add hostname to post logout redirect uri --- controllers/userController.js | 4 ++-- lib/oidcAuth.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/controllers/userController.js b/controllers/userController.js index d4c28f4c..a511f1c5 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -22,12 +22,12 @@ module.exports.startAuth = async (req, res) => { module.exports.logout = async (req, res) => { const user = req.session.user - console.log("USER") - console.log(user) if(!user){ return res.redirect(urls.landing) } const {id_token_hint, state} = user + console.log(`state : ${state}`) + console.log(`id_token_hint : ${id_token_hint}`) req.session.destroy() const logoutUrl = await oidcAuth.getLogoutUrl({id_token_hint, state}) diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index 54e30213..60353598 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -134,5 +134,5 @@ module.exports.finishAuth = async (req) => { module.exports.getLogoutUrl = async({state, id_token_hint}) => { const client = await this.getClient() - return client.endSessionUrl({id_token_hint,post_logout_redirect_uri: urls.landing,state}) + return client.endSessionUrl({id_token_hint,post_logout_redirect_uri: `${config.HOSTNAME_WITH_PROTOCOL}${urls.landing}`,state}) } From ac43fcfeea4343c7d175153d31d7935973ce7310 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Tue, 28 May 2024 17:29:36 +0200 Subject: [PATCH 15/19] replace id_token with id_token_int --- controllers/userController.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/controllers/userController.js b/controllers/userController.js index a511f1c5..73600885 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -25,12 +25,12 @@ module.exports.logout = async (req, res) => { if(!user){ return res.redirect(urls.landing) } - const {id_token_hint, state} = user + const {id_token, state} = user console.log(`state : ${state}`) - console.log(`id_token_hint : ${id_token_hint}`) + console.log(`id_token_hint : ${id_token}`) req.session.destroy() - const logoutUrl = await oidcAuth.getLogoutUrl({id_token_hint, state}) + const logoutUrl = await oidcAuth.getLogoutUrl({id_token_hint: id_token, state}) console.log("LOGOUT", logoutUrl) return res.redirect(logoutUrl) } From bd3cac005b77cd488b88318ec3793e9a453b7cc6 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Tue, 28 May 2024 17:39:13 +0200 Subject: [PATCH 16/19] delete logs --- controllers/userController.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/controllers/userController.js b/controllers/userController.js index 73600885..5a753420 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -26,11 +26,8 @@ module.exports.logout = async (req, res) => { return res.redirect(urls.landing) } const {id_token, state} = user - console.log(`state : ${state}`) - console.log(`id_token_hint : ${id_token}`) req.session.destroy() const logoutUrl = await oidcAuth.getLogoutUrl({id_token_hint: id_token, state}) - console.log("LOGOUT", logoutUrl) return res.redirect(logoutUrl) } From eed819a5eaa00c0b53bda1591cc374a49a129312 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Wed, 29 May 2024 11:31:43 +0200 Subject: [PATCH 17/19] add locals user --- index.js | 1 + views/partials/header.ejs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/index.js b/index.js index 1294d37f..df510842 100644 --- a/index.js +++ b/index.js @@ -70,6 +70,7 @@ app.use(function(req, res, next){ res.locals.urls = urls res.locals.version = version res.locals.siteUrl = config.HOSTNAME_WITH_PROTOCOL + res.locals.user = req.session.user next() }) diff --git a/views/partials/header.ejs b/views/partials/header.ejs index abe567b6..e60d7fd7 100644 --- a/views/partials/header.ejs +++ b/views/partials/header.ejs @@ -59,9 +59,11 @@
  • <%- include('dark-mode-switch') -%>
  • + <% if (locals.user) { %> + <% } %>
    From aed4e417b947067b24066a587308ac94eeed9fcf Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Wed, 29 May 2024 11:46:54 +0200 Subject: [PATCH 18/19] delete unused variable logout --- .env.sample | 1 - config.js | 1 - 2 files changed, 2 deletions(-) diff --git a/.env.sample b/.env.sample index 4e52f74d..2bb8b60d 100644 --- a/.env.sample +++ b/.env.sample @@ -68,7 +68,6 @@ ENCRYPT_SECRET=un_secret_avec_exactement_64_bit # Use OIDC auth instead of audioconf's magiclink auth #OIDC_PROVIDER_URL= -#OIDC_PROVIDER_LOGOUT_URL= #OIDC_CLIENT_ID= #OIDC_CLIENT_SECRET= diff --git a/config.js b/config.js index cfad6243..76c9e8c6 100644 --- a/config.js +++ b/config.js @@ -109,7 +109,6 @@ config.STATS_EXTERNAL_DASHBOARD_URL = process.env.STATS_EXTERNAL_DASHBOARD_URL config.OIDC_PROVIDER_URL = process.env.OIDC_PROVIDER_URL -config.OIDC_PROVIDER_LOGOUT_URL = process.env.OIDC_PROVIDER_LOGOUT_URL config.OIDC_CLIENT_ID = process.env.OIDC_CLIENT_ID config.OIDC_CLIENT_SECRET = process.env.OIDC_CLIENT_SECRET config.OIDC_ACR_VALUES = process.env.OIDC_ACR_VALUES From e8440e8c10a6d2c7598f31984e71fe525bd8e441 Mon Sep 17 00:00:00 2001 From: Benoit Serrano Date: Wed, 9 Oct 2024 16:25:42 +0200 Subject: [PATCH 19/19] add new scope and acr values in test --- .github/workflows/node.js.yml | 1 + test/oidcAuthTest.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 9e58a200..5e1e0d06 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -47,5 +47,6 @@ jobs: SECRET: fakesessionsecret ENCRYPT_SECRET: un_secret_avec_exactement_64_bit FEATURE_WEB_ACCESS: true + OIDC_ACR_VALUES: eidas1 DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres AFTER_MEETING_SURVEY_URL: https://startupdetat.typeform.com/to/R5uC1b0k diff --git a/test/oidcAuthTest.js b/test/oidcAuthTest.js index b4595a73..6cdafc91 100644 --- a/test/oidcAuthTest.js +++ b/test/oidcAuthTest.js @@ -64,7 +64,8 @@ describe("oidcAuth", function() { expect(request.redirectUrl).to.equal(redirectUrl) sinon.assert.calledWith(authorizationUrlStub.getCall(0), { - scope: "openid", + scope: "openid uid email", + acr_values: "eidas1", state: sinon.match.string, nonce: sinon.match.string, }