dánwòdánwò

Identity

Auth0

Auth0's Universal Login with sign-up, MFA and social connections, the authentication API's grants, and the Management API v2, on your tenant's own domain.

danwo's Auth0 emulator answers your tenant's own domain. The browser logs in, signs up and passes MFA on Universal Login. Your server uses the authentication API and the Management API, through Auth0's SDKs or plain OpenID Connect.

Set up

Add auth0Service with a tenant, your application and a user:

danwo.config.ts
import { appEnvironment, auth0Service, defineConfig } from "@danwo/sdk"

const url = "http://localhost:3000"
const domain = "my-app.us.auth0.com"
const client = { client_id: "danwo-client", client_secret: "danwo-client-secret" }

export default defineConfig({
  testDir: "tests",
  environment: () =>
    appEnvironment({
      app: {
        command: "npm run dev",
        url,
        env: {
          AUTH0_DOMAIN: domain,
          AUTH0_CLIENT_ID: client.client_id,
          AUTH0_CLIENT_SECRET: client.client_secret,
        },
      },
      services: [
        auth0Service({
          seed: {
            tenants: [
              {
                domain,
                clients: [
                  {
                    ...client,
                    name: "My app",
                    app_type: "regular_web",
                    callbacks: [`${url}/auth/callback`],
                    allowed_logout_urls: [url],
                  },
                ],
                users: [{ email: "[email protected]", password: "correct-horse-battery" }],
              },
            ],
          },
        }),
      ],
    }),
})

Seed it

Each tenant takes:

FieldWhat it seeds
domain, custom_domainsWhere the tenant answers.
clientsApplications: type, callbacks, logout URLs, grant types, refresh-token rotation.
apisAPIs by identifier, with scopes, RBAC, permissions in the token and token lifetime.
rolesRoles and their permissions.
organizationsOrganizations users can belong to.
usersUsers with a password, metadata, roles, organizations, an MFA secret or blocked.
connectionsSocial logins on the login page: google-oauth2, github or windowslive.
post_login_claims, roles_claimClaims added to tokens, as an Action would add them.

Use it in a test

Log in on Universal Login, then check the tenant recorded it:

tests/login.danwo.ts
import { type Auth0Fixtures, auth0Tenant, test as base } from "@danwo/sdk"

const test = base.extend<Auth0Fixtures>()

test("logs in with a password", async ({ app, screen, expect, auth0 }) => {
  await app.open("/")
  await screen.getByRole("link", { name: "Log in" }).click()
  await screen.getByLabel("Email address").fill("[email protected]")
  await screen.getByLabel("Password").fill("correct-horse-battery")
  await screen.getByRole("button", { name: "Continue" }).click()

  await expect(screen.getByText("Signed in as [email protected]")).toBeVisible()

  const [login] = auth0Tenant(auth0).logins("[email protected]")

  expect(login?.mfa).toBe(false)
})
auth0Tenant(auth0)What it's for
users(), user(email)The tenant's users.
logins(email)Each login, with its method and whether MFA was passed.
liveRefreshTokens()How many refresh tokens still work.
emails(to)The verification emails the tenant sent.
block(email)Block a user mid-test.

For a user seeded with an mfa_secret, type auth0OtpAt(secret, new Date()) into "Enter your one-time code".

What's covered

AreaCovered
Universal LoginLog in, sign up, MFA with a one-time code, email verification, social logins.
Authentication APIAuthorization code with PKCE, refresh, client credentials, password, revoke, user info, logout.
OpenID ConnectDiscovery, signing keys, and tokens with your claims.
Management API v2Users, roles and permissions, organizations, blocks, verification emails.

Faults

CallFaults the matrix tries
POST /oauth/token429, 500, 503, a 10-second delay, connection reset, answer lost after Auth0 issued the token, a 403 invalid_grant refresh
GET /.well-known/jwks.json5xx and a connection reset, so you can show your app fails closed
GET /userinfo429, 500, connection reset
The Management API429 with x-ratelimit-reset, 5xx, a delay, connection reset, and an answer lost after a write

The Universal Login pages themselves are left alone, so the browser always reaches them.

Fidelity

Not checked live yet. There's no Auth0 suite; the emulator follows Auth0's documented answers.

Not covered yet

  • Actions, Rules and Hooks: use post_login_claims for claims
  • Passwordless email and SMS
  • Enterprise connections (SAML, Active Directory)
  • Webhooks: Auth0 sends none, and log streams aren't emulated

Next

On this page

Run it on every pull request

A GitHub check and one comment per pull request, with the flight records attached.

Set up CI