import { Inject, Injectable, Logger, UnauthorizedException } from '@nestjs/common' import { PrismaService } from '../Prisma/prisma.service' import { Request } from 'express' import { clerkClient } from '@clerk/express' import { RedisService } from '../Redis/redis.service' @Injectable() export class GraphqlService { constructor( private readonly prisma: PrismaService, @Inject('REDIS_CLIENT') private readonly redis: RedisService, ) {} async acquireContextFromSessionId(sessionId: string) { return this.acquireContext({ headers: { 'x-session-id': sessionId }, } as unknown as Request) } async acquireContext(req: Request) { // get x-session-id from headers let sessionId: string const disableAuth = process.env.DISABLE_AUTH === 'true' try { sessionId = req.headers['x-session-id'] as string } catch (_error) { return null } if (disableAuth) { return null } // check if the sessionId is valid if (!sessionId) { return null } // redis context cache const cachedUser = await this.redis.getUser(sessionId) if (cachedUser) { // Logger.log(`Found cached user for sessionId: ${sessionId}`) return cachedUser } // check if the token is valid const session = await clerkClient.sessions.getSession(sessionId as string) if (!session) { throw new UnauthorizedException('Invalid session') } const user = await this.prisma.user.findUnique({ where: { id: session.userId }, }) if (!user) { throw new UnauthorizedException('User not found') } await this.redis.setUser(sessionId, user, session.expireAt) return user } async invalidateCache(sessionId: string) { // invalidate redis cache for sessionId await this.redis.del(sessionId) Logger.log(`Invalidated cache for sessionId: ${sessionId}`) } }