mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-17 22:37:04 +08: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.',
|
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 Errors
|
||||||
user_not_found: {
|
user_not_found: {
|
||||||
type: 'resource_not_found',
|
type: 'resource_not_found',
|
||||||
|
|||||||
@@ -21,6 +21,16 @@ export class NotFound extends UserFriendlyError {
|
|||||||
super('resource_not_found', 'not_found', message);
|
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 {
|
export class UserNotFound extends UserFriendlyError {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
@@ -645,6 +655,7 @@ export enum ErrorNames {
|
|||||||
INTERNAL_SERVER_ERROR,
|
INTERNAL_SERVER_ERROR,
|
||||||
TOO_MANY_REQUEST,
|
TOO_MANY_REQUEST,
|
||||||
NOT_FOUND,
|
NOT_FOUND,
|
||||||
|
QUERY_TOO_LONG,
|
||||||
USER_NOT_FOUND,
|
USER_NOT_FOUND,
|
||||||
USER_AVATAR_NOT_FOUND,
|
USER_AVATAR_NOT_FOUND,
|
||||||
EMAIL_ALREADY_USED,
|
EMAIL_ALREADY_USED,
|
||||||
@@ -735,5 +746,5 @@ registerEnumType(ErrorNames, {
|
|||||||
export const ErrorDataUnionType = createUnionType({
|
export const ErrorDataUnionType = createUnionType({
|
||||||
name: 'ErrorDataUnion',
|
name: 'ErrorDataUnion',
|
||||||
types: () =>
|
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,
|
ResolveField,
|
||||||
Resolver,
|
Resolver,
|
||||||
} from '@nestjs/graphql';
|
} from '@nestjs/graphql';
|
||||||
import { PrismaClient, WorkspaceMemberStatus } from '@prisma/client';
|
import { Prisma, PrismaClient, WorkspaceMemberStatus } from '@prisma/client';
|
||||||
import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';
|
import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';
|
||||||
|
|
||||||
import type { FileUpload } from '../../../base';
|
import type { FileUpload } from '../../../base';
|
||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
EventEmitter,
|
EventEmitter,
|
||||||
InternalServerError,
|
InternalServerError,
|
||||||
MemberQuotaExceeded,
|
MemberQuotaExceeded,
|
||||||
|
QueryTooLong,
|
||||||
RequestMutex,
|
RequestMutex,
|
||||||
SpaceAccessDenied,
|
SpaceAccessDenied,
|
||||||
SpaceNotFound,
|
SpaceNotFound,
|
||||||
@@ -148,25 +149,42 @@ export class WorkspaceResolver {
|
|||||||
async members(
|
async members(
|
||||||
@Parent() workspace: WorkspaceType,
|
@Parent() workspace: WorkspaceType,
|
||||||
@Args('skip', { type: () => Int, nullable: true }) skip?: number,
|
@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 },
|
where: { workspaceId: workspace.id },
|
||||||
skip,
|
skip,
|
||||||
take: take || 8,
|
take: take || 8,
|
||||||
orderBy: [{ createdAt: 'asc' }, { type: 'desc' }],
|
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
|
return data.map(({ id, accepted, status, type, user }) => ({
|
||||||
.filter(({ user }) => !!user)
|
...user,
|
||||||
.map(({ id, accepted, status, type, user }) => ({
|
permission: type,
|
||||||
...user,
|
inviteId: id,
|
||||||
permission: type,
|
accepted,
|
||||||
inviteId: id,
|
status,
|
||||||
accepted,
|
}));
|
||||||
status,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField(() => WorkspacePageMeta, {
|
@ResolveField(() => WorkspacePageMeta, {
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ type EditorType {
|
|||||||
name: String!
|
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 {
|
enum ErrorNames {
|
||||||
ACCESS_DENIED
|
ACCESS_DENIED
|
||||||
@@ -271,6 +271,7 @@ enum ErrorNames {
|
|||||||
OAUTH_STATE_EXPIRED
|
OAUTH_STATE_EXPIRED
|
||||||
PAGE_IS_NOT_PUBLIC
|
PAGE_IS_NOT_PUBLIC
|
||||||
PASSWORD_REQUIRED
|
PASSWORD_REQUIRED
|
||||||
|
QUERY_TOO_LONG
|
||||||
RUNTIME_CONFIG_NOT_FOUND
|
RUNTIME_CONFIG_NOT_FOUND
|
||||||
SAME_EMAIL_PROVIDED
|
SAME_EMAIL_PROVIDED
|
||||||
SAME_SUBSCRIPTION_RECURRING
|
SAME_SUBSCRIPTION_RECURRING
|
||||||
@@ -692,6 +693,10 @@ input QueryChatHistoriesInput {
|
|||||||
skip: Int
|
skip: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type QueryTooLongDataType {
|
||||||
|
max: Int!
|
||||||
|
}
|
||||||
|
|
||||||
type QuotaQueryType {
|
type QuotaQueryType {
|
||||||
blobLimit: SafeInt!
|
blobLimit: SafeInt!
|
||||||
copilotActionLimit: SafeInt
|
copilotActionLimit: SafeInt
|
||||||
@@ -1059,7 +1064,7 @@ type WorkspaceType {
|
|||||||
memberCount: Int!
|
memberCount: Int!
|
||||||
|
|
||||||
"""Members of workspace"""
|
"""Members of workspace"""
|
||||||
members(skip: Int, take: Int): [InviteUserType!]!
|
members(query: String, skip: Int, take: Int): [InviteUserType!]!
|
||||||
|
|
||||||
"""Owner of workspace"""
|
"""Owner of workspace"""
|
||||||
owner: UserType!
|
owner: UserType!
|
||||||
|
|||||||
Reference in New Issue
Block a user