mirror of
https://github.com/docmost/docmost.git
synced 2026-05-17 14:54:05 +08:00
collaborative editor - wip
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { Extension, onAuthenticatePayload } from '@hocuspocus/server';
|
||||
import { UserService } from '../../core/user/user.service';
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { TokenService } from '../../core/auth/services/token.service';
|
||||
|
||||
@Injectable()
|
||||
export class AuthenticationExtension implements Extension {
|
||||
constructor(
|
||||
private tokenService: TokenService,
|
||||
private userService: UserService,
|
||||
) {}
|
||||
|
||||
async onAuthenticate(data: onAuthenticatePayload) {
|
||||
const { documentName, token } = data;
|
||||
|
||||
let jwtPayload = null;
|
||||
|
||||
try {
|
||||
jwtPayload = await this.tokenService.verifyJwt(token);
|
||||
} catch (error) {
|
||||
throw new UnauthorizedException('Could not verify jwt token');
|
||||
}
|
||||
|
||||
const userId = jwtPayload.sub;
|
||||
const user = await this.userService.findById(userId);
|
||||
|
||||
//TODO: Check if the page exists and verify user permissions for page.
|
||||
// if all fails, abort connection
|
||||
|
||||
return {
|
||||
user,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { Extension, onLoadDocumentPayload, onStoreDocumentPayload } from '@hocuspocus/server';
|
||||
import * as Y from 'yjs';
|
||||
import { PageService } from '../../core/page/page.service';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { TiptapTransformer } from '@hocuspocus/transformer';
|
||||
|
||||
@Injectable()
|
||||
export class PersistenceExtension implements Extension {
|
||||
constructor(private readonly pageService: PageService) {}
|
||||
|
||||
async onLoadDocument(data: onLoadDocumentPayload) {
|
||||
const { documentName, document } = data;
|
||||
|
||||
if (!document.isEmpty('default')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const page = await this.pageService.findById(documentName);
|
||||
|
||||
if (!page) {
|
||||
console.log('page does not exist.');
|
||||
//TODO: terminate connection if the page does not exist?
|
||||
return;
|
||||
}
|
||||
|
||||
if (page.ydoc) {
|
||||
const doc = new Y.Doc();
|
||||
const dbState = new Uint8Array(page.ydoc);
|
||||
|
||||
Y.applyUpdate(doc, dbState);
|
||||
return doc;
|
||||
}
|
||||
|
||||
// if no ydoc state in db convert json in page.content to Ydoc.
|
||||
const ydoc = TiptapTransformer.toYdoc(page.content, 'default');
|
||||
|
||||
Y.encodeStateAsUpdate(ydoc);
|
||||
return ydoc;
|
||||
}
|
||||
|
||||
async onStoreDocument(data: onStoreDocumentPayload) {
|
||||
const { documentName, document, context } = data;
|
||||
|
||||
const pageId = documentName;
|
||||
|
||||
const tiptapJson = TiptapTransformer.fromYdoc(document, 'default');
|
||||
const ydocState = Buffer.from(Y.encodeStateAsUpdate(document));
|
||||
|
||||
try {
|
||||
await this.pageService.updateState(
|
||||
pageId,
|
||||
tiptapJson,
|
||||
ydocState,
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(`Failed to update page ${documentName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user