Merge remote-tracking branch 'remotes/origin/develop' into feature/go-lang
# Conflicts: # CHANGELOG.md
31
.github/workflows/artifact-php-laravel.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
name: Artifact PHP Laravel
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master]
|
||||
paths: ['web/documentserver-example/php-laravel/**']
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths: ['web/documentserver-example/php-laravel/**']
|
||||
|
||||
jobs:
|
||||
artifact:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Build Artifact
|
||||
run: |
|
||||
cd ${{ github.workspace }}
|
||||
git submodule update --init --recursive
|
||||
cd ./web/documentserver-example/php-laravel
|
||||
mkdir -p ./deploy/'PHP Laravel Example'
|
||||
rsync -av --exclude='deploy' ./ ./deploy/'PHP Laravel Example'
|
||||
rm -rf ./deploy/'PHP Laravel Example'/public/assets/document-formats/.git
|
||||
rm -rf ./deploy/'PHP Laravel Example'/public/assets/document-templates/.git
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: PHP-Laravel.Example
|
||||
path: ${{ github.workspace }}/web/documentserver-example/php-laravel/deploy
|
||||
37
.github/workflows/lint-php-laravel.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: Laravel Pint
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master, main]
|
||||
paths: ['web/documentserver-example/php-laravel/**']
|
||||
pull_request:
|
||||
branches: [master, main, develop]
|
||||
paths: ['web/documentserver-example/php-laravel/**']
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
php: [8.2]
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web/documentserver-example/php-laravel
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: json, dom, curl, libxml, mbstring
|
||||
coverage: none
|
||||
|
||||
- name: Install Pint
|
||||
run: composer global require laravel/pint
|
||||
|
||||
- name: Run Pint
|
||||
run: pint --test
|
||||
2
.github/workflows/lint-php.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
working-directory: ./web/documentserver-example/php
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
|
||||
2
.github/workflows/lint-ruby.yml
vendored
@ -30,7 +30,7 @@ jobs:
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
bundle update
|
||||
bundle install
|
||||
|
||||
- name: Rubocop
|
||||
run: |
|
||||
|
||||
11
.github/workflows/release.yml
vendored
@ -63,6 +63,14 @@ jobs:
|
||||
rsync -av --exclude='PHP Example' ./ ./'PHP Example'
|
||||
rm -rf ./'PHP Example'/assets/document-formats/.git
|
||||
rm -rf ./'PHP Example'/assets/document-templates/.git
|
||||
- name: Build PHP Laravel Artifact
|
||||
run: |
|
||||
cd ${{ github.workspace }}
|
||||
cd ./web/documentserver-example/php-laravel
|
||||
mkdir -p ./'PHP Laravel Example'
|
||||
rsync -av --exclude='PHP Laravel Example' ./ ./'PHP Laravel Example'
|
||||
rm -rf ./'PHP Laravel Example'/public/assets/document-formats/.git
|
||||
rm -rf ./'PHP Laravel Example'/public/assets/document-templates/.git
|
||||
- name: Build Python Artifact
|
||||
run: |
|
||||
cd ${{ github.workspace }}
|
||||
@ -107,6 +115,8 @@ jobs:
|
||||
zip -r Node.js.Example.zip ./'Node.js Example'
|
||||
cd ${{ github.workspace }}/web/documentserver-example/php
|
||||
zip -r PHP.Example.zip ./'PHP Example'
|
||||
cd ${{ github.workspace }}/web/documentserver-example/php-laravel
|
||||
zip -r PHP.Laravel.Example.zip ./'PHP Laravel Example'
|
||||
cd ${{ github.workspace }}/web/documentserver-example/python
|
||||
zip -r Python.Example.zip ./'Python Example'
|
||||
cd ${{ github.workspace }}/web/documentserver-example/ruby
|
||||
@ -126,6 +136,7 @@ jobs:
|
||||
${{ github.workspace }}/web/documentserver-example/java/Java.Example.zip,
|
||||
${{ github.workspace }}/web/documentserver-example/nodejs/Node.js.Example.zip,
|
||||
${{ github.workspace }}/web/documentserver-example/php/PHP.Example.zip,
|
||||
${{ github.workspace }}/web/documentserver-example/php-laravel/PHP.Laravel.Example.zip,
|
||||
${{ github.workspace }}/web/documentserver-example/python/Python.Example.zip,
|
||||
${{ github.workspace }}/web/documentserver-example/ruby/Ruby.Example.zip,
|
||||
${{ github.workspace }}/web/documentserver-example/java-spring/Java.Spring.Example.zip,
|
||||
|
||||
13
.gitmodules
vendored
@ -5,7 +5,6 @@
|
||||
[submodule "web/documentserver-example/nodejs/public/assets/document-formats"]
|
||||
path = web/documentserver-example/nodejs/public/assets/document-formats
|
||||
url = https://github.com/ONLYOFFICE/document-formats
|
||||
branch = feature/v8.0
|
||||
[submodule "web/documentserver-example/csharp-mvc/assets/document-templates"]
|
||||
path = web/documentserver-example/csharp-mvc/assets/document-templates
|
||||
url = https://github.com/ONLYOFFICE/document-templates
|
||||
@ -57,10 +56,6 @@
|
||||
path = web/documentserver-example/java/src/main/resources/assets/document-formats
|
||||
url = https://github.com/ONLYOFFICE/document-formats
|
||||
branch = master
|
||||
[submodule "web/documentserver-example/java-spring/src/main/resources/assets/document-formats"]
|
||||
path = web/documentserver-example/java-spring/src/main/resources/assets/document-formats
|
||||
url = https://github.com/ONLYOFFICE/document-formats
|
||||
branch = master
|
||||
[submodule "web/documentserver-example/csharp/assets/document-templates"]
|
||||
path = web/documentserver-example/csharp/assets/document-templates
|
||||
url = https://github.com/ONLYOFFICE/document-templates
|
||||
@ -68,3 +63,11 @@
|
||||
[submodule "web/documentserver-example/csharp/assets/document-formats"]
|
||||
path = web/documentserver-example/csharp/assets/document-formats
|
||||
url = https://github.com/ONLYOFFICE/document-formats
|
||||
[submodule "web/documentserver-example/php-laravel/public/assets/document-formats"]
|
||||
path = web/documentserver-example/php-laravel/public/assets/document-formats
|
||||
url = https://github.com/ONLYOFFICE/document-formats
|
||||
branch = master
|
||||
[submodule "web/documentserver-example/php-laravel/public/assets/document-templates"]
|
||||
path = web/documentserver-example/php-laravel/public/assets/document-templates
|
||||
url = https://github.com/ONLYOFFICE/document-templates
|
||||
branch = main/en
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
Document Server integration example uses code from the following 3rd party projects.
|
||||
|
||||
|
||||
web/documentserver-example/csharp
|
||||
|
||||
jQuery.BlockUI - The jQuery BlockUI Plugin lets you simulate synchronous behavior when using AJAX, without locking the browser. (https://github.com/malsup/blockui/)
|
||||
@ -132,6 +131,10 @@ Jackson Databind - General-purpose data-binding functionality and tree-model for
|
||||
License: Apache 2.0
|
||||
License File: jackson-databind.license
|
||||
|
||||
Jackson Dataformat Properties - Support for reading and writing content of "Java Properties" style configuration files as if there was implied nesting structure (by default using dots as separators). (https://github.com/FasterXML/jackson-dataformats-text/blob/master/LICENSE)
|
||||
License: Apache 2.0
|
||||
License File: jackson-dataformat-properties.license
|
||||
|
||||
jQuery.BlockUI - The jQuery BlockUI Plugin lets you simulate synchronous behavior when using AJAX, without locking the browser. (https://github.com/malsup/blockui/)
|
||||
License: MIT, GPL
|
||||
License File: jQuery.BlockUI.license
|
||||
@ -156,6 +159,10 @@ jQuery.UI - jQuery UI is an open source library of interface components —
|
||||
License: MIT
|
||||
License File: jQuery.UI.license
|
||||
|
||||
JSON - JSON is a light-weight, language independent, data interchange format. (https://github.com/stleary/JSON-java/blob/master/LICENSE)
|
||||
License Public Domain
|
||||
License File: json.license
|
||||
|
||||
JSON.simple - JSON.simple is a simple Java toolkit for JSON. You can use JSON.simple to encode or decode JSON text. (https://github.com/fangyidong/json-simple/blob/master/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: JSON.simple.license
|
||||
@ -168,14 +175,14 @@ ModelMapper - ModelMapper is an intelligent object mapping library that automa
|
||||
License: Apache 2.0
|
||||
License File modelmapper.license
|
||||
|
||||
Prime JWT - is intended to be fast and easy to use. Prime JWT has a single external dependency on Jackson. (https://github.com/ws-apps/prime-jwt/blob/master/LICENSE)
|
||||
License: Apache 2.0
|
||||
License File: prime-jwt.license
|
||||
|
||||
Spring Boot - Helps create Spring-powered, production-grade applications and services. Has external dependencies on Spring Framework. (https://github.com/spring-projects/spring-boot/blob/main/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: spring-boot.license
|
||||
|
||||
Spring Boot Web - Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container. (https://github.com/spring-projects/spring-boot/blob/main/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: spring-boot.license
|
||||
|
||||
Spring Boot Devtools - Provides fast application restarts, LiveReload, and configurations for enhanced development experience. (https://github.com/spring-projects/spring-boot/blob/main/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: spring-boot.license
|
||||
@ -271,6 +278,9 @@ urllib - Request HTTP URLs in a complex world — basic and digest authen
|
||||
License: MIT
|
||||
License File: urllib.license
|
||||
|
||||
utf7 - Encodes and decodes JavaScript (Unicode/UCS-2) strings to UTF-7 ASCII strings. (https://github.com/kkaefer/utf7/blob/master/LICENSE)
|
||||
License: MIT
|
||||
License File: utf7.license
|
||||
|
||||
|
||||
web/documentserver-example/php
|
||||
|
||||
31
CHANGELOG.md
@ -1,10 +1,41 @@
|
||||
# Change Log
|
||||
|
||||
- golang: new integration example
|
||||
- golang: upload files to the server
|
||||
- golang: create blank files and files with sample content
|
||||
- glang: edit uploaded files in onlyoffice editor
|
||||
- golang: delete files on the server
|
||||
- golang: show files history
|
||||
- php-laravel: new integration example
|
||||
- php-laravel: upload files to the server
|
||||
- php-laravel: create blank files and files with sample content
|
||||
- php-laravel: edit uploaded files in onlyoffice editor
|
||||
- php-laravel: delete files on the server
|
||||
- php-laravel: create, edit, and submit pdf forms
|
||||
- php-laravel: show forgotten files on a seperate page
|
||||
|
||||
## 1.10.0
|
||||
- nodejs: converting function on index page
|
||||
- java-spring: using java docs-integration-sdk
|
||||
- tabs menu
|
||||
- creating and editing pdf instead docxf
|
||||
- filling by default
|
||||
- forgotten files
|
||||
- delete all files
|
||||
- save as for pdf
|
||||
- handling conversion -9 error
|
||||
- change inserted image
|
||||
- different goback for users
|
||||
|
||||
## 1.9.0
|
||||
- nodejs: filling by default
|
||||
- nodejs: docxf, oform as pdf documentType
|
||||
- nodejs: creating and editing pdf instead docxf
|
||||
- nodejs: wopi formsubmit icon
|
||||
- nodejs: close editor
|
||||
- en-GB, sr-Cyrl-RS skin languages
|
||||
- switching from filling to editing
|
||||
- fill permission in embedded mode
|
||||
|
||||
## 1.8.0
|
||||
- nodejs: pdf, djvu, xps, oxps as pdf documentType
|
||||
|
||||
@ -38,9 +38,15 @@ namespace OnlineEditorsExampleMVC
|
||||
|
||||
// create the main script bundle
|
||||
bundles.Add(new ScriptBundle("~/bundles/scripts").Include(
|
||||
"~/Scripts/formats.js",
|
||||
"~/Scripts/jscript.js"
|
||||
));
|
||||
|
||||
// create the forgotten page script bundle
|
||||
bundles.Add(new ScriptBundle("~/bundles/forgotten").Include(
|
||||
"~/Scripts/forgotten.js"
|
||||
));
|
||||
|
||||
// create a style bundle
|
||||
bundles.Add(new StyleBundle("~/Content/css").Include(
|
||||
"~/Content/stylesheet.css",
|
||||
@ -52,6 +58,11 @@ namespace OnlineEditorsExampleMVC
|
||||
bundles.Add(new StyleBundle("~/Content/editor").Include(
|
||||
"~/Content/editor.css"
|
||||
));
|
||||
|
||||
// create the forgotten page style bundle
|
||||
bundles.Add(new StyleBundle("~/Content/forgotten").Include(
|
||||
"~/Content/forgotten.css"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
161
web/documentserver-example/csharp-mvc/Content/forgotten.css
Normal file
@ -0,0 +1,161 @@
|
||||
.center {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
width: 256px;
|
||||
}
|
||||
|
||||
.main-panel {
|
||||
width: 832px;
|
||||
margin: 0 32px;
|
||||
padding: 48px 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #E2E2E2;
|
||||
}
|
||||
|
||||
.tableRow td:first-child {
|
||||
width: 70%;
|
||||
flex-grow: 0;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.tableHeader td:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tableHeader td:last-child, .tableRow td:last-child {
|
||||
width: 10%;
|
||||
text-align: center;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.tableHeader {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stored-edit {
|
||||
display: block;
|
||||
padding-top: 0;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
menu.links {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scroll-table-body table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.stored-edit span {
|
||||
font-size: 12px;
|
||||
line-height: normal;
|
||||
position: static;
|
||||
}
|
||||
|
||||
.scroll-table-body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.stored-list {
|
||||
height: calc(100% - 58px);
|
||||
}
|
||||
|
||||
header {
|
||||
min-width:auto;
|
||||
}
|
||||
|
||||
header a {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
width: 1152px;
|
||||
}
|
||||
|
||||
@media (max-width: 1279px) and (min-width: 1024px) {
|
||||
.left-panel {
|
||||
width: 208px;
|
||||
}
|
||||
|
||||
.main-panel {
|
||||
width: 688px;
|
||||
}
|
||||
|
||||
header a {
|
||||
width: 928px;
|
||||
}
|
||||
|
||||
header img {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) and (min-width: 593px) {
|
||||
.center {
|
||||
max-width: 768px;
|
||||
width: calc(100% - 80px);
|
||||
}
|
||||
|
||||
.table-main {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
width: 208px;
|
||||
}
|
||||
|
||||
.main-panel {
|
||||
width: calc(100% - 32px);
|
||||
}
|
||||
|
||||
.tableHeader td:last-child, .tableRow td:last-child {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
header a {
|
||||
width: 768px;
|
||||
}
|
||||
|
||||
header img {
|
||||
margin-left: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 592px) and (min-width: 320px) {
|
||||
.center, .table-main {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main-panel {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 28px 16px;
|
||||
}
|
||||
|
||||
.tableHeader td:last-child, .tableRow td:last-child {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
header a {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.scroll-table-body {
|
||||
top: 40px;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
padding: 8px 0;
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#27ABA3"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#008078"/><path fill-rule="evenodd" clip-rule="evenodd" d="M24 14H6v7h18v-7zm-.8182 5.9978H6.81818V15H23.1818v4.9978zM24 23H6v7h18v-7zm-.8182 5.9978H6.81818V24H23.1818v4.9978z" fill="#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 463 B |
@ -0,0 +1,5 @@
|
||||
<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 0H23L30 7V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#9E1919"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.0062 15V16.0065H24V15H17.0062ZM17.0062 19V20.0163H24V19H17.0062ZM24 23H17.0062V24.0261H24V23ZM6 28V27.0293H24V28H6ZM7 16H14V23H7V16ZM6 15H7H14H15V16V23V24H14H7H6V23V16V15Z" fill="white"/>
|
||||
<path d="M23 0L30 7H26C24.3431 7 23 5.65685 23 4V0Z" fill="black" fill-opacity="0.25"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 558 B |
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="17" viewBox="0 0 20 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 17V11H12V17H17V9H20L10 0L0 9H3V17H8Z" fill="#444444"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 173 B |
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 1h8l4 4v10H2V1z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M14 5l-4-4H2v14h12V5zm-4-5l5 5v11H1V0h9z" fill="#BFBFBF"/><path fill="#9E1919" d="M3 10h10v4H3z"/><path d="M7 7V2H3v5h4zM8 3V2h2v1H8zM8 5V4h5v1H8zM13 6H8v1h5V6zM13 8H3v1h10V8z" fill="#BFBFBF"/><path opacity=".3" d="M9 1h1v3h4l1 1H9V1z" fill="#333"/></svg>
|
||||
|
After Width: | Height: | Size: 441 B |
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="23" viewBox="0 0 24 23" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5332 22.2243L0.632544 17.5921C-0.210848 17.1877 -0.210848 16.5627 0.632544 16.1951L4.07945 14.5775L10.4966 17.5921C11.34 17.9965 12.6967 17.9965 13.5034 17.5921L19.9206 14.5775L23.3675 16.1951C24.2108 16.5995 24.2108 17.2245 23.3675 17.5921L13.4668 22.2243C12.6967 22.592 11.34 22.592 10.5332 22.2243Z" fill="#FF6F3D"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5011 16.4922L0.630617 11.8546C-0.210206 11.4497 -0.210206 10.824 0.630617 10.456L3.99391 8.87329L10.5011 11.9282C11.342 12.3331 12.6946 12.3331 13.4989 11.9282L20.0061 8.87329L23.3694 10.456C24.2102 10.8608 24.2102 11.4865 23.3694 11.8546L13.4989 16.4922C12.658 16.897 11.3054 16.897 10.5011 16.4922Z" fill="#95C038"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5011 10.8195L0.630617 6.24863C-0.210206 5.84959 -0.210206 5.23289 0.630617 4.87013L10.5011 0.299281C11.342 -0.0997605 12.6946 -0.0997605 13.4989 0.299281L23.3694 4.87013C24.2102 5.26917 24.2102 5.88587 23.3694 6.24863L13.4989 10.8195C12.658 11.1822 11.3054 11.1822 10.5011 10.8195Z" fill="#5DC0E8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,5 @@
|
||||
<svg width="20" height="14" viewBox="0 0 20 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="20" height="2" rx="1" fill="white"/>
|
||||
<rect y="6" width="20" height="2" rx="1" fill="white"/>
|
||||
<rect y="12" width="20" height="2" rx="1" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 278 B |
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 17C13 17.5523 12.5523 18 12 18C11.4477 18 11 17.5523 11 17V13H7C6.44772 13 6 12.5523 6 12C6 11.4477 6.44772 11 7 11H11V7C11 6.44772 11.4477 6 12 6C12.5523 6 13 6.44772 13 7V11H17C17.5523 11 18 11.4477 18 12C18 12.5523 17.5523 13 17 13H13V17Z" fill="#444444"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 416 B |
@ -79,7 +79,8 @@
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
@ -119,7 +120,8 @@
|
||||
.contentCells-icon{
|
||||
width: 5%;
|
||||
}
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 55%;
|
||||
}
|
||||
|
||||
@ -175,7 +177,8 @@
|
||||
}
|
||||
|
||||
@media (max-width: 715px) {
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 45%;
|
||||
}
|
||||
}
|
||||
@ -263,7 +266,8 @@
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
@ -293,7 +297,8 @@
|
||||
width: 580px;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
@ -407,7 +412,8 @@
|
||||
padding: 16px 0 6px;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
@ -538,7 +544,8 @@
|
||||
}
|
||||
|
||||
@media (max-width: 510px) and (min-width: 470px) {
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
@ -564,7 +571,8 @@
|
||||
}
|
||||
|
||||
@media (max-width: 470px) and (min-width: 420px) {
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 30%;
|
||||
}
|
||||
.tableRow td:first-child{
|
||||
@ -599,7 +607,8 @@
|
||||
}
|
||||
|
||||
@media (max-width: 420px) and (min-width: 320px) {
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
@ -649,7 +658,8 @@
|
||||
}
|
||||
}
|
||||
@media (max-width: 769px) and (min-width: 715px){
|
||||
.tableRow{
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
@ -698,3 +708,216 @@
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 592px) and (min-width: 320px) {
|
||||
body.menu-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
header {
|
||||
min-width: auto;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
header a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
header img {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
header, footer {
|
||||
position: -webkit-sticky; /* Safari */
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.center {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
background-color: rgba(186, 186, 186, 0.6);
|
||||
display: none;
|
||||
flex-direction: row;
|
||||
align-items: start;
|
||||
max-width: none;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
height: calc(100% - 124px);
|
||||
z-index:99;
|
||||
}
|
||||
|
||||
.left-panel.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.help-block {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background-color: #F5F5F5;
|
||||
width: 248px;
|
||||
padding-left: 16px;
|
||||
padding-top: 33px;
|
||||
padding-bottom: 33px;
|
||||
padding-right: 40px;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.table-main {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mobile-close-btn {
|
||||
display: block;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-color: #E2E2E2;
|
||||
border-radius: 2px;
|
||||
border-color: #E2E2E2;
|
||||
color: #808080;
|
||||
cursor: pointer;
|
||||
outline: inherit;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.main-panel {
|
||||
width: 100%;
|
||||
left: 0;
|
||||
padding: 28px 16px;
|
||||
}
|
||||
|
||||
#portal-info {
|
||||
width: 100%;
|
||||
max-width: fit-content;
|
||||
}
|
||||
|
||||
menu.links {
|
||||
width: 100%;
|
||||
margin-top: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
span.portal-name {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
span.portal-descr:first-child {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
span.portal-descr {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.user-descr {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
min-width: auto;
|
||||
border-bottom: 1px solid #E5E5E5;
|
||||
padding: 12px 0;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-descr ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.user-descr ul.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.user-descr b {
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 8px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.user-descr b::before {
|
||||
content: url("images/plus.svg");
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.storedHeader {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.storedHeaderClearAll {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.scroll-table-body {
|
||||
top: 36px;
|
||||
}
|
||||
|
||||
.scroll-table-body tr:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
padding: 16px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tableRow td:first-child {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stored-edit span {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.header-list {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.firstContentCellViewers {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.firstContentCellViewers ~ td {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.downloadContentCellShift:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.responsive-nav {
|
||||
height: 44px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 0;
|
||||
align-items: center;
|
||||
column-gap: 16px;
|
||||
padding: 10px 16px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.main {
|
||||
height: calc(100% - 124px);
|
||||
}
|
||||
|
||||
.user-block-table {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,6 +65,14 @@ header img {
|
||||
margin: 10px 0 22px 32px;
|
||||
}
|
||||
|
||||
.responsive-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-close-btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.center {
|
||||
position:relative;
|
||||
margin: 0 auto 0;
|
||||
@ -164,7 +172,7 @@ label .checkbox {
|
||||
}
|
||||
|
||||
.try-editor.form {
|
||||
background-image: url("images/file_docxf.svg");
|
||||
background-image: url("images/file_pdf.svg");
|
||||
}
|
||||
|
||||
.side-option {
|
||||
@ -298,6 +306,43 @@ label .checkbox {
|
||||
border-bottom: 1px solid #D0D5DA;
|
||||
}
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
padding: 0;
|
||||
column-gap: 30px;
|
||||
align-items: center;
|
||||
list-style: none;
|
||||
border-bottom: 1px solid #E2E2E2;
|
||||
margin: 0;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.links li {
|
||||
padding: 4px;
|
||||
border-bottom: 2px solid transparent;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.links li.active {
|
||||
border-bottom: 2px solid #FF6F3D;
|
||||
}
|
||||
|
||||
.links li.active a {
|
||||
color: #FF6F3D;
|
||||
}
|
||||
|
||||
.links li.active a img {
|
||||
filter: invert(55%) sepia(67%) saturate(2727%) hue-rotate(335deg) brightness(104%) contrast(101%);
|
||||
}
|
||||
|
||||
.links a {
|
||||
display: inline-block;
|
||||
padding: 2px 0;
|
||||
line-height: 20px;
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#mainProgress {
|
||||
color: #333333;
|
||||
display: none;
|
||||
@ -491,6 +536,11 @@ footer table tr td:first-child {
|
||||
background-image: url("images/icon_pptx.svg");
|
||||
}
|
||||
|
||||
.stored-edit.pdf,
|
||||
.uploadFileName.pdf {
|
||||
background-image: url("images/icon_pdf.svg");
|
||||
}
|
||||
|
||||
.stored-edit span {
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
|
||||
@ -17,10 +17,13 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Web.Mvc;
|
||||
using OnlineEditorsExampleMVC.Helpers;
|
||||
using OnlineEditorsExampleMVC.Models;
|
||||
using System.Web.Configuration;
|
||||
|
||||
namespace OnlineEditorsExampleMVC.Controllers
|
||||
{
|
||||
@ -31,6 +34,46 @@ namespace OnlineEditorsExampleMVC.Controllers
|
||||
return View();
|
||||
}
|
||||
|
||||
public ActionResult Forgotten()
|
||||
{
|
||||
if (!bool.Parse(WebConfigurationManager.AppSettings["enable-forgotten"]))
|
||||
{
|
||||
ViewData["Message"] = "The forgotten page is disabled";
|
||||
return View("~/Views/Shared/Error.aspx");
|
||||
}
|
||||
|
||||
var files = new List<Dictionary<string, string>>();
|
||||
|
||||
try
|
||||
{
|
||||
var response = TrackManager.commandRequest("getForgottenList", null);
|
||||
ArrayList keys = (ArrayList)response["keys"];
|
||||
|
||||
// fetch all the forgotten files from the document server
|
||||
foreach (string key in keys)
|
||||
{
|
||||
var file = new Dictionary<string, string>();
|
||||
var fileResult = TrackManager.commandRequest("getForgotten", key);
|
||||
file.Add("key", fileResult["key"].ToString());
|
||||
file.Add("url", fileResult["url"].ToString());
|
||||
file.Add(
|
||||
"type",
|
||||
FileUtility.GetFileType(fileResult["url"].ToString())
|
||||
.ToString()
|
||||
.ToLower()
|
||||
);
|
||||
|
||||
files.Add(file);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
return View("Forgotten", new ForgottenFilesModel(files));
|
||||
}
|
||||
|
||||
// viewing file in the editor
|
||||
public ActionResult Editor(string fileName, string editorsMode, string editorsType, string directUrl)
|
||||
{
|
||||
@ -52,7 +95,7 @@ namespace OnlineEditorsExampleMVC.Controllers
|
||||
var id = Request.Cookies.GetOrDefault("uid", null);
|
||||
var user = Users.getUser(id);
|
||||
DocManagerHelper.CreateMeta(fileName, user.id, user.name); // create meta information for the sample document
|
||||
Response.Redirect(Url.Action("Editor", "Home", new { fileName = fileName }));
|
||||
Response.Redirect(Url.Action("Editor", "Home", new { fileName = fileName, editorsMode="edit" }));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,7 +282,7 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
}
|
||||
|
||||
// create a command request
|
||||
public static void commandRequest(string method, string key, object meta = null)
|
||||
public static Dictionary<string, object> commandRequest(string method, string key, object meta = null)
|
||||
{
|
||||
DocManagerHelper.VerifySSL();
|
||||
|
||||
@ -345,6 +345,7 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
{
|
||||
throw new Exception(dataResponse);
|
||||
}
|
||||
return responseObj;
|
||||
}
|
||||
|
||||
// save file
|
||||
|
||||
@ -77,18 +77,19 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
var jss = new JavaScriptSerializer();
|
||||
|
||||
var ext = Path.GetExtension(FileName).ToLower(); // get file extension
|
||||
var editorsMode = Mode ?? "edit"; // get editor mode
|
||||
var canFill = DocManagerHelper.FillFormExts.Contains(ext);
|
||||
var editorsMode = Mode ?? (canFill ? "fillForms" : "edit"); // get editor mode
|
||||
|
||||
var canEdit = DocManagerHelper.EditedExts.Contains(ext); // check if the file with such an extension can be edited
|
||||
|
||||
var id = request.Cookies.GetOrDefault("uid", null);
|
||||
var user = Users.getUser(id); // get the user
|
||||
|
||||
if ((!canEdit && editorsMode.Equals("edit") || editorsMode.Equals("fillForms")) && DocManagerHelper.FillFormExts.Contains(ext)) {
|
||||
if ((!canEdit && editorsMode.Equals("edit") || editorsMode.Equals("fillForms")) && canFill) {
|
||||
editorsMode = "fillForms";
|
||||
canEdit = true;
|
||||
}
|
||||
var submitForm = editorsMode.Equals("fillForms") && id.Equals("uid-1"); // check if the Submit form button is displayed or not
|
||||
var submitForm = (editorsMode.Equals("fillForms") || editorsMode.Equals("embedded")) && user.id.Equals("uid-1"); // check if the Submit form button is displayed or not
|
||||
var mode = canEdit && editorsMode != "view" ? "edit" : "view"; // set the mode parameter: change it to view if the document can't be edited
|
||||
|
||||
// favorite icon state
|
||||
|
||||
@ -33,7 +33,8 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
{
|
||||
Word,
|
||||
Cell,
|
||||
Slide
|
||||
Slide,
|
||||
Pdf
|
||||
}
|
||||
|
||||
// get file type
|
||||
@ -41,6 +42,7 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
{
|
||||
var ext = Path.GetExtension(fileName).ToLower();
|
||||
|
||||
if (FormatManager.PdfExtensions().Contains(ext)) return FileType.Pdf; // pdf type for document extensions
|
||||
if (FormatManager.DocumentExtensions().Contains(ext)) return FileType.Word; // word type for document extensions
|
||||
if (FormatManager.SpreadsheetExtensions().Contains(ext)) return FileType.Cell; // cell type for spreadsheet extensions
|
||||
if (FormatManager.PresentationExtensions().Contains(ext)) return FileType.Slide; // slide type for presentation extensions
|
||||
@ -185,6 +187,20 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static List<string> PdfExtensions()
|
||||
{
|
||||
return Pdfs()
|
||||
.Select(format => format.Extension())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static List<Format> Pdfs()
|
||||
{
|
||||
return All()
|
||||
.Where(format => format.Type == FileType.Pdf)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static List<string> AllExtensions()
|
||||
{
|
||||
return All()
|
||||
|
||||
30
web/documentserver-example/csharp-mvc/Models/ForgottenFilesModel.cs
Executable file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OnlineEditorsExampleMVC.Models
|
||||
{
|
||||
// create file model
|
||||
public class ForgottenFilesModel
|
||||
{
|
||||
public List<Dictionary<string, string>> files { get; set; }
|
||||
|
||||
public ForgottenFilesModel(List<Dictionary<string, string>> files) { this.files = files; }
|
||||
}
|
||||
}
|
||||
@ -116,6 +116,7 @@
|
||||
<Compile Include="Helpers\Utils.cs" />
|
||||
<Compile Include="Models\FileModel.cs" />
|
||||
<Compile Include="Models\FileUtility.cs" />
|
||||
<Compile Include="Models\ForgottenFilesModel.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="WebEditor.ashx.cs">
|
||||
<DependentUpon>WebEditor.ashx</DependentUpon>
|
||||
@ -123,6 +124,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\editor.css" />
|
||||
<Content Include="Content\forgotten.css" />
|
||||
<Content Include="Content\images\block-content.svg" />
|
||||
<Content Include="Content\images\cell.ico" />
|
||||
<Content Include="Content\images\close.svg" />
|
||||
@ -140,6 +142,7 @@
|
||||
<Content Include="Content\images\file_xlsx.svg" />
|
||||
<Content Include="Content\images\fill-forms.svg" />
|
||||
<Content Include="Content\images\filter.svg" />
|
||||
<Content Include="Content\images\home.svg" />
|
||||
<Content Include="Content\images\icon_docx.svg" />
|
||||
<Content Include="Content\images\icon_pptx.svg" />
|
||||
<Content Include="Content\images\icon_xlsx.svg" />
|
||||
@ -151,6 +154,8 @@
|
||||
<Content Include="Content\images\notdone.svg" />
|
||||
<Content Include="Content\images\review.svg" />
|
||||
<Content Include="Content\images\slide.ico" />
|
||||
<Content Include="Content\images\uid-1.png" />
|
||||
<Content Include="Content\images\uid-2.png" />
|
||||
<Content Include="Content\images\word.ico" />
|
||||
<Content Include="Content\jquery-ui.css" />
|
||||
<Content Include="Content\media.css" />
|
||||
@ -158,6 +163,10 @@
|
||||
<Content Include="favicon.ico" />
|
||||
<Content Include="Global.asax" />
|
||||
<Content Include="LICENSE" />
|
||||
<Content Include="Scripts\forgotten.js" />
|
||||
<Content Include="Scripts\formats.js" />
|
||||
<Content Include="Scripts\jquery-3.6.4.js" />
|
||||
<Content Include="Scripts\jquery-migrate-3.4.1.js" />
|
||||
<Content Include="Scripts\jquery-ui.js" />
|
||||
<Content Include="Scripts\jquery.blockUI.js" />
|
||||
<Content Include="Scripts\jquery.dropdownToggle.js" />
|
||||
@ -165,17 +174,13 @@
|
||||
<Content Include="Scripts\jquery.iframe-transport.js" />
|
||||
<Content Include="Scripts\jscript.js" />
|
||||
<Content Include="Views\Home\Editor.aspx" />
|
||||
<Content Include="Views\Home\Forgotten.aspx" />
|
||||
<Content Include="Views\Home\Index.aspx" />
|
||||
<Content Include="Web.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="Views\Web.config" />
|
||||
<Content Include="Views\Shared\Error.aspx" />
|
||||
<Content Include="licenses\EntityFramework.license" />
|
||||
<Content Include="licenses\Microsoft.Web.Infrastructure.license" />
|
||||
<Content Include="licenses\Newtonsoft.Json.license" />
|
||||
<Content Include="licenses\jquery.license" />
|
||||
<Content Include="licenses\WebGrease.license" />
|
||||
<Content Include="web.appsettings.config" />
|
||||
<Content Include="WebEditor.ashx" />
|
||||
</ItemGroup>
|
||||
|
||||
19
web/documentserver-example/csharp-mvc/Scripts/forgotten.js
Executable file
@ -0,0 +1,19 @@
|
||||
function deleteFile(event) {
|
||||
let filename = event.currentTarget.getAttribute("data");
|
||||
filename = encodeURIComponent(filename);
|
||||
let url = `webeditor.ashx?type=removeforgotten&filename=${filename}`;
|
||||
|
||||
fetch(url, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
}).then(result => {
|
||||
if(result.status == 204) {
|
||||
document.location.reload(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.querySelectorAll('.delete-file').forEach(el => {
|
||||
el.addEventListener('click', deleteFile);
|
||||
});
|
||||
@ -421,4 +421,27 @@ if (typeof jQuery != "undefined") {
|
||||
}).mouseout(function () {
|
||||
jq("div.tooltip").remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSidePanel(event) {
|
||||
event.preventDefault();
|
||||
let sidePanel = document.querySelector(".left-panel");
|
||||
let body = document.querySelector("body");
|
||||
if (sidePanel.classList.contains("active")) {
|
||||
sidePanel.classList.remove("active");
|
||||
body.classList.remove("menu-open");
|
||||
} else {
|
||||
sidePanel.classList.add("active")
|
||||
body.classList.add("menu-open");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleUserDescr(event) {
|
||||
let list = event.currentTarget.querySelector("ul");
|
||||
let cursor = window.getComputedStyle(event.currentTarget).getPropertyValue("cursor");
|
||||
|
||||
if (cursor === "pointer") {
|
||||
if (list.classList.contains("active")) list.classList.remove("active");
|
||||
else list.classList.add("active");
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@
|
||||
|
||||
// the user is trying to switch the document from the viewing into the editing mode
|
||||
var onRequestEditRights = function () {
|
||||
location.href = location.href.replace(RegExp("editorsMode=view\&?", "i"), "");
|
||||
location.href = location.href.replace(RegExp("editorsMode=\\w+\&?", "i"), "") + "&editorsMode=edit";
|
||||
};
|
||||
|
||||
// an error or some other specific event occurs
|
||||
@ -108,7 +108,7 @@
|
||||
|
||||
// the meta information of the document is changed via the meta command
|
||||
var onMetaChange = function (event) {
|
||||
if (event.data.favorite) {
|
||||
if (event.data.favorite !== undefined) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
|
||||
144
web/documentserver-example/csharp-mvc/Views/Home/Forgotten.aspx
Executable file
@ -0,0 +1,144 @@
|
||||
<%@ Page Title="ONLYOFFICE" Language="C#" Inherits="System.Web.Mvc.ViewPage<OnlineEditorsExampleMVC.Models.ForgottenFilesModel>" %>
|
||||
|
||||
<%@ Import Namespace="System.IO" %>
|
||||
<%@ Import Namespace="System.Web.Configuration" %>
|
||||
<%@ Import Namespace="OnlineEditorsExampleMVC.Helpers" %>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html lang="en">
|
||||
<head runat="server">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="server-version" content=<%= DocManagerHelper.GetVersion() %> />
|
||||
<!--
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
-->
|
||||
<title>ONLYOFFICE</title>
|
||||
|
||||
<link href="<%: Url.Content("~/favicon.ico") %>" rel="shortcut icon" type="image/x-icon" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans:900,800,700,600,500,400,300&subset=latin,cyrillic-ext,cyrillic,latin-ext" />
|
||||
|
||||
<%: Styles.Render("~/Content/css") %>
|
||||
<%: Styles.Render("~/Content/forgotten") %>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="center main-nav">
|
||||
<a href="./">
|
||||
<img src ="content/images/logo.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</div>
|
||||
<menu class="responsive-nav">
|
||||
<li>
|
||||
<a href="#" onclick="toggleSidePanel(event)">
|
||||
<img src="content/images/mobile-menu.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="./">
|
||||
<img src ="content/images/mobile-logo.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</li>
|
||||
</menu>
|
||||
</header>
|
||||
|
||||
<div class="center main">
|
||||
<table class="table-main">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="left-panel section"></td>
|
||||
<td class="section">
|
||||
<div class="main-panel">
|
||||
<menu class="links">
|
||||
<li class="home-link" >
|
||||
<a href="./">
|
||||
<img src="content/images/home.svg" alt="Home"/>
|
||||
</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<a href="/Forgotten">Forgotten files</a>
|
||||
</li>
|
||||
</menu>
|
||||
<div class="stored-list">
|
||||
<div class="storedHeader">
|
||||
<div class="storedHeaderText">
|
||||
<span class="header-list">Forgotten files</span>
|
||||
</div>
|
||||
</div>
|
||||
<table class="tableHeader" cellspacing="0" cellpadding="0" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="tableHeaderCell">Filename</td>
|
||||
<td class="tableHeaderCell">Action</td>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<div class="scroll-table-body">
|
||||
<table cellspacing="0" cellpadding="0" width="100%">
|
||||
<tbody>
|
||||
<% foreach (var file in Model.files) { %>
|
||||
<tr class="tableRow" title="<%= file["key"] %>">
|
||||
<td>
|
||||
<a class="stored-edit action-link <%= file["type"] %>" href="<%= file["url"] %>" target="_blank">
|
||||
<span><%= file["key"] %></span>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<%= file["url"] %>">
|
||||
<img class="icon-download" src="content/images/download.svg" alt="Download" title="Download" /></a>
|
||||
<a class="delete-file" data="<%= file["key"] %>">
|
||||
<img class="icon-action" src="content/images/delete.svg" alt="Delete" title="Delete" /></a>
|
||||
</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div class="center">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="http://api.onlyoffice.com/editors/howitworks" target="_blank">API Documentation</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="mailto:sales@onlyoffice.com">Submit your request</a>
|
||||
</td>
|
||||
<td class="copy">
|
||||
© Ascensio System SIA <%= DateTime.Now.Year.ToString() %>. All rights reserved.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<%: Scripts.Render("~/bundles/jquery", "~/bundles/forgotten") %>
|
||||
</body>
|
||||
</html>
|
||||
@ -41,11 +41,23 @@
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="center">
|
||||
<a href="">
|
||||
<div class="center main-nav">
|
||||
<a href="./">
|
||||
<img src ="content/images/logo.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</div>
|
||||
<menu class="responsive-nav">
|
||||
<li>
|
||||
<a href="#" onclick="toggleSidePanel(event)">
|
||||
<img src="content/images/mobile-menu.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="./">
|
||||
<img src ="content/images/mobile-logo.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</li>
|
||||
</menu>
|
||||
</header>
|
||||
|
||||
<div class="center main">
|
||||
@ -68,7 +80,7 @@
|
||||
<a class="try-editor slide" data-type="pptx">Presentation</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="try-editor form" data-type="docxf">PDF form</a>
|
||||
<a class="try-editor form" data-type="pdf">PDF form</a>
|
||||
</li>
|
||||
</ul>
|
||||
<label class="side-option">
|
||||
@ -122,9 +134,24 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button class="mobile-close-btn" onclick="toggleSidePanel(event)">
|
||||
<img src="content/images/close.svg" alt="">
|
||||
</button>
|
||||
</td>
|
||||
<td class="section">
|
||||
<div class="main-panel">
|
||||
<menu class="links">
|
||||
<li class="home-link active" >
|
||||
<a href="./">
|
||||
<img src="content/images/home.svg" alt="Home"/>
|
||||
</a>
|
||||
</li>
|
||||
<% if (bool.Parse(WebConfigurationManager.AppSettings["enable-forgotten"])) { %>
|
||||
<li>
|
||||
<a href="/Forgotten">Forgotten files</a>
|
||||
</li>
|
||||
<% } %>
|
||||
</menu>
|
||||
<% var storedFiles = DocManagerHelper.GetStoredFiles(); %>
|
||||
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "table-cell" %>">
|
||||
<span class="portal-name">ONLYOFFICE Document Editors – Welcome!</span>
|
||||
@ -136,7 +163,7 @@
|
||||
<span class="portal-descr">You can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</span>
|
||||
<% foreach (User user in Users.getAllUsers())
|
||||
{ %>
|
||||
<div class="user-descr">
|
||||
<div class="user-descr" onclick="toggleUserDescr(event)">
|
||||
<b><%= user.name.IsEmpty() ? "Anonymous" : user.name %></b>
|
||||
<ul>
|
||||
<% foreach (string description in user.descriptions)
|
||||
@ -200,11 +227,13 @@
|
||||
<img src="content/images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
|
||||
</a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "comment", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
|
||||
</a>
|
||||
</td>
|
||||
<% if (docType != "pdf") { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "comment", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
|
||||
</a>
|
||||
</td>
|
||||
<% } %>
|
||||
<% if (docType == "word") { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "review", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
<hgroup>
|
||||
<h1>Error.</h1>
|
||||
<h2>An error occurred while processing your request.</h2>
|
||||
<p><%= ViewData["Message"] %></p>
|
||||
</hgroup>
|
||||
</body>
|
||||
</html>
|
||||
@ -69,6 +69,9 @@ namespace OnlineEditorsExampleMVC
|
||||
case "remove":
|
||||
Remove(context);
|
||||
break;
|
||||
case "removeforgotten":
|
||||
RemoveForgotten(context);
|
||||
break;
|
||||
case "assets":
|
||||
Assets(context);
|
||||
break;
|
||||
@ -996,6 +999,32 @@ namespace OnlineEditorsExampleMVC
|
||||
context.Response.Write("{ \"error\": \"" + e.Message + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
// delete a forgotten file from the document server
|
||||
private static void RemoveForgotten(HttpContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!bool.Parse(WebConfigurationManager.AppSettings["enable-forgotten"]))
|
||||
{
|
||||
throw new HttpException(403, "The forgotten page is disabled");
|
||||
}
|
||||
|
||||
string filename = context.Request["filename"];
|
||||
|
||||
if (!String.IsNullOrEmpty(filename))
|
||||
{
|
||||
TrackManager.commandRequest("deleteForgotten", filename);
|
||||
}
|
||||
|
||||
context.Response.StatusCode = 204;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
context.Response.StatusCode = 500;
|
||||
context.Response.Write("{ \"error\": \"" + e.Message + "\"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,11 +1,12 @@
|
||||
<?xml version="1.0"?>
|
||||
<appSettings>
|
||||
<clear />
|
||||
<add key="version" value="1.8.0"/>
|
||||
<add key="version" value="1.10.0"/>
|
||||
|
||||
<add key="filesize-max" value="52428800"/>
|
||||
<add key="storage-path" value=""/>
|
||||
<add key="filename-max" value="50"/>
|
||||
<add key="enable-forgotten" value="true"/>
|
||||
|
||||
<add key="files.docservice.timeout" value="120000" />
|
||||
<add key="files.docservice.secret" value="" />
|
||||
@ -15,7 +16,7 @@
|
||||
|
||||
<add key="files.docservice.verify-peer-off" value="true"/>
|
||||
|
||||
<add key="files.docservice.languages" value="en:English|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Latn-RS:Serbian|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA:Test Language"/>
|
||||
<add key="files.docservice.languages" value="en:English|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Cyrl-RS:Serbian (Cyrillic)|sr-Latn-RS:Serbian (Latin)|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA:Test Language"/>
|
||||
|
||||
<add key="files.docservice.url.site" value="http://documentserver/"/>
|
||||
|
||||
|
||||
161
web/documentserver-example/csharp/App_Themes/forgotten.css
Executable file
@ -0,0 +1,161 @@
|
||||
.center {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
width: 256px;
|
||||
}
|
||||
|
||||
.main-panel {
|
||||
width: 832px;
|
||||
margin: 0 32px;
|
||||
padding: 48px 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #E2E2E2;
|
||||
}
|
||||
|
||||
.tableRow td:first-child {
|
||||
width: 70%;
|
||||
flex-grow: 0;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.tableHeader td:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tableHeader td:last-child, .tableRow td:last-child {
|
||||
width: 10%;
|
||||
text-align: center;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.tableHeader {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stored-edit {
|
||||
display: block;
|
||||
padding-top: 0;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
menu.links {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scroll-table-body table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.stored-edit span {
|
||||
font-size: 12px;
|
||||
line-height: normal;
|
||||
position: static;
|
||||
}
|
||||
|
||||
.scroll-table-body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.stored-list {
|
||||
height: calc(100% - 58px);
|
||||
}
|
||||
|
||||
header {
|
||||
min-width:auto;
|
||||
}
|
||||
|
||||
header a {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
width: 1152px;
|
||||
}
|
||||
|
||||
@media (max-width: 1279px) and (min-width: 1024px) {
|
||||
.left-panel {
|
||||
width: 208px;
|
||||
}
|
||||
|
||||
.main-panel {
|
||||
width: 688px;
|
||||
}
|
||||
|
||||
header a {
|
||||
width: 928px;
|
||||
}
|
||||
|
||||
header img {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) and (min-width: 593px) {
|
||||
.center {
|
||||
max-width: 768px;
|
||||
width: calc(100% - 80px);
|
||||
}
|
||||
|
||||
.table-main {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
width: 208px;
|
||||
}
|
||||
|
||||
.main-panel {
|
||||
width: calc(100% - 32px);
|
||||
}
|
||||
|
||||
.tableHeader td:last-child, .tableRow td:last-child {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
header a {
|
||||
width: 768px;
|
||||
}
|
||||
|
||||
header img {
|
||||
margin-left: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 592px) and (min-width: 320px) {
|
||||
.center, .table-main {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main-panel {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 28px 16px;
|
||||
}
|
||||
|
||||
.tableHeader td:last-child, .tableRow td:last-child {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
header a {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.scroll-table-body {
|
||||
top: 40px;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
padding: 8px 0;
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 3c0-1.65685 1.34315-3 3-3h20l7 7v30c0 1.6569-1.3431 3-3 3H3c-1.65685 0-3-1.3431-3-3V3z" fill="#27ABA3"/><path d="M23 0l7 7h-4c-1.6569 0-3-1.34315-3-3V0z" fill="#008078"/><path fill-rule="evenodd" clip-rule="evenodd" d="M24 14H6v7h18v-7zm-.8182 5.9978H6.81818V15H23.1818v4.9978zM24 23H6v7h18v-7zm-.8182 5.9978H6.81818V24H23.1818v4.9978z" fill="#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 463 B |
@ -0,0 +1,5 @@
|
||||
<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 0H23L30 7V37C30 38.6569 28.6569 40 27 40H3C1.34315 40 0 38.6569 0 37V3Z" fill="#9E1919"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.0062 15V16.0065H24V15H17.0062ZM17.0062 19V20.0163H24V19H17.0062ZM24 23H17.0062V24.0261H24V23ZM6 28V27.0293H24V28H6ZM7 16H14V23H7V16ZM6 15H7H14H15V16V23V24H14H7H6V23V16V15Z" fill="white"/>
|
||||
<path d="M23 0L30 7H26C24.3431 7 23 5.65685 23 4V0Z" fill="black" fill-opacity="0.25"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 558 B |
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="17" viewBox="0 0 20 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 17V11H12V17H17V9H20L10 0L0 9H3V17H8Z" fill="#444444"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 173 B |
@ -0,0 +1 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 1h8l4 4v10H2V1z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M14 5l-4-4H2v14h12V5zm-4-5l5 5v11H1V0h9z" fill="#BFBFBF"/><path fill="#9E1919" d="M3 10h10v4H3z"/><path d="M7 7V2H3v5h4zM8 3V2h2v1H8zM8 5V4h5v1H8zM13 6H8v1h5V6zM13 8H3v1h10V8z" fill="#BFBFBF"/><path opacity=".3" d="M9 1h1v3h4l1 1H9V1z" fill="#333"/></svg>
|
||||
|
After Width: | Height: | Size: 441 B |
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="23" viewBox="0 0 24 23" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5332 22.2243L0.632544 17.5921C-0.210848 17.1877 -0.210848 16.5627 0.632544 16.1951L4.07945 14.5775L10.4966 17.5921C11.34 17.9965 12.6967 17.9965 13.5034 17.5921L19.9206 14.5775L23.3675 16.1951C24.2108 16.5995 24.2108 17.2245 23.3675 17.5921L13.4668 22.2243C12.6967 22.592 11.34 22.592 10.5332 22.2243Z" fill="#FF6F3D"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5011 16.4922L0.630617 11.8546C-0.210206 11.4497 -0.210206 10.824 0.630617 10.456L3.99391 8.87329L10.5011 11.9282C11.342 12.3331 12.6946 12.3331 13.4989 11.9282L20.0061 8.87329L23.3694 10.456C24.2102 10.8608 24.2102 11.4865 23.3694 11.8546L13.4989 16.4922C12.658 16.897 11.3054 16.897 10.5011 16.4922Z" fill="#95C038"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5011 10.8195L0.630617 6.24863C-0.210206 5.84959 -0.210206 5.23289 0.630617 4.87013L10.5011 0.299281C11.342 -0.0997605 12.6946 -0.0997605 13.4989 0.299281L23.3694 4.87013C24.2102 5.26917 24.2102 5.88587 23.3694 6.24863L13.4989 10.8195C12.658 11.1822 11.3054 11.1822 10.5011 10.8195Z" fill="#5DC0E8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,5 @@
|
||||
<svg width="20" height="14" viewBox="0 0 20 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="20" height="2" rx="1" fill="white"/>
|
||||
<rect y="6" width="20" height="2" rx="1" fill="white"/>
|
||||
<rect y="12" width="20" height="2" rx="1" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 278 B |
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 17C13 17.5523 12.5523 18 12 18C11.4477 18 11 17.5523 11 17V13H7C6.44772 13 6 12.5523 6 12C6 11.4477 6.44772 11 7 11H11V7C11 6.44772 11.4477 6 12 6C12.5523 6 13 6.44772 13 7V11H17C17.5523 11 18 11.4477 18 12C18 12.5523 17.5523 13 17 13H13V17Z" fill="#444444"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 416 B |
@ -79,7 +79,8 @@
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
@ -119,7 +120,8 @@
|
||||
.contentCells-icon{
|
||||
width: 5%;
|
||||
}
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 55%;
|
||||
}
|
||||
|
||||
@ -175,7 +177,8 @@
|
||||
}
|
||||
|
||||
@media (max-width: 715px) {
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 45%;
|
||||
}
|
||||
}
|
||||
@ -263,7 +266,8 @@
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
@ -293,7 +297,8 @@
|
||||
width: 580px;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
@ -407,7 +412,8 @@
|
||||
padding: 16px 0 6px;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
@ -538,7 +544,8 @@
|
||||
}
|
||||
|
||||
@media (max-width: 510px) and (min-width: 470px) {
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
@ -564,7 +571,8 @@
|
||||
}
|
||||
|
||||
@media (max-width: 470px) and (min-width: 420px) {
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 30%;
|
||||
}
|
||||
.tableRow td:first-child{
|
||||
@ -599,7 +607,8 @@
|
||||
}
|
||||
|
||||
@media (max-width: 420px) and (min-width: 320px) {
|
||||
.tableRow {
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
@ -649,7 +658,8 @@
|
||||
}
|
||||
}
|
||||
@media (max-width: 769px) and (min-width: 715px){
|
||||
.tableRow{
|
||||
.tableRow,
|
||||
menu.links {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
@ -698,3 +708,216 @@
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 592px) and (min-width: 320px) {
|
||||
body.menu-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
header {
|
||||
min-width: auto;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
header a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
header img {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
header, footer {
|
||||
position: -webkit-sticky; /* Safari */
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.center {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
background-color: rgba(186, 186, 186, 0.6);
|
||||
display: none;
|
||||
flex-direction: row;
|
||||
align-items: start;
|
||||
max-width: none;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
height: calc(100% - 124px);
|
||||
z-index:99;
|
||||
}
|
||||
|
||||
.left-panel.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.help-block {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background-color: #F5F5F5;
|
||||
width: 248px;
|
||||
padding-left: 16px;
|
||||
padding-top: 33px;
|
||||
padding-bottom: 33px;
|
||||
padding-right: 40px;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.table-main {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mobile-close-btn {
|
||||
display: block;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-color: #E2E2E2;
|
||||
border-radius: 2px;
|
||||
border-color: #E2E2E2;
|
||||
color: #808080;
|
||||
cursor: pointer;
|
||||
outline: inherit;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.main-panel {
|
||||
width: 100%;
|
||||
left: 0;
|
||||
padding: 28px 16px;
|
||||
}
|
||||
|
||||
#portal-info {
|
||||
width: 100%;
|
||||
max-width: fit-content;
|
||||
}
|
||||
|
||||
menu.links {
|
||||
width: 100%;
|
||||
margin-top: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
span.portal-name {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
span.portal-descr:first-child {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
span.portal-descr {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.user-descr {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
min-width: auto;
|
||||
border-bottom: 1px solid #E5E5E5;
|
||||
padding: 12px 0;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-descr ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.user-descr ul.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.user-descr b {
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 8px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.user-descr b::before {
|
||||
content: url("images/plus.svg");
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.storedHeader {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.storedHeaderClearAll {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.scroll-table-body {
|
||||
top: 36px;
|
||||
}
|
||||
|
||||
.scroll-table-body tr:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
padding: 16px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tableRow td:first-child {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stored-edit span {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.header-list {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.firstContentCellViewers {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.firstContentCellViewers ~ td {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.downloadContentCellShift:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.responsive-nav {
|
||||
height: 44px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 0;
|
||||
align-items: center;
|
||||
column-gap: 16px;
|
||||
padding: 10px 16px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.main {
|
||||
height: calc(100% - 124px);
|
||||
}
|
||||
|
||||
.user-block-table {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,6 +65,14 @@ header img {
|
||||
margin: 10px 0 22px 32px;
|
||||
}
|
||||
|
||||
.responsive-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-close-btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.center {
|
||||
position: relative;
|
||||
margin: 0 auto 0;
|
||||
@ -164,7 +172,7 @@ label .checkbox {
|
||||
}
|
||||
|
||||
.try-editor.form {
|
||||
background-image: url("images/file_docxf.svg");
|
||||
background-image: url("images/file_pdf.svg");
|
||||
}
|
||||
|
||||
.side-option {
|
||||
@ -298,6 +306,43 @@ label .checkbox {
|
||||
border-bottom: 1px solid #D0D5DA;
|
||||
}
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
padding: 0;
|
||||
column-gap: 30px;
|
||||
align-items: center;
|
||||
list-style: none;
|
||||
border-bottom: 1px solid #E2E2E2;
|
||||
margin: 0;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.links li {
|
||||
padding: 4px;
|
||||
border-bottom: 2px solid transparent;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.links li.active {
|
||||
border-bottom: 2px solid #FF6F3D;
|
||||
}
|
||||
|
||||
.links li.active a {
|
||||
color: #FF6F3D;
|
||||
}
|
||||
|
||||
.links li.active a img {
|
||||
filter: invert(55%) sepia(67%) saturate(2727%) hue-rotate(335deg) brightness(104%) contrast(101%);
|
||||
}
|
||||
|
||||
.links a {
|
||||
display: inline-block;
|
||||
padding: 2px 0;
|
||||
line-height: 20px;
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#mainProgress {
|
||||
color: #333333;
|
||||
display: none;
|
||||
@ -495,6 +540,11 @@ footer a:hover {
|
||||
background-image: url("images/icon_pptx.svg");
|
||||
}
|
||||
|
||||
.stored-edit.pdf,
|
||||
.uploadFileName.pdf {
|
||||
background-image: url("images/icon_pdf.svg");
|
||||
}
|
||||
|
||||
.stored-edit span {
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
|
||||
@ -45,11 +45,23 @@
|
||||
<body>
|
||||
<form id="form1" runat="server">
|
||||
<header>
|
||||
<div class="center">
|
||||
<a href="">
|
||||
<div class="center main-nav">
|
||||
<a href="./">
|
||||
<img src ="app_themes/images/logo.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</div>
|
||||
<menu class="responsive-nav">
|
||||
<li>
|
||||
<a href="#" onclick="toggleSidePanel(event)">
|
||||
<img src="app_themes/images/mobile-menu.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="./">
|
||||
<img src ="app_themes/images/mobile-logo.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</li>
|
||||
</menu>
|
||||
</header>
|
||||
<div class="center main">
|
||||
<table class="table-main">
|
||||
@ -71,7 +83,7 @@
|
||||
<a class="try-editor slide" data-type="slide">Presentation</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="try-editor form" data-type="docxf">PDF form</a>
|
||||
<a class="try-editor form" data-type="pdf">PDF form</a>
|
||||
</li>
|
||||
</ul>
|
||||
<label class="side-option">
|
||||
@ -124,10 +136,25 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button class="mobile-close-btn" onclick="toggleSidePanel(event)">
|
||||
<img src="app_themes/images/close.svg" alt="">
|
||||
</button>
|
||||
</td>
|
||||
<td class="section">
|
||||
<% var storedFiles = GetStoredFiles(); %>
|
||||
<div class="main-panel">
|
||||
<menu class="links">
|
||||
<li class="home-link active" >
|
||||
<a href="./">
|
||||
<img src="app_themes/images/home.svg" alt="Home"/>
|
||||
</a>
|
||||
</li>
|
||||
<% if (bool.Parse(WebConfigurationManager.AppSettings["enable-forgotten"])) { %>
|
||||
<li>
|
||||
<a href="/Forgotten.aspx">Forgotten files</a>
|
||||
</li>
|
||||
<% } %>
|
||||
</menu>
|
||||
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "table-cell" %>">
|
||||
<span class="portal-name">ONLYOFFICE Document Editors – Welcome!</span>
|
||||
<span class="portal-descr">
|
||||
@ -138,7 +165,7 @@
|
||||
<span class="portal-descr">You can open the same document using different users in different Web browser sessions, so you can check out multi-user editing functions.</span>
|
||||
<% foreach (User user in Users.getAllUsers())
|
||||
{ %>
|
||||
<div class="user-descr">
|
||||
<div class="user-descr" onclick="toggleUserDescr(event)">
|
||||
<b><%= user.name.IsEmpty() ? "Anonymous" : user.name %></b>
|
||||
<ul>
|
||||
<% foreach (string description in user.descriptions)
|
||||
@ -202,11 +229,13 @@
|
||||
<img src="app_themes/images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
|
||||
</a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=comment" %>" target="_blank">
|
||||
<img src="app_themes/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
|
||||
</a>
|
||||
</td>
|
||||
<% if (docType != "pdf") { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=comment" %>" target="_blank">
|
||||
<img src="app_themes/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
|
||||
</a>
|
||||
</td>
|
||||
<% } %>
|
||||
<% if (docType == "word") { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=review" %>" target="_blank">
|
||||
|
||||
@ -250,6 +250,7 @@ namespace OnlineEditorsExample
|
||||
{
|
||||
var ext = Path.GetExtension(fileName).ToLower();
|
||||
|
||||
if (FormatManager.PdfExtensions().Contains(ext)) return "pdf"; // pdf for pdf extensions
|
||||
if (FormatManager.DocumentExtensions().Contains(ext)) return "word"; // word for text document extensions
|
||||
if (FormatManager.SpreadsheetExtensions().Contains(ext)) return "cell"; // cell for spreadsheet extensions
|
||||
if (FormatManager.PresentationExtensions().Contains(ext)) return "slide"; // slide for presentation extensions
|
||||
|
||||
@ -86,7 +86,7 @@
|
||||
|
||||
// the user is trying to switch the document from the viewing into the editing mode
|
||||
var onRequestEditRights = function () {
|
||||
location.href = location.href.replace(RegExp("editorsMode=view\&?", "i"), "");
|
||||
location.href = location.href.replace(RegExp("editorsMode=\\w+\&?", "i"), "") + "&editorsMode=edit";
|
||||
};
|
||||
|
||||
// an error or some other specific event occurs
|
||||
@ -126,7 +126,7 @@
|
||||
|
||||
// the meta information of the document is changed via the meta command
|
||||
var onMetaChange = function (event) {
|
||||
if (event.data.favorite) {
|
||||
if (event.data.favorite !== undefined) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
|
||||
@ -135,14 +135,14 @@ namespace OnlineEditorsExample
|
||||
{
|
||||
// create demo document of a specified file type
|
||||
Try(type, Request["sample"], Request);
|
||||
Response.Redirect("doceditor.aspx?fileID=" + HttpUtility.UrlEncode(FileName));
|
||||
Response.Redirect("doceditor.aspx?editorsMode=edit&fileID=" + HttpUtility.UrlEncode(FileName));
|
||||
}
|
||||
|
||||
// get file extension
|
||||
var ext = Path.GetExtension(FileName).ToLower();
|
||||
|
||||
var canFill = _Default.FillFormsExts.Contains(ext);
|
||||
// get editor mode or set the default one (edit)
|
||||
var editorsMode = Request.GetOrDefault("editorsMode", "edit");
|
||||
var editorsMode = Request.GetOrDefault("editorsMode", canFill ? "fillForms" : "edit");
|
||||
|
||||
var canEdit = _Default.EditedExts.Contains(ext); // check if this file can be edited
|
||||
var editorsType = Request.GetOrDefault("editorsType", "desktop");
|
||||
@ -150,11 +150,11 @@ namespace OnlineEditorsExample
|
||||
var id = Request.Cookies.GetOrDefault("uid", null);
|
||||
var user = Users.getUser(id); // get the user
|
||||
|
||||
if ((!canEdit && editorsMode.Equals("edit") || editorsMode.Equals("fillForms")) && _Default.FillFormsExts.Contains(ext)) {
|
||||
if ((!canEdit && editorsMode.Equals("edit") || editorsMode.Equals("fillForms")) && canFill) {
|
||||
editorsMode = "fillForms";
|
||||
canEdit = true;
|
||||
}
|
||||
var submitForm = editorsMode.Equals("fillForms") && id.Equals("uid-1"); // check if the Submit form button is displayed or hidden
|
||||
var submitForm = (editorsMode.Equals("fillForms") || editorsMode.Equals("embedded")) && user.id.Equals("uid-1"); // check if the Submit form button is displayed or hidden
|
||||
var mode = canEdit && editorsMode != "view" ? "edit" : "view"; // get the editor opening mode (edit or view)
|
||||
|
||||
var jss = new JavaScriptSerializer();
|
||||
@ -489,8 +489,8 @@ namespace OnlineEditorsExample
|
||||
case "slide":
|
||||
ext = ".pptx"; // .pptx for slide document type
|
||||
break;
|
||||
case "docxf":
|
||||
ext = ".docxf";
|
||||
case "pdf":
|
||||
ext = ".pdf";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
||||
147
web/documentserver-example/csharp/Forgotten.aspx
Executable file
@ -0,0 +1,147 @@
|
||||
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Forgotten.aspx.cs" Inherits="OnlineEditorsExample.Forgotten" Title="ONLYOFFICE" %>
|
||||
|
||||
<%@ Import Namespace="System.IO" %>
|
||||
<%@ Import Namespace="OnlineEditorsExample" %>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head runat="server">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="server-version" content=<%= GetVersion() %> />
|
||||
<title>ONLYOFFICE</title>
|
||||
<!--
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
-->
|
||||
<link rel="icon" href="~/favicon.ico" type="image/x-icon" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans:900,800,700,600,500,400,300&subset=latin,cyrillic-ext,cyrillic,latin-ext" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="app_themes/stylesheet.css" />
|
||||
<link rel="stylesheet" type="text/css" href="app_themes/media.css" />
|
||||
<link rel="stylesheet" type="text/css" href="app_themes/forgotten.css" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="app_themes/jquery-ui.css" />
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<form id="form1" runat="server">
|
||||
<header>
|
||||
<div class="center main-nav">
|
||||
<a href="./">
|
||||
<img src ="app_themes/images/logo.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</div>
|
||||
<menu class="responsive-nav">
|
||||
<li>
|
||||
<a href="#">
|
||||
<img src="app_themes/images/mobile-menu.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="./">
|
||||
<img src ="app_themes/images/mobile-logo.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</li>
|
||||
</menu>
|
||||
</header>
|
||||
<div class="center main">
|
||||
<table class="table-main">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="left-panel section"></td>
|
||||
<td class="section">
|
||||
<div class="main-panel">
|
||||
<menu class="links">
|
||||
<li class="home-link" >
|
||||
<a href="./">
|
||||
<img src="app_themes/images/home.svg" alt="Home"/>
|
||||
</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<a href="/Forgotten.aspx">Forgotten files</a>
|
||||
</li>
|
||||
</menu>
|
||||
<div class="stored-list">
|
||||
<div class="storedHeader">
|
||||
<div class="storedHeaderText">
|
||||
<span class="header-list">Forgotten files</span>
|
||||
</div>
|
||||
</div>
|
||||
<table class="tableHeader" cellspacing="0" cellpadding="0" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="tableHeaderCell">Filename</td>
|
||||
<td class="tableHeaderCell">Action</td>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<div class="scroll-table-body">
|
||||
<table cellspacing="0" cellpadding="0" width="100%">
|
||||
<tbody>
|
||||
<% foreach (var file in GetForgottenFiles()) { %>
|
||||
<tr class="tableRow" title="<%= file["key"] %>">
|
||||
<td>
|
||||
<a class="stored-edit <%= file["type"] %>" href="<%= file["url"] %>" target="_blank">
|
||||
<span><%= file["key"] %></span>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<%= file["url"] %>">
|
||||
<img class="icon-download" src="app_themes/images/download.svg" alt="Download" title="Download" /></a>
|
||||
<a class="delete-file" data="<%= file["key"] %>">
|
||||
<img class="icon-action" src="app_themes/images/delete.svg" alt="Delete" title="Delete" /></a>
|
||||
</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div class="center">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="http://api.onlyoffice.com/editors/howitworks" target="_blank">API Documentation</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="mailto:sales@onlyoffice.com">Submit your request</a>
|
||||
</td>
|
||||
<td class="copy">
|
||||
© Ascensio System SIA <%= DateTime.Now.Year.ToString() %>. All rights reserved.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</footer>
|
||||
</form>
|
||||
|
||||
<script language="javascript" type="text/javascript" src="script/forgotten.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
96
web/documentserver-example/csharp/Forgotten.aspx.cs
Executable file
@ -0,0 +1,96 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.UI;
|
||||
|
||||
namespace OnlineEditorsExample
|
||||
{
|
||||
public partial class Forgotten : Page
|
||||
{
|
||||
|
||||
//get server version
|
||||
public static string GetVersion()
|
||||
{
|
||||
return WebConfigurationManager.AppSettings["version"];
|
||||
}
|
||||
|
||||
private static bool? _ismono;
|
||||
|
||||
public static bool IsMono
|
||||
{
|
||||
get { return _ismono.HasValue ? _ismono.Value : (_ismono = (bool?)(Type.GetType("Mono.Runtime") != null)).Value; }
|
||||
}
|
||||
|
||||
// get the document type
|
||||
public static string DocumentType(string fileName)
|
||||
{
|
||||
var ext = Path.GetExtension(fileName).ToLower();
|
||||
|
||||
if (FormatManager.DocumentExtensions().Contains(ext)) return "word"; // word for text document extensions
|
||||
if (FormatManager.SpreadsheetExtensions().Contains(ext)) return "cell"; // cell for spreadsheet extensions
|
||||
if (FormatManager.PresentationExtensions().Contains(ext)) return "slide"; // slide for presentation extensions
|
||||
|
||||
return "word"; // the default document type is word
|
||||
}
|
||||
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (!bool.Parse(WebConfigurationManager.AppSettings["enable-forgotten"]))
|
||||
{
|
||||
Response.Clear();
|
||||
Response.StatusCode = 403;
|
||||
Response.End();
|
||||
}
|
||||
}
|
||||
|
||||
// fetch forgotten files from the document server
|
||||
public static List<Dictionary<string, string>> GetForgottenFiles()
|
||||
{
|
||||
var files = new List<Dictionary<string, string>>();
|
||||
|
||||
try
|
||||
{
|
||||
var response = TrackManager.commandRequest("getForgottenList", null);
|
||||
ArrayList keys = (ArrayList) response["keys"];
|
||||
|
||||
// fetch all the forgotten files from the document server
|
||||
foreach (string key in keys)
|
||||
{
|
||||
var file = new Dictionary<string, string>();
|
||||
var fileResult = TrackManager.commandRequest("getForgotten", key);
|
||||
file.Add("key", fileResult["key"].ToString());
|
||||
file.Add("url", fileResult["url"].ToString());
|
||||
file.Add("type", DocumentType(fileResult["url"].ToString()));
|
||||
|
||||
files.Add(file);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
web/documentserver-example/csharp/Forgotten.aspx.designer.cs
generated
Executable file
@ -0,0 +1,24 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace OnlineEditorsExample {
|
||||
|
||||
|
||||
public partial class Forgotten {
|
||||
|
||||
/// <summary>
|
||||
/// form1 control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
|
||||
}
|
||||
}
|
||||
@ -150,6 +150,20 @@ namespace OnlineEditorsExample
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static List<string> PdfExtensions()
|
||||
{
|
||||
return Pdfs()
|
||||
.Select(format => format.Extension())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static List<Format> Pdfs()
|
||||
{
|
||||
return All()
|
||||
.Where(format => format.Type == "pdf")
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static List<string> AllExtensions()
|
||||
{
|
||||
return All()
|
||||
|
||||
@ -77,6 +77,7 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="App_Themes\forgotten.css" />
|
||||
<Content Include="App_Themes\images\block-content.svg" />
|
||||
<Content Include="App_Themes\images\cell.ico" />
|
||||
<Content Include="App_Themes\images\close.svg" />
|
||||
@ -94,6 +95,7 @@
|
||||
<Content Include="App_Themes\images\file_xlsx.svg" />
|
||||
<Content Include="App_Themes\images\fill-forms.svg" />
|
||||
<Content Include="App_Themes\images\filter.svg" />
|
||||
<Content Include="App_Themes\images\home.svg" />
|
||||
<Content Include="App_Themes\images\icon_docx.svg" />
|
||||
<Content Include="App_Themes\images\icon_pptx.svg" />
|
||||
<Content Include="App_Themes\images\icon_xlsx.svg" />
|
||||
@ -104,10 +106,16 @@
|
||||
<Content Include="App_Themes\images\notdone.svg" />
|
||||
<Content Include="App_Themes\images\review.svg" />
|
||||
<Content Include="App_Themes\images\slide.ico" />
|
||||
<Content Include="App_Themes\images\uid-1.png" />
|
||||
<Content Include="App_Themes\images\uid-2.png" />
|
||||
<Content Include="App_Themes\images\word.ico" />
|
||||
<Content Include="App_Themes\media.css" />
|
||||
<Content Include="Forgotten.aspx" />
|
||||
<Content Include="LICENSE" />
|
||||
<Content Include="licenses\jquery.license" />
|
||||
<Content Include="script\forgotten.js" />
|
||||
<Content Include="script\formats.js" />
|
||||
<Content Include="script\jquery-3.6.4.min.js" />
|
||||
<Content Include="script\jquery-migrate-3.4.1.min.js" />
|
||||
<Content Include="Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -119,6 +127,12 @@
|
||||
<DependentUpon>DocEditor.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="DocumentConverter.cs" />
|
||||
<Compile Include="Forgotten.aspx.cs">
|
||||
<DependentUpon>Forgotten.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forgotten.aspx.designer.cs">
|
||||
<DependentUpon>Forgotten.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="FormatManager.cs" />
|
||||
<Compile Include="JwtManager.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
||||
@ -285,7 +285,7 @@ namespace OnlineEditorsExample
|
||||
}
|
||||
|
||||
// create a command request
|
||||
public static void commandRequest(string method, string key, object meta = null)
|
||||
public static Dictionary<string, object> commandRequest(string method, string key, object meta = null)
|
||||
{
|
||||
_Default.VerifySSL();
|
||||
|
||||
@ -348,6 +348,7 @@ namespace OnlineEditorsExample
|
||||
{
|
||||
throw new Exception(dataResponse);
|
||||
}
|
||||
return responseObj;
|
||||
}
|
||||
|
||||
private static void SaveFile(byte[] data, string path)
|
||||
|
||||
@ -69,6 +69,9 @@ namespace OnlineEditorsExample
|
||||
case "remove":
|
||||
Remove(context);
|
||||
break;
|
||||
case "removeforgotten":
|
||||
RemoveForgotten(context);
|
||||
break;
|
||||
case "assets":
|
||||
Assets(context);
|
||||
break;
|
||||
@ -811,5 +814,30 @@ namespace OnlineEditorsExample
|
||||
context.Response.Write("{ \"error\": \"" + e.Message + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
// delete a forgotten file from the document server
|
||||
private static void RemoveForgotten(HttpContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!bool.Parse(WebConfigurationManager.AppSettings["enable-forgotten"]))
|
||||
{
|
||||
throw new HttpException(403, "The forgotten page is disabled");
|
||||
}
|
||||
|
||||
string filename = context.Request["filename"];
|
||||
|
||||
if (!String.IsNullOrEmpty(filename))
|
||||
{
|
||||
TrackManager.commandRequest("deleteForgotten", filename);
|
||||
}
|
||||
|
||||
context.Response.StatusCode = 204;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
context.Response.Write("{ \"error\": \"" + e.Message + "\"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
web/documentserver-example/csharp/script/forgotten.js
Executable file
@ -0,0 +1,19 @@
|
||||
function deleteFile(event) {
|
||||
let filename = event.currentTarget.getAttribute("data");
|
||||
filename = encodeURIComponent(filename);
|
||||
let url = `webeditor.ashx?type=removeforgotten&filename=${filename}`;
|
||||
|
||||
fetch(url, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
}).then(result => {
|
||||
if (result.status == 204) {
|
||||
document.location.reload(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.querySelectorAll('.delete-file').forEach(el => {
|
||||
el.addEventListener('click', deleteFile);
|
||||
});
|
||||
@ -421,4 +421,27 @@ if (typeof jQuery != "undefined") {
|
||||
}).mouseout(function () {
|
||||
jq("div.tooltip").remove();
|
||||
});
|
||||
}
|
||||
|
||||
function toggleSidePanel(event) {
|
||||
event.preventDefault();
|
||||
let sidePanel = document.querySelector(".left-panel");
|
||||
let body = document.querySelector("body");
|
||||
if (sidePanel.classList.contains("active")) {
|
||||
sidePanel.classList.remove("active");
|
||||
body.classList.remove("menu-open");
|
||||
} else {
|
||||
sidePanel.classList.add("active")
|
||||
body.classList.add("menu-open");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleUserDescr(event) {
|
||||
let list = event.currentTarget.querySelector("ul");
|
||||
let cursor = window.getComputedStyle(event.currentTarget).getPropertyValue("cursor");
|
||||
|
||||
if (cursor === "pointer") {
|
||||
if (list.classList.contains("active")) list.classList.remove("active");
|
||||
else list.classList.add("active");
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<appSettings>
|
||||
<clear />
|
||||
<add key="version" value="1.8.0"/>
|
||||
<add key="version" value="1.10.0"/>
|
||||
|
||||
<add key="filesize-max" value="52428800"/>
|
||||
<add key="storage-path" value=""/>
|
||||
<add key="filename-max" value="50"/>
|
||||
<add key="enable-forgotten" value="true"/>
|
||||
|
||||
<add key="files.docservice.timeout" value="120000" />
|
||||
<add key="files.docservice.secret" value="" />
|
||||
@ -14,7 +15,7 @@
|
||||
|
||||
<add key="files.docservice.token.useforrequest" value="true" />
|
||||
|
||||
<add key="files.docservice.languages" value="en:English|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Latn-RS:Serbian|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA: Test Language"/>
|
||||
<add key="files.docservice.languages" value="en:English|ar:Arabic|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|cs:Czech|da:Danish|nl:Dutch|en-GB:English (United Kingdom)|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sr-Cyrl-RS:Serbian (Cyrillic)|sr-Latn-RS:Serbian (Latin)|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA: Test Language"/>
|
||||
|
||||
<add key="files.docservice.url.site" value="http://documentserver/"/>
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
ONLYOFFICE Applications example uses code from the following 3rd party projects:
|
||||
|
||||
|
||||
Gson - Gson is a Java library that can be used to convert Java Objects into their JSON representation. (https://github.com/google/gson/blob/master/LICENSE)
|
||||
License: Apache 2.0
|
||||
License File: gson.license
|
||||
@ -13,6 +12,10 @@ Jackson Databind - General-purpose data-binding functionality and tree-model for
|
||||
License: Apache 2.0
|
||||
License File: jackson-databind.license
|
||||
|
||||
Jackson Dataformat Properties - Support for reading and writing content of "Java Properties" style configuration files as if there was implied nesting structure (by default using dots as separators). (https://github.com/FasterXML/jackson-dataformats-text/blob/master/LICENSE)
|
||||
License: Apache 2.0
|
||||
License File: jackson-dataformat-properties.license
|
||||
|
||||
jQuery.BlockUI - The jQuery BlockUI Plugin lets you simulate synchronous behavior when using AJAX, without locking the browser. (https://github.com/malsup/blockui/)
|
||||
License: MIT, GPL
|
||||
License File: jQuery.BlockUI.license
|
||||
@ -37,6 +40,10 @@ jQuery.UI - jQuery UI is an open source library of interface components —
|
||||
License: MIT
|
||||
License File: jQuery.UI.license
|
||||
|
||||
JSON - JSON is a light-weight, language independent, data interchange format. (https://github.com/stleary/JSON-java/blob/master/LICENSE)
|
||||
License Public Domain
|
||||
License File: json.license
|
||||
|
||||
JSON.simple - JSON.simple is a simple Java toolkit for JSON. You can use JSON.simple to encode or decode JSON text. (https://github.com/fangyidong/json-simple/blob/master/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: JSON.simple.license
|
||||
@ -49,14 +56,14 @@ ModelMapper - ModelMapper is an intelligent object mapping library that automa
|
||||
License: Apache 2.0
|
||||
License File modelmapper.license
|
||||
|
||||
Prime JWT - is intended to be fast and easy to use. Prime JWT has a single external dependency on Jackson. (https://github.com/ws-apps/prime-jwt/blob/master/LICENSE)
|
||||
License: Apache 2.0
|
||||
License File: prime-jwt.license
|
||||
|
||||
Spring Boot - Helps create Spring-powered, production-grade applications and services. Has external dependencies on Spring Framework. (https://github.com/spring-projects/spring-boot/blob/main/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: spring-boot.license
|
||||
|
||||
Spring Boot Web - Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container. (https://github.com/spring-projects/spring-boot/blob/main/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: spring-boot.license
|
||||
|
||||
Spring Boot Devtools - Provides fast application restarts, LiveReload, and configurations for enhanced development experience. (https://github.com/spring-projects/spring-boot/blob/main/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: spring-boot.license
|
||||
|
||||
@ -135,9 +135,9 @@ See the detailed guide to learn how to install Document Server [for Linux](https
|
||||
a) archive with Java-Spring:
|
||||
|
||||
```
|
||||
wget https://api.onlyoffice.com/app_data/editor/Java.Spring.Example.zip
|
||||
wget https://github.com/ONLYOFFICE/document-server-integration/releases/latest/download/Java.Spring.Example.zip
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
unzip Java.Spring.Example.zip
|
||||
```
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
ONLYOFFICE Applications example uses code from the following 3rd party projects:
|
||||
|
||||
|
||||
Gson - Gson is a Java library that can be used to convert Java Objects into their JSON representation. (https://github.com/google/gson/blob/master/LICENSE)
|
||||
License: Apache 2.0
|
||||
License File: gson.license
|
||||
@ -13,6 +12,10 @@ Jackson Databind - General-purpose data-binding functionality and tree-model for
|
||||
License: Apache 2.0
|
||||
License File: jackson-databind.license
|
||||
|
||||
Jackson Dataformat Properties - Support for reading and writing content of "Java Properties" style configuration files as if there was implied nesting structure (by default using dots as separators). (https://github.com/FasterXML/jackson-dataformats-text/blob/master/LICENSE)
|
||||
License: Apache 2.0
|
||||
License File: jackson-dataformat-properties.license
|
||||
|
||||
jQuery.BlockUI - The jQuery BlockUI Plugin lets you simulate synchronous behavior when using AJAX, without locking the browser. (https://github.com/malsup/blockui/)
|
||||
License: MIT, GPL
|
||||
License File: jQuery.BlockUI.license
|
||||
@ -37,6 +40,10 @@ jQuery.UI - jQuery UI is an open source library of interface components —
|
||||
License: MIT
|
||||
License File: jQuery.UI.license
|
||||
|
||||
JSON - JSON is a light-weight, language independent, data interchange format. (https://github.com/stleary/JSON-java/blob/master/LICENSE)
|
||||
License Public Domain
|
||||
License File: json.license
|
||||
|
||||
JSON.simple - JSON.simple is a simple Java toolkit for JSON. You can use JSON.simple to encode or decode JSON text. (https://github.com/fangyidong/json-simple/blob/master/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: JSON.simple.license
|
||||
@ -49,14 +56,14 @@ ModelMapper - ModelMapper is an intelligent object mapping library that automa
|
||||
License: Apache 2.0
|
||||
License File modelmapper.license
|
||||
|
||||
Prime JWT - is intended to be fast and easy to use. Prime JWT has a single external dependency on Jackson. (https://github.com/ws-apps/prime-jwt/blob/master/LICENSE)
|
||||
License: Apache 2.0
|
||||
License File: prime-jwt.license
|
||||
|
||||
Spring Boot - Helps create Spring-powered, production-grade applications and services. Has external dependencies on Spring Framework. (https://github.com/spring-projects/spring-boot/blob/main/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: spring-boot.license
|
||||
|
||||
Spring Boot Web - Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container. (https://github.com/spring-projects/spring-boot/blob/main/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: spring-boot.license
|
||||
|
||||
Spring Boot Devtools - Provides fast application restarts, LiveReload, and configurations for enhanced development experience. (https://github.com/spring-projects/spring-boot/blob/main/LICENSE.txt)
|
||||
License: Apache 2.0
|
||||
License File: spring-boot.license
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
Apache License
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
@ -178,7 +179,7 @@ Apache License
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
@ -186,7 +187,7 @@ Apache License
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -0,0 +1 @@
|
||||
Public Domain.
|
||||
@ -50,11 +50,6 @@
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.inversoft</groupId>
|
||||
<artifactId>prime-jwt</artifactId>
|
||||
<version>1.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
@ -71,12 +66,39 @@
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.13.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-properties</artifactId>
|
||||
<version>2.13.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.modelmapper</groupId>
|
||||
<artifactId>modelmapper</artifactId>
|
||||
<version>2.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20231013</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.onlyoffice</groupId>
|
||||
<artifactId>docs-integration-sdk</artifactId>
|
||||
<version>1.1.4-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>ossrh</id>
|
||||
<name>Sonatype OSSRH</name>
|
||||
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@ -102,23 +102,25 @@ public class ExampleData {
|
||||
userService.createUser("John Smith", "smith@example.com", descriptionUserFirst,
|
||||
"", List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
|
||||
List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
|
||||
List.of(FilterState.NULL.toString()), null, true, true, true, new Goback(null, false));
|
||||
List.of(FilterState.NULL.toString()), null, true, true, true,
|
||||
new Goback(null, false), true);
|
||||
|
||||
// create user 2 with the specified parameters
|
||||
userService.createUser("Mark Pottato", "pottato@example.com", descriptionUserSecond,
|
||||
"group-2", List.of("", "group-2"), List.of(FilterState.NULL.toString()),
|
||||
List.of("group-2", ""), List.of("group-2"), List.of("group-2", ""), true, true,
|
||||
true, true, new Goback("Go to Documents", null));
|
||||
true, true, new Goback("Go to Documents", null), false);
|
||||
|
||||
// create user 3 with the specified parameters
|
||||
userService.createUser("Hamish Mitchell", null, descriptionUserThird,
|
||||
"group-3", List.of("group-2"), List.of("group-2", "group-3"), List.of("group-2"),
|
||||
new ArrayList<>(), List.of("group-2"), false, true, true, false, null);
|
||||
new ArrayList<>(), List.of("group-2"), false, true, true, false,
|
||||
null, false);
|
||||
|
||||
// create user 0 with the specified parameters
|
||||
userService.createUser("Anonymous", null, descriptionUserZero, "",
|
||||
List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
|
||||
List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
|
||||
new ArrayList<>(), null, false, false, false, null);
|
||||
new ArrayList<>(), null, false, false, false, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,17 @@ package com.onlyoffice.integration;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.manager.document.DocumentManager;
|
||||
import com.onlyoffice.manager.request.DefaultRequestManager;
|
||||
import com.onlyoffice.manager.request.RequestManager;
|
||||
import com.onlyoffice.manager.security.DefaultJwtManager;
|
||||
import com.onlyoffice.manager.security.JwtManager;
|
||||
import com.onlyoffice.manager.settings.SettingsManager;
|
||||
import com.onlyoffice.manager.url.UrlManager;
|
||||
import com.onlyoffice.service.command.CommandService;
|
||||
import com.onlyoffice.service.command.DefaultCommandService;
|
||||
import com.onlyoffice.service.convert.ConvertService;
|
||||
import com.onlyoffice.service.convert.DefaultConvertService;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.modelmapper.convention.MatchingStrategies;
|
||||
@ -30,23 +41,15 @@ import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.util.SSLUtils;
|
||||
|
||||
@Configuration
|
||||
public class IntegrationConfiguration {
|
||||
|
||||
@Value("${files.storage}")
|
||||
private String storageAddress;
|
||||
|
||||
@Value("${files.docservice.verify-peer-off}")
|
||||
private String verifyPerrOff;
|
||||
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
|
||||
@Autowired
|
||||
private SSLUtils ssl;
|
||||
|
||||
@Bean
|
||||
public ModelMapper mapper() { // create the model mapper
|
||||
ModelMapper mapper = new ModelMapper();
|
||||
@ -67,21 +70,34 @@ public class IntegrationConfiguration {
|
||||
@PostConstruct
|
||||
public void init() { // initialize the storage path builder
|
||||
storagePathBuilder.configure(storageAddress.isBlank() ? null : storageAddress);
|
||||
if (!verifyPerrOff.isEmpty()) {
|
||||
try {
|
||||
if (verifyPerrOff.equals("true")) {
|
||||
ssl.turnOffSslChecking(); //the certificate will be ignored
|
||||
} else {
|
||||
ssl.turnOnSslChecking(); //the certificate will be verified
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ObjectMapper objectMapper() { // create the object mapper
|
||||
return new ObjectMapper();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtManager jwtManager(final SettingsManager settingsManager) {
|
||||
return new DefaultJwtManager(settingsManager);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RequestManager requestManager(final UrlManager urlManager, final JwtManager jwtManager,
|
||||
final SettingsManager settingsManager) {
|
||||
return new DefaultRequestManager(urlManager, jwtManager, settingsManager);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConvertService convertService(final DocumentManager documentManager, final UrlManager urlManager,
|
||||
final RequestManager requestManager,
|
||||
final SettingsManager settingsManager) {
|
||||
return new DefaultConvertService(documentManager, urlManager, requestManager, settingsManager);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CommandService commandService(final RequestManager requestManager) {
|
||||
return new DefaultCommandService(requestManager);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -20,19 +20,22 @@ package com.onlyoffice.integration.controllers;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Action;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.dto.Mentions;
|
||||
import com.onlyoffice.integration.dto.UserInfo;
|
||||
import com.onlyoffice.integration.dto.Protect;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Type;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.FileModel;
|
||||
import com.onlyoffice.integration.dto.UserInfo;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.sdk.manager.UrlManager;
|
||||
import com.onlyoffice.integration.sdk.service.ConfigService;
|
||||
import com.onlyoffice.integration.services.UserServices;
|
||||
import com.onlyoffice.integration.services.configurers.FileConfigurer;
|
||||
import com.onlyoffice.integration.services.configurers.wrappers.DefaultFileWrapper;
|
||||
import com.onlyoffice.manager.security.JwtManager;
|
||||
import com.onlyoffice.manager.settings.SettingsManager;
|
||||
import com.onlyoffice.model.documenteditor.Config;
|
||||
import com.onlyoffice.model.documenteditor.config.document.Type;
|
||||
import com.onlyoffice.model.settings.SettingsConstants;
|
||||
import lombok.SneakyThrows;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@ -56,12 +59,6 @@ import static com.onlyoffice.integration.documentserver.util.Constants.ANONYMOUS
|
||||
@Controller
|
||||
public class EditorController {
|
||||
|
||||
@Value("${files.docservice.url.site}")
|
||||
private String docserviceSite;
|
||||
|
||||
@Value("${files.docservice.url.api}")
|
||||
private String docserviceApiUrl;
|
||||
|
||||
@Value("${files.docservice.languages}")
|
||||
private String langs;
|
||||
|
||||
@ -78,7 +75,13 @@ public class EditorController {
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
private FileConfigurer<DefaultFileWrapper> fileConfigurer;
|
||||
private SettingsManager settingsManager;
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private UrlManager urlManager;
|
||||
|
||||
@GetMapping(path = "${url.editor}")
|
||||
// process request to open the editor page
|
||||
@ -91,17 +94,19 @@ public class EditorController {
|
||||
@CookieValue(value = "uid") final String uid,
|
||||
@CookieValue(value = "ulang") final String lang,
|
||||
final Model model) throws JsonProcessingException {
|
||||
Action action = Action.edit;
|
||||
Type type = Type.desktop;
|
||||
Action action = null;
|
||||
Type type = Type.DESKTOP;
|
||||
Locale locale = new Locale("en");
|
||||
|
||||
if (actionParam != null) {
|
||||
action = Action.valueOf(actionParam);
|
||||
}
|
||||
if (typeParam != null) {
|
||||
type = Type.valueOf(typeParam);
|
||||
type = Type.valueOf(typeParam.toUpperCase());
|
||||
}
|
||||
|
||||
settingsManager.setSetting(SettingsConstants.DIRECT_URL, String.valueOf(directUrl));
|
||||
|
||||
List<String> langsAndKeys = Arrays.asList(langs.split("\\|"));
|
||||
for (String langAndKey : langsAndKeys) {
|
||||
String[] couple = langAndKey.split(":");
|
||||
@ -118,30 +123,25 @@ public class EditorController {
|
||||
return "index.html";
|
||||
}
|
||||
|
||||
User user = optionalUser.get();
|
||||
user.setImage(user.getAvatar() ? storagePathBuilder.getServerUrl(true) + "/css/img/uid-"
|
||||
+ user.getId() + ".png" : null);
|
||||
|
||||
// get file model with the default file parameters
|
||||
FileModel fileModel = fileConfigurer.getFileModel(
|
||||
DefaultFileWrapper
|
||||
.builder()
|
||||
.fileName(fileName)
|
||||
.type(type)
|
||||
.lang(locale.toLanguageTag())
|
||||
.action(action)
|
||||
.user(user)
|
||||
.actionData(actionLink)
|
||||
.isEnableDirectUrl(directUrl)
|
||||
.build()
|
||||
Config config = configService.createConfig(
|
||||
fileName,
|
||||
action,
|
||||
type
|
||||
);
|
||||
|
||||
// add attributes to the specified model
|
||||
// add file model with the default parameters to the original model
|
||||
model.addAttribute("model", fileModel);
|
||||
JSONObject actionData = null;
|
||||
|
||||
if (actionLink != null && !actionLink.isEmpty()) {
|
||||
actionData = new JSONObject(actionLink);
|
||||
}
|
||||
|
||||
config.getEditorConfig().setActionLink(actionData);
|
||||
config.getEditorConfig().setLang(locale.toLanguageTag());
|
||||
|
||||
model.addAttribute("model", config);
|
||||
|
||||
// create the document service api URL and add it to the model
|
||||
model.addAttribute("docserviceApiUrl", docserviceSite + docserviceApiUrl);
|
||||
model.addAttribute("docserviceApiUrl", urlManager.getDocumentServerApiUrl());
|
||||
|
||||
// get an image and add it to the model
|
||||
model.addAttribute("dataInsertImage", getInsertImage(directUrl));
|
||||
@ -220,7 +220,7 @@ public class EditorController {
|
||||
}
|
||||
|
||||
// check if the document token is enabled
|
||||
if (jwtManager.tokenEnabled()) {
|
||||
if (settingsManager.isSecurityEnabled()) {
|
||||
|
||||
// create token from the dataInsertImage object
|
||||
dataInsertImage.put("token", jwtManager.createToken(dataInsertImage));
|
||||
@ -242,7 +242,7 @@ public class EditorController {
|
||||
}
|
||||
|
||||
// check if the document token is enabled
|
||||
if (jwtManager.tokenEnabled()) {
|
||||
if (settingsManager.isSecurityEnabled()) {
|
||||
|
||||
// create token from the dataDocument object
|
||||
dataDocument.put("token", jwtManager.createToken(dataDocument));
|
||||
@ -261,7 +261,7 @@ public class EditorController {
|
||||
}
|
||||
|
||||
// check if the document token is enabled
|
||||
if (jwtManager.tokenEnabled()) {
|
||||
if (settingsManager.isSecurityEnabled()) {
|
||||
|
||||
// create token from the dataSpreadsheet object
|
||||
dataSpreadsheet.put("token", jwtManager.createToken(dataSpreadsheet));
|
||||
|
||||
@ -21,32 +21,38 @@ package com.onlyoffice.integration.controllers;
|
||||
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;
|
||||
import com.onlyoffice.integration.sdk.manager.DocumentManager;
|
||||
import com.onlyoffice.integration.services.UserServices;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import com.onlyoffice.integration.documentserver.util.service.ServiceConverter;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
import com.onlyoffice.integration.documentserver.managers.callback.CallbackManager;
|
||||
|
||||
import com.onlyoffice.manager.request.RequestManager;
|
||||
import com.onlyoffice.manager.security.JwtManager;
|
||||
import com.onlyoffice.manager.settings.SettingsManager;
|
||||
import com.onlyoffice.manager.url.UrlManager;
|
||||
import com.onlyoffice.model.commandservice.CommandRequest;
|
||||
import com.onlyoffice.model.commandservice.CommandResponse;
|
||||
import com.onlyoffice.model.commandservice.commandrequest.Command;
|
||||
import com.onlyoffice.model.commandservice.commandrequest.Meta;
|
||||
import com.onlyoffice.model.convertservice.ConvertRequest;
|
||||
import com.onlyoffice.model.convertservice.ConvertResponse;
|
||||
import com.onlyoffice.model.documenteditor.Callback;
|
||||
import com.onlyoffice.model.documenteditor.config.document.ReferenceData;
|
||||
import com.onlyoffice.service.command.CommandService;
|
||||
import com.onlyoffice.service.convert.ConvertService;
|
||||
import com.onlyoffice.service.documenteditor.callback.CallbackService;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@ -74,7 +80,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
@ -91,22 +96,6 @@ import java.util.Optional;
|
||||
@Controller
|
||||
public class FileController {
|
||||
|
||||
@Value("${files.docservice.header}")
|
||||
private String documentJwtHeader;
|
||||
|
||||
@Value("${filesize-max}")
|
||||
private String filesizeMax;
|
||||
|
||||
@Value("${files.docservice.url.site}")
|
||||
private String docserviceUrlSite;
|
||||
|
||||
@Value("${files.docservice.url.command}")
|
||||
private String docserviceUrlCommand;
|
||||
|
||||
@Autowired
|
||||
private FileUtility fileUtility;
|
||||
@Autowired
|
||||
private DocumentManager documentManager;
|
||||
@Autowired
|
||||
private JwtManager jwtManager;
|
||||
@Autowired
|
||||
@ -116,20 +105,29 @@ public class FileController {
|
||||
@Autowired
|
||||
private UserServices userService;
|
||||
@Autowired
|
||||
private CallbackHandler callbackHandler;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
@Autowired
|
||||
private ServiceConverter serviceConverter;
|
||||
@Autowired
|
||||
private CallbackManager callbackManager;
|
||||
@Autowired
|
||||
private HistoryManager historyManager;
|
||||
@Autowired
|
||||
private DocumentManager documentManager;
|
||||
@Autowired
|
||||
private ConvertService convertService;
|
||||
@Autowired
|
||||
private RequestManager requestManager;
|
||||
@Autowired
|
||||
private SettingsManager settingsManager;
|
||||
@Autowired
|
||||
private CallbackService callbackService;
|
||||
@Autowired
|
||||
private CommandService commandService;
|
||||
@Autowired
|
||||
private UrlManager urlManager;
|
||||
|
||||
// create user metadata
|
||||
private String createUserMetadata(final String uid, final String fullFileName) {
|
||||
Optional<User> optionalUser = userService.findUserById(Integer.parseInt(uid)); // find a user by their ID
|
||||
String documentType = fileUtility.getDocumentType(fullFileName).toString().toLowerCase(); // get document type
|
||||
// get document type
|
||||
String documentType = documentManager.getDocumentType(fullFileName).toString().toLowerCase();
|
||||
if (optionalUser.isPresent()) {
|
||||
User user = optionalUser.get();
|
||||
storageMutator.createMeta(fullFileName, // create meta information with the user ID and name specified
|
||||
@ -196,17 +194,17 @@ public class FileController {
|
||||
@CookieValue("uid") final String uid) {
|
||||
try {
|
||||
String fullFileName = file.getOriginalFilename(); // get file name
|
||||
String fileExtension = fileUtility.getFileExtension(fullFileName); // get file extension
|
||||
String fileExtension = documentManager.getExtension(fullFileName); // get file extension
|
||||
long fileSize = file.getSize(); // get file size
|
||||
byte[] bytes = file.getBytes(); // get file in bytes
|
||||
|
||||
// check if the file size exceeds the maximum file size or is less than 0
|
||||
if (fileUtility.getMaxFileSize() < fileSize || fileSize <= 0) {
|
||||
if (documentManager.getMaxFileSize() < fileSize || fileSize <= 0) {
|
||||
return "{ \"error\": \"File size is incorrect\"}"; // if so, write an error message to the response
|
||||
}
|
||||
|
||||
// check if file extension is supported by the editor
|
||||
if (!fileUtility.getFileExts().contains(fileExtension)) {
|
||||
if (documentManager.getDocumentType(fullFileName) == null) {
|
||||
|
||||
// if not, write an error message to the response
|
||||
return "{ \"error\": \"File type is not supported\"}";
|
||||
@ -217,7 +215,7 @@ public class FileController {
|
||||
throw new IOException("Could not update a file"); // if the file cannot be updated, an error occurs
|
||||
}
|
||||
|
||||
fullFileName = fileUtility.getFileNameWithoutExtension(fileNamePath)
|
||||
fullFileName = documentManager.getBaseName(fileNamePath)
|
||||
+ "." + fileExtension; // get full file name
|
||||
|
||||
return createUserMetadata(uid, fullFileName); // create user metadata and return it
|
||||
@ -235,56 +233,54 @@ public class FileController {
|
||||
@CookieValue("uid") final String uid, @CookieValue("ulang") final String lang) {
|
||||
// get file name
|
||||
String fileName = body.getFileName();
|
||||
|
||||
// get URL for downloading a file with the specified name
|
||||
String fileUri = documentManager.getDownloadUrl(fileName, true);
|
||||
|
||||
// get file password if it exists
|
||||
String filePass = body.getFilePass() != null ? body.getFilePass() : null;
|
||||
|
||||
// get file extension
|
||||
String fileExt = fileUtility.getFileExtension(fileName);
|
||||
|
||||
// get document type (word, cell or slide)
|
||||
DocumentType type = fileUtility.getDocumentType(fileName);
|
||||
|
||||
// get an auto-conversion extension from the request body or set it to the ooxml extension
|
||||
String conversionExtension = body.getFileExt() != null ? body.getFileExt() : "ooxml";
|
||||
|
||||
try {
|
||||
// check if the file with such an extension can be converted
|
||||
if (fileUtility.getConvertExts().contains(fileExt)) {
|
||||
String key = serviceConverter.generateRevisionId(fileUri); // generate document key
|
||||
ConvertedData response = serviceConverter // get the URL to the converted file
|
||||
.getConvertedData(fileUri, fileExt, conversionExtension, key, filePass, true, lang);
|
||||
if (documentManager.getDefaultConvertExtension(fileName) != null) {
|
||||
ConvertRequest convertRequest = ConvertRequest.builder()
|
||||
.password(filePass)
|
||||
.outputtype(conversionExtension)
|
||||
.region(lang)
|
||||
.async(true)
|
||||
.build();
|
||||
|
||||
String newFileUri = response.getUri();
|
||||
String newFileType = "." + response.getFileType();
|
||||
ConvertResponse convertResponse = convertService.processConvert(convertRequest, fileName);
|
||||
|
||||
if (newFileUri.isEmpty()) {
|
||||
return "{ \"step\" : \"0\", \"filename\" : \"" + fileName + "\"}";
|
||||
if (convertResponse.getError() != null || convertResponse.getFileUrl() == null) {
|
||||
return objectMapper.writeValueAsString(convertResponse);
|
||||
}
|
||||
|
||||
String newFileUri = convertResponse.getFileUrl();
|
||||
String newFileType = convertResponse.getFileType();
|
||||
|
||||
/* get a file name of an internal file extension with an index if the file
|
||||
with such a name already exists */
|
||||
String nameWithInternalExt = fileUtility.getFileNameWithoutExtension(fileName) + newFileType;
|
||||
final String oldFileName = fileName;
|
||||
String nameWithInternalExt = documentManager.getBaseName(fileName) + "." + newFileType;
|
||||
String correctedName = documentManager.getCorrectName(nameWithInternalExt);
|
||||
|
||||
URL url = new URL(newFileUri);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
InputStream stream = connection.getInputStream(); // get input stream of the converted file
|
||||
fileName = requestManager.executeGetRequest(newFileUri, new RequestManager.Callback<String>() {
|
||||
public String doWork(final Object response) throws IOException {
|
||||
InputStream stream = ((HttpEntity) response).getContent(); // get input stream of the converted
|
||||
// file
|
||||
|
||||
if (stream == null) {
|
||||
connection.disconnect();
|
||||
throw new RuntimeException("Input stream is null");
|
||||
}
|
||||
if (stream == null) {
|
||||
throw new RuntimeException("Input stream is null");
|
||||
}
|
||||
|
||||
// remove source file
|
||||
storageMutator.deleteFile(fileName);
|
||||
|
||||
// create the converted file with input stream
|
||||
storageMutator.createFile(Path.of(storagePathBuilder.getFileLocation(correctedName)), stream);
|
||||
fileName = correctedName;
|
||||
// remove source file
|
||||
storageMutator.deleteFile(oldFileName);
|
||||
|
||||
// create the converted file with input stream
|
||||
storageMutator.createFile(Path.of(storagePathBuilder.getFileLocation(correctedName)), stream);
|
||||
return correctedName;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// create meta information about the converted file with the user ID and name specified
|
||||
@ -305,7 +301,7 @@ public class FileController {
|
||||
boolean success = false;
|
||||
|
||||
if (filename != null) {
|
||||
String fullFileName = fileUtility.getFileName(filename); // get full file name
|
||||
String fullFileName = documentManager.getDocumentName(filename); // get full file name
|
||||
|
||||
// delete a file from the storage and return the status of this operation (true or false)
|
||||
boolean fileSuccess = storageMutator.deleteFile(fullFileName);
|
||||
@ -331,13 +327,12 @@ public class FileController {
|
||||
@RequestParam("file") final String file) { // history file
|
||||
try {
|
||||
// check if a token is enabled or not
|
||||
if (jwtManager.tokenEnabled() && jwtManager.tokenUseForRequest()) {
|
||||
String header = request.getHeader(documentJwtHeader == null // get the document JWT header
|
||||
|| documentJwtHeader.isEmpty() ? "Authorization" : documentJwtHeader);
|
||||
if (settingsManager.isSecurityEnabled()) {
|
||||
String header = request.getHeader(settingsManager.getSecurityHeader());
|
||||
if (header != null && !header.isEmpty()) {
|
||||
String token = header
|
||||
.replace("Bearer ", ""); // token is the header without the Bearer prefix
|
||||
jwtManager.readToken(token); // read the token
|
||||
jwtManager.verify(token); // read the token
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -355,13 +350,12 @@ public class FileController {
|
||||
final String userAddress) {
|
||||
try {
|
||||
// check if a token is enabled or not
|
||||
if (jwtManager.tokenEnabled() && userAddress != null && jwtManager.tokenUseForRequest()) {
|
||||
String header = request.getHeader(documentJwtHeader == null // get the document JWT header
|
||||
|| documentJwtHeader.isEmpty() ? "Authorization" : documentJwtHeader);
|
||||
if (settingsManager.isSecurityEnabled() && userAddress != null) {
|
||||
String header = request.getHeader(settingsManager.getSecurityHeader());
|
||||
if (header != null && !header.isEmpty()) {
|
||||
String token = header
|
||||
.replace("Bearer ", ""); // token is the header without the Bearer prefix
|
||||
jwtManager.readToken(token); // read the token
|
||||
jwtManager.verify(token); // read the token
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -391,10 +385,10 @@ public class FileController {
|
||||
sampleData,
|
||||
uid,
|
||||
user.get().getName()); // create a demo document with the sample data
|
||||
if (fileName.isBlank() || fileName == null) {
|
||||
if (fileName == null || fileName.isBlank()) {
|
||||
throw new RuntimeException("You must have forgotten to add asset files");
|
||||
}
|
||||
return "redirect:editor?fileName=" + URLEncoder
|
||||
return "redirect:editor?action=edit&fileName=" + URLEncoder
|
||||
.encode(fileName, StandardCharsets.UTF_8); // redirect the request
|
||||
} catch (Exception ex) {
|
||||
model.addAttribute("error", ex.getMessage());
|
||||
@ -427,28 +421,26 @@ public class FileController {
|
||||
public String track(final HttpServletRequest request, // track file changes
|
||||
@RequestParam("fileName") final String fileName,
|
||||
@RequestParam("userAddress") final String userAddress,
|
||||
@RequestBody final Track body) {
|
||||
Track track;
|
||||
@RequestBody final Callback body) {
|
||||
Callback callback;
|
||||
try {
|
||||
String bodyString = objectMapper
|
||||
.writeValueAsString(body); // write the request body to the object mapper as a string
|
||||
String header = request.getHeader(documentJwtHeader == null // get the request header
|
||||
|| documentJwtHeader.isEmpty() ? "Authorization" : documentJwtHeader);
|
||||
|
||||
if (bodyString.isEmpty()) { // if the request body is empty, an error occurs
|
||||
throw new RuntimeException("{\"error\":1,\"message\":\"Request payload is empty\"}");
|
||||
}
|
||||
|
||||
JSONObject bodyCheck = jwtManager.parseBody(bodyString, header); // parse the request body
|
||||
track = objectMapper.readValue(bodyCheck.toJSONString(), Track.class); // read the request body
|
||||
String authorizationHeader = request.getHeader(settingsManager.getSecurityHeader());
|
||||
callback = callbackService.verifyCallback(body, authorizationHeader);
|
||||
|
||||
callbackService.processCallback(callback, fileName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
}
|
||||
|
||||
int error = callbackHandler.handle(track, fileName);
|
||||
|
||||
return "{\"error\":" + error + "}";
|
||||
return "{\"error\":\"0\"}";
|
||||
}
|
||||
|
||||
@PostMapping("/saveas")
|
||||
@ -456,24 +448,30 @@ public class FileController {
|
||||
public String saveAs(@RequestBody final SaveAs body, @CookieValue("uid") final String uid) {
|
||||
try {
|
||||
String fileName = documentManager.getCorrectName(body.getTitle());
|
||||
String curExt = fileUtility.getFileExtension(fileName);
|
||||
|
||||
if (!fileUtility.getFileExts().contains(curExt)) {
|
||||
if (documentManager.getDocumentType(fileName) == null) {
|
||||
return "{\"error\":\"File type is not supported\"}";
|
||||
}
|
||||
|
||||
URL url = new URL(body.getUrl());
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
InputStream stream = connection.getInputStream();
|
||||
String url = body.getUrl();
|
||||
|
||||
if (Integer.parseInt(filesizeMax) < stream.available() || stream.available() <= 0) {
|
||||
return "{\"error\":\"File size is incorrect\"}";
|
||||
}
|
||||
storageMutator.createFile(Path.of(storagePathBuilder.getFileLocation(fileName)), stream);
|
||||
createUserMetadata(uid, fileName);
|
||||
url = urlManager.replaceToInnerDocumentServerUrl(url);
|
||||
|
||||
return "{\"file\": \"" + fileName + "\"}";
|
||||
} catch (IOException e) {
|
||||
return requestManager.executeGetRequest(url, new RequestManager.Callback<String>() {
|
||||
@Override
|
||||
public String doWork(final Object response) throws Exception {
|
||||
InputStream stream = ((HttpEntity) response).getContent();
|
||||
|
||||
if (documentManager.getMaxFileSize() < stream.available() || stream.available() <= 0) {
|
||||
return "{\"error\":\"File size is incorrect\"}";
|
||||
}
|
||||
storageMutator.createFile(Path.of(storagePathBuilder.getFileLocation(fileName)), stream);
|
||||
createUserMetadata(uid, fileName);
|
||||
|
||||
return "{\"file\": \"" + fileName + "\"}";
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "{ \"error\" : 1, \"message\" : \"" + e.getMessage() + "\"}";
|
||||
}
|
||||
@ -482,14 +480,18 @@ public class FileController {
|
||||
@PostMapping("/rename")
|
||||
@ResponseBody
|
||||
public String rename(@RequestBody final Rename body) {
|
||||
String fileName = body.getFileName();
|
||||
|
||||
HashMap<String, String> meta = new HashMap<>();
|
||||
meta.put("title", fileName + "." + body.getFileType());
|
||||
CommandRequest commandRequest = CommandRequest.builder()
|
||||
.key(body.getFileKey())
|
||||
.c(Command.META)
|
||||
.meta(Meta.builder()
|
||||
.title(body.getFileName() + "." + body.getFileType())
|
||||
.build())
|
||||
.build();
|
||||
|
||||
try {
|
||||
callbackManager.commandRequest("meta", body.getFileKey(), meta);
|
||||
return "result ok";
|
||||
|
||||
CommandResponse commandResponse = commandService.processCommand(commandRequest, body.getFileName());
|
||||
return commandResponse.getError().getDescription();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
@ -538,7 +540,8 @@ public class FileController {
|
||||
if (fileName.equals("")) {
|
||||
try {
|
||||
String path = (String) body.getPath();
|
||||
path = fileUtility.getFileName(path);
|
||||
path = path.substring(path.lastIndexOf('/') + 1);
|
||||
path = path.split("\\?")[0];
|
||||
File f = new File(storagePathBuilder.getFileLocation(path));
|
||||
if (f.exists()) {
|
||||
fileName = path;
|
||||
@ -561,19 +564,19 @@ public class FileController {
|
||||
referenceData.put("fileKey", gson.toJson(fileKey));
|
||||
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("fileType", fileUtility.getFileExtension(fileName));
|
||||
data.put("key", serviceConverter.generateRevisionId(
|
||||
data.put("fileType", documentManager.getDocumentName(fileName));
|
||||
data.put("key", documentManager.generateRevisionId(
|
||||
storagePathBuilder.getStorageLocation()
|
||||
+ "/" + fileName + "/"
|
||||
+ new File(storagePathBuilder.getFileLocation(fileName)).lastModified()
|
||||
));
|
||||
data.put("url", documentManager.getDownloadUrl(fileName, true));
|
||||
data.put("directUrl", body.getDirectUrl() ? documentManager.getDownloadUrl(fileName, false) : null);
|
||||
data.put("url", urlManager.getFileUrl(fileName));
|
||||
data.put("directUrl", body.getDirectUrl() ? urlManager.getDirectFileUrl(fileName) : null);
|
||||
data.put("referenceData", referenceData);
|
||||
data.put("path", fileName);
|
||||
data.put("link", storagePathBuilder.getServerUrl(true) + "/editor?fileName=" + fileName);
|
||||
|
||||
if (jwtManager.tokenEnabled()) {
|
||||
if (settingsManager.isSecurityEnabled()) {
|
||||
String token = jwtManager.createToken(data);
|
||||
data.put("token", token);
|
||||
}
|
||||
@ -608,7 +611,7 @@ public class FileController {
|
||||
String historyDirectory = storagePathBuilder.getHistoryDir(sourcePathFile.toString());
|
||||
|
||||
Integer bumpedVersion = storagePathBuilder.getFileVersion(historyDirectory, false);
|
||||
String bumpedVersionStringDirectory = documentManager.versionDir(historyDirectory, bumpedVersion, true);
|
||||
String bumpedVersionStringDirectory = historyManager.versionDir(historyDirectory, bumpedVersion, true);
|
||||
File bumpedVersionDirectory = new File(bumpedVersionStringDirectory);
|
||||
if (!bumpedVersionDirectory.exists()) {
|
||||
bumpedVersionDirectory.mkdir();
|
||||
@ -617,7 +620,7 @@ public class FileController {
|
||||
Path bumpedKeyPathFile = Paths.get(bumpedVersionStringDirectory, "key.txt");
|
||||
String bumpedKeyStringFile = bumpedKeyPathFile.toString();
|
||||
File bumpedKeyFile = new File(bumpedKeyStringFile);
|
||||
String bumpedKey = serviceConverter.generateRevisionId(
|
||||
String bumpedKey = documentManager.generateRevisionId(
|
||||
storagePathBuilder.getStorageLocation()
|
||||
+ "/"
|
||||
+ body.getFileName()
|
||||
@ -651,13 +654,13 @@ public class FileController {
|
||||
bumpedChangesFileWriter.write(bumpedChangesContent);
|
||||
bumpedChangesFileWriter.close();
|
||||
|
||||
String sourceExtension = fileUtility.getFileExtension(body.getFileName());
|
||||
String sourceExtension = documentManager.getExtension(body.getFileName());
|
||||
String previousBasename = "prev." + sourceExtension;
|
||||
|
||||
Path bumpedFile = Paths.get(bumpedVersionStringDirectory, previousBasename);
|
||||
Files.move(sourcePathFile, bumpedFile);
|
||||
|
||||
String recoveryVersionStringDirectory = documentManager.versionDir(
|
||||
String recoveryVersionStringDirectory = historyManager.versionDir(
|
||||
historyDirectory,
|
||||
body.getVersion(),
|
||||
true
|
||||
|
||||
@ -0,0 +1,121 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* 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.controllers;
|
||||
|
||||
import com.onlyoffice.integration.dto.ForgottenFile;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import com.onlyoffice.model.commandservice.CommandRequest;
|
||||
import com.onlyoffice.model.commandservice.CommandResponse;
|
||||
import com.onlyoffice.model.commandservice.commandrequest.Command;
|
||||
import com.onlyoffice.manager.document.DocumentManager;
|
||||
import com.onlyoffice.service.command.CommandService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@CrossOrigin("*")
|
||||
@Controller
|
||||
public class ForgottenController {
|
||||
@Value("${server.version}")
|
||||
private String serverVersion;
|
||||
|
||||
@Value("${enable-forgotten}")
|
||||
private String enableForgotten;
|
||||
|
||||
@Autowired
|
||||
private CommandService commandService;
|
||||
|
||||
@Autowired
|
||||
private DocumentManager documentManager;
|
||||
|
||||
@GetMapping("${url.forgotten}")
|
||||
public String index(final Model model) {
|
||||
if (!forgottenEnabled()) {
|
||||
model.addAttribute("error", "The forgotten page is disabled");
|
||||
return "error.html";
|
||||
}
|
||||
|
||||
model.addAttribute("files", getForgottenFiles());
|
||||
model.addAttribute("serverVersion", serverVersion);
|
||||
|
||||
return "forgotten.html";
|
||||
}
|
||||
|
||||
private ArrayList<ForgottenFile> getForgottenFiles() {
|
||||
ArrayList<ForgottenFile> files = new ArrayList<ForgottenFile>();
|
||||
try {
|
||||
CommandRequest commandRequest = CommandRequest.builder()
|
||||
.c(Command.GET_FORGOTTEN_LIST)
|
||||
.build();
|
||||
CommandResponse commandResponse = commandService.processCommand(commandRequest, null);
|
||||
List<String> keys = commandResponse.getKeys();
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
commandRequest = CommandRequest.builder()
|
||||
.c(Command.GET_FORGOTTEN)
|
||||
.key(keys.get(i))
|
||||
.build();
|
||||
commandResponse = commandService.processCommand(commandRequest, null);
|
||||
ForgottenFile file = new ForgottenFile(
|
||||
commandResponse.getKey(),
|
||||
documentManager.getDocumentType(commandResponse.getUrl()).toString().toLowerCase(),
|
||||
commandResponse.getUrl()
|
||||
);
|
||||
files.add(file);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
private boolean forgottenEnabled() {
|
||||
return Boolean.valueOf(enableForgotten);
|
||||
}
|
||||
|
||||
@DeleteMapping("/forgotten/{filename}")
|
||||
public ResponseEntity<String> delete(@PathVariable("filename") final String filename) {
|
||||
if (!forgottenEnabled()) {
|
||||
return new ResponseEntity<>(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
try {
|
||||
CommandRequest commandRequest = CommandRequest.builder()
|
||||
.c(Command.DELETE_FORGOTTEN)
|
||||
.key(filename)
|
||||
.build();
|
||||
|
||||
CommandResponse commandResponse = commandService.processCommand(commandRequest, null);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -21,9 +21,9 @@ package com.onlyoffice.integration.controllers;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStorageMutator;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.documentserver.util.Misc;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import com.onlyoffice.integration.documentserver.util.service.FormatService;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.sdk.manager.DocumentManager;
|
||||
import com.onlyoffice.integration.sdk.manager.UrlManager;
|
||||
import com.onlyoffice.integration.services.UserServices;
|
||||
import com.onlyoffice.integration.dto.FormatsList;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -55,9 +55,6 @@ public class IndexController {
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
|
||||
@Autowired
|
||||
private FileUtility fileUtility;
|
||||
|
||||
@Autowired
|
||||
private Misc mistUtility;
|
||||
|
||||
@ -65,13 +62,10 @@ public class IndexController {
|
||||
private UserServices userService;
|
||||
|
||||
@Autowired
|
||||
private FormatService formatService;
|
||||
private DocumentManager documentManager;
|
||||
|
||||
@Value("${files.docservice.url.site}")
|
||||
private String docserviceSite;
|
||||
|
||||
@Value("${files.docservice.url.preloader}")
|
||||
private String docservicePreloader;
|
||||
@Autowired
|
||||
private UrlManager urlManager;
|
||||
|
||||
@Value("${url.converter}")
|
||||
private String urlConverter;
|
||||
@ -85,6 +79,9 @@ public class IndexController {
|
||||
@Value("${server.version}")
|
||||
private String serverVersion;
|
||||
|
||||
@Value("${enable-forgotten}")
|
||||
private String enableForgotten;
|
||||
|
||||
@GetMapping("${url.index}")
|
||||
public String index(@RequestParam(value = "directUrl", required = false) final Boolean directUrl,
|
||||
final Model model) {
|
||||
@ -111,15 +108,14 @@ public class IndexController {
|
||||
|
||||
for (java.io.File file:files) { // run through all the files
|
||||
String fileName = file.getName(); // get file name
|
||||
docTypes.add(fileUtility
|
||||
docTypes.add(documentManager
|
||||
.getDocumentType(fileName)
|
||||
.toString()
|
||||
.toLowerCase()); // add a document type of each file to the list
|
||||
filesEditable.add(fileUtility.getEditedExts()
|
||||
.contains(fileUtility.getFileExtension(fileName))); // specify if a file is editable or not
|
||||
filesEditable.add(documentManager.isEditable(fileName)); // specify if a file is editable or not
|
||||
versions.add(" [" + storagePathBuilder.
|
||||
getFileVersion(fileName, true) + "]"); // add a file version to the list
|
||||
isFillFormDoc.add(fileUtility.getFillExts().contains(fileUtility.getFileExtension(fileName)));
|
||||
isFillFormDoc.add(documentManager.isFillable(fileName));
|
||||
}
|
||||
|
||||
// add all the parameters to the model
|
||||
@ -128,12 +124,13 @@ public class IndexController {
|
||||
model.addAttribute("files", files);
|
||||
model.addAttribute("docTypes", docTypes);
|
||||
model.addAttribute("filesEditable", filesEditable);
|
||||
model.addAttribute("datadocs", docserviceSite + docservicePreloader);
|
||||
model.addAttribute("datadocs", urlManager.getDocumentServerPreloaderApiUrl());
|
||||
model.addAttribute("tooltip", tooltip);
|
||||
model.addAttribute("users", users);
|
||||
model.addAttribute("languages", languages);
|
||||
model.addAttribute("directUrl", directUrl);
|
||||
model.addAttribute("serverVersion", serverVersion);
|
||||
model.addAttribute("enableForgotten", Boolean.valueOf(enableForgotten));
|
||||
|
||||
return "index.html";
|
||||
}
|
||||
@ -151,7 +148,7 @@ public class IndexController {
|
||||
@GetMapping("/formats")
|
||||
@ResponseBody
|
||||
public ResponseEntity<FormatsList> formats() { // return all the supported formats
|
||||
FormatsList list = new FormatsList(formatService.getFormats());
|
||||
FormatsList list = new FormatsList(documentManager.getFormats());
|
||||
return ResponseEntity.ok(list);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.callbacks;
|
||||
|
||||
import com.onlyoffice.integration.dto.Track;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class CallbackHandler {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(CallbackHandler.class);
|
||||
|
||||
private Map<Integer, Callback> callbackHandlers = new HashMap<>();
|
||||
|
||||
public void register(final int code, final Callback callback) { // register a callback handler
|
||||
callbackHandlers.put(code, callback);
|
||||
}
|
||||
|
||||
public int handle(final Track body, final String fileName) { // handle a callback
|
||||
Callback callback = callbackHandlers.get(body.getStatus());
|
||||
if (callback == null) {
|
||||
logger.warn("Callback status " + body.getStatus() + " is not supported yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int result = callback.handle(body, fileName);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.callbacks;
|
||||
|
||||
// document status
|
||||
public enum Status {
|
||||
EDITING(1), // 1 - document is being edited
|
||||
SAVE(2), // 2 - document is ready for saving
|
||||
CORRUPTED(3), // 3 - document saving error has occurred
|
||||
MUST_FORCE_SAVE(6), // 6 - document is being edited, but the current document state is saved
|
||||
CORRUPTED_FORCE_SAVE(7); // 7 - error has occurred while force saving the document
|
||||
private int code;
|
||||
Status(final int codeParam) {
|
||||
this.code = codeParam;
|
||||
}
|
||||
public int getCode() { // get document status
|
||||
return this.code;
|
||||
}
|
||||
}
|
||||
@ -1,59 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.callbacks.implementations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Callback;
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Status;
|
||||
import com.onlyoffice.integration.documentserver.managers.callback.CallbackManager;
|
||||
import com.onlyoffice.integration.dto.Action;
|
||||
import com.onlyoffice.integration.dto.Track;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class EditCallback implements Callback {
|
||||
@Autowired
|
||||
private CallbackManager callbackManager;
|
||||
@Override
|
||||
public int handle(final Track body,
|
||||
final String fileName) { // handle the callback when the document is being edited
|
||||
int result = 0;
|
||||
Action action = body.getActions().get(0); // get the user ID who is editing the document
|
||||
if (action.getType().equals(com.onlyoffice.integration.documentserver.models.enums
|
||||
.Action.edit)) { // if this value is not equal to the user ID
|
||||
String user = action.getUserid(); // get user ID
|
||||
if (!body.getUsers().contains(user)) { // if this user is not specified in the body
|
||||
String key = body.getKey(); // get document key
|
||||
try {
|
||||
// create a command request to forcibly save the document being edited without closing it
|
||||
callbackManager.commandRequest("forcesave", key, null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatus() { // get document status
|
||||
return Status.EDITING.getCode(); // return status 1 - document is being edited
|
||||
}
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.callbacks.implementations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Callback;
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Status;
|
||||
import com.onlyoffice.integration.documentserver.managers.callback.CallbackManager;
|
||||
import com.onlyoffice.integration.dto.Track;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ForcesaveCallback implements Callback {
|
||||
@Autowired
|
||||
private CallbackManager callbackManager;
|
||||
@Override
|
||||
public int handle(final Track body,
|
||||
final String fileName) { // handle the callback when the force saving request is performed
|
||||
int result = 0;
|
||||
try {
|
||||
callbackManager.processForceSave(body, fileName); // file force saving process
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
result = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatus() { // get document status
|
||||
// return status 6 - document is being edited, but the current document state is saved
|
||||
return Status.MUST_FORCE_SAVE.getCode();
|
||||
}
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.callbacks.implementations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Callback;
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Status;
|
||||
import com.onlyoffice.integration.documentserver.managers.callback.CallbackManager;
|
||||
import com.onlyoffice.integration.dto.Track;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SaveCallback implements Callback {
|
||||
@Autowired
|
||||
private CallbackManager callbackManager;
|
||||
@Override
|
||||
public int handle(final Track body,
|
||||
final String fileName) { // handle the callback when the saving request is performed
|
||||
int result = 0;
|
||||
try {
|
||||
callbackManager.processSave(body, fileName); // file saving process
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatus() { // get document status
|
||||
return Status.SAVE.getCode(); // return status 2 - document is ready for saving
|
||||
}
|
||||
}
|
||||
@ -18,11 +18,10 @@
|
||||
|
||||
package com.onlyoffice.integration.documentserver.managers.callback;
|
||||
|
||||
import com.onlyoffice.integration.dto.Track;
|
||||
import java.util.HashMap;
|
||||
import com.onlyoffice.model.documenteditor.Callback;
|
||||
|
||||
public interface CallbackManager { // specify the callback manager functions
|
||||
void processSave(Track body, String fileName); // file saving process
|
||||
void commandRequest(String method, String key, HashMap meta); // create a command request
|
||||
void processForceSave(Track body, String fileName); // file force saving process
|
||||
void processEditing(Callback callback, String fileName);
|
||||
void processSave(Callback callback, String fileName);
|
||||
void processForceSave(Callback callback, String fileName);
|
||||
}
|
||||
|
||||
@ -19,62 +19,60 @@
|
||||
package com.onlyoffice.integration.documentserver.managers.callback;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
|
||||
import com.onlyoffice.integration.documentserver.managers.history.HistoryManager;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStorageMutator;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import com.onlyoffice.integration.dto.Action;
|
||||
import com.onlyoffice.integration.documentserver.util.service.ServiceConverter;
|
||||
import com.onlyoffice.integration.dto.Track;
|
||||
import com.onlyoffice.integration.sdk.manager.DocumentManager;
|
||||
import com.onlyoffice.integration.sdk.manager.UrlManager;
|
||||
import com.onlyoffice.manager.request.RequestManager;
|
||||
import com.onlyoffice.model.commandservice.CommandRequest;
|
||||
import com.onlyoffice.model.commandservice.commandrequest.Command;
|
||||
import com.onlyoffice.model.convertservice.ConvertRequest;
|
||||
import com.onlyoffice.model.convertservice.ConvertResponse;
|
||||
import com.onlyoffice.model.documenteditor.Callback;
|
||||
import com.onlyoffice.model.documenteditor.callback.Action;
|
||||
import com.onlyoffice.model.documenteditor.callback.ForcesaveType;
|
||||
import com.onlyoffice.model.documenteditor.callback.action.Type;
|
||||
import com.onlyoffice.service.command.CommandService;
|
||||
import com.onlyoffice.service.convert.ConvertService;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.FILE_SAVE_TIMEOUT;
|
||||
|
||||
// todo: Refactoring
|
||||
@Component
|
||||
@Primary
|
||||
public class DefaultCallbackManager implements CallbackManager {
|
||||
|
||||
@Value("${files.docservice.url.site}")
|
||||
private String docserviceUrlSite;
|
||||
@Value("${files.docservice.url.command}")
|
||||
private String docserviceUrlCommand;
|
||||
@Value("${files.docservice.header}")
|
||||
private String documentJwtHeader;
|
||||
|
||||
@Autowired
|
||||
private DocumentManager documentManager;
|
||||
@Autowired
|
||||
private JwtManager jwtManager;
|
||||
@Autowired
|
||||
private FileUtility fileUtility;
|
||||
@Autowired
|
||||
private FileStorageMutator storageMutator;
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
@Autowired
|
||||
private ServiceConverter serviceConverter;
|
||||
private ConvertService convertService;
|
||||
@Autowired
|
||||
private RequestManager requestManager;
|
||||
@Autowired
|
||||
private CommandService commandService;
|
||||
@Autowired
|
||||
private HistoryManager historyManager;
|
||||
|
||||
@Autowired
|
||||
private UrlManager urlManager;
|
||||
|
||||
// download file from url
|
||||
@SneakyThrows
|
||||
@ -83,23 +81,18 @@ public class DefaultCallbackManager implements CallbackManager {
|
||||
throw new RuntimeException("Url argument is not specified"); // URL isn't specified
|
||||
}
|
||||
|
||||
URL uri = new URL(url);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
|
||||
connection.setConnectTimeout(FILE_SAVE_TIMEOUT);
|
||||
InputStream stream = connection.getInputStream(); // get input stream of the file information from the URL
|
||||
return requestManager.executeGetRequest(url, new RequestManager.Callback<byte[]>() {
|
||||
public byte[] doWork(final Object response) throws IOException {
|
||||
InputStream stream = ((HttpEntity) response).getContent(); // get input stream of the converted
|
||||
// file
|
||||
|
||||
int statusCode = connection.getResponseCode();
|
||||
if (statusCode != HttpStatus.OK.value()) { // checking status code
|
||||
connection.disconnect();
|
||||
throw new RuntimeException("Document editing service returned status: " + statusCode);
|
||||
}
|
||||
if (stream == null) {
|
||||
throw new RuntimeException("Input stream is null");
|
||||
}
|
||||
|
||||
if (stream == null) {
|
||||
connection.disconnect();
|
||||
throw new RuntimeException("Input stream is null");
|
||||
}
|
||||
|
||||
return stream.readAllBytes();
|
||||
return stream.readAllBytes();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// file saving
|
||||
@ -112,34 +105,66 @@ public class DefaultCallbackManager implements CallbackManager {
|
||||
storageMutator.createOrUpdateFile(path, new ByteArrayInputStream(byteArray));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processEditing(final Callback callback, final String fileName) {
|
||||
Action action = callback.getActions().get(0); // get the user ID who is editing the document
|
||||
if (action.getType().equals(Type.CONNECTED)) { // if this value is not equal to the user ID
|
||||
String user = action.getUserid(); // get user ID
|
||||
if (!callback.getUsers().contains(user)) { // if this user is not specified in the body
|
||||
CommandRequest commandRequest = CommandRequest.builder()
|
||||
.c(Command.FORCESAVE)
|
||||
.key(callback.getKey())
|
||||
.build();
|
||||
|
||||
// create a command request to forcibly save the document being edited without closing it
|
||||
try {
|
||||
commandService.processCommand(commandRequest, fileName);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void processSave(final Track body, final String fileName) { // file saving process
|
||||
String downloadUri = body.getUrl();
|
||||
String changesUri = body.getChangesurl();
|
||||
String key = body.getKey();
|
||||
public void processSave(final Callback callback, final String fileName) { // file saving process
|
||||
String downloadUri = callback.getUrl();
|
||||
String changesUri = callback.getChangesurl();
|
||||
String key = callback.getKey();
|
||||
String newFileName = fileName;
|
||||
|
||||
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
|
||||
String downloadExt = body.getFiletype(); // get an extension of the downloaded file
|
||||
String curExt = documentManager.getExtension(fileName); // get current file extension
|
||||
String downloadExt = callback.getFiletype(); // get an extension of the downloaded file
|
||||
|
||||
downloadUri = urlManager.replaceToInnerDocumentServerUrl(downloadUri);
|
||||
changesUri = urlManager.replaceToInnerDocumentServerUrl(changesUri);
|
||||
|
||||
// todo: Refactoring
|
||||
// convert downloaded file to the file with the current extension if these extensions aren't equal
|
||||
if (!curExt.equals(downloadExt)) {
|
||||
try {
|
||||
String newFileUri = serviceConverter
|
||||
.getConvertedData(downloadUri, downloadExt, curExt,
|
||||
serviceConverter.generateRevisionId(downloadUri), null, false,
|
||||
null).getUri(); // convert a file and get URL to a new file
|
||||
if (newFileUri.isEmpty()) {
|
||||
ConvertRequest convertRequest = ConvertRequest.builder()
|
||||
.key(documentManager.generateRevisionId(downloadUri))
|
||||
.url(downloadUri)
|
||||
.outputtype(curExt)
|
||||
.async(false)
|
||||
.build();
|
||||
|
||||
// convert a file and get URL to a new file
|
||||
ConvertResponse convertResponse = convertService.processConvert(convertRequest, fileName);
|
||||
|
||||
String newFileUri = convertResponse.getFileUrl();
|
||||
|
||||
if (newFileUri == null || newFileUri.isEmpty()) {
|
||||
newFileName = documentManager
|
||||
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + "."
|
||||
.getCorrectName(documentManager.getBaseName(fileName) + "."
|
||||
+ downloadExt); // get the correct file name if it already exists
|
||||
} else {
|
||||
downloadUri = newFileUri;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
newFileName = documentManager
|
||||
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + "." + downloadExt);
|
||||
.getCorrectName(documentManager.getBaseName(fileName) + "." + downloadExt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +178,7 @@ public class DefaultCallbackManager implements CallbackManager {
|
||||
Path histDir = Paths.get(storagePathBuilder.getHistoryDir(storagePath)); // get the history directory
|
||||
storageMutator.createDirectory(histDir); // and create it
|
||||
|
||||
String versionDir = documentManager
|
||||
String versionDir = historyManager
|
||||
.versionDir(histDir.toAbsolutePath().toString(), // get the file version directory
|
||||
storagePathBuilder
|
||||
.getFileVersion(histDir.toAbsolutePath().toString(), false), true);
|
||||
@ -172,13 +197,13 @@ public class DefaultCallbackManager implements CallbackManager {
|
||||
.of(versionDir + File.separator + "diff.zip")); // save file changes to the diff.zip archive
|
||||
|
||||
JSONObject jsonChanges = new JSONObject(); // create a json object for document changes
|
||||
jsonChanges.put("changes", body.getHistory().getChanges()); // put the changes to the json object
|
||||
jsonChanges.put("serverVersion", body.getHistory()
|
||||
jsonChanges.put("changes", callback.getHistory().getChanges()); // put the changes to the json object
|
||||
jsonChanges.put("serverVersion", callback.getHistory()
|
||||
.getServerVersion()); // put the server version to the json object
|
||||
String history = objectMapper.writeValueAsString(jsonChanges);
|
||||
|
||||
if (history == null && body.getHistory() != null) {
|
||||
history = objectMapper.writeValueAsString(body.getHistory());
|
||||
if (history == null && callback.getHistory() != null) {
|
||||
history = objectMapper.writeValueAsString(callback.getHistory());
|
||||
}
|
||||
|
||||
if (history != null && !history.isEmpty()) {
|
||||
@ -194,82 +219,16 @@ public class DefaultCallbackManager implements CallbackManager {
|
||||
}
|
||||
}
|
||||
|
||||
// todo: Replace (String method) with (Enum method)
|
||||
@SneakyThrows
|
||||
public void commandRequest(final String method,
|
||||
final String key,
|
||||
final HashMap meta) { // create a command request
|
||||
String documentCommandUrl = docserviceUrlSite + docserviceUrlCommand;
|
||||
public void processForceSave(final Callback callback, final String fileNameParam) { // file force saving process
|
||||
|
||||
URL url = new URL(documentCommandUrl);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
|
||||
HashMap<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("c", method);
|
||||
params.put("key", key);
|
||||
|
||||
if (meta != null) {
|
||||
params.put("meta", meta);
|
||||
}
|
||||
|
||||
String headerToken;
|
||||
// check if a secret key to generate token exists or not
|
||||
if (jwtManager.tokenEnabled() && jwtManager.tokenUseForRequest()) {
|
||||
Map<String, Object> payloadMap = new HashMap<>();
|
||||
payloadMap.put("payload", params);
|
||||
headerToken = jwtManager.createToken(payloadMap); // encode a payload object into a header token
|
||||
|
||||
// add a header Authorization with a header token and Authorization prefix in it
|
||||
connection.setRequestProperty(documentJwtHeader.equals("")
|
||||
? "Authorization" : documentJwtHeader, "Bearer " + headerToken);
|
||||
|
||||
String token = jwtManager.createToken(params); // encode a payload object into a body token
|
||||
params.put("token", token);
|
||||
}
|
||||
|
||||
String bodyString = objectMapper.writeValueAsString(params);
|
||||
|
||||
byte[] bodyByte = bodyString.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
connection.setRequestMethod("POST"); // set the request method
|
||||
connection
|
||||
.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); // set the Content-Type header
|
||||
connection.setDoOutput(true); // set the doOutput field to true
|
||||
connection.connect();
|
||||
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
os.write(bodyByte); // write bytes to the output stream
|
||||
}
|
||||
|
||||
InputStream stream = connection.getInputStream(); // get input stream
|
||||
|
||||
if (stream == null) {
|
||||
throw new RuntimeException("Could not get an answer");
|
||||
}
|
||||
|
||||
String jsonString = serviceConverter.convertStreamToString(stream); // convert stream to json string
|
||||
connection.disconnect();
|
||||
|
||||
JSONObject response = serviceConverter.convertStringToJSON(jsonString); // convert json string to json object
|
||||
// todo: Add errors ENUM
|
||||
String responseCode = response.get("error").toString();
|
||||
switch (responseCode) {
|
||||
case "0":
|
||||
case "4":
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(response.toJSONString());
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void processForceSave(final Track body, final String fileNameParam) { // file force saving process
|
||||
|
||||
String downloadUri = body.getUrl();
|
||||
String downloadUri = callback.getUrl();
|
||||
String fileName = fileNameParam;
|
||||
|
||||
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
|
||||
String downloadExt = body.getFiletype(); // get an extension of the downloaded file
|
||||
String curExt = documentManager.getExtension(fileName); // get current file extension
|
||||
String downloadExt = callback.getFiletype(); // get an extension of the downloaded file
|
||||
|
||||
downloadUri = urlManager.replaceToInnerDocumentServerUrl(downloadUri);
|
||||
|
||||
Boolean newFileName = false;
|
||||
|
||||
@ -277,11 +236,19 @@ public class DefaultCallbackManager implements CallbackManager {
|
||||
// todo: Extract function
|
||||
if (!curExt.equals(downloadExt)) {
|
||||
try {
|
||||
// convert file and get URL to a new file
|
||||
String newFileUri = serviceConverter
|
||||
.getConvertedData(downloadUri, downloadExt, curExt, serviceConverter
|
||||
.generateRevisionId(downloadUri), null, false, null).getUri();
|
||||
if (newFileUri.isEmpty()) {
|
||||
ConvertRequest convertRequest = ConvertRequest.builder()
|
||||
.key(documentManager.generateRevisionId(downloadUri))
|
||||
.url(downloadUri)
|
||||
.outputtype(curExt)
|
||||
.async(false)
|
||||
.build();
|
||||
|
||||
// convert a file and get URL to a new file
|
||||
ConvertResponse convertResponse = convertService.processConvert(convertRequest, fileName);
|
||||
|
||||
String newFileUri = convertResponse.getFileUrl();
|
||||
|
||||
if (newFileUri == null || newFileUri.isEmpty()) {
|
||||
newFileName = true;
|
||||
} else {
|
||||
downloadUri = newFileUri;
|
||||
@ -296,32 +263,34 @@ public class DefaultCallbackManager implements CallbackManager {
|
||||
|
||||
// todo: Use ENUMS
|
||||
// todo: Pointless toString conversion
|
||||
boolean isSubmitForm = body.getForcesavetype().toString().equals("3");
|
||||
boolean isSubmitForm = callback.getForcesavetype().equals(ForcesaveType.SUBMIT_FORM);
|
||||
|
||||
// todo: Extract function
|
||||
if (isSubmitForm) { // if the form is submitted
|
||||
if (newFileName) {
|
||||
// get the correct file name if it already exists
|
||||
fileName = documentManager
|
||||
.getCorrectName(fileUtility
|
||||
.getFileNameWithoutExtension(fileName) + "-form." + downloadExt);
|
||||
.getCorrectName(documentManager
|
||||
.getBaseName(fileName) + "-form." + downloadExt);
|
||||
} else {
|
||||
fileName = documentManager
|
||||
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + "-form." + curExt);
|
||||
.getCorrectName(documentManager.getBaseName(fileName) + "-form." + curExt);
|
||||
}
|
||||
forcesavePath = storagePathBuilder.getFileLocation(fileName); // create forcesave path if it doesn't exist
|
||||
List<Action> actions = body.getActions();
|
||||
Action action = actions.get(0);
|
||||
List<com.onlyoffice.model.documenteditor.callback.Action> actions = callback.getActions();
|
||||
com.onlyoffice.model.documenteditor.callback.Action action = actions.get(0);
|
||||
String user = action.getUserid(); // get the user ID
|
||||
// create meta data for the forcesaved file
|
||||
storageMutator.createMeta(fileName, user, "Filling Form");
|
||||
|
||||
try {
|
||||
String formsDataUrl = body.getFormsdataurl();
|
||||
String formsDataUrl = callback.getFormsdataurl();
|
||||
|
||||
formsDataUrl = urlManager.replaceToInnerDocumentServerUrl(formsDataUrl);
|
||||
|
||||
if (formsDataUrl != null && !formsDataUrl.isEmpty()) {
|
||||
String formsName = documentManager.getCorrectName(fileUtility
|
||||
.getFileNameWithoutExtension(fileName) + ".txt");
|
||||
String formsName = documentManager.getCorrectName(documentManager
|
||||
.getBaseName(fileName) + ".txt");
|
||||
String formsPath = storagePathBuilder.getFileLocation(formsName);
|
||||
|
||||
byte[] byteArrayFormsData = getDownloadFile(formsDataUrl);
|
||||
@ -336,7 +305,7 @@ public class DefaultCallbackManager implements CallbackManager {
|
||||
} else {
|
||||
if (newFileName) {
|
||||
fileName = documentManager
|
||||
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + downloadExt);
|
||||
.getCorrectName(documentManager.getBaseName(fileName) + "." + downloadExt);
|
||||
}
|
||||
|
||||
forcesavePath = storagePathBuilder.getForcesavePath(fileName, false);
|
||||
|
||||
@ -1,246 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.managers.document;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStorageMutator;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import com.onlyoffice.integration.documentserver.util.service.ServiceConverter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.KILOBYTE_SIZE;
|
||||
|
||||
@Component
|
||||
@Primary
|
||||
public class DefaultDocumentManager implements DocumentManager {
|
||||
|
||||
@Value("${files.storage.folder}")
|
||||
private String storageFolder;
|
||||
@Value("${files.storage}")
|
||||
private String filesStorage;
|
||||
@Value("${url.track}")
|
||||
private String trackUrl;
|
||||
@Value("${url.download}")
|
||||
private String downloadUrl;
|
||||
|
||||
@Autowired
|
||||
private FileStorageMutator storageMutator;
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
@Autowired
|
||||
private FileUtility fileUtility;
|
||||
@Autowired
|
||||
private ServiceConverter serviceConverter;
|
||||
|
||||
// get URL to the created file
|
||||
public String getCreateUrl(final String fileName, final Boolean sample) {
|
||||
String fileExt = fileUtility.getFileExtension(fileName);
|
||||
String url = storagePathBuilder.getServerUrl(true)
|
||||
+ "/create?fileExt=" + fileExt + "&sample=" + sample;
|
||||
return url;
|
||||
}
|
||||
|
||||
// get a file name with an index if the file with such a name already exists
|
||||
public String getCorrectName(final String fileName) {
|
||||
String baseName = fileUtility.getFileNameWithoutExtension(fileName); // get file name without extension
|
||||
String ext = fileUtility.getFileExtension(fileName); // get file extension
|
||||
String name = baseName + "." + ext; // create a full file name
|
||||
|
||||
Path path = Paths.get(storagePathBuilder.getFileLocation(name));
|
||||
|
||||
// run through all the files with such a name in the storage directory
|
||||
for (int i = 1; Files.exists(path); i++) {
|
||||
name = baseName + " (" + i + ")." + ext; // and add an index to the base name
|
||||
path = Paths.get(storagePathBuilder.getFileLocation(name));
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
// get file URL
|
||||
public String getFileUri(final String fileName, final Boolean forDocumentServer) {
|
||||
try {
|
||||
String serverPath = storagePathBuilder.getServerUrl(forDocumentServer); // get server URL
|
||||
String hostAddress = storagePathBuilder.getStorageLocation(); // get the storage directory
|
||||
String filePathDownload = !fileName.contains(InetAddress.getLocalHost().getHostAddress()) ? fileName
|
||||
: fileName.substring(fileName.indexOf(InetAddress.getLocalHost()
|
||||
.getHostAddress()) + InetAddress.getLocalHost().getHostAddress().length() + 1);
|
||||
if (!filesStorage.isEmpty() && filePathDownload.contains(filesStorage)) {
|
||||
filePathDownload = filePathDownload.substring(filesStorage.length() + 1);
|
||||
}
|
||||
|
||||
String filePath = serverPath + "/download?fileName=" + URLEncoder
|
||||
.encode(filePathDownload, java.nio.charset.StandardCharsets.UTF_8.toString()) + "&userAddress"
|
||||
+ URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
|
||||
return filePath;
|
||||
} catch (UnsupportedEncodingException | UnknownHostException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// get file URL
|
||||
public String getHistoryFileUrl(final String fileName, final Integer version, final String file,
|
||||
final Boolean forDocumentServer) {
|
||||
try {
|
||||
String serverPath = storagePathBuilder.getServerUrl(forDocumentServer); // get server URL
|
||||
String hostAddress = storagePathBuilder.getStorageLocation(); // get the storage directory
|
||||
String filePathDownload = !fileName.contains(InetAddress.getLocalHost().getHostAddress()) ? fileName
|
||||
: fileName.substring(fileName.indexOf(InetAddress.getLocalHost().getHostAddress())
|
||||
+ InetAddress.getLocalHost().getHostAddress().length() + 1);
|
||||
String userAddress = forDocumentServer ? "&userAddress" + URLEncoder
|
||||
.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString()) : "";
|
||||
String filePath = serverPath + "/downloadhistory?fileName=" + URLEncoder
|
||||
.encode(filePathDownload, java.nio.charset.StandardCharsets.UTF_8.toString())
|
||||
+ "&ver=" + version + "&file=" + file
|
||||
+ userAddress;
|
||||
return filePath;
|
||||
} catch (UnsupportedEncodingException | UnknownHostException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// get the callback URL
|
||||
public String getCallback(final String fileName) {
|
||||
String serverPath = storagePathBuilder.getServerUrl(true);
|
||||
String storageAddress = storagePathBuilder.getStorageLocation();
|
||||
try {
|
||||
String query = trackUrl + "?fileName="
|
||||
+ URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString())
|
||||
+ "&userAddress=" + URLEncoder
|
||||
.encode(storageAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
|
||||
return serverPath + query;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// get URL to download a file
|
||||
public String getDownloadUrl(final String fileName, final Boolean isServer) {
|
||||
String serverPath = storagePathBuilder.getServerUrl(isServer);
|
||||
String storageAddress = storagePathBuilder.getStorageLocation();
|
||||
try {
|
||||
String userAddress = isServer ? "&userAddress=" + URLEncoder
|
||||
.encode(storageAddress, java.nio.charset.StandardCharsets.UTF_8.toString()) : "";
|
||||
String query = downloadUrl + "?fileName="
|
||||
+ URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString())
|
||||
+ userAddress;
|
||||
|
||||
return serverPath + query;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// get file information
|
||||
public ArrayList<Map<String, Object>> getFilesInfo() {
|
||||
ArrayList<Map<String, Object>> files = new ArrayList<>();
|
||||
|
||||
// run through all the stored files
|
||||
for (File file : storageMutator.getStoredFiles()) {
|
||||
Map<String, Object> map = new LinkedHashMap<>(); // write all the parameters to the map
|
||||
map.put("version", storagePathBuilder.getFileVersion(file.getName(), false));
|
||||
map.put("id", serviceConverter
|
||||
.generateRevisionId(storagePathBuilder.getStorageLocation()
|
||||
+ "/" + file.getName() + "/"
|
||||
+ Paths.get(storagePathBuilder.getFileLocation(file.getName()))
|
||||
.toFile()
|
||||
.lastModified()));
|
||||
map.put("contentLength", new BigDecimal(String.valueOf((file.length() / Double.valueOf(KILOBYTE_SIZE))))
|
||||
.setScale(2, RoundingMode.HALF_UP) + " KB");
|
||||
map.put("pureContentLength", file.length());
|
||||
map.put("title", file.getName());
|
||||
map.put("updated", String.valueOf(new Date(file.lastModified())));
|
||||
files.add(map);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
// get file information by its ID
|
||||
public ArrayList<Map<String, Object>> getFilesInfo(final String fileId) {
|
||||
ArrayList<Map<String, Object>> file = new ArrayList<>();
|
||||
|
||||
for (Map<String, Object> map : getFilesInfo()) {
|
||||
if (map.get("id").equals(fileId)) {
|
||||
file.add(map);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
// get the path to the file version by the history path and file version
|
||||
public String versionDir(final String path, final Integer version, final boolean historyPath) {
|
||||
if (!historyPath) {
|
||||
return storagePathBuilder.getHistoryDir(storagePathBuilder.getFileLocation(path)) + version;
|
||||
}
|
||||
return path + File.separator + version;
|
||||
}
|
||||
|
||||
// create demo document
|
||||
public String createDemo(final String fileExt, final Boolean sample, final String uid, final String uname) {
|
||||
String demoName = (sample ? "sample." : "new.")
|
||||
+ fileExt; // create sample or new template file with the necessary extension
|
||||
String demoPath =
|
||||
"assets"
|
||||
+ File.separator
|
||||
+ "document-templates"
|
||||
+ File.separator
|
||||
+ (sample ? "sample" : "new")
|
||||
+ File.separator
|
||||
+ demoName;
|
||||
|
||||
// get a file name with an index if the file with such a name already exists
|
||||
String fileName = getCorrectName(demoName);
|
||||
|
||||
InputStream stream = Thread.currentThread()
|
||||
.getContextClassLoader()
|
||||
.getResourceAsStream(demoPath); // get the input file stream
|
||||
|
||||
if (stream == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
storageMutator.createFile(Path.of(storagePathBuilder
|
||||
.getFileLocation(fileName)), stream); // create a file in the specified directory
|
||||
storageMutator.createMeta(fileName, uid, uname); // create meta information of the demo file
|
||||
|
||||
return fileName;
|
||||
}
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.managers.document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
// specify the document manager functions
|
||||
public interface DocumentManager {
|
||||
|
||||
// get a file name with an index if the file with such a name already exists
|
||||
String getCorrectName(String fileName);
|
||||
String getFileUri(String fileName, Boolean forDocumentServer); // get file URL
|
||||
String getHistoryFileUrl(String fileName, Integer version, String file, Boolean forDocumentServer); // get file URL
|
||||
String getCallback(String fileName); // get the callback URL
|
||||
String getDownloadUrl(String fileName, Boolean forDocumentServer); // get URL to download a file
|
||||
ArrayList<Map<String, Object>> getFilesInfo(); // get file information
|
||||
ArrayList<Map<String, Object>> getFilesInfo(String fileId); // get file information by its ID
|
||||
|
||||
// get the path to the file version by the history path and file version
|
||||
String versionDir(String path, Integer version, boolean historyPath);
|
||||
|
||||
// create demo document
|
||||
String createDemo(String fileExt, Boolean sample, String uid, String uname) throws Exception;
|
||||
String getCreateUrl(String fileName, Boolean sample); // get URL to the created file
|
||||
}
|
||||
@ -20,14 +20,17 @@ package com.onlyoffice.integration.documentserver.managers.history;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
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 com.onlyoffice.integration.sdk.manager.DocumentManager;
|
||||
import com.onlyoffice.integration.sdk.manager.UrlManager;
|
||||
import com.onlyoffice.manager.security.JwtManager;
|
||||
import com.onlyoffice.manager.settings.SettingsManager;
|
||||
import com.onlyoffice.model.common.User;
|
||||
import com.onlyoffice.model.documenteditor.HistoryData;
|
||||
import com.onlyoffice.model.documenteditor.callback.History;
|
||||
import com.onlyoffice.model.documenteditor.history.Version;
|
||||
import com.onlyoffice.model.documenteditor.historydata.Previous;
|
||||
import lombok.SneakyThrows;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -35,6 +38,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -49,15 +53,9 @@ public class DefaultHistoryManager implements HistoryManager {
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
|
||||
@Autowired
|
||||
private DocumentManager documentManager;
|
||||
|
||||
@Autowired
|
||||
private JwtManager jwtManager;
|
||||
|
||||
@Autowired
|
||||
private FileUtility fileUtility;
|
||||
|
||||
@Autowired
|
||||
private JSONParser parser;
|
||||
|
||||
@ -65,109 +63,13 @@ public class DefaultHistoryManager implements HistoryManager {
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
private ServiceConverter serviceConverter;
|
||||
private SettingsManager settingsManager;
|
||||
|
||||
// todo: Refactoring
|
||||
@SneakyThrows
|
||||
public String[] getHistory(final Document document) { // get document history
|
||||
@Autowired
|
||||
private UrlManager urlManager;
|
||||
|
||||
// get history directory
|
||||
String histDir = storagePathBuilder.getHistoryDir(storagePathBuilder.getFileLocation(document.getTitle()));
|
||||
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<>();
|
||||
Map<String, Object> histData = new HashMap<>();
|
||||
|
||||
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, true); // get the path to the given file version
|
||||
|
||||
String key = i == curVer ? document.getKey() : readFileToEnd(new File(verDir
|
||||
+ File.separator + "key.txt")); // get document key
|
||||
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()));
|
||||
dataObj.put("key", key);
|
||||
dataObj.put("url", i == curVer ? document.getUrl()
|
||||
: documentManager.getHistoryFileUrl(document.getTitle(), i, "prev." + fileUtility
|
||||
.getFileExtension(document.getTitle()), true));
|
||||
if (!document.getDirectUrl().equals("")) {
|
||||
dataObj.put("directUrl", i == curVer ? document.getDirectUrl()
|
||||
: documentManager.getHistoryFileUrl(document.getTitle(), i, "prev." + fileUtility
|
||||
.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, 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"));
|
||||
|
||||
// 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"));
|
||||
prevInfo.put("key", prev.get("key")); // write key and URL information about previous file version
|
||||
prevInfo.put("url", prev.get("url"));
|
||||
if (!document.getDirectUrl().equals("")) {
|
||||
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(document.getTitle(), verdiff, "diff.zip", true));
|
||||
}
|
||||
|
||||
if (jwtManager.tokenEnabled()) {
|
||||
dataObj.put("token", jwtManager.createToken(dataObj));
|
||||
}
|
||||
|
||||
hist.add(obj);
|
||||
histData.put(Integer.toString(i - 1), dataObj);
|
||||
}
|
||||
|
||||
// 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 new String[]{objectMapper.writeValueAsString(histObj),
|
||||
objectMapper.writeValueAsString(histData)};
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return new String[]{"", ""};
|
||||
}
|
||||
@Autowired
|
||||
private DocumentManager documentManager;
|
||||
|
||||
// todo: Refactoring
|
||||
@SneakyThrows
|
||||
@ -178,16 +80,14 @@ public class DefaultHistoryManager implements HistoryManager {
|
||||
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<>();
|
||||
List<Version> history = 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 verDir = versionDir(histDir, i, true); // get the path to the given file version
|
||||
|
||||
String key;
|
||||
if (i == curVer) {
|
||||
key = serviceConverter
|
||||
key = documentManager
|
||||
.generateRevisionId(storagePathBuilder.getStorageLocation()
|
||||
+ "/" + fileName + "/"
|
||||
+ new File(storagePathBuilder.getFileLocation(fileName)).lastModified());
|
||||
@ -195,8 +95,10 @@ public class DefaultHistoryManager implements HistoryManager {
|
||||
key = readFileToEnd(new File(verDir + File.separator + "key.txt"));
|
||||
}
|
||||
|
||||
obj.put("key", key);
|
||||
obj.put("version", i);
|
||||
Version version = Version.builder()
|
||||
.key(key)
|
||||
.version(String.valueOf(i))
|
||||
.build();
|
||||
|
||||
if (i == 1) { // check if the version number is equal to 1
|
||||
String createdInfo = readFileToEnd(new File(histDir
|
||||
@ -204,33 +106,35 @@ public class DefaultHistoryManager implements HistoryManager {
|
||||
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);
|
||||
version.setCreated(String.valueOf(json.get("created")));
|
||||
version.setUser(User.builder()
|
||||
.id(String.valueOf(json.get("id")))
|
||||
.name(String.valueOf(json.get("name")))
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
InputStream changesSteam = new FileInputStream(
|
||||
versionDir(histDir, i - 1, true) + File.separator + "changes.json");
|
||||
|
||||
History changes = objectMapper.readValue(changesSteam, History.class);
|
||||
|
||||
// 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"));
|
||||
version.setChanges(changes.getChanges());
|
||||
version.setServerVersion(changes.getServerVersion());
|
||||
version.setCreated(changes.getChanges().get(0).getCreated());
|
||||
version.setUser(changes.getChanges().get(0).getUser());
|
||||
}
|
||||
|
||||
hist.add(obj);
|
||||
history.add(version);
|
||||
}
|
||||
|
||||
// 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);
|
||||
histObj.put("history", history);
|
||||
|
||||
try {
|
||||
return objectMapper.writeValueAsString(histObj);
|
||||
@ -249,68 +153,69 @@ public class DefaultHistoryManager implements HistoryManager {
|
||||
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<>();
|
||||
Map<String, HistoryData> historyDataMap = 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 verDir = versionDir(histDir, i, true); // get the path to the given file version
|
||||
|
||||
String key;
|
||||
if (i == curVer) {
|
||||
key = serviceConverter
|
||||
key = documentManager
|
||||
.generateRevisionId(storagePathBuilder.getStorageLocation()
|
||||
+ "/" + fileName + "/"
|
||||
+ new File(storagePathBuilder.getFileLocation(fileName)).lastModified());
|
||||
} else {
|
||||
key = readFileToEnd(new File(verDir + File.separator + "key.txt"));
|
||||
}
|
||||
HistoryData historyData = HistoryData.builder()
|
||||
.fileType(documentManager.getExtension(fileName))
|
||||
.key(key)
|
||||
.url(i == curVer ? urlManager.getFileUrl(fileName)
|
||||
: urlManager.getHistoryFileUrl(fileName, i, "prev" + documentManager
|
||||
.getExtension(fileName), true))
|
||||
.build();
|
||||
|
||||
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));
|
||||
historyData.setDirectUrl(i == curVer
|
||||
? urlManager.getDirectFileUrl(fileName)
|
||||
: urlManager.getHistoryFileUrl(fileName, i, "prev" + documentManager
|
||||
.getExtension(fileName), false)
|
||||
);
|
||||
}
|
||||
dataObj.put("version", i);
|
||||
historyData.setVersion(String.valueOf(i));
|
||||
|
||||
if (i > 1) { //check if the version number is greater than 1
|
||||
Integer verdiff = i - 1;
|
||||
// get the history data from the previous file version
|
||||
Map<String, Object> prev = (Map<String, Object>) histData.get(Integer.toString(verdiff));
|
||||
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"));
|
||||
HistoryData historyDataPrev = historyDataMap.get(Integer.toString(verdiff));
|
||||
Previous previous = Previous.builder()
|
||||
.fileType(historyDataPrev.getFileType())
|
||||
.key(historyDataPrev.getKey())
|
||||
.url(historyDataPrev.getUrl())
|
||||
.build();
|
||||
if (directUrl) {
|
||||
prevInfo.put("directUrl", prev.get("directUrl"));
|
||||
previous.setDirectUrl(historyDataPrev.getDirectUrl());
|
||||
}
|
||||
|
||||
// write information about previous file version to the data object
|
||||
dataObj.put("previous", prevInfo);
|
||||
historyData.setPrevious(previous);
|
||||
|
||||
if (diffExists(histDir, verdiff)) {
|
||||
// write the path to the diff.zip archive with differences in this file version
|
||||
dataObj.put("changesUrl", documentManager
|
||||
historyData.setChangesUrl(urlManager
|
||||
.getHistoryFileUrl(fileName, verdiff, "diff.zip", true));
|
||||
}
|
||||
}
|
||||
|
||||
if (jwtManager.tokenEnabled()) {
|
||||
dataObj.put("token", jwtManager.createToken(dataObj));
|
||||
if (settingsManager.isSecurityEnabled()) {
|
||||
historyData.setToken(jwtManager.createToken(historyData));
|
||||
}
|
||||
|
||||
histData.put(Integer.toString(i), dataObj);
|
||||
historyDataMap.put(Integer.toString(i), historyData);
|
||||
}
|
||||
|
||||
try {
|
||||
return objectMapper.writeValueAsString(histData.get(version));
|
||||
return objectMapper.writeValueAsString(historyDataMap.get(version));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -318,6 +223,14 @@ public class DefaultHistoryManager implements HistoryManager {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String versionDir(final String path, final Integer version, final boolean historyPath) {
|
||||
if (!historyPath) {
|
||||
return storagePathBuilder.getHistoryDir(storagePathBuilder.getFileLocation(path)) + version;
|
||||
}
|
||||
return path + File.separator + version;
|
||||
}
|
||||
|
||||
|
||||
// read a file
|
||||
private String readFileToEnd(final File file) {
|
||||
|
||||
@ -21,6 +21,6 @@ package com.onlyoffice.integration.documentserver.managers.history;
|
||||
// specify the history manager functions
|
||||
public interface HistoryManager {
|
||||
String getHistory(String fileName); // get document history
|
||||
|
||||
String getHistoryData(String fileName, String version, Boolean directUrl); // get document history data
|
||||
String versionDir(String path, Integer version, boolean historyPath);
|
||||
}
|
||||
|
||||
@ -1,130 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.managers.jwt;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.primeframework.jwt.Signer;
|
||||
import org.primeframework.jwt.Verifier;
|
||||
import org.primeframework.jwt.domain.JWT;
|
||||
import org.primeframework.jwt.hmac.HMACSigner;
|
||||
import org.primeframework.jwt.hmac.HMACVerifier;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class DefaultJwtManager implements JwtManager {
|
||||
@Value("${files.docservice.secret}")
|
||||
private String tokenSecret;
|
||||
@Value("${files.docservice.token-use-for-request}")
|
||||
private String tokenUseForRequest;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
@Autowired
|
||||
private JSONParser parser;
|
||||
|
||||
// create document token
|
||||
public String createToken(final Map<String, Object> payloadClaims) {
|
||||
try {
|
||||
// build a HMAC signer using a SHA-256 hash
|
||||
Signer signer = HMACSigner.newSHA256Signer(tokenSecret);
|
||||
JWT jwt = new JWT();
|
||||
for (String key : payloadClaims.keySet()) { // run through all the keys from the payload
|
||||
jwt.addClaim(key, payloadClaims.get(key)); // and write each claim to the jwt
|
||||
}
|
||||
return JWT.getEncoder().encode(jwt, signer); // sign and encode the JWT to a JSON string representation
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// check if the token is enabled
|
||||
public boolean tokenEnabled() {
|
||||
return tokenSecret != null && !tokenSecret.isEmpty();
|
||||
}
|
||||
|
||||
public boolean tokenUseForRequest() {
|
||||
return Boolean.parseBoolean(tokenUseForRequest) && !tokenUseForRequest.isEmpty();
|
||||
}
|
||||
|
||||
// read document token
|
||||
public JWT readToken(final String token) {
|
||||
try {
|
||||
// build a HMAC verifier using the token secret
|
||||
Verifier verifier = HMACVerifier.newVerifier(tokenSecret);
|
||||
|
||||
// verify and decode the encoded string JWT to a rich object
|
||||
return JWT.getDecoder().decode(token, verifier);
|
||||
} catch (Exception exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// parse the body
|
||||
public JSONObject parseBody(final String payload, final String header) {
|
||||
JSONObject body;
|
||||
try {
|
||||
Object obj = parser.parse(payload); // get body parameters by parsing the payload
|
||||
body = (JSONObject) obj;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("{\"error\":1,\"message\":\"JSON Parsing error\"}");
|
||||
}
|
||||
if (tokenEnabled() && tokenUseForRequest()) { // check if the token is enabled
|
||||
String token = (String) body.get("token"); // get token from the body
|
||||
if (token == null) { // if token is empty
|
||||
if (header != null && !header.isBlank()) { // and the header is defined
|
||||
|
||||
// get token from the header (it is placed after the Bearer prefix if it exists)
|
||||
token = header.startsWith("Bearer ") ? header.substring("Bearer ".length()) : header;
|
||||
}
|
||||
}
|
||||
if (token == null || token.isBlank()) {
|
||||
throw new RuntimeException("{\"error\":1,\"message\":\"JWT expected\"}");
|
||||
}
|
||||
|
||||
JWT jwt = readToken(token); // read token
|
||||
if (jwt == null) {
|
||||
throw new RuntimeException("{\"error\":1,\"message\":\"JWT validation failed\"}");
|
||||
}
|
||||
if (jwt.getObject("payload") != null) { // get payload from the token and check if it is not empty
|
||||
try {
|
||||
@SuppressWarnings("unchecked") LinkedHashMap<String, Object> jwtPayload =
|
||||
(LinkedHashMap<String, Object>) jwt.getObject("payload");
|
||||
|
||||
jwt.claims = jwtPayload;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("{\"error\":1,\"message\":\"Wrong payload\"}");
|
||||
}
|
||||
}
|
||||
try {
|
||||
Object obj = parser.parse(objectMapper.writeValueAsString(jwt.claims));
|
||||
body = (JSONObject) obj;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("{\"error\":1,\"message\":\"Parsing error\"}");
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.managers.jwt;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
import org.primeframework.jwt.domain.JWT;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
// specify the jwt manager functions
|
||||
public interface JwtManager {
|
||||
boolean tokenEnabled(); // check if the token is enabled
|
||||
boolean tokenUseForRequest(); // check if the token is enabled
|
||||
String createToken(Map<String, Object> payloadClaims); // create document token
|
||||
JWT readToken(String token); // read document token
|
||||
JSONObject parseBody(String payload, String header); // parse the body
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.managers.template;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.enums.DocumentType;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.Template;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Qualifier("sample")
|
||||
public class SampleTemplateManager implements TemplateManager {
|
||||
@Autowired
|
||||
private DocumentManager documentManager;
|
||||
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
|
||||
@Autowired
|
||||
private FileUtility fileUtility;
|
||||
|
||||
// create a template document with the specified name
|
||||
public List<Template> createTemplates(final String fileName) {
|
||||
List<Template> templates = List.of(
|
||||
new Template("", "Blank", documentManager
|
||||
.getCreateUrl(fileName, false)), // create a blank template
|
||||
new Template(getTemplateImageUrl(fileName), "With sample content", documentManager
|
||||
.getCreateUrl(fileName,
|
||||
true)) // create a template with sample content using the template image
|
||||
);
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
// get the template image URL for the specified file
|
||||
public String getTemplateImageUrl(final String fileName) {
|
||||
DocumentType fileType = fileUtility.getDocumentType(fileName); // get the file type
|
||||
String path = storagePathBuilder.getServerUrl(true); // get server URL
|
||||
if (fileType.equals(DocumentType.word)) { // get URL to the template image for the word document type
|
||||
return path + "/css/img/file_docx.svg";
|
||||
} else if (fileType.equals(DocumentType.slide)) { // get URL to the template image for the slide document type
|
||||
return path + "/css/img/file_pptx.svg";
|
||||
} else if (fileType.equals(DocumentType.cell)) { // get URL to the template image for the cell document type
|
||||
return path + "/css/img/file_xlsx.svg";
|
||||
}
|
||||
return path + "/css/img/file_docx.svg"; // get URL to the template image for the default document type (word)
|
||||
}
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.configurations;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
@Getter
|
||||
@Setter
|
||||
/* The parameters which allow to customize the editor interface so that it looked like your
|
||||
other products (if there are any) and change the presence or absence of the additional buttons,
|
||||
links, change logos and editor owner details. */
|
||||
public class Customization {
|
||||
@Autowired
|
||||
private Goback goback; // the settings for the Open file location menu button and upper right corner button
|
||||
private Boolean autosave = true; // if the Autosave menu option is enabled or disabled
|
||||
private Boolean comments = true; // if the Comments menu button is displayed or hidden
|
||||
private Boolean compactHeader = false; /* if the additional action buttons are displayed
|
||||
in the upper part of the editor window header next to the logo (false) or in the toolbar (true) */
|
||||
private Boolean compactToolbar = false; // if the top toolbar type displayed is full (false) or compact (true)
|
||||
private Boolean compatibleFeatures = false; // the use of functionality only compatible with the OOXML format
|
||||
private Boolean forcesave = false; /* add the request for the forced file saving to the callback handler
|
||||
when saving the document within the document editing service */
|
||||
private Boolean help = true; // if the Help menu button is displayed or hidden
|
||||
private Boolean hideRightMenu = false; // if the right menu is displayed or hidden on first loading
|
||||
private Boolean hideRulers = false; // if the editor rulers are displayed or hidden
|
||||
private Boolean submitForm = true; // if the Submit form button is displayed or hidden
|
||||
private Boolean about = true;
|
||||
private Boolean feedback = true;
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.configurations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.enums.ToolbarDocked;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
@Getter
|
||||
@Setter
|
||||
/* The parameters which allow to change the settings
|
||||
which define the behavior of the buttons in the embedded mode */
|
||||
public class Embedded {
|
||||
private String embedUrl; /* the absolute URL to the document serving as a source file for the document embedded
|
||||
into the web page */
|
||||
private String saveUrl; /* the absolute URL that will allow the document to be saved
|
||||
onto the user personal computer */
|
||||
private String shareUrl; // the absolute URL that will allow other users to share this document
|
||||
private ToolbarDocked toolbarDocked; // the place for the embedded viewer toolbar, can be either top or bottom
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.configurations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
public class Goback { // the settings for the Open file location menu button and upper right corner button
|
||||
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
|
||||
@Value("${url.index}")
|
||||
private String indexMapping;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String url; /* the absolute URL to the website address which will be opened
|
||||
when clicking the Open file location menu button */
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String text;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Boolean blank;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
this.url = storagePathBuilder.getServerUrl(false) + indexMapping;
|
||||
}
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.configurations;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
@Getter
|
||||
@Setter
|
||||
/* The additional parameters for the document (document owner, folder where the document is stored,
|
||||
uploading date, sharing settings) */
|
||||
public class Info {
|
||||
private String owner = "Me"; // the name of the document owner/creator
|
||||
private Boolean favorite = null; // the highlighting state of the Favorite icon
|
||||
private String uploaded = getDate(); // the document uploading date
|
||||
|
||||
private String getDate() {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE MMM dd yyyy", Locale.US);
|
||||
return simpleDateFormat.format(new Date());
|
||||
}
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.enums;
|
||||
|
||||
public enum ConvertErrorType {
|
||||
EMPTY_ERROR(0, ""),
|
||||
CONVERTATION_UNKNOWN(-1, "Error convertation unknown"),
|
||||
CONVERTATION_TIMEOUT(-2, "Error convertation timeout"),
|
||||
CONVERTATION_ERROR(-3, "Error convertation error"),
|
||||
DOWNLOAD_ERROR(-4, "Error download error"),
|
||||
UNEXPECTED_GUID_ERROR(-5, "Error unexpected guid"),
|
||||
DATABASE_ERROR(-6, "Error database"),
|
||||
DOCUMENT_REQUEST_ERROR(-7, "Error document request"),
|
||||
DOCUMENT_VKEY_ERROR(-8, "Error document VKey"),
|
||||
DOCUMENT_CONVERSION_OUTPUT_ERROR(-9, "Error conversion output format");
|
||||
|
||||
private final int code;
|
||||
private final String label;
|
||||
|
||||
ConvertErrorType(final int codeParam, final String labelParam) {
|
||||
this.code = codeParam;
|
||||
this.label = labelParam;
|
||||
}
|
||||
|
||||
public static String labelOfCode(final int code) {
|
||||
for (ConvertErrorType convertErrorType : values()) {
|
||||
if (convertErrorType.code == code) {
|
||||
return convertErrorType.label;
|
||||
}
|
||||
}
|
||||
return "ErrorCode = " + code;
|
||||
}
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.onlyoffice.integration.documentserver.serializers.SerializerFilter;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CommentGroup {
|
||||
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SerializerFilter.class)
|
||||
private List<String> view; // define a list of groups whose comments the user can view
|
||||
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SerializerFilter.class)
|
||||
private List<String> edit; // define a list of groups whose comments the user can edit
|
||||
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SerializerFilter.class)
|
||||
private List<String> remove; // define a list of groups whose comments the user can remove
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Info;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
@Getter
|
||||
@Setter
|
||||
public class Document { // the parameters pertaining to the document (title, url, file type, etc.)
|
||||
@Autowired
|
||||
private Info info; /* additional parameters for the document (document owner, folder where the document is stored,
|
||||
uploading date, sharing settings) */
|
||||
@Autowired
|
||||
private Permission permissions; // the permission for the document to be edited and downloaded or not
|
||||
private String fileType; // the file type for the source viewed or edited document
|
||||
private String key; // the unique document identifier used by the service to recognize the document
|
||||
private String urlUser; /* the absolute URL that will allow the document to be saved
|
||||
onto the user personal computer */
|
||||
private String title; /* the desired file name for the viewed or edited document which will also be used
|
||||
as file name when the document is downloaded */
|
||||
private String url; // the absolute URL where the source viewed or edited document is stored
|
||||
private String directUrl;
|
||||
private HashMap<String, Object> referenceData;
|
||||
}
|
||||
@ -1,59 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Customization;
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Embedded;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Mode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class EditorConfig { /* the parameters pertaining to the editor interface: opening mode (viewer or editor),
|
||||
interface language, additional buttons, etc. */
|
||||
private HashMap<String, Object> actionLink = null; /* the data which contains the information about the
|
||||
action in the document that will be scrolled to */
|
||||
private String callbackUrl; // the absolute URL to the document storage service
|
||||
private HashMap<String, Object> coEditing = null;
|
||||
private String createUrl; // the absolute URL of the document where it will be created and available after creation
|
||||
@Autowired
|
||||
private Customization customization; /* the parameters which allow to customize the editor interface
|
||||
so that it looked like your other products (if there are any) and change the presence or absence
|
||||
of the additional buttons, links, change logos and editor owner details */
|
||||
@Autowired
|
||||
private Embedded embedded; /* the parameters which allow to change the settings which define
|
||||
the behavior of the buttons in the embedded mode */
|
||||
private String lang; // the editor interface language
|
||||
private Mode mode; // the editor opening mode
|
||||
@Autowired
|
||||
private User user; // the user currently viewing or editing the document
|
||||
private List<Template> templates; /* the presence or absence
|
||||
of the templates in the <b>Create New...</b> menu option */
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.enums.DocumentType;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Type;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
@Getter
|
||||
@Setter
|
||||
/* the file base parameters which include the platform type used,
|
||||
document display size (width and height) and type of the document opened */
|
||||
public class FileModel {
|
||||
@Autowired
|
||||
private Document document; // the parameters pertaining to the document (title, url, file type, etc.)
|
||||
private DocumentType documentType; // the document type to be opened
|
||||
@Autowired
|
||||
private EditorConfig editorConfig; /* the parameters pertaining to the
|
||||
editor interface: opening mode (viewer or editor), interface language, additional buttons, etc. */
|
||||
private String token; // the encrypted signature added to the Document Server config
|
||||
private Type type; // the platform type used to access the document
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.onlyoffice.integration.documentserver.models.AbstractModel;
|
||||
import com.onlyoffice.integration.documentserver.serializers.SerializerFilter;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
@Getter
|
||||
@Setter
|
||||
public class Permission extends AbstractModel { // the permission for the document to be edited and downloaded or not
|
||||
private Boolean comment = true; // if the document can be commented or not
|
||||
private Boolean copy = true; // if the content can be copied to the clipboard or not
|
||||
private Boolean download = true; // if the document can be downloaded or only viewed or edited online
|
||||
private Boolean edit = true; // if the document can be edited or only viewed
|
||||
private Boolean print = true; // if the document can be printed or not
|
||||
private Boolean fillForms = true; // if the forms can be filled
|
||||
private Boolean modifyFilter = true; /* if the filter can applied globally (true) affecting all the
|
||||
other users, or locally (false) */
|
||||
private Boolean modifyContentControl = true; // if the content control settings can be changed
|
||||
private Boolean review = true; // if the document can be reviewed or not
|
||||
private Boolean chat = true; // if a chat can be used
|
||||
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SerializerFilter.class)
|
||||
private List<String> reviewGroups; // the groups whose changes the user can accept/reject
|
||||
@Autowired
|
||||
private CommentGroup commentGroups; // the groups whose comments the user can edit, remove and/or view
|
||||
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SerializerFilter.class)
|
||||
private List<String> userInfoGroups;
|
||||
private Boolean protect = true;
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class ReferenceData {
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
private final String instanceId;
|
||||
private final Map<String, String> fileKey;
|
||||
public ReferenceData(final String fileName, final String curUserHostAddress, final User user) {
|
||||
instanceId = storagePathBuilder.getServerUrl(true);
|
||||
Map<String, String> fileKeyList = new HashMap<>();
|
||||
if (!user.getId().equals("uid-0")) {
|
||||
fileKeyList.put("fileName", fileName);
|
||||
fileKeyList.put("userAddress", curUserHostAddress);
|
||||
} else {
|
||||
fileKeyList = null;
|
||||
}
|
||||
fileKey = fileKeyList;
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
public class Template { // the document template parameters
|
||||
private String image; // the absolute URL to the image for template
|
||||
private String title; // the template title that will be displayed in the <b>Create New...</b> menu option
|
||||
private String url; // the absolute URL to the document where it will be created and available after creation
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2024
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.AbstractModel;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
@Getter
|
||||
@Setter
|
||||
public class User extends AbstractModel {
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
private String id;
|
||||
private String name;
|
||||
private String group;
|
||||
private String image;
|
||||
|
||||
// the user configuration parameters
|
||||
public void configure(final int idParam, final String nameParam, final String groupParam) {
|
||||
this.id = "uid-" + idParam; // the user id
|
||||
this.name = nameParam; // the user name
|
||||
this.group = groupParam; // the group the user belongs to
|
||||
this.image = storagePathBuilder.getServerUrl(true) + "/css/img/uid-" + this.id + ".png";
|
||||
}
|
||||
}
|
||||