Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/b2c_custom_policiesV2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ on:
- stg
- test
- demo
- prod

jobs:
build-and-deploy:
Expand Down
23 changes: 20 additions & 3 deletions b2c/custom_policies/demo/B2C_1A_SignUpOrSignin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,26 @@
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 6: Issue token -->
<OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

<!-- Step 5b: Read account from AAD after signup to populate signInNames.emailAddress -->
<OrchestrationStep Order="6" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>isForgotPassword</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
<Precondition Type="ClaimsExist" ExecuteActionsIf="false">
<Value>isSignUp</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadAfterSignUp" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 7: Issue token -->
<OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

</OrchestrationSteps>
</UserJourney>
Expand Down Expand Up @@ -230,7 +248,6 @@
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
<OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,7 @@
<Protocol Name="Proprietary"
Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
<Metadata>
<Item Key="ServiceUrl">https://sds-api-mgmt.demo.platform.hmcts.net/pre-api-b2c/b2c/email-verification
</Item>
<Item Key="ServiceUrl">https://sds-api-mgmt.demo.platform.hmcts.net/pre-api-b2c/b2c/email-verification</Item>
<Item Key="SendClaimsIn">Body</Item>
<Item Key="AuthenticationType">Bearer</Item>
<Item Key="UseClaimAsBearerToken">bearerToken</Item>
Expand Down
23 changes: 20 additions & 3 deletions b2c/custom_policies/dev/B2C_1A_SignUpOrSignin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,26 @@
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 6: Issue token -->
<OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

<!-- Step 5b: Read account from AAD after signup to populate signInNames.emailAddress -->
<OrchestrationStep Order="6" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>isForgotPassword</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
<Precondition Type="ClaimsExist" ExecuteActionsIf="false">
<Value>isSignUp</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadAfterSignUp" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 7: Issue token -->
<OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

</OrchestrationSteps>
</UserJourney>
Expand Down Expand Up @@ -231,7 +249,6 @@
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
<OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
Expand Down
265 changes: 265 additions & 0 deletions b2c/custom_policies/prod/B2C_1A_SignUpOrSignin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TrustFrameworkPolicy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
PolicySchemaVersion="0.3.0.0"
TenantId="hmctsprodextid.onmicrosoft.com"
PolicyId="B2C_1A_SignUpOrSignin"
DeploymentMode="Development"
PublicPolicyUri="http://hmctsprodextid.onmicrosoft.com/policies/B2C_1A_SignUpOrSignin.xml"
UserJourneyRecorderEndpoint="urn:journeyrecorder:applicationinsights"
>
<BasePolicy>
<TenantId>hmctsprodextid.onmicrosoft.com</TenantId>
<PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId>
</BasePolicy>

<UserJourneys>
<UserJourney Id="CustomSignUpSignIn">
<OrchestrationSteps>

<!-- Step 1: Sign-in (email) on the unified page -->
<OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
<ClaimsProviderSelections>
<ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
<ClaimsProviderSelection TargetClaimsExchangeId="ForgotPasswordExchange" />
</ClaimsProviderSelections>
<ClaimsExchanges>
<ClaimsExchange
Id="LocalAccountSigninEmailExchange"
TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-Email"
/>
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 2: If the user clicked Forgot password -->
<OrchestrationStep Order="2" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>objectId</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange
Id="SignUpWithLogonEmailExchange"
TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail"
/>
<ClaimsExchange Id="ForgotPasswordExchange" TechnicalProfileReferenceId="ForgotPassword" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 3: If the user clicked Forgot password -->
<OrchestrationStep Order="3" Type="InvokeSubJourney">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="false">
<Value>isForgotPassword</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<JourneyList>
<Candidate SubJourneyReferenceId="PasswordResetSubJourney" />
</JourneyList>
</OrchestrationStep>

<OrchestrationStep Order="4" Type="InvokeSubJourney">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>isForgotPassword</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>isSignUp</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
<Precondition Type="ClaimEquals" ExecuteActionsIf="true">
<Value>objectId</Value>
<Value>ea7978c4-da9a-42ae-ad9e-c5a93e7fa46d</Value> <!-- assume automated test user has valid phone -->
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
<Precondition Type="ClaimEquals" ExecuteActionsIf="true">
<Value>objectId</Value>
<Value>72778f3e-e09a-4711-96bf-c93dd8ef9a5a</Value> <!-- prod user to skip OTP -->
<Action>SkipThisOrchestrationStep</Action>
</Precondition>

