I've been struggling with this for days as well. I've managed to get it working by adding the following to the Extensions file.
- Add step 3 to the existing OrchestrationSteps for the PasswordReset UserJourney
<UserJourney Id="PasswordReset">
<OrchestrationSteps>
<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="3" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="ShowSuccess" TechnicalProfileReferenceId="LocalAccountWritePasswordChanged" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
</OrchestrationSteps>
<ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
- Add this ClaimType in BuildingBlocks/ClaimsSchema
<ClaimType Id="justResetPassword">
<DisplayName>justResetPassword</DisplayName>
<DataType>boolean</DataType>
<UserHelpText>Indicates whether the user just reset their password via the forgot password feature.</UserHelpText>
<UserInputType>Button</UserInputType>
</ClaimType>
- Add the above mentioned new TechnicalProfile: LocalAccountWritePasswordChanged
<TechnicalProfile Id="LocalAccountWritePasswordChanged">
<DisplayName>Changed password</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.passwordchangesuccess</Item>
<Item Key="language.button_continue">Back to Login</Item>
<Item Key="language.initial_intro">Ready to login again...</Item>
<Item Key="language.verifying_blurb">Preparing login screen.</Item>
<!-- TODO: Hide cancel button -->
</Metadata>
<CryptographicKeys>
<Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
</CryptographicKeys>
<InputClaims>
<InputClaim ClaimTypeReferenceId="objectId" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="justResetPassword" DefaultValue="true" />
</OutputClaims>
</TechnicalProfile>
- Modify your Relying Party file to also have an outputClaim of the new type justResetPassword
<OutputClaim ClaimTypeReferenceId="justResetPassword" />
I think the trick is that this new technical profile has an outputclaim of justResetPassword, so it will fire to try and capture that value. As it's datatype is button though it doesn't display. This bit I am not very clear on, but as it is working and it took me this long to get here, I'm not going to question it too much.
You may notice this new technical profile references a ContentDefinition of api.passwordchangesuccess
. This is a custom content definition that I created myself to provide a nicer custom heading for the "Password reset message". You may be able to utilize the ContentDefinition api.selfasserted instead if you don't need too much customisation of the success page.
Final result after resetting password:
Screenshot