Compare commits

...

116 Commits

Author SHA1 Message Date
45473a9db3 Merge pull request 'release/1.14.1' from release/1.14.1 into master
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/80
2025-10-16 13:30:16 +00:00
8d6c728b32 1.14.1 2025-10-15 10:13:29 +03:00
ccdd02bbac nodejs: formats for ds v9.1
# Conflicts:
#	CHANGELOG.md
2025-10-15 10:11:45 +03:00
591e38ddac channge release action 2025-07-31 10:38:12 +03:00
c73eece042 Merge pull request 'ci: added create-tag.yml and run release on create tag' from ci/git-actions into master
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/70
2025-07-01 14:19:30 +00:00
8701cc53e9 Merge pull request 'release/1.14.0' from release/1.14.0 into master
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/69
2025-07-01 14:09:50 +00:00
5a214b80d9 ci: added create-tag.yml and run release on create tag 2025-07-01 17:08:29 +03:00
f231b1cd72 nodejs: fix lint 2025-07-01 16:46:51 +03:00
2166b31858 nodejs: infinite scroll for users pagination 2025-06-20 16:11:13 +03:00
07b7615efd nodejs: formats update 2025-06-18 15:04:25 +03:00
307f15581b fix changelog 2025-06-17 15:19:53 +03:00
e15d9a3163 1.14.0 2025-06-09 16:04:30 +03:00
cd47a8e0de Merge remote-tracking branch 'remotes/origin/feature/setUsers' into release/v9.0.0 2025-06-02 12:39:34 +03:00
cf1541bf3a nodejs: set users by parts 2025-05-31 23:08:54 +03:00
d533cca184 nodejs: support md 2025-05-12 17:18:15 +03:00
537d7eaeb9 nodejs: changed preloading (71c937ae37) 2025-05-12 15:07:23 +03:00
a5e8db73f8 ur skin language 2025-04-28 13:17:40 +03:00
05f22b9e24 nodejs: auto-convert for odg 2025-04-24 15:22:00 +03:00
84936a506f nodejs: move preload to changelog (71c937ae37) 2025-04-22 16:25:16 +03:00
501fbeacaf Merge remote-tracking branch 'remotes/origin/hotfix/v8.3.3' into release/v9.0.0
# Conflicts:
#	CHANGELOG.md
2025-04-15 09:26:36 +03:00
71c937ae37 nodejs: preload frame moved from uploading popap 2025-04-14 16:25:47 +03:00
71bcc65522 nodejs: fix host on verification (9faf628fba) 2025-04-14 15:52:47 +03:00
13554abfcb Merge branch 'feature/preload' into release/v9.0.0 2025-04-14 13:26:59 +03:00
f5e279ca11 change preload address 2025-04-14 13:22:17 +03:00
9395d183b0 nodejs: use default config 2025-04-14 12:50:04 +03:00
09600d91c2 nodejs: edit xlsb, view odg 2025-04-11 17:00:11 +03:00
a7552677eb Merge branch 'hotfix/v8.3.3' into release/v9.0.0
# Conflicts:
#	CHANGELOG.md
#	web/documentserver-example/nodejs/public/assets/document-formats
#	web/documentserver-example/nodejs/public/images/diagram.ico
2025-03-28 13:45:09 +03:00
c585e30eb8 Merge remote-tracking branch 'remotes/origin/master' into hotfix/v8.3.3
# Conflicts:
#	CHANGELOG.md
2025-03-28 13:42:34 +03:00
4af422acb3 Merge pull request 'release/1.13.0' from release/1.13.0 into master
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/60
2025-03-28 10:34:05 +00:00
6bac7ffc5b upload-artifact v4 2025-03-28 12:49:27 +03:00
b6a9a4ba77 nodejs: fix lint
# Conflicts:
#	web/documentserver-example/nodejs/helpers/users.js
2025-03-28 12:41:50 +03:00
76ee327af8 fix readme 2025-03-28 12:35:21 +03:00
2df44605c3 3rd-party license 2025-03-28 12:24:35 +03:00
888fb0e12c Merge pull request 'fix(ruby): replacing host when version download url is present. Fix Bug 73693' from fix/ruby-restore into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/59
2025-03-27 07:57:59 +00:00
f1c4e8d875 fix(ruby): replacing host when version download url is present. Fix Bug 73693 2025-03-26 12:44:04 +07:00
f394be17a4 Merge pull request '1.13.0-bugfix' from 1.13.0-bugfix into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/57
2025-03-25 08:06:11 +00:00
ebd306d2b2 fix(python): correct version author when changes exist. Fix Bug 73505 2025-03-25 14:11:12 +07:00
2447aaef12 fix(ruby): correct version author when changes exist. Fix Bug 73505 2025-03-25 13:15:01 +07:00
ed586de8c8 fix(ruby): replace public hostname in the intermediate version download url. Fix Bug 73655 2025-03-25 13:14:05 +07:00
a759f97508 fix(ruby): sort files by modification time. Fix Bug 73654 2025-03-25 11:48:16 +07:00
30c541d119 Merge pull request 'bugfix-1.13.0' from bugfix-1.13.0 into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/56
2025-03-24 09:52:52 +00:00
e4984f4c3e fix(php-laravel): open source with correct host. Fix Bug 73552 2025-03-21 13:13:28 +07:00
5ca511d838 fix(go): correct file uploading error processing. Fix Bug 73601 2025-03-20 15:12:20 +07:00
649e167916 php-laravel: Copyright 2025 2025-03-19 15:46:27 +03:00
64fce32be6 Merge pull request 'release/1.13.0 bugfix' from fix/1.13 into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/53
2025-03-19 08:46:25 +00:00
5cbb905285 refactoring 2025-03-19 11:44:07 +03:00
9769641539 fix(java-spring): correct file name for conversion instead of changing download link 2025-03-19 15:27:35 +07:00
806fee40dd fix(java): correct file name for conversion instead of changing download link 2025-03-19 15:27:35 +07:00
1db4e22007 fix(nodejs): correct file name for conversion instead of changing download link 2025-03-19 15:27:35 +07:00
1a73be6a12 fix(ruby): correct file name for conversion instead of changing download link 2025-03-19 15:27:35 +07:00
c8288b3141 fix(php-laravel): correct file name for conversion instead of changing download link 2025-03-19 15:27:35 +07:00
c03a15a230 fix(php-laravel): get server url from new SettingsManager. Fix Bug 73556 2025-03-19 15:27:34 +07:00
a16318fa71 fix(java): correct version author when changes exist. Fix Bug 73505 2025-03-19 15:27:34 +07:00
a5d98055ce fix(java-spring): correct version author when changes exist. Fix Bug 73505 2025-03-19 15:27:34 +07:00
ec0e2e1b4a fix(php): correct version author when changes exist. Fix Bug 73505 2025-03-19 15:27:34 +07:00
cbd464ad0a fix(php): correct download name of converted file. Fix Bug 73522 2025-03-19 15:27:34 +07:00
9378e4313b fix(csharp-mvc): correct download name of converted file. Fix Bug 73522 2025-03-19 15:27:34 +07:00
5d23ac7572 fix(csharp): correct download name of converted file. Fix Bug 73522 2025-03-19 15:27:34 +07:00
26adbf454b fix(python): correct download name of converted file. Fix Bug 73522 2025-03-19 15:27:25 +07:00
47a8bff158 fix(csharp-mvc): sort files by modification time. Fix Bug 73528 2025-03-19 15:27:04 +07:00
54b0735295 fix(csharp): sort files by modification time. Fix Bug 73528 2025-03-19 15:27:04 +07:00
248ca25671 fix(java): sort files by modification time. Fix Bug 73528 2025-03-19 15:27:04 +07:00
b0f3d02191 fix(java-spring): sort files by modification time. Fix Bug 73528 2025-03-19 15:27:04 +07:00
92325894f9 build(ruby): add nokogiri for linux-musl to gemfile.lock to run using docker. Fix Bug 73519 2025-03-19 15:27:04 +07:00
0a9a37e355 fix(php): replace public url in the intermediate version download link and ignore command service error code 4. Fix Bug 73526 2025-03-19 15:27:04 +07:00
2784c47873 fix(python): replace public url in the intermediate version download link. Fix Bug 73520 2025-03-19 15:27:04 +07:00
6cbe243baa fix: reloading page after upload(java, java-spring). Fix Bug 73527 2025-03-19 15:27:03 +07:00
53daf9121d fix(go): correct change reference source processing. Fix Bug 73529 2025-03-19 15:27:03 +07:00
07b0f2c5be fix(go): enable close for uid-2 and uid-3. Fix Bug 73506 2025-03-19 15:27:03 +07:00
167467e3b3 Merge pull request 'build(ruby): bump rack to 2.2.13' from ruby-bump-rack into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/54
2025-03-19 08:16:56 +00:00
0d2fb178fa build(ruby): bump rack to 2.2.13 2025-03-19 11:16:23 +03:00
a5d2a38809 nodejs: start filling 2025-03-14 17:02:03 +03:00
a2088ae8e1 nodejs: user role 2025-03-14 16:24:16 +03:00
f83b4a8be8 nodejs: second user can submit 2025-03-14 16:15:12 +03:00
43f1a9a800 Merge remote-tracking branch 'remotes/origin/fix/golang' into release/1.13.0 2025-03-12 12:22:44 +03:00
336e37cf44 fix version author when changes exist ( Fix Bug 73505 ) 2025-03-12 12:22:11 +03:00
f554de193e fix(go): correct converted file name. Fix Bug 73501 2025-03-12 15:02:10 +07:00
688cdd8ee9 Merge branch 'hotfix/v8.3.1' into release/1.13.0 2025-03-11 11:53:20 +03:00
c796154fe1 update diagram tab icon
# Conflicts:
#	web/documentserver-example/csharp-mvc/Content/images/diagram.ico
#	web/documentserver-example/csharp/App_Themes/images/diagram.ico
#	web/documentserver-example/go/static/images/diagram.ico
#	web/documentserver-example/java/src/main/webapp/css/img/diagram.ico
#	web/documentserver-example/php/assets/images/diagram.ico
#	web/documentserver-example/python/static/images/diagram.ico
#	web/documentserver-example/ruby/app/assets/images/diagram.ico
2025-03-11 11:44:48 +03:00
0599f74117 nodejs: support diagram editor
# Conflicts:
#	CHANGELOG.md
#	web/documentserver-example/nodejs/public/assets/document-formats
2025-03-11 11:44:26 +03:00
8f944e203d nodejs: support vsdx in visio editor
# Conflicts:
#	CHANGELOG.md
#	web/documentserver-example/nodejs/public/assets/document-formats
2025-03-11 11:43:38 +03:00
9337ff720e Merge pull request 'fix(go): sort files by time. Fix Bug 73390' from fix/golang-sort-by-time into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/51
2025-03-03 05:41:35 +00:00
91024f8626 fix(go): sort files by time. Fix Bug 73390 2025-03-03 11:07:35 +07:00
c36f1c67a9 Merge pull request 'fix(go): return the name of the file created by url. Fix Bug 73389' from fix/golang-create-by-url into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/50
2025-02-28 06:28:56 +00:00
3e64597f45 fix(go): return the name of the file created by url. Fix Bug 73389 2025-02-28 12:20:51 +07:00
f9ab6e47b1 Merge pull request 'fix(go): remove directUrl from index page script. Fix Bug 73380' from fix/golang-direct-url into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/49
2025-02-27 10:43:15 +00:00
283687b692 fix(go): remove directUrl from index page script. Fix Bug 73380 2025-02-27 13:42:27 +03:00
08015e06b6 Merge pull request 'jwt-lifetime' from jwt-lifetime into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/31
2025-02-24 14:20:29 +00:00
ce4b905f06 feat(php-laravel): add jwt token lifetime from config 2025-02-24 17:19:43 +03:00
b6613b5d21 feat(php): add jwt token lifetime from config 2025-02-24 17:18:52 +03:00
ab0993f09f feat(ruby): add jwt token lifetime from config 2025-02-24 17:18:52 +03:00
3c4b2e2877 feat(python): add jwt token lifetime from config 2025-02-24 17:18:51 +03:00
3102f4835c feat(java-spring): add jwt token lifetime from config 2025-02-24 17:18:51 +03:00
7ea4545657 feat(java): add jwt token lifetime from config 2025-02-24 17:18:51 +03:00
635d70d8f4 feat(csharp-mvc): add jwt token lifetime from config 2025-02-24 17:18:51 +03:00
90f3a3e44e feat(csharp): add jwt token lifetime from config 2025-02-24 17:18:50 +03:00
46cf8baa28 feat(go): add jwt token lifetime from config 2025-02-24 17:18:50 +03:00
326fd4a586 Merge branch 'feature/wopi-verification' into release/1.13.0 2025-02-24 17:16:23 +03:00
d0efe3e1f2 nodejs: proof key to changelog 2025-02-24 15:17:17 +03:00
91a601dbfe fix(nodejs): skip wopi verification when proof key is missing in discovery 2025-02-24 15:13:33 +03:00
9faf628fba feat(nodejs): wopi proof key verification 2025-02-24 15:13:32 +03:00
af9a3a97ec Merge pull request 'build(ruby): bump nokogiri to 1.18.3' from bump-nokogiri into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/47
2025-02-24 12:08:22 +00:00
c2d01c68fb build(ruby): bump nokogiri to 1.18.3 2025-02-24 15:07:27 +03:00
f46505a07c Merge pull request 'narrow-mobile-screen-fix' from narrow-mobile-screen-fix into release/1.13.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/45
2025-02-20 10:17:35 +00:00
08fe615b93 fix(ruby): support for mobile screens with width less than 320px 2025-02-20 13:16:45 +03:00
da071258f6 fix(python): support for mobile screens with width less than 320px 2025-02-20 13:16:45 +03:00
8c136540be fix(php-laravel): support for mobile screens with width less than 320px 2025-02-20 13:16:44 +03:00
c65eb623a2 fix(php): support for mobile screens with width less than 320px 2025-02-20 13:16:44 +03:00
9c96a577b4 fix(java-spring): support for mobile screens with width less than 320px 2025-02-20 13:16:44 +03:00
00506049aa fix(java): support for mobile screens with width less than 320px 2025-02-20 13:16:43 +03:00
b6ace095e5 fix(go): support for mobile screens with width less than 320px 2025-02-20 13:16:43 +03:00
cce42cb94c fix(csharp-mvc): support for mobile screens with width less than 320px 2025-02-20 13:16:43 +03:00
83abe9f175 fix(csharp): support for mobile screens with width less than 320px 2025-02-20 13:16:43 +03:00
1374aeb2fd fix(nodejs): support for mobile screens with width less than 320px 2025-02-20 13:16:42 +03:00
f0ced2f587 nodejs: encode path in url for wopi 2025-02-19 11:33:29 +03:00
1074735afc Merge pull request 'Release/1.12.0' from release/1.12.0 into master
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/document-server-integration/pulls/41
2025-02-11 08:43:18 +00:00
134 changed files with 675 additions and 296 deletions