</Preconditions>
<JourneyList>
<Candidate SubJourneyReferenceId="EmailOtpFlow" />
</JourneyList>
</OrchestrationStep>

<!-- Step 5: Create or read account from AAD B2C -->
<OrchestrationStep Order="5" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>isForgotPassword</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>isSignUp</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
<Precondition Type="ClaimEquals" ExecuteActionsIf="false">
<Value>otpVerified</Value>
<Value>true</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadOrCreate" TechnicalProfileReferenceId="AAD-UserReadUsingEmailAddress" />
</ClaimsExchanges>
</OrchestrationStep>


<!-- Step 5b: Read account from AAD after signup to populate signInNames.emailAddress -->
<OrchestrationStep Order="6" Type="ClaimsExchange">
<Preconditions>
<Precondition Type="ClaimsExist" ExecuteActionsIf="true">
<Value>isForgotPassword</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
<Precondition Type="ClaimsExist" ExecuteActionsIf="false">
<Value>isSignUp</Value>
<Action>SkipThisOrchestrationStep</Action>
</Precondition>
</Preconditions>
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadAfterSignUp" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 7: Issue token -->
<OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

</OrchestrationSteps>
</UserJourney>

</UserJourneys>

<SubJourneys>
<SubJourney Id="EmailOtpFlow" Type="Call">
<OrchestrationSteps>

<!-- Step 1: Generate OTP -->
<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="GenerateEmailCode" TechnicalProfileReferenceId="GenerateCode" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 2: Acquire API token -->
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AcquireToken" TechnicalProfileReferenceId="REST-AcquireAccessToken" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 3: Send OTP -->
<OrchestrationStep Order="3" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="SendEmailCodeAPI" TechnicalProfileReferenceId="SendEmailVerificationAPI" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 4: Ask user to enter OTP -->
<OrchestrationStep Order="4" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="EnterEmailCode" TechnicalProfileReferenceId="SelfAsserted-VerifyEmailCode" />
</ClaimsExchanges>
</OrchestrationStep>

</OrchestrationSteps>
</SubJourney>


<SubJourney Id="PasswordResetSubJourney" Type="Call">
<OrchestrationSteps>
<!-- Step 1: Collect email -->
<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="PasswordReset-CollectEmail"
TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress-NoMsEmail" />
</ClaimsExchanges>
</OrchestrationStep>


<!-- Step 2: Generate OTP -->
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="GenerateEmailCode" TechnicalProfileReferenceId="GenerateCode" />
</ClaimsExchanges>
</OrchestrationStep>

<OrchestrationStep Order="3" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AcquireToken" TechnicalProfileReferenceId="REST-AcquireAccessToken" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 3: Send OTP -->
<!-- Debug Step: Show OTP on screen -->
<OrchestrationStep Order="4" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="SendEmailCodeAPI" TechnicalProfileReferenceId="SendEmailVerificationAPI" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 4: Enter OTP -->
<OrchestrationStep Order="5" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="EnterEmailCode" TechnicalProfileReferenceId="SelfAsserted-VerifyEmailCode" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 5: Lookup user -->
<OrchestrationStep Order="6" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="ReadUserByEmail" TechnicalProfileReferenceId="AAD-UserReadUsingEmailAddress" />
</ClaimsExchanges>
</OrchestrationStep>

<!-- Step 6: Reset password -->
<OrchestrationStep Order="7" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="PasswordReset" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
</OrchestrationSteps>
</SubJourney>

</SubJourneys>

<RelyingParty>
<DefaultUserJourney ReferenceId="CustomSignUpSignIn" />
<Endpoints>
<!--points to refresh token journey when app makes refresh token request-->
<Endpoint Id="Token" UserJourneyReferenceId="RedeemRefreshToken" />
<Endpoint Id="UserInfo" UserJourneyReferenceId="UserInfoJourney" />
</Endpoints>
<UserJourneyBehaviors>
<SessionExpiryType>Absolute</SessionExpiryType>
<SessionExpiryInSeconds>3600</SessionExpiryInSeconds>
<JourneyInsights
TelemetryEngine="ApplicationInsights"
InstrumentationKey="3790f980-7828-4f4b-9e24-c944bbe5498a"
DeveloperMode="true"
ClientEnabled="true"
ServerEnabled="true" />
<ScriptExecution>Allow</ScriptExecution>
</UserJourneyBehaviors>
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
<OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
<OutputClaim ClaimTypeReferenceId="isSignUp" />
<OutputClaim ClaimTypeReferenceId="isForgotPassword" DefaultValue="false" />
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
</RelyingParty>
</TrustFrameworkPolicy>
Loading