diff --git a/packages/velog-server/src/common/plugins/global/authPlugin.ts b/packages/velog-server/src/common/plugins/global/authPlugin.ts index da76d1f8..8ca590df 100644 --- a/packages/velog-server/src/common/plugins/global/authPlugin.ts +++ b/packages/velog-server/src/common/plugins/global/authPlugin.ts @@ -35,13 +35,12 @@ const authPlugin: FastifyPluginAsync = async (fastify) => { await userService.restoreToken({ request, reply }) } - // const user = await userService.findById(accessTokenData.user_id) - - // if (!user) { - // cookie.clearCookie(reply, 'access_token') - // cookie.clearCookie(reply, 'refresh_token') - // throw new Error('User not found') - // } + const user = await userService.checkExistsUser(accessTokenData.user_id) + if (!user) { + cookie.clearCookie(reply, 'access_token') + cookie.clearCookie(reply, 'refresh_token') + throw new Error('User not found') + } request.user = { id: accessTokenData.user_id } return diff --git a/packages/velog-server/src/graphql/resolvers/postResolvers.ts b/packages/velog-server/src/graphql/resolvers/postResolvers.ts index e2a391bf..97d9b114 100644 --- a/packages/velog-server/src/graphql/resolvers/postResolvers.ts +++ b/packages/velog-server/src/graphql/resolvers/postResolvers.ts @@ -18,8 +18,19 @@ const postResolvers: Resolvers = { Post: { user: async (parent: PostIncludeUser) => { if (!parent.user) { - const userService = container.resolve(UserService) - return await userService.getCurrentUser(parent.fk_user_id) + if (parent?.fk_user_id) { + const userService = container.resolve(UserService) + return await userService.getCurrentUser(parent.fk_user_id) + } + + if (parent.id) { + const postService = container.resolve(PostService) + const userService = container.resolve(UserService) + const post = await postService.findById(parent.id) + return await userService.getCurrentUser(post?.fk_user_id) + } + + return null } return parent?.user }, diff --git a/packages/velog-server/src/lib/elasticSearch/ElasticSearchService.ts b/packages/velog-server/src/lib/elasticSearch/ElasticSearchService.ts index 901b0cf4..c3b2a7d3 100644 --- a/packages/velog-server/src/lib/elasticSearch/ElasticSearchService.ts +++ b/packages/velog-server/src/lib/elasticSearch/ElasticSearchService.ts @@ -4,6 +4,7 @@ import { injectable, singleton } from 'tsyringe' import { BuildQueryService } from './BuildQueryService.js' import { PostIncludeTags } from '@services/PostService/PostServiceInterface.js' import { Post } from '@prisma/client' +import { UserService } from '@services/UserService/index.js' interface Service { get client(): Client @@ -13,7 +14,10 @@ interface Service { @injectable() @singleton() export class ElasticSearchService implements Service { - constructor(private readonly buildQueryService: BuildQueryService) {} + constructor( + private readonly userService: UserService, + private readonly buildQueryService: BuildQueryService, + ) {} public get client(): Client { return new Client({ node: ENV.esHost }) } @@ -147,14 +151,26 @@ export class ElasticSearchService implements Service { }, }) - const posts = result.body.hits.hits.map((hit: any) => hit._source) - posts.forEach((p: any) => { - p.released_at = new Date(p.released_at) + const sources = result.body.hits.hits + .map((hit: any) => hit._source) + .map((p: any) => ({ ...p, released_at: new Date(p.released_at) })) + + const promises = sources.map(async (post: any) => { + try { + const result = await this.userService.checkExistsUser(post?.user?.id) + return { id: post.id, result } + } catch (error) { + console.error('Error checking user:', error) + return { id: post.id, result: false } + } }) + const promiseResult = await Promise.all(promises) + const existsUserPosts = promiseResult.filter(({ result }) => result).map(({ id }) => id) + const data = { count: result.body.hits.total.value, - posts: result.body.hits.hits.map((hit: any) => hit._source), + posts: sources.filter((post: any) => existsUserPosts.includes(post.id)), } return data diff --git a/packages/velog-server/src/lib/redis/RedisService.ts b/packages/velog-server/src/lib/redis/RedisService.ts index ffd6e1dc..72626fec 100644 --- a/packages/velog-server/src/lib/redis/RedisService.ts +++ b/packages/velog-server/src/lib/redis/RedisService.ts @@ -33,6 +33,7 @@ export class RedisService extends Redis implements Service { `ssr:/@${username}/series/${seriesUrlSlug}`, changeEmail: (code: string) => `changeEmailCode:${code}`, trendingWriters: () => `trending:writers`, + existsUser: (userId: string) => `exists:user:${userId}`, } } @@ -61,6 +62,7 @@ type GenerateRedisKey = { postSeries: (username: string, seriesUrlSlug: string) => string changeEmail: (code: string) => string trendingWriters: () => string + existsUser: (userId: string) => string } type QueueName = 'createFeed' | 'checkPostSpam' diff --git a/packages/velog-server/src/services/UserService/index.ts b/packages/velog-server/src/services/UserService/index.ts index a036c413..6bd1fa4b 100644 --- a/packages/velog-server/src/services/UserService/index.ts +++ b/packages/velog-server/src/services/UserService/index.ts @@ -41,6 +41,7 @@ interface Service { initiateChangeEmail(email: string, signedUserId?: string): Promise confirmChangeEmail(code: string, signedUserId?: string): Promise checkTrust(userId: string): Promise + checkExistsUser(userId: string): Promise } @injectable() @@ -316,6 +317,19 @@ export class UserService implements Service { const diffDays = differenceInDays(today, joinDay) return diffDays > 20 } + public async checkExistsUser(userId?: string): Promise { + if (!userId) return false + + const key = this.redis.generateKey.existsUser(userId) + const value = await this.redis.get(key) + if (value === 'true') return true + if (value === 'false') return false + + const user = await this.findById(userId) + const save = user ? 'true' : 'false' + await this.redis.set(key, save, 'EX', Time.ONE_MINUTE_IN_S * 10) + return !!user + } } type FindByIdOrUsernameArgs = {