Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
IlCallo opened this issue May 6, 2021 · 1 comment
Open

Comments

@IlCallo
Copy link

IlCallo commented May 6, 2021

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;
  }
}
@adamjmcgrath
Copy link
Owner

👍 Thanks @IlCallo

@adamjmcgrath adamjmcgrath pinned this issue May 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants