fix(server): default page owner (#10015)
This commit is contained in:
@@ -39,15 +39,16 @@ export class PaginationInput {
|
|||||||
'returns the elements in the list that come after the specified cursor.',
|
'returns the elements in the list that come after the specified cursor.',
|
||||||
middleware: [parseCursorMiddleware],
|
middleware: [parseCursorMiddleware],
|
||||||
})
|
})
|
||||||
after!: string | null;
|
after?: string | null;
|
||||||
|
|
||||||
@Field(() => String, {
|
// NOT IMPLEMENTED YET
|
||||||
nullable: true,
|
// @Field(() => String, {
|
||||||
description:
|
// nullable: true,
|
||||||
'returns the elements in the list that come before the specified cursor.',
|
// description:
|
||||||
middleware: [parseCursorMiddleware],
|
// 'returns the elements in the list that come before the specified cursor.',
|
||||||
})
|
// middleware: [parseCursorMiddleware],
|
||||||
before!: string | null;
|
// })
|
||||||
|
// before?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const encode = (input: string) => Buffer.from(input).toString('base64');
|
const encode = (input: string) => Buffer.from(input).toString('base64');
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
import { Type } from '@nestjs/common';
|
import { Type } from '@nestjs/common';
|
||||||
import { Field, ObjectType } from '@nestjs/graphql';
|
import { Field, FieldOptions, ObjectType } from '@nestjs/graphql';
|
||||||
|
|
||||||
import { ApplyType } from '../utils/types';
|
import { ApplyType } from '../utils/types';
|
||||||
|
|
||||||
export function registerObjectType<T>(
|
export function registerObjectType<T>(
|
||||||
fields: Record<string, Type<any>>,
|
fields: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
type: () => Type<any>;
|
||||||
|
options?: FieldOptions;
|
||||||
|
}
|
||||||
|
>,
|
||||||
options: {
|
options: {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
const Inner = ApplyType<T>();
|
const Inner = ApplyType<T>();
|
||||||
for (const [key, value] of Object.entries(fields)) {
|
for (const [key, { type, options }] of Object.entries(fields)) {
|
||||||
Field(() => value)(Inner.prototype, key);
|
Field(type, options)(Inner.prototype, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectType(options.name)(Inner);
|
ObjectType(options.name)(Inner);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ declare global {
|
|||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
docId: string;
|
docId: string;
|
||||||
};
|
};
|
||||||
'doc.update.pushed': {
|
'doc.created': {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
docId: string;
|
docId: string;
|
||||||
editor?: string;
|
editor?: string;
|
||||||
@@ -63,6 +63,8 @@ export class PgWorkspaceDocStorageAdapter extends DocStorageAdapter {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isNewDoc = !(await this.docExisted(workspaceId, docId));
|
||||||
|
|
||||||
let pendings = updates;
|
let pendings = updates;
|
||||||
let done = 0;
|
let done = 0;
|
||||||
let timestamp = Date.now();
|
let timestamp = Date.now();
|
||||||
@@ -110,11 +112,14 @@ export class PgWorkspaceDocStorageAdapter extends DocStorageAdapter {
|
|||||||
await this.updateCachedUpdatesCount(workspaceId, docId, batch.length);
|
await this.updateCachedUpdatesCount(workspaceId, docId, batch.length);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.event.emit('doc.update.pushed', {
|
|
||||||
|
if (isNewDoc) {
|
||||||
|
this.event.emit('doc.created', {
|
||||||
workspaceId,
|
workspaceId,
|
||||||
docId,
|
docId,
|
||||||
editor: editorId,
|
editor: editorId,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.error('Failed to insert doc updates', e);
|
this.logger.error('Failed to insert doc updates', e);
|
||||||
metrics.doc.counter('doc_update_insert_failed').add(1);
|
metrics.doc.counter('doc_update_insert_failed').add(1);
|
||||||
@@ -589,6 +594,27 @@ export class PgWorkspaceDocStorageAdapter extends DocStorageAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async docExisted(workspaceId: string, docId: string) {
|
||||||
|
const snapshot = await this.db.snapshot.count({
|
||||||
|
where: {
|
||||||
|
workspaceId,
|
||||||
|
id: docId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (snapshot > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updates = await this.db.update.count({
|
||||||
|
where: {
|
||||||
|
workspaceId,
|
||||||
|
id: docId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return updates > 0;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -30,16 +30,23 @@ export class PermissionService {
|
|||||||
private readonly event: EventBus
|
private readonly event: EventBus
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@OnEvent('doc.update.pushed')
|
@OnEvent('doc.created')
|
||||||
async onDocUpdatePushed(payload: Events['doc.update.pushed']) {
|
async setDefaultPageOwner(payload: Events['doc.created']) {
|
||||||
const { workspaceId, docId, editor } = payload;
|
const { workspaceId, docId, editor } = payload;
|
||||||
|
|
||||||
await this.prisma.$queryRaw`
|
if (!editor) {
|
||||||
INSERT INTO "workspace_page_user_permissions" ("workspace_id", "page_id", "user_id", "type", "created_at")
|
return;
|
||||||
VALUES (${workspaceId}, ${docId}, ${editor}, ${DocRole.Owner}, now())
|
}
|
||||||
ON CONFLICT ("workspace_id", "page_id", "user_id")
|
|
||||||
DO NOTHING
|
await this.prisma.workspacePageUserPermission.createMany({
|
||||||
`;
|
data: {
|
||||||
|
workspaceId,
|
||||||
|
pageId: docId,
|
||||||
|
userId: editor,
|
||||||
|
type: DocRole.Owner,
|
||||||
|
createdAt: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private get acceptedCondition() {
|
private get acceptedCondition() {
|
||||||
|
|||||||
@@ -130,7 +130,15 @@ class PaginatedGrantedDocUserType extends Paginated(GrantedDocUserType) {}
|
|||||||
|
|
||||||
const DocPermissions = registerObjectType<DocActionPermissions>(
|
const DocPermissions = registerObjectType<DocActionPermissions>(
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
DOC_ACTIONS.map(action => [action.replaceAll('.', '_'), Boolean])
|
DOC_ACTIONS.map(action => [
|
||||||
|
action,
|
||||||
|
{
|
||||||
|
type: () => Boolean,
|
||||||
|
options: {
|
||||||
|
name: action.replaceAll('.', '_'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
),
|
),
|
||||||
{ name: 'DocPermissions' }
|
{ name: 'DocPermissions' }
|
||||||
);
|
);
|
||||||
@@ -281,10 +289,20 @@ export class PagePermissionResolver {
|
|||||||
where: {
|
where: {
|
||||||
workspaceId: workspace.id,
|
workspaceId: workspace.id,
|
||||||
pageId: docId.guid,
|
pageId: docId.guid,
|
||||||
|
createdAt: pagination.after
|
||||||
|
? {
|
||||||
|
gt: pagination.after,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
orderBy: {
|
orderBy: [
|
||||||
|
{
|
||||||
|
type: 'desc',
|
||||||
|
},
|
||||||
|
{
|
||||||
createdAt: 'desc',
|
createdAt: 'desc',
|
||||||
},
|
},
|
||||||
|
],
|
||||||
take: pagination.first,
|
take: pagination.first,
|
||||||
skip: pagination.offset,
|
skip: pagination.offset,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -77,7 +77,15 @@ class WorkspacePageMeta {
|
|||||||
|
|
||||||
const WorkspacePermissions = registerObjectType<WorkspaceActionPermissions>(
|
const WorkspacePermissions = registerObjectType<WorkspaceActionPermissions>(
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
WORKSPACE_ACTIONS.map(action => [action.replaceAll('.', '_'), Boolean])
|
WORKSPACE_ACTIONS.map(action => [
|
||||||
|
action,
|
||||||
|
{
|
||||||
|
type: () => Boolean,
|
||||||
|
options: {
|
||||||
|
name: action.replaceAll('.', '_'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
),
|
),
|
||||||
{ name: 'WorkspacePermissions' }
|
{ name: 'WorkspacePermissions' }
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -699,11 +699,6 @@ input PaginationInput {
|
|||||||
"""returns the elements in the list that come after the specified cursor."""
|
"""returns the elements in the list that come after the specified cursor."""
|
||||||
after: String
|
after: String
|
||||||
|
|
||||||
"""
|
|
||||||
returns the elements in the list that come before the specified cursor.
|
|
||||||
"""
|
|
||||||
before: String
|
|
||||||
|
|
||||||
"""returns the first n elements from the list."""
|
"""returns the first n elements from the list."""
|
||||||
first: Int = 10
|
first: Int = 10
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user