Releases
Features and breaking changes released in versions of Triggers in the Login Flow are listed below.
v3
Post-login
Breaking changes
api.redirect.canRedirect()
marked as deprecated.api.redirect.sendUserTo()
will no longer skip redirecting when in a non-interactive flow. This means that calls toapi.redirect.sendUserTo()
should first check if the redirect is needed before issuing the redirect. Information likeevent.authentication.methods
can be consulted to see if a redirect was successfully completed and recorded viaapi.authentication.recordMethod()
. Attempting to trigger a redirect in a non-interactive flow will correctly trigger aninteraction_required
error.
New features
event.authentication.methods
may now also contain custom methods completed by users within that session and recorded usingapi.authentication.recordMethod()
from theonContinuePostLogin
handler.api.authentication.recordMethod()
is added as a way to store a record for the completion of a custom method in the user’s session. These APIs allow you to strictly require custom factors for certain scenarios. The user (on a specific device) will be required to complete the custom factor, regardless of whether or not an interactive login is happening. If the conditions are met for requiring the custom factor and the user’s session doesn’t have a record of its completion, the interactivity of the flow shouldn’t influence whether the factor is required or not. For example, if you wanted to implement a required custom factor, you would set up the following:In
onExecutePostLogin
, search for a record in theevent.authentication.methods
array with the custom method’s identifier URL. If the method is there and has a current enough timestamp, allow the login to continue. Otherwise, trigger a redirect to the URL implementing the custom factor usingapi.redirect.sendUserTo()
. Custom data can be encoded into a JWT and signed usingapi.redirect.encodeToken()
.When the user is redirected to
/continue
, theonContinuePostLogin
handler will be invoked. Within that handler, validate any data coming back from the custom factor (if needed) and signal its completion by callingapi.authentication.recordMethod()
.
v2 (GA)
Post-login
Breaking changes
Perform side effects
In the pre-GA version of the post-login trigger, side effects were performed by returning an object from an Action. In Actions GA, an api
object is provided to encapsulate these changes and provide better in-editor type hints and inline documentation.
Update user user_metadata
Pre-GA Trigger:
async function myFunction(event, context) {
return {
user: {
userMetadata: {
myParam: "foo"
}
}
};
}
Was this helpful?
GA Trigger:
async function onExecutePostLogin(event, api) {
api.user.setUserMetadata('myParam', 'foo');
}
Was this helpful?
Update user app_metadata
Pre-GA Trigger:
async function myFunction(event, context) {
return {
user: {
appMetadata: {
myParam: "foo"
}
}
};
}
Was this helpful?
GA Trigger:
async function onExecutePostLogin(event, api) {
api.user.setAppMetadata('myParam', 'foo');
}
Was this helpful?
Deny a login
Pre-GA Trigger:
async function myFunction(event, context) {
throw new Error("Access denied.");
}
Was this helpful?
GA Trigger:
async function onExecutePostLogin(event, api) {
api.access.deny("Access denied.");
}
Was this helpful?
Add Custom Claims to the Access Token
Pre-GA Trigger:
async function myFunc(event, context) {
return {
accessToken: {
customClaims: {
'https://example.com/custom/claim': 'Custom claim value',
}
}
};
}
Was this helpful?
async function myFunc(event, api) {
api.accessToken.setCustomClaim('https://example.com/custom/claim', 'Custom claim value');
}
Was this helpful?
Add Custom Claims to the ID Token
Pre-GA Trigger:
async function myFunc(event, context) {
return {
idToken: {
customClaims: {
'https://example.com/custom/claim': 'Custom claim value',
}
}
};
}
Was this helpful?
GA Trigger:
async function myFunc(event, api) {
api.idToken.setCustomClaim('https://example.com/custom/claim', 'Custom claim value');
}
Was this helpful?
Dynamically enable multi-factor authentication
Pre-GA Trigger:
async function myFunction(event, context) {
return {
command: {
type: "multifactor",
provider: "any"
}
};
}
Was this helpful?
GA Trigger:
async function onExecutePostLogin(event, api) {
api.multifactor.enable("duo");
}
Was this helpful?
Redirect the user
Pre-GA Trigger:
async function myFunction(event, context) {
return {
command: {
type: "redirect",
url: "https://my-app.example.com"
}
};
}
Was this helpful?
GA Trigger:
async function onExecutePostLogin(event, api) {
api.redirect.sendUserTo("https://my-app.example.com");
}
Was this helpful?
To ensure parameters are being sent securely and to avoid replay attacks, passing data via redirects has changed significantly in Actions GA. For more information, see Redirect with Actions.
Manipulate scopes
Although we experimented with providing direct manipulation of ID and Access Token scopes during the Actions Beta, we do not support this functionality in Actions GA.