diff --git a/authentik/stages/identification/models.py b/authentik/stages/identification/models.py index a25d149c2..f8fc7ba15 100644 --- a/authentik/stages/identification/models.py +++ b/authentik/stages/identification/models.py @@ -17,6 +17,7 @@ class UserFields(models.TextChoices): E_MAIL = "email" USERNAME = "username" + UPN = "upn" class IdentificationStage(Stage): diff --git a/authentik/stages/identification/stage.py b/authentik/stages/identification/stage.py index ec86e2d9e..99297445b 100644 --- a/authentik/stages/identification/stage.py +++ b/authentik/stages/identification/stage.py @@ -96,7 +96,11 @@ class IdentificationStageView(ChallengeStageView): current_stage: IdentificationStage = self.executor.current_stage query = Q() for search_field in current_stage.user_fields: - model_field = search_field + model_field = { + "email": "email", + "username": "username", + "upn": "attributes__upn", + }[search_field] if current_stage.case_insensitive_matching: model_field += "__iexact" else: diff --git a/schema.yml b/schema.yml index a963ba658..9e6d2f9a5 100644 --- a/schema.yml +++ b/schema.yml @@ -27687,6 +27687,7 @@ components: enum: - email - username + - upn type: string UserLoginStage: type: object diff --git a/web/src/flows/stages/identification/IdentificationStage.ts b/web/src/flows/stages/identification/IdentificationStage.ts index 0290904ac..59c306aee 100644 --- a/web/src/flows/stages/identification/IdentificationStage.ts +++ b/web/src/flows/stages/identification/IdentificationStage.ts @@ -11,7 +11,7 @@ import PFAlert from "@patternfly/patternfly/components/Alert/alert.css"; import AKGlobal from "../../../authentik.css"; import "../../../elements/forms/FormElement"; import "../../../elements/EmptyState"; -import { FlowChallengeRequest, IdentificationChallenge, IdentificationChallengeResponseRequest, UILoginButton } from "authentik-api"; +import { FlowChallengeRequest, IdentificationChallenge, IdentificationChallengeResponseRequest, UILoginButton, UserFieldsEnum } from "authentik-api"; export const PasswordManagerPrefill: { password: string | undefined; @@ -149,13 +149,18 @@ export class IdentificationStage extends BaseStage`; } - if (this.challenge?.userFields === ["email"]) { + const fields = this.challenge?.userFields.sort() || []; + if (fields === [UserFieldsEnum.Email]) { label = t`Email`; type = "email"; - } else if (this.challenge?.userFields === ["username"]) { + } else if (fields === [UserFieldsEnum.Username]) { label = t`Username`; - } else { + } else if (fields === [UserFieldsEnum.Upn]) { + label = t`UPN`; + } else if (fields === [UserFieldsEnum.Email, UserFieldsEnum.Username]) { label = t`Email or username`; + } else { + label = t`Email, UPN or username`; } return html` ${t`Email`} +

${t`Fields a user can identify themselves with. If no fields are selected, the user will only be able to use sources.`}

${t`Hold control/command to select multiple items.`}