Actions Transaction Metadata

Actions Transaction Metadata stores, accesses, and/or shares, custom metadata within a post-login Action for the duration of a transaction.

Previously, each Action operated independently, making it difficult to pass information between them. With Actions Transaction Metadata, now it's possible to:

  • Share data across Actions, such as API responses or intermediate calculations.

  • Eliminate the need to re-fetch or re-calculate the same information in different Actions.

How it works

Use the post-login API object api.transaction.setMetadata to set the key/value pair in order to store transaction metadata.

Use the post-login Event object event.transaction.metadata to access stored key/value pair in the same Action or subsequent Actions on the post-login trigger for a single execution.

The API and Event objects accept the following parameters:

Value Type Description
Key String The key of the metadata property to be set.
Value String, Number, Boolean The value of the metadata property.
Set to null removes the property.

To learn more about writing Actions, read Write Your First Action.

Latency

Using Actions Transaction Metadata could cause a nominal additional latency. Any latency would be proportional to the metadata payload size and would be relevant when Action suspensions happen. For example, triggering MFA, redirecting from Actions, or rendering Forms, could cause latency issues due to the need of reloading data from storage.

Still, the potential latency should be minimal than the redundant outgoing HTTP requests to retrieve data the sequence of Actions needs.

Examples

Access metadata immediately

Set key/value pairs in transaction metadata and access values immediately.

exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('hello', 'Auth0');

  console.log('Hello ', event.transaction?.metadata?.hello);
  /* Outputs "Hello Auth0" */
};

Was this helpful?

/

Set supported values

Set values of types: string, number, and boolean.

exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('string_value', 'Auth0');
  api.transaction.setMetadata('boolean_value', true);
  api.transaction.setMetadata('number_value', 12);

  console.log('string_value', event.transaction?.metadata?.string_value);
  /* Outputs "string_value Auth0" */
  console.log('boolean_value', event.transaction?.metadata?.boolean_value);
  /* Outputs "boolean_value true" */
  console.log('number_value', event.transaction?.metadata?.number_value);
  /* Outputs "number_value 12" */
};

Was this helpful?

/

Serialize values

Serialize values as strings within limits.

exports.onExecutePostLogin = async (event, api) => {
  const serialized_object_value = JSON.stringify({
    string_value: 'Auth0',
    boolean_value: true,
    number_value: 12
  });

  api.transaction.setMetadata('serialized_object_value', serialized_object_value);

  const serialized_array_value = JSON.stringify([
    'Auth0',
    true,
    12
  ]);
  api.transaction.setMetadata('serialized_array_value', serialized_array_value);

  console.log('serialized_object_value',
    JSON.parse(event.transaction?.metadata?.serialized_object_value)
  );
  /* Outputs "serialized_object_value { string_value: 'Auth0', boolean_value: true, number_value: 12 }" */

  console.log('serialized_array_value',
    JSON.parse(event.transaction?.metadata?.serialized_array_value)
  );
  /* Outputs "serialized_array_value [ 'Auth0', true, 12 ]" */
};

Was this helpful?

/

Share values between Actions

Share key/value pairs between Actions in the same execution sequence.

Action 1

Set hello key with Auth0 value with the api object setMetadata method.

exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('hello', 'Auth0');
};

Was this helpful?

/

Action 2

Log the Auth0 value for hello key in the transaction metadata with the event object transaction.metadata property to access the set values.

exports.onExecutePostLogin = async (event, api) => {
  console.log('Hello', event.transaction?.metadata?.hello);
  /* Outputs "Hello Auth0" */
};

Was this helpful?

/

Update metadata

Set an existing key with a different value to update metadata.

Action 1

Set transaction metadata key/value pair as custom_tx_id and xyz123.

exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('custom_tx_id', 'xyz123');
};

Was this helpful?

/

Action 2

Log the key as custom_tx_id and the value as xyz123. Then, set custom_tx_id to abc456 to log again with the latest value for custom_tx_id in the transaction metadata.

exports.onExecutePostLogin = async (event, api) => {
  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id xyz123" */

  api.transaction.setMetadata('custom_tx_id', 'abc456');

  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id abc456" */
};

