From 104872252df989c3b36c048bc71e1221000fd959 Mon Sep 17 00:00:00 2001 From: drosoCode Date: Sun, 2 Apr 2023 19:34:25 +0200 Subject: [PATCH] feat: onlyoffice jwt token support --- cmd/config_init.go | 5 ++++- cmd/config_set.go | 6 ++++-- frontend/package-lock.json | 16 ++++++++++++++++ frontend/package.json | 1 + frontend/src/i18n/en.json | 1 + frontend/src/views/files/OnlyOfficeEditor.vue | 18 +++++++++++++++--- frontend/src/views/settings/Global.vue | 13 ++++++++++++- http/settings.go | 2 +- settings/onlyoffice.go | 7 +++++++ settings/settings.go | 2 +- 10 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 settings/onlyoffice.go diff --git a/cmd/config_init.go b/cmd/config_init.go index 1dc0fd52..c9455d00 100644 --- a/cmd/config_init.go +++ b/cmd/config_init.go @@ -39,7 +39,10 @@ override the options.`, DisableExternal: mustGetBool(flags, "branding.disableExternal"), Files: mustGetString(flags, "branding.files"), }, - OnlyOffice: "", + OnlyOffice: settings.OnlyOffice{ + URL: mustGetString(flags, "onlyoffice.url"), + JWTSecret: mustGetString(flags, "onlyoffice.jwtSecret"), + }, } ser := &settings.Server{ diff --git a/cmd/config_set.go b/cmd/config_set.go index 31b83e29..5152d785 100644 --- a/cmd/config_set.go +++ b/cmd/config_set.go @@ -55,8 +55,10 @@ you want to change. Other options will remain unchanged.`, set.Branding.DisableExternal = mustGetBool(flags, flag.Name) case "branding.files": set.Branding.Files = mustGetString(flags, flag.Name) - case "onlyoffice": - set.OnlyOffice = mustGetString(flags, flag.Name) + case "onlyoffice.url": + set.OnlyOffice.URL = mustGetString(flags, flag.Name) + case "onlyoffice.jwtSecret": + set.OnlyOffice.JWTSecret = mustGetString(flags, flag.Name) } }) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ad4009d1..406d6c64 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -12,6 +12,7 @@ "clipboard": "^2.0.4", "core-js": "^3.9.1", "css-vars-ponyfill": "^2.4.3", + "jose": "^4.13.1", "js-base64": "^2.5.1", "lodash.clonedeep": "^4.5.0", "lodash.throttle": "^4.1.1", @@ -8523,6 +8524,14 @@ "node": ">=8" } }, + "node_modules/jose": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.13.1.tgz", + "integrity": "sha512-MSJQC5vXco5Br38mzaQKiq9mwt7lwj2eXpgpRyQYNHYt2lq1PjkWa7DLXX0WVcQLE9HhMh3jPiufS7fhJf+CLQ==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-base64": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", @@ -16835,6 +16844,7 @@ "integrity": "sha512-8q67ORQ9O0Ms0nlqsXTVhaBefRBaLrzPxOewAZhdcO7onHwcO5/wRdWtHhZgfpCZlhY7NogkU16z3WnorSSkEA==", "dev": true, "requires": { + "@babel/core": "^7.11.0", "@babel/helper-compilation-targets": "^7.9.6", "@babel/helper-module-imports": "^7.8.3", "@babel/plugin-proposal-class-properties": "^7.8.3", @@ -16847,6 +16857,7 @@ "@vue/babel-plugin-jsx": "^1.0.3", "@vue/babel-preset-jsx": "^1.2.4", "babel-plugin-dynamic-import-node": "^2.3.3", + "core-js": "^3.6.5", "core-js-compat": "^3.6.5", "semver": "^6.1.0" } @@ -22220,6 +22231,11 @@ } } }, + "jose": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.13.1.tgz", + "integrity": "sha512-MSJQC5vXco5Br38mzaQKiq9mwt7lwj2eXpgpRyQYNHYt2lq1PjkWa7DLXX0WVcQLE9HhMh3jPiufS7fhJf+CLQ==" + }, "js-base64": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", diff --git a/frontend/package.json b/frontend/package.json index bdf17bc9..f7aa2752 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,6 +14,7 @@ "clipboard": "^2.0.4", "core-js": "^3.9.1", "css-vars-ponyfill": "^2.4.3", + "jose": "^4.13.1", "js-base64": "^2.5.1", "lodash.clonedeep": "^4.5.0", "lodash.throttle": "^4.1.1", diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 22e05141..7ec663a2 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -195,6 +195,7 @@ "newUser": "New User", "onlyOffice": "Only Office Integration", "onlyOfficeUrl": "Only Office URL (leave blank to disable)", + "onlyOfficeJwtSecret": "Only Office JWT Secret (works only with https, leave blank to disable)", "password": "Password", "passwordUpdated": "Password updated!", "path": "Path", diff --git a/frontend/src/views/files/OnlyOfficeEditor.vue b/frontend/src/views/files/OnlyOfficeEditor.vue index 01bfd487..a577df0a 100644 --- a/frontend/src/views/files/OnlyOfficeEditor.vue +++ b/frontend/src/views/files/OnlyOfficeEditor.vue @@ -22,6 +22,7 @@ import { mapState } from "vuex"; import url from "@/utils/url"; import { baseURL, onlyOffice } from "@/utils/constants"; +import * as jose from "jose"; import HeaderBar from "@/components/header/HeaderBar"; import Action from "@/components/header/Action"; @@ -80,7 +81,7 @@ export default { let onlyofficeScript = document.createElement("script"); onlyofficeScript.setAttribute( "src", - `${onlyOffice}/web-apps/apps/api/documents/api.js` + `${onlyOffice.url}/web-apps/apps/api/documents/api.js` ); document.head.appendChild(onlyofficeScript); @@ -100,7 +101,7 @@ export default { .replaceAll(/[!~[\]*'()/,;:\-%+. ]/g, "") ).substring(0, 20); - let config = { + const config = { document: { fileType: this.req.extension.substring(1), key: key, @@ -126,7 +127,18 @@ export default { mode: this.user.perm.modify ? "edit" : "view" } }; - this.editor = new DocsAPI.DocEditor("editor", config); + + if(onlyOffice.jwtSecret != "") { + const alg = 'HS256'; + new jose.SignJWT(config) + .setProtectedHeader({ alg }) + .sign(new TextEncoder().encode(onlyOffice.jwtSecret)).then((jwt) => { + config.token = jwt; + this.editor = new DocsAPI.DocEditor("editor", config); + }) + } else { + this.editor = new DocsAPI.DocEditor("editor", config); + } }; /*eslint-enable */ }, diff --git a/frontend/src/views/settings/Global.vue b/frontend/src/views/settings/Global.vue index 060fcea4..47e5bd84 100644 --- a/frontend/src/views/settings/Global.vue +++ b/frontend/src/views/settings/Global.vue @@ -93,10 +93,21 @@

+

+ + +

diff --git a/http/settings.go b/http/settings.go index 5e551e91..db8ca9e0 100644 --- a/http/settings.go +++ b/http/settings.go @@ -16,7 +16,7 @@ type settingsData struct { Branding settings.Branding `json:"branding"` Shell []string `json:"shell"` Commands map[string][]string `json:"commands"` - OnlyOffice string `json:"onlyoffice"` + OnlyOffice settings.OnlyOffice `json:"onlyoffice"` } var settingsGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { diff --git a/settings/onlyoffice.go b/settings/onlyoffice.go new file mode 100644 index 00000000..1b6cb185 --- /dev/null +++ b/settings/onlyoffice.go @@ -0,0 +1,7 @@ +package settings + +// OnlyOffice contains the onlyoffice server connection settings of the app. +type OnlyOffice struct { + URL string `json:"url"` + JWTSecret string `json:"jwtSecret"` +} diff --git a/settings/settings.go b/settings/settings.go index e7b46a1b..2a9c21dd 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -21,7 +21,7 @@ type Settings struct { Commands map[string][]string `json:"commands"` Shell []string `json:"shell"` Rules []rules.Rule `json:"rules"` - OnlyOffice string `json:"onlyoffice"` + OnlyOffice OnlyOffice `json:"onlyoffice"` } // GetRules implements rules.Provider.