Validate OTP
Validates a one-time passcode (OTP) that the user enters in the client within a web to mobile authentication or transaction signing flow, matching the code displayed in the web journey.
About client-facing steps
A journey is a sequence of steps that are executed when it's invoked by a client application (known as the "client"). Some steps require involvement from the client, such as to collect user input. Other steps, like validating a token, are executed in the backend by the Mosaic journey engine alone.
When invoked, the journey begins executing the steps while the client waits for further instructions. When a journey reaches a client-facing step, the journey asks the client for the required input and then waits for the client to respond. The client presents their own UI if user interaction is required, and returns input to the journey. The journey then proceeds in a similar manner until it's completed.
Description
In the context of web to mobile authentication or transaction signing journeys, this step instructs the client application to present a form on the user’s mobile device, where the user enters an OTP that was displayed in the web journey (for example, when Display Web OTP is enabled in the Web to Mobile step).
The web journey waits for the client to submit the user’s input and validates it against the code generated earlier for the session.
This step is designed to be used in a dedicated mobile journey. This journey is specifically called by the Web to mobile authentication and Web to mobile transaction signing steps, which handle the initial authentication request from the web application. When the Display Web OTP parameter is enabled in these steps, the journey engine automatically invokes the mobile journey containing the Validate OTP step to complete the authentication process.
Note
The code length, expiry, failed-attempts limit, and lockout duration are inherited from the application’s OTP authentication method settings.
If validation succeeds, the journey proceeds to the next step. If it fails, the journey follows the configured failure behavior.
Configuration
Field | Description |
---|---|
Error Output Variable | Name of the variable that stores any error returned by the step. |
Failure Behavior | Determines the behavior in case of failure, which either aborts the journey or proceeds to a failure branch of the control flow (default). |
Example
Suppose a web user initiates authentication or transaction signing through a Web to Mobile journey where Display Web OTP is enabled. The Mosaic journey engine displays an OTP on the web browser and automatically triggers the corresponding mobile journey that includes the Validate OTP step.
When the mobile approve journey reaches the Validate OTP step, the app prompts the user to enter the OTP (for example, in a form) previously displayed in the web session and submits it back to Mosaic for validation using the Orchestration SDK call:
class ExampleClass: TSIdoDelegate {
func TSIdoDidReceiveResult(_ result: Result<IdentityOrchestration.TSIdoServiceResponse, IdentityOrchestration.TSIdoJourneyError>) {
switch result {
case .success(let response):
let stepId = response.journeyStepId
// Check if the current step is the Validate OTP step
if stepId == .otpValidation {
// Present the OTP input screen to the user
showOtpValidationScreen() { otp in
// Submit the user's OTP input back to the Mosaic journey
try? TSIdo.submitClientResponse(
clientResponseOptionId: .clientInput,
data: ["passcode": otp] // 'passcode' must match the expected input key
)
}
}
case .failure(let error):
// Handle journey or network errors
print("Journey error: \(error)")
}
}
private func showOtpValidationScreen(completion: @escaping (String) -> Void) {
// Display a UI where the user can enter the OTP from the web journey
// Once submitted, call completion(otp)
}
}
data class OtpResult(val passcode: String)
private fun processServiceResponse(idoResponse: TSIdoServiceResponse) {
when (idoResponse.journeyStepId) {
TSIdoJourneyActionType.ValidateOtp.type -> validateOtp(idoResponse)
}
}
private fun validateOtp(idoResponse: TSIdoServiceResponse) {
//TODO: show ui to collect the otp code from user, and process the input code when user hits the submit button.
//For example: the otp code is collected into otpCode variable
val codeLength = idoResponse.responseData?.optInt("code_length", 4)
if (otpCode.length != codeLength) {
//handle invalid code length
} else {
val responseData = OtpResult(otpCode)
TSIdo.submitClientResponse(TSIdoClientResponseOptionType.ClientInput.type, responseData, callback)
}
}