Email verification doesnot work after adding custom phone verification with Display control in custom SignUp policy

Viewed 15

I have a requirement to perform verification with both email and phone I used the Local accounts starter pack and I was able to successfully sign up with email verification and then also checked that the sign in is working with email and password To add phone verification I used Display control and called my custom REST APIs to send and verify OTP. Once I verified the OTP successfully, the verification code for email was not displayed Here are the claims

        <!-- This claim is for the MFA with mobile number -->
    <ClaimType Id="signInNames.phoneNumber">
        <DisplayName>Mobile Number signInNamesphoneNumber</DisplayName>
        <DataType>string</DataType>
        <UserHelpText>Please enter your mobile number.</UserHelpText>
        <UserInputType>TextBox</UserInputType>
      </ClaimType>
    <!-- This claim is used to store the transformed phone number-->
    <!-- country code is added to user entered number using string transformation-->
    <ClaimType Id="fullPhoneNumber">
        <DisplayName>Mobile Number signInNamesphoneNumber</DisplayName>
        <DataType>string</DataType>
        <UserHelpText>Please enter your mobile number.</UserHelpText>
      </ClaimType>
    <!-- This is for SMS OTP-->
    <ClaimType Id="verificationCode">
        <DisplayName>Mobile Number Verification Code</DisplayName>
        <DataType>string</DataType>
        <UserHelpText>Please enter the verification code.</UserHelpText>
        <UserInputType>TextBox</UserInputType>
      </ClaimType>
    <!-- This is for the OTP Id, this is sent by the custom OTP Provider-->
    <ClaimType Id="pinId">
        <DisplayName>Mobile Number Verification Code ID</DisplayName>
        <DataType>string</DataType>
        <UserHelpText>Verification code ID.</UserHelpText>
      </ClaimType>
      <ClaimType Id="sendOTPRequestBody">
      <DisplayName>JSON request body to send OTP SMS</DisplayName>
      <DataType>string</DataType>
    </ClaimType>
    <ClaimType Id="verifyOTPRequestBody">
      <DisplayName>JSON request body to send OTP SMS</DisplayName>
      <DataType>string</DataType>
    </ClaimType>

Here are the transformations

        <ClaimsTransformation Id="CreatFullPhoneNumber" TransformationMethod="FormatStringClaim">
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="signInNames.phoneNumber" TransformationClaimType="inputClaim" />
      </InputClaims>
      <InputParameters>
        <InputParameter Id="stringFormat" DataType="string" Value="974{0}" />
      </InputParameters>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="fullPhoneNumber" TransformationClaimType="outputClaim" />
      </OutputClaims>
  </ClaimsTransformation>

    <ClaimsTransformation Id="GenerateSendOTPRequestBody" TransformationMethod="GenerateJson">
    <InputClaims>
     <!-- <InputClaim ClaimTypeReferenceId="signInNames.phoneNumber" TransformationClaimType="to" /> -->
      <InputClaim ClaimTypeReferenceId="fullPhoneNumber" TransformationClaimType="to" />
    </InputClaims> 
    <InputParameters>
    <InputParameter Id="applicationId" DataType="string" Value="xxxxxxx"/>
    <InputParameter Id="messageId" DataType="string" Value="xxxxxxx"/>
    <InputParameter Id="from" DataType="string" Value="xxxxxxxxx"/>
  </InputParameters>   
    <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="sendOTPRequestBody" TransformationClaimType="outputClaim"/>
    </OutputClaims>
    </ClaimsTransformation>

    <ClaimsTransformation Id="GenerateVerifyOTPRequestBody" TransformationMethod="GenerateJson">
    <InputClaims>
     <!-- <InputClaim ClaimTypeReferenceId="signInNames.phoneNumber" TransformationClaimType="to" /> -->
      <InputClaim ClaimTypeReferenceId="verificationCode" TransformationClaimType="pin" />
      <InputClaim ClaimTypeReferenceId="pinId" TransformationClaimType="pinId" />
    </InputClaims> 
    <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="verifyOTPRequestBody" TransformationClaimType="outputClaim"/>
    </OutputClaims>
    </ClaimsTransformation>

Here is the Display control definition

        <DisplayControls>
    <DisplayControl Id="PhoneVerificationControl" UserInterfaceControlType="VerificationControl">
    <DisplayClaims>
      <DisplayClaim ClaimTypeReferenceId="signInNames.phoneNumber"  Required="true" />
      <DisplayClaim ClaimTypeReferenceId="verificationCode" ControlClaimType="VerificationCode" Required="true" />
    </DisplayClaims>
    <OutputClaims>
      <OutputClaim ClaimTypeReferenceId="signInNames.phoneNumber" />
      <OutputClaim ClaimTypeReferenceId="pinId" />
    </OutputClaims>
    <Actions>
      <Action Id="SendCode">
        <ValidationClaimsExchange>
          
          <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="InfoBipSendOTP" />
        </ValidationClaimsExchange>
      </Action>
      <Action Id="VerifyCode">
        <ValidationClaimsExchange>
          <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="RESTSecure-VerifyOTP" />
        </ValidationClaimsExchange>
      </Action>
    </Actions>
  </DisplayControl>
</DisplayControls>

