mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
feat(server): search user in workspace (#9870)
This commit is contained in:
@@ -250,6 +250,13 @@ export const USER_FRIENDLY_ERRORS = {
|
||||
message: 'Resource not found.',
|
||||
},
|
||||
|
||||
// Input errors
|
||||
query_too_long: {
|
||||
type: 'invalid_input',
|
||||
args: { max: 'number' },
|
||||
message: ({ max }) => `Query is too long, max length is ${max}.`,
|
||||
},
|
||||
|
||||
// User Errors
|
||||
user_not_found: {
|
||||
type: 'resource_not_found',
|
||||
|
||||
@@ -21,6 +21,16 @@ export class NotFound extends UserFriendlyError {
|
||||
super('resource_not_found', 'not_found', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class QueryTooLongDataType {
|
||||
@Field() max!: number
|
||||
}
|
||||
|
||||
export class QueryTooLong extends UserFriendlyError {
|
||||
constructor(args: QueryTooLongDataType, message?: string | ((args: QueryTooLongDataType) => string)) {
|
||||
super('invalid_input', 'query_too_long', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class UserNotFound extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
@@ -645,6 +655,7 @@ export enum ErrorNames {
|
||||
INTERNAL_SERVER_ERROR,
|
||||
TOO_MANY_REQUEST,
|
||||
NOT_FOUND,
|
||||
QUERY_TOO_LONG,
|
||||
USER_NOT_FOUND,
|
||||
USER_AVATAR_NOT_FOUND,
|
||||
EMAIL_ALREADY_USED,
|
||||
@@ -735,5 +746,5 @@ registerEnumType(ErrorNames, {
|
||||
export const ErrorDataUnionType = createUnionType({
|
||||
name: 'ErrorDataUnion',
|
||||
types: () =>
|
||||
[WrongSignInCredentialsDataType, UnknownOauthProviderDataType, MissingOauthQueryParameterDataType, InvalidEmailDataType, InvalidPasswordLengthDataType, SpaceNotFoundDataType, MemberNotFoundInSpaceDataType, NotInSpaceDataType, AlreadyInSpaceDataType, SpaceAccessDeniedDataType, SpaceOwnerNotFoundDataType, DocNotFoundDataType, DocAccessDeniedDataType, VersionRejectedDataType, InvalidHistoryTimestampDataType, DocHistoryNotFoundDataType, BlobNotFoundDataType, UnsupportedSubscriptionPlanDataType, SubscriptionAlreadyExistsDataType, SubscriptionNotExistsDataType, SameSubscriptionRecurringDataType, SubscriptionPlanNotFoundDataType, CopilotMessageNotFoundDataType, CopilotPromptNotFoundDataType, CopilotProviderSideErrorDataType, RuntimeConfigNotFoundDataType, InvalidRuntimeConfigTypeDataType, InvalidLicenseUpdateParamsDataType, WorkspaceMembersExceedLimitToDowngradeDataType] as const,
|
||||
[QueryTooLongDataType, WrongSignInCredentialsDataType, UnknownOauthProviderDataType, MissingOauthQueryParameterDataType, InvalidEmailDataType, InvalidPasswordLengthDataType, SpaceNotFoundDataType, MemberNotFoundInSpaceDataType, NotInSpaceDataType, AlreadyInSpaceDataType, SpaceAccessDeniedDataType, SpaceOwnerNotFoundDataType, DocNotFoundDataType, DocAccessDeniedDataType, VersionRejectedDataType, InvalidHistoryTimestampDataType, DocHistoryNotFoundDataType, BlobNotFoundDataType, UnsupportedSubscriptionPlanDataType, SubscriptionAlreadyExistsDataType, SubscriptionNotExistsDataType, SameSubscriptionRecurringDataType, SubscriptionPlanNotFoundDataType, CopilotMessageNotFoundDataType, CopilotPromptNotFoundDataType, CopilotProviderSideErrorDataType, RuntimeConfigNotFoundDataType, InvalidRuntimeConfigTypeDataType, InvalidLicenseUpdateParamsDataType, WorkspaceMembersExceedLimitToDowngradeDataType] as const,
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
ResolveField,
|
||||
Resolver,
|
||||
} from '@nestjs/graphql';
|
||||
import { PrismaClient, WorkspaceMemberStatus } from '@prisma/client';
|
||||
import { Prisma, PrismaClient, WorkspaceMemberStatus } from '@prisma/client';
|
||||
import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';
|
||||
|
||||
import type { FileUpload } from '../../../base';
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
EventEmitter,
|
||||
InternalServerError,
|
||||
MemberQuotaExceeded,
|
||||
QueryTooLong,
|
||||
RequestMutex,
|
||||
SpaceAccessDenied,
|
||||
SpaceNotFound,
|
||||
@@ -148,25 +149,42 @@ export class WorkspaceResolver {
|
||||
async members(
|
||||
@Parent() workspace: WorkspaceType,
|
||||
@Args('skip', { type: () => Int, nullable: true }) skip?: number,
|
||||
@Args('take', { type: () => Int, nullable: true }) take?: number
|
||||
@Args('take', { type: () => Int, nullable: true }) take?: number,
|
||||
@Args('query', { type: () => String, nullable: true }) query?: string
|
||||
) {
|
||||
const data = await this.prisma.workspaceUserPermission.findMany({
|
||||
const args: Prisma.WorkspaceUserPermissionFindManyArgs = {
|
||||
where: { workspaceId: workspace.id },
|
||||
skip,
|
||||
take: take || 8,
|
||||
orderBy: [{ createdAt: 'asc' }, { type: 'desc' }],
|
||||
include: { user: true },
|
||||
};
|
||||
|
||||
if (query) {
|
||||
if (query.length > 255) {
|
||||
throw new QueryTooLong({ max: 255 });
|
||||
}
|
||||
|
||||
// @ts-expect-error not null
|
||||
args.where.user = {
|
||||
// TODO(@forehalo): case-insensitive search later
|
||||
OR: [{ name: { contains: query } }, { email: { contains: query } }],
|
||||
};
|
||||
}
|
||||
|
||||
const data = await this.prisma.workspaceUserPermission.findMany({
|
||||
...args,
|
||||
include: {
|
||||
user: true,
|
||||
},
|
||||
});
|
||||
|
||||
return data
|
||||
.filter(({ user }) => !!user)
|
||||
.map(({ id, accepted, status, type, user }) => ({
|
||||
...user,
|
||||
permission: type,
|
||||
inviteId: id,
|
||||
accepted,
|
||||
status,
|
||||
}));
|
||||
return data.map(({ id, accepted, status, type, user }) => ({
|
||||
...user,
|
||||
permission: type,
|
||||
inviteId: id,
|
||||
accepted,
|
||||
status,
|
||||
}));
|
||||
}
|
||||
|
||||
@ResolveField(() => WorkspacePageMeta, {
|
||||
|
||||
@@ -209,7 +209,7 @@ type EditorType {
|
||||
name: String!
|
||||
}
|
||||
|
||||
union ErrorDataUnion = AlreadyInSpaceDataType | BlobNotFoundDataType | CopilotMessageNotFoundDataType | CopilotPromptNotFoundDataType | CopilotProviderSideErrorDataType | DocAccessDeniedDataType | DocHistoryNotFoundDataType | DocNotFoundDataType | InvalidEmailDataType | InvalidHistoryTimestampDataType | InvalidLicenseUpdateParamsDataType | InvalidPasswordLengthDataType | InvalidRuntimeConfigTypeDataType | MemberNotFoundInSpaceDataType | MissingOauthQueryParameterDataType | NotInSpaceDataType | RuntimeConfigNotFoundDataType | SameSubscriptionRecurringDataType | SpaceAccessDeniedDataType | SpaceNotFoundDataType | SpaceOwnerNotFoundDataType | SubscriptionAlreadyExistsDataType | SubscriptionNotExistsDataType | SubscriptionPlanNotFoundDataType | UnknownOauthProviderDataType | UnsupportedSubscriptionPlanDataType | VersionRejectedDataType | WorkspaceMembersExceedLimitToDowngradeDataType | WrongSignInCredentialsDataType
|
||||
union ErrorDataUnion = AlreadyInSpaceDataType | BlobNotFoundDataType | CopilotMessageNotFoundDataType | CopilotPromptNotFoundDataType | CopilotProviderSideErrorDataType | DocAccessDeniedDataType | DocHistoryNotFoundDataType | DocNotFoundDataType | InvalidEmailDataType | InvalidHistoryTimestampDataType | InvalidLicenseUpdateParamsDataType | InvalidPasswordLengthDataType | InvalidRuntimeConfigTypeDataType | MemberNotFoundInSpaceDataType | MissingOauthQueryParameterDataType | NotInSpaceDataType | QueryTooLongDataType | RuntimeConfigNotFoundDataType | SameSubscriptionRecurringDataType | SpaceAccessDeniedDataType | SpaceNotFoundDataType | SpaceOwnerNotFoundDataType | SubscriptionAlreadyExistsDataType | SubscriptionNotExistsDataType | SubscriptionPlanNotFoundDataType | UnknownOauthProviderDataType | UnsupportedSubscriptionPlanDataType | VersionRejectedDataType | WorkspaceMembersExceedLimitToDowngradeDataType | WrongSignInCredentialsDataType
|
||||
|
||||
enum ErrorNames {
|
||||
ACCESS_DENIED
|
||||
@@ -271,6 +271,7 @@ enum ErrorNames {
|
||||
OAUTH_STATE_EXPIRED
|
||||
PAGE_IS_NOT_PUBLIC
|
||||
PASSWORD_REQUIRED
|
||||
QUERY_TOO_LONG
|
||||
RUNTIME_CONFIG_NOT_FOUND
|
||||
SAME_EMAIL_PROVIDED
|
||||
SAME_SUBSCRIPTION_RECURRING
|
||||
@@ -692,6 +693,10 @@ input QueryChatHistoriesInput {
|
||||
skip: Int
|
||||
}
|
||||
|
||||
type QueryTooLongDataType {
|
||||
max: Int!
|
||||
}
|
||||
|
||||
type QuotaQueryType {
|
||||
blobLimit: SafeInt!
|
||||
copilotActionLimit: SafeInt
|
||||
@@ -1059,7 +1064,7 @@ type WorkspaceType {
|
||||
memberCount: Int!
|
||||
|
||||
"""Members of workspace"""
|
||||
members(skip: Int, take: Int): [InviteUserType!]!
|
||||
members(query: String, skip: Int, take: Int): [InviteUserType!]!
|
||||
|
||||
"""Owner of workspace"""
|
||||
owner: UserType!
|
||||
|
||||
Reference in New Issue
Block a user