From 1fec674d28f2c6abe26710d4eb60c7eaae9c0e91 Mon Sep 17 00:00:00 2001 From: Florent Date: Wed, 22 Nov 2023 20:58:29 +0100 Subject: [PATCH] OIDC: ensure that email_veridied is set by default (#765) Co-authored-by: Florent FAYOLLE --- app/server/lib/OIDCConfig.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/server/lib/OIDCConfig.ts b/app/server/lib/OIDCConfig.ts index 5c36d09c..58d01443 100644 --- a/app/server/lib/OIDCConfig.ts +++ b/app/server/lib/OIDCConfig.ts @@ -29,6 +29,9 @@ * env GRIST_OIDC_IDP_SKIP_END_SESSION_ENDPOINT * If set to "true", on logout, there won't be any attempt to call the IdP's end_session_endpoint * (the user will remain logged in in the IdP). + * env GRIST_OIDC_SP_IGNORE_EMAIL_VERIFIED + * If set to "true", the user will be allowed to login even if the email is not verified by the IDP. + * Defaults to false. * * This version of OIDCConfig has been tested with Keycloak OIDC IdP following the instructions * at: @@ -61,6 +64,7 @@ export class OIDCConfig { private _namePropertyKey?: string; private _emailPropertyKey: string; private _skipEndSessionEndpoint: boolean; + private _ignoreEmailVerified: boolean; public constructor() { } @@ -95,6 +99,11 @@ export class OIDCConfig { defaultValue: false, })!; + this._ignoreEmailVerified = section.flag('ignoreEmailVerified').readBool({ + envVar: 'GRIST_OIDC_SP_IGNORE_EMAIL_VERIFIED', + defaultValue: false, + })!; + const issuer = await Issuer.discover(issuerUrl); this._redirectUrl = new URL(CALLBACK_URL, spHost).href; this._client = new issuer.Client({ @@ -134,6 +143,11 @@ export class OIDCConfig { ); const userInfo = await this._client.userinfo(tokenSet); + + if (!this._ignoreEmailVerified && userInfo.email_verified !== true) { + throw new Error(`OIDCConfig: email not verified for ${userInfo.email}`); + } + const profile = this._makeUserProfileFromUserInfo(userInfo); log.info(`OIDCConfig: got OIDC response for ${profile.email} (${profile.name}) redirecting to ${targetUrl}`); @@ -204,7 +218,6 @@ export class OIDCConfig { return { email: String(userInfo[ this._emailPropertyKey ]), name: this._extractName(userInfo) - }; }