Why does useGenericAuth not change the context as expected?

99 views Asked by At

Cutting straight to the case: backend project using typescript and graphql. We have a package /graphql_gateway where all requests are sent to. This gateway uses graphQL mesh to stitch the schemas of our Supabase and our server which is located in the package /graphql_server.

This is the .meshrc.yaml file:

serve:
  endpoint: /graphqlyour text
  playground: true
  port: 3000
sources:
  - name: Supabase
    handler:
      graphql:
        endpoint: '{env.SUPABASE_GRAPHQL_URL}'
        operationHeaders:
          apiKey: '{env.SUPABASE_API_KEY}'
          Content-Type: application/json
        schemaHeaders:
          apiKey: '{env.SUPABASE_API_KEY}'
          Content-Type: application/json
  - name: Server
    handler:
      graphql:
        endpoint: '{env.SERVER_GRAPHQL_URL}'
        source: ./../graphql_server/src/graphql/schema.ts
additionalEnvelopPlugins: './src/envelopPlugins'

this is corresponding the envelopPlugins.ts file:

import { ResolveUserFn, useGenericAuth } from '@envelop/generic-auth'
import { User, createClient } from '@supabase/supabase-js'
import { parse } from 'cookie'
import { IncomingMessage } from 'http'

const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_API_KEY)

type Context = {
  req: IncomingMessage
}

const resolveUserFn: ResolveUserFn<User, Context> = async (context: Context) => {
  // Get cookies from authorization header (temporary workaround)
  const cookies = parse(context?.req?.headers?.authorization as string)

  if (!cookies?.['supabase-auth-token']) {
    console.error('Auth token missing')
    return null
  }

  // Get JWT from cookie (cookie set by Supabase is array of tokens)
  const tokenArray: string[] = JSON.parse(cookies?.['supabase-auth-token']) as string[]
  const jwt = tokenArray?.[0]

  // Get user from Supabase if JWT is valid
  const {
    data: { user },
    error
  } = await supabase.auth.getUser(jwt)

  if (error) {
    console.error('Error while trying to get user from Supabase', error)
    return null
  }

  return user
}

const plugins = [
  useGenericAuth({
    resolveUserFn,
    mode: 'protect-all'
  })
]

export default plugins

Now I would assume according to the documentation of useGenericAuth, that it injects the user into the context and that I can therefore access context.currentUser or similar in the resolvers.ts file of /graphql_server, in case that /graphql_gateway decides to send forward the request to there.

that is the server.ts file of /graphql_server:


import Fastify from 'fastify'
import mercurius from 'mercurius'
import resolvers from './graphql/resolvers'
import schema from './graphql/schema'

const ENV = process.env.NODE_ENV || 'development'

const envToLogger = {
development: {
transport: {
target: 'pino-pretty',
options: {
translateTime: 'HH:MM:ss Z',
ignore: 'pid,hostname'
}
}
},
production: true
}

const app = Fastify({
logger: envToLogger\[ENV\]
})
app.addHook('preHandler', function (req, reply, done) {
if (req.body) {
req.log.info({ body: req.body }, 'parsed body')
}
done()
})

// https://github.com/mercurius-js/mercurius-typescript/tree/master/examples
void app.register(mercurius, {
schema,
resolvers,
graphiql: true // see http://localhost:3001/graphiql
})
export default app

In resolvers.ts i would like to do somthing like

...
Query: {
  testQuery: (parent: unknown, args: unknown, context: any, info: unknown) =\> {
    console.log(context.currentUser)
    return 'test'
  }
}
...

As described above I tried to use the useGenericAuth function to inject the user into the context, so that I can access it in the resolvers. But the user is not set, either because useGenericAuth does not work as expected, or because the Context is not transferred to the /graphql_server part of our app. How can I access the currently logged in user in the resolvers?

0

There are 0 answers