Compare commits

..

63 Commits

Author SHA1 Message Date
d790c2954f Merge remote-tracking branch 'remotes/origin/release/v7.5.0' into develop 2023-10-09 13:37:45 +03:00
5645c24b63 Merge pull request #461 from ONLYOFFICE/feature/referenceData-key
Feature/reference data key
2023-10-09 12:35:57 +03:00
1f6178c68a csharp: added key in referenceData 2023-10-09 15:50:52 +07:00
86ad08d2ca csharp-mvc: added key in referenceData 2023-10-09 15:29:17 +07:00
d65633427f java: added key in referenceData 2023-10-09 15:16:19 +07:00
61398f93f1 java-spring: added key in referenceData 2023-10-09 15:00:05 +07:00
a5cc51b1cd changelog update 2023-10-09 14:39:37 +07:00
178c8e3b56 php: added key in referenceData 2023-10-09 14:38:29 +07:00
aa5bb183e3 python: added key in referenceData 2023-10-09 14:30:21 +07:00
bc6fd8f796 ruby: added key in referenceData 2023-10-09 14:25:02 +07:00
e49372123b update icons 2023-09-29 14:23:44 +03:00
2bf4187fd4 Merge remote-tracking branch 'remotes/origin/release/v7.5.0' into develop 2023-09-29 14:20:53 +03:00
f5b91299ba Merge pull request #459 from ONLYOFFICE/hotfix/update-packages
ruby: update rails to 7.0.8
2023-09-28 14:47:47 +03:00
c274923072 ruby: update nokogiri to 1.14.3 2023-09-28 14:39:58 +03:00
6eafce5462 ruby: update rails to 7.0.8 2023-09-28 10:55:26 +03:00
7eddfa4703 Merge remote-tracking branch 'remotes/origin/release/v7.5.0' into develop 2023-09-25 12:48:01 +03:00
c19d561c1c Merge pull request #458 from ONLYOFFICE/fix/archive-names
Fixed archive names
2023-09-21 10:01:16 +03:00
01e9dcf1a8 fixed the sample archive names 2023-09-20 17:58:00 +03:00
2e36067513 Merge pull request #456 from ONLYOFFICE/feature/java-matrix-formats
Feature/java matrix formats
2023-09-14 12:41:53 +03:00
84c6f4c726 java: 3rd-Party.license 2023-09-14 12:40:00 +03:00
df5f311949 Merge remote-tracking branch 'remotes/origin/develop' into feature/java-matrix-formats
# Conflicts:
#	.gitmodules
#	CHANGELOG.md
2023-09-14 12:37:01 +03:00
95b357a53b Merge pull request #457 from ONLYOFFICE/feature/java-spring-matrix-formats
Feature/java spring matrix formats
2023-09-14 12:34:43 +03:00
b75074ba2f java: matrix-format to changelog 2023-09-13 15:28:09 +03:00
d39ad1c677 java-spring: matrix-format to changelog 2023-09-13 15:27:05 +03:00
64a63f2c35 java-spring: changed getFileExtension return without dot 2023-09-13 15:23:02 +03:00
00c7194ef4 java-spring: replace format properties on formats matrix 2023-09-13 15:22:56 +03:00
bbdd0878e9 java-spring: added Format.java, FormatService.java 2023-09-13 15:22:48 +03:00
fb8f47062c java-spring: added submodule document-formats 2023-09-13 15:22:04 +03:00
5a63bd47c1 java: changed getFileExtension return without dot 2023-09-13 11:27:06 +03:00
5e2f812fee java: refactoring Format.java, FormatManager.java, FileType.java 2023-09-13 11:24:51 +03:00
0f3bb28d92 java: added lombok dependency 2023-09-13 11:17:43 +03:00
cb21d73641 format to changelog 2023-09-12 21:37:27 +03:00
89912eac76 Merge pull request #439 from ONLYOFFICE/feature/java-matrix-formats
java: add support for formats
2023-09-12 21:36:35 +03:00
c20687e241 java: added submodule document-formats 2023-09-12 17:34:46 +03:00
5f3b0c61eb java: delete submodule document-formats 2023-09-12 17:33:52 +03:00
45051d2c29 java: fixed FormatManager 2023-09-12 17:24:29 +03:00
940ea2797e Merge branch 'develop' into feature/java-matrix-formats
# Conflicts:
#	.gitmodules
2023-09-12 16:39:32 +03:00
ef53346f16 nodejs: fix lint (6315ccbf45) 2023-09-11 22:34:11 +03:00
3415c1ec4f Merge pull request #455 from ONLYOFFICE/feature/config-paths
Paths to the config files
2023-09-11 22:26:20 +03:00
33600df8a9 added paths to the config files 2023-09-11 18:57:19 +03:00
6315ccbf45 Merge remote-tracking branch 'remotes/origin/feature/referenceData-link' into develop 2023-09-07 11:18:14 +03:00
969a8c6cfe nodejs: link in referenceData 2023-09-07 11:05:57 +03:00
f4dd6d665f Merge pull request #454 from ONLYOFFICE/refactoring/java-spring-dto
Refactoring/java spring dto
2023-09-07 10:54:10 +03:00
427d13af24 Merge pull request #453 from ONLYOFFICE/feature/java-example-docker
Java instructions for Docker
2023-09-07 10:28:06 +03:00
6bdadd6053 Merge remote-tracking branch 'remotes/origin/develop' into refactoring/java-spring-dto 2023-09-07 10:26:03 +03:00
95579f2376 java-spring: added dto/SaveAs.java 2023-09-07 10:25:30 +03:00
8c518fd109 java-spring: added dto/Rename.java 2023-09-07 10:24:53 +03:00
aa245e2aae java-spring: added dto/Reference.java and dto/ReferenceData.java 2023-09-07 10:24:18 +03:00
6511507093 java-spring: added dto/Restore.java 2023-09-07 10:23:34 +03:00
8f14876b81 java and java spring: updated Docker instructions 2023-09-06 15:55:07 +03:00
09f24a3b87 fix changelog 2023-09-05 14:42:58 +03:00
14b014cb7f Merge pull request #452 from ONLYOFFICE/feature/java-spring-refactoring-history
Feature/java spring refactoring history
2023-09-05 14:39:41 +03:00
2d83d3ec87 Merge pull request #451 from ONLYOFFICE/feature/java-refactoring-history
Feature/java refactoring history
2023-09-05 14:39:14 +03:00
05904fd68a java: link to Oracle 2023-09-05 13:57:13 +03:00
a56b411c93 java-spring: changed restore version without reload page 2023-09-04 15:32:15 +03:00
bc5393e28c java-spring: added api (history, historyData) for getting history 2023-09-04 15:29:23 +03:00
a3fa30b192 fixed: directUrl for historyData 2023-09-04 15:19:34 +03:00
24b9a35651 java: changed restore version without reload page 2023-09-04 13:11:20 +03:00
52a722cf89 java: added api (history, historyData) for getting history 2023-09-04 13:10:54 +03:00
4fa9d4c9fd nodejs: remove /files route (8bcc15e320) 2023-09-02 11:18:34 +03:00
fb16b88dd1 java: replace the previous implementation of formats 2023-08-16 15:21:33 +04:00
d259cf3ff7 java: add format module 2023-08-16 15:21:33 +04:00
558c7892d3 java: add document-formats submodule 2023-08-16 15:21:33 +04:00
118 changed files with 1942 additions and 1135 deletions

View File

@ -21,9 +21,11 @@ jobs:
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/csharp-mvc
mkdir -p ./deploy/'DotNet (Csharp MVC) Example'
mkdir -p ./deploy/'DotNet (Csharp MVN) Example'
rsync -av --exclude='deploy' ./ ./deploy/'DotNet (Csharp MVC) Example'
rm -rf ./deploy/'DotNet (Csharp MVC) Example'/assets/.git
cd ./deploy/'DotNet (Csharp MVC) Example'/assets
rm -rf ./.git/
rm .git
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:

View File

@ -18,11 +18,14 @@ jobs:
- name: Build Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/csharp
mkdir -p ./deploy/'DotNet (Csharp) Example'
rsync -av --exclude='deploy' ./ ./deploy/'DotNet (Csharp) Example'
rm -rf ./deploy/'DotNet (Csharp) Example'/assets/.git
cd ./deploy/'DotNet (Csharp) Example'/assets
rm -rf ./.git/
rm .git
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:

View File

@ -18,12 +18,14 @@ jobs:
- name: Build Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/java
mkdir -p ./deploy/'Java Example'
rsync -av --exclude='deploy' ./ ./deploy/'Java Example'
rm -rf ./deploy/'Java Example'/src/main/resources/assets/document-formats/.git
rm -rf ./deploy/'Java Example'/src/main/resources/assets/document-templates/.git
cd ./deploy/'Java Example'/src/main/resources/assets
rm -rf ./.git/
rm .git
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:

View File

@ -18,12 +18,14 @@ jobs:
- name: Build Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/nodejs
mkdir -p ./deploy/'Node.js Example'
rsync -av --exclude='deploy' ./ ./deploy/'Node.js Example'
rm -rf ./deploy/'Node.js Example'/public/assets/document-formats/.git
rm -rf ./deploy/'Node.js Example'/public/assets/document-templates/.git
cd ./deploy/'Node.js Example'/public/assets
rm -rf ./.git/
rm .git
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:

View File

@ -18,12 +18,14 @@ jobs:
- name: Build Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/php
mkdir -p ./deploy/'PHP Example'
rsync -av --exclude='deploy' ./ ./deploy/'PHP Example'
rm -rf ./deploy/'PHP Example'/assets/document-formats/.git
rm -rf ./deploy/'PHP Example'/assets/document-templates/.git
cd ./deploy/'PHP Example'/assets
rm -rf ./.git/
rm .git
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:

View File

@ -18,12 +18,14 @@ jobs:
- name: Build Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/python
mkdir -p ./deploy/'Python Example'
rsync -av --exclude='deploy' ./ ./deploy/'Python Example'
rm -rf ./deploy/'Python Example'/assets/document-formats/.git
rm -rf ./deploy/'Python Example'/assets/document-templates/.git
cd ./deploy/'Python Example'/assets
rm -rf ./.git/
rm .git
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:

View File

@ -18,12 +18,14 @@ jobs:
- name: Build Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/ruby
mkdir -p ./deploy/'Ruby Example'
rsync -av --exclude='deploy' ./ ./deploy/'Ruby Example'
rm -rf ./deploy/'Ruby Example'/public/assets/document-formats/.git
rm -rf ./deploy/'Ruby Example'/public/assets/document-templates/.git
cd ./deploy/'Ruby Example'/public/assets
rm -rf ./.git/
rm .git
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:

View File

@ -23,8 +23,9 @@ jobs:
cd ./web/documentserver-example/java-spring
mkdir -p ./deploy/'Java Spring Example'
rsync -av --exclude='deploy' ./ ./deploy/'Java Spring Example'
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
cd ./deploy/'Java Spring Example'/src/main/resources/assets
rm -rf ./.git/
rm .git
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:

View File

@ -32,9 +32,9 @@ jobs:
- name: Lint Flake8
run: |
flake8 --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 --count --max-complexity=10 --max-line-length=79 --statistics
flake8 ./**/*.py --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 ./**/*.py --count --max-complexity=10 --max-line-length=79 --statistics
- name: Lint Pylint
run: |
find . -type f -name "*.py" | xargs pylint
pylint ./**/*.py

View File

@ -16,22 +16,16 @@ jobs:
run:
working-directory: ./web/documentserver-example/ruby
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2.2'
- name: Update Submodules
run: |
git submodule update --init --recursive
- name: Install Dependencies
run: |
bundle update
- name: Rubocop
run: |
bundle exec rubocop
- name: Checkout Repository
uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
bundler-cache: true
- name: Install dependencies
run: |
bundle install
- name: Rubocop
run: |
gem install rubocop
rubocop

View File

@ -13,10 +13,8 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Clone Submodules
run: |
cd ${{ github.workspace }}
git submodule update --init --recursive
- name: Install Zip
run: sudo apt-get install zip
- name: Get Info
run: |
echo "version=$(grep -Eo '[0-9]+(\.[0-9]+)+' CHANGELOG.md | head -n 1)" >> $GITHUB_OUTPUT
@ -27,66 +25,91 @@ jobs:
- name: Build Csharp MVC Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/csharp-mvc
mkdir -p ./'DotNet (Csharp MVC) Example'
rsync -av --exclude='DotNet (Csharp MVC) Example' ./ ./'DotNet (Csharp MVC) Example'
cd ./'DotNet (Csharp MVC) Example'/assets
rm -rf .git
rm -rf ./.git/
rm .git
- name: Build Csharp Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/csharp
mkdir -p ./'DotNet (Csharp) Example'
rsync -av --exclude='DotNet (Csharp) Example' ./ ./'DotNet (Csharp) Example'
rm -rf ./'DotNet (Csharp) Example'/assets/.git
cd ./'DotNet (Csharp) Example'/assets
rm -rf ./.git/
rm .git
- name: Build Java Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/java
mkdir -p ./'Java Example'
rsync -av --exclude='Java Example' ./ ./'Java Example'
rm -rf ./'Java Example'/src/main/resources/assets/document-formats/.git
rm -rf ./'Java Example'/src/main/resources/assets/document-templates/.git
cd ./'Java Example'/src/main/resources/assets
rm -rf ./.git/
rm .git
- name: Build Nodejs Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/nodejs
mkdir -p ./'Node.js Example'
rsync -av --exclude='Node.js Example' ./ ./'Node.js Example'
rm -rf ./'Node.js Example'/public/assets/document-formats/.git
rm -rf ./'Node.js Example'/public/assets/document-templates/.git
cd ./'Node.js Example'/public/assets
rm -rf ./.git/
rm .git
- name: Build PHP Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/php
mkdir -p ./'PHP Example'
rsync -av --exclude='PHP Example' ./ ./'PHP Example'
rm -rf ./'PHP Example'/assets/document-formats/.git
rm -rf ./'PHP Example'/assets/document-templates/.git
cd ./'PHP Example'/assets
rm -rf ./.git/
rm .git
- name: Build Python Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/python
mkdir -p ./'Python Example'
rsync -av --exclude='Python Example' ./ ./'Python Example'
rm -rf ./'Python Example'/assets/document-formats/.git
rm -rf ./'Python Example'/assets/document-templates/.git
cd ./'Python Example'/assets
rm -rf ./.git/
rm .git
- name: Build Ruby Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/ruby
mkdir -p ./'Ruby Example'
rsync -av --exclude='Ruby Example' ./ ./'Ruby Example'
rm -rf ./'Ruby Example'/public/assets/document-formats/.git
rm -rf ./'Ruby Example'/public/assets/document-templates/.git
cd ./'Ruby Example'/public/assets
rm -rf ./.git/
rm .git
- name: Build Spring Artifact
run: |
cd ${{ github.workspace }}
cwd=$(pwd)
git submodule update --init --recursive
cd ./web/documentserver-example/java-spring
mkdir -p ./'Java Spring Example'
rsync -av --exclude='Java Spring Example' ./ ./'Java Spring Example'
rm -rf ./'Java Spring Example'/src/main/resources/assets/document-formats/.git
rm -rf ./'Java Spring Example'/src/main/resources/assets/document-templates/.git
cd ./'Java Spring Example'/src/main/resources/assets
rm -rf ./.git/
rm .git
- name: Pack Artifacts
run: |
cd ${{ github.workspace }}/web/documentserver-example/csharp-mvc

8
.gitmodules vendored
View File

@ -46,3 +46,11 @@
path = web/documentserver-example/ruby/assets/document-formats
url = https://github.com/ONLYOFFICE/document-formats
branch = master
[submodule "web/documentserver-example/java/src/main/resources/assets/document-formats"]
path = web/documentserver-example/java/src/main/resources/assets/document-formats
url = https://github.com/ONLYOFFICE/document-formats
branch = master
[submodule "web/documentserver-example/java-spring/src/main/resources/assets/document-formats"]
path = web/documentserver-example/java-spring/src/main/resources/assets/document-formats
url = https://github.com/ONLYOFFICE/document-formats
branch = master

View File

