Skip to content
  • Workflows
  • Workflow tutorials

Block disposable emails with Kinde workflows

The workflow runs on the user:pre_registration trigger and checks the sign-up email against your own list.

  • A Kinde account (Sign up for free)
  • A workflow Git repository connected to your Kinde account (follow the quick start guide)
  • Your own list of prohibited email domains

Block disposable emails

Link to this section

Set up the environment variable

Link to this section
  1. Create a new environment variable in Settings > Data management > Env variables called DISPOSABLE_EMAIL_DOMAINS.
  2. Use a comma-separated list, for example yopmail.com,guerrillamail.com,mailinator.com.

Workflow logic

Link to this section
  1. Read the email from the pre-registration event:

    event.context.user.email
  2. Read your domain list from your environment variable (e.g., DISPOSABLE_EMAIL_DOMAINS):

    const disposableEmailDomains = getEnvironmentVariable(
    "DISPOSABLE_EMAIL_DOMAINS"
    )?.value
  3. Display a message on the Kinde form when registration is blocked using the denyAccess built-in function:

    denyAccess("Disposable email domain detected")

Full Workflow.ts file example

Link to this section
import {
onUserPreRegistrationEvent,
WorkflowSettings,
WorkflowTrigger,
denyAccess,
getEnvironmentVariable,
} from "@kinde/infrastructure";
// The settings for this workflow
export const workflowSettings: WorkflowSettings = {
id: "preRegistration",
name: "Block disposable emails",
failurePolicy: {
action: "stop",
},
trigger: "user:pre_registration",
bindings: {
"kinde.env": {},
"kinde.auth": {},
},
};
// The workflow code to be executed when the event is triggered
export default async function Workflow(
event: onUserPreRegistrationEvent
) {
console.log("handlePreRegistration");
// Check if user email exists in the event
if (!event.context.user?.email) {
console.log(
"No user email found in pre-registration event, allowing registration"
);
return;
}
const disposableEmailDomains = getEnvironmentVariable(
"DISPOSABLE_EMAIL_DOMAINS"
)?.value;
// If no disposable email domains are configured, allow registration
if (!disposableEmailDomains) {
console.log(
"No disposable email domains configured, allowing registration"
);
return;
}
const disposableEmailDomainsArray = disposableEmailDomains
.split(",")
.map((domain) => domain.trim().toLowerCase());
const userEmailDomain = event.context.user.email.split("@")[1]?.toLowerCase();
if (userEmailDomain && disposableEmailDomainsArray.includes(userEmailDomain)) {
console.log(
`Blocking registration for disposable email domain: ${userEmailDomain}`
);
denyAccess("Disposable email domain detected");
} else {
console.log(`Allowing registration for email domain: ${userEmailDomain}`);
}
}

The workflow checks the sign-up email against the domains in DISPOSABLE_EMAIL_DOMAINS:

  • If the event has no user or email, registration continues.
  • If the environment variable is not set, registration continues.
  • If the domain matches a listed domain, denyAccess stops registration and the user sees Disposable email domain detected.
  • Domains are compared in lowercase, so a configured domain matches the sign-up domain regardless of casing.

Required bindings

Link to this section
  • kinde.env: required to read the environment variable
  • kinde.auth: required for denyAccess on the pre-registration trigger

Test the workflow

Link to this section
  1. Attempt to sign up with an email address whose domain is in DISPOSABLE_EMAIL_DOMAINS. Registration will be blocked and the user sees Disposable email domain detected.
  2. Attempt to sign up with an email address whose domain is not in the list. Registration will continue.