Compare commits
20 Commits
v7.5.1.32
...
v99.99.99.
| Author | SHA1 | Date | |
|---|---|---|---|
| 6315ccbf45 | |||
| 969a8c6cfe | |||
| f4dd6d665f | |||
| 427d13af24 | |||
| 6bdadd6053 | |||
| 95579f2376 | |||
| 8c518fd109 | |||
| aa245e2aae | |||
| 6511507093 | |||
| 8f14876b81 | |||
| 09f24a3b87 | |||
| 14b014cb7f | |||
| 2d83d3ec87 | |||
| 05904fd68a | |||
| a56b411c93 | |||
| bc5393e28c | |||
| a3fa30b192 | |||
| 24b9a35651 | |||
| 52a722cf89 | |||
| 4fa9d4c9fd |
6
.github/workflows/artifact-csharp-mvc.yml
vendored
@ -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:
|
||||
|
||||
5
.github/workflows/artifact-csharp.yml
vendored
@ -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:
|
||||
|
||||
6
.github/workflows/artifact-java.yml
vendored
@ -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:
|
||||
|
||||
6
.github/workflows/artifact-node.yml
vendored
@ -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:
|
||||
|
||||
6
.github/workflows/artifact-php.yml
vendored
@ -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:
|
||||
|
||||
6
.github/workflows/artifact-python.yml
vendored
@ -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:
|
||||
|
||||
6
.github/workflows/artifact-ruby.yml
vendored
@ -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:
|
||||
|
||||
5
.github/workflows/artifact-spring.yml
vendored
@ -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:
|
||||
|
||||
6
.github/workflows/lint-python.yml
vendored
@ -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
|
||||
|
||||
32
.github/workflows/lint-ruby.yml
vendored
@ -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
|
||||
|
||||
59
.github/workflows/release.yml
vendored
@ -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
|
||||
|
||||
13
CHANGELOG.md
@ -1,24 +1,21 @@
|
||||
# Change Log
|
||||
|
||||
## 1.7.0
|
||||
- nodejs: link in referenceData
|
||||
- nodejs: onRequestSelectDocument method
|
||||
- nodejs: onRequestSelectSpreadsheet method
|
||||
- nodejs: onRequestOpen
|
||||
- nodejs: submitForm
|
||||
- nodejs: key in referenceData
|
||||
- nodejs: change reference source
|
||||
- php: using a repo with a list of formats
|
||||
- nodejs: 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
|
||||
|
||||
@ -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=""/>
|
||||
|
||||
@ -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=""/>
|
||||
|
||||
@ -128,11 +128,7 @@ 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:
|
||||
|
||||
@ -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%20Spring%20Example.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 *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:
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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) {
|
||||
@ -412,19 +419,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 +447,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 +464,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 +472,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 +487,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 +502,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());
|
||||
@ -523,7 +513,7 @@ public class FileController {
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("fileType", fileUtility.getFileExtension(fileName).replace(".", ""));
|
||||
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 +528,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 +564,7 @@ public class FileController {
|
||||
String bumpedKey = serviceConverter.generateRevisionId(
|
||||
storagePathBuilder.getStorageLocation()
|
||||
+ "/"
|
||||
+ sourceBasename
|
||||
+ body.getFileName()
|
||||
+ "/"
|
||||
+ Long.toString(sourceFile.lastModified())
|
||||
);
|
||||
@ -572,8 +572,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 +595,17 @@ public class FileController {
|
||||
bumpedChangesFileWriter.write(bumpedChangesContent);
|
||||
bumpedChangesFileWriter.close();
|
||||
|
||||
String sourceExtension = fileUtility.getFileExtension(sourceBasename);
|
||||
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);
|
||||
|
||||
@ -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
|
||||
@ -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 = "";
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
server.version=1.7.0
|
||||
server.version=1.6.0
|
||||
|
||||
server.address=
|
||||
server.port=4000
|
||||
|
||||
@ -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
|
||||
|
||||
@ -140,11 +140,7 @@ 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:
|
||||
|
||||
@ -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%20Example.zip
|
||||
```
|
||||
|
||||
```
|
||||
unzip Java\ Example.zip
|
||||
```
|
||||
|
||||
3. Change the current directory for the project directory:
|
||||
|
||||
```
|
||||
cd Java\ Example/
|
||||
```
|
||||
|
||||
4. Edit the *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
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -825,6 +832,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).substring(1));
|
||||
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,
|
||||
|
||||
@ -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";
|
||||
@ -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;
|
||||
|
||||
@ -31,6 +31,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,6 +51,7 @@ 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;
|
||||
@ -599,4 +601,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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
version=1.7.0
|
||||
version=1.6.0
|
||||
|
||||
filesize-max=5242880
|
||||
storage-folder=app_data
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
@ -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;
|
||||
}
|
||||
|
||||
let 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);
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,6 @@
|
||||
{
|
||||
"server": {
|
||||
"siteUrl": "/",
|
||||
"maxFileSize": 104857600,
|
||||
"static":[
|
||||
{
|
||||
"name": "/files",
|
||||
"path": "./files",
|
||||
"options": {"maxAge": "7d"}
|
||||
}
|
||||
]
|
||||
"maxFileSize": 104857600
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,9 +152,9 @@ 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()} `
|
||||
const dateFormat = `${dateCreate.getFullYear()}-${month}-${dateCreate.getDate()}`
|
||||
+ `${dateCreate.getHours()}:${minutes}:${sec}`;
|
||||
|
||||
const fileInfo = this.historyPath(fileName, address, true); // get file history information
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -34,15 +34,13 @@ const requestDiscovery = async function requestDiscovery(url) {
|
||||
urllib.request(urlModule.parse(url + configServer.get('wopi.discovery')), { method: 'GET' }, (err, data) => {
|
||||
if (data) {
|
||||
// create the discovery XML file with the parameters from the response
|
||||
const xmlParseOptions = {
|
||||
const discovery = xmlParser.parse(data.toString(), {
|
||||
attributeNamePrefix: '',
|
||||
ignoreAttributes: false,
|
||||
parseAttributeValue: true,
|
||||
attrValueProcessor: (val) => he.decode(val, { isAttributeValue: true }),
|
||||
};
|
||||
const parser = new xmlParser.XMLParser(xmlParseOptions);
|
||||
// create the discovery XML file with the parameters from the response
|
||||
const discovery = parser.parse(data.toString());
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
attrValueProcessor: (val, attrName) => he.decode(val, { isAttributeValue: true }),
|
||||
});
|
||||
if (discovery['wopi-discovery']) {
|
||||
discovery['wopi-discovery']['net-zone'].app.forEach((app) => {
|
||||
let appAction = app.action;
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
"debug": "^4.2.0",
|
||||
"ejs": "^3.1.5",
|
||||
"express": "^4.17.1",
|
||||
"fast-xml-parser": "^4.3.1",
|
||||
"fast-xml-parser": "^3.19.0",
|
||||
"formidable": "^1.2.2",
|
||||
"he": "^1.2.0",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
@ -1509,24 +1509,15 @@
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
|
||||
},
|
||||
"node_modules/fast-xml-parser": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.1.tgz",
|
||||
"integrity": "sha512-viVv3xb8D+SiS1W4cv4tva3bni08kAkx0gQnWrykMM8nXPc1FxqZPU00dCEVjkiCg4HoXd2jC4x29Nzg/l2DAA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/naturalintelligence"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"strnum": "^1.0.5"
|
||||
},
|
||||
"version": "3.19.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz",
|
||||
"integrity": "sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==",
|
||||
"bin": {
|
||||
"fxparser": "src/cli/cli.js"
|
||||
"xml2js": "cli.js"
|
||||
},
|
||||
"funding": {
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/naturalintelligence"
|
||||
}
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
@ -3524,11 +3515,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/strnum": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
||||
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
@ -5007,12 +4993,9 @@
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
|
||||
},
|
||||
"fast-xml-parser": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.1.tgz",
|
||||
"integrity": "sha512-viVv3xb8D+SiS1W4cv4tva3bni08kAkx0gQnWrykMM8nXPc1FxqZPU00dCEVjkiCg4HoXd2jC4x29Nzg/l2DAA==",
|
||||
"requires": {
|
||||
"strnum": "^1.0.5"
|
||||
}
|
||||
"version": "3.19.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz",
|
||||
"integrity": "sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg=="
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.13.0",
|
||||
@ -6528,11 +6511,6 @@
|
||||
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||
"dev": true
|
||||
},
|
||||
"strnum": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
||||
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
"debug": "^4.2.0",
|
||||
"ejs": "^3.1.5",
|
||||
"express": "^4.17.1",
|
||||
"fast-xml-parser": "^4.3.1",
|
||||
"fast-xml-parser": "^3.19.0",
|
||||
"formidable": "^1.2.2",
|
||||
"he": "^1.2.0",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
|
||||
@ -1 +1,8 @@
|
||||
<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>
|
||||
<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>
|
||||
|
||||
|
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 738 B |
@ -1 +1,6 @@
|
||||
<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>
|
||||
<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>
|
||||
|
||||
|
Before Width: | Height: | Size: 463 B After Width: | Height: | Size: 477 B |
@ -1 +1,8 @@
|
||||
<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>
|
||||
<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>
|
||||
|
||||
|
Before Width: | Height: | Size: 366 B After Width: | Height: | Size: 691 B |
@ -1 +1,6 @@
|
||||
<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>
|
||||
<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>
|
||||
|
||||
|
Before Width: | Height: | Size: 797 B After Width: | Height: | Size: 992 B |
@ -1 +1,12 @@
|
||||
<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>
|
||||
<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>
|
||||
|
||||
|
Before Width: | Height: | Size: 545 B After Width: | Height: | Size: 1004 B |
@ -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
|
||||
```
|
||||

|
||||
|
||||
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
|
||||

|
||||
|
||||
After clicking **OK**, the new **PHP version** will be registered with IIS and will become active.
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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**.
|
||||
|
||||

|
||||
|
||||
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**.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
3. Browse your website with the IIS manager:
|
||||
|
||||
Right-click the site -> **Manage Website** -> **Browse**
|
||||
|
||||

|
||||
|
||||
### 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%20Example.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.
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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.
|
||||
@ -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:
|
||||
|
||||
82
web/documentserver-example/python/readme.md
Executable 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%20Example.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.
|
||||
@ -21,7 +21,7 @@ from urllib.parse import ParseResult, urlparse, urljoin
|
||||
from src.common import string
|
||||
|
||||
class ConfigurationManager:
|
||||
version = '1.7.0'
|
||||
version = '1.6.0'
|
||||
|
||||
def example_url(self) -> Optional[ParseResult]:
|
||||
url = environ.get('EXAMPLE_URL')
|
||||
|
||||
@ -2,84 +2,89 @@
|
||||
|
||||
This example will help you integrate ONLYOFFICE Docs into your web application written on Ruby.
|
||||
|
||||
> [!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
|
||||
## Step 1. Install ONLYOFFICE Docs
|
||||
|
||||
The Ruby example offers various installation options, but we highly recommend using Docker for this purpose.
|
||||
Download and install ONLYOFFICE Docs (packaged as Document Server).
|
||||
|
||||
### Using Docker
|
||||
See the detailed guide to learn how to install Document Server [for Windows](https://helpcenter.onlyoffice.com/installation/docs-developer-install-windows.aspx), [for Linux](https://helpcenter.onlyoffice.com/installation/docs-developer-install-ubuntu.aspx), or [for Docker](https://helpcenter.onlyoffice.com/server/developer-edition/docker/docker-installation.aspx).
|
||||
|
||||
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.
|
||||
## Step 2. Install the prerequisites and run the website with the editors
|
||||
|
||||
Once you have everything installed, download the release archive and unarchive it.
|
||||
1. Install **Ruby Version Manager (RVM)** and the latest stable **Ruby** version:
|
||||
|
||||
```sh
|
||||
$ curl --output Ruby.Example.zip --location https://github.com/ONLYOFFICE/document-server-integration/releases/latest/download/Ruby.Example.zip
|
||||
$ unzip Ruby.Example.zip
|
||||
```
|
||||
```
|
||||
gpg --keyserver "hkp://keys.gnupg.net" --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
|
||||
```
|
||||
|
||||
Then open the example directory and [up containers](./Makefile#L46).
|
||||
```
|
||||
\curl -sSL https://get.rvm.io | bash -s stable --ruby
|
||||
```
|
||||
|
||||
```sh
|
||||
$ cd "Ruby Example"
|
||||
$ make compose-prod
|
||||
```
|
||||
2. Download the archive with the Ruby example and unpack the archive:
|
||||
|
||||
By default, the server starts at `localhost:80`.
|
||||
```
|
||||
wget "https://api.onlyoffice.com/app_data/editor/Ruby%20Example.zip"
|
||||
```
|
||||
|
||||
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.
|
||||
```
|
||||
unzip Ruby\ Example.zip
|
||||
```
|
||||
|
||||
### On Local Machine
|
||||
3. Change the current directory for the project directory:
|
||||
|
||||
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).
|
||||
```
|
||||
cd Ruby\ Example
|
||||
```
|
||||
|
||||
To run the example on your local machine, you will need [Ruby 3.2.2](https://ruby-lang.org) with [Bundler 2.4.10](https://bundler.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.
|
||||
4. Install the dependencies:
|
||||
|
||||
Once you have everything installed, download the release archive and unarchive it.
|
||||
```
|
||||
bundle install
|
||||
```
|
||||
|
||||
```sh
|
||||
$ curl --output Ruby.Example.zip --location https://github.com/ONLYOFFICE/document-server-integration/releases/latest/download/Ruby.Example.zip
|
||||
$ unzip Ruby.Example.zip
|
||||
```
|
||||
5. Edit the *application.rb* configuration file. Specify the name of your local server with the ONLYOFFICE Document Server installed.
|
||||
|
||||
Then open the example directory, [install dependencies](./Makefile#L33), and [start the server](./Makefile#L42).
|
||||
```
|
||||
nano config/application.rb
|
||||
```
|
||||
|
||||
```sh
|
||||
$ cd "Ruby Example"
|
||||
$ make prod
|
||||
$ make server-prod
|
||||
```
|
||||
Edit the following lines:
|
||||
|
||||
By default, the server starts at `0.0.0.0:3000`.
|
||||
```
|
||||
Rails.configuration.storagePath="app_data"
|
||||
Rails.configuration.urlSite="https://documentserver/"
|
||||
```
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Post Installation
|
||||
6. Run the **Rails** application:
|
||||
|
||||
```
|
||||
rails server -u webrick
|
||||
rails s -b 0.0.0.0 -p 80
|
||||
```
|
||||
|
||||
7. See the result in your browser using the address:
|
||||
|
||||
```
|
||||
http://localhost
|
||||
```
|
||||
|
||||
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) in the *views\home\editor.html.erb* file.
|
||||
|
||||
## 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.
|
||||
|
||||
## Configuration
|
||||
|
||||
The example is configured by changing environment variables.
|
||||
|
||||
| Name | Description | Example |
|
||||
| ------------- | ------------- | ------------- |
|
||||
| `BINDING` | The address where the server should be started. | `0.0.0.0` |
|
||||
| `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` |
|
||||
| `PORT` | The port on which the server should be running. | `80` |
|
||||
|
||||
## Security Info
|
||||
## 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.
|
||||
@ -30,7 +30,7 @@ class ConfigurationManager
|
||||
|
||||
sig { void }
|
||||
def initialize
|
||||
@version = '1.7.0'
|
||||
@version = '1.6.0'
|
||||
end
|
||||
|
||||
sig { returns(T.nilable(URI::Generic)) }
|
||||
|
||||
@ -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:
|
||||
|
||||