Coder Social home page Coder Social logo

cypress-spa-example's People

Contributors

adamjmcgrath avatar rico-ci avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

cypress-spa-example's Issues

Example for auth0-react

I was following along with this bug ticket because we're in a near identical situation and tried implementing the solutions you have here but we couldn't get the isAuthenticated to ever return True.
The only difference that I can tell is that we use the Auth0-React package instead of the SPA one.

With that said do they both work in the same way now, by storing tokens in session storage?
and would you know of anything to change from the sample code you have here to support the Auth0-react package?

Updated version using underlying SPA SDK with Cypress 6+, TS and Vue

For anyone coming here, here's an updated version which uses SPA SDK itself to perform the flow.
A static config file is assumed, but can be adapted to use env variables.

Care as it uses deep import to get many types which aren't exposed.

Head here it you want the TS + Vue3 compatible version of Auth0 wrapper for Vue.

// main.ts

import { Auth0Instance, initAuth0 } from 'src/composables/auth0/instance';
import { audience, client_id, domain } from '../../auth0.config.json';

declare module 'vue/types/vue' {
  interface Vue {
    $auth: Auth0Instance;
  }
}

declare global {
  interface Window {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    Cypress?: any;
    Auth0?: Auth0Instance;
  }
}

const auth0Instance = initAuth0({
    client_id,
    domain,
    audience,
    onRedirectCallback: appState =>
      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
      router.push(appState?.targetUrl ?? window.location.pathname),
    cacheLocation: window.Cypress ? 'localstorage' : 'memory'
});

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
Vue.prototype.$auth = auth0Instance;

// When executing into Cypress, expose Auth0 instance
if (window.Cypress) {
  window.Auth0 = auth0Instance;
}
// cypress/support/auth0-helpers.ts

import { TokenEndpointResponse as Auth0TokenEndpointResponse } from '@auth0/auth0-spa-js/dist/typings/api';
import { ICache } from '@auth0/auth0-spa-js/dist/typings/cache';
import type { verify } from '@auth0/auth0-spa-js/dist/typings/jwt';
import { Ref } from '@vue/composition-api';
import { Auth0Instance } from 'src/composables/auth0/instance';

// These methods are private, we are forced to use them to comply to SPA SDK flow
interface Auth0ClientPrivateMethods {
  _verifyIdToken(id_token: string): ReturnType<typeof verify>;
  cache: ICache;
}

export interface TokenEndpointResponse extends Auth0TokenEndpointResponse {
  token_type: string;
}

export const useAuth0 = () =>
  cy.window().its('Auth0') as Cypress.Chainable<
    Auth0Instance & { auth0Client: Ref<Auth0ClientPrivateMethods> }
  >;
// cypress/support/commands.ts

import {
  audience,
  client_id,
  client_secret,
  domain,
  password,
  scope,
  username
} from 'auth0.config.json';
import { TokenEndpointResponse, useAuth0 } from './auth0-helpers';

Cypress.Commands.add('login', () => {
  cy.request({
    method: 'POST',
    url: `https://${domain}/oauth/token`,
    body: {
      grant_type: 'password',
      username,
      password,
      audience,
      scope,
      client_id,
      client_secret
    }
  }).then(({ body }) => {
    const { id_token, ...otherFields } = body as TokenEndpointResponse;

    useAuth0().then(auth0 => {
      const auth0Client = auth0.auth0Client.value;

      const decodedToken = auth0Client._verifyIdToken(id_token);

      const cacheEntry = {
        ...otherFields,
        scope,
        client_id,
        id_token,
        audience,
        decodedToken
      };

      auth0Client.cache.save(cacheEntry);
    });
  });
});
// cypress/support/types.d.ts

// Must be put in its own file because ES6 imports into 'commands.ts' prevents TS from discovering the augmentation
// eslint-disable-next-line @typescript-eslint/no-namespace, @typescript-eslint/no-unused-vars
declare namespace Cypress {
  interface Chainable {
    /**
     * Custom command to login using Auth0 provider.
     * @example cy.login()
     */
    login(): void;
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.