npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@shreyas-kuloor/simulacrum-auth0-simulator

v0.9.3

Published

Run local instance of Auth0 API for local development and integration testing

Downloads

210

Readme

Auth0 simulator

Read about this simulator on our blog: Simplified Local Development and Testing with Auth0 Simulation.

Table of Contents

Please read the main README for more background on simulacrum.

The auth0 simulator has been initially written to mimic the responses of a real auth0 server that is called from auth0 client libraries like auth0/react and auth0-spa-js that use the OpenID authorization code flow.

If this does not meet your needs then please create a github issue to start a conversation about adding new OpenID flows.

Quick Start

This quick start assumes you have your own app with auth0. Check out nextjs with auth0 react and nextjs with nextjs auth0 for more complete examples that provides a barebone application.

Graphql

Let's start our server.

PORT=4000 npx auth0-simulator  # this will start a test simulacrum server at http://localhost:4000

Open a browser at http://localhost:4000.

This will open a graphql graphiql editor.

Enter the following mutation:

mutation CreateSimulation {
 createSimulation(simulator: "auth0",
  options: {
    options:{
      audience: "[your audience]",
      scope: "[your scope]",
      clientID: "[your client-id]"
    },
    services:{
      auth0:{
        port: 4400
      }
    }
  }) {
    id
    status
    services {
      url
      name
    }
  }
}

This mutation creates your first simulation. Every time you start the server, you will need to apply these mutations. This can also be done programmatically which will be your likely interface while writing tests.

create simulation.

Use the values returned from the query to update your configuration in the client application that calls the auth0 endpoints as shown below. This will point your app at the simulation instead of the Auth0 endpoint.

{
  "domain": "localhost:4400",
  "clientID": "00000000000000000000000000000000",
  "audience": "https://your-audience/"
}

Create a fake user whose credentials can be used for authentication with this query.

mutation CreatePerson {
  given(a: "person", simulation: "6fbe024f-2316-4265-a6e8-d65a837e308a")
}

person query

The fake user can now be used on your app. Use the email and password fields as login credentials.

You now have a running auth0 server!

Code

An auth0 simulator can be created using the @simulacrum/client package. This is how you would apply the mutations programmatically.

npm install @simulacrum/client
npm install @simulacrum/auth0-simulator

The following examples are written in Typescript, but using Typescript is not a requirement. The Auth0 simulator creates a server with a graphql interface. This means that your interactions with the server can be written in any language or framework that can communicate over http / graphql.

import { main } from "effection";
import { createSimulationServer, Server } from "@simulacrum/server";
import { auth0 } from "@simulacrum/auth0-simulator";
import { createClient } from "@simulacrum/client";

const port = Number(process.env.PORT) ?? 4000; // port for the main simulation service

// effection is a structured concurrency library and this will help us handle errors and shutting down the server gracefully
main(function* () {
  let server: Server = yield createSimulationServer({
    seed: 1,
    port,
    simulators: { auth0 },
  });

  let url = `http://localhost:${server.address.port}`;

  console.log(`simulation server running at ${url}`);

  let client = createClient(url);

  let simulation = yield client.createSimulation("auth0", {
    options: {
      audience: "[your audience]",
      scope: "[your scope]",
      clientID: "[your client-id]",
    },
    services: {
      auth0: {
        port: 4400, // port for the auth0 service itself
      },
    },
  });

  console.log(`auth0 service running at ${simulation.services[0].url}`);
  let person = yield client.given(simulation, "person");

  console.log(`store populated with user`);
  console.log(
    `username = ${person.data.email} password = ${person.data.password}`
  );

  yield;
});

The client is also expected to be run in many different contexts, and, as such, supports async/await as well.

import { main } from "effection";
import { createSimulationServer } from "@simulacrum/server";
import { auth0 } from "@simulacrum/auth0-simulator";
import { createClient } from "@simulacrum/client";

const port = Number(process.env.PORT) || 4000; // port for the main simulation service

main(function* startServer() {
  // the simulation server needs to run within the scope
  // of an effection context
  let server = yield createSimulationServer({
    port,
    simulators: { auth0 },
  });

  let url = `http://localhost:${server.address.port}`;

  console.log(`simulation server running at ${url}`);

  yield setupClient({ url });
});

// the client is expected to run anywhere and does not expect
// the effection scope, as such, it also can be used with async/await
async function setupClient({ url }) {
  let client = createClient(url);

  let simulation = await client.createSimulation("auth0", {
    options: {
      audience: "https://your-audience/",
      scope: "openid profile email offline_access",
      clientID: "YOUR_AUTH0_CLIENT_ID",
    },
    services: {
      auth0: {
        port: 4400, // port for the auth0 service itself
      },
    },
  });

  console.log(`auth0 service running at ${simulation.services[0].url}`);

  let person = await client.given(simulation, "person");

  console.log(`store populated with user`);
  console.log(
    `username = ${person.data.email} password = ${person.data.password}`
  );
}

Configuration

Both the graphql createSimulation mutation and the @simulacrum/client take an optional options and services object.

// A snippet from the previous `Code` example.
let simulation = yield client.createSimulation("auth0", {
  options: {
    audience: "[your audience]",
    scope: "[your scope]",
    clientID: "[your client-id]",
    rulesDirectory: "test/rules",
  },
  services: {
    auth0: {
      port: 4400,
    },
  },
});

Options

The options field supports the auth0 configuration fields. The option fields should match the fields in the client application that is calling the auth0 server.

The scope also accepts an array of objects containing clientID, scope and optionally audience to enable dynamic scopes from a single simulator. This should allow multiple clients to all use the same simulator. Additionally, setting the clientID: "default" will enable a default fallback scope so every client does not need to be included.

An optional rulesDirectory field can specify a directory of auth0 rules code files, more on this below.

Services

The services object configures simulators to start on specific ports.

let simulation = yield client.createSimulation("auth0", {
  options: {
    services: {
      auth0: {
        port: 4400,
      },
    },
  },
});

Rules

It is possible to run auth0 rules if the compiled code files are on disk and all located in the same directory.

Set the rulesDirectory of the options field to a path relative to your current working directory.

For example, a sample rules directory is in the auth0 package for testing.

If we want to run these rules files then we would add the rulesDirectory field to the options object.

let simulation = yield client.createSimulation(url, {
  options: {
    rulesDirectory: "test/rules",
  },
});

Endpoints

The following endpoints have been assigned handlers:

  • /authorize
  • /login
  • /u/login
  • /usernamepassword/login
  • /login/callback
  • /oauth/token
  • /v2/logout
  • /.well-known/jwks.json
  • /.well-known/openid-configuration