Skip to content

Commit

Permalink
add whitelisting emails (#285)
Browse files Browse the repository at this point in the history
  • Loading branch information
BenoitSerrano authored Oct 9, 2024
2 parents 0331514 + a79657d commit b9eb021
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 3 deletions.
2 changes: 2 additions & 0 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,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
config.OIDC_ACR_VALUES = process.env.OIDC_ACR_VALUES
Expand Down
5 changes: 2 additions & 3 deletions controllers/createConfController.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,10 @@ const createConfWithDay = async (email, conferenceDay, userTimezoneOffset) => {
module.exports.createConf = async (req, res) => {
const confData = await oidcAuth.finishAuth(req)

const { email, durationInMinutes, conferenceDay, userTimezoneOffset } = confData
const { email, durationInMinutes, conferenceDay, userTimezoneOffset, error } = confData

if (!conferenceDay && !durationInMinutes) {
console.error("Login token contained no conferenceDay and no durationInMinutes. Cannot create conference.")
req.flash("error", "La conférence n'a pas pu être créée. Vous pouvez réessayer.")
req.flash("error", error || "La conférence n'a pas pu être créée. Vous pouvez réessayer.")
return res.redirect("/")
}

Expand Down
12 changes: 12 additions & 0 deletions lib/domains.js
Original file line number Diff line number Diff line change
@@ -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
}
14 changes: 14 additions & 0 deletions lib/format.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
40 changes: 40 additions & 0 deletions lib/format.test.js
Original file line number Diff line number Diff line change
@@ -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 = "[email protected]";
const domain = extractEmailDomain(email);
expect(domain).toBe("example.com");
});

test("devrait retourner le domaine d\"une adresse email académique", () => {
const email = "[email protected]";
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");
});
});

})
14 changes: 14 additions & 0 deletions lib/oidcAuth.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ 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 { getWhitelistedDomains } = require("./domains.js")

const urlCallback = urls.createConf

Expand Down Expand Up @@ -119,6 +121,18 @@ module.exports.finishAuth = async (req) => {
return { error: "L'identification a échoué. Entrez votre adresse mail ci-dessous pour recommencer." }
}
const email = userinfo.email

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. Si vous êtes agent de l'État, contactez-nous à [email protected]` }
}

const user = {id_token: tokenSet.id_token, state: request.state}

req.session.user = user
Expand Down

0 comments on commit b9eb021

Please sign in to comment.