mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
Add email verification check during sign-in flow (#12605)
* Add email verification check during sign-in flow * Add support for Entra External ID with OIDC standard verification claim
This commit is contained in:
@@ -102,6 +102,18 @@ if (env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET) {
|
||||
const user =
|
||||
context.state?.auth?.user ?? (await getUserFromOAuthState(context));
|
||||
|
||||
// Microsoft's email claim is mutable, only trust it when a verification
|
||||
// claim confirms it — xms_edov for workforce tenants, or the standard
|
||||
// email_verified claim in External ID / OIDC scenarios.
|
||||
// https://learn.microsoft.com/en-us/entra/identity-platform/reference-claims-customization
|
||||
const verificationClaims = [profile.xms_edov, profile.email_verified];
|
||||
const presentClaims = verificationClaims.filter(
|
||||
(claim) => claim !== undefined
|
||||
);
|
||||
const emailVerified = presentClaims.length
|
||||
? presentClaims.some((claim) => claim === true || claim === "true")
|
||||
: undefined;
|
||||
|
||||
const domain = parseEmail(email).domain;
|
||||
const subdomain = slugifyDomain(domain);
|
||||
|
||||
@@ -121,6 +133,7 @@ if (env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET) {
|
||||
user: {
|
||||
name: profile.name,
|
||||
email,
|
||||
emailVerified,
|
||||
avatarUrl: profile.picture,
|
||||
},
|
||||
authenticationProvider: {
|
||||
|
||||
@@ -201,6 +201,7 @@ if (env.DISCORD_CLIENT_ID && env.DISCORD_CLIENT_SECRET) {
|
||||
},
|
||||
user: {
|
||||
email,
|
||||
emailVerified: profile.verified,
|
||||
name: userName,
|
||||
language,
|
||||
avatarUrl: userAvatarUrl,
|
||||
|
||||
@@ -127,6 +127,8 @@ if (env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET) {
|
||||
},
|
||||
user: {
|
||||
email: profile.email,
|
||||
// Google only returns confirmed workspace email addresses.
|
||||
emailVerified: true,
|
||||
name: profile.displayName,
|
||||
language,
|
||||
avatarUrl,
|
||||
|
||||
@@ -105,6 +105,7 @@ export function createOIDCRouter(
|
||||
|
||||
return decoded as {
|
||||
email?: string;
|
||||
email_verified?: boolean | string;
|
||||
preferred_username?: string;
|
||||
sub?: string;
|
||||
};
|
||||
@@ -122,6 +123,15 @@ export function createOIDCRouter(
|
||||
);
|
||||
}
|
||||
|
||||
// The email_verified claim is part of the OIDC standard claims.
|
||||
// https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
|
||||
const emailVerifiedClaim =
|
||||
profile.email_verified ?? token.email_verified;
|
||||
const emailVerified =
|
||||
emailVerifiedClaim === undefined
|
||||
? undefined
|
||||
: emailVerifiedClaim === true || emailVerifiedClaim === "true";
|
||||
|
||||
const team = await getTeamFromContext(context);
|
||||
const client = getClientFromOAuthState(context);
|
||||
const user =
|
||||
@@ -206,6 +216,7 @@ export function createOIDCRouter(
|
||||
user: {
|
||||
name,
|
||||
email,
|
||||
emailVerified,
|
||||
avatarUrl,
|
||||
},
|
||||
authenticationProvider: {
|
||||
|
||||
@@ -110,6 +110,8 @@ if (env.SLACK_CLIENT_ID && env.SLACK_CLIENT_SECRET) {
|
||||
user: {
|
||||
name: profile.user.name,
|
||||
email: profile.user.email,
|
||||
// Slack only returns confirmed workspace email addresses.
|
||||
emailVerified: true,
|
||||
avatarUrl: profile.user.image_192,
|
||||
},
|
||||
authenticationProvider: {
|
||||
|
||||
Reference in New Issue
Block a user