This document will tell you about the Advance JavaScript Customizations available in LoginRadius and the customization steps around them.
Here we will see how we can customize JavaScript to Add the functionality of a specific LoginRadius function. JS customization of features/functions that we can build in Javascript are achieved with initialization of method with the respective action
Prerequisites:
All of the advanced customizations which we have explained here require that the LoginRadius User Registration Interface is configured on your site. For more information have a look at the getting started document
Before proceeding with further JS Customizations, please make sure that the LRObject is initiated correctly and for initialization, you can refer here.
To verify a customer's email address, use the LRObject.init method with the verifyEmail action. The following code can be used for reference:
var verifyemail_options = {};verifyemail_options.onSuccess = function (response) { // On Success console.log(response);};verifyemail_options.onError = function (errors) { // On Errors console.log(errors);};LRObject.util.ready(function () { LRObject.init("verifyEmail", verifyemail_options);});
Note:
The success callback will return a JSON object {IsPosted: true}.
verifyEmail action can be used both to verify email and reset password, depending upon the vtype passed in the link.
If you have enabled the Token Type as OTP for Delete Account Email Template to receive the OTP for deleting an account, you must specify the container below.
This section covers how to setup Risk-Based Authentication in your LoginRadius Implementation via our JavaScript Interface.
Make sure you have configured Risk-Based Authentication with the desired options in your LoginRadius Admin Console as per our documentation here.
In your LoginRadius JavaScript initialization options, you will need to add the following parameters:
Options.riskBasedAuthentication = true; // If you configured to prompt for Multi-Factor Authentication // via SMS you will need enable the Phone Login parameter Options.phoneLogin = true;
Note: If you are using Multi-Factor Authentication with Risk Based Authentication, your LoginRadius Account needs to be configured for Passwordless Login. To enable Passwordless Login please contact LoginRadius Support
Following options can be used with commonOptions to configure Risk Based Authentication:
Name
Type
Description
rbaOneclickEmailTemplate
String
Risk based authentication email template name one click
rbaCityEmailTemplate
String
Risk based authentication email template name for City
rbaCountryEmailTemplate
String
Risk based authentication email template name for Country
rbaBrowserEmailTemplate
String
Risk based authentication email template name for Browser
rbaIpEmailTemplate
String
Risk based authentication email template name for IP
rbaDeviceEmailTemplate
String
Risk based authentication email template name for Device
rbaOTPSmsTemplate
String
Risk based authentication sms template name for otp
rbaCitySmsTemplate
String
Risk based authentication sms template name for City
rbaCountrySmsTemplate
String
Risk based authentication sms template name for Country
rbaBrowserSmsTemplate
String
Risk based authentication sms template name for Browser
rbaIpSmsTemplate
String
Risk based authentication sms template name for IP
rbaDeviceSmsTemplate
String
Risk based authentication sms template name for Device
To send a request to delete a customer's profile, use the LRObject.init with the deleteUser action. This action will work when a customer is logged in. The following code can be used for reference:
var deleteuser_options = {};deleteuser_options.onSuccess = function(response) {// On Successconsole.log(response);};deleteuser_options.onError = function(errors) {// On Errorsconsole.log(errors);}LRObject.util.ready(function() {LRObject.init("deleteUser", deleteuser_options);});
Note:
The success callback will return a JSON object {IsDeleteRequestAccepted: true}.
To confirm the deletion of a customer's profile, use the LRObject.init with the deleteUserConfirm action. The following code can be used for reference:
var deleteuser_confirm_options = {};deleteuser_confirm_options.onSuccess = function(response) {// On Successconsole.log(response);};deleteuser_confirm_options.onError = function(errors) {// On Errorsconsole.log(errors);}LRObject.util.ready(function() {LRObject.init("deleteUserConfirm", deleteuser_confirm_options);});
Account Linking allows you to provide a flow for customers to link their social provider accounts into a single unified account. For more information on this have a look at Account Linking documentation.
This section covers the technical aspects of implementing Account Linking. The following steps will only work when the customer is logged in.
To implement the account unlinking interface, use the LRObject.init method with the unLinkAccount action. The following code can be used for reference:
var unlink_options = {};unlink_options.onSuccess = function(response) {// On Successconsole.log(response);};unlink_options.onError = function(errors) {// On Errorsconsole.log(errors);}LRObject.util.ready(function() {LRObject.init("unLinkAccount", unlink_options);});
4 . Add Template Code
<script type="text/html" id="loginradiuscustom_tmpl_link"><# if(isLinked) { #><div class="lr-linked"><a class="lr-provider-label" href="javascript:void(0)" title="<#= Name #>" alt="Connected"><#=Name#> is connected</a><a onclick='return <#=ObjectName#>.util.unLinkAccount(\"<#= Name.toLowerCase() #>\",\"<#= providerId #>\")'>delete</a></div><# } else {#><div class="lr-unlinked"><a class="lr-provider-label" href="javascript:void(0)" onclick="return <#=ObjectName#>.util.openWindow('<#= Endpoint #>');" title="<#= Name #>" alt="Sign in with <#=Name#>"><#=Name#></a> </div><# } #></script>
Note:
The template code uses the variable isLinked to conditionally display the linked or unlinked account.
Method 2: REST APIs for Account Linking and Unlinking
While it's easy to implement account linking using our JavaScript interfaces, we also provide API calls that you can make on the client-side to accomplish the same goal:
Refer to the following sample code to implement the Account linking using the programmatic link. The following code linked the account using the post method:
<!DOCTYPE html><html><head> <title>Social Login | LR Social Account Unlinking</title> <meta charset="utf-8"> <script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script> <script src="https://auth.lrcontent.com/v2/js/LoginRadiusV2.js"></script></head><body> <h3>Soicallogin by programmatic links</h3> <div id="provider-container"> <button class="provider" onclick="openWin()">login with google</button> </div> <script type="text/javascript"> function openWin() { let accessToken = "<LR access token>";//LR access token received from authentication let callback = window.location.href; let appname = "<LR app name>"; let apikey = "<LR api key>"; let url = `https://${appname}.hub.loginradius.com/RequestHandler.aspx?apikey=${apikey}&provider=google&callback=${callback}&same_window=&is_access_token=true&callbacktype=&disablesignup=undefined&scope=&ac_linking=true`; window.open(url, "childWindow", 'menubar=1,resizable=1,width=450,height=450,scrollbars=1'); window.addEventListener("message", LRReceiveMessage, false); function LRReceiveMessage(event) { console.log(event); if (event.origin.indexOf(('hub.loginradius.com')) > -1) { console.log("LRTokenKey", event.data); let candidatetoken = event.data; linkAccountAPI(candidatetoken); } } function linkAccountAPI(candidatetoken) { $.ajax({ async: true, type: "POST", crossDomain: true, url: `https://api.loginradius.com/identity/v2/auth/socialidentity?apikey=${apikey}`, dataType: "json", headers: { "content-Type": "application/json", "Authorization": `Bearer ${accessToken}` }, "data": JSON.stringify({ "candidatetoken": candidatetoken }) }).done(function (response) {// write your code after linking successfully console.log(response); }); } } </script></body></html>
To implement the profile editor interface, use the LRObject.init method with the profileEditor action. The following code can be used for reference:
var profileeditor_options = {};profileeditor_options.container = "profileeditor-container";profileeditor_options.onSuccess = function(response) {// On Successconsole.log(response);};profileeditor_options.onError = function(response) {// On Errorconsole.log(response);};LRObject.util.ready(function() {LRObject.init("profileEditor",profileeditor_options);});
<div id="profileeditor-container"></div>
When the Profile Editor is initialized, it loads all of the fields specified in your Registration Form Schema excluding the password fields. The schema is located within the LRObject: LRObject.registrationFormSchema and can be hard coded to any custom schema that you would like to present the customer for profile editing.
Note: At the moment the Profile Editor does not provide support for complex fields / arrays of objects.
To implement the interface for resending verification email, use the LRObject.init method with the resendVerificationEmail action. The following code can be used for reference:
var resendemailverification_options= {};resendemailverification_options.container = "resendemailverification-container";resendemailverification_options.onSuccess = function(response) {// On Successconsole.log(response);};resendemailverification_options.onError = function(response) {// On Errorconsole.log(response);};LRObject.util.ready(function() {LRObject.init("resendVerificationEmail",resendemailverification_options);});
To implement an interface for Multi-Factor Authentication, use the LRObject.init method with the createTwoFactorAuthentication action. The following code can be used for reference:
var authentication_options = {};authentication_options.container = "authentication-container";authentication_options.onSuccess = function(response) {// On Successconsole.log(response);};authentication_options.onError = function(errors) {// On Errorsconsole.log(errors);}LRObject.util.ready(function() {LRObject.init("createTwoFactorAuthentication", authentication_options);});
To implement an interface for One Touch Login, use the LRObject.init method with the onetouchLogin action. The following code can be used for reference:
var one_touch_options = {};one_touch_options.container = "onetouchLogin-container";one_touch_options.onSuccess = function(response) {// On Successconsole.log(response);};one_touch_options.onError = function(errors) {// On Errorsconsole.log(errors);}LRObject.util.ready(function() {LRObject.init("onetouchLogin", one_touch_options);});
To implement the interface for Passwordless Login, use the LRObject.util method with the passwordlessLoginValidate action. The following code can be used for reference:
var passwordless_options= {};passwordless_options.onSuccess = function(response) {// On Successconsole.log(response);};passwordless_options.onError = function(errors) {// On Errorsconsole.log(errors);}LRObject.util.ready(function() {LRObject.init('passwordlessLoginValidate', passwordless_options);});
The Security Question workflow allows you to verify the customer’s identities upon different events, such as reset password requests and login via an unfamiliar device by providing a secret answer to a predefined security question.
For a step-by-step guide on configuring security questions through your LoginRadius Admin Console, as well as in-depth coverage on relevant API end points, see this documentation.
Customers will then be asked upon registration via the registration form to fill out the questions. see below for details on the other use cases:
The following interface will allow customers to select a Security Question and Provide an Answer. Upon providing valid credentials the customer will be prompted to complete a password reset:
var resetPasswordBySecQ_options = {};resetPasswordBySecQ_options.container = "resetPasswordBySecQ-container";resetPasswordBySecQ_options.onSuccess = function(response) { // On Success console.log(response);};resetPasswordBySecQ_options.onError = function(errors) { // On Errors console.log(errors);}LRObject.util.ready(function() { LRObject.init("resetPasswordBySecurityQuestion", resetPasswordBySecQ_options );});
The following interface will allow customers to reset the passkey. You need to initialize the resetPassKey container in the auth Page, before-script.js, as explained below:
var commonOptions = {};commonOptions.apiKey = <your api key>;commonOptions.resetPassKeyUrl = window.location; //Change as per requirementvar LRObject = new LoginRadiusV2(commonOptions);LRObject.util.ready(function () { LRObject.init("passkeylogin", passkey_manage);});
The following interface will allow customers to show a list of passkeys. You need to initialize the passkeylogin container in the profile Page, before-script.js, as explained below:
var commonOptions = {};commonOptions.apiKey = <your api key>;commonOptions.resetPassKeyUrl = window.location; //Change as per requirementvar LRObject = new LoginRadiusV2(commonOptions);LRObject.util.ready(function() { LRObject.init("passkeylogin", {container:'passkeylogin-container'});});
If a customer is trying to login on a Smart TV, typing the password on a TV remote can be challenging. By enabling this option, customers can enter their email address or username and click on the smartLogin button. An email is then sent to the customer's email address, containing a link to login to the Smart TV.
Following options can be used with commonOptions to configure smart login:
Name
Type
Description
smartLoginPingCount
Number
Total number of ping requests made by client before it expires.
smartLoginPingInterval
Number
Time interval between each ping request in seconds
smartLoginEmailTemplate
String
Email template which is sent on smartLogin
smartLoginRedirectUrl
String
redirection url for smartLogin
Note:
Smart Login has to be enabled on your LoginRadius site in order to use this feature. It can be enabled by reaching out to LoginRadius support.
1 . Add the smartLogin parameters in User Registration JS:
var commonOptions = {};commonOptions.apiKey = "<your api key>";commonOptions.smartLoginPingCount = <any number>; //default is 100 timescommonOptions.smartLoginPingInterval = <any number>; //default is 5 secondcommonOptions.smartLoginEmailTemplate = <Email template>commonOptions.smartLoginRedirectUrl = <Redirect Url>...
2 . Use the following hook to change the button's name
You can customize all the button names with the following fields:
Field Name
Original Text
login
Login
registration
Register
socialregistration
Login
loginrequiredfieldsupdate
Login
verifyemail
Verify
resetpassword
Reset Password
sociallogin
Login
otp
Verify
twofaotp
Verify
showqrcode
Verify
updatephone
Update
changephone
Update
forgotpassword
Send
securityquestions
Get
changepassword
Submit
resendemailverification
Send
addemail
Send
removeemail
Send
changeusername
Submit
profileeditor
Update Profile
otplogin
OTP
passwordlessloginbuttonlabel
Email me a link to Sign In
passwordlessloginotpbuttonlabel
Send an OTP to Sign In
createtwofactorauthentication
2-Step Verification
sendotp
Send OTP
resendotp
Resend OTP
changenumber
Change Number
backupcode
Login
backupcodebutton
Try another way to Sign In
disablegoogleauthenticator
Disable Google Authenticator
disableotpauthenticator
Disable OTP Authenticator
updatesecurityquestion
Update Security Question
resetpwdbysecq
Reset Password By SecurityQ
smartlogin
Smart Login
validatecode
Validate
onetouchlogin
Login
progressiveprofiling
Progressive Profiling
3 . The following can be used to handle the smartLogin event:
var options = {};options.onSuccess = function(response) {//On Successconsole.log(response);if (response.access_token) {// Handle the access token to Login a user}};options.onError = function(errors) {//On Errorconsole.log(errors);};options.container = "smartLogin-container";LRObject.util.ready(function() {LRObject.init("smartLogin",options);})
<div id="smartLogin-container"></div>
Note:
After clicking on the login button, the client will continuously ping the server to confirm whether customer has clicked on the link in the email.
The following methods return the Account ID (UID) and Token for the currently logged in customer. These functions can be used after the customer login.
LoginRadius provides you with the ability to have both Standard and Phone Login at the same time. You can learn more about this workflow here. This section covers setting up the workflow using the LoginRadius JavaScript interface.
1 . In LoginRadius Admin Console, navigate to
Branding > Forms and make sure you choose Phone ID from the Standard Fields (Basic) section and click Save to make it part of the Enabled Fields. In the Enabled Fields area, click on the edit button next to *Email.
Click the Advanced tab, set Email as optional, and click Save. Repeat this step with Phone ID Finally, click on Save Configuration.
For a customer to leverage the PIN Authentication features they must first set one on their given account. Pin setup can be implemented at two places: Registration or during Login (depending on your requirements).
With the help of the flag "AskOnRegistration" flag, we can prompt the customer to provide the PIN at the time of registration only.
PIN configuration response from app configuration API
PIN configuration, at the time of login is needed when the PIN is not setup earlier and :
AskOnLogin is true
AskOnlyOnFirstLogin is true and customer is logging in first time.
Note: The Point is to be noted that if PIN configuration is mandatory then at the time of login, if any of the above two condition meet the criteria the core API would send an Error code "1243" and accordingly we have to set pin using pinauthtoken. But in case if PIN configuration is optional, then core API would not handle any PIN handling, and at that time JS would be showing PIN configuration schema along with skip button. Now here we can use profile update API to update PIN data. If skipped here (since it is optional) then PIN skipped value would be sent to true.
This scenario comes into existence only when the customer has not setup his pin earlier either due to:
The customer is already a registered customer and at the time of registration PIN configuration was not available on the platform.
The customer is not the existing one , he is the new customer but since the AskOnRegistration into the pin configuration is set to be false. Hence the customer has not configured his PIN.
In this case customer core API would not restrict customer profile response in login API, however customer would be prompted to setup the pin at JS end. In this case the account update API would be used to set the pin in the customer profile.
This scenario comes into existence only when the customer has not set up his pin earlier either due to:
The customer is already a registered customer and at the time of registration, PIN configuration was not available on the platform.
The customer is not the existing one, (new customer) but since the AskOnRegistration into the pin configuration is set to be false. Hence the customer has not configured his PIN.
AskOnlyOnFirstLogin will be handled in the same way as of AskOnLogin case with additional condition of the first login customer.
This feature will provide an option for the customer to reset their PIN if they forgot the existing PIN. A customer can reset PIN by using the following methods:
The Security Question workflow allows customers to reset their pin by providing a secret answer to a predefined security question.
This workflow needs to be configured and enabled from your LoginRadius Admin Console.
The customers will then be asked upon registration via the registration form to fill out the questions. Once configured the security questions flow, the same can be used for resetting the configured PIN.
Sample code for Reset PIN By Security Questions:
var resetPINBySecQ_options = {};resetPINBySecQ_options.container = "resetPINBySecQ-container";resetPINBySecQ_options.onSuccess = function(response) { // On Success console.log(response);};resetPINBySecQ_options.onError = function(errors) { // On Errors console.log(errors);}LRObject.util.ready(function() { LRObject.init("resetPINBySecurityQuestion", resetPINBySecQ_options );});
In the MFA required flow, if Duo Authentication is enabled, the JavaScript will display a "Verify identity via Duo Security" button during the MFA login process. The JavaScript will then call the LoginRadius APIs to authenticate the user using the code and state provided by Duo.
In the MFA optional flow, the "Verify identity via Duo Security" button will be available on the profile page. When clicked, the JavaScript will call the LoginRadius APIs to authenticate the user using the code and state returned by Duo.
Two custom APIs have been created in JavaScript to facilitate integration with the Duo authentication process. Below is a demonstration of how these can be implemented:
duoVerify
The duoVerify API accepts duoData, which contains the state and code provided after Duo verification from the DuoAuth endpoint. The following JavaScript code demonstrates how to use this API.
Similar to duoVerify, the duoVerifyByAccessToken API also accepts duoData, including the state and code from the DuoAuth endpoint. The JavaScript implementation is as follows:
Note:
This section covers the Projection of Fields when using the LoginRadius JS Interfaces. If you're looking to configure the Projection of Fields when directly using our APIs, see our Advanced API Usage documentation.
Using the LoginRadius JS Interfaces you're able to limit which primary/root fields you would like to be returned in your API response, For Example, the profile, access_token. This allows you to streamline your process and only get the data that you need as part of your workflow.
The structure is as follows:
Action Name: This is the name of the JavaScript Interface action that is called in your init method that you will be expecting a response from,For Example "login, registration". You can find a list of all possible actions in the actions table of our Getting Started guide.
Field Name: The names of the primary / root fields you would like to be returned in your API response. These fields vary depending on the JavaScript Interface you're targeting. The fields that are not included here will be left out from the API response.
To apply this selection, you need add the projectionFields parameter as part of your options in your Initialization Object.
The projectionFields parameter takes an object with the action names as the key and the field names as values inside an array:
To implement the Progressive Profiling interface, use the LRObject.progressiveProfiling.init method (no action needs to be specified).
You will need to decide when you will want to prompt your customer for additional information/scopes.
Some useful examples as to when you could prompt the customer are:
Upon First Login
At a custom defined Number of Logins
Upon Navigating to a specific property
Clicking a specific link or CTA button
Use the following snippet in your code wherever you have a desired event during which you would like to prompt a progressive profiling step:
var poptions = {};poptions.container = "progressive-container";// If this step will be for Social Data Progressive profilinyou will need to specify a template.// By specifying a template, a Social Login Interface wilautomatically be loaded in the progressive profilincontainer div.poptions.templateName = "loginradiuscustom_tmpl_progressive";///poptions.onSuccess = function(response) { console.log(response);}poptions.onError = function(response) { console.log(response);}LRObject.progressiveProfiling.execStep('Step Name', poptions)LRObject.util.ready(function() { LRObject.progressiveProfiling.init();});
<div id="progressive-container"></div>
Note:
The success callback will return a JSON object {IsPosted: true}.
Note: "Step Name" is the name of progressive profiling steps created via Branding > Forms > Progressive Profiling.. If this step will be for Social Data Progressive Profiling, make sure that you have a template ready for the Social Login Interface that will load the buttons with the scopes you've configured in the Admin Console E.g. :
<script type="text/html" id="loginradiuscustom_tmpl_progressive"><a class="lr-provider-label" href="javascript:void(0)" onclick="return <#=ObjectName #>.util.openWindow('<#=Endpoint #>');" title="<#=Name #>" alt="Sign in with <#=Name #>"> <#=Name #></a></script>
For details on customizing the Social Login Interface Template you can refer to the Social Login section of our Getting Started doc.
Use the following snippet in your code if you would like to show progressive profile fields to customers on the profile page. This will allow the customer to edit the progressive profile fields.
var LRObject = new LoginRadiusV2(commonOptions);LRObject.progressiveProfiling.showInEditor= true;
Idempotent requests are requests which are generated with the same set of inputs and return identical result when called over and over.
LoginRadius prevents such requests from being accidentally executed twice or thrice upon the submit operation of a form (like Registration, Login, Forgot Password, etc). Once a submit operation is performed, it will disable the Submit button until the response (success/error) is not received from the server. Once the response is received from the server, it can be set enabled back.
Following options can be used with commonOptions to enable/disable the Submit Button:
Name
Type
Description
disableButtonOnsubmit
String
If it's true, "Submit Button" will be disabled after the first submit operation. By default, it will remain disabled even after successful API call. Set enableSubmitOnSuccess to true to enable it after the successful API call.
enableSubmitOnSuccess
String
If it's true, the "Submit Button" will be enabled after successful API call.
Configure the feature as follows:
Set the option disableButtonOnsubmit to true to disable the submit button to make the Idempotent requests
commonOptions.disableButtonOnsubmit= true;
By default, the submit button will not be enabled after successful API call on submit button request. However we can configure the button to be enabled after successful API call by setting enableSubmitOnSuccess to true.