View File

@ -25,7 +25,7 @@ jobs:
rsync -av --exclude='deploy' ./ ./deploy/'DotNet (Csharp MVC) Example'
rm -rf ./deploy/'DotNet (Csharp MVC) Example'/assets/.git
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: DotNet.Csharp.MVC.Example
path: ${{ github.workspace }}/web/documentserver-example/csharp-mvc/deploy

View File

@ -24,7 +24,7 @@ jobs:
rsync -av --exclude='deploy' ./ ./deploy/'DotNet (Csharp) Example'
rm -rf ./deploy/'DotNet (Csharp) Example'/assets/.git
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: DotNet.Csharp.Example
path: ${{ github.workspace }}/web/documentserver-example/csharp/deploy

View File

@ -25,7 +25,7 @@ jobs:
rm -rf ./deploy/'Java Example'/src/main/resources/assets/document-formats/.git
rm -rf ./deploy/'Java Example'/src/main/resources/assets/document-templates/.git
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Java.Example
path: ${{ github.workspace }}/web/documentserver-example/java/deploy

View File

@ -25,7 +25,7 @@ jobs:
rm -rf ./deploy/'Node.js Example'/public/assets/document-formats/.git
rm -rf ./deploy/'Node.js Example'/public/assets/document-templates/.git
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Node.js.Example
path: ${{ github.workspace }}/web/documentserver-example/nodejs/deploy

View File

@ -25,7 +25,7 @@ jobs:
rm -rf ./deploy/'PHP Example'/assets/document-formats/.git
rm -rf ./deploy/'PHP Example'/assets/document-templates/.git
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: PHP.Example
path: ${{ github.workspace }}/web/documentserver-example/php/deploy

View File

@ -25,7 +25,7 @@ jobs:
rm -rf ./deploy/'Python Example'/assets/document-formats/.git
rm -rf ./deploy/'Python Example'/assets/document-templates/.git
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Python.Example
path: ${{ github.workspace }}/web/documentserver-example/python/deploy

View File

@ -25,7 +25,7 @@ jobs:
rm -rf ./deploy/'Ruby Example'/public/assets/document-formats/.git
rm -rf ./deploy/'Ruby Example'/public/assets/document-templates/.git
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Ruby.Example
path: ${{ github.workspace }}/web/documentserver-example/ruby/deploy

View File

@ -26,7 +26,7 @@ jobs:
rm -rf ./deploy/'Java Spring Example'/src/main/resources/assets/document-formats/.git
rm -rf ./deploy/'Java Spring Example'/src/main/resources/assets/document-templates/.git
- name: Upload Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Java.Spring.Example
path: ${{ github.workspace }}/web/documentserver-example/java-spring/deploy

27
.github/workflows/create-tag.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: Create Tag
on:
push:
branches: [master]
paths-ignore:
- '.github/**'
- '**/AUTHORS.md'
- '**/LICENSE'
- '**/README.md'
jobs:
create-tag:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Get Info
run: |
echo "version=$(grep -Eo '[0-9]+(\.[0-9]+)+' CHANGELOG.md | head -n 1)" >> $GITHUB_OUTPUT
id: info
- name: Create Tag
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
git tag -a 'v${{ steps.info.outputs.version }}' -m 'Release/v${{ steps.info.outputs.version }}'
git push origin 'v${{ steps.info.outputs.version }}'

View File

@ -2,7 +2,8 @@ name: Release
on:
push:
branches: [master]
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
permissions:
contents: write

View File

