refactor: rename all page query to doc (#10019)
This commit is contained in:
@@ -25,16 +25,16 @@ model User {
|
|||||||
features UserFeature[]
|
features UserFeature[]
|
||||||
userStripeCustomer UserStripeCustomer?
|
userStripeCustomer UserStripeCustomer?
|
||||||
workspacePermissions WorkspaceUserPermission[]
|
workspacePermissions WorkspaceUserPermission[]
|
||||||
pagePermissions WorkspacePageUserPermission[]
|
docPermissions WorkspaceDocUserPermission[]
|
||||||
connectedAccounts ConnectedAccount[]
|
connectedAccounts ConnectedAccount[]
|
||||||
sessions UserSession[]
|
sessions UserSession[]
|
||||||
aiSessions AiSession[]
|
aiSessions AiSession[]
|
||||||
updatedRuntimeConfigs RuntimeConfig[]
|
updatedRuntimeConfigs RuntimeConfig[]
|
||||||
userSnapshots UserSnapshot[]
|
userSnapshots UserSnapshot[]
|
||||||
createdSnapshot Snapshot[] @relation("createdSnapshot")
|
createdSnapshot Snapshot[] @relation("createdSnapshot")
|
||||||
updatedSnapshot Snapshot[] @relation("updatedSnapshot")
|
updatedSnapshot Snapshot[] @relation("updatedSnapshot")
|
||||||
createdUpdate Update[] @relation("createdUpdate")
|
createdUpdate Update[] @relation("createdUpdate")
|
||||||
createdHistory SnapshotHistory[] @relation("createdHistory")
|
createdHistory SnapshotHistory[] @relation("createdHistory")
|
||||||
|
|
||||||
@@index([email])
|
@@index([email])
|
||||||
@@map("users")
|
@@map("users")
|
||||||
@@ -102,11 +102,11 @@ model Workspace {
|
|||||||
enableAi Boolean @default(true) @map("enable_ai")
|
enableAi Boolean @default(true) @map("enable_ai")
|
||||||
enableUrlPreview Boolean @default(false) @map("enable_url_preview")
|
enableUrlPreview Boolean @default(false) @map("enable_url_preview")
|
||||||
|
|
||||||
features WorkspaceFeature[]
|
features WorkspaceFeature[]
|
||||||
pages WorkspacePage[]
|
docs WorkspaceDoc[]
|
||||||
permissions WorkspaceUserPermission[]
|
permissions WorkspaceUserPermission[]
|
||||||
pagePermissions WorkspacePageUserPermission[]
|
docPermissions WorkspaceDocUserPermission[]
|
||||||
blobs Blob[]
|
blobs Blob[]
|
||||||
|
|
||||||
@@map("workspaces")
|
@@map("workspaces")
|
||||||
}
|
}
|
||||||
@@ -116,18 +116,18 @@ model Workspace {
|
|||||||
// We won't make sure every page has a corresponding record in this table.
|
// We won't make sure every page has a corresponding record in this table.
|
||||||
// Only the ones that have ever changed will have records here,
|
// Only the ones that have ever changed will have records here,
|
||||||
// and for others we will make sure it's has a default value return in our business logic.
|
// and for others we will make sure it's has a default value return in our business logic.
|
||||||
model WorkspacePage {
|
model WorkspaceDoc {
|
||||||
workspaceId String @map("workspace_id") @db.VarChar
|
workspaceId String @map("workspace_id") @db.VarChar
|
||||||
pageId String @map("page_id") @db.VarChar
|
docId String @map("page_id") @db.VarChar
|
||||||
public Boolean @default(false)
|
public Boolean @default(false)
|
||||||
// Workspace user's default role in this page, default is `Manager`
|
// Workspace user's default role in this page, default is `Manager`
|
||||||
defaultRole Int @default(30) @db.SmallInt
|
defaultRole Int @default(30) @db.SmallInt
|
||||||
// Page/Edgeless
|
// Page/Edgeless
|
||||||
mode Int @default(0) @db.SmallInt
|
mode Int @default(0) @db.SmallInt
|
||||||
|
|
||||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
@@id([workspaceId, pageId])
|
@@id([workspaceId, docId])
|
||||||
@@map("workspace_pages")
|
@@map("workspace_pages")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,9 +162,9 @@ model WorkspaceUserPermission {
|
|||||||
@@map("workspace_user_permissions")
|
@@map("workspace_user_permissions")
|
||||||
}
|
}
|
||||||
|
|
||||||
model WorkspacePageUserPermission {
|
model WorkspaceDocUserPermission {
|
||||||
workspaceId String @map("workspace_id") @db.VarChar
|
workspaceId String @map("workspace_id") @db.VarChar
|
||||||
pageId String @map("page_id") @db.VarChar
|
docId String @map("page_id") @db.VarChar
|
||||||
userId String @map("user_id") @db.VarChar
|
userId String @map("user_id") @db.VarChar
|
||||||
// External/Reader/Editor/Manager/Owner
|
// External/Reader/Editor/Manager/Owner
|
||||||
type Int @db.SmallInt
|
type Int @db.SmallInt
|
||||||
@@ -173,7 +173,7 @@ model WorkspacePageUserPermission {
|
|||||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
@@id([workspaceId, pageId, userId])
|
@@id([workspaceId, docId, userId])
|
||||||
@@map("workspace_page_user_permissions")
|
@@map("workspace_page_user_permissions")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ test.after(async t => {
|
|||||||
test('should create page with default mode and public false', async t => {
|
test('should create page with default mode and public false', async t => {
|
||||||
const page = await t.context.page.upsert(workspace.id, 'page1');
|
const page = await t.context.page.upsert(workspace.id, 'page1');
|
||||||
t.is(page.workspaceId, workspace.id);
|
t.is(page.workspaceId, workspace.id);
|
||||||
t.is(page.pageId, 'page1');
|
t.is(page.docId, 'page1');
|
||||||
t.is(page.mode, PublicPageMode.Page);
|
t.is(page.mode, PublicPageMode.Page);
|
||||||
t.is(page.public, false);
|
t.is(page.public, false);
|
||||||
});
|
});
|
||||||
@@ -110,7 +110,7 @@ test('should get public pages of a workspace', async t => {
|
|||||||
await t.context.page.upsert(workspace.id, 'page3');
|
await t.context.page.upsert(workspace.id, 'page3');
|
||||||
const pages = await t.context.page.findPublics(workspace.id);
|
const pages = await t.context.page.findPublics(workspace.id);
|
||||||
t.is(pages.length, 2);
|
t.is(pages.length, 2);
|
||||||
t.deepEqual(pages.map(p => p.pageId).sort(), ['page1', 'page2']);
|
t.deepEqual(pages.map(p => p.docId).sort(), ['page1', 'page2']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should grant a member to access a page', async t => {
|
test('should grant a member to access a page', async t => {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
createInviteLink,
|
createInviteLink,
|
||||||
createTestingApp,
|
createTestingApp,
|
||||||
createWorkspace,
|
createWorkspace,
|
||||||
|
docGrantedUsersList,
|
||||||
getInviteInfo,
|
getInviteInfo,
|
||||||
getInviteLink,
|
getInviteLink,
|
||||||
getWorkspace,
|
getWorkspace,
|
||||||
@@ -31,7 +32,6 @@ import {
|
|||||||
inviteUser,
|
inviteUser,
|
||||||
inviteUsers,
|
inviteUsers,
|
||||||
leaveWorkspace,
|
leaveWorkspace,
|
||||||
pageGrantedUsersList,
|
|
||||||
revokeDocUserRoles,
|
revokeDocUserRoles,
|
||||||
revokeInviteLink,
|
revokeInviteLink,
|
||||||
revokeMember,
|
revokeMember,
|
||||||
@@ -39,7 +39,7 @@ import {
|
|||||||
signUp,
|
signUp,
|
||||||
sleep,
|
sleep,
|
||||||
TestingApp,
|
TestingApp,
|
||||||
updatePageDefaultRole,
|
updateDocDefaultRole,
|
||||||
UserAuthedType,
|
UserAuthedType,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
@@ -817,13 +817,13 @@ test('should be able to grant and revoke users role in page', async t => {
|
|||||||
read,
|
read,
|
||||||
external,
|
external,
|
||||||
} = await init(app, 5);
|
} = await init(app, 5);
|
||||||
const pageId = nanoid();
|
const docId = nanoid();
|
||||||
|
|
||||||
const res = await grantDocUserRoles(
|
const res = await grantDocUserRoles(
|
||||||
app,
|
app,
|
||||||
admin.token.token,
|
admin.token.token,
|
||||||
ws.id,
|
ws.id,
|
||||||
pageId,
|
docId,
|
||||||
[read.id, write.id],
|
[read.id, write.id],
|
||||||
DocRole.Manager
|
DocRole.Manager
|
||||||
);
|
);
|
||||||
@@ -840,7 +840,7 @@ test('should be able to grant and revoke users role in page', async t => {
|
|||||||
app,
|
app,
|
||||||
admin.token.token,
|
admin.token.token,
|
||||||
ws.id,
|
ws.id,
|
||||||
pageId,
|
docId,
|
||||||
[read.id],
|
[read.id],
|
||||||
DocRole.Reader
|
DocRole.Reader
|
||||||
);
|
);
|
||||||
@@ -849,7 +849,7 @@ test('should be able to grant and revoke users role in page', async t => {
|
|||||||
app,
|
app,
|
||||||
read.token.token,
|
read.token.token,
|
||||||
ws.id,
|
ws.id,
|
||||||
pageId,
|
docId,
|
||||||
[external.id],
|
[external.id],
|
||||||
DocRole.Editor
|
DocRole.Editor
|
||||||
);
|
);
|
||||||
@@ -859,15 +859,15 @@ test('should be able to grant and revoke users role in page', async t => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const pageUsersList = await pageGrantedUsersList(
|
const docUsersList = await docGrantedUsersList(
|
||||||
app,
|
app,
|
||||||
admin.token.token,
|
admin.token.token,
|
||||||
ws.id,
|
ws.id,
|
||||||
pageId
|
docId
|
||||||
);
|
);
|
||||||
t.is(pageUsersList.data.workspace.pageGrantedUsersList.totalCount, 3);
|
t.is(docUsersList.data.workspace.doc.grantedUsersList.totalCount, 3);
|
||||||
const externalRole =
|
const externalRole =
|
||||||
pageUsersList.data.workspace.pageGrantedUsersList.edges.find(
|
docUsersList.data.workspace.doc.grantedUsersList.edges.find(
|
||||||
(edge: any) => edge.node.user.id === external.id
|
(edge: any) => edge.node.user.id === external.id
|
||||||
)?.node.role;
|
)?.node.role;
|
||||||
t.is(externalRole, DocRole[DocRole.Editor]);
|
t.is(externalRole, DocRole[DocRole.Editor]);
|
||||||
@@ -877,18 +877,18 @@ test('should be able to grant and revoke users role in page', async t => {
|
|||||||
test('should be able to change the default role in page', async t => {
|
test('should be able to change the default role in page', async t => {
|
||||||
const { app } = t.context;
|
const { app } = t.context;
|
||||||
const { teamWorkspace: ws, admin } = await init(app, 5);
|
const { teamWorkspace: ws, admin } = await init(app, 5);
|
||||||
const pageId = nanoid();
|
const docId = nanoid();
|
||||||
const res = await updatePageDefaultRole(
|
const res = await updateDocDefaultRole(
|
||||||
app,
|
app,
|
||||||
admin.token.token,
|
admin.token.token,
|
||||||
ws.id,
|
ws.id,
|
||||||
pageId,
|
docId,
|
||||||
DocRole.Reader
|
DocRole.Reader
|
||||||
);
|
);
|
||||||
|
|
||||||
t.deepEqual(res.body, {
|
t.deepEqual(res.body, {
|
||||||
data: {
|
data: {
|
||||||
updatePageDefaultRole: true,
|
updateDocDefaultRole: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -902,53 +902,53 @@ test('default page role should be able to override the workspace role', async t
|
|||||||
external,
|
external,
|
||||||
} = await init(app, 5);
|
} = await init(app, 5);
|
||||||
|
|
||||||
const pageId = nanoid();
|
const docId = nanoid();
|
||||||
|
|
||||||
const res = await updatePageDefaultRole(
|
const res = await updateDocDefaultRole(
|
||||||
app,
|
app,
|
||||||
admin.token.token,
|
admin.token.token,
|
||||||
workspace.id,
|
workspace.id,
|
||||||
pageId,
|
docId,
|
||||||
DocRole.Manager
|
DocRole.Manager
|
||||||
);
|
);
|
||||||
|
|
||||||
t.deepEqual(res.body, {
|
t.deepEqual(res.body, {
|
||||||
data: {
|
data: {
|
||||||
updatePageDefaultRole: true,
|
updateDocDefaultRole: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// reader can manage the page if the page default role is Manager
|
// reader can manage the page if the page default role is Manager
|
||||||
{
|
{
|
||||||
const readerRes = await updatePageDefaultRole(
|
const readerRes = await updateDocDefaultRole(
|
||||||
app,
|
app,
|
||||||
read.token.token,
|
read.token.token,
|
||||||
workspace.id,
|
workspace.id,
|
||||||
pageId,
|
docId,
|
||||||
DocRole.Manager
|
DocRole.Manager
|
||||||
);
|
);
|
||||||
|
|
||||||
t.deepEqual(readerRes.body, {
|
t.deepEqual(readerRes.body, {
|
||||||
data: {
|
data: {
|
||||||
updatePageDefaultRole: true,
|
updateDocDefaultRole: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// external can't manage the page even if the page default role is Manager
|
// external can't manage the page even if the page default role is Manager
|
||||||
{
|
{
|
||||||
const externalRes = await updatePageDefaultRole(
|
const externalRes = await updateDocDefaultRole(
|
||||||
app,
|
app,
|
||||||
external.token.token,
|
external.token.token,
|
||||||
workspace.id,
|
workspace.id,
|
||||||
pageId,
|
docId,
|
||||||
DocRole.Manager
|
DocRole.Manager
|
||||||
);
|
);
|
||||||
|
|
||||||
t.like(externalRes.body, {
|
t.like(externalRes.body, {
|
||||||
errors: [
|
errors: [
|
||||||
{
|
{
|
||||||
message: `You do not have permission to access doc ${pageId} under Space ${workspace.id}.`,
|
message: `You do not have permission to access doc ${docId} under Space ${workspace.id}.`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -958,13 +958,13 @@ test('default page role should be able to override the workspace role', async t
|
|||||||
test('should be able to grant and revoke doc user role', async t => {
|
test('should be able to grant and revoke doc user role', async t => {
|
||||||
const { app } = t.context;
|
const { app } = t.context;
|
||||||
const { teamWorkspace: ws, admin, read, external } = await init(app, 5);
|
const { teamWorkspace: ws, admin, read, external } = await init(app, 5);
|
||||||
const pageId = nanoid();
|
const docId = nanoid();
|
||||||
|
|
||||||
const res = await grantDocUserRoles(
|
const res = await grantDocUserRoles(
|
||||||
app,
|
app,
|
||||||
admin.token.token,
|
admin.token.token,
|
||||||
ws.id,
|
ws.id,
|
||||||
pageId,
|
docId,
|
||||||
[external.id],
|
[external.id],
|
||||||
DocRole.Manager
|
DocRole.Manager
|
||||||
);
|
);
|
||||||
@@ -981,7 +981,7 @@ test('should be able to grant and revoke doc user role', async t => {
|
|||||||
app,
|
app,
|
||||||
external.token.token,
|
external.token.token,
|
||||||
ws.id,
|
ws.id,
|
||||||
pageId,
|
docId,
|
||||||
[read.id],
|
[read.id],
|
||||||
DocRole.Manager
|
DocRole.Manager
|
||||||
);
|
);
|
||||||
@@ -999,7 +999,7 @@ test('should be able to grant and revoke doc user role', async t => {
|
|||||||
app,
|
app,
|
||||||
admin.token.token,
|
admin.token.token,
|
||||||
ws.id,
|
ws.id,
|
||||||
pageId,
|
docId,
|
||||||
external.id
|
external.id
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1014,14 +1014,14 @@ test('should be able to grant and revoke doc user role', async t => {
|
|||||||
app,
|
app,
|
||||||
external.token.token,
|
external.token.token,
|
||||||
ws.id,
|
ws.id,
|
||||||
pageId,
|
docId,
|
||||||
read.id
|
read.id
|
||||||
);
|
);
|
||||||
|
|
||||||
t.like(externalRes.body, {
|
t.like(externalRes.body, {
|
||||||
errors: [
|
errors: [
|
||||||
{
|
{
|
||||||
message: `You do not have permission to access doc ${pageId} under Space ${ws.id}.`,
|
message: `You do not have permission to access doc ${docId} under Space ${ws.id}.`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -1031,7 +1031,7 @@ test('should be able to grant and revoke doc user role', async t => {
|
|||||||
test('update page default role should throw error if the space does not exist', async t => {
|
test('update page default role should throw error if the space does not exist', async t => {
|
||||||
const { app } = t.context;
|
const { app } = t.context;
|
||||||
const { admin } = await init(app, 5);
|
const { admin } = await init(app, 5);
|
||||||
const pageId = nanoid();
|
const docId = nanoid();
|
||||||
const nonExistWorkspaceId = 'non-exist-workspace';
|
const nonExistWorkspaceId = 'non-exist-workspace';
|
||||||
const res = await request(app.getHttpServer())
|
const res = await request(app.getHttpServer())
|
||||||
.post('/graphql')
|
.post('/graphql')
|
||||||
@@ -1040,9 +1040,9 @@ test('update page default role should throw error if the space does not exist',
|
|||||||
.send({
|
.send({
|
||||||
query: `
|
query: `
|
||||||
mutation {
|
mutation {
|
||||||
updatePageDefaultRole(input: {
|
updateDocDefaultRole(input: {
|
||||||
workspaceId: "${nonExistWorkspaceId}",
|
workspaceId: "${nonExistWorkspaceId}",
|
||||||
docId: "${pageId}",
|
docId: "${docId}",
|
||||||
role: Manager,
|
role: Manager,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1052,7 +1052,7 @@ test('update page default role should throw error if the space does not exist',
|
|||||||
t.like(res.body, {
|
t.like(res.body, {
|
||||||
errors: [
|
errors: [
|
||||||
{
|
{
|
||||||
message: `You do not have permission to access doc ${pageId} under Space ${nonExistWorkspaceId}.`,
|
message: `You do not have permission to access doc ${docId} under Space ${nonExistWorkspaceId}.`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export function revokeDocUserRoles(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updatePageDefaultRole(
|
export function updateDocDefaultRole(
|
||||||
app: INestApplication,
|
app: INestApplication,
|
||||||
token: string,
|
token: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
@@ -68,7 +68,7 @@ export function updatePageDefaultRole(
|
|||||||
.send({
|
.send({
|
||||||
query: `
|
query: `
|
||||||
mutation {
|
mutation {
|
||||||
updatePageDefaultRole(input: {
|
updateDocDefaultRole(input: {
|
||||||
workspaceId: "${workspaceId}",
|
workspaceId: "${workspaceId}",
|
||||||
docId: "${docId}",
|
docId: "${docId}",
|
||||||
role: ${DocRole[role]}
|
role: ${DocRole[role]}
|
||||||
@@ -78,7 +78,7 @@ export function updatePageDefaultRole(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function pageGrantedUsersList(
|
export async function docGrantedUsersList(
|
||||||
app: INestApplication,
|
app: INestApplication,
|
||||||
token: string,
|
token: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
@@ -94,14 +94,16 @@ export async function pageGrantedUsersList(
|
|||||||
query: `
|
query: `
|
||||||
query {
|
query {
|
||||||
workspace(id: "${workspaceId}") {
|
workspace(id: "${workspaceId}") {
|
||||||
pageGrantedUsersList(pageId: "${docId}", pagination: { first: ${first}, offset: ${offset} }) {
|
doc(docId: "${docId}") {
|
||||||
totalCount
|
grantedUsersList(pagination: { first: ${first}, offset: ${offset} }) {
|
||||||
edges {
|
totalCount
|
||||||
|
edges {
|
||||||
cursor
|
cursor
|
||||||
node {
|
node {
|
||||||
role
|
role
|
||||||
user {
|
user {
|
||||||
id
|
id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,11 +103,11 @@ export async function updateWorkspace(
|
|||||||
return res.body.data.updateWorkspace.public;
|
return res.body.data.updateWorkspace.public;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function publishPage(
|
export async function publishDoc(
|
||||||
app: INestApplication,
|
app: INestApplication,
|
||||||
token: string,
|
token: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
pageId: string
|
docId: string
|
||||||
) {
|
) {
|
||||||
const res = await request(app.getHttpServer())
|
const res = await request(app.getHttpServer())
|
||||||
.post(gql)
|
.post(gql)
|
||||||
@@ -116,7 +116,7 @@ export async function publishPage(
|
|||||||
.send({
|
.send({
|
||||||
query: `
|
query: `
|
||||||
mutation {
|
mutation {
|
||||||
publishPage(workspaceId: "${workspaceId}", pageId: "${pageId}") {
|
publishDoc(workspaceId: "${workspaceId}", docId: "${docId}") {
|
||||||
id
|
id
|
||||||
mode
|
mode
|
||||||
}
|
}
|
||||||
@@ -124,14 +124,14 @@ export async function publishPage(
|
|||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
.expect(200);
|
.expect(200);
|
||||||
return res.body.errors?.[0]?.message || res.body.data?.publishPage;
|
return res.body.errors?.[0]?.message || res.body.data?.publishDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function revokePublicPage(
|
export async function revokePublicDoc(
|
||||||
app: INestApplication,
|
app: INestApplication,
|
||||||
token: string,
|
token: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
pageId: string
|
docId: string
|
||||||
) {
|
) {
|
||||||
const res = await request(app.getHttpServer())
|
const res = await request(app.getHttpServer())
|
||||||
.post(gql)
|
.post(gql)
|
||||||
@@ -140,7 +140,7 @@ export async function revokePublicPage(
|
|||||||
.send({
|
.send({
|
||||||
query: `
|
query: `
|
||||||
mutation {
|
mutation {
|
||||||
revokePublicPage(workspaceId: "${workspaceId}", pageId: "${pageId}") {
|
revokePublicDoc(workspaceId: "${workspaceId}", docId: "${docId}") {
|
||||||
id
|
id
|
||||||
mode
|
mode
|
||||||
public
|
public
|
||||||
@@ -149,7 +149,7 @@ export async function revokePublicPage(
|
|||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
.expect(200);
|
.expect(200);
|
||||||
return res.body.errors?.[0]?.message || res.body.data?.revokePublicPage;
|
return res.body.errors?.[0]?.message || res.body.data?.revokePublicDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function grantMember(
|
export async function grantMember(
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import {
|
|||||||
createWorkspace,
|
createWorkspace,
|
||||||
getWorkspacePublicPages,
|
getWorkspacePublicPages,
|
||||||
inviteUser,
|
inviteUser,
|
||||||
publishPage,
|
publishDoc,
|
||||||
revokePublicPage,
|
revokePublicDoc,
|
||||||
signUp,
|
signUp,
|
||||||
TestingApp,
|
TestingApp,
|
||||||
updateWorkspace,
|
updateWorkspace,
|
||||||
@@ -83,8 +83,8 @@ test('should share a page', async t => {
|
|||||||
|
|
||||||
const workspace = await createWorkspace(app, u1.token.token);
|
const workspace = await createWorkspace(app, u1.token.token);
|
||||||
|
|
||||||
const share = await publishPage(app, u1.token.token, workspace.id, 'page1');
|
const share = await publishDoc(app, u1.token.token, workspace.id, 'doc1');
|
||||||
t.is(share.id, 'page1', 'failed to share page');
|
t.is(share.id, 'doc1', 'failed to share doc');
|
||||||
const pages = await getWorkspacePublicPages(
|
const pages = await getWorkspacePublicPages(
|
||||||
app,
|
app,
|
||||||
u1.token.token,
|
u1.token.token,
|
||||||
@@ -93,8 +93,8 @@ test('should share a page', async t => {
|
|||||||
t.is(pages.length, 1, 'failed to get shared pages');
|
t.is(pages.length, 1, 'failed to get shared pages');
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
pages[0],
|
pages[0],
|
||||||
{ id: 'page1', mode: 'Page' },
|
{ id: 'doc1', mode: 'Page' },
|
||||||
'failed to get shared page: page1'
|
'failed to get shared doc: doc1'
|
||||||
);
|
);
|
||||||
|
|
||||||
const resp1 = await request(app.getHttpServer())
|
const resp1 = await request(app.getHttpServer())
|
||||||
@@ -107,53 +107,48 @@ test('should share a page', async t => {
|
|||||||
t.is(resp2.statusCode, 200, 'failed to get root doc with public pages');
|
t.is(resp2.statusCode, 200, 'failed to get root doc with public pages');
|
||||||
|
|
||||||
const resp3 = await request(app.getHttpServer())
|
const resp3 = await request(app.getHttpServer())
|
||||||
.get(`/api/workspaces/${workspace.id}/docs/page1`)
|
.get(`/api/workspaces/${workspace.id}/docs/doc1`)
|
||||||
.auth(u1.token.token, { type: 'bearer' });
|
.auth(u1.token.token, { type: 'bearer' });
|
||||||
// 404 because we don't put the page doc to server
|
// 404 because we don't put the page doc to server
|
||||||
t.is(resp3.statusCode, 404, 'failed to get shared doc with u1 token');
|
t.is(resp3.statusCode, 404, 'failed to get shared doc with u1 token');
|
||||||
const resp4 = await request(app.getHttpServer()).get(
|
const resp4 = await request(app.getHttpServer()).get(
|
||||||
`/api/workspaces/${workspace.id}/docs/page1`
|
`/api/workspaces/${workspace.id}/docs/doc1`
|
||||||
);
|
);
|
||||||
// 404 because we don't put the page doc to server
|
// 404 because we don't put the page doc to server
|
||||||
t.is(resp4.statusCode, 404, 'should not get shared doc without token');
|
t.is(resp4.statusCode, 404, 'should not get shared doc without token');
|
||||||
|
|
||||||
const msg1 = await publishPage(app, u2.token.token, 'not_exists_ws', 'page2');
|
const msg1 = await publishDoc(app, u2.token.token, 'not_exists_ws', 'doc2');
|
||||||
t.is(
|
t.is(
|
||||||
msg1,
|
msg1,
|
||||||
'You do not have permission to access doc page2 under Space not_exists_ws.',
|
'You do not have permission to access doc doc2 under Space not_exists_ws.',
|
||||||
'unauthorized user can share page'
|
'unauthorized user can share doc'
|
||||||
);
|
);
|
||||||
const msg2 = await revokePublicPage(
|
const msg2 = await revokePublicDoc(
|
||||||
app,
|
app,
|
||||||
u2.token.token,
|
u2.token.token,
|
||||||
'not_exists_ws',
|
'not_exists_ws',
|
||||||
'page2'
|
'doc2'
|
||||||
);
|
);
|
||||||
t.is(
|
t.is(
|
||||||
msg2,
|
msg2,
|
||||||
'You do not have permission to access doc page2 under Space not_exists_ws.',
|
'You do not have permission to access doc doc2 under Space not_exists_ws.',
|
||||||
'unauthorized user can share page'
|
'unauthorized user can share doc'
|
||||||
);
|
);
|
||||||
const revoke = await revokePublicPage(
|
const revoke = await revokePublicDoc(
|
||||||
app,
|
app,
|
||||||
u1.token.token,
|
u1.token.token,
|
||||||
workspace.id,
|
workspace.id,
|
||||||
'page1'
|
'doc1'
|
||||||
);
|
);
|
||||||
t.false(revoke.public, 'failed to revoke page');
|
t.false(revoke.public, 'failed to revoke doc');
|
||||||
const pages2 = await getWorkspacePublicPages(
|
const pages2 = await getWorkspacePublicPages(
|
||||||
app,
|
app,
|
||||||
u1.token.token,
|
u1.token.token,
|
||||||
workspace.id
|
workspace.id
|
||||||
);
|
);
|
||||||
t.is(pages2.length, 0, 'failed to get shared pages');
|
t.is(pages2.length, 0, 'failed to get shared pages');
|
||||||
const msg4 = await revokePublicPage(
|
const msg4 = await revokePublicDoc(app, u1.token.token, workspace.id, 'doc3');
|
||||||
app,
|
t.is(msg4, 'Doc is not public');
|
||||||
u1.token.token,
|
|
||||||
workspace.id,
|
|
||||||
'page3'
|
|
||||||
);
|
|
||||||
t.is(msg4, 'Page is not public');
|
|
||||||
|
|
||||||
const pages3 = await getWorkspacePublicPages(
|
const pages3 = await getWorkspacePublicPages(
|
||||||
app,
|
app,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ test.before(async t => {
|
|||||||
t.context.storage = app.get(WorkspaceBlobStorage);
|
t.context.storage = app.get(WorkspaceBlobStorage);
|
||||||
t.context.workspace = app.get(PgWorkspaceDocStorageAdapter);
|
t.context.workspace = app.get(PgWorkspaceDocStorageAdapter);
|
||||||
|
|
||||||
await db.workspacePage.create({
|
await db.workspaceDoc.create({
|
||||||
data: {
|
data: {
|
||||||
workspace: {
|
workspace: {
|
||||||
create: {
|
create: {
|
||||||
@@ -49,12 +49,12 @@ test.before(async t => {
|
|||||||
public: true,
|
public: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pageId: 'private',
|
docId: 'private',
|
||||||
public: false,
|
public: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await db.workspacePage.create({
|
await db.workspaceDoc.create({
|
||||||
data: {
|
data: {
|
||||||
workspace: {
|
workspace: {
|
||||||
create: {
|
create: {
|
||||||
@@ -62,12 +62,12 @@ test.before(async t => {
|
|||||||
public: false,
|
public: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pageId: 'public',
|
docId: 'public',
|
||||||
public: true,
|
public: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await db.workspacePage.create({
|
await db.workspaceDoc.create({
|
||||||
data: {
|
data: {
|
||||||
workspace: {
|
workspace: {
|
||||||
create: {
|
create: {
|
||||||
@@ -75,7 +75,7 @@ test.before(async t => {
|
|||||||
public: false,
|
public: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pageId: 'private',
|
docId: 'private',
|
||||||
public: false,
|
public: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -261,8 +261,8 @@ test('should be able to change page publish mode', async t => {
|
|||||||
t.is(res.status, HttpStatus.OK);
|
t.is(res.status, HttpStatus.OK);
|
||||||
t.is(res.get('publish-mode'), 'page');
|
t.is(res.get('publish-mode'), 'page');
|
||||||
|
|
||||||
await db.workspacePage.update({
|
await db.workspaceDoc.update({
|
||||||
where: { workspaceId_pageId: { workspaceId: 'private', pageId: 'public' } },
|
where: { workspaceId_docId: { workspaceId: 'private', docId: 'public' } },
|
||||||
data: { mode: 1 },
|
data: { mode: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -428,13 +428,13 @@ export const USER_FRIENDLY_ERRORS = {
|
|||||||
message: ({ spaceId, blobId }) =>
|
message: ({ spaceId, blobId }) =>
|
||||||
`Blob ${blobId} not found in Space ${spaceId}.`,
|
`Blob ${blobId} not found in Space ${spaceId}.`,
|
||||||
},
|
},
|
||||||
expect_to_publish_page: {
|
expect_to_publish_doc: {
|
||||||
type: 'invalid_input',
|
type: 'invalid_input',
|
||||||
message: 'Expected to publish a page, not a Space.',
|
message: 'Expected to publish a doc, not a Space.',
|
||||||
},
|
},
|
||||||
expect_to_revoke_public_page: {
|
expect_to_revoke_public_doc: {
|
||||||
type: 'invalid_input',
|
type: 'invalid_input',
|
||||||
message: 'Expected to revoke a public page, not a Space.',
|
message: 'Expected to revoke a public doc, not a Space.',
|
||||||
},
|
},
|
||||||
expect_to_grant_doc_user_roles: {
|
expect_to_grant_doc_user_roles: {
|
||||||
type: 'invalid_input',
|
type: 'invalid_input',
|
||||||
@@ -454,9 +454,9 @@ export const USER_FRIENDLY_ERRORS = {
|
|||||||
message: ({ spaceId, docId }) =>
|
message: ({ spaceId, docId }) =>
|
||||||
`Expect update roles on doc ${docId} under Space ${spaceId}, not a Space.`,
|
`Expect update roles on doc ${docId} under Space ${spaceId}, not a Space.`,
|
||||||
},
|
},
|
||||||
page_is_not_public: {
|
doc_is_not_public: {
|
||||||
type: 'bad_request',
|
type: 'bad_request',
|
||||||
message: 'Page is not public.',
|
message: 'Doc is not public.',
|
||||||
},
|
},
|
||||||
failed_to_save_updates: {
|
failed_to_save_updates: {
|
||||||
type: 'internal_server_error',
|
type: 'internal_server_error',
|
||||||
@@ -470,13 +470,13 @@ export const USER_FRIENDLY_ERRORS = {
|
|||||||
type: 'action_forbidden',
|
type: 'action_forbidden',
|
||||||
message: 'A Team workspace is required to perform this action.',
|
message: 'A Team workspace is required to perform this action.',
|
||||||
},
|
},
|
||||||
page_default_role_can_not_be_owner: {
|
doc_default_role_can_not_be_owner: {
|
||||||
type: 'invalid_input',
|
type: 'invalid_input',
|
||||||
message: 'Page default role can not be owner.',
|
message: 'Doc default role can not be owner.',
|
||||||
},
|
},
|
||||||
can_not_batch_grant_page_owner_permissions: {
|
can_not_batch_grant_doc_owner_permissions: {
|
||||||
type: 'invalid_input',
|
type: 'invalid_input',
|
||||||
message: 'Can not batch grant page owner permissions.',
|
message: 'Can not batch grant doc owner permissions.',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Subscription Errors
|
// Subscription Errors
|
||||||
|
|||||||
@@ -337,15 +337,15 @@ export class BlobNotFound extends UserFriendlyError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ExpectToPublishPage extends UserFriendlyError {
|
export class ExpectToPublishDoc extends UserFriendlyError {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super('invalid_input', 'expect_to_publish_page', message);
|
super('invalid_input', 'expect_to_publish_doc', message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ExpectToRevokePublicPage extends UserFriendlyError {
|
export class ExpectToRevokePublicDoc extends UserFriendlyError {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super('invalid_input', 'expect_to_revoke_public_page', message);
|
super('invalid_input', 'expect_to_revoke_public_doc', message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
@@ -382,9 +382,9 @@ export class ExpectToUpdateDocUserRole extends UserFriendlyError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PageIsNotPublic extends UserFriendlyError {
|
export class DocIsNotPublic extends UserFriendlyError {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super('bad_request', 'page_is_not_public', message);
|
super('bad_request', 'doc_is_not_public', message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,15 +406,15 @@ export class ActionForbiddenOnNonTeamWorkspace extends UserFriendlyError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PageDefaultRoleCanNotBeOwner extends UserFriendlyError {
|
export class DocDefaultRoleCanNotBeOwner extends UserFriendlyError {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super('invalid_input', 'page_default_role_can_not_be_owner', message);
|
super('invalid_input', 'doc_default_role_can_not_be_owner', message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CanNotBatchGrantPageOwnerPermissions extends UserFriendlyError {
|
export class CanNotBatchGrantDocOwnerPermissions extends UserFriendlyError {
|
||||||
constructor(message?: string) {
|
constructor(message?: string) {
|
||||||
super('invalid_input', 'can_not_batch_grant_page_owner_permissions', message);
|
super('invalid_input', 'can_not_batch_grant_doc_owner_permissions', message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
@@ -764,17 +764,17 @@ export enum ErrorNames {
|
|||||||
INVALID_HISTORY_TIMESTAMP,
|
INVALID_HISTORY_TIMESTAMP,
|
||||||
DOC_HISTORY_NOT_FOUND,
|
DOC_HISTORY_NOT_FOUND,
|
||||||
BLOB_NOT_FOUND,
|
BLOB_NOT_FOUND,
|
||||||
EXPECT_TO_PUBLISH_PAGE,
|
EXPECT_TO_PUBLISH_DOC,
|
||||||
EXPECT_TO_REVOKE_PUBLIC_PAGE,
|
EXPECT_TO_REVOKE_PUBLIC_DOC,
|
||||||
EXPECT_TO_GRANT_DOC_USER_ROLES,
|
EXPECT_TO_GRANT_DOC_USER_ROLES,
|
||||||
EXPECT_TO_REVOKE_DOC_USER_ROLES,
|
EXPECT_TO_REVOKE_DOC_USER_ROLES,
|
||||||
EXPECT_TO_UPDATE_DOC_USER_ROLE,
|
EXPECT_TO_UPDATE_DOC_USER_ROLE,
|
||||||
PAGE_IS_NOT_PUBLIC,
|
DOC_IS_NOT_PUBLIC,
|
||||||
FAILED_TO_SAVE_UPDATES,
|
FAILED_TO_SAVE_UPDATES,
|
||||||
FAILED_TO_UPSERT_SNAPSHOT,
|
FAILED_TO_UPSERT_SNAPSHOT,
|
||||||
ACTION_FORBIDDEN_ON_NON_TEAM_WORKSPACE,
|
ACTION_FORBIDDEN_ON_NON_TEAM_WORKSPACE,
|
||||||
PAGE_DEFAULT_ROLE_CAN_NOT_BE_OWNER,
|
DOC_DEFAULT_ROLE_CAN_NOT_BE_OWNER,
|
||||||
CAN_NOT_BATCH_GRANT_PAGE_OWNER_PERMISSIONS,
|
CAN_NOT_BATCH_GRANT_DOC_OWNER_PERMISSIONS,
|
||||||
UNSUPPORTED_SUBSCRIPTION_PLAN,
|
UNSUPPORTED_SUBSCRIPTION_PLAN,
|
||||||
FAILED_TO_CHECKOUT,
|
FAILED_TO_CHECKOUT,
|
||||||
INVALID_CHECKOUT_PARAMETERS,
|
INVALID_CHECKOUT_PARAMETERS,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export {
|
|||||||
fixupDocRole,
|
fixupDocRole,
|
||||||
mapDocRoleToPermissions,
|
mapDocRoleToPermissions,
|
||||||
mapWorkspaceRoleToPermissions,
|
mapWorkspaceRoleToPermissions,
|
||||||
PublicPageMode,
|
PublicDocMode,
|
||||||
WORKSPACE_ACTIONS,
|
WORKSPACE_ACTIONS,
|
||||||
type WorkspaceActionPermissions,
|
type WorkspaceActionPermissions,
|
||||||
WorkspaceRole,
|
WorkspaceRole,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Injectable, Logger } from '@nestjs/common';
|
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 { PrismaClient, WorkspaceMemberStatus } from '@prisma/client';
|
||||||
import { groupBy } from 'lodash-es';
|
import { groupBy } from 'lodash-es';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CanNotBatchGrantPageOwnerPermissions,
|
CanNotBatchGrantDocOwnerPermissions,
|
||||||
DocAccessDenied,
|
DocAccessDenied,
|
||||||
EventBus,
|
EventBus,
|
||||||
OnEvent,
|
OnEvent,
|
||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
docActionRequiredRole,
|
docActionRequiredRole,
|
||||||
docActionRequiredWorkspaceRole,
|
docActionRequiredWorkspaceRole,
|
||||||
DocRole,
|
DocRole,
|
||||||
PublicPageMode,
|
PublicDocMode,
|
||||||
WorkspaceRole,
|
WorkspaceRole,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
@@ -38,10 +38,10 @@ export class PermissionService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.prisma.workspacePageUserPermission.createMany({
|
await this.prisma.workspaceDocUserPermission.createMany({
|
||||||
data: {
|
data: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId: docId,
|
docId,
|
||||||
userId: editor,
|
userId: editor,
|
||||||
type: DocRole.Owner,
|
type: DocRole.Owner,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
@@ -172,7 +172,7 @@ export class PermissionService {
|
|||||||
// if workspace is public or have any public page, then allow to access
|
// if workspace is public or have any public page, then allow to access
|
||||||
const [isPublicWorkspace, publicPages] = await Promise.all([
|
const [isPublicWorkspace, publicPages] = await Promise.all([
|
||||||
this.tryCheckWorkspace(ws, user, WorkspaceRole.Collaborator),
|
this.tryCheckWorkspace(ws, user, WorkspaceRole.Collaborator),
|
||||||
this.prisma.workspacePage.count({
|
this.prisma.workspaceDoc.count({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
public: true,
|
public: true,
|
||||||
@@ -555,17 +555,17 @@ export class PermissionService {
|
|||||||
|
|
||||||
async tryCheckPage(
|
async tryCheckPage(
|
||||||
ws: string,
|
ws: string,
|
||||||
page: string,
|
doc: string,
|
||||||
action: DocAction,
|
action: DocAction,
|
||||||
user?: string
|
user?: string
|
||||||
) {
|
) {
|
||||||
const role = docActionRequiredRole(action);
|
const role = docActionRequiredRole(action);
|
||||||
// check whether page is public
|
// check whether page is public
|
||||||
if (action === 'Doc.Read') {
|
if (action === 'Doc.Read') {
|
||||||
const count = await this.prisma.workspacePage.count({
|
const count = await this.prisma.workspaceDoc.count({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
public: true,
|
public: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -579,20 +579,20 @@ export class PermissionService {
|
|||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
const [roleEntity, pageEntity, workspaceRoleEntity] = await Promise.all([
|
const [roleEntity, pageEntity, workspaceRoleEntity] = await Promise.all([
|
||||||
this.prisma.workspacePageUserPermission.findFirst({
|
this.prisma.workspaceDocUserPermission.findFirst({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
userId: user,
|
userId: user,
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
type: true,
|
type: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
this.prisma.workspacePage.findFirst({
|
this.prisma.workspaceDoc.findFirst({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
defaultRole: true,
|
defaultRole: true,
|
||||||
@@ -629,7 +629,7 @@ export class PermissionService {
|
|||||||
}
|
}
|
||||||
this.logger.log("User's role is lower than required", {
|
this.logger.log("User's role is lower than required", {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
docId: page,
|
docId: doc,
|
||||||
userId: user,
|
userId: user,
|
||||||
workspaceRole: workspaceRoleEntity
|
workspaceRole: workspaceRoleEntity
|
||||||
? WorkspaceRole[workspaceRoleEntity.type]
|
? WorkspaceRole[workspaceRoleEntity.type]
|
||||||
@@ -651,24 +651,24 @@ export class PermissionService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async isPublicPage(ws: string, page: string) {
|
async isPublicPage(ws: string, doc: string) {
|
||||||
return this.prisma.workspacePage
|
return this.prisma.workspaceDoc
|
||||||
.count({
|
.count({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
public: true,
|
public: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(count => count > 0);
|
.then(count => count > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
async publishPage(ws: string, page: string, mode = PublicPageMode.Page) {
|
async publishPage(ws: string, doc: string, mode = PublicDocMode.Page) {
|
||||||
return this.prisma.workspacePage.upsert({
|
return this.prisma.workspaceDoc.upsert({
|
||||||
where: {
|
where: {
|
||||||
workspaceId_pageId: {
|
workspaceId_docId: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
@@ -677,19 +677,19 @@ export class PermissionService {
|
|||||||
},
|
},
|
||||||
create: {
|
create: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
mode,
|
mode,
|
||||||
public: true,
|
public: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async revokePublicPage(ws: string, page: string) {
|
async revokePublicPage(ws: string, doc: string) {
|
||||||
return this.prisma.workspacePage.upsert({
|
return this.prisma.workspaceDoc.upsert({
|
||||||
where: {
|
where: {
|
||||||
workspaceId_pageId: {
|
workspaceId_docId: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
@@ -697,20 +697,20 @@ export class PermissionService {
|
|||||||
},
|
},
|
||||||
create: {
|
create: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
public: false,
|
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(
|
const [p] = await this.prisma.$transaction(
|
||||||
[
|
[
|
||||||
this.prisma.workspacePageUserPermission.upsert({
|
this.prisma.workspaceDocUserPermission.upsert({
|
||||||
where: {
|
where: {
|
||||||
workspaceId_pageId_userId: {
|
workspaceId_docId_userId: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
userId: user,
|
userId: user,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -719,7 +719,7 @@ export class PermissionService {
|
|||||||
},
|
},
|
||||||
create: {
|
create: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
userId: user,
|
userId: user,
|
||||||
type: permission,
|
type: permission,
|
||||||
},
|
},
|
||||||
@@ -727,10 +727,10 @@ export class PermissionService {
|
|||||||
|
|
||||||
// If the new permission is owner, we need to revoke old owner
|
// If the new permission is owner, we need to revoke old owner
|
||||||
permission === DocRole.Owner
|
permission === DocRole.Owner
|
||||||
? this.prisma.workspacePageUserPermission.updateMany({
|
? this.prisma.workspaceDocUserPermission.updateMany({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
type: DocRole.Owner,
|
type: DocRole.Owner,
|
||||||
userId: {
|
userId: {
|
||||||
not: user,
|
not: user,
|
||||||
@@ -744,14 +744,14 @@ export class PermissionService {
|
|||||||
].filter(Boolean) as Prisma.PrismaPromise<any>[]
|
].filter(Boolean) as Prisma.PrismaPromise<any>[]
|
||||||
);
|
);
|
||||||
|
|
||||||
return p as WorkspacePageUserPermission;
|
return p as WorkspaceDocUserPermission;
|
||||||
}
|
}
|
||||||
|
|
||||||
async revokePage(ws: string, page: string, user: string) {
|
async revokePage(ws: string, doc: string, user: string) {
|
||||||
const result = await this.prisma.workspacePageUserPermission.deleteMany({
|
const result = await this.prisma.workspaceDocUserPermission.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: ws,
|
workspaceId: ws,
|
||||||
pageId: page,
|
docId: doc,
|
||||||
userId: user,
|
userId: user,
|
||||||
type: {
|
type: {
|
||||||
// We shouldn't revoke owner permission, should auto deleted by workspace/user delete cascading
|
// We shouldn't revoke owner permission, should auto deleted by workspace/user delete cascading
|
||||||
@@ -765,7 +765,7 @@ export class PermissionService {
|
|||||||
|
|
||||||
async batchGrantPage(
|
async batchGrantPage(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
pageId: string,
|
docId: string,
|
||||||
userIds: string[],
|
userIds: string[],
|
||||||
role: DocRole
|
role: DocRole
|
||||||
) {
|
) {
|
||||||
@@ -774,14 +774,14 @@ export class PermissionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (role === DocRole.Owner) {
|
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,
|
skipDuplicates: true,
|
||||||
data: userIds.map(id => ({
|
data: userIds.map(id => ({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId,
|
docId,
|
||||||
userId: id,
|
userId: id,
|
||||||
type: role,
|
type: role,
|
||||||
})),
|
})),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { LeafPaths, LeafVisitor } from '../../base';
|
import { LeafPaths, LeafVisitor } from '../../base';
|
||||||
|
|
||||||
export enum PublicPageMode {
|
export enum PublicDocMode {
|
||||||
Page,
|
Page,
|
||||||
Edgeless,
|
Edgeless,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
} from '../../base';
|
} from '../../base';
|
||||||
import { CurrentUser, Public } from '../auth';
|
import { CurrentUser, Public } from '../auth';
|
||||||
import { PgWorkspaceDocStorageAdapter } from '../doc';
|
import { PgWorkspaceDocStorageAdapter } from '../doc';
|
||||||
import { PermissionService, PublicPageMode } from '../permission';
|
import { PermissionService, PublicDocMode } from '../permission';
|
||||||
import { WorkspaceBlobStorage } from '../storage';
|
import { WorkspaceBlobStorage } from '../storage';
|
||||||
import { DocID } from '../utils/doc';
|
import { DocID } from '../utils/doc';
|
||||||
|
|
||||||
@@ -109,16 +109,16 @@ export class WorkspacesController {
|
|||||||
|
|
||||||
if (!docId.isWorkspace) {
|
if (!docId.isWorkspace) {
|
||||||
// fetch the publish page mode for publish page
|
// fetch the publish page mode for publish page
|
||||||
const publishPage = await this.prisma.workspacePage.findUnique({
|
const publishPage = await this.prisma.workspaceDoc.findUnique({
|
||||||
where: {
|
where: {
|
||||||
workspaceId_pageId: {
|
workspaceId_docId: {
|
||||||
workspaceId: docId.workspace,
|
workspaceId: docId.workspace,
|
||||||
pageId: docId.guid,
|
docId: docId.guid,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const publishPageMode =
|
const publishPageMode =
|
||||||
publishPage?.mode === PublicPageMode.Edgeless ? 'edgeless' : 'page';
|
publishPage?.mode === PublicDocMode.Edgeless ? 'edgeless' : 'page';
|
||||||
|
|
||||||
res.setHeader('publish-mode', publishPageMode);
|
res.setHeader('publish-mode', publishPageMode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ import { UserModule } from '../user';
|
|||||||
import { WorkspacesController } from './controller';
|
import { WorkspacesController } from './controller';
|
||||||
import {
|
import {
|
||||||
DocHistoryResolver,
|
DocHistoryResolver,
|
||||||
PagePermissionResolver,
|
DocResolver,
|
||||||
TeamWorkspaceResolver,
|
TeamWorkspaceResolver,
|
||||||
WorkspaceBlobResolver,
|
WorkspaceBlobResolver,
|
||||||
|
WorkspaceDocResolver,
|
||||||
WorkspaceResolver,
|
WorkspaceResolver,
|
||||||
WorkspaceService,
|
WorkspaceService,
|
||||||
} from './resolvers';
|
} from './resolvers';
|
||||||
@@ -31,7 +32,8 @@ import {
|
|||||||
providers: [
|
providers: [
|
||||||
WorkspaceResolver,
|
WorkspaceResolver,
|
||||||
TeamWorkspaceResolver,
|
TeamWorkspaceResolver,
|
||||||
PagePermissionResolver,
|
WorkspaceDocResolver,
|
||||||
|
DocResolver,
|
||||||
DocHistoryResolver,
|
DocHistoryResolver,
|
||||||
WorkspaceBlobResolver,
|
WorkspaceBlobResolver,
|
||||||
WorkspaceService,
|
WorkspaceService,
|
||||||
|
|||||||
@@ -10,18 +10,18 @@ import {
|
|||||||
ResolveField,
|
ResolveField,
|
||||||
Resolver,
|
Resolver,
|
||||||
} from '@nestjs/graphql';
|
} 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 { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DocAccessDenied,
|
DocAccessDenied,
|
||||||
|
DocDefaultRoleCanNotBeOwner,
|
||||||
|
DocIsNotPublic,
|
||||||
ExpectToGrantDocUserRoles,
|
ExpectToGrantDocUserRoles,
|
||||||
ExpectToPublishPage,
|
ExpectToPublishDoc,
|
||||||
ExpectToRevokeDocUserRoles,
|
ExpectToRevokeDocUserRoles,
|
||||||
ExpectToRevokePublicPage,
|
ExpectToRevokePublicDoc,
|
||||||
ExpectToUpdateDocUserRole,
|
ExpectToUpdateDocUserRole,
|
||||||
PageDefaultRoleCanNotBeOwner,
|
|
||||||
PageIsNotPublic,
|
|
||||||
paginate,
|
paginate,
|
||||||
Paginated,
|
Paginated,
|
||||||
PaginationInput,
|
PaginationInput,
|
||||||
@@ -36,27 +36,27 @@ import {
|
|||||||
fixupDocRole,
|
fixupDocRole,
|
||||||
mapDocRoleToPermissions,
|
mapDocRoleToPermissions,
|
||||||
PermissionService,
|
PermissionService,
|
||||||
PublicPageMode,
|
PublicDocMode,
|
||||||
} from '../../permission';
|
} from '../../permission';
|
||||||
import { PublicUserType } from '../../user';
|
import { PublicUserType } from '../../user';
|
||||||
import { DocID } from '../../utils/doc';
|
import { DocID } from '../../utils/doc';
|
||||||
import { WorkspaceType } from '../types';
|
import { WorkspaceType } from '../types';
|
||||||
|
|
||||||
registerEnumType(PublicPageMode, {
|
registerEnumType(PublicDocMode, {
|
||||||
name: 'PublicPageMode',
|
name: 'PublicDocMode',
|
||||||
description: 'The mode which the public page default in',
|
description: 'The mode which the public doc default in',
|
||||||
});
|
});
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
class WorkspacePage implements Partial<PrismaWorkspacePage> {
|
class DocType implements Partial<PrismaWorkspaceDoc> {
|
||||||
@Field(() => String, { name: 'id' })
|
@Field(() => String, { name: 'id' })
|
||||||
pageId!: string;
|
docId!: string;
|
||||||
|
|
||||||
@Field()
|
@Field()
|
||||||
workspaceId!: string;
|
workspaceId!: string;
|
||||||
|
|
||||||
@Field(() => PublicPageMode)
|
@Field(() => PublicDocMode)
|
||||||
mode!: PublicPageMode;
|
mode!: PublicDocMode;
|
||||||
|
|
||||||
@Field()
|
@Field()
|
||||||
public!: boolean;
|
public!: boolean;
|
||||||
@@ -105,7 +105,7 @@ class RevokeDocUserRoleInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@InputType()
|
@InputType()
|
||||||
class UpdatePageDefaultRoleInput {
|
class UpdateDocDefaultRoleInput {
|
||||||
@Field(() => String)
|
@Field(() => String)
|
||||||
docId!: string;
|
docId!: string;
|
||||||
|
|
||||||
@@ -144,13 +144,7 @@ const DocPermissions = registerObjectType<DocActionPermissions>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
class DocType {
|
export class DocRolePermissions {
|
||||||
@Field(() => String)
|
|
||||||
id!: string;
|
|
||||||
|
|
||||||
@Field(() => Boolean)
|
|
||||||
public!: boolean;
|
|
||||||
|
|
||||||
@Field(() => DocRole)
|
@Field(() => DocRole)
|
||||||
role!: DocRole;
|
role!: DocRole;
|
||||||
|
|
||||||
@@ -159,8 +153,207 @@ class DocType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Resolver(() => WorkspaceType)
|
@Resolver(() => WorkspaceType)
|
||||||
export class PagePermissionResolver {
|
export class WorkspaceDocResolver {
|
||||||
private readonly logger = new Logger(PagePermissionResolver.name);
|
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(
|
constructor(
|
||||||
private readonly prisma: PrismaClient,
|
private readonly prisma: PrismaClient,
|
||||||
@@ -168,96 +361,31 @@ export class PagePermissionResolver {
|
|||||||
private readonly models: Models
|
private readonly models: Models
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
@ResolveField(() => DocPermissions)
|
||||||
* @deprecated
|
async permissions(
|
||||||
*/
|
@CurrentUser() user: CurrentUser,
|
||||||
@ResolveField(() => [String], {
|
@Parent() doc: DocType
|
||||||
description: 'Shared pages of workspace',
|
): Promise<DocRolePermissions> {
|
||||||
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,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const [permission, workspacePermission] = await this.prisma.$transaction(
|
const [permission, workspacePermission] = await this.prisma.$transaction(
|
||||||
tx =>
|
tx =>
|
||||||
Promise.all([
|
Promise.all([
|
||||||
tx.workspacePageUserPermission.findFirst({
|
tx.workspaceDocUserPermission.findFirst({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: workspace.id,
|
workspaceId: doc.workspaceId,
|
||||||
pageId,
|
docId: doc.docId,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
tx.workspaceUserPermission.findFirst({
|
tx.workspaceUserPermission.findFirst({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: workspace.id,
|
workspaceId: doc.workspaceId,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: pageId,
|
|
||||||
public: page?.public ?? false,
|
|
||||||
role: permission?.type ?? DocRole.External,
|
role: permission?.type ?? DocRole.External,
|
||||||
permissions: mapDocRoleToPermissions(
|
permissions: mapDocRoleToPermissions(
|
||||||
fixupDocRole(workspacePermission?.type, permission?.type)
|
fixupDocRole(workspacePermission?.type, permission?.type)
|
||||||
@@ -266,29 +394,27 @@ export class PagePermissionResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField(() => PaginatedGrantedDocUserType, {
|
@ResolveField(() => PaginatedGrantedDocUserType, {
|
||||||
description: 'Page granted users list',
|
description: 'paginated doc granted users list',
|
||||||
complexity: 4,
|
complexity: 4,
|
||||||
})
|
})
|
||||||
async pageGrantedUsersList(
|
async grantedUsersList(
|
||||||
@CurrentUser() user: CurrentUser,
|
@CurrentUser() user: CurrentUser,
|
||||||
@Parent() workspace: WorkspaceType,
|
@Parent() doc: DocType,
|
||||||
@Args('pageId') pageId: string,
|
|
||||||
@Args('pagination') pagination: PaginationInput
|
@Args('pagination') pagination: PaginationInput
|
||||||
): Promise<PaginatedGrantedDocUserType> {
|
): Promise<PaginatedGrantedDocUserType> {
|
||||||
await this.permission.checkPagePermission(
|
await this.permission.checkPagePermission(
|
||||||
workspace.id,
|
doc.workspaceId,
|
||||||
pageId,
|
doc.docId,
|
||||||
'Doc.Users.Read',
|
'Doc.Users.Read',
|
||||||
user.id
|
user.id
|
||||||
);
|
);
|
||||||
|
|
||||||
const docId = new DocID(pageId, workspace.id);
|
|
||||||
const [permissions, totalCount] = await this.prisma.$transaction(tx => {
|
const [permissions, totalCount] = await this.prisma.$transaction(tx => {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
tx.workspacePageUserPermission.findMany({
|
tx.workspaceDocUserPermission.findMany({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: workspace.id,
|
workspaceId: doc.workspaceId,
|
||||||
pageId: docId.guid,
|
docId: doc.docId,
|
||||||
createdAt: pagination.after
|
createdAt: pagination.after
|
||||||
? {
|
? {
|
||||||
gt: pagination.after,
|
gt: pagination.after,
|
||||||
@@ -306,10 +432,10 @@ export class PagePermissionResolver {
|
|||||||
take: pagination.first,
|
take: pagination.first,
|
||||||
skip: pagination.offset,
|
skip: pagination.offset,
|
||||||
}),
|
}),
|
||||||
tx.workspacePageUserPermission.count({
|
tx.workspaceDocUserPermission.count({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: workspace.id,
|
workspaceId: doc.workspaceId,
|
||||||
pageId: docId.guid,
|
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)
|
@Mutation(() => Boolean)
|
||||||
async grantDocUserRoles(
|
async grantDocUserRoles(
|
||||||
@CurrentUser() user: CurrentUser,
|
@CurrentUser() user: CurrentUser,
|
||||||
@@ -580,13 +591,13 @@ export class PagePermissionResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Mutation(() => Boolean)
|
@Mutation(() => Boolean)
|
||||||
async updatePageDefaultRole(
|
async updateDocDefaultRole(
|
||||||
@CurrentUser() user: CurrentUser,
|
@CurrentUser() user: CurrentUser,
|
||||||
@Args('input') input: UpdatePageDefaultRoleInput
|
@Args('input') input: UpdateDocDefaultRoleInput
|
||||||
) {
|
) {
|
||||||
if (input.role === DocRole.Owner) {
|
if (input.role === DocRole.Owner) {
|
||||||
this.logger.log('Page default role can not be owner', input);
|
this.logger.log('Doc default role can not be owner', input);
|
||||||
throw new PageDefaultRoleCanNotBeOwner();
|
throw new DocDefaultRoleCanNotBeOwner();
|
||||||
}
|
}
|
||||||
const doc = new DocID(input.docId, input.workspaceId);
|
const doc = new DocID(input.docId, input.workspaceId);
|
||||||
const pairs = {
|
const pairs = {
|
||||||
@@ -622,11 +633,11 @@ export class PagePermissionResolver {
|
|||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
await this.prisma.workspacePage.upsert({
|
await this.prisma.workspaceDoc.upsert({
|
||||||
where: {
|
where: {
|
||||||
workspaceId_pageId: {
|
workspaceId_docId: {
|
||||||
workspaceId: doc.workspace,
|
workspaceId: doc.workspace,
|
||||||
pageId: doc.guid,
|
docId: doc.guid,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
@@ -634,7 +645,7 @@ export class PagePermissionResolver {
|
|||||||
},
|
},
|
||||||
create: {
|
create: {
|
||||||
workspaceId: doc.workspace,
|
workspaceId: doc.workspace,
|
||||||
pageId: doc.guid,
|
docId: doc.guid,
|
||||||
defaultRole: input.role,
|
defaultRole: input.role,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
export * from './blob';
|
export * from './blob';
|
||||||
|
export * from './doc';
|
||||||
export * from './history';
|
export * from './history';
|
||||||
export * from './page';
|
|
||||||
export * from './service';
|
export * from './service';
|
||||||
export * from './team';
|
export * from './team';
|
||||||
export * from './workspace';
|
export * from './workspace';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Transactional } from '@nestjs-cls/transactional';
|
import { Transactional } from '@nestjs-cls/transactional';
|
||||||
import {
|
import {
|
||||||
type WorkspacePage as Page,
|
type WorkspaceDoc as Page,
|
||||||
type WorkspacePageUserPermission as PageUserPermission,
|
type WorkspaceDocUserPermission as PageUserPermission,
|
||||||
} from '@prisma/client';
|
} from '@prisma/client';
|
||||||
|
|
||||||
import { WorkspaceRole } from '../core/permission';
|
import { WorkspaceRole } from '../core/permission';
|
||||||
@@ -21,12 +21,12 @@ export class PageModel extends BaseModel {
|
|||||||
/**
|
/**
|
||||||
* Create or update the page.
|
* Create or update the page.
|
||||||
*/
|
*/
|
||||||
async upsert(workspaceId: string, pageId: string, data?: UpdatePageInput) {
|
async upsert(workspaceId: string, docId: string, data?: UpdatePageInput) {
|
||||||
return await this.db.workspacePage.upsert({
|
return await this.db.workspaceDoc.upsert({
|
||||||
where: {
|
where: {
|
||||||
workspaceId_pageId: {
|
workspaceId_docId: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId,
|
docId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
@@ -35,7 +35,7 @@ export class PageModel extends BaseModel {
|
|||||||
create: {
|
create: {
|
||||||
...data,
|
...data,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId,
|
docId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -45,12 +45,12 @@ export class PageModel extends BaseModel {
|
|||||||
* @param isPublic: if true, only return the public page. If false, only return the private page.
|
* @param isPublic: if true, only return the public page. If false, only return the private page.
|
||||||
* If not set, return public or private both.
|
* If not set, return public or private both.
|
||||||
*/
|
*/
|
||||||
async get(workspaceId: string, pageId: string, isPublic?: boolean) {
|
async get(workspaceId: string, docId: string, isPublic?: boolean) {
|
||||||
return await this.db.workspacePage.findUnique({
|
return await this.db.workspaceDoc.findUnique({
|
||||||
where: {
|
where: {
|
||||||
workspaceId_pageId: {
|
workspaceId_docId: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId,
|
docId,
|
||||||
},
|
},
|
||||||
public: isPublic,
|
public: isPublic,
|
||||||
},
|
},
|
||||||
@@ -61,7 +61,7 @@ export class PageModel extends BaseModel {
|
|||||||
* Find the workspace public pages.
|
* Find the workspace public pages.
|
||||||
*/
|
*/
|
||||||
async findPublics(workspaceId: string) {
|
async findPublics(workspaceId: string) {
|
||||||
return await this.db.workspacePage.findMany({
|
return await this.db.workspaceDoc.findMany({
|
||||||
where: {
|
where: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
public: true,
|
public: true,
|
||||||
@@ -73,7 +73,7 @@ export class PageModel extends BaseModel {
|
|||||||
* Get the workspace public pages count.
|
* Get the workspace public pages count.
|
||||||
*/
|
*/
|
||||||
async getPublicsCount(workspaceId: string) {
|
async getPublicsCount(workspaceId: string) {
|
||||||
return await this.db.workspacePage.count({
|
return await this.db.workspaceDoc.count({
|
||||||
where: {
|
where: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
public: true,
|
public: true,
|
||||||
@@ -91,15 +91,15 @@ export class PageModel extends BaseModel {
|
|||||||
@Transactional()
|
@Transactional()
|
||||||
async grantMember(
|
async grantMember(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
pageId: string,
|
docId: string,
|
||||||
userId: string,
|
userId: string,
|
||||||
permission: WorkspaceRole = WorkspaceRole.Collaborator
|
permission: WorkspaceRole = WorkspaceRole.Collaborator
|
||||||
): Promise<PageUserPermission> {
|
): Promise<PageUserPermission> {
|
||||||
let data = await this.db.workspacePageUserPermission.findUnique({
|
let data = await this.db.workspaceDocUserPermission.findUnique({
|
||||||
where: {
|
where: {
|
||||||
workspaceId_pageId_userId: {
|
workspaceId_docId_userId: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId,
|
docId,
|
||||||
userId,
|
userId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -109,11 +109,11 @@ export class PageModel extends BaseModel {
|
|||||||
if (!data || data.type !== permission) {
|
if (!data || data.type !== permission) {
|
||||||
if (data) {
|
if (data) {
|
||||||
// Update the permission
|
// Update the permission
|
||||||
data = await this.db.workspacePageUserPermission.update({
|
data = await this.db.workspaceDocUserPermission.update({
|
||||||
where: {
|
where: {
|
||||||
workspaceId_pageId_userId: {
|
workspaceId_docId_userId: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId,
|
docId,
|
||||||
userId,
|
userId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -121,10 +121,10 @@ export class PageModel extends BaseModel {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Create a new permission
|
// Create a new permission
|
||||||
data = await this.db.workspacePageUserPermission.create({
|
data = await this.db.workspaceDocUserPermission.create({
|
||||||
data: {
|
data: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId,
|
docId,
|
||||||
userId,
|
userId,
|
||||||
type: permission,
|
type: permission,
|
||||||
},
|
},
|
||||||
@@ -133,17 +133,17 @@ export class PageModel extends BaseModel {
|
|||||||
|
|
||||||
// If the new permission is owner, we need to revoke old owner
|
// If the new permission is owner, we need to revoke old owner
|
||||||
if (permission === WorkspaceRole.Owner) {
|
if (permission === WorkspaceRole.Owner) {
|
||||||
await this.db.workspacePageUserPermission.updateMany({
|
await this.db.workspaceDocUserPermission.updateMany({
|
||||||
where: {
|
where: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId,
|
docId,
|
||||||
type: WorkspaceRole.Owner,
|
type: WorkspaceRole.Owner,
|
||||||
userId: { not: userId },
|
userId: { not: userId },
|
||||||
},
|
},
|
||||||
data: { type: WorkspaceRole.Admin },
|
data: { type: WorkspaceRole.Admin },
|
||||||
});
|
});
|
||||||
this.logger.log(
|
this.logger.log(
|
||||||
`Change owner of workspace ${workspaceId} page ${pageId} to user ${userId}`
|
`Change owner of workspace ${workspaceId} doc ${docId} to user ${userId}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
@@ -159,14 +159,14 @@ export class PageModel extends BaseModel {
|
|||||||
*/
|
*/
|
||||||
async isMember(
|
async isMember(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
pageId: string,
|
docId: string,
|
||||||
userId: string,
|
userId: string,
|
||||||
permission: WorkspaceRole = WorkspaceRole.Collaborator
|
permission: WorkspaceRole = WorkspaceRole.Collaborator
|
||||||
) {
|
) {
|
||||||
const count = await this.db.workspacePageUserPermission.count({
|
const count = await this.db.workspaceDocUserPermission.count({
|
||||||
where: {
|
where: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId,
|
docId,
|
||||||
userId,
|
userId,
|
||||||
type: {
|
type: {
|
||||||
gte: permission,
|
gte: permission,
|
||||||
@@ -180,11 +180,11 @@ export class PageModel extends BaseModel {
|
|||||||
* Delete a page member
|
* Delete a page member
|
||||||
* Except the owner, the owner can't be deleted.
|
* Except the owner, the owner can't be deleted.
|
||||||
*/
|
*/
|
||||||
async deleteMember(workspaceId: string, pageId: string, userId: string) {
|
async deleteMember(workspaceId: string, docId: string, userId: string) {
|
||||||
const { count } = await this.db.workspacePageUserPermission.deleteMany({
|
const { count } = await this.db.workspaceDocUserPermission.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
pageId,
|
docId,
|
||||||
userId,
|
userId,
|
||||||
type: {
|
type: {
|
||||||
// We shouldn't revoke owner permission, should auto deleted by workspace/user delete cascading
|
// We shouldn't revoke owner permission, should auto deleted by workspace/user delete cascading
|
||||||
|
|||||||
@@ -230,10 +230,13 @@ enum DocRole {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DocType {
|
type DocType {
|
||||||
|
"""paginated doc granted users list"""
|
||||||
|
grantedUsersList(pagination: PaginationInput!): PaginatedGrantedDocUserType!
|
||||||
id: String!
|
id: String!
|
||||||
|
mode: PublicDocMode!
|
||||||
permissions: DocPermissions!
|
permissions: DocPermissions!
|
||||||
public: Boolean!
|
public: Boolean!
|
||||||
role: DocRole!
|
workspaceId: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
type EditorType {
|
type EditorType {
|
||||||
@@ -254,7 +257,7 @@ enum ErrorNames {
|
|||||||
CANNOT_DELETE_ALL_ADMIN_ACCOUNT
|
CANNOT_DELETE_ALL_ADMIN_ACCOUNT
|
||||||
CANNOT_DELETE_OWN_ACCOUNT
|
CANNOT_DELETE_OWN_ACCOUNT
|
||||||
CANT_UPDATE_ONETIME_PAYMENT_SUBSCRIPTION
|
CANT_UPDATE_ONETIME_PAYMENT_SUBSCRIPTION
|
||||||
CAN_NOT_BATCH_GRANT_PAGE_OWNER_PERMISSIONS
|
CAN_NOT_BATCH_GRANT_DOC_OWNER_PERMISSIONS
|
||||||
CAPTCHA_VERIFICATION_FAILED
|
CAPTCHA_VERIFICATION_FAILED
|
||||||
COPILOT_ACTION_TAKEN
|
COPILOT_ACTION_TAKEN
|
||||||
COPILOT_FAILED_TO_CREATE_MESSAGE
|
COPILOT_FAILED_TO_CREATE_MESSAGE
|
||||||
@@ -268,16 +271,18 @@ enum ErrorNames {
|
|||||||
COPILOT_SESSION_NOT_FOUND
|
COPILOT_SESSION_NOT_FOUND
|
||||||
CUSTOMER_PORTAL_CREATE_FAILED
|
CUSTOMER_PORTAL_CREATE_FAILED
|
||||||
DOC_ACCESS_DENIED
|
DOC_ACCESS_DENIED
|
||||||
|
DOC_DEFAULT_ROLE_CAN_NOT_BE_OWNER
|
||||||
DOC_HISTORY_NOT_FOUND
|
DOC_HISTORY_NOT_FOUND
|
||||||
|
DOC_IS_NOT_PUBLIC
|
||||||
DOC_NOT_FOUND
|
DOC_NOT_FOUND
|
||||||
EARLY_ACCESS_REQUIRED
|
EARLY_ACCESS_REQUIRED
|
||||||
EMAIL_ALREADY_USED
|
EMAIL_ALREADY_USED
|
||||||
EMAIL_TOKEN_NOT_FOUND
|
EMAIL_TOKEN_NOT_FOUND
|
||||||
EMAIL_VERIFICATION_REQUIRED
|
EMAIL_VERIFICATION_REQUIRED
|
||||||
EXPECT_TO_GRANT_DOC_USER_ROLES
|
EXPECT_TO_GRANT_DOC_USER_ROLES
|
||||||
EXPECT_TO_PUBLISH_PAGE
|
EXPECT_TO_PUBLISH_DOC
|
||||||
EXPECT_TO_REVOKE_DOC_USER_ROLES
|
EXPECT_TO_REVOKE_DOC_USER_ROLES
|
||||||
EXPECT_TO_REVOKE_PUBLIC_PAGE
|
EXPECT_TO_REVOKE_PUBLIC_DOC
|
||||||
EXPECT_TO_UPDATE_DOC_USER_ROLE
|
EXPECT_TO_UPDATE_DOC_USER_ROLE
|
||||||
FAILED_TO_CHECKOUT
|
FAILED_TO_CHECKOUT
|
||||||
FAILED_TO_SAVE_UPDATES
|
FAILED_TO_SAVE_UPDATES
|
||||||
@@ -306,8 +311,6 @@ enum ErrorNames {
|
|||||||
NO_COPILOT_PROVIDER_AVAILABLE
|
NO_COPILOT_PROVIDER_AVAILABLE
|
||||||
OAUTH_ACCOUNT_ALREADY_CONNECTED
|
OAUTH_ACCOUNT_ALREADY_CONNECTED
|
||||||
OAUTH_STATE_EXPIRED
|
OAUTH_STATE_EXPIRED
|
||||||
PAGE_DEFAULT_ROLE_CAN_NOT_BE_OWNER
|
|
||||||
PAGE_IS_NOT_PUBLIC
|
|
||||||
PASSWORD_REQUIRED
|
PASSWORD_REQUIRED
|
||||||
QUERY_TOO_LONG
|
QUERY_TOO_LONG
|
||||||
RUNTIME_CONFIG_NOT_FOUND
|
RUNTIME_CONFIG_NOT_FOUND
|
||||||
@@ -621,7 +624,8 @@ type Mutation {
|
|||||||
invite(email: String!, permission: Permission @deprecated(reason: "never used"), sendInviteMail: Boolean, workspaceId: String!): String!
|
invite(email: String!, permission: Permission @deprecated(reason: "never used"), sendInviteMail: Boolean, workspaceId: String!): String!
|
||||||
inviteBatch(emails: [String!]!, sendInviteMail: Boolean, workspaceId: String!): [InviteResult!]!
|
inviteBatch(emails: [String!]!, sendInviteMail: Boolean, workspaceId: String!): [InviteResult!]!
|
||||||
leaveWorkspace(sendLeaveMail: Boolean, workspaceId: String!, workspaceName: String @deprecated(reason: "no longer used")): Boolean!
|
leaveWorkspace(sendLeaveMail: Boolean, workspaceId: String!, workspaceName: String @deprecated(reason: "no longer used")): Boolean!
|
||||||
publishPage(mode: PublicPageMode = Page, pageId: String!, workspaceId: String!): WorkspacePage!
|
publishDoc(docId: String!, mode: PublicDocMode = Page, workspaceId: String!): DocType!
|
||||||
|
publishPage(mode: PublicDocMode = Page, pageId: String!, workspaceId: String!): DocType! @deprecated(reason: "use publishDoc instead")
|
||||||
recoverDoc(guid: String!, timestamp: DateTime!, workspaceId: String!): DateTime!
|
recoverDoc(guid: String!, timestamp: DateTime!, workspaceId: String!): DateTime!
|
||||||
releaseDeletedBlobs(workspaceId: String!): Boolean!
|
releaseDeletedBlobs(workspaceId: String!): Boolean!
|
||||||
|
|
||||||
@@ -632,23 +636,22 @@ type Mutation {
|
|||||||
revoke(userId: String!, workspaceId: String!): Boolean!
|
revoke(userId: String!, workspaceId: String!): Boolean!
|
||||||
revokeDocUserRoles(input: RevokeDocUserRoleInput!): Boolean!
|
revokeDocUserRoles(input: RevokeDocUserRoleInput!): Boolean!
|
||||||
revokeInviteLink(workspaceId: String!): Boolean!
|
revokeInviteLink(workspaceId: String!): Boolean!
|
||||||
revokePage(pageId: String!, workspaceId: String!): Boolean! @deprecated(reason: "use revokePublicPage")
|
revokePublicDoc(docId: String!, workspaceId: String!): DocType!
|
||||||
revokePublicPage(pageId: String!, workspaceId: String!): WorkspacePage!
|
revokePublicPage(docId: String!, workspaceId: String!): DocType! @deprecated(reason: "use revokePublicDoc instead")
|
||||||
sendChangeEmail(callbackUrl: String!, email: String): Boolean!
|
sendChangeEmail(callbackUrl: String!, email: String): Boolean!
|
||||||
sendChangePasswordEmail(callbackUrl: String!, email: String @deprecated(reason: "fetched from signed in user")): Boolean!
|
sendChangePasswordEmail(callbackUrl: String!, email: String @deprecated(reason: "fetched from signed in user")): Boolean!
|
||||||
sendSetPasswordEmail(callbackUrl: String!, email: String @deprecated(reason: "fetched from signed in user")): Boolean!
|
sendSetPasswordEmail(callbackUrl: String!, email: String @deprecated(reason: "fetched from signed in user")): Boolean!
|
||||||
sendVerifyChangeEmail(callbackUrl: String!, email: String!, token: String!): Boolean!
|
sendVerifyChangeEmail(callbackUrl: String!, email: String!, token: String!): Boolean!
|
||||||
sendVerifyEmail(callbackUrl: String!): Boolean!
|
sendVerifyEmail(callbackUrl: String!): Boolean!
|
||||||
setBlob(blob: Upload!, workspaceId: String!): String!
|
setBlob(blob: Upload!, workspaceId: String!): String!
|
||||||
sharePage(pageId: String!, workspaceId: String!): Boolean! @deprecated(reason: "renamed to publishPage")
|
|
||||||
|
|
||||||
"""Update a copilot prompt"""
|
"""Update a copilot prompt"""
|
||||||
updateCopilotPrompt(messages: [CopilotPromptMessageInput!]!, name: String!): CopilotPromptType!
|
updateCopilotPrompt(messages: [CopilotPromptMessageInput!]!, name: String!): CopilotPromptType!
|
||||||
|
|
||||||
"""Update a chat session"""
|
"""Update a chat session"""
|
||||||
updateCopilotSession(options: UpdateChatSessionInput!): String!
|
updateCopilotSession(options: UpdateChatSessionInput!): String!
|
||||||
|
updateDocDefaultRole(input: UpdateDocDefaultRoleInput!): Boolean!
|
||||||
updateDocUserRole(input: UpdateDocUserRoleInput!): Boolean!
|
updateDocUserRole(input: UpdateDocUserRoleInput!): Boolean!
|
||||||
updatePageDefaultRole(input: UpdatePageDefaultRoleInput!): Boolean!
|
|
||||||
updateProfile(input: UpdateUserInput!): UserType!
|
updateProfile(input: UpdateUserInput!): UserType!
|
||||||
|
|
||||||
"""update server runtime configurable setting"""
|
"""update server runtime configurable setting"""
|
||||||
@@ -719,8 +722,8 @@ enum Permission {
|
|||||||
Owner
|
Owner
|
||||||
}
|
}
|
||||||
|
|
||||||
"""The mode which the public page default in"""
|
"""The mode which the public doc default in"""
|
||||||
enum PublicPageMode {
|
enum PublicDocMode {
|
||||||
Edgeless
|
Edgeless
|
||||||
Page
|
Page
|
||||||
}
|
}
|
||||||
@@ -1005,6 +1008,12 @@ input UpdateChatSessionInput {
|
|||||||
sessionId: String!
|
sessionId: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input UpdateDocDefaultRoleInput {
|
||||||
|
docId: String!
|
||||||
|
role: DocRole!
|
||||||
|
workspaceId: String!
|
||||||
|
}
|
||||||
|
|
||||||
input UpdateDocUserRoleInput {
|
input UpdateDocUserRoleInput {
|
||||||
docId: String!
|
docId: String!
|
||||||
role: DocRole!
|
role: DocRole!
|
||||||
@@ -1012,12 +1021,6 @@ input UpdateDocUserRoleInput {
|
|||||||
workspaceId: String!
|
workspaceId: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdatePageDefaultRoleInput {
|
|
||||||
docId: String!
|
|
||||||
role: DocRole!
|
|
||||||
workspaceId: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
input UpdateUserInput {
|
input UpdateUserInput {
|
||||||
"""User name"""
|
"""User name"""
|
||||||
name: String
|
name: String
|
||||||
@@ -1128,13 +1131,6 @@ type WorkspaceMembersExceedLimitToDowngradeDataType {
|
|||||||
limit: Int!
|
limit: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
type WorkspacePage {
|
|
||||||
id: String!
|
|
||||||
mode: PublicPageMode!
|
|
||||||
public: Boolean!
|
|
||||||
workspaceId: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
type WorkspacePageMeta {
|
type WorkspacePageMeta {
|
||||||
createdAt: DateTime!
|
createdAt: DateTime!
|
||||||
createdBy: EditorType
|
createdBy: EditorType
|
||||||
@@ -1199,6 +1195,9 @@ type WorkspaceType {
|
|||||||
"""Workspace created date"""
|
"""Workspace created date"""
|
||||||
createdAt: DateTime!
|
createdAt: DateTime!
|
||||||
|
|
||||||
|
"""Get get with given id"""
|
||||||
|
doc(docId: String!): DocType!
|
||||||
|
|
||||||
"""Enable AI"""
|
"""Enable AI"""
|
||||||
enableAi: Boolean!
|
enableAi: Boolean!
|
||||||
|
|
||||||
@@ -1229,23 +1228,21 @@ type WorkspaceType {
|
|||||||
"""Owner of workspace"""
|
"""Owner of workspace"""
|
||||||
owner: UserType!
|
owner: UserType!
|
||||||
|
|
||||||
"""Page granted users list"""
|
|
||||||
pageGrantedUsersList(pageId: String!, pagination: PaginationInput!): PaginatedGrantedDocUserType!
|
|
||||||
|
|
||||||
"""Cloud page metadata of workspace"""
|
"""Cloud page metadata of workspace"""
|
||||||
pageMeta(pageId: String!): WorkspacePageMeta!
|
pageMeta(pageId: String!): WorkspacePageMeta!
|
||||||
|
|
||||||
"""Check if current user has permission to access the page"""
|
|
||||||
pagePermission(pageId: String!): DocType!
|
|
||||||
|
|
||||||
"""is Public workspace"""
|
"""is Public workspace"""
|
||||||
public: Boolean!
|
public: Boolean!
|
||||||
|
|
||||||
"""Get public page of a workspace by page id."""
|
"""Get public page of a workspace by page id."""
|
||||||
publicPage(pageId: String!): WorkspacePage
|
publicDoc(docId: String!): DocType
|
||||||
|
|
||||||
"""Public pages of a workspace"""
|
"""Get public docs of a workspace"""
|
||||||
publicPages: [WorkspacePage!]!
|
publicDocs: [DocType!]!
|
||||||
|
|
||||||
|
"""Get public page of a workspace by page id."""
|
||||||
|
publicPage(pageId: String!): DocType @deprecated(reason: "use [WorkspaceType.publicDoc] instead")
|
||||||
|
publicPages: [DocType!]! @deprecated(reason: "use [WorkspaceType.publicDocs] instead")
|
||||||
|
|
||||||
"""quota of workspace"""
|
"""quota of workspace"""
|
||||||
quota: WorkspaceQuotaType!
|
quota: WorkspaceQuotaType!
|
||||||
@@ -1253,9 +1250,6 @@ type WorkspaceType {
|
|||||||
"""Role of current signed in user in workspace"""
|
"""Role of current signed in user in workspace"""
|
||||||
role: Permission!
|
role: Permission!
|
||||||
|
|
||||||
"""Shared pages of workspace"""
|
|
||||||
sharedPages: [String!]! @deprecated(reason: "use WorkspaceType.publicPages")
|
|
||||||
|
|
||||||
"""The team subscription of the workspace, if exists."""
|
"""The team subscription of the workspace, if exists."""
|
||||||
subscription: SubscriptionType
|
subscription: SubscriptionType
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { ServerService } from '@affine/core/modules/cloud';
|
|||||||
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
|
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
|
||||||
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
|
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
|
||||||
import { ShareInfoService } from '@affine/core/modules/share-doc';
|
import { ShareInfoService } from '@affine/core/modules/share-doc';
|
||||||
import { PublicPageMode } from '@affine/graphql';
|
import { PublicDocMode } from '@affine/graphql';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { track } from '@affine/track';
|
import { track } from '@affine/track';
|
||||||
import {
|
import {
|
||||||
@@ -92,7 +92,7 @@ export const AFFiNESharePage = (props: ShareMenuProps) => {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// TODO(@JimmFly): remove mode when we have a better way to handle it
|
// TODO(@JimmFly): remove mode when we have a better way to handle it
|
||||||
await shareInfoService.shareInfo.enableShare(PublicPageMode.Page);
|
await shareInfoService.shareInfo.enableShare(PublicDocMode.Page);
|
||||||
track.$.sharePanel.$.createShareLink();
|
track.$.sharePanel.$.createShareLink();
|
||||||
notify.success({
|
notify.success({
|
||||||
title:
|
title:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { FavoriteTag } from '@affine/core/components/page-list/components/favori
|
|||||||
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/favorite';
|
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/favorite';
|
||||||
import { ShareDocsListService } from '@affine/core/modules/share-doc';
|
import { ShareDocsListService } from '@affine/core/modules/share-doc';
|
||||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||||
import { PublicPageMode } from '@affine/graphql';
|
import { PublicDocMode } from '@affine/graphql';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import type { DocMeta, Workspace } from '@blocksuite/affine/store';
|
import type { DocMeta, Workspace } from '@blocksuite/affine/store';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
@@ -68,9 +68,9 @@ export const useAllPageListConfig = () => {
|
|||||||
allPages: pageMetas,
|
allPages: pageMetas,
|
||||||
getPublicMode(id) {
|
getPublicMode(id) {
|
||||||
const mode = shareDocs?.find(shareDoc => shareDoc.id === id)?.mode;
|
const mode = shareDocs?.find(shareDoc => shareDoc.id === id)?.mode;
|
||||||
if (mode === PublicPageMode.Edgeless) {
|
if (mode === PublicDocMode.Edgeless) {
|
||||||
return 'edgeless';
|
return 'edgeless';
|
||||||
} else if (mode === PublicPageMode.Page) {
|
} else if (mode === PublicDocMode.Page) {
|
||||||
return 'page';
|
return 'page';
|
||||||
} else {
|
} else {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useBlockSuiteDocMeta } from '@affine/core/components/hooks/use-block-su
|
|||||||
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/favorite';
|
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/favorite';
|
||||||
import { ShareDocsListService } from '@affine/core/modules/share-doc';
|
import { ShareDocsListService } from '@affine/core/modules/share-doc';
|
||||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||||
import { PublicPageMode } from '@affine/graphql';
|
import { PublicDocMode } from '@affine/graphql';
|
||||||
import { Trans, useI18n } from '@affine/i18n';
|
import { Trans, useI18n } from '@affine/i18n';
|
||||||
import type { DocMeta } from '@blocksuite/affine/store';
|
import type { DocMeta } from '@blocksuite/affine/store';
|
||||||
import { FilterIcon } from '@blocksuite/icons/rc';
|
import { FilterIcon } from '@blocksuite/icons/rc';
|
||||||
@@ -76,9 +76,9 @@ export const SelectPage = ({
|
|||||||
const getPublicMode = useCallback(
|
const getPublicMode = useCallback(
|
||||||
(id: string) => {
|
(id: string) => {
|
||||||
const mode = shareDocs?.find(shareDoc => shareDoc.id === id)?.mode;
|
const mode = shareDocs?.find(shareDoc => shareDoc.id === id)?.mode;
|
||||||
if (mode === PublicPageMode.Edgeless) {
|
if (mode === PublicDocMode.Edgeless) {
|
||||||
return 'edgeless';
|
return 'edgeless';
|
||||||
} else if (mode === PublicPageMode.Page) {
|
} else if (mode === PublicDocMode.Page) {
|
||||||
return 'page';
|
return 'page';
|
||||||
} else {
|
} else {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/favorite';
|
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/favorite';
|
||||||
import { ShareDocsListService } from '@affine/core/modules/share-doc';
|
import { ShareDocsListService } from '@affine/core/modules/share-doc';
|
||||||
import type { Collection, Filter } from '@affine/env/filter';
|
import type { Collection, Filter } from '@affine/env/filter';
|
||||||
import { PublicPageMode } from '@affine/graphql';
|
import { PublicDocMode } from '@affine/graphql';
|
||||||
import type { DocMeta } from '@blocksuite/affine/store';
|
import type { DocMeta } from '@blocksuite/affine/store';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
import { useCallback, useEffect, useMemo } from 'react';
|
import { useCallback, useEffect, useMemo } from 'react';
|
||||||
@@ -23,7 +23,7 @@ export const useFilteredPageMetas = (
|
|||||||
(id: string) => {
|
(id: string) => {
|
||||||
const mode = shareDocs?.find(shareDoc => shareDoc.id === id)?.mode;
|
const mode = shareDocs?.find(shareDoc => shareDoc.id === id)?.mode;
|
||||||
return mode
|
return mode
|
||||||
? mode === PublicPageMode.Edgeless
|
? mode === PublicDocMode.Edgeless
|
||||||
? ('edgeless' as const)
|
? ('edgeless' as const)
|
||||||
: ('page' as const)
|
: ('page' as const)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/favorite';
|
|||||||
import { GlobalContextService } from '@affine/core/modules/global-context';
|
import { GlobalContextService } from '@affine/core/modules/global-context';
|
||||||
import { ShareDocsListService } from '@affine/core/modules/share-doc';
|
import { ShareDocsListService } from '@affine/core/modules/share-doc';
|
||||||
import type { Collection } from '@affine/env/filter';
|
import type { Collection } from '@affine/env/filter';
|
||||||
import { PublicPageMode } from '@affine/graphql';
|
import { PublicDocMode } from '@affine/graphql';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import track from '@affine/track';
|
import track from '@affine/track';
|
||||||
import type { DocMeta } from '@blocksuite/affine/store';
|
import type { DocMeta } from '@blocksuite/affine/store';
|
||||||
@@ -161,9 +161,9 @@ const ExplorerCollectionNodeChildren = ({
|
|||||||
const pageData = {
|
const pageData = {
|
||||||
meta: meta as DocMeta,
|
meta: meta as DocMeta,
|
||||||
publicMode:
|
publicMode:
|
||||||
publicMode === PublicPageMode.Edgeless
|
publicMode === PublicDocMode.Edgeless
|
||||||
? ('edgeless' as const)
|
? ('edgeless' as const)
|
||||||
: publicMode === PublicPageMode.Page
|
: publicMode === PublicDocMode.Page
|
||||||
? ('page' as const)
|
? ('page' as const)
|
||||||
: undefined,
|
: undefined,
|
||||||
favorite: favourites.some(fav => fav.id === meta.id),
|
favorite: favourites.some(fav => fav.id === meta.id),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { GlobalContextService } from '@affine/core/modules/global-context';
|
|||||||
import { ShareDocsListService } from '@affine/core/modules/share-doc';
|
import { ShareDocsListService } from '@affine/core/modules/share-doc';
|
||||||
import type { AffineDNDData } from '@affine/core/types/dnd';
|
import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||||
import type { Collection } from '@affine/env/filter';
|
import type { Collection } from '@affine/env/filter';
|
||||||
import { PublicPageMode } from '@affine/graphql';
|
import { PublicDocMode } from '@affine/graphql';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { track } from '@affine/track';
|
import { track } from '@affine/track';
|
||||||
import type { DocMeta } from '@blocksuite/affine/store';
|
import type { DocMeta } from '@blocksuite/affine/store';
|
||||||
@@ -283,9 +283,9 @@ const ExplorerCollectionNodeChildren = ({
|
|||||||
const pageData = {
|
const pageData = {
|
||||||
meta: meta as DocMeta,
|
meta: meta as DocMeta,
|
||||||
publicMode:
|
publicMode:
|
||||||
publicMode === PublicPageMode.Edgeless
|
publicMode === PublicDocMode.Edgeless
|
||||||
? ('edgeless' as const)
|
? ('edgeless' as const)
|
||||||
: publicMode === PublicPageMode.Page
|
: publicMode === PublicDocMode.Page
|
||||||
? ('page' as const)
|
? ('page' as const)
|
||||||
: undefined,
|
: undefined,
|
||||||
favorite: favourites.some(fav => fav.id === meta.id),
|
favorite: favourites.some(fav => fav.id === meta.id),
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ import type { GlobalCache } from '../../storage';
|
|||||||
import type { WorkspaceService } from '../../workspace';
|
import type { WorkspaceService } from '../../workspace';
|
||||||
import type { ShareDocsStore } from '../stores/share-docs';
|
import type { ShareDocsStore } from '../stores/share-docs';
|
||||||
|
|
||||||
type ShareDocListType =
|
type ShareDocListType = GetWorkspacePublicPagesQuery['workspace']['publicDocs'];
|
||||||
GetWorkspacePublicPagesQuery['workspace']['publicPages'];
|
|
||||||
|
|
||||||
export const logger = new DebugLogger('affine:share-doc-list');
|
export const logger = new DebugLogger('affine:share-doc-list');
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type {
|
import type {
|
||||||
GetWorkspacePublicPageByIdQuery,
|
GetWorkspacePublicPageByIdQuery,
|
||||||
PublicPageMode,
|
PublicDocMode,
|
||||||
} from '@affine/graphql';
|
} from '@affine/graphql';
|
||||||
import {
|
import {
|
||||||
backoffRetry,
|
backoffRetry,
|
||||||
@@ -20,7 +20,7 @@ import type { DocService } from '../../doc';
|
|||||||
import type { WorkspaceService } from '../../workspace';
|
import type { WorkspaceService } from '../../workspace';
|
||||||
import type { ShareStore } from '../stores/share';
|
import type { ShareStore } from '../stores/share';
|
||||||
|
|
||||||
type ShareInfoType = GetWorkspacePublicPageByIdQuery['workspace']['publicPage'];
|
type ShareInfoType = GetWorkspacePublicPageByIdQuery['workspace']['publicDoc'];
|
||||||
|
|
||||||
export class ShareInfo extends Entity {
|
export class ShareInfo extends Entity {
|
||||||
info$ = new LiveData<ShareInfoType | undefined | null>(null);
|
info$ = new LiveData<ShareInfoType | undefined | null>(null);
|
||||||
@@ -70,7 +70,7 @@ export class ShareInfo extends Entity {
|
|||||||
return this.isRevalidating$.waitFor(v => v === false, signal);
|
return this.isRevalidating$.waitFor(v => v === false, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
async enableShare(mode: PublicPageMode) {
|
async enableShare(mode: PublicDocMode) {
|
||||||
await this.store.enableSharePage(
|
await this.store.enableSharePage(
|
||||||
this.workspaceService.workspace.id,
|
this.workspaceService.workspace.id,
|
||||||
this.docService.doc.id,
|
this.docService.doc.id,
|
||||||
@@ -79,7 +79,7 @@ export class ShareInfo extends Entity {
|
|||||||
await this.waitForRevalidation();
|
await this.waitForRevalidation();
|
||||||
}
|
}
|
||||||
|
|
||||||
async changeShare(mode: PublicPageMode) {
|
async changeShare(mode: PublicDocMode) {
|
||||||
await this.enableShare(mode);
|
await this.enableShare(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,6 @@ export class ShareDocsStore extends Store {
|
|||||||
signal,
|
signal,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return data.workspace.publicPages;
|
return data.workspace.publicDocs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { PublicPageMode } from '@affine/graphql';
|
import type { PublicDocMode } from '@affine/graphql';
|
||||||
import {
|
import {
|
||||||
getWorkspacePublicPageByIdQuery,
|
getWorkspacePublicPageByIdQuery,
|
||||||
publishPageMutation,
|
publishPageMutation,
|
||||||
@@ -31,13 +31,13 @@ export class ShareStore extends Store {
|
|||||||
signal,
|
signal,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return data.workspace.publicPage ?? undefined;
|
return data.workspace.publicDoc ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async enableSharePage(
|
async enableSharePage(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
pageId: string,
|
pageId: string,
|
||||||
docMode?: PublicPageMode,
|
docMode?: PublicDocMode,
|
||||||
signal?: AbortSignal
|
signal?: AbortSignal
|
||||||
) {
|
) {
|
||||||
if (!this.workspaceServerService.server) {
|
if (!this.workspaceServerService.server) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
query getWorkspacePublicPageById($workspaceId: String!, $pageId: String!) {
|
query getWorkspacePublicPageById($workspaceId: String!, $pageId: String!) {
|
||||||
workspace(id: $workspaceId) {
|
workspace(id: $workspaceId) {
|
||||||
publicPage(pageId: $pageId) {
|
publicDoc(docId: $pageId) {
|
||||||
id
|
id
|
||||||
mode
|
mode
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
query getWorkspacePublicPages($workspaceId: String!) {
|
query getWorkspacePublicPages($workspaceId: String!) {
|
||||||
workspace(id: $workspaceId) {
|
workspace(id: $workspaceId) {
|
||||||
publicPages {
|
publicDocs {
|
||||||
id
|
id
|
||||||
mode
|
mode
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -752,7 +752,7 @@ export const getWorkspacePublicPageByIdQuery = {
|
|||||||
query: `
|
query: `
|
||||||
query getWorkspacePublicPageById($workspaceId: String!, $pageId: String!) {
|
query getWorkspacePublicPageById($workspaceId: String!, $pageId: String!) {
|
||||||
workspace(id: $workspaceId) {
|
workspace(id: $workspaceId) {
|
||||||
publicPage(pageId: $pageId) {
|
publicDoc(docId: $pageId) {
|
||||||
id
|
id
|
||||||
mode
|
mode
|
||||||
}
|
}
|
||||||
@@ -768,7 +768,7 @@ export const getWorkspacePublicPagesQuery = {
|
|||||||
query: `
|
query: `
|
||||||
query getWorkspacePublicPages($workspaceId: String!) {
|
query getWorkspacePublicPages($workspaceId: String!) {
|
||||||
workspace(id: $workspaceId) {
|
workspace(id: $workspaceId) {
|
||||||
publicPages {
|
publicDocs {
|
||||||
id
|
id
|
||||||
mode
|
mode
|
||||||
}
|
}
|
||||||
@@ -937,11 +937,11 @@ query prices {
|
|||||||
export const publishPageMutation = {
|
export const publishPageMutation = {
|
||||||
id: 'publishPageMutation' as const,
|
id: 'publishPageMutation' as const,
|
||||||
operationName: 'publishPage',
|
operationName: 'publishPage',
|
||||||
definitionName: 'publishPage',
|
definitionName: 'publishDoc',
|
||||||
containsFile: false,
|
containsFile: false,
|
||||||
query: `
|
query: `
|
||||||
mutation publishPage($workspaceId: String!, $pageId: String!, $mode: PublicPageMode = Page) {
|
mutation publishPage($workspaceId: String!, $pageId: String!, $mode: PublicDocMode = Page) {
|
||||||
publishPage(workspaceId: $workspaceId, pageId: $pageId, mode: $mode) {
|
publishDoc(workspaceId: $workspaceId, docId: $pageId, mode: $mode) {
|
||||||
id
|
id
|
||||||
mode
|
mode
|
||||||
}
|
}
|
||||||
@@ -1033,11 +1033,11 @@ mutation revokeMemberPermission($workspaceId: String!, $userId: String!) {
|
|||||||
export const revokePublicPageMutation = {
|
export const revokePublicPageMutation = {
|
||||||
id: 'revokePublicPageMutation' as const,
|
id: 'revokePublicPageMutation' as const,
|
||||||
operationName: 'revokePublicPage',
|
operationName: 'revokePublicPage',
|
||||||
definitionName: 'revokePublicPage',
|
definitionName: 'revokePublicDoc',
|
||||||
containsFile: false,
|
containsFile: false,
|
||||||
query: `
|
query: `
|
||||||
mutation revokePublicPage($workspaceId: String!, $pageId: String!) {
|
mutation revokePublicPage($workspaceId: String!, $pageId: String!) {
|
||||||
revokePublicPage(workspaceId: $workspaceId, pageId: $pageId) {
|
revokePublicDoc(workspaceId: $workspaceId, docId: $pageId) {
|
||||||
id
|
id
|
||||||
mode
|
mode
|
||||||
public
|
public
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
mutation publishPage(
|
mutation publishPage(
|
||||||
$workspaceId: String!
|
$workspaceId: String!
|
||||||
$pageId: String!
|
$pageId: String!
|
||||||
$mode: PublicPageMode = Page
|
$mode: PublicDocMode = Page
|
||||||
) {
|
) {
|
||||||
publishPage(workspaceId: $workspaceId, pageId: $pageId, mode: $mode) {
|
publishDoc(workspaceId: $workspaceId, docId: $pageId, mode: $mode) {
|
||||||
id
|
id
|
||||||
mode
|
mode
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
mutation revokePublicPage($workspaceId: String!, $pageId: String!) {
|
mutation revokePublicPage($workspaceId: String!, $pageId: String!) {
|
||||||
revokePublicPage(workspaceId: $workspaceId, pageId: $pageId) {
|
revokePublicDoc(workspaceId: $workspaceId, docId: $pageId) {
|
||||||
id
|
id
|
||||||
mode
|
mode
|
||||||
public
|
public
|
||||||
|
|||||||
@@ -253,6 +253,23 @@ export interface DocNotFoundDataType {
|
|||||||
spaceId: Scalars['String']['output'];
|
spaceId: Scalars['String']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DocPermissions {
|
||||||
|
__typename?: 'DocPermissions';
|
||||||
|
Doc_Copy: Scalars['Boolean']['output'];
|
||||||
|
Doc_Delete: Scalars['Boolean']['output'];
|
||||||
|
Doc_Duplicate: Scalars['Boolean']['output'];
|
||||||
|
Doc_Properties_Read: Scalars['Boolean']['output'];
|
||||||
|
Doc_Properties_Update: Scalars['Boolean']['output'];
|
||||||
|
Doc_Publish: Scalars['Boolean']['output'];
|
||||||
|
Doc_Read: Scalars['Boolean']['output'];
|
||||||
|
Doc_Restore: Scalars['Boolean']['output'];
|
||||||
|
Doc_TransferOwner: Scalars['Boolean']['output'];
|
||||||
|
Doc_Trash: Scalars['Boolean']['output'];
|
||||||
|
Doc_Update: Scalars['Boolean']['output'];
|
||||||
|
Doc_Users_Manage: Scalars['Boolean']['output'];
|
||||||
|
Doc_Users_Read: Scalars['Boolean']['output'];
|
||||||
|
}
|
||||||
|
|
||||||
/** User permission in doc */
|
/** User permission in doc */
|
||||||
export enum DocRole {
|
export enum DocRole {
|
||||||
Editor = 'Editor',
|
Editor = 'Editor',
|
||||||
@@ -264,10 +281,17 @@ export enum DocRole {
|
|||||||
|
|
||||||
export interface DocType {
|
export interface DocType {
|
||||||
__typename?: 'DocType';
|
__typename?: 'DocType';
|
||||||
|
/** paginated doc granted users list */
|
||||||
|
grantedUsersList: PaginatedGrantedDocUserType;
|
||||||
id: Scalars['String']['output'];
|
id: Scalars['String']['output'];
|
||||||
permissions: RolePermissions;
|
mode: PublicDocMode;
|
||||||
|
permissions: DocPermissions;
|
||||||
public: Scalars['Boolean']['output'];
|
public: Scalars['Boolean']['output'];
|
||||||
role: DocRole;
|
workspaceId: Scalars['String']['output'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DocTypeGrantedUsersListArgs {
|
||||||
|
pagination: PaginationInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EditorType {
|
export interface EditorType {
|
||||||
@@ -337,16 +361,18 @@ export enum ErrorNames {
|
|||||||
COPILOT_SESSION_NOT_FOUND = 'COPILOT_SESSION_NOT_FOUND',
|
COPILOT_SESSION_NOT_FOUND = 'COPILOT_SESSION_NOT_FOUND',
|
||||||
CUSTOMER_PORTAL_CREATE_FAILED = 'CUSTOMER_PORTAL_CREATE_FAILED',
|
CUSTOMER_PORTAL_CREATE_FAILED = 'CUSTOMER_PORTAL_CREATE_FAILED',
|
||||||
DOC_ACCESS_DENIED = 'DOC_ACCESS_DENIED',
|
DOC_ACCESS_DENIED = 'DOC_ACCESS_DENIED',
|
||||||
|
DOC_DEFAULT_ROLE_CAN_NOT_BE_OWNER = 'DOC_DEFAULT_ROLE_CAN_NOT_BE_OWNER',
|
||||||
DOC_HISTORY_NOT_FOUND = 'DOC_HISTORY_NOT_FOUND',
|
DOC_HISTORY_NOT_FOUND = 'DOC_HISTORY_NOT_FOUND',
|
||||||
|
DOC_IS_NOT_PUBLIC = 'DOC_IS_NOT_PUBLIC',
|
||||||
DOC_NOT_FOUND = 'DOC_NOT_FOUND',
|
DOC_NOT_FOUND = 'DOC_NOT_FOUND',
|
||||||
EARLY_ACCESS_REQUIRED = 'EARLY_ACCESS_REQUIRED',
|
EARLY_ACCESS_REQUIRED = 'EARLY_ACCESS_REQUIRED',
|
||||||
EMAIL_ALREADY_USED = 'EMAIL_ALREADY_USED',
|
EMAIL_ALREADY_USED = 'EMAIL_ALREADY_USED',
|
||||||
EMAIL_TOKEN_NOT_FOUND = 'EMAIL_TOKEN_NOT_FOUND',
|
EMAIL_TOKEN_NOT_FOUND = 'EMAIL_TOKEN_NOT_FOUND',
|
||||||
EMAIL_VERIFICATION_REQUIRED = 'EMAIL_VERIFICATION_REQUIRED',
|
EMAIL_VERIFICATION_REQUIRED = 'EMAIL_VERIFICATION_REQUIRED',
|
||||||
EXPECT_TO_GRANT_DOC_USER_ROLES = 'EXPECT_TO_GRANT_DOC_USER_ROLES',
|
EXPECT_TO_GRANT_DOC_USER_ROLES = 'EXPECT_TO_GRANT_DOC_USER_ROLES',
|
||||||
EXPECT_TO_PUBLISH_PAGE = 'EXPECT_TO_PUBLISH_PAGE',
|
EXPECT_TO_PUBLISH_DOC = 'EXPECT_TO_PUBLISH_DOC',
|
||||||
EXPECT_TO_REVOKE_DOC_USER_ROLES = 'EXPECT_TO_REVOKE_DOC_USER_ROLES',
|
EXPECT_TO_REVOKE_DOC_USER_ROLES = 'EXPECT_TO_REVOKE_DOC_USER_ROLES',
|
||||||
EXPECT_TO_REVOKE_PUBLIC_PAGE = 'EXPECT_TO_REVOKE_PUBLIC_PAGE',
|
EXPECT_TO_REVOKE_PUBLIC_DOC = 'EXPECT_TO_REVOKE_PUBLIC_DOC',
|
||||||
EXPECT_TO_UPDATE_DOC_USER_ROLE = 'EXPECT_TO_UPDATE_DOC_USER_ROLE',
|
EXPECT_TO_UPDATE_DOC_USER_ROLE = 'EXPECT_TO_UPDATE_DOC_USER_ROLE',
|
||||||
FAILED_TO_CHECKOUT = 'FAILED_TO_CHECKOUT',
|
FAILED_TO_CHECKOUT = 'FAILED_TO_CHECKOUT',
|
||||||
FAILED_TO_SAVE_UPDATES = 'FAILED_TO_SAVE_UPDATES',
|
FAILED_TO_SAVE_UPDATES = 'FAILED_TO_SAVE_UPDATES',
|
||||||
@@ -375,7 +401,6 @@ export enum ErrorNames {
|
|||||||
NO_COPILOT_PROVIDER_AVAILABLE = 'NO_COPILOT_PROVIDER_AVAILABLE',
|
NO_COPILOT_PROVIDER_AVAILABLE = 'NO_COPILOT_PROVIDER_AVAILABLE',
|
||||||
OAUTH_ACCOUNT_ALREADY_CONNECTED = 'OAUTH_ACCOUNT_ALREADY_CONNECTED',
|
OAUTH_ACCOUNT_ALREADY_CONNECTED = 'OAUTH_ACCOUNT_ALREADY_CONNECTED',
|
||||||
OAUTH_STATE_EXPIRED = 'OAUTH_STATE_EXPIRED',
|
OAUTH_STATE_EXPIRED = 'OAUTH_STATE_EXPIRED',
|
||||||
PAGE_IS_NOT_PUBLIC = 'PAGE_IS_NOT_PUBLIC',
|
|
||||||
PASSWORD_REQUIRED = 'PASSWORD_REQUIRED',
|
PASSWORD_REQUIRED = 'PASSWORD_REQUIRED',
|
||||||
QUERY_TOO_LONG = 'QUERY_TOO_LONG',
|
QUERY_TOO_LONG = 'QUERY_TOO_LONG',
|
||||||
RUNTIME_CONFIG_NOT_FOUND = 'RUNTIME_CONFIG_NOT_FOUND',
|
RUNTIME_CONFIG_NOT_FOUND = 'RUNTIME_CONFIG_NOT_FOUND',
|
||||||
@@ -453,23 +478,16 @@ export interface GrantDocUserRolesInput {
|
|||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GrantedDocUserEdge {
|
|
||||||
__typename?: 'GrantedDocUserEdge';
|
|
||||||
cursor: Scalars['String']['output'];
|
|
||||||
user: GrantedDocUserType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GrantedDocUserType {
|
export interface GrantedDocUserType {
|
||||||
__typename?: 'GrantedDocUserType';
|
__typename?: 'GrantedDocUserType';
|
||||||
role: DocRole;
|
role: DocRole;
|
||||||
user: UserType;
|
user: PublicUserType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GrantedDocUsersConnection {
|
export interface GrantedDocUserTypeEdge {
|
||||||
__typename?: 'GrantedDocUsersConnection';
|
__typename?: 'GrantedDocUserTypeEdge';
|
||||||
edges: Array<GrantedDocUserEdge>;
|
cursor: Scalars['String']['output'];
|
||||||
pageInfo: PageInfo;
|
node: GrantedDocUserType;
|
||||||
totalCount: Scalars['Int']['output'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InvalidEmailDataType {
|
export interface InvalidEmailDataType {
|
||||||
@@ -688,7 +706,9 @@ export interface Mutation {
|
|||||||
invite: Scalars['String']['output'];
|
invite: Scalars['String']['output'];
|
||||||
inviteBatch: Array<InviteResult>;
|
inviteBatch: Array<InviteResult>;
|
||||||
leaveWorkspace: Scalars['Boolean']['output'];
|
leaveWorkspace: Scalars['Boolean']['output'];
|
||||||
publishPage: WorkspacePage;
|
publishDoc: DocType;
|
||||||
|
/** @deprecated use publishDoc instead */
|
||||||
|
publishPage: DocType;
|
||||||
recoverDoc: Scalars['DateTime']['output'];
|
recoverDoc: Scalars['DateTime']['output'];
|
||||||
releaseDeletedBlobs: Scalars['Boolean']['output'];
|
releaseDeletedBlobs: Scalars['Boolean']['output'];
|
||||||
/** Remove user avatar */
|
/** Remove user avatar */
|
||||||
@@ -698,21 +718,20 @@ export interface Mutation {
|
|||||||
revoke: Scalars['Boolean']['output'];
|
revoke: Scalars['Boolean']['output'];
|
||||||
revokeDocUserRoles: Scalars['Boolean']['output'];
|
revokeDocUserRoles: Scalars['Boolean']['output'];
|
||||||
revokeInviteLink: Scalars['Boolean']['output'];
|
revokeInviteLink: Scalars['Boolean']['output'];
|
||||||
/** @deprecated use revokePublicPage */
|
revokePublicDoc: DocType;
|
||||||
revokePage: Scalars['Boolean']['output'];
|
/** @deprecated use revokePublicDoc instead */
|
||||||
revokePublicPage: WorkspacePage;
|
revokePublicPage: DocType;
|
||||||
sendChangeEmail: Scalars['Boolean']['output'];
|
sendChangeEmail: Scalars['Boolean']['output'];
|
||||||
sendChangePasswordEmail: Scalars['Boolean']['output'];
|
sendChangePasswordEmail: Scalars['Boolean']['output'];
|
||||||
sendSetPasswordEmail: Scalars['Boolean']['output'];
|
sendSetPasswordEmail: Scalars['Boolean']['output'];
|
||||||
sendVerifyChangeEmail: Scalars['Boolean']['output'];
|
sendVerifyChangeEmail: Scalars['Boolean']['output'];
|
||||||
sendVerifyEmail: Scalars['Boolean']['output'];
|
sendVerifyEmail: Scalars['Boolean']['output'];
|
||||||
setBlob: Scalars['String']['output'];
|
setBlob: Scalars['String']['output'];
|
||||||
/** @deprecated renamed to publishPage */
|
|
||||||
sharePage: Scalars['Boolean']['output'];
|
|
||||||
/** Update a copilot prompt */
|
/** Update a copilot prompt */
|
||||||
updateCopilotPrompt: CopilotPromptType;
|
updateCopilotPrompt: CopilotPromptType;
|
||||||
/** Update a chat session */
|
/** Update a chat session */
|
||||||
updateCopilotSession: Scalars['String']['output'];
|
updateCopilotSession: Scalars['String']['output'];
|
||||||
|
updateDocDefaultRole: Scalars['Boolean']['output'];
|
||||||
updateDocUserRole: Scalars['Boolean']['output'];
|
updateDocUserRole: Scalars['Boolean']['output'];
|
||||||
updateProfile: UserType;
|
updateProfile: UserType;
|
||||||
/** update server runtime configurable setting */
|
/** update server runtime configurable setting */
|
||||||
@@ -867,8 +886,14 @@ export interface MutationLeaveWorkspaceArgs {
|
|||||||
workspaceName?: InputMaybe<Scalars['String']['input']>;
|
workspaceName?: InputMaybe<Scalars['String']['input']>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MutationPublishDocArgs {
|
||||||
|
docId: Scalars['String']['input'];
|
||||||
|
mode?: InputMaybe<PublicDocMode>;
|
||||||
|
workspaceId: Scalars['String']['input'];
|
||||||
|
}
|
||||||
|
|
||||||
export interface MutationPublishPageArgs {
|
export interface MutationPublishPageArgs {
|
||||||
mode?: InputMaybe<PublicPageMode>;
|
mode?: InputMaybe<PublicDocMode>;
|
||||||
pageId: Scalars['String']['input'];
|
pageId: Scalars['String']['input'];
|
||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
@@ -900,21 +925,20 @@ export interface MutationRevokeArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface MutationRevokeDocUserRolesArgs {
|
export interface MutationRevokeDocUserRolesArgs {
|
||||||
docId: Scalars['String']['input'];
|
input: RevokeDocUserRolesInput;
|
||||||
userIds: Array<Scalars['String']['input']>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MutationRevokeInviteLinkArgs {
|
export interface MutationRevokeInviteLinkArgs {
|
||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MutationRevokePageArgs {
|
export interface MutationRevokePublicDocArgs {
|
||||||
pageId: Scalars['String']['input'];
|
docId: Scalars['String']['input'];
|
||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MutationRevokePublicPageArgs {
|
export interface MutationRevokePublicPageArgs {
|
||||||
pageId: Scalars['String']['input'];
|
docId: Scalars['String']['input'];
|
||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -948,11 +972,6 @@ export interface MutationSetBlobArgs {
|
|||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MutationSharePageArgs {
|
|
||||||
pageId: Scalars['String']['input'];
|
|
||||||
workspaceId: Scalars['String']['input'];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MutationUpdateCopilotPromptArgs {
|
export interface MutationUpdateCopilotPromptArgs {
|
||||||
messages: Array<CopilotPromptMessageInput>;
|
messages: Array<CopilotPromptMessageInput>;
|
||||||
name: Scalars['String']['input'];
|
name: Scalars['String']['input'];
|
||||||
@@ -962,10 +981,12 @@ export interface MutationUpdateCopilotSessionArgs {
|
|||||||
options: UpdateChatSessionInput;
|
options: UpdateChatSessionInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MutationUpdateDocDefaultRoleArgs {
|
||||||
|
input: UpdateDocDefaultRoleInput;
|
||||||
|
}
|
||||||
|
|
||||||
export interface MutationUpdateDocUserRoleArgs {
|
export interface MutationUpdateDocUserRoleArgs {
|
||||||
docId: Scalars['String']['input'];
|
input: UpdateDocUserRoleInput;
|
||||||
role: DocRole;
|
|
||||||
userId: Scalars['String']['input'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MutationUpdateProfileArgs {
|
export interface MutationUpdateProfileArgs {
|
||||||
@@ -1021,15 +1042,6 @@ export enum OAuthProviderType {
|
|||||||
OIDC = 'OIDC',
|
OIDC = 'OIDC',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PageGrantedUsersInput {
|
|
||||||
/** Cursor */
|
|
||||||
after?: InputMaybe<Scalars['String']['input']>;
|
|
||||||
/** Cursor */
|
|
||||||
before?: InputMaybe<Scalars['String']['input']>;
|
|
||||||
first: Scalars['Int']['input'];
|
|
||||||
offset: Scalars['Int']['input'];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PageInfo {
|
export interface PageInfo {
|
||||||
__typename?: 'PageInfo';
|
__typename?: 'PageInfo';
|
||||||
endCursor: Maybe<Scalars['String']['output']>;
|
endCursor: Maybe<Scalars['String']['output']>;
|
||||||
@@ -1038,6 +1050,22 @@ export interface PageInfo {
|
|||||||
startCursor: Maybe<Scalars['String']['output']>;
|
startCursor: Maybe<Scalars['String']['output']>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PaginatedGrantedDocUserType {
|
||||||
|
__typename?: 'PaginatedGrantedDocUserType';
|
||||||
|
edges: Array<GrantedDocUserTypeEdge>;
|
||||||
|
pageInfo: PageInfo;
|
||||||
|
totalCount: Scalars['Int']['output'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PaginationInput {
|
||||||
|
/** returns the elements in the list that come after the specified cursor. */
|
||||||
|
after?: InputMaybe<Scalars['String']['input']>;
|
||||||
|
/** returns the first n elements from the list. */
|
||||||
|
first?: InputMaybe<Scalars['Int']['input']>;
|
||||||
|
/** ignore the first n elements from the list. */
|
||||||
|
offset?: InputMaybe<Scalars['Int']['input']>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface PasswordLimitsType {
|
export interface PasswordLimitsType {
|
||||||
__typename?: 'PasswordLimitsType';
|
__typename?: 'PasswordLimitsType';
|
||||||
maxLength: Scalars['Int']['output'];
|
maxLength: Scalars['Int']['output'];
|
||||||
@@ -1052,12 +1080,20 @@ export enum Permission {
|
|||||||
Owner = 'Owner',
|
Owner = 'Owner',
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The mode which the public page default in */
|
/** The mode which the public doc default in */
|
||||||
export enum PublicPageMode {
|
export enum PublicDocMode {
|
||||||
Edgeless = 'Edgeless',
|
Edgeless = 'Edgeless',
|
||||||
Page = 'Page',
|
Page = 'Page',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PublicUserType {
|
||||||
|
__typename?: 'PublicUserType';
|
||||||
|
avatarUrl: Maybe<Scalars['String']['output']>;
|
||||||
|
email: Scalars['String']['output'];
|
||||||
|
id: Scalars['String']['output'];
|
||||||
|
name: Scalars['String']['output'];
|
||||||
|
}
|
||||||
|
|
||||||
export interface Query {
|
export interface Query {
|
||||||
__typename?: 'Query';
|
__typename?: 'Query';
|
||||||
/** @deprecated use `user.quotaUsage` instead */
|
/** @deprecated use `user.quotaUsage` instead */
|
||||||
@@ -1166,34 +1202,10 @@ export interface RemoveAvatar {
|
|||||||
success: Scalars['Boolean']['output'];
|
success: Scalars['Boolean']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RolePermissions {
|
export interface RevokeDocUserRolesInput {
|
||||||
__typename?: 'RolePermissions';
|
docId: Scalars['String']['input'];
|
||||||
Doc_Copy: Scalars['Boolean']['output'];
|
userIds: Array<Scalars['String']['input']>;
|
||||||
Doc_Delete: Scalars['Boolean']['output'];
|
workspaceId: Scalars['String']['input'];
|
||||||
Doc_Duplicate: Scalars['Boolean']['output'];
|
|
||||||
Doc_Properties_Read: Scalars['Boolean']['output'];
|
|
||||||
Doc_Properties_Update: Scalars['Boolean']['output'];
|
|
||||||
Doc_Publish: Scalars['Boolean']['output'];
|
|
||||||
Doc_Read: Scalars['Boolean']['output'];
|
|
||||||
Doc_Restore: Scalars['Boolean']['output'];
|
|
||||||
Doc_TransferOwner: Scalars['Boolean']['output'];
|
|
||||||
Doc_Trash: Scalars['Boolean']['output'];
|
|
||||||
Doc_Update: Scalars['Boolean']['output'];
|
|
||||||
Doc_Users_Manage: Scalars['Boolean']['output'];
|
|
||||||
Doc_Users_Read: Scalars['Boolean']['output'];
|
|
||||||
Workspace_CreateDoc: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Delete: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Organize_Read: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Properties_Create: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Properties_Delete: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Properties_Read: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Properties_Update: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Settings_Read: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Settings_Update: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Sync: Scalars['Boolean']['output'];
|
|
||||||
Workspace_TransferOwner: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Users_Manage: Scalars['Boolean']['output'];
|
|
||||||
Workspace_Users_Read: Scalars['Boolean']['output'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RuntimeConfigNotFoundDataType {
|
export interface RuntimeConfigNotFoundDataType {
|
||||||
@@ -1395,6 +1407,19 @@ export interface UpdateChatSessionInput {
|
|||||||
sessionId: Scalars['String']['input'];
|
sessionId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UpdateDocDefaultRoleInput {
|
||||||
|
docId: Scalars['String']['input'];
|
||||||
|
role: DocRole;
|
||||||
|
workspaceId: Scalars['String']['input'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateDocUserRoleInput {
|
||||||
|
docId: Scalars['String']['input'];
|
||||||
|
role: DocRole;
|
||||||
|
userId: Scalars['String']['input'];
|
||||||
|
workspaceId: Scalars['String']['input'];
|
||||||
|
}
|
||||||
|
|
||||||
export interface UpdateUserInput {
|
export interface UpdateUserInput {
|
||||||
/** User name */
|
/** User name */
|
||||||
name?: InputMaybe<Scalars['String']['input']>;
|
name?: InputMaybe<Scalars['String']['input']>;
|
||||||
@@ -1514,14 +1539,6 @@ export interface WorkspaceMembersExceedLimitToDowngradeDataType {
|
|||||||
limit: Scalars['Int']['output'];
|
limit: Scalars['Int']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkspacePage {
|
|
||||||
__typename?: 'WorkspacePage';
|
|
||||||
id: Scalars['String']['output'];
|
|
||||||
mode: PublicPageMode;
|
|
||||||
public: Scalars['Boolean']['output'];
|
|
||||||
workspaceId: Scalars['String']['output'];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WorkspacePageMeta {
|
export interface WorkspacePageMeta {
|
||||||
__typename?: 'WorkspacePageMeta';
|
__typename?: 'WorkspacePageMeta';
|
||||||
createdAt: Scalars['DateTime']['output'];
|
createdAt: Scalars['DateTime']['output'];
|
||||||
@@ -1591,6 +1608,8 @@ export interface WorkspaceType {
|
|||||||
blobsSize: Scalars['Int']['output'];
|
blobsSize: Scalars['Int']['output'];
|
||||||
/** Workspace created date */
|
/** Workspace created date */
|
||||||
createdAt: Scalars['DateTime']['output'];
|
createdAt: Scalars['DateTime']['output'];
|
||||||
|
/** Get get with given id */
|
||||||
|
doc: DocType;
|
||||||
/** Enable AI */
|
/** Enable AI */
|
||||||
enableAi: Scalars['Boolean']['output'];
|
enableAi: Scalars['Boolean']['output'];
|
||||||
/** Enable url previous when sharing */
|
/** Enable url previous when sharing */
|
||||||
@@ -1612,33 +1631,35 @@ export interface WorkspaceType {
|
|||||||
members: Array<InviteUserType>;
|
members: Array<InviteUserType>;
|
||||||
/** Owner of workspace */
|
/** Owner of workspace */
|
||||||
owner: UserType;
|
owner: UserType;
|
||||||
/** Page granted users list */
|
|
||||||
pageGrantedUsersList: GrantedDocUsersConnection;
|
|
||||||
/** Cloud page metadata of workspace */
|
/** Cloud page metadata of workspace */
|
||||||
pageMeta: WorkspacePageMeta;
|
pageMeta: WorkspacePageMeta;
|
||||||
/** Check if current user has permission to access the page */
|
|
||||||
pagePermission: DocType;
|
|
||||||
/** is Public workspace */
|
/** is Public workspace */
|
||||||
public: Scalars['Boolean']['output'];
|
public: Scalars['Boolean']['output'];
|
||||||
/** Get public page of a workspace by page id. */
|
/** Get public page of a workspace by page id. */
|
||||||
publicPage: Maybe<WorkspacePage>;
|
publicDoc: Maybe<DocType>;
|
||||||
/** Public pages of a workspace */
|
/** Get public docs of a workspace */
|
||||||
publicPages: Array<WorkspacePage>;
|
publicDocs: Array<DocType>;
|
||||||
|
/**
|
||||||
|
* Get public page of a workspace by page id.
|
||||||
|
* @deprecated use [WorkspaceType.publicDoc] instead
|
||||||
|
*/
|
||||||
|
publicPage: Maybe<DocType>;
|
||||||
|
/** @deprecated use [WorkspaceType.publicDocs] instead */
|
||||||
|
publicPages: Array<DocType>;
|
||||||
/** quota of workspace */
|
/** quota of workspace */
|
||||||
quota: WorkspaceQuotaType;
|
quota: WorkspaceQuotaType;
|
||||||
/** Role of current signed in user in workspace */
|
/** Role of current signed in user in workspace */
|
||||||
role: Permission;
|
role: Permission;
|
||||||
/**
|
|
||||||
* Shared pages of workspace
|
|
||||||
* @deprecated use WorkspaceType.publicPages
|
|
||||||
*/
|
|
||||||
sharedPages: Array<Scalars['String']['output']>;
|
|
||||||
/** The team subscription of the workspace, if exists. */
|
/** The team subscription of the workspace, if exists. */
|
||||||
subscription: Maybe<SubscriptionType>;
|
subscription: Maybe<SubscriptionType>;
|
||||||
/** if workspace is team workspace */
|
/** if workspace is team workspace */
|
||||||
team: Scalars['Boolean']['output'];
|
team: Scalars['Boolean']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WorkspaceTypeDocArgs {
|
||||||
|
docId: Scalars['String']['input'];
|
||||||
|
}
|
||||||
|
|
||||||
export interface WorkspaceTypeHistoriesArgs {
|
export interface WorkspaceTypeHistoriesArgs {
|
||||||
before?: InputMaybe<Scalars['DateTime']['input']>;
|
before?: InputMaybe<Scalars['DateTime']['input']>;
|
||||||
guid: Scalars['String']['input'];
|
guid: Scalars['String']['input'];
|
||||||
@@ -1656,17 +1677,12 @@ export interface WorkspaceTypeMembersArgs {
|
|||||||
take?: InputMaybe<Scalars['Int']['input']>;
|
take?: InputMaybe<Scalars['Int']['input']>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkspaceTypePageGrantedUsersListArgs {
|
|
||||||
pageGrantedUsersInput: PageGrantedUsersInput;
|
|
||||||
pageId: Scalars['String']['input'];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WorkspaceTypePageMetaArgs {
|
export interface WorkspaceTypePageMetaArgs {
|
||||||
pageId: Scalars['String']['input'];
|
pageId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkspaceTypePagePermissionArgs {
|
export interface WorkspaceTypePublicDocArgs {
|
||||||
pageId: Scalars['String']['input'];
|
docId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkspaceTypePublicPageArgs {
|
export interface WorkspaceTypePublicPageArgs {
|
||||||
@@ -2357,10 +2373,10 @@ export type GetWorkspacePublicPageByIdQuery = {
|
|||||||
__typename?: 'Query';
|
__typename?: 'Query';
|
||||||
workspace: {
|
workspace: {
|
||||||
__typename?: 'WorkspaceType';
|
__typename?: 'WorkspaceType';
|
||||||
publicPage: {
|
publicDoc: {
|
||||||
__typename?: 'WorkspacePage';
|
__typename?: 'DocType';
|
||||||
id: string;
|
id: string;
|
||||||
mode: PublicPageMode;
|
mode: PublicDocMode;
|
||||||
} | null;
|
} | null;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -2373,10 +2389,10 @@ export type GetWorkspacePublicPagesQuery = {
|
|||||||
__typename?: 'Query';
|
__typename?: 'Query';
|
||||||
workspace: {
|
workspace: {
|
||||||
__typename?: 'WorkspaceType';
|
__typename?: 'WorkspaceType';
|
||||||
publicPages: Array<{
|
publicDocs: Array<{
|
||||||
__typename?: 'WorkspacePage';
|
__typename?: 'DocType';
|
||||||
id: string;
|
id: string;
|
||||||
mode: PublicPageMode;
|
mode: PublicDocMode;
|
||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -2527,16 +2543,12 @@ export type PricesQuery = {
|
|||||||
export type PublishPageMutationVariables = Exact<{
|
export type PublishPageMutationVariables = Exact<{
|
||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
pageId: Scalars['String']['input'];
|
pageId: Scalars['String']['input'];
|
||||||
mode?: InputMaybe<PublicPageMode>;
|
mode?: InputMaybe<PublicDocMode>;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type PublishPageMutation = {
|
export type PublishPageMutation = {
|
||||||
__typename?: 'Mutation';
|
__typename?: 'Mutation';
|
||||||
publishPage: {
|
publishDoc: { __typename?: 'DocType'; id: string; mode: PublicDocMode };
|
||||||
__typename?: 'WorkspacePage';
|
|
||||||
id: string;
|
|
||||||
mode: PublicPageMode;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type QuotaQueryVariables = Exact<{ [key: string]: never }>;
|
export type QuotaQueryVariables = Exact<{ [key: string]: never }>;
|
||||||
@@ -2618,10 +2630,10 @@ export type RevokePublicPageMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type RevokePublicPageMutation = {
|
export type RevokePublicPageMutation = {
|
||||||
__typename?: 'Mutation';
|
__typename?: 'Mutation';
|
||||||
revokePublicPage: {
|
revokePublicDoc: {
|
||||||
__typename?: 'WorkspacePage';
|
__typename?: 'DocType';
|
||||||
id: string;
|
id: string;
|
||||||
mode: PublicPageMode;
|
mode: PublicDocMode;
|
||||||
public: boolean;
|
public: boolean;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user