From 528d8830fbeffaf0f078e9979b0c70b17be1cd60 Mon Sep 17 00:00:00 2001 From: Eric Doughty-Papassideris Date: Mon, 23 Sep 2024 02:59:34 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20oo-connector:=20rename=20from=20OO?= =?UTF-8?q?=20(#525)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/controllers/onlyoffice.controller.ts | 23 ++++++++++++++++++ .../src/routes/onlyoffice.route.ts | 1 + .../src/services/drive.service.ts | 22 +++++++++++++++++ .../onlyoffice-connector/src/views/index.eta | 24 +++++++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/tdrive/connectors/onlyoffice-connector/src/controllers/onlyoffice.controller.ts b/tdrive/connectors/onlyoffice-connector/src/controllers/onlyoffice.controller.ts index 1f94d87f..3a7ad59c 100644 --- a/tdrive/connectors/onlyoffice-connector/src/controllers/onlyoffice.controller.ts +++ b/tdrive/connectors/onlyoffice-connector/src/controllers/onlyoffice.controller.ts @@ -15,6 +15,10 @@ interface RequestQuery { token: string; } +interface RenameRequestBody { + name: string; +} + /** These expose a OnlyOffice document storage service methods, called by the OnlyOffice document editing service * to load and save files */ @@ -145,6 +149,25 @@ class OnlyOfficeController { next(error || 'error'); } }; + + /** This route is called directly by the inline JS in the editor page, called by the client-side OO editor component */ + public rename = async (req: Request<{}, {}, RenameRequestBody, RequestQuery>, res: Response, next: NextFunction): Promise => { + try { + const { token } = req.query; + const officeTokenPayload = jwt.verify(token, CREDENTIALS_SECRET) as OfficeToken; + const { company_id, drive_file_id } = officeTokenPayload; + const { name } = req.body; + + if (!drive_file_id) throw new Error('OO Rename request missing drive_file_id'); + if (!name) throw new Error('OO Rename request missing name'); + + const result = await driveService.update({ company_id, drive_file_id, changes: { name } }); + res.send(result); + } catch (error) { + logger.error(`OO Rename request root error`, { error }); + next(error || 'error'); + } + }; } export default OnlyOfficeController; diff --git a/tdrive/connectors/onlyoffice-connector/src/routes/onlyoffice.route.ts b/tdrive/connectors/onlyoffice-connector/src/routes/onlyoffice.route.ts index 5faa09c7..921157cd 100644 --- a/tdrive/connectors/onlyoffice-connector/src/routes/onlyoffice.route.ts +++ b/tdrive/connectors/onlyoffice-connector/src/routes/onlyoffice.route.ts @@ -11,5 +11,6 @@ export const OnlyOfficeRoutes = { const controller = new OnlyOfficeController(); router.get(`/:mode/read`, requirementsMiddleware, controller.read.bind(controller)); router.post(`/:mode/callback`, requirementsMiddleware, controller.ooCallback.bind(controller)); + router.post(`/:mode/rename`, requirementsMiddleware, controller.rename.bind(controller)); }, }; diff --git a/tdrive/connectors/onlyoffice-connector/src/services/drive.service.ts b/tdrive/connectors/onlyoffice-connector/src/services/drive.service.ts index 2199bb66..ebb2bf65 100644 --- a/tdrive/connectors/onlyoffice-connector/src/services/drive.service.ts +++ b/tdrive/connectors/onlyoffice-connector/src/services/drive.service.ts @@ -36,6 +36,28 @@ class DriveService implements IDriveService { } }; + public update = async (params: { + company_id: string; + drive_file_id: string; + changes: Partial; + completeResult?: boolean; + }): Promise<(typeof params)['changes']> => { + try { + const { company_id, drive_file_id } = params; + const resource = await apiService.post<(typeof params)['changes'], ReturnType>({ + url: makeNonEditingSessionItemUrl(company_id, drive_file_id), + payload: params.changes, + }); + if (params.completeResult) return resource; + const result = {}; + Object.keys(params.changes).forEach(k => (result[k] = resource[k])); + return result; + } catch (error) { + logger.error('Failed to update file metadata: ', error.stack); + return Promise.reject(); + } + }; + public createVersion = async (params: { company_id: string; drive_file_id: string; diff --git a/tdrive/connectors/onlyoffice-connector/src/views/index.eta b/tdrive/connectors/onlyoffice-connector/src/views/index.eta index 8cb20ad1..fa1c3fd4 100644 --- a/tdrive/connectors/onlyoffice-connector/src/views/index.eta +++ b/tdrive/connectors/onlyoffice-connector/src/views/index.eta @@ -5,6 +5,7 @@ + Twake Drive @@ -35,6 +36,11 @@ preview: <%= it.preview %>, } } + function updateTitle(title) { + const el = document.querySelector('head title'); + if (el) el.innerText = title + ' — Twake Drive'; + } + updateTitle(doc.title); window.docEditor = new DocsAPI.DocEditor('onlyoffice_container_instance', { scrollSensitivity: window.mode === 'text' ? 100 : 40, @@ -44,6 +50,24 @@ document: doc, token: "<%= it.drive_file_id %>", type: screen.width < 600 ? 'mobile' : 'desktop', + events: { + onRequestRename: function (event) { + let name = event.data; + const prevExtension = /\.[^.]+$/.exec(doc.title); + if (prevExtension) name += prevExtension[0]; + $. + post(`${window.baseURL}rename${callbackQueryString}`, { name }). + done((changed) => { + if (changed.name != name) + window.docEditor.showMessage(`✅ Renamed to: ${changed.name}`); + }). + fail(() => window.docEditor.showMessage('🚨 Error renaming the file')); + }, + onMetaChange: function (event) { + const { title } = event.data; + if (title) updateTitle(title); + }, + }, editorConfig: { callbackUrl: `${window.baseURL}callback${callbackQueryString}`, lang: window.user.language,