0

and thanks for the tool .

I'm working on a Nestjs (v8.x) application relying on Passport.js with a JWT strategy through HttpOnly cookies. For testing the different endpoints of my app, I'm using supertest (v6.1.x).

In order to reach certain endpoints, I need to get an authentication cookie set after submitting credentials. When playing with the UI, everything is working correctly and I can get the data I want. However, when trying to create an automated test based on that, it does not work (at all).

My tests looks like following:

it('gives the current user when the token is valid', async () => {
      const cookieToken = await authenticate(app);

      const { body: user } = await request(app.getHttpServer())
        .get('/users/me')
        .set('Cookie', cookieToken);

      expect(user.email).toEqual('joe.doe@gmail.com');
      expect(user.fullname).toEqual('Joe Doe');
      expect(user.uuid).toBeTruthy();
      expect(user.password).toBeFalsy();
    });

The authenticate function is a helper that looks like:

export const authenticate = async (
  app: INestApplication,
  username = 'joe.doe@gmail.com',
  password = 'password',
) => {
  const res = await request(app.getHttpServer()).post('/auth/login').send({
    username,
    password,
  });

  // This cookie resolves correctly
  const cookieWithToken = res.headers['set-cookie'];

  return cookieWithToken;
};

This tests fails and I got a 401 response from my JWT strategy. The code for this strategy looks like:

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromExtractors([
        (request: Request) => {
          let data = request?.cookies?.['auth-cookie'];

          // In the test scenario, request.cookies is always undefined
          if (!data) {
            throw new UnauthorizedException();
          }

          return data.access_token;
        },
      ]),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload: any) {
    // Not important for this issue
  }
}

During the test run, request?.cookies is undefined and never set, thus throws the 401 error to the caller.


I don't know what is going but it looks like something is wrong on the way I set it.

I've tried the following approaches:

  • Adding withCredentials (cuz, who knows...)
  • Nesting the second call inside the callback resolving the login call in case there's a shared context between the requests
  • Relying on the same agent to make both the calls instead of directly calling superagent

But still, without success :(

Do you have any ideas?

mfrachet
  • 8,772
  • 17
  • 55
  • 110

0 Answers0