0

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?

Igor Shmukler
  • 1,742
  • 3
  • 15
  • 48
  • What's the 500 error? – Adam Jenkins Nov 03 '21 at 00:00
  • 1
    Internal Server Error – Igor Shmukler Nov 03 '21 at 00:11
  • I mean what is the substance of the error - what is the error message? – Adam Jenkins Nov 03 '21 at 09:34
  • The problem is with the auth0 support library not being able to validate the token. – Igor Shmukler Nov 03 '21 at 11:05
  • **What is the error that is being thrown from the library**? You're in a testing environment, just go to your error middleware and `console.log` the error to see what the message is. Once you **post the actual error message**, it will give a clue on where to look next. – Adam Jenkins Nov 03 '21 at 13:07
  • 1
    ```The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received function uploadComplete``` The error actually happens inside `got/source/request-as-event-emitter.js`. – Igor Shmukler Nov 03 '21 at 13:43
  • Cool, so you're using `got` and passing something bad. At this point I'm guessing there's a chancce you're using the token improperly (in a way that works with auth0 but not with createJWKSMock, which is a sign that you've done something that works, but is incorrect). What does your token handling code look like? What `got` call is this coming from (i.e. find the function call in the stack trace that is **your code** and go from there)? – Adam Jenkins Nov 03 '21 at 13:57
  • I am NOT using `got` directly. It is a dependency of `fastify-auth0-verify`. It's an open-source library. – Igor Shmukler Nov 03 '21 at 14:44
  • At this point it sounds like an incompatibility between (your version) of fastify-auth0-verify and createJWKSMock. – Adam Jenkins Nov 03 '21 at 15:12

0 Answers0