diff --git a/config.js b/config.js index d68a3ad8..70a6c78b 100644 --- a/config.js +++ b/config.js @@ -110,6 +110,8 @@ config.STATS_EXTERNAL_DASHBOARD_URL = process.env.STATS_EXTERNAL_DASHBOARD_URL config.OIDC_PROVIDER_URL = process.env.OIDC_PROVIDER_URL +config.GRIST_API_KEY = process.env.GRIST_API_KEY +config.GRIST_API_DOMAINS_URL = process.env.GRIST_API_DOMAINS_URL config.OIDC_CLIENT_ID = process.env.OIDC_CLIENT_ID config.OIDC_CLIENT_SECRET = process.env.OIDC_CLIENT_SECRET diff --git a/lib/domains.js b/lib/domains.js new file mode 100644 index 00000000..f336eafd --- /dev/null +++ b/lib/domains.js @@ -0,0 +1,12 @@ +const config = require("../config") + +module.exports.getWhitelistedDomains = async () => { + const URL = config.GRIST_API_DOMAINS_URL + const API_KEY = config.GRIST_API_KEY + const result = await fetch(URL, {headers: {Authorization: `Bearer ${API_KEY}`}}) + const data = await result.json() + if(data.status !== "success") { + throw new Error("Error while fetching GRIST API") + } + return data.items +} diff --git a/lib/format.js b/lib/format.js index 82166220..dc107725 100644 --- a/lib/format.js +++ b/lib/format.js @@ -80,3 +80,17 @@ module.exports.formatLocalTime = function(date) { return date.getHours() + ":" + minutes + ":" + seconds } +module.exports.extractEmailDomain = function(email) { + // Expression régulière pour valider une adresse email + const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; + + // Vérification si l'adresse email est valide + if (!emailRegex.test(email)) { + throw new Error("Adresse email invalide"); + } + + // Extraction du domaine avec un split + const domain = email.split("@")[1]; + + return domain; +} diff --git a/lib/format.test.js b/lib/format.test.js new file mode 100644 index 00000000..aa940d3a --- /dev/null +++ b/lib/format.test.js @@ -0,0 +1,40 @@ +const { expect } = require("chai") +const sinon = require("sinon") + +const extractEmailDomain = require("./format") + +describe("format", function() { + + describe("extractEmailDomain", () => { + test("devrait retourner le domaine d\"une adresse email valide", () => { + const email = "john.doe@example.com"; + const domain = extractEmailDomain(email); + expect(domain).toBe("example.com"); + }); + + test("devrait retourner le domaine d\"une adresse email académique", () => { + const email = "student@university.edu"; + const domain = extractEmailDomain(email); + expect(domain).toBe("university.edu"); + }); + + test("devrait lever une erreur pour une adresse email sans @", () => { + expect(() => { + extractEmailDomain("invalidEmail"); + }).toThrow("Adresse email invalide"); + }); + + test("devrait lever une erreur pour un domaine manquant", () => { + expect(() => { + extractEmailDomain("john.doe@"); + }).toThrow("Domaine email invalide"); + }); + + test("devrait lever une erreur pour une chaîne vide", () => { + expect(() => { + extractEmailDomain("); + }).toThrow("Adresse email invalide"); + }); +}); + +}) diff --git a/lib/oidcAuth.js b/lib/oidcAuth.js index 62498a63..fc219cf8 100644 --- a/lib/oidcAuth.js +++ b/lib/oidcAuth.js @@ -13,6 +13,7 @@ const config = require("../config.js") const urls = require("../urls") const db = require("../lib/db") const format = require("../lib/format") +const { getWhitelistedDomains } = require("./domains.js") const urlCallback = urls.createConf @@ -104,8 +105,20 @@ module.exports.finishAuth = async (req) => { } ) const claims = tokenSet.claims() + console.log("claims", JSON.stringify(claims)) const email = claims.preferred_username + try { + const domain = format.extractEmailDomain(email) + const whitelistedDomains = await getWhitelistedDomains() + if(!whitelistedDomains.includes(domain)){ + throw new Error(`The domain ${domain} is not whitelisted.`) + } + } catch(e){ + console.error(`error when validating email ${email}`,e) + return { error: `L'adresse e-mail ${email} n'est pas autorisée à utiliser ce service.` } + } + return { email, durationInMinutes: request.durationInMinutes,