4
votes

I am using custom policies to do some User Journeys and using SocialAndLocalAccountsWithMfa. In one of the step I am asking the user for their email address

I am using "LocalAccountDiscoveryUsingEmailAddress" to get their email address on the first screen. And then depending on if they are registered for MFA they are sent to Mobile OTP screen or sent to the mail address OTP screen.

Now what happens is that after they put their email address and press ok (and they are sent to the emial OTP screen) they are presented again with another screen to put their email address again to verify. I am looking for two possibilites here

1) (Preferred) They are immediately sent an email OTP - so they don't have to type their email address and then click on "verify emial" to send OTP

Or

2) Their email address is populated in the screen already so they don't have to type it again and thus all they have to do is click on "Verify Email" button.

My Userjourney for this looks something like

   <UserJourney Id="PasswordReset">
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="PasswordResetUsingEmailAddress" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
              <Value>strongAuthenticationPhoneNumber</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>           
          </Preconditions>  
          <ClaimsExchanges>
            <ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddressOTP" />
          </ClaimsExchanges>
        </OrchestrationStep>        
        <OrchestrationStep Order="3" Type="ClaimsExchange">
          <Preconditions>
            <Precondition Type="ClaimsExist" ExecuteActionsIf="false">
              <Value>strongAuthenticationPhoneNumber</Value>
              <Action>SkipThisOrchestrationStep</Action>
            </Precondition>           
          </Preconditions>  
          <ClaimsExchanges>
            <ClaimsExchange Id="PhoneFactor-Verify" TechnicalProfileReferenceId="PhoneFactor-InputOrVerify" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="4" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="5" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
      <ClientDefinition ReferenceId="DefaultWeb" />
    </UserJourney>
1

1 Answers

3
votes

Firstly, for #2, you can implement a technical profile that accepts the email address as an input claim so that it is pre-filled in the self-asserted page, such as:

<TechnicalProfile Id="SelfAsserted-LocalAccount-EmailVerification">
  <DisplayName>Local Account Email Address Verification</DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ContentDefinitionReferenceId">api.localaccount.emailverification</Item>
    <Item Key="EnforceEmailVerification">true</Item>
  </Metadata>
  <InputClaimsTransformations>
    <InputClaimsTransformation ReferenceId="CreateReadonlyEmailClaim" />
  </InputClaimsTransformations>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="readonlyEmail" />
  </InputClaims>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="readonlyEmail" PartnerClaimType="verified.email" Required="true" />
  </OutputClaims>
</TechnicalProfile>

This technical profile is referring to a read-only email address so that the end user can't change the email address for the OTP verification.

The CreateReadonlyEmailClaim claims transformation is defined as:

<ClaimsTransformation Id="CreateReadonlyEmailClaim" TransformationMethod="FormatStringClaim">
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="inputClaim" />
  </InputClaims>
  <InputParameters>
    <InputParameter Id="stringFormat" DataType="string" Value="{0}" />
  </InputParameters>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="readonlyEmail" TransformationClaimType="outputClaim" />
  </OutputClaims>
</ClaimsTransformation>

The readonlyEmail claim type is declared as:

<ClaimType Id="readonlyEmail">
  <DisplayName>E-mail Address</DisplayName>
  <DataType>string</DataType>
  <UserInputType>Readonly</UserInputType>
</ClaimType>

For #1, you can implement the above changes as well as implement a JavaScript function in a custom page UI to "click" the Verify Email button to initiate the OTP verification.