fastify-passport: Request user is null when reading from within Mercurius

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

3.20.2

Plugin version

0.4.3

Node.js version

14.16.0

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

10.15.7

Description

I’ve been trying to integrate Mercurius with my Rest API backend. I have it working without auth, and I really would like to be able to read the request.user field from the Mercurius context. I don’t understand why the value is always null.

instance.register(passportSetup);
instance.register(
  Mercurius,
  {
    schema,
    graphiql: true,
    async context(request) {
      return {
        user: request.user, // always null
        origin: getRequestOrigin(request)
      };
    }
  }
);
export const passportSetup = fp(async (instance) => {
  instance.register(fastifySecureSession, {
    key: Buffer.from(COOKIE_SECRET, 'hex'),
    cookieName: 'session',
    cookie: {
      maxAge: 24 * 60 * 60 * 1000 * 30,
      // Do not change the lines below, they make cy.auth() work in e2e tests
      secure: process.env.NODE_ENV !== 'development' && !process.env.INSECURE_AUTH,
      signed: process.env.NODE_ENV !== 'development' && !process.env.INSECURE_AUTH,
    },
  });
  instance.register(passport.initialize());
  instance.register(passport.secureSession());

  passport.registerUserSerializer(async (passportUser: { email: string, redirect: string }) => {
    const { email, redirect } = passportUser;
    await instance
      .db('users')
      .insert({
        email,
        confirmed_at: new Date(),
      })
      .onConflict('email')
      .ignore();

    const [user] = await instance
      .db<{ id: string, email: string }>('users')
      .where('email', email)
      .select('id');

    return { userId: user.id, redirect };
  });

  passport.registerUserDeserializer(async ({ userId, redirect }: { userId: string, redirect: string }) => {
    const [user] = await instance.db('users').where('id', userId);
    return { ...user, redirect };
  });

  passport.use(STRATEGY, magicLink);
});

Steps to Reproduce

Create a custom context and try to access the passportUser from within the request or the reply.request objects.

Expected Behavior

It should be possible to access the session user after deserialization by passport.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (9 by maintainers)

Most upvoted comments

@sorodrigo I would recommend that you try to remove some stuff from the repro, it’s too bloated right now and removing stuff may highlight the issue more easily