@ -361,6 +361,41 @@ License: MIT
License File: serializer.license
web/documentserver-example/php-laravel
jQuery.BlockUI - The jQuery BlockUI Plugin lets you simulate synchronous behavior when using AJAX, without locking the browser. (https://github.com/malsup/blockui/)
License: MIT, GPL
License File: jQuery.BlockUI.license
jQuery.FileUpload - File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads. (https://github.com/blueimp/jQuery-File-Upload/blob/master/LICENSE.txt)
License: MIT
License File: jQuery.FileUpload.license
jQuery.iframe-transport - jQuery Iframe Transport Plugin for File Upload (https://github.com/blueimp/jQuery-File-Upload/blob/master/LICENSE.txt)
License: MIT
License File: jQuery.iframe-transport.license
jQuery - jQuery is a new kind of JavaScript Library. jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript. NOTE: This package is maintained on behalf of the library owners by the NuGet Community Packages project at https://nugetpackages.codeplex.com/ (https://jquery.org/license/)
License: MIT
License File: jQuery.license
jQuery.Migrate - Upgrading libraries such as jQuery can be a lot of work, when breaking changes have been introduced. jQuery Migrate makes this easier, by restoring the APIs that were removed, and additionally shows warnings in the browser console (development version of jQuery Migrate only) when removed and/or deprecated APIs are used. (https://github.com/jquery/jquery-migrate/blob/main/LICENSE.txt)
License: OpenJS
License File: jQuery.Migrate.license
jQuery.UI - jQuery UI is an open source library of interface components — interactions, full-featured widgets, and animation effects — based on the stellar jQuery javascript library . Each component is built according to jQuery's event-driven architecture (find something, manipulate it) and is themeable, making it easy for developers of any skill level to integrate and extend into their own code. (https://jquery.org/license/)
License: MIT
License File: jQuery.UI.license
JWT - PHP package for JWT (https://github.com/firebase/php-jwt/blob/main/LICENSE)
License: BSD-3-Clause
License File: jwt.license
Laravel - Laravel is a web application framework with expressive, elegant syntax. Weve already laid the foundation for your next big idea — freeing you to create without sweating the small things. (https://github.com/laravel/framework/blob/master/LICENSE.md)
License - MIT
License File - laravel.license
web/documentserver-example/python
django-stubs - PEP-484 stubs for Django. (https://github.com/typeddjango/django-stubs/blob/master/LICENSE.md)

View File

@ -1,8 +1,24 @@
# Change Log
## 1.14.1
- nodejs: formats for ds v9.1
## 1.14.0
- nodejs: set users by parts
- nodejs: preload frame moved from uploading popap
- nodejs: view odg, md
- nodejs: edit xlsb
- nodejs: support vsdx in diagram editor
- nodejs: fix wopi verification
- nodejs: user role
- nodejs: start filling
- ur skin language
- change preload.html address
## 1.13.0
- nodejs: rename in wopi
- nodejs: using faviconUrl from WOPI discovery
- nodejs: wopi proof key verification
- golang: new integration example
- golang: upload files to the server
- golang: create blank files and files with sample content
@ -18,6 +34,7 @@
- php-laravel: show forgotten files on a seperate page
- php-laravel: fetch files
- php-laravel: integrate sdk
- jwt token lifetime from config
- onUserActionRequired
- support pages, numbers, key formats
- support hwp, hwpx formats

View File

@ -5,7 +5,7 @@ Do NOT use these integration examples on your own server without proper code mod
In case you enabled any of the test examples, disable it before going for production.
These examples show the way to integrate [ONLYOFFICE Docs][2] into your own website or application using one of the programming languages.
The package contains examples written in .Net (C# MVC), .Net (C#), Java, Java Spring, Node.js, PHP, Python and Ruby.
The package contains examples written in .Net (C# MVC), .Net (C#), Go, Java, Java Spring, Node.js, PHP, PHP (Laravel), Python and Ruby.
You should change `http://documentserver` to your server address in these files:
* [.Net (C# MVC)](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/csharp-mvc) - `web/documentserver-example/csharp-mvc/web.appsettings.config`
@ -15,6 +15,7 @@ You should change `http://documentserver` to your server address in these files:
* [Java Spring](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/java-spring) - `web/documentserver-example/java-spring/src/main/resources/application.properties`
* [Node.js](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/nodejs) - `web/documentserver-example/nodejs/config/default.json`
* [PHP](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/php) - `web/documentserver-example/php/src/configuration/ConfigurationManager.php`
* [PHP (Laravel)](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/php-laravel) - `web/documentserver-example/php-laravel/.env.example`
* [Python](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/python) - `web/documentserver-example/python/src/configuration/configuration.py`
* [Ruby](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/ruby) - `web/documentserver-example/ruby/app/configuration/configuration.rb`

View File

@ -146,7 +146,7 @@ header a {
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
.center, .table-main {
width: 100%;
}

View File

@ -639,7 +639,7 @@
}
}
@media (max-width: 420px) and (min-width: 320px) {
@media (max-width: 420px) {
.tableRow,
menu.links {
width: 25%;
@ -715,7 +715,7 @@
max-width: 45%;
}
}
@media (max-width: 600px) and (min-width: 320px) {
@media (max-width: 600px) {
.main-panel{
display: flex;
flex-direction: column;
@ -742,7 +742,7 @@
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
body.menu-open {
overflow: hidden;
}

View File

@ -217,7 +217,9 @@ namespace OnlineEditorsExampleMVC.Helpers
var directoryInfo = new DirectoryInfo(directory);
// take files from the root directory
List<FileInfo> storedFiles = directoryInfo.GetFiles("*.*", SearchOption.TopDirectoryOnly).ToList();
List<FileInfo> storedFiles = directoryInfo.GetFiles("*.*", SearchOption.TopDirectoryOnly)
.OrderByDescending(f => f.LastWriteTimeUtc)
.ToList();
return storedFiles;
}

View File

@ -83,7 +83,8 @@ namespace OnlineEditorsExampleMVC.Helpers
bool isAsync,
out Dictionary<string, string> convertedDocumentData,
string filePass = null,
string lang = null)
string lang = null,
string fileName = null)
{
convertedDocumentData = new Dictionary<string, string>();
@ -91,7 +92,7 @@ namespace OnlineEditorsExampleMVC.Helpers
fromExtension = string.IsNullOrEmpty(fromExtension) ? Path.GetExtension(documentUri).ToLower() : fromExtension;
// check if the file name parameter is defined; if not, get random uuid for this file
var title = Path.GetFileName(documentUri);
var title = string.IsNullOrEmpty(fileName) ? Path.GetFileName(documentUri) : fileName;
title = string.IsNullOrEmpty(title) ? Guid.NewGuid().ToString() : title;
// get document key

View File

@ -20,6 +20,7 @@ using JWT;
using JWT.Algorithms;
using JWT.Builder;
using JWT.Serializers;
using System;
using System.Collections.Generic;
using System.Web.Configuration;
@ -30,17 +31,25 @@ namespace OnlineEditorsExampleMVC.Helpers
private static readonly string Secret;
public static readonly bool Enabled;
public static readonly bool SignatureUseForRequest;
public static readonly int ExpiresIn;
static JwtManager()
{
Secret = WebConfigurationManager.AppSettings["files.docservice.secret"] ?? ""; // get token secret from the config parameters
Enabled = !string.IsNullOrEmpty(Secret); // check if the token is enabled
ExpiresIn = int.Parse(WebConfigurationManager.AppSettings["files.docservice.token.expires-in"]);
SignatureUseForRequest = bool.Parse(WebConfigurationManager.AppSettings["files.docservice.token.useforrequest"]);
}
// encode a payload object into a token using a secret key
public static string Encode(IDictionary<string, object> payload)
{
var now = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
var expires = now + ExpiresIn * 60;
payload["iat"] = now;
payload["exp"] = expires;
var encoder = new JwtEncoder(new HMACSHA256Algorithm(),
new JsonNetSerializer(),
new JwtBase64UrlEncoder());

View File

@ -415,14 +415,12 @@ if (typeof jQuery != "undefined") {
jq("#convertStep2").removeClass("current").addClass("done");
jq("#convertStep2").text(`2. File conversion to ${fileExt}`);
jq("#downloadConverted").removeClass("disable");
jq("#hiddenFileName").attr("data",response.filename);
if (response.error !== "FileTypeIsNotSupported") {
jq("#hiddenFileName").attr("data",response.filename);
jq("#beginEditConverted").removeClass("disable");
jq("#beginViewConverted").removeClass("disable");
jq("#downloadConverted").attr("data","fromStorage");
} else {
let newFilename = fileName.split('.').slice(0,-1).join('.')
jq("#hiddenFileName").attr("data",response.filename.split("&filename=download").join(`&filename=${newFilename}`));
jq("#downloadConverted").attr("data","fromConverter");
}
jq("td[name='convertingTypeButton']").removeClass("disable orange");

View File

@ -280,7 +280,7 @@ namespace OnlineEditorsExampleMVC
// get the url and file type of the converted file
Dictionary<string, string> newFileData;
var result = ServiceConverter.GetConvertedData(downloadUri.ToString(), extension, conversionExtension, key, true, out newFileData, filePass, lang);
var result = ServiceConverter.GetConvertedData(downloadUri.ToString(), extension, conversionExtension, key, true, out newFileData, filePass, lang, fileName);
if (result != 100)
{
context.Response.Write("{ \"step\" : \"" + result + "\", \"filename\" : \"" + fileName + "\"}");
@ -990,7 +990,7 @@ namespace OnlineEditorsExampleMVC
var changes = jss.Deserialize<Dictionary<string, object>>(File.ReadAllText(changesPath));
var changesArray = (ArrayList)changes["changes"];
var change = changesArray.Count > 0
? (Dictionary<string, object>)changesArray[0]
? (Dictionary<string, object>)changesArray[changesArray.Count - 1]
: new Dictionary<string, object>();
// write information about changes to the object

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<appSettings>
<clear />
<add key="version" value="1.13.0"/>
<add key="version" value="1.14.0"/>
<add key="filesize-max" value="52428800"/>
<add key="storage-path" value=""/>
@ -13,16 +13,17 @@
<add key="files.docservice.header" value="Authorization" />
<add key="files.docservice.token.useforrequest" value="true" />
<add key="files.docservice.token.expires-in" value="5"/>
<add key="files.docservice.verify-peer-off" value="true"/>
<add key="files.docservice.languages" value="en:English|sq-AL:Albanian (Albania)|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|he-IL:Hebrew (Israel)|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Cyrl-RS:Serbian (Cyrillic)|sr-Latn-RS:Serbian (Latin)|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA:Test Language"/>
<add key="files.docservice.languages" value="en:English|sq-AL:Albanian (Albania)|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|he-IL:Hebrew (Israel)|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Cyrl-RS:Serbian (Cyrillic)|sr-Latn-RS:Serbian (Latin)|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|ur:Urdu|vi:Vietnamese|aa-AA:Test Language"/>
<add key="files.docservice.url.site" value="http://documentserver/"/>
<add key="files.docservice.url.converter" value="converter"/>
<add key="files.docservice.url.api" value="web-apps/apps/api/documents/api.js"/>
<add key="files.docservice.url.preloader" value="web-apps/apps/api/documents/cache-scripts.html"/>
<add key="files.docservice.url.preloader" value="web-apps/apps/api/documents/preload.html"/>
<add key="files.docservice.url.command" value="command"/>
<add key="files.docservice.url.example" value=""/>

View File

@ -146,7 +146,7 @@ header a {
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
.center, .table-main {
width: 100%;
}

View File

@ -639,7 +639,7 @@
}
}
@media (max-width: 420px) and (min-width: 320px) {
@media (max-width: 420px) {
.tableRow,
menu.links {
width: 25%;
@ -715,7 +715,7 @@
max-width: 45%;
}
}
@media (max-width: 600px) and (min-width: 320px) {
@media (max-width: 600px) {
.main-panel{
display: flex;
flex-direction: column;
@ -742,7 +742,7 @@
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
body.menu-open {
overflow: hidden;
}

View File

@ -469,7 +469,7 @@ namespace OnlineEditorsExample
// get the url and file type of the converted file
Dictionary<string, string> newFileData;
var result = ServiceConverter.GetConvertedData(fileUrl.ToString() , extension, conversionExtension, key, true, out newFileData, filePass, lang);
var result = ServiceConverter.GetConvertedData(fileUrl.ToString() , extension, conversionExtension, key, true, out newFileData, filePass, lang, _fileName);
if (result != 100)
{
return "{ \"step\" : \"" + result + "\", \"filename\" : \"" + _fileName + "\"}";
@ -562,7 +562,10 @@ namespace OnlineEditorsExample
var directoryInfo = new DirectoryInfo(directory); // read the user host directory contents
// get the list of stored files from the host directory
List<FileInfo> storedFiles = directoryInfo.GetFiles("*.*", SearchOption.TopDirectoryOnly).ToList();
var storedFiles = directoryInfo.GetFiles("*.*", SearchOption.TopDirectoryOnly).ToList();
storedFiles.Sort((a, b) => b.LastWriteTimeUtc.CompareTo(a.LastWriteTimeUtc)); // sort files by the modification date
return storedFiles;
}

View File

@ -85,7 +85,8 @@ namespace ASC.Api.DocumentConverter
bool isAsync,
out Dictionary<string, string> convertedDocumentData,
string filePass = null,
string lang = null)
string lang = null,
string filename = null)
{
convertedDocumentData = new Dictionary<string, string>();
@ -93,7 +94,7 @@ namespace ASC.Api.DocumentConverter
fromExtension = string.IsNullOrEmpty(fromExtension) ? Path.GetExtension(documentUri).ToLower() : fromExtension;
// check if the file name parameter is defined; if not, get random uuid for this file
var title = Path.GetFileName(documentUri);
var title = string.IsNullOrEmpty(filename) ? Path.GetFileName(documentUri) : filename;
title = string.IsNullOrEmpty(title) ? Guid.NewGuid().ToString() : title;
// get document key

View File

@ -20,6 +20,7 @@ using JWT;
using JWT.Algorithms;
using JWT.Builder;
using JWT.Serializers;
using System;
using System.Collections.Generic;
using System.Web.Configuration;
@ -28,6 +29,7 @@ namespace OnlineEditorsExample
public static class JwtManager
{
private static readonly string Secret;
private static readonly int ExpiresIn;
public static readonly bool Enabled;
public static readonly bool SignatureUseForRequest;
@ -35,12 +37,19 @@ namespace OnlineEditorsExample
{
Secret = WebConfigurationManager.AppSettings["files.docservice.secret"] ?? ""; // get token secret from the config parameters
Enabled = !string.IsNullOrEmpty(Secret); // check if the token is enabled
ExpiresIn = int.Parse(WebConfigurationManager.AppSettings["files.docservice.token.expires-in"]);
SignatureUseForRequest = bool.Parse(WebConfigurationManager.AppSettings["files.docservice.token.useforrequest"]);
}
// encode a payload object into a token using a secret key
public static string Encode(IDictionary<string, object> payload)
{
var now = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
var expires = now + ExpiresIn * 60;
payload["iat"] = now;
payload["exp"] = expires;
var encoder = new JwtEncoder(new HMACSHA256Algorithm(),
new JsonNetSerializer(),
new JwtBase64UrlEncoder());

View File

@ -778,7 +778,7 @@ namespace OnlineEditorsExample
var changes = jss.Deserialize<Dictionary<string, object>>(File.ReadAllText(changesPath));
var changesArray = (ArrayList)changes["changes"];
var change = changesArray.Count > 0
? (Dictionary<string, object>)changesArray[0]
? (Dictionary<string, object>)changesArray[changesArray.Count - 1]
: new Dictionary<string, object>();
// write information about changes to the object

View File

@ -415,14 +415,12 @@ if (typeof jQuery != "undefined") {
jq("#convertStep2").removeClass("current").addClass("done");
jq("#convertStep2").text(`2. File conversion to ${fileExt}`);
jq("#downloadConverted").removeClass("disable");
jq("#hiddenFileName").attr("data",response.filename);
if (response.error !== "FileTypeIsNotSupported") {
jq("#hiddenFileName").attr("data",response.filename);
jq("#beginEditConverted").removeClass("disable");
jq("#beginViewConverted").removeClass("disable");
jq("#downloadConverted").attr("data","fromStorage");
} else {
let newFilename = fileName.split('.').slice(0,-1).join('.')
jq("#hiddenFileName").attr("data",response.filename.split("&filename=download").join(`&filename=${newFilename}`));
jq("#downloadConverted").attr("data","fromConverter");
}
jq("td[name='convertingTypeButton']").removeClass("disable orange");

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<clear />
<add key="version" value="1.13.0"/>
<add key="version" value="1.14.0"/>
<add key="filesize-max" value="52428800"/>
<add key="storage-path" value=""/>
@ -14,14 +14,15 @@
<add key="files.docservice.verify-peer-off" value="true"/>
<add key="files.docservice.token.useforrequest" value="true" />
<add key="files.docservice.token.expires-in" value="5"/>
<add key="files.docservice.languages" value="en:English|sq-AL:Albanian (Albania)|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|he-IL:Hebrew (Israel)|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Cyrl-RS:Serbian (Cyrillic)|sr-Latn-RS:Serbian (Latin)|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA: Test Language"/>
<add key="files.docservice.languages" value="en:English|sq-AL:Albanian (Albania)|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|he-IL:Hebrew (Israel)|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Cyrl-RS:Serbian (Cyrillic)|sr-Latn-RS:Serbian (Latin)|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|ur:Urdu|vi:Vietnamese|aa-AA: Test Language"/>
<add key="files.docservice.url.site" value="http://documentserver/"/>
<add key="files.docservice.url.converter" value="converter"/>
<add key="files.docservice.url.api" value="web-apps/apps/api/documents/api.js"/>
<add key="files.docservice.url.preloader" value="web-apps/apps/api/documents/cache-scripts.html"/>
<add key="files.docservice.url.preloader" value="web-apps/apps/api/documents/preload.html"/>
<add key="files.docservice.url.command" value="command"/>
<add key="files.docservice.url.example" value=""/>

View File

@ -4,6 +4,7 @@ linters:
- cyclop
- depguard
- dogsled
- durationcheck
- err113
- errchkjson
- execinquery

View File

@ -1,5 +1,5 @@
{
"VERSION": "1.13.0",
"VERSION": "1.14.0",
"SERVER_ADDRESS" : "",
"SERVER_PORT" : 3000,
@ -7,10 +7,11 @@
"DOC_SERVER_HOST" : "http://documentserver/",
"DOC_SERVER_CONVERTER_URL" : "converter",
"DOC_SERVER_API_URL" : "web-apps/apps/api/documents/api.js",
"DOC_SERVER_PRELOADER_URL" : "web-apps/apps/api/documents/cache-scripts.html",
"DOC_SERVER_PRELOADER_URL" : "web-apps/apps/api/documents/preload.html",
"DOC_SERVER_COMMAND_URL" : "command",
"JWT_IS_ENABLED" : false,
"JWT_EXPIRES_IN" : 5,
"JWT_SECRET" : "secret",
"JWT_HEADER" : "Authorization",
@ -66,6 +67,7 @@
"sv": "Swedish",
"tr": "Turkish",
"uk": "Ukrainian",
"ur": "Urdu",
"vi": "Vietnamese",
"aa-AA": "Test Language"
}

View File

@ -20,6 +20,7 @@ package config
import (
"path/filepath"
"runtime"
"time"
"github.com/ONLYOFFICE/document-server-integration/utils"
"github.com/spf13/viper"
@ -36,6 +37,7 @@ type ApplicationConfig struct {
DocumentServerPreloader string `mapstructure:"DOC_SERVER_PRELOADER_URL"`
DocumentServerCommandUrl string `mapstructure:"DOC_SERVER_COMMAND_URL"`
JwtEnabled bool `mapstructure:"JWT_IS_ENABLED"`
JwtExpiresIn time.Duration `mapstructure:"JWT_EXPIRES_IN"`
JwtHeader string `mapstructure:"JWT_HEADER"`
JwtSecret string `mapstructure:"JWT_SECRET"`
StoragePath string `mapstructure:"STORAGE_PATH"`

View File

@ -22,10 +22,12 @@ import (
"fmt"
"net/http"
"strings"
"time"
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/ONLYOFFICE/document-server-integration/server/shared"
"github.com/golang-jwt/jwt"
)
func (srv *DefaultServerEndpointsHandler) Config(w http.ResponseWriter, r *http.Request) {
@ -71,6 +73,10 @@ func (srv *DefaultServerEndpointsHandler) Config(w http.ResponseWriter, r *http.
),
Mode: "edit",
},
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * srv.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
},
}
secret := strings.TrimSpace(srv.config.JwtSecret)

View File

@ -79,7 +79,7 @@ func (srv *DefaultServerEndpointsHandler) Convert(w http.ResponseWriter, r *http
return
}
newUrl, newExt, err := srv.ConversionManager.GetConverterUri(fileUrl, fileExt, toExt, key, true)
newUrl, newExt, err := srv.ConversionManager.GetConverterUri(fileUrl, fileExt, toExt, key, true, filename)
if err != nil {
response.Error = err.Error()
srv.logger.Errorf("File conversion error: %s", err.Error())

View File

@ -96,6 +96,10 @@ func (srv *DefaultServerEndpointsHandler) Create(w http.ResponseWriter, r *http.
srv.logger.Errorf("meta creation error: %s", err.Error())
}
res := map[string]interface{}{
"file": correctName,
}
shared.SendResponse(w, res)
return
}

View File

@ -23,11 +23,13 @@ import (
"net/http"
"net/url"
"strings"
"time"
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/ONLYOFFICE/document-server-integration/server/shared"
"github.com/ONLYOFFICE/document-server-integration/utils"
"github.com/golang-jwt/jwt"
)
func (srv *DefaultServerEndpointsHandler) Reference(w http.ResponseWriter, r *http.Request) {
@ -43,15 +45,11 @@ func (srv *DefaultServerEndpointsHandler) Reference(w http.ResponseWriter, r *ht
var fileKey map[string]string
err := json.Unmarshal([]byte(body.ReferenceData.FileKey), &fileKey)
if err != nil {
srv.logger.Error("FileKey decoding error")
shared.SendDocumentServerRespose(w, true)
return
}
path, _ := srv.GenerateFilePath(fileKey["fileName"])
if body.ReferenceData.InstanceId == remoteAddr && srv.PathExists(path) {
fileName = fileKey["fileName"]
if err == nil {
path, _ := srv.GenerateFilePath(fileKey["fileName"])
if body.ReferenceData.InstanceId == remoteAddr && srv.PathExists(path) {
fileName = fileKey["fileName"]
}
}
if fileName == "" && body.Link != "" {
@ -99,6 +97,10 @@ func (srv *DefaultServerEndpointsHandler) Reference(w http.ResponseWriter, r *ht
},
Link: remoteAddr + "/editor?filename=" + url.QueryEscape(fileName),
Path: fileName,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * srv.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
},
}
secret := strings.TrimSpace(srv.config.JwtSecret)

View File

@ -44,7 +44,7 @@ func (srv *DefaultServerEndpointsHandler) Upload(w http.ResponseWriter, r *http.
srv.logger.Debug("A new upload call")
if !srv.DocumentManager.IsDocumentConvertable(handler.Filename) {
srv.logger.Errorf("File %s is not supported", handler.Filename)
shared.SendCustomErrorResponse(w, "File type is not supported")
shared.SendResponse(w, map[string]string{"error": "File type is not supported"})
return
}

View File

@ -77,7 +77,7 @@ type ConversionManager interface {
GetInternalExtension(fileType string) string
IsCanConvert(ext string) bool
IsCanFill(ext string) bool
GetConverterUri(docUri, fromExt, toExt, docKey string, isAsync bool) (string, string, error)
GetConverterUri(docUri, fromExt, toExt, docKey string, isAsync bool, title string) (string, string, error)
}
type CommandManager interface {

View File

@ -23,6 +23,7 @@ import (
"net/http"
"net/url"
"strings"
"time"
"github.com/ONLYOFFICE/document-server-integration/config"
"github.com/ONLYOFFICE/document-server-integration/server/managers"
@ -59,6 +60,10 @@ func (cm DefaultCommandManager) CommandRequest(method string, docKey string, met
payload := CommandPayload{
C: method,
Key: docKey,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * cm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
},
}
if meta != nil {
payload.Meta = meta
@ -68,7 +73,7 @@ func (cm DefaultCommandManager) CommandRequest(method string, docKey string, met
var headerToken string
secret := strings.TrimSpace(cm.config.JwtSecret)
if secret != "" && cm.config.JwtEnabled {
headerPayload := fillJwtByUrl(uri, payload)
headerPayload := fillJwtByUrl(uri, payload, cm.config)
headerToken, err = cm.JwtManager.JwtSign(headerPayload, []byte(secret))
if err != nil {
return nil, err
@ -103,7 +108,7 @@ func (cm DefaultCommandManager) CommandRequest(method string, docKey string, met
return response, nil
}
func fillJwtByUrl(uri string, payload CommandPayload) CommandRequestHeaderPayload {
func fillJwtByUrl(uri string, payload CommandPayload, config config.ApplicationConfig) CommandRequestHeaderPayload {
urlObj, _ := url.Parse(uri)
query, _ := url.ParseQuery(urlObj.RawQuery)
queryMap := make(map[string]string)
@ -114,5 +119,9 @@ func fillJwtByUrl(uri string, payload CommandPayload) CommandRequestHeaderPayloa
return CommandRequestHeaderPayload{
Query: queryMap,
Payload: payload,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
},
}
}

View File

@ -24,11 +24,13 @@ import (
"io"
"net/http"
"strings"
"time"
"github.com/ONLYOFFICE/document-server-integration/config"
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/ONLYOFFICE/document-server-integration/server/shared"
"github.com/ONLYOFFICE/document-server-integration/utils"
"github.com/golang-jwt/jwt"
"go.uber.org/zap"
)
@ -97,6 +99,7 @@ func (cm DefaultConversionManager) GetConverterUri(
toExt string,
docKey string,
isAsync bool,
title string,
) (string, string, error) {
if fromExt == "" {
fromExt = utils.GetFileExt(docUri, true)
@ -106,9 +109,13 @@ func (cm DefaultConversionManager) GetConverterUri(
DocUrl: docUri,
OutputType: strings.ReplaceAll(toExt, ".", ""),
FileType: fromExt,
Title: utils.GetFileName(docUri),
Title: title,
Key: docKey,
Async: isAsync,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * cm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
},
}
var headerToken string
@ -116,7 +123,13 @@ func (cm DefaultConversionManager) GetConverterUri(
secret := strings.TrimSpace(cm.config.JwtSecret)
if secret != "" && cm.config.JwtEnabled {
headerPayload := managers.ConvertRequestHeaderPayload{Payload: payload}
headerPayload := managers.ConvertRequestHeaderPayload{
Payload: payload,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * cm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
},
}
headerToken, err = cm.JwtManager.JwtSign(headerPayload, []byte(secret))
if err != nil {
return "", "", err

View File

@ -28,6 +28,7 @@ import (
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/ONLYOFFICE/document-server-integration/utils"
"github.com/golang-jwt/jwt"
"go.uber.org/zap"
)
@ -152,7 +153,7 @@ func (dm DefaultDocumentManager) BuildDocumentConfig(
return nil, err
}
config := models.Config{
config := &models.Config{
Type: parameters.Type,
DocumentType: dm.ConversionManager.GetFileType(parameters.Filename),
Document: models.Document{
@ -223,6 +224,10 @@ func (dm DefaultDocumentManager) BuildDocumentConfig(
},
},
},
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * dm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
},
}
secret := strings.TrimSpace(dm.config.JwtSecret)
@ -231,7 +236,7 @@ func (dm DefaultDocumentManager) BuildDocumentConfig(
config.Token = token
}
return &config, nil
return config, nil
}
func (dm DefaultDocumentManager) IsDocumentConvertable(filename string) bool {

View File

@ -23,12 +23,14 @@ import (
"fmt"
"net/http"
"path"
"time"
"github.com/ONLYOFFICE/document-server-integration/config"
"github.com/ONLYOFFICE/document-server-integration/server/managers"
"github.com/ONLYOFFICE/document-server-integration/server/models"
"github.com/ONLYOFFICE/document-server-integration/server/shared"
"github.com/ONLYOFFICE/document-server-integration/utils"
"github.com/golang-jwt/jwt"
"go.uber.org/zap"
)
@ -195,6 +197,10 @@ func (hm DefaultHistoryManager) fetchNextHistoryEntry(
Key: key,
Url: url,
Version: version,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * hm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
},
}
}
@ -261,6 +267,10 @@ func (hm DefaultHistoryManager) GetHistory(
Url: hm.StorageManager.GeneratePublicFileUri(filename, remoteAddress, managers.FileMeta{}),
Version: version,
ChangesUrl: changesUrl,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Minute * hm.config.JwtExpiresIn).Unix(),
IssuedAt: time.Now().Unix(),
},
}
rhist.History = append(rhist.History, models.History{

View File

@ -94,7 +94,7 @@ func (sm DefaultStorageManager) GetStoredFiles(remoteAddress string) ([]models.D
}
sort.Slice(files, func(i, j int) bool {
return files[i].ModTime().Before(files[j].ModTime())
return !files[i].ModTime().Before(files[j].ModTime())
})
for _, v := range files {

View File

@ -86,7 +86,9 @@ func NewDefaultUserManager(logger *zap.SugaredLogger) managers.UserManager {
Goback: map[string]interface{}{
"text": "Go to Documents",
},
Close: nil,
Close: map[string]interface{}{
"visible": true,
},
},
{
Id: "uid-3",
@ -106,7 +108,9 @@ func NewDefaultUserManager(logger *zap.SugaredLogger) managers.UserManager {
Templates: false,
Avatar: false,
Goback: nil,
Close: nil,
Close: map[string]interface{}{
"visible": true,
},
},
}
return &DefaultUserManager{

View File

@ -20,10 +20,10 @@ package models
import "github.com/golang-jwt/jwt"
type Config struct {
Type string `json:"type"`
Document Document `json:"document"`
DocumentType string `json:"documentType"`
EditorConfig EditorConfig `json:"editorConfig"`
Token string `json:"token,omitempty"`
jwt.StandardClaims `json:"-"`
Type string `json:"type"`
Document Document `json:"document"`
DocumentType string `json:"documentType"`
EditorConfig EditorConfig `json:"editorConfig"`
Token string `json:"token,omitempty"`
jwt.StandardClaims
}

View File

@ -25,12 +25,12 @@ type ReferenceData struct {
}
type Reference struct {
ReferenceData ReferenceData `json:"referenceData"`
Link string `json:"link"`
Path string `json:"path"`
FileType string `json:"fileType"`
Key string `json:"key"`
Url string `json:"url"`
Token string `json:"token,omitempty"`
jwt.StandardClaims `json:"-"`
ReferenceData ReferenceData `json:"referenceData"`
Link string `json:"link"`
Path string `json:"path"`
FileType string `json:"fileType"`
Key string `json:"key"`
Url string `json:"url"`
Token string `json:"token,omitempty"`
jwt.StandardClaims
}

View File

@ -16,7 +16,6 @@
*
*/
var directUrl;
var formatManager;
window.onload = function () {
@ -42,19 +41,8 @@ window.onload = function () {
if (typeof jQuery !== "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function() {
window.location = "?directUrl=" + jq(this).prop("checked");
});
jq(function () {
jq("#fileupload").fileupload({
dataType: "json",
@ -277,7 +265,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?mode=edit&fileName=" + fileId+ "&directUrl=" + directUrl;
var url = UrlEditor + "?mode=edit&fileName=" + fileId;
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
@ -286,7 +274,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?mode=view&fileName=" + fileId+ "&directUrl=" + directUrl;
var url = UrlEditor + "?mode=view&fileName=" + fileId;
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
@ -295,7 +283,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?type=embedded&mode=embedded&fileName=" + fileId + "&directUrl=" + directUrl;
var url = UrlEditor + "?type=embedded&mode=embedded&fileName=" + fileId;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -414,14 +402,12 @@ if (typeof jQuery !== "undefined") {
jq("#convertStep2").removeClass("current").addClass("done");
jq("#convertStep2").text(`2. File conversion to ${fileExt}`);
jq("#downloadConverted").removeClass("disable");
jq("#hiddenFileName").attr("data",response.filename);
if (response.error !== "FileTypeIsNotSupported") {
jq("#hiddenFileName").attr("data",response.filename);
jq("#beginEditConverted").removeClass("disable");
jq("#beginViewConverted").removeClass("disable");
jq("#downloadConverted").attr("data","fromStorage");
} else {
let newFilename = fileName.split('.').slice(0,-1).join('.')
jq("#hiddenFileName").attr("data",response.filename.split("&filename=download").join(`&filename=${newFilename}`));
jq("#downloadConverted").attr("data","fromConverter");
}
jq("td[name='convertingTypeButton']").removeClass("disable orange");

View File

@ -146,7 +146,7 @@ header a {
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
.center, .table-main {
width: 100%;
}

View File

@ -640,7 +640,7 @@
}
}
@media (max-width: 420px) and (min-width: 320px) {
@media (max-width: 420px) {
.tableRow,
menu.links {
width: 25%;
@ -716,7 +716,7 @@
max-width: 45%;
}
}
@media (max-width: 600px) and (min-width: 320px) {
@media (max-width: 600px) {
.main-panel{
display: flex;
flex-direction: column;
@ -743,7 +743,7 @@
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
body.menu-open {
overflow: hidden;
}

View File

@ -256,6 +256,7 @@ public class FileController {
.outputtype(conversionExtension)
.region(lang)
.async(true)
.title(fileName)
.build();
ConvertResponse convertResponse = convertService.processConvert(convertRequest, fileName);

View File

@ -123,7 +123,10 @@ public class DefaultHistoryManager implements HistoryManager {
History changes = objectMapper.readValue(changesSteam, History.class);
List<Object> historyChanges = changes.getChanges();
Map<String, Object> historyChange = objectMapper.convertValue(historyChanges.get(0), Map.class);
Map<String, Object> historyChange = objectMapper.convertValue(
historyChanges.get(historyChanges.size() - 1),
Map.class
);
// write information about changes to the object
version.setChanges(changes.getChanges());

View File

@ -46,6 +46,8 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -317,7 +319,9 @@ public class LocalFileStorage implements FileStorageMutator, FileStoragePathBuil
// get a collection of all the stored files
public File[] getStoredFiles() {
File file = new File(getStorageLocation());
return file.listFiles(pathname -> pathname.isFile());
File[] files = file.listFiles(pathname -> pathname.isFile());
Arrays.sort(files, Comparator.comparingLong(File::lastModified).reversed());
return files;
}
@SneakyThrows

View File

@ -1,4 +1,4 @@
server.version=1.13.0
server.version=1.14.0
server.address=
server.port=4000
@ -15,7 +15,7 @@ files.docservice.history.postfix=-hist
files.docservice.url.example=
files.docservice.languages=en:English|sq-AL:Albanian (Albania)|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|he-IL:Hebrew (Israel)|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Cyrl-RS:Serbian (Cyrillic)|sr-Latn-RS:Serbian (Latin)|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA:Test Language
files.docservice.languages=en:English|sq-AL:Albanian (Albania)|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|he-IL:Hebrew (Israel)|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Cyrl-RS:Serbian (Cyrillic)|sr-Latn-RS:Serbian (Latin)|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|ur:Urdu|vi:Vietnamese|aa-AA:Test Language
docservice.url=http://documentserver/
docservice.ignoreSSLCertificate=false
@ -23,6 +23,7 @@ docservice.lossyEdit=epub, fb2, html, odt, ott, rtf, txt, csv, ods, ots, odp, ot
docservice.security.key=
docservice.security.header=
docservice.security.tokenValidityInMinutes=5
spring.datasource.url=jdbc:h2:mem:usersdb
spring.datasource.driverClassName=org.h2.Driver

View File

@ -146,7 +146,7 @@ header a {
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
.center, .table-main {
width: 100%;
}

View File

@ -626,7 +626,7 @@
}
}
@media (max-width: 420px) and (min-width: 320px) {
@media (max-width: 420px) {
.tableRow,
menu.links {
width: 25%;
@ -702,7 +702,7 @@
max-width: 45%;
}
}
@media (max-width: 600px) and (min-width: 320px) {
@media (max-width: 600px) {
.main-panel{
display: flex;
flex-direction: column;
@ -729,7 +729,7 @@
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
body.menu-open {
overflow: hidden;
}

View File

@ -274,6 +274,7 @@ if (typeof jQuery !== "undefined") {
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
document.location.reload();
});
jq(document).on("click", "#beginView:not(.disable)", function () {
@ -282,6 +283,7 @@ if (typeof jQuery !== "undefined") {
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
document.location.reload();
});
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
@ -405,14 +407,12 @@ if (typeof jQuery !== "undefined") {
jq("#convertStep2").removeClass("current").addClass("done");
jq("#convertStep2").text(`2. File conversion to ${fileExt}`);
jq("#downloadConverted").removeClass("disable");
jq("#hiddenFileName").attr("data",response.filename);
if (response.error !== "FileTypeIsNotSupported") {
jq("#hiddenFileName").attr("data",response.filename);
jq("#beginEditConverted").removeClass("disable");
jq("#beginViewConverted").removeClass("disable");
jq("#downloadConverted").attr("data","fromStorage");
} else {
let newFilename = fileName.split('.').slice(0,-1).join('.')
jq("#hiddenFileName").attr("data",response.filename.split("&filename=download").join(`&filename=${newFilename}`));
jq("#downloadConverted").attr("data","fromConverter");
}
jq("td[name='convertingTypeButton']").removeClass("disable orange");

View File

@ -303,7 +303,7 @@ public class IndexServlet extends HttpServlet {
// get the url and file type to the converted file
Map<String, String> newFileData = ServiceConverter
.getConvertedData(fileUri, fileExt, conversionExtension, key, filePass, true, lang);
.getConvertedData(fileUri, fileExt, conversionExtension, key, filePass, true, lang, fileName);
String newFileUri = newFileData.get("fileUrl");
String newFileType = newFileData.get("fileType");
@ -960,7 +960,8 @@ public class IndexServlet extends HttpServlet {
JSONObject changes = (JSONObject) parser.parse(
DocumentManager.readFileToEnd(new File(DocumentManager
.versionDir(histDir, i - 1) + File.separator + "changes.json")));
JSONObject change = (JSONObject) ((JSONArray) changes.get("changes")).get(0);
JSONObject change = (JSONObject) ((JSONArray) changes.get("changes"))
.get(((JSONArray) changes.get("changes")).size() - 1);
// write information about changes to the object
obj.put("changes", !change.isEmpty() ? changes.get("changes") : null);

View File

@ -47,8 +47,10 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
@ -290,12 +292,17 @@ public final class DocumentManager {
String directory = filesRootPath(userAddress);
File file = new File(directory);
return file.listFiles(new FileFilter() { // take only files from the root directory
File[] files = file.listFiles(new FileFilter() { // take only files from the root directory
@Override
public boolean accept(final File pathname) {
return pathname.isFile();
}
});
Arrays.sort(files, Comparator.comparingLong(File::lastModified).reversed());
return files;
}
// create demo document
@ -543,6 +550,7 @@ public final class DocumentManager {
for (String key : payloadClaims.keySet()) { // run through all the keys from the payload
jwt.addClaim(key, payloadClaims.get(key)); // and write each claim to the jwt
}
jwt.setExpiration(ZonedDateTime.now().plusMinutes(getTokenExpiration()));
return JWT.getEncoder().encode(jwt, signer); // sign and encode the JWT to a JSON string representation
} catch (Exception e) {
return "";
@ -579,6 +587,11 @@ public final class DocumentManager {
return ConfigManager.getProperty("files.docservice.secret");
}
// get token expiration time in minutes from the config parameters
public static Integer getTokenExpiration() {
return Integer.parseInt(ConfigManager.getProperty("files.docservice.token-expiration"));
}
// get config request jwt
public static String getTokenUseForRequest() {
return ConfigManager.getProperty("files.docservice.token-use-for-request");

View File

@ -140,13 +140,13 @@ public final class ServiceConverter {
public static Map<String, String> getConvertedData(final String documentUri, final String fromExtension,
final String toExtension, final String documentRevisionId,
final String filePass, final Boolean isAsync,
final String lang) throws Exception {
final String lang, final String filename) throws Exception {
// check if the fromExtension parameter is defined; if not, get it from the document url
String fromExt = fromExtension == null || fromExtension.isEmpty()
? FileUtility.getFileExtension(documentUri) : fromExtension;
// check if the file name parameter is defined; if not, get random uuid for this file
String title = FileUtility.getFileName(documentUri);
String title = filename == null || filename.isEmpty() ? FileUtility.getFileName(documentUri) : filename;
title = title == null || title.isEmpty() ? UUID.randomUUID().toString() : title;
String documentRevId = documentRevisionId == null || documentRevisionId.isEmpty()

View File

@ -158,7 +158,7 @@ public final class TrackManager {
String newFileUri = ServiceConverter
.getConvertedData(downloadUri, downloadExt, curExt,
ServiceConverter.generateRevisionId(downloadUri),
null, false, null).get("fileUrl"); // convert file and get url to a new file
null, false, null, null).get("fileUrl"); // convert file and get url to a new file
if (newFileUri.isEmpty()) {
// get the correct file name if it already exists
@ -250,7 +250,7 @@ public final class TrackManager {
String newFileUri = ServiceConverter
.getConvertedData(downloadUri, downloadExt, curExt,
ServiceConverter.generateRevisionId(downloadUri), null,
false, null).get("fileUrl"); // convert file and get url to a new file
false, null, null).get("fileUrl"); // convert file and get url to a new file
if (newFileUri.isEmpty()) {
newFileName = true;
} else {

View File

@ -1,4 +1,4 @@
version=1.13.0
version=1.14.0
filesize-max=5242880
storage-folder=app_data
@ -11,13 +11,14 @@ files.docservice.url.site=http://documentserver/
files.docservice.url.converter=converter
files.docservice.url.command=command
files.docservice.url.api=web-apps/apps/api/documents/api.js
files.docservice.url.preloader=web-apps/apps/api/documents/cache-scripts.html
files.docservice.url.preloader=web-apps/apps/api/documents/preload.html
files.docservice.url.example=
files.docservice.languages=en:English|sq-AL:Albanian (Albania)|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|he-IL:Hebrew (Israel)|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Cyrl-RS:Serbian (Cyrillic)|sr-Latn-RS:Serbian (Latin)|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA:Test Language
files.docservice.languages=en:English|sq-AL:Albanian (Albania)|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|he-IL:Hebrew (Israel)|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Cyrl-RS:Serbian (Cyrillic)|sr-Latn-RS:Serbian (Latin)|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|ur:Urdu|vi:Vietnamese|aa-AA:Test Language
files.docservice.secret=
files.docservice.header=Authorization
files.docservice.token-use-for-request=TRUE
files.docservice.token-expiration=5
files.docservice.verify-peer-off=TRUE

View File

@ -146,7 +146,7 @@ header a {
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
.center, .table-main {
width: 100%;
}

View File

@ -625,7 +625,7 @@
}
}
@media (max-width: 420px) and (min-width: 320px) {
@media (max-width: 420px) {
.tableRow,
menu.links {
width: 25%;
@ -701,7 +701,7 @@
max-width: 45%;
}
}
@media (max-width: 600px) and (min-width: 320px) {
@media (max-width: 600px) {
.main-panel{
display: flex;
flex-direction: column;
@ -728,7 +728,7 @@
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
body.menu-open {
overflow: hidden;
}

View File

@ -281,6 +281,7 @@ if (typeof jQuery !== "undefined") {
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
document.location.reload();
});
jq(document).on("click", "#beginView:not(.disable)", function () {
@ -289,6 +290,7 @@ if (typeof jQuery !== "undefined") {
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
document.location.reload();
});
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
@ -412,14 +414,12 @@ if (typeof jQuery !== "undefined") {
jq("#convertStep2").removeClass("current").addClass("done");
jq("#convertStep2").text(`2. File conversion to ${fileExt}`);
jq("#downloadConverted").removeClass("disable");
jq("#hiddenFileName").attr("data",response.filename);
if (response.error !== "FileTypeIsNotSupported") {
jq("#hiddenFileName").attr("data",response.filename);
jq("#beginEditConverted").removeClass("disable");
jq("#beginViewConverted").removeClass("disable");
jq("#downloadConverted").attr("data","fromStorage");
} else {
let newFilename = fileName.split('.').slice(0,-1).join('.')
jq("#hiddenFileName").attr("data",response.filename.split("&filename=download").join(`&filename=${newFilename}`));
jq("#downloadConverted").attr("data","fromConverter");
}
jq("td[name='convertingTypeButton']").removeClass("disable orange");

View File

@ -500,7 +500,7 @@ app.post('/convert', (req, res) => { // define a handler for converting files
key = documentService.generateRevisionId(key); // get document key
// get the url to the converted file
documentService.getConvertedUri(fileUri, fileExt, convExt, key, true, callback, filePass, lang);
documentService.getConvertedUri(fileUri, fileExt, convExt, key, true, callback, filePass, lang, fileName);
} else {
// if the file with such an extension can't be converted, write the origin file to the result object
writeResult(fileName, null, null);
@ -1139,6 +1139,7 @@ app.get('/editor', (req, res) => { // define a handler for editing document
const { reviewGroups } = user;
const { commentGroups } = user;
const { userInfoGroups } = user;
const userRoles = user.roles;
const usersInfo = [];
const usersForProtect = [];
@ -1180,7 +1181,7 @@ app.get('/editor', (req, res) => { // define a handler for editing document
let submitForm = false;
if (mode !== 'view') {
submitForm = userid === 'uid-1';
submitForm = user.canSubmitForm;
}
if (user.goback != null) {
@ -1226,6 +1227,7 @@ app.get('/editor', (req, res) => { // define a handler for editing document
userImage: user.avatar ? `${req.DocManager.getServerUrl()}/images/${user.id}.png` : null,
name,
userGroup,
userRoles,
reviewGroups: JSON.stringify(reviewGroups),
commentGroups: JSON.stringify(commentGroups),
userInfoGroups: JSON.stringify(userInfoGroups),

View File

@ -1,5 +1,5 @@
{
"version": "1.13.0",
"version": "1.14.1",
"log": {
"appenders": [
{
@ -20,7 +20,7 @@
"commandUrl": "command",
"converterUrl": "converter",
"apiUrl": "web-apps/apps/api/documents/api.js",
"preloaderUrl": "web-apps/apps/api/documents/cache-scripts.html",
"preloaderUrl": "web-apps/apps/api/documents/preload.html",
"exampleUrl": null,
"storageFolder": "./files",
"storagePath": "/files",
@ -83,6 +83,7 @@
"sv": "Swedish",
"tr": "Turkish",
"uk": "Ukrainian",
"ur": "Urdu",
"vi": "Vietnamese",
"aa-AA": "Test Language"
}

View File

@ -1,8 +1,6 @@
{
"server": {
"port": 3000,
"siteUrl": "http://127.0.0.1:8000/",
"apiUrl": "web-apps/apps/api/documents/api.js",
"preloaderUrl": "web-apps/apps/api/documents/cache-scripts.html"
"siteUrl": "http://127.0.0.1:8000/"
}
}

View File

@ -1,8 +1,6 @@
{
"server": {
"port": 3000,
"siteUrl": "http://127.0.0.1:8000/",
"apiUrl": "web-apps/apps/api/documents/api.js",
"preloaderUrl": "web-apps/apps/api/documents/cache-scripts.html"
"siteUrl": "http://127.0.0.1:8000/"
}
}

View File

@ -1,8 +1,6 @@
{
"server": {
"port": 80,
"siteUrl": "http://127.0.0.1:8000/",
"apiUrl": "web-apps/apps/api/documents/api.js",
"preloaderUrl": "web-apps/apps/api/documents/cache-scripts.html"
"siteUrl": "http://127.0.0.1:8000/"
}
}

View File

@ -533,7 +533,8 @@ DocManager.prototype.getHistory = function getHistory(fileName, content, keyVers
let createdFromJson = null;
if (fileContent) { // if content is defined
if (fileContent.changes && fileContent.changes.length) { // and there are some modifications in the content
[contentJson] = fileContent.changes; // write these modifications to the json content
// write these modifications to the json content
contentJson = fileContent.changes[fileContent.changes.length - 1];
} else if (fileContent.length) {
[contentJson] = fileContent; // otherwise, write original content to the json content
oldVersion = true; // and note that this is an old version

View File

@ -60,12 +60,13 @@ documentService.getConvertedUri = function getConvertedUri(
callback,
filePass = null,
lang = null,
filename = null,
) {
// get the current document extension
const fromExt = fromExtension || fileUtility.getFileExtension(documentUri, false, true);
// get the current document name or uuid
const title = fileUtility.getFileNameFromUrl(documentUri) || guidManager.newGuid();
const title = filename || fileUtility.getFileNameFromUrl(documentUri) || guidManager.newGuid();
// generate the document key value
const revisionId = documentService.generateRevisionId(documentRevisionId || documentUri);

View File

@ -32,6 +32,8 @@ class User {
avatar,
goback,
close,
canSubmitForm,
roles,
) {
this.id = id;
this.name = name;
@ -47,6 +49,8 @@ class User {
this.avatar = avatar;
this.goback = goback;
this.close = close;
this.canSubmitForm = canSubmitForm;
this.roles = roles;
}
}
@ -60,6 +64,8 @@ const descrUser1 = [
'Can see the information about all users',
'Can submit forms',
'Has an avatar',
'Has no roles',
'Can start filling',
];
const descrUser2 = [
@ -69,8 +75,10 @@ const descrUser2 = [
'This file is marked as favorite',
'Can create new files from the editor',
'Can see the information about users from Group2 and users who dont belong to any group',
'Cant submit forms',
'Can submit forms',
'Has an avatar',
'Has role "Anyone"',
'Can start filling',
];
const descrUser3 = [
@ -86,6 +94,8 @@ const descrUser3 = [
'Cant submit forms',
'Cant close history',
'Cant restore the file version',
'Has role "role"',
'Can start filling',
];
const descrUser0 = [
@ -103,6 +113,8 @@ const descrUser0 = [
'View file without collaboration',
'Cant submit forms',
'Cant refresh outdated file',
'Has empty role',
'Cant start filling',
];
const users = [
@ -121,6 +133,8 @@ const users = [
true,
{ blank: false },
{ visible: false },
true,
null,
),
new User(
'uid-2',
@ -141,6 +155,8 @@ const users = [
true,
{ text: 'Go to Documents' },
{},
true,
['Anyone'],
),
new User(
'uid-3',
@ -161,8 +177,10 @@ const users = [
false,
null,
{},
false,
['role'],
),
new User('uid-0', null, null, null, null, {}, [], null, ['protect'], descrUser0, false, false, null, null),
new User('uid-0', null, null, null, null, {}, [], null, ['protect'], descrUser0, false, false, null, null, false, []),
];
// get a list of all the users

View File

@ -57,6 +57,10 @@ const requestHeaders = Object.freeze({
LockFailureReason: 'X-WOPI-LockFailureReason',
LockedByOtherInterface: 'X-WOPI-LockedByOtherInterface',
Proof: 'X-WOPI-Proof',
ProofOld: 'X-WOPI-ProofOld',
Timestamp: 'X-WOPI-Timestamp',
FileConversion: 'X-WOPI-FileConversion',
FileName: 'X-WOPI-RequestedName',

View File

@ -16,4 +16,45 @@
*
*/
exports.isValidToken = (req, res, next) => next();
const wopiValidator = require('@mercadoeletronico/wopi-proof-validator');
const DocManager = require('../docManager');
const reqConsts = require('./request');
const utils = require('./utils');
exports.isValidToken = async (req, res, next) => {
try {
req.DocManager = new DocManager(req, res);
const proofKey = await utils.getProofKey(req.DocManager);
if (!proofKey) {
next();
return;
}
const isValid = wopiValidator.check(
{
url: `${req.DocManager.getServerPath()}${req.originalUrl || req.url}`,
accessToken: req.query.access_token,
timestamp: req.headers[reqConsts.requestHeaders.Timestamp.toLowerCase()],
},
{
proof: req.headers[reqConsts.requestHeaders.Proof.toLowerCase()],
proofold: req.headers[reqConsts.requestHeaders.ProofOld.toLowerCase()],
},
{
modulus: proofKey.modulus,
exponent: proofKey.exponent,
oldmodulus: proofKey.oldmodulus,
oldexponent: proofKey.oldexponent,
},
);
if (isValid) {
next();
} else {
console.warn('Proof key verification failed');
res.status(500).send('Not verified');
}
} catch (error) {
console.error(error);
res.status(500).send(`Verification error: ${error.message}`);
}
};

View File

@ -37,6 +37,7 @@ const requestDiscovery = async function requestDiscovery(DocManager) {
return new Promise((resolve, reject) => {
const uri = absSiteUrl + configServer.get('wopi.discovery');
const actions = [];
let proofKey = null;
// parse url to allow request by relative url after
// https://github.com/node-modules/urllib/pull/321/commits/514de1924bf17a38a6c2db2a22a6bc3494c0a959
@ -77,33 +78,47 @@ const requestDiscovery = async function requestDiscovery(DocManager) {
});
});
});
proofKey = discovery['wopi-discovery']['proof-key'];
}
}
resolve(actions);
resolve({ actions, proofKey });
},
);
});
};
// get the wopi discovery information
const getDiscoveryInfo = async function getDiscoveryInfo(DocManager) {
let actions = [];
const getDiscovery = async function getDiscovery(DocManager) {
let discovery = {};
if (cache) return cache;
try {
actions = await requestDiscovery(DocManager);
discovery = await requestDiscovery(DocManager);
} catch (e) {
return actions;
return discovery;
}
cache = actions;
cache = discovery;
setTimeout(() => {
cache = null;
return cache;
}, 1000 * 60 * 60); // 1 hour
return actions;
return discovery;
};
// get the wopi discovery actions information
const getDiscoveryInfo = async function getDiscoveryInfo(DocManager) {
const discovery = await getDiscovery(DocManager);
return discovery.actions;
};
// get the wopi discovery proof key
const getProofKey = async function getProofKey(DocManager) {
const discovery = await getDiscovery(DocManager);
return discovery.proofKey;
};
// get actions of the specified extension
@ -150,7 +165,7 @@ const getDefaultAction = async function getDefaultAction(DocManager, ext) {
// get the action url
const getActionUrl = function getActionUrl(host, userAddress, action, filename) {
const WOPISrc = `${host}/wopi/files/${filename}@${userAddress}`;
const WOPISrc = `${host}/wopi/files/${encodeURIComponent(filename)}@${encodeURIComponent(userAddress)}`;
return `${action.urlsrc.replace(/<.*&>/g, '')}WOPISrc=${encodeURIComponent(WOPISrc)}`;
};
@ -176,5 +191,6 @@ exports.getEditNewText = getEditNewText;
exports.getDiscoveryInfo = getDiscoveryInfo;
exports.getAction = getAction;
exports.getActions = getActions;
exports.getProofKey = getProofKey;
exports.getActionUrl = getActionUrl;
exports.getDefaultAction = getDefaultAction;

View File

@ -32,7 +32,7 @@ const getCustomWopiParams = function getCustomWopiParams(query) {
let actionParams = '';
const { userid } = query; // user id
tokenParams += (userid ? `&userid=${userid}` : '');
tokenParams += (userid ? `-userid=${userid}` : '');
const { lang } = query; // language
actionParams += (lang ? `&ui=${lang}` : '');

View File

@ -9,6 +9,7 @@
"version": "1.6.0",
"license": "Apache",
"dependencies": {
"@mercadoeletronico/wopi-proof-validator": "^1.0.2",
"body-parser": "^1.20.3",
"config": "^3.3.12",
"debug": "^4.3.4",
@ -132,6 +133,18 @@
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
"dev": true
},
"node_modules/@mercadoeletronico/wopi-proof-validator": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@mercadoeletronico/wopi-proof-validator/-/wopi-proof-validator-1.0.2.tgz",
"integrity": "sha512-ywaC2b/wBWhVSC1E8E2E5KgFg+irsr/WtgkgeiopxNbV56OZdLupaVd7aT/lOb1vppJ55TG+w4kaPFVh1tLn9A==",
"license": "Apache-2.0",
"dependencies": {
"cross-env": "^6.0.3",
"debug": "^4.1.1",
"int64-buffer": "^0.99.1007",
"rsa-pem-from-mod-exp": "^0.8.4"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -619,11 +632,26 @@
"resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz",
"integrity": "sha512-3DdaFaU/Zf1AnpLiFDeNCD4TOWe3Zl2RZaTzUvWiIk5ERzcCodOE20Vqq4fzCbNoHURFHT4/us/Lfq+S2zyY4w=="
},
"node_modules/cross-env": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-6.0.3.tgz",
"integrity": "sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag==",
"license": "MIT",
"dependencies": {
"cross-spawn": "^7.0.0"
},
"bin": {
"cross-env": "src/bin/cross-env.js",
"cross-env-shell": "src/bin/cross-env-shell.js"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@ -1860,6 +1888,15 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/int64-buffer": {
"version": "0.99.1007",
"resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.99.1007.tgz",
"integrity": "sha512-XDBEu44oSTqlvCSiOZ/0FoUkpWu/vwjJLGSKDabNISPQNZ5wub1FodGHBljRsrR0IXRPq7SslshZYMuA55CgTQ==",
"license": "MIT",
"engines": {
"node": ">= 4.5.0"
}
},
"node_modules/internal-slot": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
@ -2124,8 +2161,7 @@
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
},
"node_modules/jake": {
"version": "10.8.7",
@ -2706,7 +2742,6 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -2906,6 +2941,12 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rsa-pem-from-mod-exp": {
"version": "0.8.6",
"resolved": "https://registry.npmjs.org/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.6.tgz",
"integrity": "sha512-c5ouQkOvGHF1qomUUDJGFcXsomeSO2gbEs6hVhMAtlkE1CuaZase/WzoaKFG/EZQuNmq6pw/EMCeEnDvOgCJYQ==",
"license": "MIT"
},
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@ -3123,7 +3164,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"dependencies": {
"shebang-regex": "^3.0.0"
},
@ -3135,7 +3175,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -3585,7 +3624,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"dependencies": {
"isexe": "^2.0.0"
},
@ -3733,6 +3771,17 @@
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
"dev": true
},
"@mercadoeletronico/wopi-proof-validator": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@mercadoeletronico/wopi-proof-validator/-/wopi-proof-validator-1.0.2.tgz",
"integrity": "sha512-ywaC2b/wBWhVSC1E8E2E5KgFg+irsr/WtgkgeiopxNbV56OZdLupaVd7aT/lOb1vppJ55TG+w4kaPFVh1tLn9A==",
"requires": {
"cross-env": "^6.0.3",
"debug": "^4.1.1",
"int64-buffer": "^0.99.1007",
"rsa-pem-from-mod-exp": "^0.8.4"
}
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -4091,11 +4140,18 @@
"resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz",
"integrity": "sha512-3DdaFaU/Zf1AnpLiFDeNCD4TOWe3Zl2RZaTzUvWiIk5ERzcCodOE20Vqq4fzCbNoHURFHT4/us/Lfq+S2zyY4w=="
},
"cross-env": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-6.0.3.tgz",
"integrity": "sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag==",
"requires": {
"cross-spawn": "^7.0.0"
}
},
"cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@ -5033,6 +5089,11 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"int64-buffer": {
"version": "0.99.1007",
"resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.99.1007.tgz",
"integrity": "sha512-XDBEu44oSTqlvCSiOZ/0FoUkpWu/vwjJLGSKDabNISPQNZ5wub1FodGHBljRsrR0IXRPq7SslshZYMuA55CgTQ=="
},
"internal-slot": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
@ -5207,8 +5268,7 @@
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
},
"jake": {
"version": "10.8.7",
@ -5646,8 +5706,7 @@
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
},
"path-parse": {
"version": "1.0.7",
@ -5780,6 +5839,11 @@
"glob": "^7.1.3"
}
},
"rsa-pem-from-mod-exp": {
"version": "0.8.6",
"resolved": "https://registry.npmjs.org/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.6.tgz",
"integrity": "sha512-c5ouQkOvGHF1qomUUDJGFcXsomeSO2gbEs6hVhMAtlkE1CuaZase/WzoaKFG/EZQuNmq6pw/EMCeEnDvOgCJYQ=="
},
"run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@ -5947,7 +6011,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"requires": {
"shebang-regex": "^3.0.0"
}
@ -5955,8 +6018,7 @@
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
},
"side-channel": {
"version": "1.0.4",
@ -6284,7 +6346,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}

View File

@ -14,6 +14,7 @@
"url": "https://github.com/ONLYOFFICE/document-server-integration/issues"
},
"dependencies": {
"@mercadoeletronico/wopi-proof-validator": "^1.0.2",
"body-parser": "^1.20.3",
"config": "^3.3.12",
"debug": "^4.3.4",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -19,7 +19,7 @@
var language;
var userid;
var directUrl;
var formatManager;
var formatManager = new FormatManager();
window.onload = function () {
fetch('formats')
@ -38,7 +38,12 @@ window.onload = function () {
});
formatManager = new FormatManager(formats);
}
})
});
var urlScripts = jq("#loadScripts").attr("data-docs");
var frame = '<iframe id="iframeScripts" width=1 height=1 style="position: absolute; visibility: hidden;" ></iframe>';
jq("#loadScripts").html(frame);
jq("#loadScripts iframe").attr("src", urlScripts);
}
if (typeof jQuery != "undefined") {
@ -139,7 +144,7 @@ if (typeof jQuery != "undefined") {
if (!formatManager.isAutoConvertible(posExt)) {
jq("#step2").addClass("done").removeClass("current");
loadScripts();
onuploaded();
return;
}
@ -199,35 +204,14 @@ if (typeof jQuery != "undefined") {
checkConvert(filePass, fileType);
} else {
jq("#step2").addClass("done").removeClass("current");
loadScripts();
onuploaded();
}
}
});
}, 1000);
};
var loadScripts = function () {
if (!jq("#mainProgress").is(":visible")) {
return;
}
jq("#step3").addClass("current");
if (jq("#loadScripts").is(":empty")) {
var urlScripts = jq("#loadScripts").attr("data-docs");
var frame = '<iframe id="iframeScripts" width=1 height=1 style="position: absolute; visibility: hidden;" ></iframe>';
jq("#loadScripts").html(frame);
document.getElementById("iframeScripts").onload = onloadScripts;
jq("#loadScripts iframe").attr("src", urlScripts);
} else {
onloadScripts();
}
};
var onloadScripts = function () {
if (!jq("#mainProgress").is(":visible")) {
return;
}
jq("#step3").addClass("done").removeClass("current");
var onuploaded = function () {
jq("#beginView, #beginEmbedded").removeClass("disable");
var fileName = jq("#hiddenFileName").val();
@ -276,7 +260,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#skipPass", function () {
jq("#blockPassword").hide();
loadScripts();
onuploaded();
});
jq(document).on("click", "#beginEdit:not(.disable)", function () {
@ -454,14 +438,12 @@ if (typeof jQuery != "undefined") {
jq("#convertStep2").removeClass("current").addClass("done");
jq("#convertStep2").text(`2. File conversion to ${fileExt}`);
jq("#downloadConverted").removeClass("disable");
jq("#hiddenFileName").attr("data",response.filename);
if (response.error !== "FileTypeIsNotSupported") {
jq("#hiddenFileName").attr("data",response.filename);
jq("#beginEditConverted").removeClass("disable");
jq("#beginViewConverted").removeClass("disable");
jq("#downloadConverted").attr("data","fromStorage");
} else {
let newFilename = fileName.split('.').slice(0,-1).join('.')
jq("#hiddenFileName").attr("data",response.filename.split("&filename=download").join(`&filename=${newFilename}`));
jq("#downloadConverted").attr("data","fromConverter");
}
jq("td[name='convertingTypeButton']").removeClass("disable orange");

View File

@ -146,7 +146,7 @@ header a {
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
.center, .table-main {
width: 100%;
}

View File

@ -679,7 +679,7 @@
}
}
@media (max-width: 420px) and (min-width: 320px) {
@media (max-width: 420px) {
.tableRow,
.storedHeader,
menu.links {
@ -760,7 +760,7 @@
max-width: 45%;
}
}
@media (max-width: 600px) and (min-width: 320px) {
@media (max-width: 600px) {
.main-panel {
display: flex;
flex-direction: column;
@ -776,7 +776,7 @@
max-width:20%;
}
}
@media (max-width:400px) and (min-width:320px){
@media (max-width:400px) {
.main-panel > span{
max-width:15%;
}
@ -787,7 +787,7 @@
}
}
@media (max-width: 592px) and (min-width: 320px) {
@media (max-width: 592px) {
body.menu-open {
overflow: hidden;
}

View File

@ -60,7 +60,8 @@
"group": "<%- editor.userGroup %>",
"id": "<%- editor.userid %>",
"image": "<%- editor.userImage %>",
"name": "<%- editor.name %>"
"name": "<%- editor.name %>",
"roles": <%- JSON.stringify(editor.userRoles) %>
}
},
"height": "100%",

View File

@ -225,10 +225,33 @@
users = <%- JSON.stringify(usersForMentions) %>;
}
docEditor.setUsers({
if ((c === "protect" || c === "mention") && users && event.data.count) {
let from = event.data.from;
let count = event.data.count;
let search = event.data.search;
if (from != 0) users = [];
var resultCount = 234;
for (var i = Math.max(users.length, from); i < Math.min(from + count, resultCount); i++){
users.push({
email: "test@test.test" + (i + 1),
id: "id" + (i + 1),
name: "test_" + search + (i + 1)
});
}
}
var result = {
"c": c,
"users": users,
});
};
if (resultCount) {
// support v9.0
result.total = 1 + (!event.data.count || users.length < event.data.count ? 0 : (event.data.from + event.data.count));
// since v9.0.1
result.isPaginated = true;
}
docEditor.setUsers(result);
};
var onRequestSendNotify = function(event) { // the user is mentioned in a comment
@ -368,6 +391,18 @@
};
};
var onRequestStartFilling = function(event) {
var data = event.data;
var submit = confirm("Start filling?\n" + JSON.stringify(data));
if (submit) {
docEditor.startFilling(true);
}
};
var onStartFilling = function(event) {
innerAlert("The form is ready to fill out.");
};
var onDocumentReady = function(){
fixSize();
};
@ -402,6 +437,8 @@
config.events.onRequestReferenceData = onRequestReferenceData;
config.events.onRequestReferenceSource = onRequestReferenceSource;
config.events.onRequestRefreshFile = onRequestRefreshFile;
config.events.onRequestStartFilling = onRequestStartFilling;
config.events.onStartFilling = onStartFilling;
if (<%- JSON.stringify(editor.userid) %> != "uid-3") {
config.events.onRequestHistoryClose = onRequestHistoryClose;
config.events.onRequestRestore = onRequestRestore;

View File

@ -322,10 +322,7 @@
<span class="errorPass"></span>
<br />
</div>
<span id="step3" class="step">3. Loading editor scripts.</span>
<span class="step-descr">They are loaded only once, they will be cached on your computer.</span>
<input type="hidden" name="hiddenFileName" id="hiddenFileName" />
<br />
<span class="progress-descr">Note the speed of all operations depends on your connection quality and server location.</span>
<br />
<div class="error-message">

View File

@ -235,11 +235,7 @@
<span class="errorPass"></span>
<br />
</div>
<span id="step3" class="step">3. Loading editor scripts.</span>
<span class="step-descr">They are loaded only once, they will be cached on your computer.</span>
<input type="hidden" name="hiddenFileName" id="hiddenFileName" />
<br />
<br />
<span class="progress-descr">Note the speed of all operations depends on your connection quality and server location.</span>
<br />
<br />

View File

@ -16,7 +16,7 @@ DOCUMENT_STORAGE_DISPLAY_FORGOTTEN_PAGE=false
## DOCUMENT SERVER ENV VARIABLES
DOCUMENT_SERVER_VERSION=1.13.0
DOCUMENT_SERVER_VERSION=1.14.0
DOCUMENT_SERVER_PUBLIC_URL=http://localhost:8080
DOCUMENT_SERVER_PRIVATE_URL=http://proxy:8080
@ -24,12 +24,13 @@ DOCUMENT_SERVER_PRIVATE_URL=http://proxy:8080
DOCUMENT_SERVER_API_PATH=web-apps/apps/api/documents/api.js
DOCUMENT_SERVER_COMMAND_PATH=command
DOCUMENT_SERVER_CONVERTER_PATH=converter
DOCUMENT_SERVER_PRELOADER_PATH=web-apps/apps/api/documents/cache-scripts.html
DOCUMENT_SERVER_PRELOADER_PATH=web-apps/apps/api/documents/preload.html
DOCUMENT_SERVER_JWT_HEADER=Authorization
DOCUMENT_SERVER_JWT_ALGORITHM=HS256
DOCUMENT_SERVER_JWT_USE_FOR_REQUEST=true
DOCUMENT_SERVER_JWT_SECRET=secret
DOCUMENT_SERVER_JWT_EXPIRATION=5
DOCUMENT_SERVER_CONVERSION_TIMEOUT=120000

View File

@ -90,11 +90,11 @@ class ReferenceController extends Controller
'instanceId' => $storagePublicUrl,
],
'path' => $filename,
'link' => "$storagePublicUrl/editor?fileID=$filename",
'link' => $request->getScheme().'://'.$request->getHost().'/editor?fileID='.$filename,
];
if ($settings->getSetting('jwt.enabled')) {
$data['token'] = $jwt->encode($data, $settings->getSetting('jwt.secret'));
$data['token'] = $jwt->jwtEncode($data, $settings->getSetting('jwt.secret'), $settings->getSetting('jwt.expiration'));
}
return response()->json($data);

View File

@ -220,13 +220,13 @@ class EditorController extends Controller
// check if the secret key to generate token exists
if ($this->settings->getSetting('jwt.enabled')) {
// encode config into the token
$config['token'] = $jwt->encode($config, $this->settings->getSetting('jwt.secret'));
$config['token'] = $jwt->jwtEncode($config, $this->settings->getSetting('jwt.secret'), $this->settings->getSetting('jwt.expiration'));
// encode the dataInsertImage object into the token
$dataInsertImage['token'] = $jwt->encode($dataInsertImage, $this->settings->getSetting('jwt.secret'));
$dataInsertImage['token'] = $jwt->jwtEncode($dataInsertImage, $this->settings->getSetting('jwt.secret'), $this->settings->getSetting('jwt.expiration'));
// encode the dataDocument object into the token
$dataDocument['token'] = $jwt->encode($dataDocument, $this->settings->getSetting('jwt.secret'));
$dataDocument['token'] = $jwt->jwtEncode($dataDocument, $this->settings->getSetting('jwt.secret'), $this->settings->getSetting('jwt.expiration'));
// encode the dataSpreadsheet object into the token
$dataSpreadsheet['token'] = $jwt->encode($dataSpreadsheet, $this->settings->getSetting('jwt.secret'));
$dataSpreadsheet['token'] = $jwt->jwtEncode($dataSpreadsheet, $this->settings->getSetting('jwt.secret'), $this->settings->getSetting('jwt.expiration'));
}
$historyLayout = '';

View File

@ -360,7 +360,7 @@ class FileController extends Controller
];
if ($this->settings->getSetting('jwt.enabled')) {
$config['token'] = $jwt->encode($config, $this->settings->getSetting('jwt.secret'));
$config['token'] = $jwt->jwtEncode($config, $this->settings->getSetting('jwt.secret'), $this->settings->getSetting('jwt.expiration'));
}
return response()

View File

@ -1,7 +1,7 @@
<?php
/**
* (c) Copyright Ascensio System SIA 2024
* (c) Copyright Ascensio System SIA 2025
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,7 +1,7 @@
<?php
/**
* (c) Copyright Ascensio System SIA 2024
* (c) Copyright Ascensio System SIA 2025
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -32,10 +32,11 @@ class SettingsManager extends OnlyOfficeSettingsManager
$publicServerUrl = rtrim(env('DOCUMENT_SERVER_PUBLIC_URL', 'http://documentserver'), '/');
$privateServerUrl = rtrim(env('DOCUMENT_SERVER_PRIVATE_URL', $publicServerUrl), '/');
$apiUrl = $publicServerUrl.'/'.env('DOCUMENT_SERVER_API_PATH', 'web-apps/apps/api/documents/api.js');
$preloaderUrl = $publicServerUrl.'/'.env('DOCUMENT_SERVER_PRELOADER_PATH', 'web-apps/apps/api/documents/cache-scripts.html');
$preloaderUrl = $publicServerUrl.'/'.env('DOCUMENT_SERVER_PRELOADER_PATH', 'web-apps/apps/api/documents/preload.html');
$conversionUrl = $privateServerUrl.'/'.env('DOCUMENT_SERVER_CONVERTER_PATH', 'convert');
$commandUrl = $privateServerUrl.'/'.env('DOCUMENT_SERVER_COMMAND_PATH', 'command');
$jwtSecret = env('DOCUMENT_SERVER_JWT_SECRET', 'secret');
$jwtExpiration = env('DOCUMENT_SERVER_JWT_EXPIRATION', 5);
$jwtUseForRequest = env('DOCUMENT_SERVER_JWT_USE_FOR_REQUEST', true);
$publicStorageUrl = rtrim(env('DOCUMENT_STORAGE_PUBLIC_URL', request()->schemeAndHttpHost()), '/');
$privateStorageUrl = rtrim(env('DOCUMENT_STORAGE_PRIVATE_URL', $publicStorageUrl), '/');
@ -54,6 +55,7 @@ class SettingsManager extends OnlyOfficeSettingsManager
'jwt' => [
'enabled' => $jwtSecret && $jwtUseForRequest,
'secret' => $jwtSecret,
'expiration' => $jwtExpiration,
'header' => env('DOCUMENT_SERVER_JWT_HEADER', 'Authorization'),
'use_for_request' => $jwtUseForRequest,
'algorithm' => env('DOCUMENT_SERVER_JWT_ALGORITHM', 'HS256'),

View File

@ -1,7 +1,7 @@
<?php
/**
* (c) Copyright Ascensio System SIA 2024
* (c) Copyright Ascensio System SIA 2025
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -35,6 +35,7 @@ class ConvertRequest
$data['key'],
false,
$data['lang'],
$data['filename'],
);
if (property_exists($result, 'Error')) {

View File

@ -1,7 +1,7 @@
<?php
//
// (c) Copyright Ascensio System SIA 2024
// (c) Copyright Ascensio System SIA 2025
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.

View File

@ -1,7 +1,7 @@
<?php
/**
* (c) Copyright Ascensio System SIA 2024.
* (c) Copyright Ascensio System SIA 2025.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,7 +1,7 @@
<?php
/**
* (c) Copyright Ascensio System SIA 2024.
* (c) Copyright Ascensio System SIA 2025.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -64,6 +64,7 @@ class LanguageRepository
'sv' => 'Swedish',
'tr' => 'Turkish',
'uk' => 'Ukrainian',
'ur' => 'Urdu',
'vi' => 'Vietnamese',
'aa-AA' => 'Test Language',
];

Some files were not shown because too many files have changed in this diff Show More