mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-25 22:38:56 +08:00
refactor: rename all page query to doc (#10019)
This commit is contained in:
@@ -16,7 +16,7 @@ export {
|
||||
fixupDocRole,
|
||||
mapDocRoleToPermissions,
|
||||
mapWorkspaceRoleToPermissions,
|
||||
PublicPageMode,
|
||||
PublicDocMode,
|
||||
WORKSPACE_ACTIONS,
|
||||
type WorkspaceActionPermissions,
|
||||
WorkspaceRole,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import type { Prisma, WorkspacePageUserPermission } from '@prisma/client';
|
||||
import type { Prisma, WorkspaceDocUserPermission } from '@prisma/client';
|
||||
import { PrismaClient, WorkspaceMemberStatus } from '@prisma/client';
|
||||
import { groupBy } from 'lodash-es';
|
||||
|
||||
import {
|
||||
CanNotBatchGrantPageOwnerPermissions,
|
||||
CanNotBatchGrantDocOwnerPermissions,
|
||||
DocAccessDenied,
|
||||
EventBus,
|
||||
OnEvent,
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
docActionRequiredRole,
|
||||
docActionRequiredWorkspaceRole,
|
||||
DocRole,
|
||||
PublicPageMode,
|
||||
PublicDocMode,
|
||||
WorkspaceRole,
|
||||
} from './types';
|
||||
|
||||
@@ -38,10 +38,10 @@ export class PermissionService {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.prisma.workspacePageUserPermission.createMany({
|
||||
await this.prisma.workspaceDocUserPermission.createMany({
|
||||
data: {
|
||||
workspaceId,
|
||||
pageId: docId,
|
||||
docId,
|
||||
userId: editor,
|
||||
type: DocRole.Owner,
|
||||
createdAt: new Date(),
|
||||
@@ -172,7 +172,7 @@ export class PermissionService {
|
||||
// if workspace is public or have any public page, then allow to access
|
||||
const [isPublicWorkspace, publicPages] = await Promise.all([
|
||||
this.tryCheckWorkspace(ws, user, WorkspaceRole.Collaborator),
|
||||
this.prisma.workspacePage.count({
|
||||
this.prisma.workspaceDoc.count({
|
||||
where: {
|
||||
workspaceId: ws,
|
||||
public: true,
|
||||
@@ -555,17 +555,17 @@ export class PermissionService {
|
||||
|
||||
async tryCheckPage(
|
||||
ws: string,
|
||||
page: string,
|
||||
doc: string,
|
||||
action: DocAction,
|
||||
user?: string
|
||||
) {
|
||||
const role = docActionRequiredRole(action);
|
||||
// check whether page is public
|
||||
if (action === 'Doc.Read') {
|
||||
const count = await this.prisma.workspacePage.count({
|
||||
const count = await this.prisma.workspaceDoc.count({
|
||||
where: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
public: true,
|
||||
},
|
||||
});
|
||||
@@ -579,20 +579,20 @@ export class PermissionService {
|
||||
|
||||
if (user) {
|
||||
const [roleEntity, pageEntity, workspaceRoleEntity] = await Promise.all([
|
||||
this.prisma.workspacePageUserPermission.findFirst({
|
||||
this.prisma.workspaceDocUserPermission.findFirst({
|
||||
where: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
userId: user,
|
||||
},
|
||||
select: {
|
||||
type: true,
|
||||
},
|
||||
}),
|
||||
this.prisma.workspacePage.findFirst({
|
||||
this.prisma.workspaceDoc.findFirst({
|
||||
where: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
},
|
||||
select: {
|
||||
defaultRole: true,
|
||||
@@ -629,7 +629,7 @@ export class PermissionService {
|
||||
}
|
||||
this.logger.log("User's role is lower than required", {
|
||||
workspaceId: ws,
|
||||
docId: page,
|
||||
docId: doc,
|
||||
userId: user,
|
||||
workspaceRole: workspaceRoleEntity
|
||||
? WorkspaceRole[workspaceRoleEntity.type]
|
||||
@@ -651,24 +651,24 @@ export class PermissionService {
|
||||
);
|
||||
}
|
||||
|
||||
async isPublicPage(ws: string, page: string) {
|
||||
return this.prisma.workspacePage
|
||||
async isPublicPage(ws: string, doc: string) {
|
||||
return this.prisma.workspaceDoc
|
||||
.count({
|
||||
where: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
public: true,
|
||||
},
|
||||
})
|
||||
.then(count => count > 0);
|
||||
}
|
||||
|
||||
async publishPage(ws: string, page: string, mode = PublicPageMode.Page) {
|
||||
return this.prisma.workspacePage.upsert({
|
||||
async publishPage(ws: string, doc: string, mode = PublicDocMode.Page) {
|
||||
return this.prisma.workspaceDoc.upsert({
|
||||
where: {
|
||||
workspaceId_pageId: {
|
||||
workspaceId_docId: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
@@ -677,19 +677,19 @@ export class PermissionService {
|
||||
},
|
||||
create: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
mode,
|
||||
public: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async revokePublicPage(ws: string, page: string) {
|
||||
return this.prisma.workspacePage.upsert({
|
||||
async revokePublicPage(ws: string, doc: string) {
|
||||
return this.prisma.workspaceDoc.upsert({
|
||||
where: {
|
||||
workspaceId_pageId: {
|
||||
workspaceId_docId: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
@@ -697,20 +697,20 @@ export class PermissionService {
|
||||
},
|
||||
create: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
public: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async grantPage(ws: string, page: string, user: string, permission: DocRole) {
|
||||
async grantPage(ws: string, doc: string, user: string, permission: DocRole) {
|
||||
const [p] = await this.prisma.$transaction(
|
||||
[
|
||||
this.prisma.workspacePageUserPermission.upsert({
|
||||
this.prisma.workspaceDocUserPermission.upsert({
|
||||
where: {
|
||||
workspaceId_pageId_userId: {
|
||||
workspaceId_docId_userId: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
userId: user,
|
||||
},
|
||||
},
|
||||
@@ -719,7 +719,7 @@ export class PermissionService {
|
||||
},
|
||||
create: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
userId: user,
|
||||
type: permission,
|
||||
},
|
||||
@@ -727,10 +727,10 @@ export class PermissionService {
|
||||
|
||||
// If the new permission is owner, we need to revoke old owner
|
||||
permission === DocRole.Owner
|
||||
? this.prisma.workspacePageUserPermission.updateMany({
|
||||
? this.prisma.workspaceDocUserPermission.updateMany({
|
||||
where: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
type: DocRole.Owner,
|
||||
userId: {
|
||||
not: user,
|
||||
@@ -744,14 +744,14 @@ export class PermissionService {
|
||||
].filter(Boolean) as Prisma.PrismaPromise<any>[]
|
||||
);
|
||||
|
||||
return p as WorkspacePageUserPermission;
|
||||
return p as WorkspaceDocUserPermission;
|
||||
}
|
||||
|
||||
async revokePage(ws: string, page: string, user: string) {
|
||||
const result = await this.prisma.workspacePageUserPermission.deleteMany({
|
||||
async revokePage(ws: string, doc: string, user: string) {
|
||||
const result = await this.prisma.workspaceDocUserPermission.deleteMany({
|
||||
where: {
|
||||
workspaceId: ws,
|
||||
pageId: page,
|
||||
docId: doc,
|
||||
userId: user,
|
||||
type: {
|
||||
// We shouldn't revoke owner permission, should auto deleted by workspace/user delete cascading
|
||||
@@ -765,7 +765,7 @@ export class PermissionService {
|
||||
|
||||
async batchGrantPage(
|
||||
workspaceId: string,
|
||||
pageId: string,
|
||||
docId: string,
|
||||
userIds: string[],
|
||||
role: DocRole
|
||||
) {
|
||||
@@ -774,14 +774,14 @@ export class PermissionService {
|
||||
}
|
||||
|
||||
if (role === DocRole.Owner) {
|
||||
throw new CanNotBatchGrantPageOwnerPermissions();
|
||||
throw new CanNotBatchGrantDocOwnerPermissions();
|
||||
}
|
||||
|
||||
const result = await this.prisma.workspacePageUserPermission.createMany({
|
||||
const result = await this.prisma.workspaceDocUserPermission.createMany({
|
||||
skipDuplicates: true,
|
||||
data: userIds.map(id => ({
|
||||
workspaceId,
|
||||
pageId,
|
||||
docId,
|
||||
userId: id,
|
||||
type: role,
|
||||
})),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { LeafPaths, LeafVisitor } from '../../base';
|
||||
|
||||
export enum PublicPageMode {
|
||||
export enum PublicDocMode {
|
||||
Page,
|
||||
Edgeless,
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
} from '../../base';
|
||||
import { CurrentUser, Public } from '../auth';
|
||||
import { PgWorkspaceDocStorageAdapter } from '../doc';
|
||||
import { PermissionService, PublicPageMode } from '../permission';
|
||||
import { PermissionService, PublicDocMode } from '../permission';
|
||||
import { WorkspaceBlobStorage } from '../storage';
|
||||
import { DocID } from '../utils/doc';
|
||||
|
||||
@@ -109,16 +109,16 @@ export class WorkspacesController {
|
||||
|
||||
if (!docId.isWorkspace) {
|
||||
// fetch the publish page mode for publish page
|
||||
const publishPage = await this.prisma.workspacePage.findUnique({
|
||||
const publishPage = await this.prisma.workspaceDoc.findUnique({
|
||||
where: {
|
||||
workspaceId_pageId: {
|
||||
workspaceId_docId: {
|
||||
workspaceId: docId.workspace,
|
||||
pageId: docId.guid,
|
||||
docId: docId.guid,
|
||||
},
|
||||
},
|
||||
});
|
||||
const publishPageMode =
|
||||
publishPage?.mode === PublicPageMode.Edgeless ? 'edgeless' : 'page';
|
||||
publishPage?.mode === PublicDocMode.Edgeless ? 'edgeless' : 'page';
|
||||
|
||||
res.setHeader('publish-mode', publishPageMode);
|
||||
}
|
||||
|
||||
@@ -10,9 +10,10 @@ import { UserModule } from '../user';
|
||||
import { WorkspacesController } from './controller';
|
||||
import {
|
||||
DocHistoryResolver,
|
||||
PagePermissionResolver,
|
||||
DocResolver,
|
||||
TeamWorkspaceResolver,
|
||||
WorkspaceBlobResolver,
|
||||
WorkspaceDocResolver,
|
||||
WorkspaceResolver,
|
||||
WorkspaceService,
|
||||
} from './resolvers';
|
||||
@@ -31,7 +32,8 @@ import {
|
||||
providers: [
|
||||
WorkspaceResolver,
|
||||
TeamWorkspaceResolver,
|
||||
PagePermissionResolver,
|
||||
WorkspaceDocResolver,
|
||||
DocResolver,
|
||||
DocHistoryResolver,
|
||||
WorkspaceBlobResolver,
|
||||
WorkspaceService,
|
||||
|
||||
+245
-234
@@ -10,18 +10,18 @@ import {
|
||||
ResolveField,
|
||||
Resolver,
|
||||
} from '@nestjs/graphql';
|
||||
import type { WorkspacePage as PrismaWorkspacePage } from '@prisma/client';
|
||||
import type { WorkspaceDoc as PrismaWorkspaceDoc } from '@prisma/client';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
import {
|
||||
DocAccessDenied,
|
||||
DocDefaultRoleCanNotBeOwner,
|
||||
DocIsNotPublic,
|
||||
ExpectToGrantDocUserRoles,
|
||||
ExpectToPublishPage,
|
||||
ExpectToPublishDoc,
|
||||
ExpectToRevokeDocUserRoles,
|
||||
ExpectToRevokePublicPage,
|
||||
ExpectToRevokePublicDoc,
|
||||
ExpectToUpdateDocUserRole,
|
||||
PageDefaultRoleCanNotBeOwner,
|
||||
PageIsNotPublic,
|
||||
paginate,
|
||||
Paginated,
|
||||
PaginationInput,
|
||||
@@ -36,27 +36,27 @@ import {
|
||||
fixupDocRole,
|
||||
mapDocRoleToPermissions,
|
||||
PermissionService,
|
||||
PublicPageMode,
|
||||
PublicDocMode,
|
||||
} from '../../permission';
|
||||
import { PublicUserType } from '../../user';
|
||||
import { DocID } from '../../utils/doc';
|
||||
import { WorkspaceType } from '../types';
|
||||
|
||||
registerEnumType(PublicPageMode, {
|
||||
name: 'PublicPageMode',
|
||||
description: 'The mode which the public page default in',
|
||||
registerEnumType(PublicDocMode, {
|
||||
name: 'PublicDocMode',
|
||||
description: 'The mode which the public doc default in',
|
||||
});
|
||||
|
||||
@ObjectType()
|
||||
class WorkspacePage implements Partial<PrismaWorkspacePage> {
|
||||
class DocType implements Partial<PrismaWorkspaceDoc> {
|
||||
@Field(() => String, { name: 'id' })
|
||||
pageId!: string;
|
||||
docId!: string;
|
||||
|
||||
@Field()
|
||||
workspaceId!: string;
|
||||
|
||||
@Field(() => PublicPageMode)
|
||||
mode!: PublicPageMode;
|
||||
@Field(() => PublicDocMode)
|
||||
mode!: PublicDocMode;
|
||||
|
||||
@Field()
|
||||
public!: boolean;
|
||||
@@ -105,7 +105,7 @@ class RevokeDocUserRoleInput {
|
||||
}
|
||||
|
||||
@InputType()
|
||||
class UpdatePageDefaultRoleInput {
|
||||
class UpdateDocDefaultRoleInput {
|
||||
@Field(() => String)
|
||||
docId!: string;
|
||||
|
||||
@@ -144,13 +144,7 @@ const DocPermissions = registerObjectType<DocActionPermissions>(
|
||||
);
|
||||
|
||||
@ObjectType()
|
||||
class DocType {
|
||||
@Field(() => String)
|
||||
id!: string;
|
||||
|
||||
@Field(() => Boolean)
|
||||
public!: boolean;
|
||||
|
||||
export class DocRolePermissions {
|
||||
@Field(() => DocRole)
|
||||
role!: DocRole;
|
||||
|
||||
@@ -159,8 +153,207 @@ class DocType {
|
||||
}
|
||||
|
||||
@Resolver(() => WorkspaceType)
|
||||
export class PagePermissionResolver {
|
||||
private readonly logger = new Logger(PagePermissionResolver.name);
|
||||
export class WorkspaceDocResolver {
|
||||
private readonly logger = new Logger(WorkspaceDocResolver.name);
|
||||
|
||||
constructor(
|
||||
private readonly prisma: PrismaClient,
|
||||
private readonly permission: PermissionService
|
||||
) {}
|
||||
|
||||
@ResolveField(() => [DocType], {
|
||||
complexity: 2,
|
||||
deprecationReason: 'use [WorkspaceType.publicDocs] instead',
|
||||
})
|
||||
async publicPages(@Parent() workspace: WorkspaceType) {
|
||||
return this.publicDocs(workspace);
|
||||
}
|
||||
|
||||
@ResolveField(() => [DocType], {
|
||||
description: 'Get public docs of a workspace',
|
||||
complexity: 2,
|
||||
})
|
||||
async publicDocs(@Parent() workspace: WorkspaceType) {
|
||||
return this.prisma.workspaceDoc.findMany({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
public: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ResolveField(() => DocType, {
|
||||
description: 'Get public page of a workspace by page id.',
|
||||
complexity: 2,
|
||||
nullable: true,
|
||||
deprecationReason: 'use [WorkspaceType.publicDoc] instead',
|
||||
})
|
||||
async publicPage(
|
||||
@Parent() workspace: WorkspaceType,
|
||||
@Args('pageId') pageId: string
|
||||
) {
|
||||
return this.publicDoc(workspace, pageId);
|
||||
}
|
||||
|
||||
@ResolveField(() => DocType, {
|
||||
description: 'Get public page of a workspace by page id.',
|
||||
complexity: 2,
|
||||
nullable: true,
|
||||
})
|
||||
async publicDoc(
|
||||
@Parent() workspace: WorkspaceType,
|
||||
@Args('docId') docId: string
|
||||
) {
|
||||
return this.prisma.workspaceDoc.findFirst({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
docId,
|
||||
public: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ResolveField(() => DocType, {
|
||||
description: 'Get get with given id',
|
||||
complexity: 2,
|
||||
})
|
||||
async doc(
|
||||
@Parent() workspace: WorkspaceType,
|
||||
@Args('docId') docId: string
|
||||
): Promise<DocType> {
|
||||
const doc = await this.prisma.workspaceDoc.findFirst({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
docId,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
doc ?? {
|
||||
docId,
|
||||
workspaceId: workspace.id,
|
||||
public: false,
|
||||
mode: PublicDocMode.Page,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Mutation(() => DocType, {
|
||||
deprecationReason: 'use publishDoc instead',
|
||||
})
|
||||
async publishPage(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('workspaceId') workspaceId: string,
|
||||
@Args('pageId') pageId: string,
|
||||
@Args({
|
||||
name: 'mode',
|
||||
type: () => PublicDocMode,
|
||||
nullable: true,
|
||||
defaultValue: PublicDocMode.Page,
|
||||
})
|
||||
mode: PublicDocMode
|
||||
) {
|
||||
return this.publishDoc(user, workspaceId, pageId, mode);
|
||||
}
|
||||
|
||||
@Mutation(() => DocType)
|
||||
async publishDoc(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('workspaceId') workspaceId: string,
|
||||
@Args('docId') rawDocId: string,
|
||||
@Args({
|
||||
name: 'mode',
|
||||
type: () => PublicDocMode,
|
||||
nullable: true,
|
||||
defaultValue: PublicDocMode.Page,
|
||||
})
|
||||
mode: PublicDocMode
|
||||
) {
|
||||
const docId = new DocID(rawDocId, workspaceId);
|
||||
|
||||
if (docId.isWorkspace) {
|
||||
this.logger.error('Expect to publish doc, but it is a workspace', {
|
||||
workspaceId,
|
||||
docId: rawDocId,
|
||||
});
|
||||
throw new ExpectToPublishDoc();
|
||||
}
|
||||
|
||||
await this.permission.checkPagePermission(
|
||||
docId.workspace,
|
||||
docId.guid,
|
||||
'Doc.Publish',
|
||||
user.id
|
||||
);
|
||||
|
||||
this.logger.log('Publish page', {
|
||||
workspaceId,
|
||||
docId: rawDocId,
|
||||
mode,
|
||||
});
|
||||
|
||||
return this.permission.publishPage(docId.workspace, docId.guid, mode);
|
||||
}
|
||||
|
||||
@Mutation(() => DocType, {
|
||||
deprecationReason: 'use revokePublicDoc instead',
|
||||
})
|
||||
async revokePublicPage(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('workspaceId') workspaceId: string,
|
||||
@Args('docId') docId: string
|
||||
) {
|
||||
return this.revokePublicDoc(user, workspaceId, docId);
|
||||
}
|
||||
|
||||
@Mutation(() => DocType)
|
||||
async revokePublicDoc(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('workspaceId') workspaceId: string,
|
||||
@Args('docId') rawDocId: string
|
||||
) {
|
||||
const docId = new DocID(rawDocId, workspaceId);
|
||||
|
||||
if (docId.isWorkspace) {
|
||||
this.logger.error('Expect to revoke public doc, but it is a workspace', {
|
||||
workspaceId,
|
||||
docId: rawDocId,
|
||||
});
|
||||
throw new ExpectToRevokePublicDoc('Expect doc not to be workspace');
|
||||
}
|
||||
|
||||
await this.permission.checkPagePermission(
|
||||
docId.workspace,
|
||||
docId.guid,
|
||||
'Doc.Publish',
|
||||
user.id
|
||||
);
|
||||
|
||||
const isPublic = await this.permission.isPublicPage(
|
||||
docId.workspace,
|
||||
docId.guid
|
||||
);
|
||||
|
||||
if (!isPublic) {
|
||||
this.logger.log('Expect to revoke public doc, but it is not public', {
|
||||
workspaceId,
|
||||
docId: rawDocId,
|
||||
});
|
||||
throw new DocIsNotPublic('Doc is not public');
|
||||
}
|
||||
|
||||
this.logger.log('Revoke public doc', {
|
||||
workspaceId,
|
||||
docId: rawDocId,
|
||||
});
|
||||
|
||||
return this.permission.revokePublicPage(docId.workspace, docId.guid);
|
||||
}
|
||||
}
|
||||
|
||||
@Resolver(() => DocType)
|
||||
export class DocResolver {
|
||||
private readonly logger = new Logger(DocResolver.name);
|
||||
|
||||
constructor(
|
||||
private readonly prisma: PrismaClient,
|
||||
@@ -168,96 +361,31 @@ export class PagePermissionResolver {
|
||||
private readonly models: Models
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@ResolveField(() => [String], {
|
||||
description: 'Shared pages of workspace',
|
||||
complexity: 2,
|
||||
deprecationReason: 'use WorkspaceType.publicPages',
|
||||
})
|
||||
async sharedPages(@Parent() workspace: WorkspaceType) {
|
||||
const data = await this.prisma.workspacePage.findMany({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
public: true,
|
||||
},
|
||||
});
|
||||
|
||||
return data.map(row => row.pageId);
|
||||
}
|
||||
|
||||
@ResolveField(() => [WorkspacePage], {
|
||||
description: 'Public pages of a workspace',
|
||||
complexity: 2,
|
||||
})
|
||||
async publicPages(@Parent() workspace: WorkspaceType) {
|
||||
return this.prisma.workspacePage.findMany({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
public: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ResolveField(() => WorkspacePage, {
|
||||
description: 'Get public page of a workspace by page id.',
|
||||
complexity: 2,
|
||||
nullable: true,
|
||||
})
|
||||
async publicPage(
|
||||
@Parent() workspace: WorkspaceType,
|
||||
@Args('pageId') pageId: string
|
||||
) {
|
||||
return this.prisma.workspacePage.findFirst({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
pageId,
|
||||
public: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ResolveField(() => DocType, {
|
||||
description: 'Check if current user has permission to access the page',
|
||||
complexity: 2,
|
||||
})
|
||||
async pagePermission(
|
||||
@Parent() workspace: WorkspaceType,
|
||||
@Args('pageId') pageId: string,
|
||||
@CurrentUser() user: CurrentUser
|
||||
): Promise<DocType> {
|
||||
const page = await this.prisma.workspacePage.findFirst({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
pageId,
|
||||
},
|
||||
select: {
|
||||
public: true,
|
||||
},
|
||||
});
|
||||
|
||||
@ResolveField(() => DocPermissions)
|
||||
async permissions(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Parent() doc: DocType
|
||||
): Promise<DocRolePermissions> {
|
||||
const [permission, workspacePermission] = await this.prisma.$transaction(
|
||||
tx =>
|
||||
Promise.all([
|
||||
tx.workspacePageUserPermission.findFirst({
|
||||
tx.workspaceDocUserPermission.findFirst({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
pageId,
|
||||
workspaceId: doc.workspaceId,
|
||||
docId: doc.docId,
|
||||
userId: user.id,
|
||||
},
|
||||
}),
|
||||
tx.workspaceUserPermission.findFirst({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
workspaceId: doc.workspaceId,
|
||||
userId: user.id,
|
||||
},
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
return {
|
||||
id: pageId,
|
||||
public: page?.public ?? false,
|
||||
role: permission?.type ?? DocRole.External,
|
||||
permissions: mapDocRoleToPermissions(
|
||||
fixupDocRole(workspacePermission?.type, permission?.type)
|
||||
@@ -266,29 +394,27 @@ export class PagePermissionResolver {
|
||||
}
|
||||
|
||||
@ResolveField(() => PaginatedGrantedDocUserType, {
|
||||
description: 'Page granted users list',
|
||||
description: 'paginated doc granted users list',
|
||||
complexity: 4,
|
||||
})
|
||||
async pageGrantedUsersList(
|
||||
async grantedUsersList(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Parent() workspace: WorkspaceType,
|
||||
@Args('pageId') pageId: string,
|
||||
@Parent() doc: DocType,
|
||||
@Args('pagination') pagination: PaginationInput
|
||||
): Promise<PaginatedGrantedDocUserType> {
|
||||
await this.permission.checkPagePermission(
|
||||
workspace.id,
|
||||
pageId,
|
||||
doc.workspaceId,
|
||||
doc.docId,
|
||||
'Doc.Users.Read',
|
||||
user.id
|
||||
);
|
||||
|
||||
const docId = new DocID(pageId, workspace.id);
|
||||
const [permissions, totalCount] = await this.prisma.$transaction(tx => {
|
||||
return Promise.all([
|
||||
tx.workspacePageUserPermission.findMany({
|
||||
tx.workspaceDocUserPermission.findMany({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
pageId: docId.guid,
|
||||
workspaceId: doc.workspaceId,
|
||||
docId: doc.docId,
|
||||
createdAt: pagination.after
|
||||
? {
|
||||
gt: pagination.after,
|
||||
@@ -306,10 +432,10 @@ export class PagePermissionResolver {
|
||||
take: pagination.first,
|
||||
skip: pagination.offset,
|
||||
}),
|
||||
tx.workspacePageUserPermission.count({
|
||||
tx.workspaceDocUserPermission.count({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
pageId: docId.guid,
|
||||
workspaceId: doc.workspaceId,
|
||||
docId: doc.docId,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
@@ -338,121 +464,6 @@ export class PagePermissionResolver {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@Mutation(() => Boolean, {
|
||||
name: 'sharePage',
|
||||
deprecationReason: 'renamed to publishPage',
|
||||
})
|
||||
async deprecatedSharePage(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('workspaceId') workspaceId: string,
|
||||
@Args('pageId') pageId: string
|
||||
) {
|
||||
await this.publishPage(user, workspaceId, pageId, PublicPageMode.Page);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Mutation(() => WorkspacePage)
|
||||
async publishPage(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('workspaceId') workspaceId: string,
|
||||
@Args('pageId') pageId: string,
|
||||
@Args({
|
||||
name: 'mode',
|
||||
type: () => PublicPageMode,
|
||||
nullable: true,
|
||||
defaultValue: PublicPageMode.Page,
|
||||
})
|
||||
mode: PublicPageMode
|
||||
) {
|
||||
const docId = new DocID(pageId, workspaceId);
|
||||
|
||||
if (docId.isWorkspace) {
|
||||
this.logger.error('Expect to publish page, but it is a workspace', {
|
||||
workspaceId,
|
||||
pageId,
|
||||
});
|
||||
throw new ExpectToPublishPage();
|
||||
}
|
||||
|
||||
await this.permission.checkPagePermission(
|
||||
docId.workspace,
|
||||
docId.guid,
|
||||
'Doc.Publish',
|
||||
user.id
|
||||
);
|
||||
|
||||
this.logger.log('Publish page', {
|
||||
workspaceId,
|
||||
pageId,
|
||||
mode,
|
||||
});
|
||||
|
||||
return this.permission.publishPage(docId.workspace, docId.guid, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@Mutation(() => Boolean, {
|
||||
name: 'revokePage',
|
||||
deprecationReason: 'use revokePublicPage',
|
||||
})
|
||||
async deprecatedRevokePage(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('workspaceId') workspaceId: string,
|
||||
@Args('pageId') pageId: string
|
||||
) {
|
||||
await this.revokePublicPage(user, workspaceId, pageId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Mutation(() => WorkspacePage)
|
||||
async revokePublicPage(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('workspaceId') workspaceId: string,
|
||||
@Args('pageId') pageId: string
|
||||
) {
|
||||
const docId = new DocID(pageId, workspaceId);
|
||||
|
||||
if (docId.isWorkspace) {
|
||||
this.logger.error('Expect to revoke public page, but it is a workspace', {
|
||||
workspaceId,
|
||||
pageId,
|
||||
});
|
||||
throw new ExpectToRevokePublicPage('Expect page not to be workspace');
|
||||
}
|
||||
|
||||
await this.permission.checkPagePermission(
|
||||
docId.workspace,
|
||||
docId.guid,
|
||||
'Doc.Publish',
|
||||
user.id
|
||||
);
|
||||
|
||||
const isPublic = await this.permission.isPublicPage(
|
||||
docId.workspace,
|
||||
docId.guid
|
||||
);
|
||||
|
||||
if (!isPublic) {
|
||||
this.logger.log('Expect to revoke public page, but it is not public', {
|
||||
workspaceId,
|
||||
pageId,
|
||||
});
|
||||
throw new PageIsNotPublic('Page is not public');
|
||||
}
|
||||
|
||||
this.logger.log('Revoke public page', {
|
||||
workspaceId,
|
||||
pageId,
|
||||
});
|
||||
|
||||
return this.permission.revokePublicPage(docId.workspace, docId.guid);
|
||||
}
|
||||
|
||||
@Mutation(() => Boolean)
|
||||
async grantDocUserRoles(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@@ -580,13 +591,13 @@ export class PagePermissionResolver {
|
||||
}
|
||||
|
||||
@Mutation(() => Boolean)
|
||||
async updatePageDefaultRole(
|
||||
async updateDocDefaultRole(
|
||||
@CurrentUser() user: CurrentUser,
|
||||
@Args('input') input: UpdatePageDefaultRoleInput
|
||||
@Args('input') input: UpdateDocDefaultRoleInput
|
||||
) {
|
||||
if (input.role === DocRole.Owner) {
|
||||
this.logger.log('Page default role can not be owner', input);
|
||||
throw new PageDefaultRoleCanNotBeOwner();
|
||||
this.logger.log('Doc default role can not be owner', input);
|
||||
throw new DocDefaultRoleCanNotBeOwner();
|
||||
}
|
||||
const doc = new DocID(input.docId, input.workspaceId);
|
||||
const pairs = {
|
||||
@@ -622,11 +633,11 @@ export class PagePermissionResolver {
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
await this.prisma.workspacePage.upsert({
|
||||
await this.prisma.workspaceDoc.upsert({
|
||||
where: {
|
||||
workspaceId_pageId: {
|
||||
workspaceId_docId: {
|
||||
workspaceId: doc.workspace,
|
||||
pageId: doc.guid,
|
||||
docId: doc.guid,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
@@ -634,7 +645,7 @@ export class PagePermissionResolver {
|
||||
},
|
||||
create: {
|
||||
workspaceId: doc.workspace,
|
||||
pageId: doc.guid,
|
||||
docId: doc.guid,
|
||||
defaultRole: input.role,
|
||||
},
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
export * from './blob';
|
||||
export * from './doc';
|
||||
export * from './history';
|
||||
export * from './page';
|
||||
export * from './service';
|
||||
export * from './team';
|
||||
export * from './workspace';
|
||||
|
||||
Reference in New Issue
Block a user