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:
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:
| Field | What it seeds |
|---|---|
domain, custom_domains | Where the tenant answers. |
clients | Applications: type, callbacks, logout URLs, grant types, refresh-token rotation. |
apis | APIs by identifier, with scopes, RBAC, permissions in the token and token lifetime. |
roles | Roles and their permissions. |
organizations | Organizations users can belong to. |
users | Users with a password, metadata, roles, organizations, an MFA secret or blocked. |
connections | Social logins on the login page: google-oauth2, github or windowslive. |
post_login_claims, roles_claim | Claims 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:
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
| Area | Covered |
|---|---|
| Universal Login | Log in, sign up, MFA with a one-time code, email verification, social logins. |
| Authentication API | Authorization code with PKCE, refresh, client credentials, password, revoke, user info, logout. |
| OpenID Connect | Discovery, signing keys, and tokens with your claims. |
| Management API v2 | Users, roles and permissions, organizations, blocks, verification emails. |
Faults
| Call | Faults the matrix tries |
|---|---|
POST /oauth/token | 429, 500, 503, a 10-second delay, connection reset, answer lost after Auth0 issued the token, a 403 invalid_grant refresh |
GET /.well-known/jwks.json | 5xx and a connection reset, so you can show your app fails closed |
GET /userinfo | 429, 500, connection reset |
| The Management API | 429 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_claimsfor claims - Passwordless email and SMS
- Enterprise connections (SAML, Active Directory)
- Webhooks: Auth0 sends none, and log streams aren't emulated
Next
GitHub
Sign in with GitHub, GitHub Apps and their installations, the REST API for repositories, issues, pull requests and checks, and signed webhooks.
Clerk
A Clerk development instance on its real hosts, with the Backend API, the Frontend API serving ClerkJS and its sign-in components, the Account Portal, stable ids and Svix-signed webhooks.