Scripted Decision node
The Scripted Decision node lets you run a server-side script in an authentication journey. It exists to let you connect the script to other nodes with the journey editor.
The script makes a decision to set the outcome for the node.
Compatibility
Product | Compatible? |
---|---|
Advanced Identity Cloud |
Yes |
PingAM (self-managed) |
Yes |
Ping Identity Platform (self-managed) |
Yes |
Inputs
Scripted Decision node inputs depend entirely on the node’s server-side script.
The script has access to the authentication context including:
-
Headers from the request
-
Query string parameters from the request
-
Secrets configured for the realm
-
Shared state data
-
User profile data
The script can use callbacks to prompt the user for information.
For details about the inputs available to the script, refer to Scripted decision node API.
You can restrict available inputs using the Script Inputs field when configuring the node.
Dependencies
A Scripted Decision node depends on a Journey Decision Node script you create before you configure the node.
Configuration
Property | Usage | ||
---|---|---|---|
Script |
Select the script to run from the drop-down list. |
||
Outcomes |
Enter one string for each The node shows only the outcomes you configure.
If you omit an When the script sets an |
||
Script Inputs |
Optionally, list the shared state data properties required by the script. If you change the setting, you must declare each property or Default:
|
||
Script Outputs |
Optionally, list the shared state data properties the node expects the script to set. If you change the setting, you must declare each property or Default: |
Outputs
Scripted Decision node outputs, such as updates to shared state data, depend entirely on the node’s server-side script.
You can restrict available outputs using the Script Outputs field when configuring the node.
Outcomes
The script defines the outcomes by setting its outcome
variable to an outcome string before returning.
You include all possible outcome
strings from the script in the Outcome field when configuring the node.
The authentication journey continues along the outcome path from the script.
Errors
The server-side script can log messages.
The node logs the following warning messages:
Warnings:
-
Found an action result from scripted node, but it was not an Action object
: An action in a legacy script didn’t return an object with typeAction
. -
Found an action result from scripted node, but it was not an ActionWrapper object
: An action in a next generation script didn’t return an object with typeActionWrapper
. -
invalid script outcome <outcome>
: The <outcome> is missing in the Outcome field of the node configuration. -
invalid script outcome <action-outcome> in action
: The <action-outcome> is missing in the Outcome field of the node configuration. -
script outcome error
: The script set an outcome not found in the Outcome field of the node configuration.
Examples
You use a Scripted Decision node when no other available node does what you need.
In this example, the node depends on the following JavaScript Journey Decision Node script. The script gets the user’s names from their profile and stores a message in a shared state property:
-
Next-generation
-
Legacy
// Get the username from shared state data:
var username = nodeState.get('username')
// Get the given name(s) and surname(s) from the user profile:
var profile = idRepository.getIdentity(username)
var givenname = profile.getAttributeValues('givenName')
var surname = profile.getAttributeValues('sn')
if (!(givenname && surname)) {
var error = `Failed to get names for ${username}: ${givenname} ${surname}`
action.goTo('Failure').withErrorMessage(error);
} else {
// Record who authenticated in the shared state data:
var firstGivenName = givenname[0]
var firstSurname = surname[0]
var now = new Date().toLocaleString()
var message = `${firstGivenName} ${firstSurname} logged in at ${now}.`
nodeState.putShared('message', message)
action.goTo('Success');
}
var goTo = org.forgerock.openam.auth.node.api.Action.goTo
// Get the username from shared state data:
var username = nodeState.get('username').asString()
// Get the given name(s) and surname(s) from the user profile:
var profile = idRepository.getIdentity(username)
var givenname = profile.getAttributeValues('givenName')
var surname = profile.getAttributeValues('sn')
if (!(givenname && surname)) {
var error = `Failed to get names for ${username}: ${givenname} ${surname}`
action = goTo('Failure').withErrorMessage(error).build()
} else {
// Record who authenticated in the shared state data:
var firstGivenName = givenname[0]
var firstSurname = surname[0]
var now = new Date().toLocaleString()
var message = `${firstGivenName} ${firstSurname} logged in at ${now}.`
nodeState.putShared('message', message)
action = goTo('Success').build()
}
Notice the script sets the outcomes using the Action.goTo(outcome)
function.
The journey is as follows:
-
The Page node prompts the user for their username and password.
-
The Identity Store Decision node checks the username and password with those in the identity store.
The node configuration enables the optional Username as Universal Identifier setting. As a result, the
nodeState.get('username').asString()
function in the script returns the user’s_id
. Theusername
inidRepository.getIdentity(username)
must be the_id
, not theuserName
, to get the attribute from the user’s profile. -
The Scripted Decision node runs the script and has the following settings:
Script
The name of the script
Outcomes
Success
,Failure
Script Inputs
username
Script Outputs
*
Notice the Outcomes setting lists all outcome strings from the script.
-
The Increment Login Count node updates the count on successful authentication.
-
The Inner Tree Evaluator node refers to another journey to perform more steps.
This node is optional.
If you activate debug mode for the journey and select Enable Debug Popup, you find the message in the debug popup window when authenticating:
{
"universalId": "id=<_id>,ou=user,o=alpha,ou=services,ou=am-config",
"transactionId": "<transaction-id>",
"password": "<password>",
"pageNodeCallbacks": {
"0": 0,
"1": 1
},
"realm": "/alpha",
"message": "Babs Jensen logged in at August 16, 2023 9:55:33 AM UTC.",
"authLevel": 0,
"objectAttributes": {
"password": "<password>"
},
"username": "id=<_id>"
}