I got a request to verify that an email has not been used before sending the verification code in our Sign Up custom policy. In our Password reset policy we use DisplayControl to check if the password exist before sending the OTP code and only send the OTP if the email has already been registered. However, I need to do the opposite for the registration process, only send the code if the email has NOT been registered.
I tried to use the following:
<DisplayControl Id="emailVerificationControlSignUp" UserInterfaceControlType="VerificationControl">
<InputClaims>
<InputClaim ClaimTypeReferenceId="emailAddress" />
</InputClaims>
<DisplayClaims>
<DisplayClaim ClaimTypeReferenceId="emailAddress" ControlClaimType="Email" Required="true" />
<DisplayClaim ClaimTypeReferenceId="verificationCode" ControlClaimType="VerificationCode" Required="true" />
</DisplayClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="azureMfaSessionId" />
</OutputClaims>
<Actions>
<!--Before generating and sending an OTP, we first take the users email and lookup the directory for a user. If a user is returned we will have the objectId claim in the claimbag-->
<Action Id="SendCode">
<ValidationClaimsExchange>
<ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="AAD-UserReadUsingEmailAddress-emailAdressExist" ContinueOnError="true" ContinueOnSuccess="false" />
<ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="AadSspr-SendCode">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>objectId</Value>
<Action>SkipThisValidationTechnicalProfile</Action>
</Precondition>
</Preconditions>
</ValidationClaimsExchangeTechnicalProfile>
</ValidationClaimsExchange>
</Action>
<Action Id="VerifyCode">
<ValidationClaimsExchange>
<ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="AadSspr-VerifyCode" />
</ValidationClaimsExchange>
</Action>
</Actions>
</DisplayControl>
and this TechnicalProfile
<TechnicalProfile Id="AAD-UserReadUsingEmailAddress-emailAdressExist">
<Metadata>
<Item Key="Operation">Read</Item>
<Item Key="RaiseErrorIfClaimsPrincipalAlreadyExists">true</Item>
<!--<Item Key="UserMessageIfClaimsPrincipalDoesNotExist">UserMessageIfClaimsPrincipalDoesNotExist</Item>
<Item Key="UserMessageIfClaimsPrincipalAlreadyExists">UserMessageIfClaimsPrincipalAlreadyExists</Item>-->
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="emailAddress" PartnerClaimType="signInNames.emailAddress" Required="true" />
</InputClaims>
<OutputClaims>
<!-- Required claims -->
<OutputClaim ClaimTypeReferenceId="objectId" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
<!-- Optional claims -->
<OutputClaim ClaimTypeReferenceId="userPrincipalName" />
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="otherMails" />
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" />
</OutputClaims>
<IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>
What happen is that the OTP is indeed only sent if the email has not been registered, however, the DisplayControl always change to show the "verify code/Send new code" buttons, even if the email has been registered. So, in the end, what happen is that if the email has been registered, the user doesn't get the OTP, only if the email has NOT been registered. However, nothing on the screen tells the user that.
Email has been registered, user should see error message and not the verify/send new code buttons
How can I fix this DisplayControl?
Thank you