@ -113,6 +113,10 @@ Prime JWT - is intended to be fast and easy to use. Prime JWT has a single e
License: Apache 2.0
License File: prime-jwt.license
Project Lombok - Spice up your java: Automatic Resource Management, automatic generation of getters, setters, equals, hashCode and toString, and more! (https://projectlombok.org/LICENSE)
License: MIT
License File: lombok.license
web/documentserver-example/java-spring

View File

@ -1,24 +1,33 @@
# Change Log
## 1.7.0
- csharp: key in referenceData
- csharp-mvc: key in referenceData
- java: key in referenceData
- java-spring: key in referenceData
- php: key in referenceData
- python: key in referenceData
- ruby: key in referenceData
- nodejs: link in referenceData
- nodejs: onRequestSelectDocument method
- nodejs: onRequestSelectSpreadsheet method
- nodejs: onRequestOpen
- nodejs: submitForm
- nodejs: key in referenceData
- nodejs: change reference source
- java-spring: using a repo with a list of formats
- java: using a repo with a list of formats
- php: using a repo with a list of formats
- nodejs: using a repo with a list of formats
- java: using a repo with a list of formats
- python: using a repo with a list of formats
- ruby: using a repo with a list of formats
- nodejs: delete file without reloading the page
- nodejs: getting history by a separate request
- nodejs: restore from history
- php: using a repo with a list of formats
- php: restore from history
- python: restore from history
- ruby: restore from history
- csharp-mvc: getting history by a separate request
- csharp-mvc: restore from history
- csharp: getting history by a separate request
- csharp: restore from history
- java: getting history by a separate request
- java-spring: getting history by a separate request
- restore from history
## 1.6.0
- nodejs: setUsers for region protection

View File

@ -11,8 +11,10 @@ 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`
* [.Net (C#)](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/csharp) - `web/documentserver-example/csharp/settings.config`
* [Java](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/java) - `web/documentserver-example/java/src/main/resources/settings.properties`
* [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/config.php`
* [PHP](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/php) - `web/documentserver-example/php/config.json`
* [Python](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/python) - `web/documentserver-example/python/config.py`
* [Ruby](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/ruby) - `web/documentserver-example/ruby/config/application.rb`
More information on how to use these examples can be found here: [http://api.onlyoffice.com/editors/demopreview](http://api.onlyoffice.com/editors/demopreview "http://api.onlyoffice.com/editors/demopreview")

View File

@ -1,8 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H21.674C22.4697 0 23.2327 0.316071 23.7953 0.87868L29.1213 6.20465C29.6839 6.76726 30 7.53032 30 8.32597V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#3779A6"/>
<path d="M22.9167 0L30.0001 7.08333H25.9167C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#1D5880"/>
<path d="M6.17627 14.7059H23.8233V15.8823H6.17627V14.7059Z" fill="white"/>
<path d="M6.17627 18.5294H23.8233V19.7059H6.17627V18.5294Z" fill="white"/>
<path d="M6.17627 22.3529H23.8233V23.5294H6.17627V22.3529Z" fill="white"/>
<path d="M6.17627 26.1765H23.8233V27.3529H6.17627V26.1765Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#1E7AAA"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path d="M6 15h18v1H6v-1zM6 19h18v1H6v-1zM6 23h18v1H6v-1zM6 27h18v1H6v-1z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 387 B

View File

@ -1,6 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#27ABA3"/>
<path d="M22.9165 0L29.9998 7.08333H25.9165C24.2597 7.08333 22.9165 5.74019 22.9165 4.08333V0Z" fill="#008078"/>
<rect x="6.5" y="15.5" width="17" height="5" stroke="white"/>
<rect x="6.5" y="23.5" width="17" height="5" stroke="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#27ABA3"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#008078"/><path fill-rule="evenodd" clip-rule="evenodd" d="M24 14H6v7h18v-7zm-.8182 5.9978H6.81818V15H23.1818v4.9978zM24 23H6v7h18v-7zm-.8182 5.9978H6.81818V24H23.1818v4.9978z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 463 B

View File

@ -1,8 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#F36700"/>
<path d="M22.9167 0L30.0001 7.08333H25.9168C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#AB531F"/>
<path d="M6.17627 16.1275H23.8233V17.3039H6.17627V16.1275Z" fill="white"/>
<path d="M6.17627 28.7745L6.17627 16.1275L7.35274 16.1275L7.35274 28.7745H6.17627Z" fill="white"/>
<path d="M23.8233 16.1275V28.7745H22.6469V16.1275L23.8233 16.1275Z" fill="white"/>
<path d="M6.17627 27.598H23.8233V28.7745H6.17627L6.17627 27.598Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#F36700"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path stroke="#fff" stroke-opacity=".95" d="M6.5 15.5h17v12h-17z"/></svg>

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 366 B

View File

@ -1,6 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 7.44186L22 0H3C1.22739 0 0 0.822551 0 2.32558V37.2093C0 38.7123 1.22739 40 3 40H27C28.7726 40 30 38.7123 30 37.2093V7.44186Z" fill="#D0D5DA"/>
<path d="M24.1042 7.27273H29.9631L22 0V5.32334C22 6.4105 22.949 7.27273 24.1042 7.27273Z" fill="#646464"/>
<path d="M16.9562 22.3485H12.9746V17.803H10.9839L14.9654 14.1667L18.947 17.803H16.9562V22.3485Z" fill="#646464"/>
<path d="M20.9378 23.7121C20.9378 24.1666 20.4401 24.6212 19.9424 24.6212H9.98848C9.49078 24.6212 8.99309 24.1666 8.99309 23.7121V22.3485C8.99309 21.8939 9.49078 21.4394 9.98848 21.4394H10.9839V20.0757H9.49078C8.49539 20.0757 7.5 20.9848 7.5 21.8939V24.1666C7.5 25.0757 8.61982 25.9848 9.49078 25.9848H20.4401C21.3111 25.9848 22.4309 25.0757 22.4309 24.1666V21.8939C22.4309 20.9848 21.4355 20.0757 20.4401 20.0757H18.947V21.4394H19.9424C20.4401 21.4394 20.9378 21.8939 20.9378 22.3485V23.7121Z" fill="#646464"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#D0D5DA"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#646464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 23c-.27614 0-.5.2239-.5.5v4c0 .2761.22386.5.5.5h15c.2761 0 .5-.2239.5-.5v-4c0-.2761-.2239-.5-.5-.5h-2c-.2761 0-.5-.2239-.5-.5s.2239-.5.5-.5h2c.8284 0 1.5.6716 1.5 1.5v4c0 .8284-.6716 1.5-1.5 1.5h-15c-.82843 0-1.5-.6716-1.5-1.5v-4c0-.8284.67157-1.5 1.5-1.5h2c.27614 0 .5.2239.5.5s-.22386.5-.5.5h-2z" fill="#646464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M20 20.0001L15 14l-5 6.0001h3v4c0 .5523.4477 1 1 1h2c.5523 0 1-.4477 1-1v-4h3z" fill="#646464"/></svg>

Before

Width:  |  Height:  |  Size: 992 B

After

Width:  |  Height:  |  Size: 797 B

View File

@ -1,12 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#78A73B"/>
<path d="M22.9167 0L30.0001 7.08333H25.9168C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#5A7D2B"/>
<path d="M6.17644 15.2941H23.8235V16.4706H6.17644V15.2941Z" fill="white"/>
<path d="M6.17644 19.1177H23.8235V20.2941H6.17644V19.1177Z" fill="white"/>
<path d="M6.17644 22.9412H23.8235V24.1177H6.17644V22.9412Z" fill="white"/>
<path d="M6.17644 26.7647H23.8235V27.9412H6.17644V26.7647Z" fill="white"/>
<path d="M5.88232 27.9412L5.88232 15.2941L7.0588 15.2941L7.0588 27.9412H5.88232Z" fill="white"/>
<path d="M11.4706 27.9412L11.4706 15.2941L12.647 15.2941V27.9412H11.4706Z" fill="white"/>
<path d="M17.0588 27.9412L17.0588 15.2941L18.2353 15.2941V27.9412H17.0588Z" fill="white"/>
<path d="M22.647 27.9412V15.2941H23.8235V27.9412H22.647Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#6AAA1E"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path fill-rule="evenodd" clip-rule="evenodd" d="M6 15h18v13H7.00001v-1H12v-3H7v4H6V15zm7 12h4v-3h-4v3zm5 0h5v-3h-5v3zm5-7v3h-5v-3h5zm-6 0v3h-4v-3h4zm-5 0v3H7v-3h5zm11-1v-3h-5v3h5zm-10-3h4v3h-4v-3zm-1 3v-3H7v3h5z" fill="#fff" fill-opacity=".95"/></svg>

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 545 B

View File

@ -14,7 +14,7 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
Download the [.Net (C# MVC) example](https://api.onlyoffice.com/editors/demopreview) from our site.
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *settings.config* file:
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *web.appsettings.config* file:
```
<add key="storage-path" value=""/>
<add key="files.docservice.url.site" value="https://documentserver/" />

View File

@ -840,6 +840,7 @@ namespace OnlineEditorsExampleMVC
var data = new Dictionary<string, object>() {
{ "fileType", (Path.GetExtension(fileName) ?? "").ToLower().Trim('.') },
{ "key", ServiceConverter.GenerateRevisionId(DocManagerHelper.CurUserHostAddress() + "/" + fileName + "/" + File.GetLastWriteTime(DocManagerHelper.StoragePath(fileName, null)).GetHashCode())},
{ "url", DocManagerHelper.GetDownloadUrl(fileName)},
{ "directUrl", directUrl ? DocManagerHelper.GetDownloadUrl(fileName, false) : null },
{ "referenceData", new Dictionary<string, string>()

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<appSettings>
<clear />
<add key="version" value="1.7.0"/>
<add key="version" value="1.6.0"/>
<add key="filesize-max" value="52428800"/>
<add key="storage-path" value=""/>

View File

@ -1,8 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H21.674C22.4697 0 23.2327 0.316071 23.7953 0.87868L29.1213 6.20465C29.6839 6.76726 30 7.53032 30 8.32597V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#3779A6"/>
<path d="M22.9167 0L30.0001 7.08333H25.9167C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#1D5880"/>
<path d="M6.17627 14.7059H23.8233V15.8823H6.17627V14.7059Z" fill="white"/>
<path d="M6.17627 18.5294H23.8233V19.7059H6.17627V18.5294Z" fill="white"/>
<path d="M6.17627 22.3529H23.8233V23.5294H6.17627V22.3529Z" fill="white"/>
<path d="M6.17627 26.1765H23.8233V27.3529H6.17627V26.1765Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#1E7AAA"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path d="M6 15h18v1H6v-1zM6 19h18v1H6v-1zM6 23h18v1H6v-1zM6 27h18v1H6v-1z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 387 B

View File

@ -1,6 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#27ABA3"/>
<path d="M22.9165 0L29.9998 7.08333H25.9165C24.2597 7.08333 22.9165 5.74019 22.9165 4.08333V0Z" fill="#008078"/>
<rect x="6.5" y="15.5" width="17" height="5" stroke="white"/>
<rect x="6.5" y="23.5" width="17" height="5" stroke="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#27ABA3"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#008078"/><path fill-rule="evenodd" clip-rule="evenodd" d="M24 14H6v7h18v-7zm-.8182 5.9978H6.81818V15H23.1818v4.9978zM24 23H6v7h18v-7zm-.8182 5.9978H6.81818V24H23.1818v4.9978z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 463 B

View File

@ -1,8 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#F36700"/>
<path d="M22.9167 0L30.0001 7.08333H25.9168C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#AB531F"/>
<path d="M6.17627 16.1275H23.8233V17.3039H6.17627V16.1275Z" fill="white"/>
<path d="M6.17627 28.7745L6.17627 16.1275L7.35274 16.1275L7.35274 28.7745H6.17627Z" fill="white"/>
<path d="M23.8233 16.1275V28.7745H22.6469V16.1275L23.8233 16.1275Z" fill="white"/>
<path d="M6.17627 27.598H23.8233V28.7745H6.17627L6.17627 27.598Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#F36700"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path stroke="#fff" stroke-opacity=".95" d="M6.5 15.5h17v12h-17z"/></svg>

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 366 B

View File

@ -1,6 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 7.44186L22 0H3C1.22739 0 0 0.822551 0 2.32558V37.2093C0 38.7123 1.22739 40 3 40H27C28.7726 40 30 38.7123 30 37.2093V7.44186Z" fill="#D0D5DA"/>
<path d="M24.1042 7.27273H29.9631L22 0V5.32334C22 6.4105 22.949 7.27273 24.1042 7.27273Z" fill="#646464"/>
<path d="M16.9562 22.3485H12.9746V17.803H10.9839L14.9654 14.1667L18.947 17.803H16.9562V22.3485Z" fill="#646464"/>
<path d="M20.9378 23.7121C20.9378 24.1666 20.4401 24.6212 19.9424 24.6212H9.98848C9.49078 24.6212 8.99309 24.1666 8.99309 23.7121V22.3485C8.99309 21.8939 9.49078 21.4394 9.98848 21.4394H10.9839V20.0757H9.49078C8.49539 20.0757 7.5 20.9848 7.5 21.8939V24.1666C7.5 25.0757 8.61982 25.9848 9.49078 25.9848H20.4401C21.3111 25.9848 22.4309 25.0757 22.4309 24.1666V21.8939C22.4309 20.9848 21.4355 20.0757 20.4401 20.0757H18.947V21.4394H19.9424C20.4401 21.4394 20.9378 21.8939 20.9378 22.3485V23.7121Z" fill="#646464"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#D0D5DA"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#646464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 23c-.27614 0-.5.2239-.5.5v4c0 .2761.22386.5.5.5h15c.2761 0 .5-.2239.5-.5v-4c0-.2761-.2239-.5-.5-.5h-2c-.2761 0-.5-.2239-.5-.5s.2239-.5.5-.5h2c.8284 0 1.5.6716 1.5 1.5v4c0 .8284-.6716 1.5-1.5 1.5h-15c-.82843 0-1.5-.6716-1.5-1.5v-4c0-.8284.67157-1.5 1.5-1.5h2c.27614 0 .5.2239.5.5s-.22386.5-.5.5h-2z" fill="#646464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M20 20.0001L15 14l-5 6.0001h3v4c0 .5523.4477 1 1 1h2c.5523 0 1-.4477 1-1v-4h3z" fill="#646464"/></svg>

Before

Width:  |  Height:  |  Size: 992 B

After

Width:  |  Height:  |  Size: 797 B

View File

@ -1,12 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#78A73B"/>
<path d="M22.9167 0L30.0001 7.08333H25.9168C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#5A7D2B"/>
<path d="M6.17644 15.2941H23.8235V16.4706H6.17644V15.2941Z" fill="white"/>
<path d="M6.17644 19.1177H23.8235V20.2941H6.17644V19.1177Z" fill="white"/>
<path d="M6.17644 22.9412H23.8235V24.1177H6.17644V22.9412Z" fill="white"/>
<path d="M6.17644 26.7647H23.8235V27.9412H6.17644V26.7647Z" fill="white"/>
<path d="M5.88232 27.9412L5.88232 15.2941L7.0588 15.2941L7.0588 27.9412H5.88232Z" fill="white"/>
<path d="M11.4706 27.9412L11.4706 15.2941L12.647 15.2941V27.9412H11.4706Z" fill="white"/>
<path d="M17.0588 27.9412L17.0588 15.2941L18.2353 15.2941V27.9412H17.0588Z" fill="white"/>
<path d="M22.647 27.9412V15.2941H23.8235V27.9412H22.647Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#6AAA1E"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path fill-rule="evenodd" clip-rule="evenodd" d="M6 15h18v13H7.00001v-1H12v-3H7v4H6V15zm7 12h4v-3h-4v3zm5 0h5v-3h-5v3zm5-7v3h-5v-3h5zm-6 0v3h-4v-3h4zm-5 0v3H7v-3h5zm11-1v-3h-5v3h5zm-10-3h4v3h-4v-3zm-1 3v-3H7v3h5z" fill="#fff" fill-opacity=".95"/></svg>

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 545 B

View File

@ -650,6 +650,9 @@ namespace OnlineEditorsExample
var data = new Dictionary<string, object>() {
{ "fileType", (Path.GetExtension(fileName) ?? "").ToLower().Trim('.') },
{ "key", ServiceConverter.GenerateRevisionId(_Default.CurUserHostAddress(null)
+ "/" + Path.GetFileName(_Default.FileUri(fileName, true))
+ "/" + File.GetLastWriteTime(_Default.StoragePath(fileName, null)).GetHashCode()) },
{ "url", DocEditor.getDownloadUrl(fileName)},
{ "directUrl", directUrl ? DocEditor.getDownloadUrl(fileName, false) : null},
{ "referenceData", new Dictionary<string, string>()

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<clear />
<add key="version" value="1.7.0"/>
<add key="version" value="1.6.0"/>
<add key="filesize-max" value="52428800"/>
<add key="storage-path" value=""/>

View File

@ -20,7 +20,7 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
Download the [Java-Spring example](https://api.onlyoffice.com/editors/demopreview) from our site.
To connect the editors to your website, specify the path to the editors installation, server port and the path to the storage folder in the *\src\main\resources\application.properties* file:
To connect the editors to your website, specify the path to the editors installation, server port and the path to the storage folder in the *src/main/resources/application.properties* file:
```
files.storage=
@ -128,22 +128,18 @@ See the detailed guide to learn how to install Document Server [for Linux](https
### Step 2. Install the prerequisites and run the website with the editors
1. Install **Java**:
```
sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install oracle-java11-installer
```
1. Install **Java** following the instructions [here](https://docs.oracle.com/en/java/javase/20/install/installation-jdk-linux-platforms.html#GUID-737A84E4-2EFF-4D38-8E60-3E29D1B884B8).
2. Download the archive with the Java-Spring example and unpack the archive or clone git repository:
a) archive with Java-Spring:
```
wget https://api.onlyoffice.com/app_data/editor/Java%20Spring%20Example.zip
wget https://api.onlyoffice.com/app_data/editor/Java.Spring.Example.zip
```
```
unzip Java\ Spring\ Example.zip
unzip Java.Spring.Example.zip
```
b) git repository:
```
@ -162,7 +158,7 @@ See the detailed guide to learn how to install Document Server [for Linux](https
```
cd document-server-integration/web/documentserver-example/java-spring
```
4. Edit the *application.properties* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed.
4. Edit the *src/main/resources/application.properties* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed.
```
nano src/main/resources/application.properties
@ -210,13 +206,51 @@ Make sure that the Document Server has access to the server with the example ins
## For Docker
1. Edit the *application.properties* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed ([installation instructions](https://helpcenter.onlyoffice.com/installation/docs-developer-install-docker.aspx)).
### Step 1. Install ONLYOFFICE Docs
Download and install ONLYOFFICE Docs (packaged as Document Server).
See the detailed guide to learn how to install Document Server [for Docker](https://helpcenter.onlyoffice.com/installation/docs-developer-install-docker.aspx).
### Step 2. Install the prerequisites and run the website with the editors
1. Install **Java** following the instructions [here](https://docs.oracle.com/en/java/javase/20/install/installation-jdk-linux-platforms.html#GUID-737A84E4-2EFF-4D38-8E60-3E29D1B884B8).
2. Download the archive with the Java-Spring example and unpack the archive or clone git repository:
a) archive with Java-Spring:
```
wget https://api.onlyoffice.com/app_data/editor/Java.Spring.Example.zip
```
```
unzip Java.Spring.Example.zip
```
b) git repository:
```
git clone https://github.com/ONLYOFFICE/document-server-integration.git
```
3. Change the current directory for the project directory:
a) from archive
```
cd Java\ Spring\ Example/
```
b) from git repository
```
cd document-server-integration/web/documentserver-example/java-spring
```
4. Edit the *src/main/resources/application.properties* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed:
```
nano src/main/resources/application.properties
```
2. Edit the following lines:
5. Edit the following lines:
```
files.storage=
@ -226,17 +260,23 @@ Make sure that the Document Server has access to the server with the example ins
where the **documentserver** is the name of the server with the ONLYOFFICE Docs installed, **port** is any available port and **files.storage** is the path where files will be created and stored (in the project folder by default). You can set an absolute path.
3. Run the next command in the java example directory:
6. Run the next command in the java example directory:
```
docker-compose up
```
4. Open your browser using **server.address** and **server.port**:
7. Open your browser using **server.address** and **server.port**:
```
http://server.address:server.port/
```
### Step 3. Check accessibility
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## Important security info
Please keep in mind the following security aspects when you are using test examples:

View File

@ -20,7 +20,6 @@ package com.onlyoffice.integration.controllers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.onlyoffice.integration.documentserver.managers.history.HistoryManager;
import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
import com.onlyoffice.integration.documentserver.models.enums.Action;
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
@ -73,9 +72,6 @@ public class EditorController {
@Autowired
private UserServices userService;
@Autowired
private HistoryManager historyManager;
@Autowired
private ObjectMapper objectMapper;
@ -140,9 +136,6 @@ public class EditorController {
// add file model with the default parameters to the original model
model.addAttribute("model", fileModel);
// get file history and add it to the model
model.addAttribute("fileHistory", historyManager.getHistory(fileModel.getDocument()));
// create the document service api URL and add it to the model
model.addAttribute("docserviceApiUrl", docserviceSite + docserviceApiUrl);

View File

@ -22,11 +22,17 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.onlyoffice.integration.documentserver.callbacks.CallbackHandler;
import com.onlyoffice.integration.documentserver.managers.history.HistoryManager;
import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
import com.onlyoffice.integration.documentserver.storage.FileStorageMutator;
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
import com.onlyoffice.integration.dto.Converter;
import com.onlyoffice.integration.dto.ConvertedData;
import com.onlyoffice.integration.dto.Reference;
import com.onlyoffice.integration.dto.ReferenceData;
import com.onlyoffice.integration.dto.Rename;
import com.onlyoffice.integration.dto.Restore;
import com.onlyoffice.integration.dto.SaveAs;
import com.onlyoffice.integration.dto.Track;
import com.onlyoffice.integration.entities.User;
import com.onlyoffice.integration.documentserver.models.enums.DocumentType;
@ -74,7 +80,6 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
@ -114,6 +119,8 @@ public class FileController {
private ServiceConverter serviceConverter;
@Autowired
private CallbackManager callbackManager;
@Autowired
private HistoryManager historyManager;
// create user metadata
private String createUserMetadata(final String uid, final String fullFileName) {
@ -184,7 +191,8 @@ public class FileController {
throw new IOException("Could not update a file"); // if the file cannot be updated, an error occurs
}
fullFileName = fileUtility.getFileNameWithoutExtension(fileNamePath) + fileExtension; // get full file name
fullFileName = fileUtility.getFileNameWithoutExtension(fileNamePath)
+ "." + fileExtension; // get full file name
return createUserMetadata(uid, fullFileName); // create user metadata and return it
} catch (Exception e) {
@ -412,19 +420,16 @@ public class FileController {
@PostMapping("/saveas")
@ResponseBody
public String saveAs(@RequestBody final JSONObject body, @CookieValue("uid") final String uid) {
String title = (String) body.get("title");
String saveAsFileUrl = (String) body.get("url");
public String saveAs(@RequestBody final SaveAs body, @CookieValue("uid") final String uid) {
try {
String fileName = documentManager.getCorrectName(title);
String fileName = documentManager.getCorrectName(body.getTitle());
String curExt = fileUtility.getFileExtension(fileName);
if (!fileUtility.getFileExts().contains(curExt)) {
return "{\"error\":\"File type is not supported\"}";
}
URL url = new URL(saveAsFileUrl);
URL url = new URL(body.getUrl());
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
InputStream stream = connection.getInputStream();
@ -443,25 +448,14 @@ public class FileController {
@PostMapping("/rename")
@ResponseBody
public String rename(@RequestBody final JSONObject body) {
String newfilename = (String) body.get("newfilename");
String dockey = (String) body.get("dockey");
String origExt = "." + (String) body.get("ext");
String curExt = newfilename;
if (newfilename.indexOf(".") != -1) {
curExt = (String) fileUtility.getFileExtension(newfilename);
}
if (origExt.compareTo(curExt) != 0) {
newfilename += origExt;
}
public String rename(@RequestBody final Rename body) {
String fileName = body.getFileName();
HashMap<String, String> meta = new HashMap<>();
meta.put("title", newfilename);
meta.put("title", fileName + "." + body.getFileType());
try {
callbackManager.commandRequest("meta", dockey, meta);
callbackManager.commandRequest("meta", body.getFileKey(), meta);
return "result ok";
} catch (Exception e) {
e.printStackTrace();
@ -471,7 +465,7 @@ public class FileController {
@PostMapping("/reference")
@ResponseBody
public String reference(@RequestBody final JSONObject body) {
public String reference(@RequestBody final Reference body) {
try {
JSONParser parser = new JSONParser();
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
@ -479,12 +473,11 @@ public class FileController {
String userAddress = "";
String fileName = "";
if (body.containsKey("referenceData")) {
LinkedHashMap referenceDataObj = (LinkedHashMap) body.get("referenceData");
String instanceId = (String) referenceDataObj.get("instanceId");
if (body.getReferenceData() != null) {
ReferenceData referenceData = body.getReferenceData();
if (instanceId.equals(storagePathBuilder.getServerUrl(false))) {
JSONObject fileKey = (JSONObject) parser.parse((String) referenceDataObj.get("fileKey"));
if (referenceData.getInstanceId().equals(storagePathBuilder.getServerUrl(false))) {
JSONObject fileKey = (JSONObject) parser.parse(referenceData.getFileKey());
userAddress = (String) fileKey.get("userAddress");
if (userAddress.equals(InetAddress.getLocalHost().getHostAddress())) {
fileName = (String) fileKey.get("fileName");
@ -495,7 +488,7 @@ public class FileController {
if (fileName.equals("")) {
try {
String path = (String) body.get("path");
String path = (String) body.getPath();
path = fileUtility.getFileName(path);
File f = new File(storagePathBuilder.getFileLocation(path));
if (f.exists()) {
@ -510,8 +503,6 @@ public class FileController {
return "{ \"error\": \"File not found\"}";
}
boolean directUrl = (boolean) body.get("directUrl");
HashMap<String, Object> fileKey = new HashMap<>();
fileKey.put("fileName", fileName);
fileKey.put("userAddress", InetAddress.getLocalHost().getHostAddress());
@ -521,9 +512,14 @@ public class FileController {
referenceData.put("fileKey", gson.toJson(fileKey));
HashMap<String, Object> data = new HashMap<>();
data.put("fileType", fileUtility.getFileExtension(fileName).replace(".", ""));
data.put("fileType", fileUtility.getFileExtension(fileName));
data.put("key", serviceConverter.generateRevisionId(
storagePathBuilder.getStorageLocation()
+ "/" + fileName + "/"
+ new File(storagePathBuilder.getFileLocation(fileName)).lastModified()
));
data.put("url", documentManager.getDownloadUrl(fileName, true));
data.put("directUrl", directUrl ? documentManager.getDownloadUrl(fileName, false) : null);
data.put("directUrl", body.getDirectUrl() ? documentManager.getDownloadUrl(fileName, false) : null);
data.put("referenceData", referenceData);
data.put("path", fileName);
@ -538,15 +534,25 @@ public class FileController {
}
}
@GetMapping("/history")
@ResponseBody
public String history(@RequestParam("fileName") final String fileName) {
return historyManager.getHistory(fileName);
}
@GetMapping("/historydata")
@ResponseBody
public String history(@RequestParam("fileName") final String fileName,
@RequestParam("version") final String version,
@RequestParam(value = "directUrl", defaultValue = "false") final Boolean directUrl) {
return historyManager.getHistoryData(fileName, version, directUrl);
}
@PutMapping("/restore")
@ResponseBody
public String restore(@RequestBody final JSONObject body) {
public String restore(@RequestBody final Restore body, @CookieValue("uid") final Integer uid) {
try {
String sourceBasename = (String) body.get("fileName");
Integer version = (Integer) body.get("version");
String userID = (String) body.get("userId");
String sourceStringFile = storagePathBuilder.getFileLocation(sourceBasename);
String sourceStringFile = storagePathBuilder.getFileLocation(body.getFileName());
File sourceFile = new File(sourceStringFile);
Path sourcePathFile = sourceFile.toPath();
String historyDirectory = storagePathBuilder.getHistoryDir(sourcePathFile.toString());
@ -564,7 +570,7 @@ public class FileController {
String bumpedKey = serviceConverter.generateRevisionId(
storagePathBuilder.getStorageLocation()
+ "/"
+ sourceBasename
+ body.getFileName()
+ "/"
+ Long.toString(sourceFile.lastModified())
);
@ -572,8 +578,7 @@ public class FileController {
bumpedKeyFileWriter.write(bumpedKey);
bumpedKeyFileWriter.close();
Integer userInnerID = Integer.parseInt(userID.replace("uid-", ""));
User user = userService.findUserById(userInnerID).get();
User user = userService.findUserById(uid).get();
Path bumpedChangesPathFile = Paths.get(bumpedVersionStringDirectory, "changes.json");
String bumpedChangesStringFile = bumpedChangesPathFile.toString();
@ -596,13 +601,17 @@ public class FileController {
bumpedChangesFileWriter.write(bumpedChangesContent);
bumpedChangesFileWriter.close();
String sourceExtension = fileUtility.getFileExtension(sourceBasename);
String previousBasename = "prev" + sourceExtension;
String sourceExtension = fileUtility.getFileExtension(body.getFileName());
String previousBasename = "prev." + sourceExtension;
Path bumpedFile = Paths.get(bumpedVersionStringDirectory, previousBasename);
Files.move(sourcePathFile, bumpedFile);
String recoveryVersionStringDirectory = documentManager.versionDir(historyDirectory, version, true);
String recoveryVersionStringDirectory = documentManager.versionDir(
historyDirectory,
body.getVersion(),
true
);
Path recoveryPathFile = Paths.get(recoveryVersionStringDirectory, previousBasename);
String recoveryStringFile = recoveryPathFile.toString();
FileInputStream recoveryStream = new FileInputStream(recoveryStringFile);

View File

@ -120,7 +120,7 @@ public class DefaultCallbackManager implements CallbackManager {
String newFileName = fileName;
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
String downloadExt = "." + body.getFiletype(); // get an extension of the downloaded file
String downloadExt = body.getFiletype(); // get an extension of the downloaded file
// todo: Refactoring
// convert downloaded file to the file with the current extension if these extensions aren't equal
@ -132,14 +132,14 @@ public class DefaultCallbackManager implements CallbackManager {
null).getUri(); // convert a file and get URL to a new file
if (newFileUri.isEmpty()) {
newFileName = documentManager
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName)
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + "."
+ downloadExt); // get the correct file name if it already exists
} else {
downloadUri = newFileUri;
}
} catch (Exception e) {
newFileName = documentManager
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + downloadExt);
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + "." + downloadExt);
}
}
@ -163,7 +163,7 @@ public class DefaultCallbackManager implements CallbackManager {
storageMutator.createDirectory(ver); // create the file version directory
lastVersion.toFile().renameTo(new File(versionDir + File.separator + "prev" + curExt));
lastVersion.toFile().renameTo(new File(versionDir + File.separator + "prev." + curExt));
saveFile(byteArrayFile, toSave); // save document file
@ -269,7 +269,7 @@ public class DefaultCallbackManager implements CallbackManager {
String fileName = fileNameParam;
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
String downloadExt = "." + body.getFiletype(); // get an extension of the downloaded file
String downloadExt = body.getFiletype(); // get an extension of the downloaded file
Boolean newFileName = false;
@ -304,10 +304,10 @@ public class DefaultCallbackManager implements CallbackManager {
// get the correct file name if it already exists
fileName = documentManager
.getCorrectName(fileUtility
.getFileNameWithoutExtension(fileName) + "-form" + downloadExt);
.getFileNameWithoutExtension(fileName) + "-form." + downloadExt);
} else {
fileName = documentManager
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + "-form" + curExt);
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + "-form." + curExt);
}
forcesavePath = storagePathBuilder.getFileLocation(fileName); // create forcesave path if it doesn't exist
List<Action> actions = body.getActions();

View File

@ -69,7 +69,7 @@ public class DefaultDocumentManager implements DocumentManager {
// get URL to the created file
public String getCreateUrl(final String fileName, final Boolean sample) {
String fileExt = fileUtility.getFileExtension(fileName).replace(".", "");
String fileExt = fileUtility.getFileExtension(fileName);
String url = storagePathBuilder.getServerUrl(true)
+ "/create?fileExt=" + fileExt + "&sample=" + sample;
return url;
@ -79,13 +79,13 @@ public class DefaultDocumentManager implements DocumentManager {
public String getCorrectName(final String fileName) {
String baseName = fileUtility.getFileNameWithoutExtension(fileName); // get file name without extension
String ext = fileUtility.getFileExtension(fileName); // get file extension
String name = baseName + ext; // create a full file name
String name = baseName + "." + ext; // create a full file name
Path path = Paths.get(storagePathBuilder.getFileLocation(name));
// run through all the files with such a name in the storage directory
for (int i = 1; Files.exists(path); i++) {
name = baseName + " (" + i + ")" + ext; // and add an index to the base name
name = baseName + " (" + i + ")." + ext; // and add an index to the base name
path = Paths.get(storagePathBuilder.getFileLocation(name));
}

View File

@ -25,6 +25,7 @@ import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
import com.onlyoffice.integration.documentserver.models.filemodel.Document;
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
import com.onlyoffice.integration.documentserver.util.service.ServiceConverter;
import lombok.SneakyThrows;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
@ -62,6 +63,9 @@ public class DefaultHistoryManager implements HistoryManager {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private ServiceConverter serviceConverter;
// todo: Refactoring
@SneakyThrows
public String[] getHistory(final Document document) { // get document history
@ -99,14 +103,14 @@ public class DefaultHistoryManager implements HistoryManager {
}
dataObj.put("fileType", fileUtility
.getFileExtension(document.getTitle()).replace(".", ""));
.getFileExtension(document.getTitle()));
dataObj.put("key", key);
dataObj.put("url", i == curVer ? document.getUrl()
: documentManager.getHistoryFileUrl(document.getTitle(), i, "prev" + fileUtility
: documentManager.getHistoryFileUrl(document.getTitle(), i, "prev." + fileUtility
.getFileExtension(document.getTitle()), true));
if (!document.getDirectUrl().equals("")) {
dataObj.put("directUrl", i == curVer ? document.getDirectUrl()
: documentManager.getHistoryFileUrl(document.getTitle(), i, "prev" + fileUtility
: documentManager.getHistoryFileUrl(document.getTitle(), i, "prev." + fileUtility
.getFileExtension(document.getTitle()), false));
}
dataObj.put("version", i);
@ -164,6 +168,153 @@ public class DefaultHistoryManager implements HistoryManager {
return new String[]{"", ""};
}
// todo: Refactoring
@SneakyThrows
public String getHistory(final String fileName) { // get document history
// get history directory
String histDir = storagePathBuilder.getHistoryDir(storagePathBuilder.getFileLocation(fileName));
Integer curVer = storagePathBuilder.getFileVersion(histDir, false); // get current file version
if (curVer > 0) { // check if the current file version is greater than 0
List<Object> hist = new ArrayList<>();
for (Integer i = 1; i <= curVer; i++) { // run through all the file versions
Map<String, Object> obj = new HashMap<String, Object>();
String verDir = documentManager
.versionDir(histDir, i, true); // get the path to the given file version
String key;
if (i == curVer) {
key = serviceConverter
.generateRevisionId(storagePathBuilder.getStorageLocation()
+ "/" + fileName + "/"
+ new File(storagePathBuilder.getFileLocation(fileName)).lastModified());
} else {
key = readFileToEnd(new File(verDir + File.separator + "key.txt"));
}
obj.put("key", key);
obj.put("version", i);
if (i == 1) { // check if the version number is equal to 1
String createdInfo = readFileToEnd(new File(histDir
+ File.separator + "createdInfo.json")); // get file with meta data
JSONObject json = (JSONObject) parser.parse(createdInfo); // and turn it into json object
// write meta information to the object (user information and creation date)
obj.put("created", json.get("created"));
Map<String, Object> user = new HashMap<String, Object>();
user.put("id", json.get("id"));
user.put("name", json.get("name"));
obj.put("user", user);
}
if (i > 1) { //check if the version number is greater than 1
// if so, get the path to the changes.json file
JSONObject changes = (JSONObject) parser.parse(readFileToEnd(new File(documentManager
.versionDir(histDir, i - 1, true) + File.separator + "changes.json")));
JSONObject change = (JSONObject) ((JSONArray) changes.get("changes")).get(0);
// write information about changes to the object
obj.put("changes", changes.get("changes"));
obj.put("serverVersion", changes.get("serverVersion"));
obj.put("created", change.get("created"));
obj.put("user", change.get("user"));
}
hist.add(obj);
}
// write history information about the current file version to the history object
Map<String, Object> histObj = new HashMap<String, Object>();
histObj.put("currentVersion", curVer);
histObj.put("history", hist);
try {
return objectMapper.writeValueAsString(histObj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return "";
}
// todo: Refactoring
@SneakyThrows
public String getHistoryData(final String fileName, final String version, final Boolean directUrl) {
// get history directory
String histDir = storagePathBuilder.getHistoryDir(storagePathBuilder.getFileLocation(fileName));
Integer curVer = storagePathBuilder.getFileVersion(histDir, false); // get current file version
if (curVer > 0) { // check if the current file version is greater than 0
Map<String, Object> histData = new HashMap<>();
for (Integer i = 1; i <= curVer; i++) { // run through all the file versions
Map<String, Object> dataObj = new HashMap<String, Object>();
String verDir = documentManager
.versionDir(histDir, i, true); // get the path to the given file version
String key;
if (i == curVer) {
key = serviceConverter
.generateRevisionId(storagePathBuilder.getStorageLocation()
+ "/" + fileName + "/"
+ new File(storagePathBuilder.getFileLocation(fileName)).lastModified());
} else {
key = readFileToEnd(new File(verDir + File.separator + "key.txt"));
}
dataObj.put("fileType", fileUtility
.getFileExtension(fileName).replace(".", ""));
dataObj.put("key", key);
dataObj.put("url", i == curVer ? documentManager.getDownloadUrl(fileName, true)
: documentManager.getHistoryFileUrl(fileName, i, "prev" + fileUtility
.getFileExtension(fileName), true));
if (directUrl) {
dataObj.put("directUrl", i == curVer
? documentManager.getDownloadUrl(fileName, false)
: documentManager.getHistoryFileUrl(fileName, i, "prev" + fileUtility
.getFileExtension(fileName), false));
}
dataObj.put("version", i);
if (i > 1) { //check if the version number is greater than 1
// get the history data from the previous file version
Map<String, Object> prev = (Map<String, Object>) histData.get(Integer.toString(i - 1));
Map<String, Object> prevInfo = new HashMap<String, Object>();
prevInfo.put("fileType", prev.get("fileType"));
prevInfo.put("key", prev.get("key")); // write key and URL information about previous file version
prevInfo.put("url", prev.get("url"));
if (directUrl) {
prevInfo.put("directUrl", prev.get("directUrl"));
}
// write information about previous file version to the data object
dataObj.put("previous", prevInfo);
// write the path to the diff.zip archive with differences in this file version
Integer verdiff = i - 1;
dataObj.put("changesUrl", documentManager
.getHistoryFileUrl(fileName, verdiff, "diff.zip", true));
}
if (jwtManager.tokenEnabled()) {
dataObj.put("token", jwtManager.createToken(dataObj));
}
histData.put(Integer.toString(i), dataObj);
}
try {
return objectMapper.writeValueAsString(histData.get(version));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return "";
}
// read a file
private String readFileToEnd(final File file) {
String output = "";

View File

@ -18,9 +18,9 @@
package com.onlyoffice.integration.documentserver.managers.history;
import com.onlyoffice.integration.documentserver.models.filemodel.Document;
// specify the history manager functions
public interface HistoryManager {
String[] getHistory(Document document); // get document history
String getHistory(String fileName); // get document history
String getHistoryData(String fileName, String version, Boolean directUrl); // get document history data
}

View File

@ -0,0 +1,36 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.onlyoffice.integration.documentserver.models;
import java.util.List;
import com.onlyoffice.integration.documentserver.models.enums.DocumentType;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class Format {
private String name;
private DocumentType type;
private List<String> actions;
private List<String> convert;
private List<String> mime;
}

View File

@ -18,7 +18,10 @@
package com.onlyoffice.integration.documentserver.util.file;
import com.onlyoffice.integration.documentserver.models.Format;
import com.onlyoffice.integration.documentserver.models.enums.DocumentType;
import com.onlyoffice.integration.documentserver.util.service.FormatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@ -26,8 +29,6 @@ import org.springframework.stereotype.Component;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.onlyoffice.integration.documentserver.util.Constants.MAX_FILE_SIZE;
@ -38,55 +39,18 @@ public class DefaultFileUtility implements FileUtility {
@Value("${filesize-max}")
private String filesizeMax;
@Value("${files.docservice.viewed-docs}")
private String docserviceViewedDocs;
@Value("${files.docservice.edited-docs}")
private String docserviceEditedDocs;
@Value("${files.docservice.convert-docs}")
private String docserviceConvertDocs;
@Value("${files.docservice.fillforms-docs}")
private String docserviceFillDocs;
// document extensions
private List<String> extsDocument = Arrays.asList(
".doc", ".docx", ".docm",
".dot", ".dotx", ".dotm",
".odt", ".fodt", ".ott", ".rtf", ".txt",
".html", ".htm", ".mht", ".xml",
".pdf", ".djvu", ".fb2", ".epub", ".xps", ".oform");
// spreadsheet extensions
private List<String> extsSpreadsheet = Arrays.asList(
".xls", ".xlsx", ".xlsm", ".xlsb",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv");
// presentation extensions
private List<String> extsPresentation = Arrays.asList(
".pps", ".ppsx", ".ppsm",
".ppt", ".pptx", ".pptm",
".pot", ".potx", ".potm",
".odp", ".fodp", ".otp");
@Autowired
private FormatService formatService;
// get the document type
public DocumentType getDocumentType(final String fileName) {
String ext = getFileExtension(fileName).toLowerCase(); // get file extension from its name
// word type for document extensions
if (extsDocument.contains(ext)) {
return DocumentType.word;
}
// cell type for spreadsheet extensions
if (extsSpreadsheet.contains(ext)) {
return DocumentType.cell;
}
// slide type for presentation extensions
if (extsPresentation.contains(ext)) {
return DocumentType.slide;
List<Format> formats = formatService.getFormats();
for (Format format : formats) {
if (format.getName().equals(ext)) {
return format.getType();
}
}
// default file type is word
@ -121,7 +85,7 @@ public class DefaultFileUtility implements FileUtility {
if (fileName == null) {
return null;
}
String fileExt = fileName.substring(fileName.lastIndexOf("."));
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1);
return fileExt.toLowerCase();
}
@ -147,34 +111,27 @@ public class DefaultFileUtility implements FileUtility {
}
public List<String> getFillExts() {
return Arrays.asList(docserviceFillDocs.split("\\|"));
return formatService.fillableExtensions();
}
// get file extensions that can be viewed
public List<String> getViewedExts() {
return Arrays.asList(docserviceViewedDocs.split("\\|"));
return formatService.viewableExtensions();
}
// get file extensions that can be edited
public List<String> getEditedExts() {
return Arrays.asList(docserviceEditedDocs.split("\\|"));
return formatService.editableExtensions();
}
// get file extensions that can be converted
public List<String> getConvertExts() {
return Arrays.asList(docserviceConvertDocs.split("\\|"));
return formatService.autoConvertExtensions();
}
// get all the supported file extensions
public List<String> getFileExts() {
List<String> res = new ArrayList<>();
res.addAll(getViewedExts());
res.addAll(getEditedExts());
res.addAll(getConvertExts());
res.addAll(getFillExts());
return res;
return formatService.allExtensions();
}
// generate the file path from file directory and name
@ -188,10 +145,10 @@ public class DefaultFileUtility implements FileUtility {
fileName = getFileNameWithoutExtension(fullFileName) + "(" + i + ")";
// create a new path for this file with the correct name and extension
path = Paths.get(directory + fileName + fileExtension);
path = Paths.get(directory + fileName + "." + fileExtension);
}
path = Paths.get(directory + fileName + fileExtension);
path = Paths.get(directory + fileName + "." + fileExtension);
return path;
}

View File

@ -0,0 +1,102 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.onlyoffice.integration.documentserver.util.service;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.onlyoffice.integration.documentserver.models.Format;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
public class DefaultFormatService implements FormatService {
private List<Format> formats;
@Autowired
public DefaultFormatService(
@Value("classpath:assets/document-formats/onlyoffice-docs-formats.json") final Resource resourceFile,
final ObjectMapper objectMapper
) {
try {
File targetFile = resourceFile.getFile();
this.formats = objectMapper.readValue(targetFile, new TypeReference<List<Format>>() { });
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public List<Format> getFormats() {
return this.formats;
}
public List<Format> getFormatsByAction(final String action) {
return this
.formats
.stream()
.filter(format -> format.getActions().contains(action))
.collect(Collectors.toList());
}
public List<String> allExtensions() {
return this
.formats
.stream()
.map(format -> format.getName())
.collect(Collectors.toList());
}
public List<String> fillableExtensions() {
return this
.getFormatsByAction("fill")
.stream()
.map(format -> format.getName())
.collect(Collectors.toList());
}
public List<String> viewableExtensions() {
return this
.getFormatsByAction("view")
.stream()
.map(format -> format.getName())
.collect(Collectors.toList());
}
public List<String> editableExtensions() {
return Stream
.of(this.getFormatsByAction("edit"), this.getFormatsByAction("lossy-edit"))
.flatMap(x -> x.stream())
.map(format -> format.getName())
.collect(Collectors.toList());
}
public List<String> autoConvertExtensions() {
return this
.getFormatsByAction("auto-convert")
.stream()
.map(format -> format.getName())
.collect(Collectors.toList());
}
}

View File

@ -146,8 +146,8 @@ public class DefaultServiceConverter implements ServiceConverter {
Convert body = new Convert();
body.setLang(lang);
body.setUrl(documentUri);
body.setOutputtype(toExtension.replace(".", ""));
body.setFiletype(fromExt.replace(".", ""));
body.setOutputtype(toExtension);
body.setFiletype(fromExt);
body.setTitle(title);
body.setKey(documentRevId);
body.setFilePass(filePass);

View File

@ -0,0 +1,33 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.onlyoffice.integration.documentserver.util.service;
import com.onlyoffice.integration.documentserver.models.Format;
import java.util.List;
public interface FormatService {
List<Format> getFormats();
List<Format> getFormatsByAction(String action);
List<String> allExtensions();
List<String> fillableExtensions();
List<String> viewableExtensions();
List<String> editableExtensions();
List<String> autoConvertExtensions();
}

View File

@ -0,0 +1,34 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.onlyoffice.integration.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Reference {
private Boolean directUrl;
private ReferenceData referenceData;
private String path;
}

View File

@ -0,0 +1,31 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.onlyoffice.integration.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ReferenceData {
private String fileKey;
private String instanceId;
}

View File

@ -0,0 +1,34 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.onlyoffice.integration.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Rename {
private String fileName;
private String fileKey;
private String fileType;
}

View File

@ -0,0 +1,33 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.onlyoffice.integration.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Restore {
private String fileName;
private Integer version;
}

View File

@ -0,0 +1,33 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.onlyoffice.integration.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class SaveAs {
private String title;
private String url;
}

View File

@ -77,7 +77,6 @@ public class DefaultEditorConfigConfigurer implements EditorConfigConfigurer<Def
(JavaType) new TypeToken<HashMap<String, Object>>() { }.getType()));
}
String fileName = wrapper.getFileName(); // set the fileName parameter from the editorConfig wrapper
String fileExt = fileUtility.getFileExtension(fileName);
boolean userIsAnon = wrapper.getUser()
.getName().equals("Anonymous"); // check if the user from the editorConfig wrapper is anonymous or not

View File

@ -1,4 +1,4 @@
server.version=1.7.0
server.version=1.6.0
server.address=
server.port=4000
@ -8,10 +8,6 @@ filesize-max=5242880
files.storage=
files.storage.folder=documents
files.docservice.fillforms-docs=.docx|.oform
files.docservice.viewed-docs=.djvu|.oxps|.pdf|.xps
files.docservice.edited-docs=.csv|.docm|.docx|.docxf|.dotm|.dotx|.epub|.fb2|.html|.odp|.ods|.odt|.otp|.ots|.ott|.potm|.potx|.ppsm|.ppsx|.pptm|.pptx|.rtf|.txt|.xlsm|.xlsx|.xltm|.xltx
files.docservice.convert-docs=.doc|.dot|.dps|.dpt|.epub|.et|.ett|.fb2|.fodp|.fods|.fodt|.htm|.html|.mht|.mhtml|.odp|.ods|.odt|.otp|.ots|.ott|.pot|.pps|.ppt|.rtf|.stw|.sxc|.sxi|.sxw|.wps|.wpt|.xls|.xlsb|.xlt|.xml
files.docservice.timeout=120000
files.docservice.history.postfix=-hist

View File

@ -1,8 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H21.674C22.4697 0 23.2327 0.316071 23.7953 0.87868L29.1213 6.20465C29.6839 6.76726 30 7.53032 30 8.32597V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#3779A6"/>
<path d="M22.9167 0L30.0001 7.08333H25.9167C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#1D5880"/>
<path d="M6.17627 14.7059H23.8233V15.8823H6.17627V14.7059Z" fill="white"/>
<path d="M6.17627 18.5294H23.8233V19.7059H6.17627V18.5294Z" fill="white"/>
<path d="M6.17627 22.3529H23.8233V23.5294H6.17627V22.3529Z" fill="white"/>
<path d="M6.17627 26.1765H23.8233V27.3529H6.17627V26.1765Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#1E7AAA"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path d="M6 15h18v1H6v-1zM6 19h18v1H6v-1zM6 23h18v1H6v-1zM6 27h18v1H6v-1z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 387 B

View File

@ -1,6 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#27ABA3"/>
<path d="M22.9165 0L29.9998 7.08333H25.9165C24.2597 7.08333 22.9165 5.74019 22.9165 4.08333V0Z" fill="#008078"/>
<rect x="6.5" y="15.5" width="17" height="5" stroke="white"/>
<rect x="6.5" y="23.5" width="17" height="5" stroke="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#27ABA3"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#008078"/><path fill-rule="evenodd" clip-rule="evenodd" d="M24 14H6v7h18v-7zm-.8182 5.9978H6.81818V15H23.1818v4.9978zM24 23H6v7h18v-7zm-.8182 5.9978H6.81818V24H23.1818v4.9978z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 463 B

View File

@ -1,8 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#F36700"/>
<path d="M22.9167 0L30.0001 7.08333H25.9168C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#AB531F"/>
<path d="M6.17627 16.1275H23.8233V17.3039H6.17627V16.1275Z" fill="white"/>
<path d="M6.17627 28.7745L6.17627 16.1275L7.35274 16.1275L7.35274 28.7745H6.17627Z" fill="white"/>
<path d="M23.8233 16.1275V28.7745H22.6469V16.1275L23.8233 16.1275Z" fill="white"/>
<path d="M6.17627 27.598H23.8233V28.7745H6.17627L6.17627 27.598Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#F36700"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path stroke="#fff" stroke-opacity=".95" d="M6.5 15.5h17v12h-17z"/></svg>

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 366 B

View File

@ -1,6 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 7.44186L22 0H3C1.22739 0 0 0.822551 0 2.32558V37.2093C0 38.7123 1.22739 40 3 40H27C28.7726 40 30 38.7123 30 37.2093V7.44186Z" fill="#D0D5DA"/>
<path d="M24.1042 7.27273H29.9631L22 0V5.32334C22 6.4105 22.949 7.27273 24.1042 7.27273Z" fill="#646464"/>
<path d="M16.9562 22.3485H12.9746V17.803H10.9839L14.9654 14.1667L18.947 17.803H16.9562V22.3485Z" fill="#646464"/>
<path d="M20.9378 23.7121C20.9378 24.1666 20.4401 24.6212 19.9424 24.6212H9.98848C9.49078 24.6212 8.99309 24.1666 8.99309 23.7121V22.3485C8.99309 21.8939 9.49078 21.4394 9.98848 21.4394H10.9839V20.0757H9.49078C8.49539 20.0757 7.5 20.9848 7.5 21.8939V24.1666C7.5 25.0757 8.61982 25.9848 9.49078 25.9848H20.4401C21.3111 25.9848 22.4309 25.0757 22.4309 24.1666V21.8939C22.4309 20.9848 21.4355 20.0757 20.4401 20.0757H18.947V21.4394H19.9424C20.4401 21.4394 20.9378 21.8939 20.9378 22.3485V23.7121Z" fill="#646464"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#D0D5DA"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#646464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 23c-.27614 0-.5.2239-.5.5v4c0 .2761.22386.5.5.5h15c.2761 0 .5-.2239.5-.5v-4c0-.2761-.2239-.5-.5-.5h-2c-.2761 0-.5-.2239-.5-.5s.2239-.5.5-.5h2c.8284 0 1.5.6716 1.5 1.5v4c0 .8284-.6716 1.5-1.5 1.5h-15c-.82843 0-1.5-.6716-1.5-1.5v-4c0-.8284.67157-1.5 1.5-1.5h2c.27614 0 .5.2239.5.5s-.22386.5-.5.5h-2z" fill="#646464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M20 20.0001L15 14l-5 6.0001h3v4c0 .5523.4477 1 1 1h2c.5523 0 1-.4477 1-1v-4h3z" fill="#646464"/></svg>

Before

Width:  |  Height:  |  Size: 992 B

After

Width:  |  Height:  |  Size: 797 B

View File

@ -1,12 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#78A73B"/>
<path d="M22.9167 0L30.0001 7.08333H25.9168C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#5A7D2B"/>
<path d="M6.17644 15.2941H23.8235V16.4706H6.17644V15.2941Z" fill="white"/>
<path d="M6.17644 19.1177H23.8235V20.2941H6.17644V19.1177Z" fill="white"/>
<path d="M6.17644 22.9412H23.8235V24.1177H6.17644V22.9412Z" fill="white"/>
<path d="M6.17644 26.7647H23.8235V27.9412H6.17644V26.7647Z" fill="white"/>
<path d="M5.88232 27.9412L5.88232 15.2941L7.0588 15.2941L7.0588 27.9412H5.88232Z" fill="white"/>
<path d="M11.4706 27.9412L11.4706 15.2941L12.647 15.2941V27.9412H11.4706Z" fill="white"/>
<path d="M17.0588 27.9412L17.0588 15.2941L18.2353 15.2941V27.9412H17.0588Z" fill="white"/>
<path d="M22.647 27.9412V15.2941H23.8235V27.9412H22.647Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#6AAA1E"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path fill-rule="evenodd" clip-rule="evenodd" d="M6 15h18v13H7.00001v-1H12v-3H7v4H6V15zm7 12h4v-3h-4v3zm5 0h5v-3h-5v3zm5-7v3h-5v-3h5zm-6 0v3h-4v-3h4zm-5 0v3H7v-3h5zm11-1v-3h-5v3h5zm-10-3h4v3h-4v-3zm-1 3v-3H7v3h5z" fill="#fff" fill-opacity=".95"/></svg>

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 545 B

View File

@ -25,9 +25,9 @@ var FillExtList;
if (typeof jQuery !== "undefined") {
jQuery.post('/config',
function(data) {
FillExtList = data.FillExtList;
ConverExtList = data.ConverExtList;
EditedExtList = data.EditedExtList;
FillExtList = data.FillExtList.split(',');
ConverExtList = data.ConverExtList.split(',');
EditedExtList = data.EditedExtList.split(',');
UrlConverter = data.UrlConverter;
UrlEditor = data.UrlEditor;
});

View File

@ -100,10 +100,10 @@ if (typeof jQuery !== "undefined") {
jq("#filePass").val("");
var fileName = jq("#hiddenFileName").val();
var posExt = fileName.lastIndexOf(".");
var posExt = fileName.lastIndexOf(".") + 1;
posExt = 0 <= posExt ? fileName.substring(posExt).trim().toLowerCase() : "";
if (ConverExtList.indexOf(posExt) === -1) {
if (ConverExtList.includes(posExt) === -1) {
jq("#step2").addClass("done").removeClass("current");
loadScripts();
return;
@ -177,10 +177,10 @@ if (typeof jQuery !== "undefined") {
jq("#beginView, #beginEmbedded").removeClass("disable");
var fileName = jq("#hiddenFileName").val();
var posExt = fileName.lastIndexOf(".");
var posExt = fileName.lastIndexOf(".") + 1;
posExt = 0 <= posExt ? fileName.substring(posExt).trim().toLowerCase() : "";
if (EditedExtList.indexOf(posExt) !== -1 || FillExtList.indexOf(posExt) !== -1) {
if (EditedExtList.includes(posExt) !== -1 || FillExtList.includes(posExt) !== -1) {
jq("#beginEdit").removeClass("disable");
}
};

View File

@ -147,9 +147,9 @@
var newfilename = event.data;
var data = {
newfilename: newfilename,
dockey: config.document.key,
ext: config.document.fileType
fileName: newfilename,
fileKey: config.document.key,
fileType: config.document.fileType
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "rename");
@ -172,25 +172,61 @@
}
};
var onRequestHistory = function () {
var xhr = new XMLHttpRequest();
xhr.open("GET", "history?fileName=" + config.document.title, false);
xhr.send();
if (xhr.status == 200) {
var historyInfo = JSON.parse(xhr.responseText);
docEditor.refreshHistory(historyInfo);
}
};
var onRequestHistoryData = function (event) {
var version = event.data;
var historyDataUri = "historydata?fileName=" + config.document.title
+ "&version=" + version
+ "&directUrl=" + !!config.document.directUrl;
var xhr = new XMLHttpRequest();
xhr.open("GET", historyDataUri, false);
xhr.send();
if (xhr.status == 200) {
var historyData = JSON.parse(xhr.responseText);
docEditor.setHistoryData(historyData);
}
};
var onRequestHistoryClose = function() {
document.location.reload();
};
function onRequestRestore(event) {
const query = new URLSearchParams(window.location.search)
const config = [[${model}]]
const payload = {
fileName: query.get('fileName'),
version: event.data.version,
userId: config.editorConfig.user.id
version: event.data.version
}
const request = new XMLHttpRequest()
request.open('PUT', 'restore')
request.setRequestHeader('Content-Type', 'application/json')
request.send(JSON.stringify(payload))
request.onload = function () {
if (request.status != 200) {
response = JSON.parse(request.response)
innerAlert(response.error)
return
const response = JSON.parse(request.responseText);
if (response.success && !response.error) {
var historyInfoUri = "history?fileName=" + config.document.title;
var xhr = new XMLHttpRequest();
xhr.open("GET", historyInfoUri, false);
xhr.send();
if (xhr.status == 200) {
var historyInfo = JSON.parse(xhr.responseText);
docEditor.refreshHistory(historyInfo);
}
} else {
innerAlert(response.error);
}
document.location.reload()
}
}
@ -206,31 +242,15 @@
"onRequestInsertImage": onRequestInsertImage,
"onRequestCompareFile": onRequestCompareFile,
"onRequestMailMergeRecipients": onRequestMailMergeRecipients,
"onRequestRestore": onRequestRestore
"onRequestRestore": onRequestRestore,
"onRequestHistory": onRequestHistory,
"onRequestHistoryData": onRequestHistoryData,
"onRequestHistoryClose": onRequestHistoryClose
};
var histArray = [[${fileHistory}]];
var hist = histArray[0];
var historyData = histArray[1];
var usersForMentions = [[${usersForMentions}]];
if (config.editorConfig.user.id != 4) {
if (hist && historyData) {
// the user is trying to show the document version history
config.events['onRequestHistory'] = function () {
docEditor.refreshHistory(JSON.parse(hist)); // show the document version history
};
// the user is trying to click the specific document version in the document version history
config.events['onRequestHistoryData'] = function (event) {
var ver = event.data;
var histData = historyData;
docEditor.setHistoryData(JSON.parse(histData)[ver - 1]); // send the link to the document for viewing the version history
};
// the user is trying to go back to the document from viewing the document version history
config.events['onRequestHistoryClose'] = function () {
document.location.reload();
};
}
// add mentions for not anonymous users
config.events['onRequestUsers'] = function () {
docEditor.setUsers({ // set a list of users to mention in the comments

View File

@ -27,3 +27,7 @@ License File: jQuery.UI.license
Prime JWT - is intended to be fast and easy to use. Prime JWT has a single external dependency on Jackson. (https://github.com/ws-apps/prime-jwt/blob/master/LICENSE)
License: Apache 2.0
License File: prime-jwt.license
Project Lombok - Spice up your java: Automatic Resource Management, automatic generation of getters, setters, equals, hashCode and toString, and more! (https://projectlombok.org/LICENSE)
License: MIT
License File: lombok.license

View File

@ -16,7 +16,7 @@ See the detailed guide to learn how to [install Document Server for Windows](htt
Download the [Java example](https://api.onlyoffice.com/editors/demopreview) from our site.
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *\src\main\resources\settings.properties* file:
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *src/main/resources/settings.properties* file:
```
storage-folder = app_data
@ -140,20 +140,16 @@ See the detailed guide to learn how to [install Document Server for Linux](https
### Step 2. Install the prerequisites and run the website with the editors
1. Install **Java**:
```
sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install oracle-java8-installer
```
1. Install **Java** following the instructions [here](https://docs.oracle.com/en/java/javase/20/install/installation-jdk-linux-platforms.html#GUID-737A84E4-2EFF-4D38-8E60-3E29D1B884B8).
2. Download the archive with the Java example and unpack the archive:
```
wget https://api.onlyoffice.com/app_data/editor/Java%20Example.zip
wget https://api.onlyoffice.com/app_data/editor/Java.Example.zip
```
```
unzip Java\ Example.zip
unzip Java.Example.zip
```
3. Change the current directory for the project directory:
@ -162,7 +158,7 @@ See the detailed guide to learn how to [install Document Server for Linux](https
cd Java\ Example/
```
4. Edit the *settings.properties* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed.
4. Edit the *src/main/resources/settings.properties* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed.
```
nano src/main/resources/settings.properties
@ -241,13 +237,39 @@ Make sure that the Document Server has access to the server with the example ins
## For Docker
1. Edit the *settings.properties* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed ([installation instructions](https://helpcenter.onlyoffice.com/installation/docs-developer-install-docker.aspx)).
### Step 1. Install ONLYOFFICE Docs
Download and install ONLYOFFICE Docs (packaged as Document Server).
See the detailed guide to learn how to install Document Server [for Docker](https://helpcenter.onlyoffice.com/installation/docs-developer-install-docker.aspx).
### Step 2. Install the prerequisites and run the website with the editors
1. Install **Java** following the instructions [here](https://docs.oracle.com/en/java/javase/20/install/installation-jdk-linux-platforms.html#GUID-737A84E4-2EFF-4D38-8E60-3E29D1B884B8).
2. Download the archive with the Java example and unpack the archive:
```
wget https://api.onlyoffice.com/app_data/editor/Java.Example.zip
```
```
unzip Java.Example.zip
```
3. Change the current directory for the project directory:
```
cd Java\ Example/
```
4. Edit the *src/main/resources/settings.properties* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed:
```
nano src/main/resources/settings.properties
```
2. Edit the following lines:
5. Edit the following lines:
```
storage-folder = app_data
@ -256,13 +278,19 @@ Make sure that the Document Server has access to the server with the example ins
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-folder** is the path where files will be created and stored.
3. Run the next command in the Java example directory:
6. Run the next command in the Java example directory:
```
docker-compose up
```
4. After it, all the *bin* files will be passed to the *./target* folder.
7. After it, all the *bin* files will be passed to the *./target* folder.
### Step 3. Check accessibility
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## Important security info

View File

@ -27,3 +27,7 @@ License File: jQuery.UI.license
Prime JWT - is intended to be fast and easy to use. Prime JWT has a single external dependency on Jackson. (https://github.com/ws-apps/prime-jwt/blob/master/LICENSE)
License: Apache 2.0
License File: prime-jwt.license
Project Lombok - Spice up your java: Automatic Resource Management, automatic generation of getters, setters, equals, hashCode and toString, and more! (https://projectlombok.org/LICENSE)
License: MIT
License File: lombok.license

View File

@ -0,0 +1,104 @@
Copyright (C) 2009-2021 The Project Lombok Authors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
==============================================================================
Licenses for included components:
org.ow2.asm:asm
org.ow2.asm:asm-analysis
org.ow2.asm:asm-commons
org.ow2.asm:asm-tree
org.ow2.asm:asm-util
ASM: a very small and fast Java bytecode manipulation framework
Copyright (c) 2000-2011 INRIA, France Telecom
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
rzwitserloot/com.zwitserloot.cmdreader
Copyright © 2010 Reinier Zwitserloot.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
------------------------------------------------------------------------------
projectlombok/lombok.patcher
Copyright (C) 2009-2021 The Project Lombok Authors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
------------------------------------------------------------------------------

View File

@ -36,6 +36,12 @@
<artifactId>prime-jwt</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>

View File

@ -62,6 +62,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
@ -132,6 +133,12 @@ public class IndexServlet extends HttpServlet {
case "restore":
restore(request, response, writer);
break;
case "history":
history(request, response, writer);
break;
case "historydata":
historyData(request, response, writer);
break;
default:
break;
}
@ -628,7 +635,7 @@ public class IndexServlet extends HttpServlet {
String newfilename = (String) body.get("newfilename");
String dockey = (String) body.get("dockey");
String origExt = "." + (String) body.get("ext");
String origExt = (String) body.get("ext");
String curExt = newfilename;
if (newfilename.indexOf(".") != -1) {
@ -636,7 +643,7 @@ public class IndexServlet extends HttpServlet {
}
if (origExt.compareTo(curExt) != 0) {
newfilename += origExt;
newfilename += "." + origExt;
}
HashMap<String, String> meta = new HashMap<>();
@ -717,7 +724,11 @@ public class IndexServlet extends HttpServlet {
referenceData.put("fileKey", gson.toJson(fileKey));
HashMap<String, Object> data = new HashMap<>();
data.put("fileType", FileUtility.getFileExtension(fileName).replace(".", ""));
data.put("fileType", FileUtility.getFileExtension(fileName));
data.put("key", ServiceConverter.generateRevisionId(DocumentManager
.curUserHostAddress(null) + "/" + fileName + "/"
+ Long.toString(new File(DocumentManager.storagePath(fileName, null))
.lastModified())));
data.put("url", DocumentManager.getDownloadUrl(fileName, true));
data.put("directUrl", directUrl ? DocumentManager.getDownloadUrl(fileName, false) : null);
data.put("referenceData", referenceData);
@ -798,7 +809,7 @@ public class IndexServlet extends HttpServlet {
bumpedChangesFileWriter.close();
String sourceExtension = FileUtility.getFileExtension(sourceBasename);
String previousBasename = "prev" + sourceExtension;
String previousBasename = "prev." + sourceExtension;
Path bumpedFile = Paths.get(bumpedVersionStringDirectory, previousBasename);
Files.move(sourcePathFile, bumpedFile);
@ -825,6 +836,176 @@ public class IndexServlet extends HttpServlet {
}
}
private static void history(final HttpServletRequest request,
final HttpServletResponse response,
final PrintWriter writer) {
String fileName = FileUtility.getFileName(request.getParameter("filename"));
String path = DocumentManager.storagePath(fileName, null);
JSONParser parser = new JSONParser();
response.setContentType("application/json");
// get history directory
String histDir = DocumentManager.historyDir(path);
if (DocumentManager.getFileVersion(histDir) > 0) {
// get current file version if it is greater than 0
Integer curVer = DocumentManager.getFileVersion(histDir);
List<Object> hist = new ArrayList<>();
Map<String, Object> histData = new HashMap<String, Object>();
for (Integer i = 1; i <= curVer; i++) { // run through all the file versions
Map<String, Object> obj = new HashMap<String, Object>();
String verDir = DocumentManager.versionDir(histDir, i); // get the path to the given file version
try {
String key = null;
// get document key
if (i == curVer) {
key = ServiceConverter.generateRevisionId(
DocumentManager.curUserHostAddress(null) + "/" + fileName + "/"
+ Long.toString(new File(DocumentManager.storagePath(fileName, null))
.lastModified()));
} else {
key = DocumentManager.readFileToEnd(new File(verDir + File.separator + "key.txt"));
}
obj.put("key", key);
obj.put("version", i);
if (i == 1) { // check if the version number is equal to 1
String createdInfo = DocumentManager.readFileToEnd(new File(histDir + File.separator
+ "createdInfo.json")); // get file with meta data
JSONObject json = (JSONObject) parser.parse(createdInfo); // and turn it into json object
// write meta information to the object (user information and creation date)
obj.put("created", json.get("created"));
Map<String, Object> user = new HashMap<String, Object>();
user.put("id", json.get("id"));
user.put("name", json.get("name"));
obj.put("user", user);
}
if (i > 1) { //check if the version number is greater than 1
// if so, get the path to the changes.json file
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);
// write information about changes to the object
obj.put("changes", !change.isEmpty() ? changes.get("changes") : null);
obj.put("serverVersion", changes.get("serverVersion"));
obj.put("created", !change.isEmpty() ? change.get("created") : null);
obj.put("user", !change.isEmpty() ? change.get("user") : null);
}
hist.add(obj);
} catch (Exception ex) { }
}
// write history information about the current file version to the history object
Map<String, Object> histObj = new HashMap<String, Object>();
histObj.put("currentVersion", curVer);
histObj.put("history", hist);
Gson gson = new Gson();
writer.write(gson.toJson(histObj));
return;
}
writer.write("{}");
}
private static void historyData(final HttpServletRequest request,
final HttpServletResponse response,
final PrintWriter writer) {
String fileName = FileUtility.getFileName(request.getParameter("filename"));
String version = request.getParameter("version");
String directUrl = request.getParameter("directUrl");
String path = DocumentManager.storagePath(fileName, null);
response.setContentType("application/json");
// get history directory
String histDir = DocumentManager.historyDir(path);
if (DocumentManager.getFileVersion(histDir) > 0) {
// get current file version if it is greater than 0
Integer curVer = DocumentManager.getFileVersion(histDir);
Map<String, Object> histData = new HashMap<String, Object>();
for (Integer i = 1; i <= curVer; i++) { // run through all the file versions
Map<String, Object> dataObj = new HashMap<String, Object>();
String verDir = DocumentManager.versionDir(histDir, i); // get the path to the given file version
try {
String key = null;
// get document key
if (i == curVer) {
key = ServiceConverter.generateRevisionId(
DocumentManager.curUserHostAddress(null) + "/" + fileName + "/"
+ Long.toString(new File(DocumentManager.storagePath(fileName, null))
.lastModified()));
} else {
key = DocumentManager.readFileToEnd(new File(verDir + File.separator + "key.txt"));
}
dataObj.put("fileType", FileUtility.getFileExtension(fileName));
dataObj.put("key", key);
dataObj.put("url", i == curVer
? DocumentManager.getDownloadUrl(fileName, true)
: DocumentManager.getDownloadHistoryUrl(fileName, i, "prev." + FileUtility
.getFileExtension(fileName), true));
if (directUrl.equals("true")) {
dataObj.put("directUrl", i == curVer
? DocumentManager.getDownloadUrl(fileName, false)
: DocumentManager.getDownloadHistoryUrl(fileName, i, "prev." + FileUtility
.getFileExtension(fileName), false));
}
dataObj.put("version", i);
if (i > 1) { //check if the version number is greater than 1
// get the history data from the previous file version
Map<String, Object> prev = (Map<String, Object>) histData.get(Integer.toString(i - 1));
Map<String, Object> prevInfo = new HashMap<String, Object>();
prevInfo.put("fileType", prev.get("fileType"));
// write key and url information about previous file version
prevInfo.put("key", prev.get("key"));
prevInfo.put("url", prev.get("url"));
if (directUrl.equals("true")) {
prevInfo.put("directUrl", prev.get("directUrl"));
}
// write information about previous file version to the data object
dataObj.put("previous", prevInfo);
// write the path to the diff.zip archive with differences in this file version
Integer verdiff = i - 1;
String changesUrl = DocumentManager
.getDownloadHistoryUrl(fileName, verdiff,
"diff.zip", true);
dataObj.put("changesUrl", changesUrl);
}
if (DocumentManager.tokenEnabled()) {
dataObj.put("token", DocumentManager.createToken(dataObj));
}
histData.put(Integer.toString(i), dataObj);
} catch (Exception ex) { }
}
Gson gson = new Gson();
writer.write(gson.toJson(histData.get(version)));
return;
}
writer.write("{}");
}
// process get request
@Override
protected void doGet(final HttpServletRequest request,

View File

@ -23,12 +23,8 @@ import com.google.gson.reflect.TypeToken;
import helpers.DocumentManager;
import helpers.FileUtility;
import helpers.ServiceConverter;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@ -36,7 +32,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;
public class FileModel {
private String type = "desktop";
@ -68,7 +63,7 @@ public class FileModel {
document.setDirectUrl(isEnableDirectUrl ? DocumentManager.getDownloadUrl(fileName, false) : "");
// get file extension from the file name
document.setFileType(FileUtility.getFileExtension(fileName).replace(".", ""));
document.setFileType(FileUtility.getFileExtension(fileName));
// generate document key
document.setKey(ServiceConverter
.generateRevisionId(DocumentManager
@ -192,128 +187,6 @@ public class FileModel {
token = DocumentManager.createToken(map);
}
// get document history
public String[] getHistory() {
JSONParser parser = new JSONParser();
// get history directory
String histDir = DocumentManager.historyDir(DocumentManager.storagePath(document.getTitle(), null));
if (DocumentManager.getFileVersion(histDir) > 0) {
// get current file version if it is greater than 0
Integer curVer = DocumentManager.getFileVersion(histDir);
List<Object> hist = new ArrayList<>();
Map<String, Object> histData = new HashMap<String, Object>();
for (Integer i = 1; i <= curVer; i++) { // run through all the file versions
Map<String, Object> obj = new HashMap<String, Object>();
Map<String, Object> dataObj = new HashMap<String, Object>();
String verDir = DocumentManager.versionDir(histDir, i); // get the path to the given file version
try {
String key = null;
// get document key
key = i == curVer
? document.getKey() : readFileToEnd(new File(verDir + File.separator + "key.txt"));
obj.put("key", key);
obj.put("version", i);
if (i == 1) { // check if the version number is equal to 1
String createdInfo = readFileToEnd(new File(histDir + File.separator
+ "createdInfo.json")); // get file with meta data
JSONObject json = (JSONObject) parser.parse(createdInfo); // and turn it into json object
// write meta information to the object (user information and creation date)
obj.put("created", json.get("created"));
Map<String, Object> user = new HashMap<String, Object>();
user.put("id", json.get("id"));
user.put("name", json.get("name"));
obj.put("user", user);
}
dataObj.put("fileType", FileUtility.getFileExtension(document.getTitle()).substring(1));
dataObj.put("key", key);
dataObj.put("url", i == curVer ? document.getUrl() : DocumentManager
.getDownloadHistoryUrl(document.getTitle(), i, "prev" + FileUtility
.getFileExtension(document.getTitle()), true));
if (!document.getDirectUrl().equals("")) {
dataObj.put("directUrl", i == curVer ? document.getUrl() : DocumentManager
.getDownloadHistoryUrl(document.getTitle(), i, "prev" + FileUtility
.getFileExtension(document.getTitle()), false));
}
dataObj.put("version", i);
if (i > 1) { //check if the version number is greater than 1
// if so, get the path to the changes.json file
JSONObject changes = (JSONObject) parser.parse(readFileToEnd(new File(DocumentManager
.versionDir(histDir, i - 1) + File.separator + "changes.json")));
JSONObject change = (JSONObject) ((JSONArray) changes.get("changes")).get(0);
// write information about changes to the object
obj.put("changes", !change.isEmpty() ? changes.get("changes") : null);
obj.put("serverVersion", changes.get("serverVersion"));
obj.put("created", !change.isEmpty() ? change.get("created") : null);
obj.put("user", !change.isEmpty() ? change.get("user") : null);
// get the history data from the previous file version
Map<String, Object> prev = (Map<String, Object>) histData.get(Integer.toString(i - 2));
Map<String, Object> prevInfo = new HashMap<String, Object>();
prevInfo.put("fileType", prev.get("fileType"));
// write key and url information about previous file version
prevInfo.put("key", prev.get("key"));
prevInfo.put("url", prev.get("url"));
// write information about previous file version to the data object
dataObj.put("previous", prevInfo);
// write the path to the diff.zip archive with differences in this file version
Integer verdiff = i - 1;
String changesUrl = DocumentManager
.getDownloadHistoryUrl(document.getTitle(), verdiff,
"diff.zip", true);
dataObj.put("changesUrl", changesUrl);
}
if (DocumentManager.tokenEnabled()) {
dataObj.put("token", DocumentManager.createToken(dataObj));
}
hist.add(obj);
histData.put(Integer.toString(i - 1), dataObj);
} catch (Exception ex) { }
}
// write history information about the current file version to the history object
Map<String, Object> histObj = new HashMap<String, Object>();
histObj.put("currentVersion", curVer);
histObj.put("history", hist);
Gson gson = new Gson();
return new String[] {gson.toJson(histObj), gson.toJson(histData) };
}
return new String[] {"", "" };
}
// read a file
private String readFileToEnd(final File file) {
String output = "";
try {
try (FileInputStream is = new FileInputStream(file)) {
Scanner scanner = new Scanner(is); // read data from the source
scanner.useDelimiter("\\A");
while (scanner.hasNext()) {
output += scanner.next();
}
scanner.close();
}
} catch (Exception e) { }
return output;
}
// the document parameters
public class Document {
private String title;

View File

@ -18,8 +18,17 @@
package entities;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.annotations.SerializedName;
public enum FileType {
Word,
Cell,
Slide
@JsonProperty("word")
@SerializedName("word")
WORD,
@JsonProperty("cell")
@SerializedName("cell")
CELL,
@JsonProperty("slide")
@SerializedName("slide")
SLIDE
}

View File

@ -0,0 +1,39 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package format;
import java.util.List;
import entities.FileType;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public final class Format {
private String name;
private FileType type;
private List<String> actions;
private List<String> convert;
private List<String> mime;
}

View File

@ -0,0 +1,119 @@
/**
*
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package format;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public final class FormatManager {
private List<Format> formats;
public FormatManager() {
formats = this.all();
}
public List<Format> getFormats() {
return this.formats;
}
public List<Format> getFormatsByAction(final String action) {
return this
.all()
.stream()
.filter(format -> format.getActions().contains(action))
.collect(Collectors.toList());
}
public List<String> allExtensions() {
return this
.formats
.stream()
.map(format -> format.getName())
.collect(Collectors.toList());
}
public List<String> fillableExtensions() {
return this
.getFormatsByAction("fill")
.stream()
.map(format -> format.getName())
.collect(Collectors.toList());
}
public List<String> viewableExtensions() {
return this
.getFormatsByAction("view")
.stream()
.map(format -> format.getName())
.collect(Collectors.toList());
}
public List<String> editableExtensions() {
return Stream.of(this.getFormatsByAction("edit"), this.getFormatsByAction("lossy-edit"))
.flatMap(x -> x.stream())
.map(format -> format.getName())
.collect(Collectors.toList());
}
public List<String> autoConvertExtensions() {
return this
.getFormatsByAction("auto-convert")
.stream()
.map(format -> format.getName())
.collect(Collectors.toList());
}
private List<Format> all() {
try {
ObjectMapper objectMapper = new ObjectMapper();
Path path = this.file();
return objectMapper.readValue(Files.readAllBytes(path), new TypeReference<List<Format>>() { });
} catch (Exception e) {
e.printStackTrace();
}
return new ArrayList<>();
}
private Path file() throws URISyntaxException {
return this
.directory()
.resolve("onlyoffice-docs-formats.json");
}
private Path directory() throws URISyntaxException {
URI uri = Thread
.currentThread()
.getContextClassLoader()
.getResource("assets/document-formats")
.toURI();
return Paths.get(uri);
}
}

View File

@ -20,6 +20,8 @@ package helpers;
import entities.FileType;
import entities.User;
import format.FormatManager;
import org.json.simple.JSONObject;
import org.primeframework.jwt.Signer;
import org.primeframework.jwt.Verifier;
@ -31,6 +33,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
@ -50,12 +53,14 @@ import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import static utils.Constants.KILOBYTE_SIZE;
import static utils.Constants.MAX_FILE_SIZE;
public final class DocumentManager {
private static HttpServletRequest request;
private static FormatManager formatManager = new FormatManager();
private DocumentManager() { }
@ -78,37 +83,26 @@ public final class DocumentManager {
// get all the supported file extensions
public static List<String> getFileExts() {
List<String> res = new ArrayList<>();
res.addAll(getViewedExts());
res.addAll(getEditedExts());
res.addAll(getConvertExts());
res.addAll(getFillExts());
return res;
return DocumentManager.formatManager.allExtensions();
}
public static List<String> getFillExts() {
String exts = ConfigManager.getProperty("files.docservice.fill-docs");
return Arrays.asList(exts.split("\\|"));
return DocumentManager.formatManager.fillableExtensions();
}
// get file extensions that can be viewed
public static List<String> getViewedExts() {
String exts = ConfigManager.getProperty("files.docservice.viewed-docs");
return Arrays.asList(exts.split("\\|"));
return DocumentManager.formatManager.viewableExtensions();
}
// get file extensions that can be edited
public static List<String> getEditedExts() {
String exts = ConfigManager.getProperty("files.docservice.edited-docs");
return Arrays.asList(exts.split("\\|"));
return DocumentManager.formatManager.editableExtensions();
}
// get file extensions that can be converted
public static List<String> getConvertExts() {
String exts = ConfigManager.getProperty("files.docservice.convert-docs");
return Arrays.asList(exts.split("\\|"));
return DocumentManager.formatManager.autoConvertExtensions();
}
// get current user host address
@ -254,12 +248,12 @@ public final class DocumentManager {
public static String getCorrectName(final String fileName, final String userAddress) {
String baseName = FileUtility.getFileNameWithoutExtension(fileName);
String ext = FileUtility.getFileExtension(fileName);
String name = baseName + ext;
String name = baseName + "." + ext;
File file = new File(storagePath(name, userAddress));
for (int i = 1; file.exists(); i++) { // run through all the files with such a name in the storage directory
name = baseName + " (" + i + ")" + ext; // and add an index to the base name
name = baseName + " (" + i + ")." + ext; // and add an index to the base name
file = new File(storagePath(name, userAddress));
}
@ -496,17 +490,17 @@ public final class DocumentManager {
// get an editor internal extension
public static String getInternalExtension(final FileType fileType) {
// .docx for word file type
if (fileType.equals(FileType.Word)) {
if (fileType.equals(FileType.WORD)) {
return ".docx";
}
// .xlsx for cell file type
if (fileType.equals(FileType.Cell)) {
if (fileType.equals(FileType.CELL)) {
return ".xlsx";
}
// .pptx for slide file type
if (fileType.equals(FileType.Slide)) {
if (fileType.equals(FileType.SLIDE)) {
return ".pptx";
}
@ -518,17 +512,17 @@ public final class DocumentManager {
public static String getTemplateImageUrl(final FileType fileType) {
String path = getServerUrl(true) + "/css/img/";
// for word file type
if (fileType.equals(FileType.Word)) {
if (fileType.equals(FileType.WORD)) {
return path + "file_docx.svg";
}
// .xlsx for cell file type
if (fileType.equals(FileType.Cell)) {
if (fileType.equals(FileType.CELL)) {
return path + "file_xlsx.svg";
}
// .pptx for slide file type
if (fileType.equals(FileType.Slide)) {
if (fileType.equals(FileType.SLIDE)) {
return path + "file_pptx.svg";
}
@ -599,4 +593,19 @@ public final class DocumentManager {
});
return languages;
}
public static String readFileToEnd(final File file) {
String output = "";
try {
try (FileInputStream is = new FileInputStream(file)) {
Scanner scanner = new Scanner(is); // read data from the source
scanner.useDelimiter("\\A");
while (scanner.hasNext()) {
output += scanner.next();
}
scanner.close();
}
} catch (Exception e) { }
return output;
}
}

View File

@ -19,64 +19,34 @@
package helpers;
import entities.FileType;
import format.Format;
import format.FormatManager;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class FileUtility {
private static FormatManager formatManager = new FormatManager();
private FileUtility() { }
// get file type
public static FileType getFileType(final String fileName) {
String ext = getFileExtension(fileName).toLowerCase();
List<Format> formats = FileUtility.formatManager.getFormats();
// word type for document extensions
if (extsDocument.contains(ext)) {
return FileType.Word;
}
// cell type for spreadsheet extensions
if (extsSpreadsheet.contains(ext)) {
return FileType.Cell;
}
// slide type for presentation extensions
if (extsPresentation.contains(ext)) {
return FileType.Slide;
for (Format format : formats) {
if (format.getName().equals(ext)) {
return format.getType();
}
}
// default file type is word
return FileType.Word;
return FileType.WORD;
}
// document extensions
private static List<String> extsDocument = Arrays.asList(
".doc", ".docx", ".docm",
".dot", ".dotx", ".dotm",
".odt", ".fodt", ".ott", ".rtf", ".txt",
".html", ".htm", ".mht", ".xml",
".pdf", ".djvu", ".fb2", ".epub", ".xps", ".oxps", ".oform"
);
// spreadsheet extensions
private static List<String> extsSpreadsheet = Arrays.asList(
".xls", ".xlsx", ".xlsm", ".xlsb",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv"
);
// presentation extensions
private static List<String> extsPresentation = Arrays.asList(
".pps", ".ppsx", ".ppsm",
".ppt", ".pptx", ".pptm",
".pot", ".potx", ".potm",
".odp", ".fodp", ".otp"
);
// get file name from the url
public static String getFileName(final String url) {
if (url == null) {
@ -105,7 +75,7 @@ public final class FileUtility {
if (fileName == null) {
return null;
}
String fileExt = fileName.substring(fileName.lastIndexOf("."));
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1);
return fileExt.toLowerCase();
}

View File

@ -158,8 +158,8 @@ public final class ServiceConverter {
ConvertBody body = new ConvertBody();
body.setRegion(lang);
body.setUrl(documentUri);
body.setOutputtype(toExtension.replace(".", ""));
body.setFiletype(fromExt.replace(".", ""));
body.setOutputtype(toExtension);
body.setFiletype(fromExt);
body.setTitle(title);
body.setKey(documentRevId);
body.setPassword(filePass);

View File

@ -150,7 +150,7 @@ public final class TrackManager {
String newFileName = fileName;
String curExt = FileUtility.getFileExtension(fileName); // get current file extension
String downloadExt = "." + (String) body.get("filetype"); // get the extension of the downloaded file
String downloadExt = (String) body.get("filetype"); // get the extension of the downloaded file
// convert downloaded file to the file with the current extension if these extensions aren't equal
if (!curExt.equals(downloadExt)) {
@ -164,13 +164,13 @@ public final class TrackManager {
// get the correct file name if it already exists
newFileName = DocumentManager
.getCorrectName(FileUtility
.getFileNameWithoutExtension(fileName) + downloadExt, userAddress);
.getFileNameWithoutExtension(fileName) + "." + downloadExt, userAddress);
} else {
downloadUri = newFileUri;
}
} catch (Exception e) {
newFileName = DocumentManager.getCorrectName(FileUtility
.getFileNameWithoutExtension(fileName) + downloadExt, userAddress);
.getFileNameWithoutExtension(fileName) + "." + downloadExt, userAddress);
}
}
@ -193,7 +193,7 @@ public final class TrackManager {
}
// get the path to the previous file version and rename the last file version with it
lastVersion.renameTo(new File(versionDir + File.separator + "prev" + curExt));
lastVersion.renameTo(new File(versionDir + File.separator + "prev." + curExt));
saveFile(byteArrayFile, toSave); // save document file
@ -236,7 +236,7 @@ public final class TrackManager {
String downloadUri = (String) body.get("url");
String curExt = FileUtility.getFileExtension(fileName); // get current file extension
String downloadExt = "." + (String) body.get("filetype"); // get the extension of the downloaded file
String downloadExt = (String) body.get("filetype"); // get the extension of the downloaded file
Boolean newFileName = false;
@ -265,10 +265,10 @@ public final class TrackManager {
// new file
if (newFileName) {
fileName = DocumentManager.getCorrectName(FileUtility.getFileNameWithoutExtension(fileName)
+ "-form" + downloadExt, userAddress); // get the correct file name if it already exists
+ "-form." + downloadExt, userAddress); // get the correct file name if it already exists
} else {
fileName = DocumentManager.getCorrectName(FileUtility.getFileNameWithoutExtension(fileName)
+ "-form" + curExt, userAddress);
+ "-form." + curExt, userAddress);
}
forcesavePath = DocumentManager.storagePath(fileName, userAddress);
} else {

View File

@ -1,12 +1,8 @@
version=1.7.0
version=1.6.0
filesize-max=5242880
storage-folder=app_data
files.docservice.fill-docs=.docx|.oform
files.docservice.viewed-docs=.djvu|.oxps|.pdf|.xps
files.docservice.edited-docs=.csv|.docm|.docx|.docxf|.dotm|.dotx|.epub|.fb2|.html|.odp|.ods|.odt|.otp|.ots|.ott|.potm|.potx|.ppsm|.ppsx|.pptm|.pptx|.rtf|.txt|.xlsm|.xlsx|.xltm|.xltx
files.docservice.convert-docs=.doc|.dot|.dps|.dpt|.epub|.et|.ett|.fb2|.fodp|.fods|.fodt|.htm|.html|.mht|.mhtml|.odp|.ods|.odt|.otp|.ots|.ott|.pot|.pps|.ppt|.rtf|.stw|.sxc|.sxi|.sxw|.wps|.wpt|.xls|.xlsb|.xlt|.xml
files.docservice.timeout=120000
files.docservice.url.site=http://documentserver/

View File

@ -1,8 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H21.674C22.4697 0 23.2327 0.316071 23.7953 0.87868L29.1213 6.20465C29.6839 6.76726 30 7.53032 30 8.32597V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#3779A6"/>
<path d="M22.9167 0L30.0001 7.08333H25.9167C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#1D5880"/>
<path d="M6.17627 14.7059H23.8233V15.8823H6.17627V14.7059Z" fill="white"/>
<path d="M6.17627 18.5294H23.8233V19.7059H6.17627V18.5294Z" fill="white"/>
<path d="M6.17627 22.3529H23.8233V23.5294H6.17627V22.3529Z" fill="white"/>
<path d="M6.17627 26.1765H23.8233V27.3529H6.17627V26.1765Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#1E7AAA"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path d="M6 15h18v1H6v-1zM6 19h18v1H6v-1zM6 23h18v1H6v-1zM6 27h18v1H6v-1z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 387 B

View File

@ -1,6 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#27ABA3"/>
<path d="M22.9165 0L29.9998 7.08333H25.9165C24.2597 7.08333 22.9165 5.74019 22.9165 4.08333V0Z" fill="#008078"/>
<rect x="6.5" y="15.5" width="17" height="5" stroke="white"/>
<rect x="6.5" y="23.5" width="17" height="5" stroke="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#27ABA3"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#008078"/><path fill-rule="evenodd" clip-rule="evenodd" d="M24 14H6v7h18v-7zm-.8182 5.9978H6.81818V15H23.1818v4.9978zM24 23H6v7h18v-7zm-.8182 5.9978H6.81818V24H23.1818v4.9978z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 463 B

View File

@ -1,8 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#F36700"/>
<path d="M22.9167 0L30.0001 7.08333H25.9168C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#AB531F"/>
<path d="M6.17627 16.1275H23.8233V17.3039H6.17627V16.1275Z" fill="white"/>
<path d="M6.17627 28.7745L6.17627 16.1275L7.35274 16.1275L7.35274 28.7745H6.17627Z" fill="white"/>
<path d="M23.8233 16.1275V28.7745H22.6469V16.1275L23.8233 16.1275Z" fill="white"/>
<path d="M6.17627 27.598H23.8233V28.7745H6.17627L6.17627 27.598Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#F36700"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path stroke="#fff" stroke-opacity=".95" d="M6.5 15.5h17v12h-17z"/></svg>

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 366 B

View File

@ -1,6 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 7.44186L22 0H3C1.22739 0 0 0.822551 0 2.32558V37.2093C0 38.7123 1.22739 40 3 40H27C28.7726 40 30 38.7123 30 37.2093V7.44186Z" fill="#D0D5DA"/>
<path d="M24.1042 7.27273H29.9631L22 0V5.32334C22 6.4105 22.949 7.27273 24.1042 7.27273Z" fill="#646464"/>
<path d="M16.9562 22.3485H12.9746V17.803H10.9839L14.9654 14.1667L18.947 17.803H16.9562V22.3485Z" fill="#646464"/>
<path d="M20.9378 23.7121C20.9378 24.1666 20.4401 24.6212 19.9424 24.6212H9.98848C9.49078 24.6212 8.99309 24.1666 8.99309 23.7121V22.3485C8.99309 21.8939 9.49078 21.4394 9.98848 21.4394H10.9839V20.0757H9.49078C8.49539 20.0757 7.5 20.9848 7.5 21.8939V24.1666C7.5 25.0757 8.61982 25.9848 9.49078 25.9848H20.4401C21.3111 25.9848 22.4309 25.0757 22.4309 24.1666V21.8939C22.4309 20.9848 21.4355 20.0757 20.4401 20.0757H18.947V21.4394H19.9424C20.4401 21.4394 20.9378 21.8939 20.9378 22.3485V23.7121Z" fill="#646464"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#D0D5DA"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#646464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 23c-.27614 0-.5.2239-.5.5v4c0 .2761.22386.5.5.5h15c.2761 0 .5-.2239.5-.5v-4c0-.2761-.2239-.5-.5-.5h-2c-.2761 0-.5-.2239-.5-.5s.2239-.5.5-.5h2c.8284 0 1.5.6716 1.5 1.5v4c0 .8284-.6716 1.5-1.5 1.5h-15c-.82843 0-1.5-.6716-1.5-1.5v-4c0-.8284.67157-1.5 1.5-1.5h2c.27614 0 .5.2239.5.5s-.22386.5-.5.5h-2z" fill="#646464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M20 20.0001L15 14l-5 6.0001h3v4c0 .5523.4477 1 1 1h2c.5523 0 1-.4477 1-1v-4h3z" fill="#646464"/></svg>

Before

Width:  |  Height:  |  Size: 992 B

After

Width:  |  Height:  |  Size: 797 B

View File

@ -1,12 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#78A73B"/>
<path d="M22.9167 0L30.0001 7.08333H25.9168C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#5A7D2B"/>
<path d="M6.17644 15.2941H23.8235V16.4706H6.17644V15.2941Z" fill="white"/>
<path d="M6.17644 19.1177H23.8235V20.2941H6.17644V19.1177Z" fill="white"/>
<path d="M6.17644 22.9412H23.8235V24.1177H6.17644V22.9412Z" fill="white"/>
<path d="M6.17644 26.7647H23.8235V27.9412H6.17644V26.7647Z" fill="white"/>
<path d="M5.88232 27.9412L5.88232 15.2941L7.0588 15.2941L7.0588 27.9412H5.88232Z" fill="white"/>
<path d="M11.4706 27.9412L11.4706 15.2941L12.647 15.2941V27.9412H11.4706Z" fill="white"/>
<path d="M17.0588 27.9412L17.0588 15.2941L18.2353 15.2941V27.9412H17.0588Z" fill="white"/>
<path d="M22.647 27.9412V15.2941H23.8235V27.9412H22.647Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#6AAA1E"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path fill-rule="evenodd" clip-rule="evenodd" d="M6 15h18v13H7.00001v-1H12v-3H7v4H6V15zm7 12h4v-3h-4v3zm5 0h5v-3h-5v3zm5-7v3h-5v-3h5zm-6 0v3h-4v-3h4zm-5 0v3H7v-3h5zm11-1v-3h-5v3h5zm-10-3h4v3h-4v-3zm-1 3v-3H7v3h5z" fill="#fff" fill-opacity=".95"/></svg>

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 545 B

View File

@ -184,15 +184,54 @@
request.open('PUT', 'IndexServlet?type=restore')
request.send(JSON.stringify(payload))
request.onload = function () {
if (request.status != 200) {
response = JSON.parse(request.response)
innerAlert(response.error)
return
const response = JSON.parse(request.responseText);
if (response.success && !response.error) {
var historyInfoUri = "IndexServlet?type=history&filename=" + config.document.title;
var xhr = new XMLHttpRequest();
xhr.open("GET", historyInfoUri, false);
xhr.send();
if (xhr.status == 200) {
var historyInfo = JSON.parse(xhr.responseText);
docEditor.refreshHistory(historyInfo);
}
} else {
innerAlert(response.error);
}
document.location.reload()
}
}
var onRequestHistory = function () {
var historyInfoUri = "IndexServlet?type=history&filename=" + config.document.title;
var xhr = new XMLHttpRequest();
xhr.open("GET", historyInfoUri, false);
xhr.send();
if (xhr.status == 200) {
var historyInfo = JSON.parse(xhr.responseText);
docEditor.refreshHistory(historyInfo);
}
};
var onRequestHistoryData = function (event) {
var version = event.data;
var historyDataUri = "IndexServlet?type=historyData&filename=" + config.document.title
+ "&version=" + version
+ "&directUrl=" + !!config.document.directUrl;
var xhr = new XMLHttpRequest();
xhr.open("GET", historyDataUri, false);
xhr.send();
if (xhr.status == 200) {
var historyData = JSON.parse(xhr.responseText);
docEditor.setHistoryData(historyData);
}
};
var onRequestHistoryClose = function() {
document.location.reload();
};
config = JSON.parse('<%= FileModel.serialize(Model) %>');
config.width = "100%";
config.height = "100%";
@ -206,33 +245,17 @@
"onRequestInsertImage": onRequestInsertImage,
"onRequestCompareFile": onRequestCompareFile,
"onRequestMailMergeRecipients": onRequestMailMergeRecipients,
"onRequestRestore": onRequestRestore
"onRequestRestore": onRequestRestore,
"onRequestHistory": onRequestHistory,
"onRequestHistoryData": onRequestHistoryData,
"onRequestHistoryClose": onRequestHistoryClose
};
<%
String[] histArray = Model.getHistory();
String history = histArray[0];
String historyData = histArray[1];
String usersForMentions = (String) request.getAttribute("usersForMentions");
%>
if (config.editorConfig.user.id) {
<% if (!history.isEmpty() && !historyData.isEmpty()) { %>
// the user is trying to show the document version history
config.events['onRequestHistory'] = function () {
docEditor.refreshHistory(<%= history %>); // show the document version history
};
// the user is trying to click the specific document version in the document version history
config.events['onRequestHistoryData'] = function (event) {
var ver = event.data;
var histData = <%= historyData %>;
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
};
// the user is trying to go back to the document from viewing the document version history
config.events['onRequestHistoryClose'] = function () {
document.location.reload();
};
<% } %>
// add mentions for not anonymous users
config.events['onRequestUsers'] = function () {
docEditor.setUsers({ // set a list of users to mention in the comments

View File

@ -367,9 +367,9 @@
<script type="text/javascript" src="scripts/jscript.js"></script>
<script language="javascript" type="text/javascript">
var FillExtList = "<%= String.join(",", DocumentManager.getFillExts()) %>";
var ConverExtList = "<%= String.join(",", DocumentManager.getConvertExts()) %>";
var EditedExtList = "<%= String.join(",", DocumentManager.getEditedExts()) %>";
var FillExtList = "<%= String.join(",", DocumentManager.getFillExts()) %>".split(",");
var ConverExtList = "<%= String.join(",", DocumentManager.getConvertExts()) %>".split(",");
var EditedExtList = "<%= String.join(",", DocumentManager.getEditedExts()) %>".split(",");
var UrlConverter = "IndexServlet?type=convert";
var UrlEditor = "EditorServlet";

View File

@ -100,10 +100,10 @@ if (typeof jQuery !== "undefined") {
jq("#filePass").val("");
var fileName = jq("#hiddenFileName").val();
var posExt = fileName.lastIndexOf(".");
var posExt = fileName.lastIndexOf(".") + 1;
posExt = 0 <= posExt ? fileName.substring(posExt).trim().toLowerCase() : "";
if (ConverExtList.indexOf(posExt) === -1) {
if (!ConverExtList.includes(posExt)) {
jq("#step2").addClass("done").removeClass("current");
loadScripts();
return;
@ -177,10 +177,10 @@ if (typeof jQuery !== "undefined") {
jq("#beginView, #beginEmbedded").removeClass("disable");
var fileName = jq("#hiddenFileName").val();
var posExt = fileName.lastIndexOf(".");
var posExt = fileName.lastIndexOf(".") + 1;
posExt = 0 <= posExt ? fileName.substring(posExt).trim().toLowerCase() : "";
if (EditedExtList.indexOf(posExt) !== -1 || FillExtList.indexOf(posExt) !== -1) {
if (EditedExtList.includes(posExt) || FillExtList.includes(posExt)) {
jq("#beginEdit").removeClass("disable");
}
};

View File

@ -91,11 +91,11 @@ See the detailed guide to learn how to [install Document Server for Linux](https
2. Download the archive with the Node.js example and unpack it:
```
wget https://api.onlyoffice.com/app_data/editor/Node.js%20Example.zip
wget https://api.onlyoffice.com/app_data/editor/Node.js.Example.zip
```
```
unzip Node.js\ Example.zip
unzip Node.js.Example.zip
```
3. Change the current directory for the project directory:
@ -110,7 +110,7 @@ See the detailed guide to learn how to [install Document Server for Linux](https
npm install
```
5. Edit the *default.json* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed.
5. Edit the *config/default.json* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed.
```
nano config/default.json

View File

@ -27,6 +27,7 @@ const jwt = require('jsonwebtoken');
const config = require('config');
const mime = require('mime');
const urllib = require('urllib');
const urlModule = require('url');
const { emitWarning } = require('process');
const DocManager = require('./helpers/docManager');
const documentService = require('./helpers/documentService');
@ -81,14 +82,6 @@ app.use((req, res, next) => {
});
app.use(express.static(path.join(__dirname, 'public'))); // public directory
// check if there are static files such as .js, .css files, images, samples and process them
if (config.has('server.static')) {
const staticContent = config.get('server.static');
for (let i = 0; i < staticContent.length; i++) {
const staticContentElem = staticContent[i];
app.use(staticContentElem.name, express.static(staticContentElem.path, staticContentElem.options));
}
}
app.use(favicon(`${__dirname}/public/images/favicon.ico`)); // use favicon
app.use(bodyParser.json()); // connect middleware that parses json
@ -506,6 +499,20 @@ app.post('/reference', (req, res) => { // define a handler for renaming file
}
}
if (!fileName && !!req.body.link) {
if (req.body.link.indexOf(req.DocManager.curUserHostAddress()) !== -1) {
result({ error: 'You do not have access to this site' });
return;
}
const urlObj = urlModule.parse(req.body.link, true);
fileName = urlObj.query.fileName;
if (!req.DocManager.existsSync(req.DocManager.storagePath(fileName, userAddress))) {
result({ error: 'File is not exist' });
return;
}
}
if (!fileName && !!req.body.path) {
const filePath = fileUtility.getFileName(req.body.path);

View File

@ -1,5 +1,5 @@
{
"version": "1.7.0",
"version": "1.6.0",
"log": {
"appenders": [
{
@ -26,12 +26,6 @@
"storagePath": "/files",
"maxFileSize": 1073741824,
"mobileRegEx": "android|avantgo|playbook|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino",
"static":[
{
"name": "/files",
"path": "./files"
}
],
"token": {
"enable": false,
"useforrequest": true,

View File

@ -2,12 +2,6 @@
"server": {
"siteUrl": "/",
"maxFileSize": 104857600,
"storageFolder": "/var/lib/onlyoffice/documentserver-example/files",
"static":[
{
"name": "/files",
"path": "/var/lib/onlyoffice/documentserver-example/files"
}
]
"storageFolder": "/var/lib/onlyoffice/documentserver-example/files"
}
}

View File

@ -1,13 +1,6 @@
{
"server": {
"siteUrl": "/",
"maxFileSize": 104857600,
"static":[
{
"name": "/files",
"path": "./files",
"options": {"maxAge": "7d"}
}
]
"maxFileSize": 104857600
}
}

View File

@ -152,7 +152,7 @@ DocManager.prototype.saveFileData = function saveFileData(fileName, userid, user
// get full creation date of the document
const dateCreate = fileSystem.statSync(this.storagePath(fileName, address)).mtime;
const minutes = (dateCreate.getMinutes() < 10 ? '0' : '') + dateCreate.getMinutes().toString();
const month = (dateCreate.getMonth() < 9 ? '0' : '') + (parseInt(dateCreate.getMonth().toString(), 10) + 1);
const month = (dateCreate.getMonth() < 10 ? '0' : '') + (parseInt(dateCreate.getMonth().toString(), 10) + 1);
const sec = (dateCreate.getSeconds() < 10 ? '0' : '') + dateCreate.getSeconds().toString();
const dateFormat = `${dateCreate.getFullYear()}-${month}-${dateCreate.getDate()} `
+ `${dateCreate.getHours()}:${minutes}:${sec}`;
@ -534,7 +534,7 @@ DocManager.prototype.getHistory = function getHistory(fileName, content, keyVers
if (content && contentJson) {
userNameFromJson = oldVersion ? contentJson.username : contentJson.user.name;
userIdFromJson = oldVersion ? contentJson.userid : contentJson.user.id;
userIdFromJson = oldVersion ? contentJson.userid : contentJson.user.userid;
createdFromJson = oldVersion ? contentJson.date : contentJson.created;
}

View File

@ -1,85 +1,212 @@
## Overview
This example will help you integrate ONLYOFFICE Docs into your web application written on PHP.
This example will help you integrate ONLYOFFICE Docs into your web application written in PHP.
> [!WARNING]
> It is intended for testing purposes and demonstrating functionality of the editors. **DO NOT** use this integration example on your own server without proper code modifications. In case you enabled the test example, disable it before going for production.
**Please note**: It is intended for testing purposes and demonstrating functionality of the editors. Do NOT use this integration example on your own server without proper code modifications! In case you enabled the test example, disable it before going for production.
## Installation
## For Windows
The PHP example offers various installation options, but we highly recommend using Docker for this purpose.
### Step 1. Install ONLYOFFICE Docs
### Using Docker
Download and install ONLYOFFICE Docs (packaged as Document Server).
To run the example using [Docker](https://docker.com), you will need [Docker Desktop 4.17.0](https://docs.docker.com/desktop) or [Docker Engine 20.10.23](https://docs.docker.com/engine) with [Docker Compose 2.15.1](https://docs.docker.com/compose). Additionally, you might want to consider installing [GNU Make 4.4.1](https://gnu.org/software/make), although it is optional. These are the minimum versions required for the tools.
See the detailed guide to learn how to [install Document Server for Windows](https://helpcenter.onlyoffice.com/installation/docs-developer-install-windows.aspx?from=api_php_example).
Once you have everything installed, download the release archive and unarchive it.
### Step 2. Download the PHP code for the editors integration
```sh
$ curl --output PHP.Example.zip --location https://github.com/ONLYOFFICE/document-server-integration/releases/latest/download/PHP.Example.zip
$ unzip PHP.Example.zip
Download the [PHP example](https://api.onlyoffice.com/editors/demopreview) from our site.
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *config.json* file:
```
"storagePath" = "";
"docServSiteUrl" = "https://documentserver/";
```
Then open the example directory and [up containers](./Makefile#L60).
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storagePath** is the path where files will be created and stored. You can set an absolute path. For example, *D:\\\\folder*. Please note that on Windows OS the double backslash must be used as a separator.
```sh
$ cd "PHP Example"
$ make compose-prod
```
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) in the *doceditor.php* file.
By default, the server starts at `localhost:80`.
### Step 3. Install the prerequisites
To configure the example, you can edit the environment variables in [`docker-compose.yml`](./docker-compose.yml). See [below](#configuration) for more information about environment variables.
You can use any web server capable of running PHP code to run the example. We will demonstrate how to run the PHP example using the **Internet Information Services (IIS)** web server. To set up and configure PHP on IIS, **PHP Manager for IIS** will be used.
### On Local Machine
* **IIS**: version 7 or later (refer to [Microsoft official website](https://www.iis.net/learn/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php) to learn how to install IIS);
* **PHP** (download it from the [http://php.net](https://php.net/downloads.php) site);
* **PHP Manager for IIS** (download it from the [Microsoft open source site](https://phpmanager.codeplex.com/releases/view/69115)).
* **Composer** (download it from the [Composer official website](https://getcomposer.org/download/)).
Before diving into the example, you will need to install ONLYOFFICE Document Server (also known as Docs). Check the detailed guide to learn how to install it on [Windows](https://helpcenter.onlyoffice.com/installation/docs-developer-install-windows.aspx), [Linux](https://helpcenter.onlyoffice.com/installation/docs-developer-install-ubuntu.aspx), or [Docker](https://helpcenter.onlyoffice.com/installation/docs-developer-install-docker.aspx).
### Step 4. IIS configuration
To run the example on your local machine, you will need [PHP 8.2.11](https://php.net) with [Composer 2.6.5](https://getcomposer.org). Additionally, you might want to consider installing [GNU Make 4.4.1](https://gnu.org/software/make), although it is optional. These are the minimum versions required for the tools.
1. **PHP Manager for IIS** configuration.
Once you have everything installed, download the release archive and unarchive it.
After PHP Manager for IIS installation is complete, launch the **IIS Manager:**
```sh
$ curl --output PHP.Example.zip --location https://github.com/ONLYOFFICE/document-server-integration/releases/latest/download/PHP.Example.zip
$ unzip PHP.Example.zip
```
**Start** -> **Control Panel** -> **System and Security** -> **Administrative Tools** -> **Internet Information Services (IIS) Manager**
Then open the example directory, [install dependencies](./Makefile#L16), and [start the server](./Makefile#L40).
and find the **PHP Manager** feature in the **Features View** in IIS.
```sh
$ cd "PHP Example"
$ make prod
$ make server-prod
```
![manager](screenshots/manager.png)
By default, the server starts at `0.0.0.0:9000`.
You need to register the installed PHP version in IIS using PHP Manager.
To configure the example, you can pass the environment variables before the command that starts the server. See [below](#configuration) for more information about environment variables.
Double-click **PHP Manager** to open it, click the **Register new PHP version** task and specify the full path to the main PHP executable file location. For example: *C:\Program Files\PHP\php-cgi.exe*.
## Post Installation
![php-version-1](screenshots/php-version-1.jpg)
After clicking **OK**, the new **PHP version** will be registered with IIS and will become active.
![php-version-2](screenshots/php-version-2.jpg)
2. Configure IIS to handle PHP requests.
For IIS to host PHP applications, you must add handler mapping that tells IIS to pass all the PHP-specific requests to the PHP application framework by using the **FastCGI** protocol.
Double-click the **Handler Mappings** feature:
![handlerclick](screenshots/handlerclick.png)
In the **Action** panel, click **Add Module Mapping**. In the **Add Module Mapping** dialog box, specify the configuration settings as follows:
* **Request path**: *.php,
* **Module**: FastCgiModule,
* **Executable**: "C:\[Path to your PHP installation]\php-cgi.exe",
* **Name**: PHP via FastCGI.
Click **OK**.
![handler-add](screenshots/handler-add.png)
After IIS manager configuration is complete, everything is ready for running the PHP example.
### Step 5. Run *composer install*:
```
php composer.phar install
```
### Step 6. Run your website with the editors
1. Add your website in the IIS Manager.
On the **Connections** panel right-click the **Sites** node in the tree, then click **Add Website**.
![add](screenshots/add.png)
2. In the **Add Website** dialog box, specify the name of the folder with the PHP project in the **Site name** box.
Specify the path to the folder with your project in the **Physical path** box.
Specify the unique value used only for this website in the **Port** box.
![php-add](screenshots/php-add.png)
3. Browse your website with the IIS manager:
Right-click the site -> **Manage Website** -> **Browse**
![browse](screenshots/browse.png)
### Step 7. Check accessibility
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## Configuration
## For Linux
The example is configured by changing environment variables.
### Step 1. Install ONLYOFFICE Docs
| Name | Description | Example |
| ----------------------------- | ----------------------------------------------------------------------- | ----------------------- |
| `ADDRESS` | The address where the server should be started. | `0.0.0.0` |
| `PORT` | The port on which the server should be running. | `80` |
| `DOCUMENT_SERVER_PRIVATE_URL` | The URL through which the server will communicate with Document Server. | `http://proxy:8080` |
| `DOCUMENT_SERVER_PUBLIC_URL` | The URL through which a user will communicate with Document Server. | `http://localhost:8080` |
| `EXAMPLE_URL` | The URL through which Document Server will communicate with the server. | `http://proxy` |
| `JWT_SECRET` | JWT authorization secret. Leave blank to disable authorization. | `your-256-bit-secret` |
Download and install ONLYOFFICE Docs (packaged as Document Server).
## Security Info
See the detailed guide to learn how to [install Document Server for Linux](https://helpcenter.onlyoffice.com/installation/docs-developer-install-ubuntu.aspx?from=api_php_example).
### Step 2. Install the prerequisites and run the website with the editors
1. Install **Apache** and **PHP**:
```
apt-get install -y apache2 php7.0 libapache2-mod-php7.0
```
2. Install **Composer**:
To install composer globally, use the following command which will download and install Composer as a system-wide command named composer, under /usr/local/bin:
```
curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
```
3. Download the archive with the PHP example and unpack the archive:
```
cd /var/www/html
```
```
wget https://api.onlyoffice.com/app_data/editor/PHP.Example.zip
```
```
unzip PHP.Example.zip
```
4. Change the current directory for the project directory:
```
cd PHP\ Example/
```
5. Edit the *config.json* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed.
```
nano config.json
```
Edit the following lines:
```
"storagePath" = "";
"docServSiteUrl" = "https://documentserver/";
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **STORAGE_PATH** is the path where files will be created and stored. You can set an absolute path.
6. Run *composer install*:
```
php composer.phar install
```
7. Set permission for site:
```
chown -R www-data:www-data /var/www/html
```
8. Restart apache:
```
service apache2 restart
```
9. See the result in your browser using the address:
```
http://localhost/PHP%20Example/
```
### Step 3. Check accessibility
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## Important security info
Please keep in mind the following security aspects when you are using test examples:
- There is no protection of the storage from unauthorized access since there is no need for authorization.
- There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
- There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
- There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
* There is no protection of the storage from unauthorized access since there is no need for authorization.
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.

View File

@ -1,8 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H21.674C22.4697 0 23.2327 0.316071 23.7953 0.87868L29.1213 6.20465C29.6839 6.76726 30 7.53032 30 8.32597V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#3779A6"/>
<path d="M22.9167 0L30.0001 7.08333H25.9167C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#1D5880"/>
<path d="M6.17627 14.7059H23.8233V15.8823H6.17627V14.7059Z" fill="white"/>
<path d="M6.17627 18.5294H23.8233V19.7059H6.17627V18.5294Z" fill="white"/>
<path d="M6.17627 22.3529H23.8233V23.5294H6.17627V22.3529Z" fill="white"/>
<path d="M6.17627 26.1765H23.8233V27.3529H6.17627V26.1765Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#1E7AAA"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path d="M6 15h18v1H6v-1zM6 19h18v1H6v-1zM6 23h18v1H6v-1zM6 27h18v1H6v-1z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 387 B

View File

@ -1,6 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#27ABA3"/>
<path d="M22.9165 0L29.9998 7.08333H25.9165C24.2597 7.08333 22.9165 5.74019 22.9165 4.08333V0Z" fill="#008078"/>
<rect x="6.5" y="15.5" width="17" height="5" stroke="white"/>
<rect x="6.5" y="23.5" width="17" height="5" stroke="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#27ABA3"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#008078"/><path fill-rule="evenodd" clip-rule="evenodd" d="M24 14H6v7h18v-7zm-.8182 5.9978H6.81818V15H23.1818v4.9978zM24 23H6v7h18v-7zm-.8182 5.9978H6.81818V24H23.1818v4.9978z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 463 B

View File

@ -1,8 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#F36700"/>
<path d="M22.9167 0L30.0001 7.08333H25.9168C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#AB531F"/>
<path d="M6.17627 16.1275H23.8233V17.3039H6.17627V16.1275Z" fill="white"/>
<path d="M6.17627 28.7745L6.17627 16.1275L7.35274 16.1275L7.35274 28.7745H6.17627Z" fill="white"/>
<path d="M23.8233 16.1275V28.7745H22.6469V16.1275L23.8233 16.1275Z" fill="white"/>
<path d="M6.17627 27.598H23.8233V28.7745H6.17627L6.17627 27.598Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#F36700"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path stroke="#fff" stroke-opacity=".95" d="M6.5 15.5h17v12h-17z"/></svg>

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 366 B

View File

@ -1,6 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 7.44186L22 0H3C1.22739 0 0 0.822551 0 2.32558V37.2093C0 38.7123 1.22739 40 3 40H27C28.7726 40 30 38.7123 30 37.2093V7.44186Z" fill="#D0D5DA"/>
<path d="M24.1042 7.27273H29.9631L22 0V5.32334C22 6.4105 22.949 7.27273 24.1042 7.27273Z" fill="#646464"/>
<path d="M16.9562 22.3485H12.9746V17.803H10.9839L14.9654 14.1667L18.947 17.803H16.9562V22.3485Z" fill="#646464"/>
<path d="M20.9378 23.7121C20.9378 24.1666 20.4401 24.6212 19.9424 24.6212H9.98848C9.49078 24.6212 8.99309 24.1666 8.99309 23.7121V22.3485C8.99309 21.8939 9.49078 21.4394 9.98848 21.4394H10.9839V20.0757H9.49078C8.49539 20.0757 7.5 20.9848 7.5 21.8939V24.1666C7.5 25.0757 8.61982 25.9848 9.49078 25.9848H20.4401C21.3111 25.9848 22.4309 25.0757 22.4309 24.1666V21.8939C22.4309 20.9848 21.4355 20.0757 20.4401 20.0757H18.947V21.4394H19.9424C20.4401 21.4394 20.9378 21.8939 20.9378 22.3485V23.7121Z" fill="#646464"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#D0D5DA"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#646464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 23c-.27614 0-.5.2239-.5.5v4c0 .2761.22386.5.5.5h15c.2761 0 .5-.2239.5-.5v-4c0-.2761-.2239-.5-.5-.5h-2c-.2761 0-.5-.2239-.5-.5s.2239-.5.5-.5h2c.8284 0 1.5.6716 1.5 1.5v4c0 .8284-.6716 1.5-1.5 1.5h-15c-.82843 0-1.5-.6716-1.5-1.5v-4c0-.8284.67157-1.5 1.5-1.5h2c.27614 0 .5.2239.5.5s-.22386.5-.5.5h-2z" fill="#646464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M20 20.0001L15 14l-5 6.0001h3v4c0 .5523.4477 1 1 1h2c.5523 0 1-.4477 1-1v-4h3z" fill="#646464"/></svg>

Before

Width:  |  Height:  |  Size: 992 B

After

Width:  |  Height:  |  Size: 797 B

View File

@ -1,12 +1 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 3C0 1.34315 1.34315 0 3 0H22.9167L30 7.08333V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#78A73B"/>
<path d="M22.9167 0L30.0001 7.08333H25.9168C24.2599 7.08333 22.9167 5.74019 22.9167 4.08333V0Z" fill="#5A7D2B"/>
<path d="M6.17644 15.2941H23.8235V16.4706H6.17644V15.2941Z" fill="white"/>
<path d="M6.17644 19.1177H23.8235V20.2941H6.17644V19.1177Z" fill="white"/>
<path d="M6.17644 22.9412H23.8235V24.1177H6.17644V22.9412Z" fill="white"/>
<path d="M6.17644 26.7647H23.8235V27.9412H6.17644V26.7647Z" fill="white"/>
<path d="M5.88232 27.9412L5.88232 15.2941L7.0588 15.2941L7.0588 27.9412H5.88232Z" fill="white"/>
<path d="M11.4706 27.9412L11.4706 15.2941L12.647 15.2941V27.9412H11.4706Z" fill="white"/>
<path d="M17.0588 27.9412L17.0588 15.2941L18.2353 15.2941V27.9412H17.0588Z" fill="white"/>
<path d="M22.647 27.9412V15.2941H23.8235V27.9412H22.647Z" fill="white"/>
</svg>
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#6AAA1E"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#000" fill-opacity=".25"/><path fill-rule="evenodd" clip-rule="evenodd" d="M6 15h18v13H7.00001v-1H12v-3H7v4H6V15zm7 12h4v-3h-4v3zm5 0h5v-3h-5v3zm5-7v3h-5v-3h5zm-6 0v3h-4v-3h4zm-5 0v3H7v-3h5zm11-1v-3h-5v3h5zm-10-3h4v3h-4v-3zm-1 3v-3H7v3h5z" fill="#fff" fill-opacity=".95"/></svg>

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 545 B

View File

@ -3,7 +3,7 @@ version: "3.8"
services:
document-server:
container_name: document-server
image: onlyoffice/documentserver:7.5
image: onlyoffice/documentserver:7.3.3.50
expose:
- "80"
environment:

View File

@ -566,6 +566,7 @@ function reference()
$data = [
"fileType" => trim(getInternalExtension($fileName), '.'),
"key" => getDocEditorKey($fileName),
"url" => getDownloadUrl($fileName),
"directUrl" => $post["directUrl"] ? getDownloadUrl($fileName, false) : null,
"referenceData" => [

View File

@ -22,7 +22,7 @@ use Example\Common\URL;
class ConfigurationManager
{
public string $version = '1.7.0';
public string $version = '1.6.0';
public function exampleURL(): ?URL
{

View File

@ -1,86 +0,0 @@
## Overview
This example will help you integrate ONLYOFFICE Docs into your web application written on Python.
> [!WARNING]
> It is intended for testing purposes and demonstrating functionality of the editors. **DO NOT** use this integration example on your own server without proper code modifications. In case you enabled the test example, disable it before going for production.
## Installation
The Python example offers various installation options, but we highly recommend using Docker for this purpose.
### Using Docker
To run the example using [Docker](https://docker.com), you will need [Docker Desktop 4.17.0](https://docs.docker.com/desktop) or [Docker Engine 20.10.23](https://docs.docker.com/engine) with [Docker Compose 2.15.1](https://docs.docker.com/compose). Additionally, you might want to consider installing [GNU Make 4.4.1](https://gnu.org/software/make), although it is optional. These are the minimum versions required for the tools.
Once you have everything installed, download the release archive and unarchive it.
```sh
$ curl --output Python.Example.zip --location https://github.com/ONLYOFFICE/document-server-integration/releases/latest/download/Python.Example.zip
$ unzip Python.Example.zip
```
Then open the example directory and [up containers](./Makefile#L38).
```sh
$ cd "Python Example"
$ make compose-prod
```
By default, the server starts at `localhost:80`.
To configure the example, you can edit the environment variables in [`compose-base.yml`](./compose-base.yml). See [below](#configuration) for more information about environment variables.
### On Local Machine
Before diving into the example, you will need to install ONLYOFFICE Document Server (also known as Docs). Check the detailed guide to learn how to install it on [Windows](https://helpcenter.onlyoffice.com/installation/docs-developer-install-windows.aspx), [Linux](https://helpcenter.onlyoffice.com/installation/docs-developer-install-ubuntu.aspx), or [Docker](https://helpcenter.onlyoffice.com/installation/docs-developer-install-docker.aspx).
To run the example on your local machine, you will need [Python 3.11.4](https://python.org) with [pip 23.1.2](https://pip.pypa.io). Additionally, you might want to consider installing [GNU Make 4.4.1](https://gnu.org/software/make), although it is optional. These are the minimum versions required for the tools.
Once you have everything installed, download the release archive and unarchive it.
```sh
$ curl --output Python.Example.zip --location https://github.com/ONLYOFFICE/document-server-integration/releases/latest/download/Python.Example.zip
$ unzip Python.Example.zip
```
Then open the example directory, [install dependencies](./Makefile#L13), and [start the server](./Makefile#L21).
```sh
$ cd "Python Example"
$ make prod
$ make server-prod
```
By default, the server starts at `0.0.0.0:8000`.
To configure the example, you can pass the environment variables before the command that starts the server. See [below](#configuration) for more information about environment variables.
## Post Installation
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## Configuration
The example is configured by changing environment variables.
| Name | Description | Example |
| ----------------------------- | ----------------------------------------------------------------------- | ----------------------- |
| `DEBUG` | Disable or enable debug mode. | `false` |
| `ADDRESS` | The address where the server should be started. | `0.0.0.0` |
| `PORT` | The port on which the server should be running. | `80` |
| `DOCUMENT_SERVER_PRIVATE_URL` | The URL through which the server will communicate with Document Server. | `http://proxy:8080` |
| `DOCUMENT_SERVER_PUBLIC_URL` | The URL through which a user will communicate with Document Server. | `http://localhost:8080` |
| `EXAMPLE_URL` | The URL through which Document Server will communicate with the server. | `http://proxy` |
| `JWT_SECRET` | JWT authorization secret. Leave blank to disable authorization. | `your-256-bit-secret` |
## Security Info
Please keep in mind the following security aspects when you are using test examples:
- There is no protection of the storage from unauthorized access since there is no need for authorization.
- There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
- There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
- There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.

View File

@ -3,7 +3,7 @@ version: "3.8"
services:
document-server:
container_name: document-server
image: onlyoffice/documentserver:7.5
image: onlyoffice/documentserver:7.3.3.50
expose:
- "80"
environment:

View File

@ -0,0 +1,82 @@
## Overview
This example will help you integrate ONLYOFFICE Docs into your web application written in Python.
**Please note**: It is intended for testing purposes and demonstrating functionality of the editors. Do NOT use this integration example on your own server without proper code modifications! In case you enabled the test example, disable it before going for production.
## Step 1. Install ONLYOFFICE Docs
Download and install ONLYOFFICE Docs (packaged as Document Server).
See the detailed guide to learn how to install Document Server [for Windows](https://helpcenter.onlyoffice.com/installation/docs-developer-install-windows.aspx?from=api_python_example), [for Linux](https://helpcenter.onlyoffice.com/installation/docs-developer-install-ubuntu.aspx?from=api_python_example), or [for Docker](https://helpcenter.onlyoffice.com/server/developer-edition/docker/docker-installation.aspx?from=api_python_example).
## Step 2. Install the prerequisites and run the website with the editors
1. **Python** comes preinstalled on most Linux distributions, and is available as a package on all others. Python 3.9 is required. Please proceed to [official documentation](https://docs.python.org/3/using/unix.html) if you have any troubles.
2. Download the archive with the Python example and unpack it:
```
wget "https://api.onlyoffice.com/app_data/editor/Python.Example.zip"
```
```
unzip Python.Example.zip
```
3. Change the current directory for the project directory:
```
cd Python\ Example
```
4. Install the dependencies:
```
pip install Django==3.1.3
pip install requests==2.25.0
pip install pyjwt==2.6.0
pip install python-magic
```
5. Edit the *config.py* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed. And specify the name of the server on which example is installed.
```
nano config.py
```
Edit the following lines:
```
STORAGE_PATH = 'app_data'
DOC_SERV_SITE_URL = 'https://documentserver/'
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **STORAGE_PATH** is the path where files will be created and stored. You can set an absolute path. For example, *D:\\\\folder*. Please note that on Windows OS the double backslash must be used as a separator.
6. Run the **Python** server:
```
python manage.py runserver 0.0.0.0:8000
```
7. See the result in your browser using the address:
```
http://localhost:8000
```
## Step 3. Check accessibility
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## Important security info
Please keep in mind the following security aspects when you are using test examples:
* There is no protection of the storage from unauthorized access since there is no need for authorization.
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.

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