Skip to content

Commit

Permalink
feat: only-office integration pt 2: performed server-side signing. ad…
Browse files Browse the repository at this point in the history
…dressed other comments.
  • Loading branch information
Alan Castro committed Jan 25, 2024
1 parent 0f39a34 commit 2660add
Show file tree
Hide file tree
Showing 15 changed files with 204 additions and 104 deletions.
3 changes: 3 additions & 0 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ func addConfigFlags(flags *pflag.FlagSet) {
flags.String("branding.files", "", "path to directory with images and custom styles")
flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links")
flags.Bool("branding.disableUsedPercentage", false, "disable used disk percentage graph")

flags.String("onlyoffice.url", "", "onlyoffice integration url")
flags.String("onlyoffice.jwtSecret", "", "onlyoffice integration secret")
}

//nolint:gocyclo
Expand Down
12 changes: 2 additions & 10 deletions files/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/spf13/afero"

"github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/fileutils"
"github.com/filebrowser/filebrowser/v2/rules"
)

Expand Down Expand Up @@ -197,16 +198,7 @@ func (i *FileInfo) Checksum(algo string) error {
}

func (i *FileInfo) RealPath() string {
if realPathFs, ok := i.Fs.(interface {
RealPath(name string) (fPath string, err error)
}); ok {
realPath, err := realPathFs.RealPath(i.Path)
if err == nil {
return realPath
}
}

return i.Path
return fileutils.GetRealPath(i.Fs, i.Path)
}

// TODO: use constants
Expand Down
13 changes: 13 additions & 0 deletions fileutils/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,16 @@ func CommonPrefix(sep byte, paths ...string) string {

return string(c)
}

func GetRealPath(fs afero.Fs, path string) string {
if realPathFs, ok := fs.(interface {
RealPath(name string) (fPath string, err error)
}); ok {
realPath, err := realPathFs.RealPath(path)
if err == nil {
return realPath
}
}

return path
}
8 changes: 0 additions & 8 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"core-js": "^3.32.0",
"css-vars-ponyfill": "^2.4.8",
"filesize": "^10.0.8",
"jose": "^4.13.1",
"js-base64": "^3.7.5",
"lodash.clonedeep": "^4.5.0",
"lodash.throttle": "^4.1.1",
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/utils/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const enableExec = window.FileBrowser.EnableExec;
const tusSettings = window.FileBrowser.TusSettings;
const origin = window.location.origin;
const tusEndpoint = `/api/tus`;
const onlyOffice = window.FileBrowser.OnlyOffice;
const onlyOfficeUrl = window.FileBrowser.OnlyOfficeUrl;

