Skip to content

Commit

Permalink
feat: remove public endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
darkskygit committed Apr 2, 2024
1 parent 27f19c9 commit 6b552b3
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 221 deletions.
10 changes: 0 additions & 10 deletions packages/backend/server/src/fundamentals/graphql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,6 @@ export type GraphqlContext = {
GraphQLModule.forRootAsync<ApolloDriverConfig>({
driver: ApolloDriver,
useFactory: (config: Config) => {
const copilotAuthorization = config.featureFlags.copilotAuthorization;
const cors = {
cors: {
origin: [
'https://try-blocksuite.vercel.app/',
'http://localhost:5173/',
],
},
};
return {
...config.graphql,
path: `${config.path}/graphql`,
Expand Down Expand Up @@ -87,7 +78,6 @@ export type GraphqlContext = {

return formattedError;
},
...(copilotAuthorization ? cors : {}),
};
},
inject: [Config],
Expand Down
8 changes: 4 additions & 4 deletions packages/backend/server/src/plugins/copilot/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class CopilotController {
@Public()
@Get('/chat/:sessionId')
async chat(
@CurrentUser() user: CurrentUser | undefined,
@CurrentUser() user: CurrentUser,
@Req() req: Request,
@Param('sessionId') sessionId: string,
@Query('message') content: string
Expand Down Expand Up @@ -71,7 +71,7 @@ export class CopilotController {
session.model,
{
signal: req.signal,
user: user?.id,
user: user.id,
}
);

Expand All @@ -93,7 +93,7 @@ export class CopilotController {
@Public()
@Sse('/chat/:sessionId/stream')
async chatStream(
@CurrentUser() user: CurrentUser | undefined,
@CurrentUser() user: CurrentUser,
@Req() req: Request,
@Param('sessionId') sessionId: string,
@Query('message') content: string
Expand All @@ -120,7 +120,7 @@ export class CopilotController {
return from(
provider.generateTextStream(session.finish(), session.model, {
signal: req.signal,
user: user?.id,
user: user.id,
})
).pipe(
connect(shared$ =>
Expand Down
72 changes: 23 additions & 49 deletions packages/backend/server/src/plugins/copilot/resolver.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ForbiddenException } from '@nestjs/common';
import {
Args,
Field,
Expand All @@ -7,7 +6,6 @@ import {
Mutation,
ObjectType,
Parent,
Query,
registerEnumType,
ResolveField,
Resolver,
Expand Down Expand Up @@ -144,12 +142,9 @@ export class CopilotResolver {
})
async getQuota(
@Parent() copilot: CopilotType,
@CurrentUser() user: CurrentUser | undefined,
@CurrentUser() user: CurrentUser,
@Args('docId') docId: string
) {
// TODO(@darkskygit): remove this after the feature is stable
if (!user) return { used: 0 };

const quota = await this.quota.getUserQuota(user.id);
const limit = quota.feature.copilotActionLimit;

Expand Down Expand Up @@ -179,9 +174,9 @@ export class CopilotResolver {
})
async chats(
@Parent() copilot: CopilotType,
@CurrentUser() user?: CurrentUser
@CurrentUser() user: CurrentUser
) {
return await this.chatSession.listSessions(user?.id, copilot.workspaceId);
return await this.chatSession.listSessions(user.id, copilot.workspaceId);
}

@ResolveField(() => [String], {
Expand All @@ -190,17 +185,17 @@ export class CopilotResolver {
})
async actions(
@Parent() copilot: CopilotType,
@CurrentUser() user?: CurrentUser
@CurrentUser() user: CurrentUser
) {
return await this.chatSession.listSessions(user?.id, copilot.workspaceId, {
return await this.chatSession.listSessions(user.id, copilot.workspaceId, {
action: true,
});
}

@ResolveField(() => [CopilotHistoriesType], {})
async histories(
@Parent() copilot: CopilotType,
@CurrentUser() user?: CurrentUser,
@CurrentUser() user: CurrentUser,
@Args('docId', { nullable: true }) docId?: string,
@Args({
name: 'options',
Expand All @@ -210,20 +205,14 @@ export class CopilotResolver {
options?: QueryChatHistoriesInput
) {
const workspaceId = copilot.workspaceId;
// todo(@darkskygit): remove this after the feature is stable
const publishable = AFFiNE.featureFlags.copilotAuthorization;
if (user) {
if (docId) {
await this.permissions.checkPagePermission(workspaceId, docId, user.id);
} else {
await this.permissions.checkWorkspace(workspaceId, user.id);
}
} else if (!publishable) {
return new ForbiddenException('Login required');
if (docId) {
await this.permissions.checkPagePermission(workspaceId, docId, user.id);
} else {
await this.permissions.checkWorkspace(workspaceId, user.id);
}

return await this.chatSession.listHistories(
user?.id,
user.id,
workspaceId,
docId,
options
Expand All @@ -235,38 +224,30 @@ export class CopilotResolver {
description: 'Create a chat session',
})
async createCopilotSession(
@CurrentUser() user: CurrentUser | undefined,
@CurrentUser() user: CurrentUser,
@Args({ name: 'options', type: () => CreateChatSessionInput })
options: CreateChatSessionInput
) {
// todo(@darkskygit): remove this after the feature is stable
const publishable = AFFiNE.featureFlags.copilotAuthorization;
if (!user && !publishable) {
return new ForbiddenException('Login required');
}

const lockFlag = `session:${user?.id}:${options.workspaceId}`;
const lockFlag = `session:${user.id}:${options.workspaceId}`;
await using lock = await this.mutex.lock(lockFlag);
if (!lock) {
return new TooManyRequestsException('Server is busy');
}
if (options.action && user) {
const { limit, used } = await this.getQuota(
{ workspaceId: options.workspaceId },
user,
options.docId

const { limit, used } = await this.getQuota(
{ workspaceId: options.workspaceId },
user,
options.docId
);
if (limit && Number.isFinite(limit) && used >= limit) {
return new PaymentRequiredException(
`You have reached the limit of actions in this workspace, please upgrade your plan.`
);
if (limit && Number.isFinite(limit) && used >= limit) {
return new PaymentRequiredException(
`You have reached the limit of actions in this workspace, please upgrade your plan.`
);
}
}

const session = await this.chatSession.create({
...options,
// todo: force user to be logged in
userId: user?.id ?? '',
userId: user.id,
});
return session;
}
Expand All @@ -284,11 +265,4 @@ export class UserCopilotResolver {
await this.permissions.checkWorkspace(workspaceId, user.id);
return { workspaceId };
}

@Public()
@Query(() => CopilotType)
async copilotAnonymous(@Args('workspaceId') workspaceId: string) {
if (!AFFiNE.featureFlags.copilotAuthorization) return;
return { workspaceId };
}
}
53 changes: 5 additions & 48 deletions packages/backend/server/src/plugins/copilot/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,24 +117,17 @@ export class ChatSession implements AsyncDisposable {
@Injectable()
export class ChatSessionService {
private readonly logger = new Logger(ChatSessionService.name);
// NOTE: only used for anonymous session in development
private readonly unsavedSessions = new Map<string, ChatSessionState>();

constructor(
private readonly db: PrismaClient,
private readonly prompt: PromptService
) {}

private async setSession(state: ChatSessionState): Promise<void> {
if (!state.userId && AFFiNE.featureFlags.copilotAuthorization) {
// todo(@darkskygit): allow anonymous session in development
// remove this after the feature is stable
this.unsavedSessions.set(state.sessionId, state);
return;
}
await this.db.aiSession.upsert({
where: {
id: state.sessionId,
userId: state.userId,
},
update: {
messages: {
Expand Down Expand Up @@ -193,15 +186,8 @@ export class ChatSessionService {
},
})
.then(async session => {
if (!session) {
const publishable = AFFiNE.featureFlags.copilotAuthorization;
if (publishable) {
// todo(@darkskygit): allow anonymous session in development
// remove this after the feature is stable
return this.unsavedSessions.get(sessionId);
}
return;
}
if (!session) return;

const messages = ChatMessageSchema.array().safeParse(session.messages);

return {
Expand Down Expand Up @@ -233,10 +219,6 @@ export class ChatSessionService {
workspaceId: string,
options?: { docId?: string; action?: boolean }
): Promise<number> {
// NOTE: only used for anonymous session in development
if (!userId && AFFiNE.featureFlags.copilotAuthorization) {
return this.unsavedSessions.size;
}
return await this.db.aiSession.count({
where: {
userId,
Expand All @@ -250,15 +232,10 @@ export class ChatSessionService {
}

async listSessions(
userId: string | undefined,
userId: string,
workspaceId: string,
options?: { docId?: string; action?: boolean }
): Promise<string[]> {
// NOTE: only used for anonymous session in development
if (!userId && AFFiNE.featureFlags.copilotAuthorization) {
return Array.from(this.unsavedSessions.keys());
}

return await this.db.aiSession
.findMany({
where: {
Expand All @@ -275,31 +252,11 @@ export class ChatSessionService {
}

async listHistories(
userId: string | undefined,
userId: string,
workspaceId: string,
docId?: string,
options?: ListHistoriesOptions
): Promise<ChatHistory[]> {
// NOTE: only used for anonymous session in development
if (!userId && AFFiNE.featureFlags.copilotAuthorization) {
return [...this.unsavedSessions.values()]
.map(state => {
const ret = ChatMessageSchema.array().safeParse(state.messages);
if (ret.success) {
const tokens = this.calculateTokenSize(state.messages, state.model);
return {
sessionId: state.sessionId,
action: state.action,
tokens,
messages: ret.data,
};
}
console.error('Unexpected error in listHistories', ret.error);
return undefined;
})
.filter((v): v is NonNullable<typeof v> => !!v);
}

return await this.db.aiSession
.findMany({
where: {
Expand Down
1 change: 0 additions & 1 deletion packages/backend/server/src/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ enum PublicPageMode {
type Query {
checkBlobSize(size: SafeInt!, workspaceId: String!): WorkspaceBlobSizes! @deprecated(reason: "no more needed")
collectAllBlobSizes: WorkspaceBlobSizes! @deprecated(reason: "use `user.storageUsage` instead")
copilotAnonymous(workspaceId: String!): Copilot!

"""Get current user"""
currentUser: UserType
Expand Down

This file was deleted.

This file was deleted.

36 changes: 0 additions & 36 deletions packages/frontend/graphql/src/graphql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,42 +251,6 @@ mutation removeEarlyAccess($email: String!) {
}`,
};

export const getCopilotAnonymousHistoriesQuery = {
id: 'getCopilotAnonymousHistoriesQuery' as const,
operationName: 'getCopilotAnonymousHistories',
definitionName: 'copilotAnonymous',
containsFile: false,
query: `
query getCopilotAnonymousHistories($workspaceId: String!, $docId: String, $options: QueryChatHistoriesInput) {
copilotAnonymous(workspaceId: $workspaceId) {
histories(docId: $docId, options: $options) {
sessionId
tokens
messages {
role
content
attachments
createdAt
}
}
}
}`,
};

export const getCopilotAnonymousSessionsQuery = {
id: 'getCopilotAnonymousSessionsQuery' as const,
operationName: 'getCopilotAnonymousSessions',
definitionName: 'copilotAnonymous',
containsFile: false,
query: `
query getCopilotAnonymousSessions($workspaceId: String!) {
copilotAnonymous(workspaceId: $workspaceId) {
chats
actions
}
}`,
};

export const getCopilotHistoriesQuery = {
id: 'getCopilotHistoriesQuery' as const,
operationName: 'getCopilotHistories',
Expand Down

0 comments on commit 6b552b3

Please sign in to comment.