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.