Create a custom button for " Resend OTP " on the page of validating OTP

How to create a custom “Resend OTP” button or feature that resends a new OTP back to the user in an authentication journey.

Referring to the attached image of the journey I wanted to know where can we have the option for “Resend OTP” feature.
We tried to a add a scripted node but it has only two options "Choice Callback " and “Text Callback”
We wanted a have a button which will redirect the journey back to the “HOTP Generator” and creates a new OTP for the user to enter.

1 Like

Hi @Schauhan

This is a good question, and I’m not 100% certain that it can be done on the collector screen, but I think it can be done. One quick note is that I believe all of the callbacks documented here are supported, not just the Choice and Text callbacks.

What about taking the approach of offering to re-send on failure from the OTP Collector Decision after executing the Retry Limit Decision node? You could present the user with a Choice Callback asking if they would like to have the OTP re-sent to them and then route your logic accordingly to either the HOTP Generator or the OTP Collector Decision.

It’s not quite as elegant of a flow, but it delivers the functionality I believe you are looking for while also offering some controls to prevent spamming OTPs by placing it behind the Retry Limit Decision node.


Hi @Schauhan,

As @mwtech points out, the available OOTB solution is not perfect, this is the limitation in using AM’s hosted login page. There is though the possibility of using a ScriptTextOutputCallback which manipulates directly the DOM, but that is a dangerous direction, fragile, as future product releases that incur changes to the DOM would break it. In order to control completely the user experience, the best avenue is to build the login frontend - possibly using the SDKs [ Feature highlights :: SDKs ]. Some of our customers have implemented use cases such as yours, but with a login frontend they own.



Having the ability to add a button which could route us to different nodes in a journey can be something that is very handy. It would be useful not only in this example, but in many others. ForgeRock should consider adding something like a “Button Node”. This would be very simple to develop too. @salbertelli01

1 Like

You could have something like this with a scripted decision node:

Capture d’écran 2023-08-11 à 18.12.39

This uses the PasswordCallback, and the BooleanAttributeInputCallback. So, you do not use the OTP Collector Decision and instead you can return the two callbacks. The script has to check the value of the boolean callback first, and if it is true then it can go back to the HOTP Generator node (ideally through a Retry Limit Decision node first, like you already have).

The key to the script is to be able to check the validation of the OTP code. You can get the generated value from the state in the script with something like this:

var code = nodeState.get("oneTimePassword").asString();
you need to compare this to the user input found in:
var response = new fr.String(callbacks.get(0).getPassword());
(note: this requires a Java String import)

So, this Scripted Decision Node would have at least a resend, and an ok output.

I hope this helps.


@gery.ducatel - this is really slick, I like this a lot!


Then with an in-house built login app, the “resend” callback rendering could be made into a button… which is a better user experience than checking a checkbox and clicking next.

Found this post while looking to implement exactly this. I’m playing with a Scripted Node using the Text Callback in place of the OTP Collector with a “resend” outcome path that loops back to the HOTP Generator.
I also tried a method of having a Page Node with the OTP Collector and a link that brings the user to a compartmentalized OTP generate and send journey. Is it possible to collect the user details after the first login and persist it through to the redirect?
I’m new to ForgeRock so I’m trying to differentiate where my roadblocks are caused by limitations of AM with Hosted Pages or my misunderstanding of usage