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 to api.redirect.sendUserTo() should first check if the redirect is needed before issuing the redirect. Information like event.authentication.methods can be consulted to see if a redirect was successfully completed and recorded via api.authentication.recordMethod(). Attempting to trigger a redirect in a non-interactive flow will correctly trigger an interaction_required error.

New features

  • event.authentication.methods may now also contain custom methods completed by users within that session and recorded using api.authentication.recordMethod() from the onContinuePostLogin 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:

    1. In onExecutePostLogin, search for a record in the event.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 using api.redirect.sendUserTo(). Custom data can be encoded into a JWT and signed using api.redirect.encodeToken().

    2. When the user is redirected to /continue, the onContinuePostLogin handler will be invoked. Within that handler, validate any data coming back from the custom factor (if needed) and signal its completion by calling api.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?

/
GA Trigger:

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.