export {
name,
Expand All @@ -40,5 +40,5 @@ export {
tusSettings,
origin,
tusEndpoint,
onlyOffice,
onlyOfficeUrl,
};
4 changes: 2 additions & 2 deletions frontend/src/views/Files.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<script>
import { files as api } from "@/api";
import { mapState, mapMutations } from "vuex";
import { onlyOffice } from "@/utils/constants";
import { onlyOfficeUrl } from "@/utils/constants";
import HeaderBar from "@/components/header/HeaderBar.vue";
import Breadcrumbs from "@/components/Breadcrumbs.vue";
Expand Down Expand Up @@ -65,7 +65,7 @@ export default {
this.req.type === "textImmutable"
) {
return "editor";
} else if (this.req.type === "officedocument" && onlyOffice !== "") {
} else if (this.req.type === "officedocument" && onlyOfficeUrl) {
return "OnlyOfficeEditor";
} else {
return "preview";
Expand Down
95 changes: 23 additions & 72 deletions frontend/src/views/files/OnlyOfficeEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,38 @@
<action icon="close" :label="$t('buttons.close')" @action="close()" />
<title>{{ req.name }}</title>
</header-bar>

<breadcrumbs base="/files" noLink />

<div id="editor"></div>
<errors v-if="error" :errorCode="error.status" />
<div id="editor">
<div id="onlyoffice-editor"></div>
</div>
</div>
</template>

<style scoped>
#editor-container {
height: 100vh;
width: 100vw;
}
</style>

<script>
import { mapState } from "vuex";
import url from "@/utils/url";
import { baseURL, onlyOffice } from "@/utils/constants";
import * as jose from "jose";
import { onlyOfficeUrl } from "@/utils/constants";
import HeaderBar from "@/components/header/HeaderBar.vue";
import Action from "@/components/header/Action.vue";
import Breadcrumbs from "@/components/Breadcrumbs.vue";
import Errors from "@/views/Errors.vue";
import { fetchJSON } from "@/api/utils";
export default {
name: "onlyofficeeditor",
components: {
HeaderBar,
Action,
Breadcrumbs,
Errors,
},
data: function () {
return {};
return {
error: null,
clientConfig: null
};
},
computed: {
...mapState(["req", "user", "jwt"]),
Expand Down Expand Up @@ -71,76 +70,28 @@ export default {
},
},
created() {
const isMobile = window.innerWidth <= 736;
this.clientConfigPromise = fetchJSON(`/api/onlyoffice/client-config${this.req.path}?isMobile=${isMobile}`);
window.addEventListener("keydown", this.keyEvent);
},
beforeDestroy() {
window.removeEventListener("keydown", this.keyEvent);
this.editor.destroyEditor();
},
mounted: function () {
let onlyofficeScript = document.createElement("script");
onlyofficeScript.setAttribute(
"src",
`${onlyOffice.url}/web-apps/apps/api/documents/api.js`
);
const scriptUrl = `${onlyOfficeUrl}/web-apps/apps/api/documents/api.js`;
const onlyofficeScript = document.createElement("script");
onlyofficeScript.setAttribute("src", scriptUrl);
document.head.appendChild(onlyofficeScript);
/*eslint-disable */
onlyofficeScript.onload = () => {
let fileUrl = `${window.location.protocol}//${window.location.host}${baseURL}/api/raw${url.encodePath(
this.req.path
)}?auth=${this.jwt}`;
// create a key from the last modified timestamp and the reversed file path (most specific part first)
// replace all special characters (only these symbols are supported: 0-9, a-z, A-Z, -._=)
// and truncate it (max length is 20 characters)
const key = (
Date.parse(this.req.modified).valueOf()
+ url
.encodePath(this.req.path.split('/').reverse().join(''))
.replaceAll(/[!~[\]*'()/,;:\-%+. ]/g, "")
).substring(0, 20);
const config = {
document: {
fileType: this.req.extension.substring(1),
key: key,
title: this.req.name,
url: fileUrl,
permissions: {
edit: this.user.perm.modify,
download: this.user.perm.download,
print: this.user.perm.download
}
},
editorConfig: {
callbackUrl: `${window.location.protocol}//${window.location.host}${baseURL}/api/onlyoffice/callback?auth=${this.jwt}&save=${encodeURIComponent(this.req.path)}`,
user: {
id: this.user.id,
name: `User ${this.user.id}`
},
customization: {
autosave: true,
forcesave: true
},
lang: this.user.locale,
mode: this.user.perm.modify ? "edit" : "view"
}
};
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);
onlyofficeScript.onload = async () => {
try {
const clientConfig = await this.clientConfigPromise
this.editor = new DocsAPI.DocEditor("onlyoffice-editor", clientConfig);
} catch(e) {
this.error = e;
}
};
/*eslint-enable */
},
methods: {
back() {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ require (
)

require (
github.com/allegro/bigcache v1.2.1 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM=
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Sereal/Sereal v0.0.0-20190618215532-0b8ac451a863 h1:BRrxwOZBolJN4gIwvZMJY1tzqBvQgpaZiQRuIDD40jM=
github.com/Sereal/Sereal v0.0.0-20190618215532-0b8ac451a863/go.mod h1:D0JMgToj/WdxCgd30Kc1UcA9E+WdZoJqeVOuYW7iTBM=
github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
Expand Down
1 change: 1 addition & 0 deletions http/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func withUser(fn handleFunc) handleFunc {
w.Header().Add("X-Renew-Token", "true")
}

d.authToken = token.Raw
d.user, err = d.store.Users.Get(d.server.Root, tk.User.ID)
if err != nil {
return http.StatusInternalServerError, err
Expand Down
11 changes: 6 additions & 5 deletions http/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ type handleFunc func(w http.ResponseWriter, r *http.Request, d *data) (int, erro

type data struct {
*runner.Runner
settings *settings.Settings
server *settings.Server
store *storage.Storage
user *users.User
raw interface{}
authToken string
settings *settings.Settings
server *settings.Server
store *storage.Storage
user *users.User
raw interface{}
}

// Check implements rules.Checker.
Expand Down
1 change: 1 addition & 0 deletions http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func NewHandler(
users.Handle("/{id:[0-9]+}", monkey(userGetHandler, "")).Methods("GET")
users.Handle("/{id:[0-9]+}", monkey(userDeleteHandler, "")).Methods("DELETE")

api.PathPrefix("/onlyoffice").Handler(monkey(onlyofficeClientConfigGetHandler, "/api/onlyoffice/client-config")).Methods("GET")
api.PathPrefix("/onlyoffice").Handler(monkey(onlyofficeCallbackHandler, "/api/onlyoffice/callback")).Methods("POST")

api.PathPrefix("/resources").Handler(monkey(resourceGetHandler, "/api/resources")).Methods("GET")
Expand Down

0 comments on commit 2660add

Please sign in to comment.