diff --git a/main/config/navigation/authenticate.json b/main/config/navigation/authenticate.json index f2cb9b6532..50f1fa62b6 100644 --- a/main/config/navigation/authenticate.json +++ b/main/config/navigation/authenticate.json @@ -161,7 +161,7 @@ "docs/authenticate/passwordless/passwordless-with-universal-login", "docs/authenticate/passwordless/passwordless-connection-limitations", "docs/authenticate/passwordless/best-practices", - "docs/authenticate/passwordless/sample-use-cases-rules" + "docs/authenticate/passwordless/sample-use-cases-actions" ] }, { diff --git a/main/config/redirects.json b/main/config/redirects.json index 998e6d1e5a..9d0a082282 100644 --- a/main/config/redirects.json +++ b/main/config/redirects.json @@ -15429,11 +15429,15 @@ }, { "source": "/docs/connections/passwordless/sample-use-cases-rules", - "destination": "/docs/authenticate/passwordless/sample-use-cases-rules" + "destination": "/docs/authenticate/passwordless/sample-use-cases-actions" }, { "source": "/docs/connections/passwordless/concepts/sample-use-cases-rules", - "destination": "/docs/authenticate/passwordless/sample-use-cases-rules" + "destination": "/docs/authenticate/passwordless/sample-use-cases-actions" + }, + { + "source": "/docs/authenticate/passwordless/sample-use-cases-rules", + "destination": "/docs/authenticate/passwordless/sample-use-cases-actions" }, { "source": "/docs/connections/social/line", diff --git a/main/docs/authenticate/passwordless/sample-use-cases-actions.mdx b/main/docs/authenticate/passwordless/sample-use-cases-actions.mdx new file mode 100644 index 0000000000..3a8588d700 --- /dev/null +++ b/main/docs/authenticate/passwordless/sample-use-cases-actions.mdx @@ -0,0 +1,91 @@ +--- +title: "Sample Use Cases: Actions with Passwordless Authentication" +description: Learn how to use Actions to customize passwordless authentication flows, including routing SMS and email OTPs through custom providers. +validatedOn: 2026-06-26 +--- + +With [Actions](/docs/customize/actions/actions-overview), you can extend [passwordless connections](/docs/authenticate/passwordless) by routing SMS and email OTP delivery through custom providers. Auth0 Actions give you control over which phone and email services handle your authentication messages. + +## Send passwordless email with a custom email provider + +When a user [authenticates through a passwordless email connection](/docs/authenticate/passwordless/authentication-methods/email-otp), Auth0 triggers the `custom-email-provider` Action to deliver the OTP. Use this Action to route messages through any email service. + +To configure the Action, navigate to [**Branding > Email Provider**](https://manage.auth0.com/#/templates/provider) and select the **Custom Provider** option. To learn more, read [Configure an Email Provider with a Customized Action](/docs/customize/email/smtp-email-providers/custom/configure-action). + +```javascript lines +/** + * Handler called when Auth0 needs to deliver a passwordless email OTP. + * @param {Event} event - Details about the notification. + * @param {CustomEmailProviderAPI} api - Methods for controlling notification behavior. + */ +exports.onExecuteCustomEmailProvider = async (event, api) => { + try { + const response = await fetch('https://api.example.com/send-email', { + method: 'POST', + headers: { + 'Authorization': `Bearer ${event.secrets.API_KEY}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + to: event.notification.to, + from: event.notification.from, + subject: event.notification.subject, + html: event.notification.html, + text: event.notification.text, + }), + }); + + if (response.status >= 500) { + api.notification.retry(`Server error from email provider: ${response.status}`); + return; + } + } catch (error) { + api.notification.drop(`Unexpected error: ${error.message}`); + } +}; +``` + +To learn more about available event properties, read [Actions Triggers: custom-email-provider - Event Object](/docs/customize/email/smtp-email-providers/custom/action-triggers-custom-email-provider-event-object). + +## Send passwordless SMS with a custom phone provider + +When a user [authenticates through a passwordless SMS connection](/docs/authenticate/passwordless/authentication-methods/sms-otp), Auth0 triggers the `custom-phone-provider` Action to deliver the OTP. Use this Action to route messages through any SMS provider. + +To configure the Action, navigate to [**Branding > Phone Provider**](https://manage.auth0.com/dashboard/#/phone/templates/phone/provider) and select the **Custom** option. To learn more, read [Configure a Custom Phone Provider](/docs/customize/phone-messages/configure-phone-messaging-providers/configure-a-custom-phone-provider). + +```javascript lines +/** + * Handler called when Auth0 needs to deliver a passwordless SMS OTP. + * @param {Event} event - Details about the notification. + * @param {CustomPhoneProviderAPI} api - Methods for controlling notification behavior. + */ +exports.onExecuteCustomPhoneProvider = async (event, api) => { + const response = await fetch('https://api.example.com/messages', { + method: 'POST', + headers: { + 'Authorization': `Bearer ${event.secrets.API_KEY}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + to: event.notification.recipient, + from: event.notification.from, + body: event.notification.as_text, + }), + }); + + if (!response.ok) { + api.notification.retry(`Failed to send SMS: ${response.status}`); + } +}; +``` + +To learn more about available event properties, read [Actions Triggers: custom-phone-provider - Event Object](/docs/customize/phone-messages/configure-phone-messaging-providers/configure-a-custom-phone-provider/actions-triggers-custom-phone-provider-event-object). + +## Learn more + +* [Configure an Email Provider with a Customized Action](/docs/customize/email/smtp-email-providers/custom/configure-action) +* [Configure a Custom Phone Provider](/docs/customize/phone-messages/configure-phone-messaging-providers/configure-a-custom-phone-provider) +* [Configure a Custom Phone Provider with Twilio Verify](/docs/customize/phone-messages/configure-phone-messaging-providers/configure-a-custom-phone-provider/configure-a-custom-phone-provider-with-twilio-verify) +* [Set Up Custom SMS Gateway for Passwordless Connections](/docs/authenticate/passwordless/authentication-methods/use-sms-gateway-passwordless) +* [Use the Unified Phone Experience for Passwordless](/docs/customize/phone-messages/unified-phone/unified-phone-experience-passwordless) +* [Passwordless Connections Best Practices](/docs/authenticate/passwordless/best-practices) diff --git a/main/docs/authenticate/passwordless/sample-use-cases-rules.mdx b/main/docs/authenticate/passwordless/sample-use-cases-rules.mdx deleted file mode 100644 index 5e74303ac2..0000000000 --- a/main/docs/authenticate/passwordless/sample-use-cases-rules.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -description: Explore Auth0 Rules use cases for passwordless connections, from enforcing MFA on first sign-in to enriching user profiles with external API data. -title: Sample Use Cases - Rules with Passwordless Authentication ---- - - -The End of Life (EOL) date of Rules and Hooks will be **November 18, 2026**, and they are no longer available to new tenants created as of **October 16, 2023**. Existing tenants with active Hooks will retain Hooks product access through end of life. - -We highly recommend that you use Actions to extend Auth0. With Actions, you have access to rich type information, inline documentation, and public `npm` packages, and can connect external integrations that enhance your overall extensibility experience. To learn more about what Actions offer, read [Understand How Auth0 Actions Work](/docs/customize/actions/actions-overview). - -To help with your migration, we offer guides that will help you [migrate from Rules to Actions](/docs/customize/actions/migrate/migrate-from-rules-to-actions) and [migrate from Hooks to Actions](/docs/customize/actions/migrate/migrate-from-hooks-to-actions). We also have a dedicated [Move to Actions](https://auth0.com/extensibility/movetoactions) page that highlights feature comparisons, [an Actions demo](https://www.youtube.com/watch?v=UesFSY1klrI), and other resources to help you on your migration journey. - -To read more about the Rules and Hooks deprecation, read our blog post: [Preparing for Rules and Hooks End of Life](https://auth0.com/blog/preparing-for-rules-and-hooks-end-of-life/). - - - -With [rules](/docs/customize/rules), you can handle more complicated cases than is possible with [passwordless connections](/docs/authenticate/passwordless) alone. For instance, you can add extra precautions to further ensure possession of an email address or device. - -## Require Multi-factor Authentication for users who are outside the corporate network - -Let's say you want to require [multi-factor authentication (MFA)](/docs/secure/multi-factor-authentication) for any users who are accessing the application using a passwordless connection from outside your corporate network. - -Using a rule, you can check whether a user is authenticating using a passwordless method (`sms`, `email`) and if their session IP falls outside of the designated corporate network, prompt them for a second authentication factor. - - - -You could also trigger this rule based on other criteria, such as whether the current IP matches the user's IP allowlist or whether geolocating the user reveals they are in a different country from the one listed in their user profile. - - - -To do this, you would [create the following rule](/docs/customize/rules/create-rules): - -```javascript lines -function(user, context, callback) { - const ipaddr = require('ipaddr.js'); - const corp_network = "192.168.1.134/26"; - const current_ip = ipaddr.parse(context.request.ip); - // is auth method passwordless and IP outside corp network? - const passwordlessOutside = context.authentication.methods.find( - (method) => ( - ((method.name === 'sms') || (method.name === 'email')) && - (!current_ip.match(ipaddr.parseCIDR(corp_network))) - ) - ); - - // if yes, then require MFA - if (passwordlessOutside) { - context.multifactor = { - provider: 'any', - allowRememberBrowser: false - }; - } - callback(null, user, context); -} -``` - - -