From 00b1f01f9ba18d9502fd81fa624b47be1dd4d254 Mon Sep 17 00:00:00 2001 From: liuyi Date: Fri, 7 Feb 2025 12:03:59 +0800 Subject: [PATCH] feat(server): add public user type (#10006) --- .../backend/server/src/core/user/index.ts | 2 +- .../backend/server/src/core/user/types.ts | 16 ++++++++ .../src/core/workspaces/resolvers/page.ts | 39 +++++++++++++------ packages/backend/server/src/models/user.ts | 7 ++++ packages/backend/server/src/schema.gql | 11 ++++-- 5 files changed, 60 insertions(+), 15 deletions(-) diff --git a/packages/backend/server/src/core/user/index.ts b/packages/backend/server/src/core/user/index.ts index aeb8f25c1e..698507c838 100644 --- a/packages/backend/server/src/core/user/index.ts +++ b/packages/backend/server/src/core/user/index.ts @@ -13,4 +13,4 @@ import { UserManagementResolver, UserResolver } from './resolver'; }) export class UserModule {} -export { UserType } from './types'; +export { PublicUserType, UserType } from './types'; diff --git a/packages/backend/server/src/core/user/types.ts b/packages/backend/server/src/core/user/types.ts index fd246f58c4..e84507408c 100644 --- a/packages/backend/server/src/core/user/types.ts +++ b/packages/backend/server/src/core/user/types.ts @@ -7,6 +7,7 @@ import { } from '@nestjs/graphql'; import type { User } from '@prisma/client'; +import { PublicUser } from '../../models'; import { type CurrentUser } from '../auth/session'; @ObjectType() @@ -42,6 +43,21 @@ export class UserType implements CurrentUser { createdAt?: Date | null; } +@ObjectType() +export class PublicUserType implements PublicUser { + @Field() + id!: string; + + @Field() + name!: string; + + @Field() + email!: string; + + @Field(() => String, { nullable: true }) + avatarUrl!: string | null; +} + @ObjectType() export class LimitedUserType implements Partial { @Field({ description: 'User email' }) diff --git a/packages/backend/server/src/core/workspaces/resolvers/page.ts b/packages/backend/server/src/core/workspaces/resolvers/page.ts index c0255a1c87..c17cd781d8 100644 --- a/packages/backend/server/src/core/workspaces/resolvers/page.ts +++ b/packages/backend/server/src/core/workspaces/resolvers/page.ts @@ -27,6 +27,7 @@ import { PaginationInput, registerObjectType, } from '../../../base'; +import { Models } from '../../../models'; import { CurrentUser } from '../../auth'; import { DOC_ACTIONS, @@ -38,6 +39,7 @@ import { PublicPageMode, WorkspaceRole, } from '../../permission'; +import { PublicUserType } from '../../user'; import { DocID } from '../../utils/doc'; import { WorkspaceType } from '../types'; @@ -117,17 +119,11 @@ class UpdatePageDefaultRoleInput { @ObjectType() class GrantedDocUserType { - @Field(() => String) - workspaceId!: string; - - @Field(() => String) - pageId!: string; - - @Field(() => String) - userId!: string; - @Field(() => DocRole, { name: 'role' }) type!: DocRole; + + @Field(() => PublicUserType) + user!: PublicUserType; } @ObjectType() @@ -161,7 +157,8 @@ export class PagePermissionResolver { constructor( private readonly prisma: PrismaClient, - private readonly permission: PermissionService + private readonly permission: PermissionService, + private readonly models: Models ) {} /** @@ -293,7 +290,27 @@ export class PagePermissionResolver { ]); }); - return paginate(permissions, 'createdAt', pagination, totalCount); + const users = new Map( + await Promise.all( + permissions.map( + async p => + [p.userId, await this.models.user.getPublicUser(p.userId)] as [ + string, + PublicUserType, + ] + ) + ) + ); + + return paginate( + permissions.map(p => ({ + ...p, + user: users.get(p.userId), + })), + 'createdAt', + pagination, + totalCount + ); } /** diff --git a/packages/backend/server/src/models/user.ts b/packages/backend/server/src/models/user.ts index b122b3ab84..fcaf1b693c 100644 --- a/packages/backend/server/src/models/user.ts +++ b/packages/backend/server/src/models/user.ts @@ -59,6 +59,13 @@ export class UserModel extends BaseModel { }); } + async getPublicUsers(ids: string[]): Promise { + return this.db.user.findMany({ + select: publicUserSelect, + where: { id: { in: ids } }, + }); + } + async getUserByEmail(email: string): Promise { const rows = await this.db.$queryRaw` SELECT id, name, email, password, registered, email_verified as emailVerifiedAt, avatar_url as avatarUrl, registered, created_at as createdAt diff --git a/packages/backend/server/src/schema.gql b/packages/backend/server/src/schema.gql index 2d50a7d714..7ac8da4e76 100644 --- a/packages/backend/server/src/schema.gql +++ b/packages/backend/server/src/schema.gql @@ -385,10 +385,8 @@ input GrantDocUserRolesInput { } type GrantedDocUserType { - pageId: String! role: DocRole! - userId: String! - workspaceId: String! + user: PublicUserType! } type GrantedDocUserTypeEdge { @@ -731,6 +729,13 @@ enum PublicPageMode { Page } +type PublicUserType { + avatarUrl: String + email: String! + id: String! + name: String! +} + type Query { collectAllBlobSizes: WorkspaceBlobSizes! @deprecated(reason: "use `user.quotaUsage` instead")