Creating JWT for testing API protected with Auth0

960 views Asked by At

I am trying to cover my API, protected by Auth0, with unit tests. Wrote the below:

'use strict';

const createJWKSMock = require('mock-jwks').default;

const startAuthServer = jwksServer => {
  const jwks = createJWKSMock(jwksServer);
  jwks.start();
  return jwks;
};

const getToken = jwks => {
  const token = jwks.token({
    iss: `https://${process.env.AUTH0_DOMAIN}/`,
    sub: 'testprovider|12345678',
    aud: [
      `${process.env.AUTH0_AUDIENCE}`,
      `https://${process.env.AUTH0_DOMAIN}/userinfo`
    ],
    iat: 1635891021,
    exp: 1635977421,
    azp: 'AndI...3oF',
    scope: 'openid profile email'
  });
  return token;
};

const stopAuthServer = jwks => {
  jwks.stop();
};

describe('/promoter/event/:id', () => {
  let server, token, jwks;
  beforeAll(() => {});

  beforeEach(async () => {
    jest.clearAllMocks();

    jwks = startAuthServer(`https://${process.env.AUTH0_DOMAIN}`);
    token = getToken(jwks);

    server = require('../../../');

    await server.ready();
  });

  afterEach(async () => {
    stopAuthServer(jwks);
  });

  it('GET for a non-exising event returns 404', async () => {
    const mockSelect = jest.fn();
    mockSelect
      .mockResolvedValueOnce({
        rowCount: 1,
        rows: [{ row_to_json: { id: 1 } }]
      })
      .mockResolvedValueOnce({
        rowCount: 0,
        rows: []
      });

    server.pg.query = mockSelect;
    // const token = `eyJhb...u5WYA`;

    const response = await server.inject({
      method: 'GET',
      url: '/promoter/event/25',
      headers: { Authorization: `Bearer ${token}` }
    });

    expect(response.statusCode).toEqual(404);
  });
});

If I run the code with a token I generate with getToken the Auth0 plugin does not let the token pass, and I am getting 500.

If I use/uncomment the token returned by Auth0 the tests pass. Hence, it is pretty clear that the problem is the token.

I decoded both tokens - those issued by Auth0 and those made by mock-jwks and the only difference I noticed is the header in the tokens made by mock-jwks is missing typ property.

The ones made by Auth0 look like:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "Mk...OQ"
}

While those produced with mock-jwks look like:

{
  "alg": "RS256",
  "kid": "Mk...OQ"
}

Internally, my server is using fastify-auth0-verify to verify the tokens.

I have also tried mocking the auth server with nock as below:

nock(`https://${process.env.AUTH0_DOMAIN}`)
  .get('/.well-known/jwks.json')
  .reply(200, nockReply);

It is not working either. The call never gets to it, and further, NodeJS prints a warning:

Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

If I disable mock-jwks, Jest/tests exit just fine both with nock and without nock.

Suggestions?

0

There are 0 answers