Here are the Technical Profiles referenced in the Display control

        <TechnicalProfile Id="InfoBipSendOTP">
          <DisplayName>Send OTP as SMS</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <Item Key="ServiceUrl">https://xxxxxx.api.infobip.com/2fa/2/pin</Item>
            <Item Key="AuthenticationType">ApiKeyHeader</Item>
            <Item Key="SendClaimsIn">Body</Item>
          <Item Key="ClaimUsedForRequestPayload">sendOTPRequestBody</Item>
          <Item Key="DefaultUserMessageIfRequestFailed">Unable to send OTP.</Item>
          <Item Key="UserMessageIfCircuitOpen">Unable to send OTP - API Not Reachable.</Item>
          <Item Key="UserMessageIfDnsResolutionFailed">Unable to send OTP - DNS Resolution Failed.</Item>
          <Item Key="UserMessageIfRequestTimeout">Unable to send OTP. - Request Timeout</Item>
          </Metadata>
        <CryptographicKeys>
          <Key Id="Authorization" StorageReferenceId="B2C_1A_Infobip2FAApiKey" />
        </CryptographicKeys>
        <InputClaimsTransformations>
          <InputClaimsTransformation ReferenceId="CreatFullPhoneNumber" />
          <InputClaimsTransformation ReferenceId="GenerateSendOTPRequestBody" />
        </InputClaimsTransformations>
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="sendOTPRequestBody" />
        </InputClaims>
        <OutputClaims>
           <OutputClaim ClaimTypeReferenceId="pinId" PartnerClaimType="pinId" />
           <OutputClaim ClaimTypeReferenceId="verificationCode"/>
        </OutputClaims>
        <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>

      <TechnicalProfile Id="RESTSecure-VerifyOTP">
          <DisplayName>Verify the OTP</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <Item Key="ServiceUrl">https://xxxxxxxapimgmtresource.azure-api.net/myTestFnApp/v1/HttpTriggerVerifyOTP</Item>
            <Item Key="AuthenticationType">ApiKeyHeader</Item>
            <Item Key="SendClaimsIn">Body</Item>
          <Item Key="ClaimUsedForRequestPayload">verifyOTPRequestBody</Item>
          <Item Key="DefaultUserMessageIfRequestFailed">Unable to verify the OTP.</Item>
          <Item Key="UserMessageIfCircuitOpen">Unable to verify the OTP - API Not Reachable.</Item>
          <Item Key="UserMessageIfDnsResolutionFailed">Unable to verify the OTP - DNS Resolution Failed.</Item>
          <Item Key="UserMessageIfRequestTimeout">Unable to verify the OTP. - Request Timeout</Item>
          </Metadata>
        <CryptographicKeys>
          <Key Id="Ocp-Apim-Subscription-Key" StorageReferenceId="B2C_1A_RestApiEncryptionKey" />
        </CryptographicKeys>
        <InputClaimsTransformations>
          <InputClaimsTransformation ReferenceId="GenerateVerifyOTPRequestBody" />
        </InputClaimsTransformations>
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="verifyOTPRequestBody" />
        </InputClaims>
        <OutputClaims>
          
        </OutputClaims>
        <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
        </TechnicalProfile>

Here is the actual self-asserted technical profile that presents the UI for the display control , email and other fields. Kindly ignore the mobile and userName claims below , they are used in custom REST API to check if userName is eligible to login and if the userName and mobile are linked in our custom user database

        <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
          <DisplayName>Email signup</DisplayName>
          <Protocol Name="Proprietary" 
      Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, 
      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          <Metadata>
            <Item Key="IpAddressClaimReferenceId">IpAddress</Item>
            <Item Key="ContentDefinitionReferenceId">api.localaccountsignup</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
          </CryptographicKeys>
          <InputClaims>
             <!-- <InputClaim ClaimTypeReferenceId="email" />  -->
          </InputClaims>
          <DisplayClaims>
              <DisplayClaim DisplayControlReferenceId="PhoneVerificationControl" />
              <DisplayClaim ClaimTypeReferenceId="email" Required="true" />
              <DisplayClaim ClaimTypeReferenceId="signInNames.userName" Required="true"/>
            <DisplayClaim ClaimTypeReferenceId="mobile" Required="true"/>
          </DisplayClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" />
            
            <OutputClaim ClaimTypeReferenceId="signInNames.userName" Required="true"/>
            <OutputClaim ClaimTypeReferenceId="mobile" Required="true"/>
            <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="Verified.Email" Required="true" />
            <OutputClaim ClaimTypeReferenceId="newPassword" Required="true" />
            <OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
            <OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" />
            <OutputClaim ClaimTypeReferenceId="newUser" />

            <!-- Optional claims, to be collected from the user -->
            <OutputClaim ClaimTypeReferenceId="displayName" />
            <OutputClaim ClaimTypeReferenceId="givenName" />
            <OutputClaim ClaimTypeReferenceId="surName" />
          </OutputClaims>
          <ValidationTechnicalProfiles>
            <ValidationTechnicalProfile ReferenceId="RESTSecure-CheckUserEligibility" />
            <ValidationTechnicalProfile ReferenceId="REST-CheckUserMobileLink" />
            <ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
          </ValidationTechnicalProfiles>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
        </TechnicalProfile>
0 Answers
Related