Was this helpful?

/

Action 3

Log the abc456 value for custom_tx_id.

exports.onExecutePostLogin = async (event, api) => {
  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id abc456" */
};

Was this helpful?

/

Remove metadata

Remove transaction metadata values by nullifying the value of each particular key.

Action 1

Set custom_tx_id in the transaction metadata.

exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('custom_tx_id', 'xyz123');
};

Was this helpful?

/

Action 2

Set custom_tx_id to null and log the null value for custom_tx_id.

exports.onExecutePostLogin = async (event, api) => {
  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id xyz123" */

  api.transaction.setMetadata('custom_tx_id', null);

  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id undefined" */
};

Was this helpful?

/

Action 3

Logs the null value for custom_tx_id.

exports.onExecutePostLogin = async (event, api) => {
  console.log('custom_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id undefined" */
};

Was this helpful?

/

Preserve values on redirect to external sites

Preserve transaction metadata during redirects. Values are available when users continue the authentication flow.

Action 1

Sets a custom_tx_id in the transaction metadata.

exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('custom_tx_id', 'xyz123');
};

Was this helpful?

/

Action 2

Redirects to an external site sending a token with the custom_tx_id from the transaction metadata. Then it compares the custom_tx_id value at the transaction metadata with the one passed to the external site that has been sent back in the payload of another token.

exports.onExecutePostLogin = async (event, api) => {
  const token = api.redirect.encodeToken({
    secret: event.secrets.REDIRECT_SECRET,
    expiresInSeconds: 60, 
    payload: {
      custom_tx_id: event.transaction?.metadata?.custom_tx_id,
      continue_uri: `https://${event.secrets.TENANT_DOMAIN}/continue`
    },
  });

  api.redirect.sendUserTo(event.secrets.REDIRECT_URL, {
    query: { session_token: token }
  });
};

exports.onContinuePostLogin = async (event, api) => {
  const payload = api.redirect.validateToken({
    secret: event.secrets.REDIRECT_SECRET
  });

  console.log('Does custon_tx_id match?',
    payload?.custom_tx_id === event.transaction?.metadata?.custom_tx_id
  );
  /* Outputs "Does custon_tx_id match? True" */
};

Was this helpful?

/

Preserve values on Forms rendering

Render Forms using Actions and transaction metadata values would be preserved and available when users continue the authentication flow.

To learn more about using Forms with Actions, read Render Forms using Actions.

Action 1

Sets a custom_tx_id in the transaction metadata.

exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('custom_tx_id', 'xyz123');
};

Was this helpful?

/

Action 2

Renders a Form. Then it logs the preserved custom_tx_id when continuing the Actions execution.

exports.onExecutePostLogin = async (event, api) => {
  api.prompt.render(event.secrets.FORM_ID);
};

exports.onContinuePostLogin = async (event, api) => {
  console.log('custon_tx_id', event.transaction?.metadata?.custom_tx_id);
  /* Outputs "custom_tx_id xyz123" */
};

Was this helpful?

/

Share values with Forms

You can render Forms using Actions and pass transaction metadata values to the Form.

Action 1

Sets a custom_tx_id in the transaction metadata.

exports.onExecutePostLogin = async (event, api) => {
  api.transaction.setMetadata('custom_tx_id', 'xyz123');
};

Was this helpful?

/

Action 2

Renders a Form passing the custom_tx_id from the transaction metadata as vars parameter. Then it compares the custom_tx_id value at the transaction metadata with the one passed to the Form, when continuing the Actions execution.

exports.onExecutePostLogin = async (event, api) => {
  api.prompt.render(event.secrets.FORM_ID, {
    vars: {
      custom_tx_id: event.transaction?.metadata?.custom_tx_id
    }
  });
};

exports.onContinuePostLogin = async (event, api) => {
  console.log('Does custon_tx_id match?',
    event.prompt?.vars?.custom_tx_id === event.transaction?.metadata?.custom_tx_id
  );
  /* Outputs "Does custon_tx_id match? True" */
};

Was this helpful?

/