mirror of
https://github.com/docmost/docmost.git
synced 2025-11-18 06:01:11 +10:00
WIP
This commit is contained in:
@ -1,6 +1,9 @@
|
||||
import { IsString } from 'class-validator';
|
||||
import { IsBoolean, IsString } from 'class-validator';
|
||||
|
||||
export class CreateShareDto {
|
||||
@IsString()
|
||||
pageId: string;
|
||||
|
||||
@IsBoolean()
|
||||
includeSubPages: boolean;
|
||||
}
|
||||
|
||||
@ -12,12 +12,14 @@ import { TokenService } from '../auth/services/token.service';
|
||||
import { jsonToNode } from '../../collaboration/collaboration.util';
|
||||
import {
|
||||
getAttachmentIds,
|
||||
getProsemirrorContent,
|
||||
isAttachmentNode,
|
||||
} from '../../common/helpers/prosemirror/utils';
|
||||
import { Node } from '@tiptap/pm/model';
|
||||
import { ShareRepo } from '@docmost/db/repos/share/share.repo';
|
||||
import { updateAttachmentAttr } from './share.util';
|
||||
import { Page } from '@docmost/db/types/entity.types';
|
||||
import { validate as isValidUUID } from 'uuid';
|
||||
|
||||
@Injectable()
|
||||
export class ShareService {
|
||||
@ -59,7 +61,21 @@ export class ShareService {
|
||||
throw new NotFoundException('Share not found');
|
||||
}
|
||||
|
||||
const page = await this.pageRepo.findById(share.pageId, {
|
||||
let targetPageId = share.pageId;
|
||||
if (dto.pageId && dto.pageId !== share.pageId) {
|
||||
// Check if dto.pageId is a descendant of the shared page.
|
||||
const isDescendant = await this.getShareAncestorPage(
|
||||
share.pageId,
|
||||
dto.pageId,
|
||||
);
|
||||
if (isDescendant) {
|
||||
targetPageId = dto.pageId;
|
||||
} else {
|
||||
throw new NotFoundException(`Shared page not found`);
|
||||
}
|
||||
}
|
||||
|
||||
const page = await this.pageRepo.findById(targetPageId, {
|
||||
includeContent: true,
|
||||
includeCreator: true,
|
||||
});
|
||||
@ -73,8 +89,74 @@ export class ShareService {
|
||||
return page;
|
||||
}
|
||||
|
||||
async getShareAncestorPage(
|
||||
ancestorPageId: string,
|
||||
childPageId: string,
|
||||
): Promise<any> {
|
||||
let ancestor = null;
|
||||
try {
|
||||
ancestor = await this.db
|
||||
.withRecursive('page_ancestors', (db) =>
|
||||
db
|
||||
.selectFrom('pages')
|
||||
.select([
|
||||
'id',
|
||||
'slugId',
|
||||
'title',
|
||||
'parentPageId',
|
||||
'spaceId',
|
||||
(eb) =>
|
||||
eb
|
||||
.case()
|
||||
.when(eb.ref('id'), '=', ancestorPageId)
|
||||
.then(true)
|
||||
.else(false)
|
||||
.end()
|
||||
.as('found'),
|
||||
])
|
||||
.where(
|
||||
!isValidUUID(childPageId) ? 'slugId' : 'id',
|
||||
'=',
|
||||
childPageId,
|
||||
)
|
||||
.unionAll((exp) =>
|
||||
exp
|
||||
.selectFrom('pages as p')
|
||||
.select([
|
||||
'p.id',
|
||||
'p.slugId',
|
||||
'p.title',
|
||||
'p.parentPageId',
|
||||
'p.spaceId',
|
||||
(eb) =>
|
||||
eb
|
||||
.case()
|
||||
.when(eb.ref('p.id'), '=', ancestorPageId)
|
||||
.then(true)
|
||||
.else(false)
|
||||
.end()
|
||||
.as('found'),
|
||||
])
|
||||
.innerJoin('page_ancestors as pa', 'pa.parentPageId', 'p.id')
|
||||
// Continue recursing only when the target ancestor hasn't been found on that branch.
|
||||
.where('pa.found', '=', false),
|
||||
),
|
||||
)
|
||||
.selectFrom('page_ancestors')
|
||||
.selectAll()
|
||||
.where('found', '=', true)
|
||||
.limit(1)
|
||||
.executeTakeFirst();
|
||||
} catch (err) {
|
||||
// empty
|
||||
}
|
||||
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
async updatePublicAttachments(page: Page): Promise<any> {
|
||||
const attachmentIds = getAttachmentIds(page.content);
|
||||
const prosemirrorJson = getProsemirrorContent(page.content);
|
||||
const attachmentIds = getAttachmentIds(prosemirrorJson);
|
||||
const attachmentMap = new Map<string, string>();
|
||||
|
||||
await Promise.all(
|
||||
@ -88,7 +170,7 @@ export class ShareService {
|
||||
}),
|
||||
);
|
||||
|
||||
const doc = jsonToNode(page.content as any);
|
||||
const doc = jsonToNode(prosemirrorJson);
|
||||
|
||||
doc?.descendants((node: Node) => {
|
||||
if (!isAttachmentNode(node.type.name)) return;
|
||||
|
||||
Reference in New Issue
Block a user