Compare commits

...

631 Commits

Author SHA1 Message Date
dbaa7c5113 Merge pull request #310 from ONLYOFFICE/bugfix/file-request-status
Bugfix/file request status
2022-11-21 13:25:47 +03:00
d6ad145111 nodejs: init type argument (fix ab03bb5490) 2022-11-18 13:51:11 +03:00
44fb3a089c php: added request timeout for download 2022-11-11 14:58:36 +03:00
513bf99adb csharp-mvc: added request timeout for download 2022-11-11 12:23:39 +03:00
6f92633ef8 csharp: added request timeout for download 2022-11-11 12:23:28 +03:00
b67e768dce python: added request status check for file 2022-11-10 19:07:17 +03:00
751a886bfa ruby: added request status check for file 2022-11-10 19:06:29 +03:00
66ea4b144b java: added request status check for file 2022-11-10 19:05:32 +03:00
7a73422231 java-spring: added request status check for file 2022-11-10 19:04:49 +03:00
93accdac7c nodejs: do not send key in referenceData 2022-11-08 16:33:19 +03:00
def268f5f2 Merge remote-tracking branch 'remotes/origin/release/1.4.0' into develop 2022-11-08 10:42:00 +03:00
6054bffb3f Merge pull request #305 from ONLYOFFICE/dependabot/maven/web/documentserver-example/java-spring/com.fasterxml.jackson.core-jackson-databind-2.13.4.1
build(deps): bump jackson-databind from 2.12.6.1 to 2.13.4.1 in /web/documentserver-example/java-spring
2022-11-08 10:31:57 +03:00
a7c917db3f Merge remote-tracking branch 'remotes/origin/release/1.4.0' into develop 2022-11-08 09:18:02 +03:00
30481005a1 removed enum Language (Fix Bug 59624) 2022-11-08 09:17:30 +03:00
5544768500 set language from cookies (Fix Bug 59352) 2022-11-08 09:17:22 +03:00
14e53970c8 update pyjwt=2.6.0 (Fix Bug 59369) 2022-11-08 09:16:37 +03:00
82efd0f18a fix 848cfb20bc 2022-11-07 14:23:01 +03:00
8ce90d89ed removed enum Language (Fix Bug 59624) 2022-11-07 13:07:34 +03:00
2b184972dc Merge pull request #306 from ONLYOFFICE/dependabot/bundler/web/documentserver-example/ruby/nokogiri-1.13.9
build(deps): bump nokogiri from 1.13.8 to 1.13.9 in /web/documentserver-example/ruby
2022-11-03 14:46:55 +03:00
0fb9da4d89 update pom.xml 2022-11-03 14:11:05 +03:00
9277d3de58 Merge branch 'feature/optionDirectUrl' into develop 2022-11-03 13:34:47 +03:00
baf7a1e5dd fix changelog about directUrl task 2022-11-03 13:34:15 +03:00
e2a14a74db Merge pull request #308 from ONLYOFFICE/feature/optionDirectUrl
Feature/option direct url
2022-11-03 13:33:20 +03:00
848cfb20bc set language from cookies (Fix Bug 59352) 2022-11-03 12:05:53 +03:00
ddd3ec82a8 update pyjwt=2.6.0 (Fix Bug 59369) 2022-11-03 10:47:39 +03:00
0ed08fd7b2 Change CHANGELOG.md 2022-11-02 14:58:12 +03:00
e1c5907003 csharp: option to send directUrl 2022-11-02 14:54:33 +03:00
9dd2d7c0db csharp-mvc: fix label for aspx 2022-11-02 14:49:40 +03:00
8f0cbb78af Change CHANGELOG.md 2022-11-02 13:10:39 +03:00
72e48914aa Merge branch 'feature/optionDirectUrl' of https://github.com/ONLYOFFICE/document-server-integration into feature/optionDirectUrl 2022-11-02 13:05:45 +03:00
82a282029a csharp-mvc: option to send directUrl 2022-11-02 13:05:08 +03:00
9b7c12b5c0 Change CHANGELOG.md 2022-11-01 23:10:46 +03:00
6ea5546099 python: option to send directUrl 2022-11-01 23:09:36 +03:00
92fbd1e293 Change CHANGELOG.md 2022-10-28 16:48:05 +03:00
855c1ed9f9 php: option to send directUrl 2022-10-28 16:47:08 +03:00
7e60ec15fd Change CHANGELOG.md 2022-10-28 13:56:28 +03:00
3697a4a888 ruby: option to send directUrl 2022-10-28 13:55:48 +03:00
0b8107d167 Change CHANGELOG.md 2022-10-28 13:52:11 +03:00
885850ee33 java: option to send directUrl 2022-10-27 14:32:21 +03:00
98c61250a6 Change CHANGELOG.md 2022-10-26 16:54:16 +03:00
457487844c java-spring: fix option to send directUrl 2022-10-26 16:47:43 +03:00
ff72956b68 java-spring: option to send directUrl 2022-10-26 16:41:59 +03:00
1593df6aec build(deps): bump nokogiri in /web/documentserver-example/ruby
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.13.8 to 1.13.9.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.13.8...v1.13.9)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-26 10:46:51 +00:00
cda8a86c2a Merge remote-tracking branch 'remotes/origin/release/1.4.0' into develop 2022-10-26 13:40:30 +03:00
16584c0abb Merge remote-tracking branch 'remotes/origin/hotfix/1.3.1' into release/1.4.0
# Conflicts:
#	CHANGELOG.md
#	web/documentserver-example/csharp/settings.config
#	web/documentserver-example/ruby/config/application.rb
2022-10-26 13:39:29 +03:00
1ddda89001 Merge pull request #307 from ONLYOFFICE/hotfix/1.3.1
Hotfix/1.3.1
2022-10-26 13:37:19 +03:00
5b76d798fb 1.3.1 2022-10-26 13:28:18 +03:00
e96200df85 java-spring: tooltip fix 2022-10-26 11:53:50 +03:00
de75b11e18 java-spring: option to send directUrl 2022-10-26 11:48:11 +03:00
f27afe1535 java-spring: option to send directUrl 2022-10-25 19:44:39 +03:00
59e17079ff build(deps): bump jackson-databind
Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.12.6.1 to 2.13.4.1.
- [Release notes](https://github.com/FasterXML/jackson/releases)
- [Commits](https://github.com/FasterXML/jackson/commits)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-19 07:08:15 +00:00
1bdb3c03bc Merge remote-tracking branch 'remotes/origin/feature/referenceData' into develop 2022-10-14 10:22:24 +03:00
111dc14f2b nodejs: referenceData 2022-10-14 10:20:45 +03:00
4a656c025f 1.4.0 2022-10-14 10:12:48 +03:00
ce9930e5bc java-spring: fixed footer positioning 2022-10-12 11:12:59 +03:00
9da22d7803 java-spring: fixed sorting of the list of languages 2022-10-12 11:00:01 +03:00
d78c677c99 java: fixed sorting of the list of languages 2022-10-12 10:59:41 +03:00
b204142c13 csharp: include assets 2022-10-11 18:04:21 +03:00
fd1c26ab9f csharp-mvc: reload refs 2022-10-11 17:53:14 +03:00
5993d10bee csharp-mvc: fix ref 2022-10-11 17:23:16 +03:00
c5771c9008 sharp-mvc: Fix merge 24aee6d194 2022-10-11 17:22:49 +03:00
2fad227272 Merge remote-tracking branch 'remotes/origin/release/v7.2.0' into develop 2022-10-05 13:33:43 +03:00
ada438ff0b Merge remote-tracking branch 'remotes/origin/develop' into release/v7.2.0 2022-09-28 09:13:23 +03:00
0dbd65a577 ruby: rails 7.0.3.1 2022-09-27 19:03:26 +03:00
48e5b8d4e0 Merge pull request #304 from ONLYOFFICE/dependabot/nuget/web/documentserver-example/csharp/Newtonsoft.Json-13.0.1
build(deps): bump Newtonsoft.Json from 10.0.3 to 13.0.1 in /web/documentserver-example/csharp
2022-09-27 18:26:31 +03:00
7f08a96681 Merge remote-tracking branch 'remotes/origin/develop' into dependabot/nuget/web/documentserver-example/csharp/Newtonsoft.Json-13.0.1
# Conflicts:
#	web/documentserver-example/csharp/packages.config
2022-09-27 18:26:07 +03:00
3549b4bc2a csharp: Newtonsoft.Json update 2022-09-27 18:24:53 +03:00
c9265d9ddc csharp-mvc: fix dep path 2022-09-27 18:08:47 +03:00
44d9ca88c6 build(deps): bump Newtonsoft.Json in /web/documentserver-example/csharp
Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 10.0.3 to 13.0.1.
- [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
- [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/10.0.3...13.0.1)

---
updated-dependencies:
- dependency-name: Newtonsoft.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-27 14:59:15 +00:00
d964b43087 Merge pull request #303 from ONLYOFFICE/develop
Release/v1.3.0
2022-09-27 17:58:46 +03:00
5a0debd9e8 Merge remote-tracking branch 'remotes/origin/develop' into release/v7.2.0 2022-09-27 17:55:26 +03:00
3b0f942eee Merge pull request #302 from ONLYOFFICE/feature/ruby-3.0.0
support ruby v.3
2022-09-27 17:54:59 +03:00
4ee110c2d5 Merge remote-tracking branch 'remotes/origin/develop' into release/v7.2.0
# Conflicts:
#	web/documentserver-example/nodejs/views/config.ejs
#	web/documentserver-example/ruby/app/models/document_helper.rb
2022-09-15 17:17:24 +03:00
ad1d93dd20 Merge pull request #301 from ONLYOFFICE/bugfix/file-request
added request status check for file
2022-09-15 14:43:19 +03:00
d2d98df5ab support ruby v.3 2022-09-01 16:56:38 +03:00
7805f7dc91 added request status check for file 2022-09-01 09:34:30 +03:00
51ec27d67c nodejs: removed trailing comma 2022-08-25 15:47:10 +03:00
9e94716df0 nodejs: reorder config items 2022-08-16 10:15:39 +03:00
988a8339b1 ruby: ERB::Util.url instead URI::encode 2022-08-15 11:10:02 +03:00
a482635e3f Merge branch 'feature/directUrl' into release/v7.2.0 2022-08-03 12:20:57 +03:00
d2c679f6b1 nodejs: option to send directUrl 2022-08-03 12:20:39 +03:00
1da452d857 Merge branch 'feature/directUrl' into release/v7.2.0 2022-08-03 12:20:18 +03:00
d9b8d2b7e9 directUrl to changelog 2022-08-03 12:14:16 +03:00
24aee6d194 Merge branch 'release/v7.2.0' into feature/directUrl
# Conflicts:
#	web/documentserver-example/csharp-mvc/Helpers/DocManagerHelper.cs
#	web/documentserver-example/csharp/DocEditor.aspx.cs
2022-08-03 12:13:12 +03:00
bd108a9c77 fix changelog 2022-08-03 12:11:01 +03:00
e737e8ed48 Merge remote-tracking branch 'remotes/origin/develop' into release/v7.2.0 2022-08-03 12:10:20 +03:00
b425d15f0a Merge branch 'feature/tooltip' into develop 2022-08-03 12:09:47 +03:00
0f8dec1e6e nodejs: revert tooltip for language (e1753a154d) 2022-08-03 12:08:10 +03:00
193b31fe75 nodejs: id to info block 2022-08-03 11:59:58 +03:00
583403cf78 update empty files (Fix Bug 58202) 2022-08-02 16:50:01 +03:00
641e45e24f 1.3.0 2022-08-02 15:35:18 +03:00
53c30fbb7d Merge branch 'develop' into release/v7.2.0
# Conflicts:
#	CHANGELOG.md
#	web/documentserver-example/csharp-mvc/Helpers/Users.cs
#	web/documentserver-example/csharp/Users.cs
#	web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/ExampleData.java
#	web/documentserver-example/java/src/main/java/helpers/Users.java
#	web/documentserver-example/nodejs/app.js
#	web/documentserver-example/nodejs/helpers/users.js
#	web/documentserver-example/php/users.php
#	web/documentserver-example/python/src/utils/users.py
#	web/documentserver-example/ruby/app/models/users.rb
2022-08-02 15:04:09 +03:00
87a1755729 Merge pull request #300 from ONLYOFFICE/feature/ruby-bundle-update
ruby: bundle update
2022-08-02 14:32:40 +03:00
752a2a2364 Merge pull request #298 from ONLYOFFICE/fix/notification-incorrect-file-size
Fix/notification incorrect file size
2022-08-02 14:32:40 +03:00
d1affa2911 Merge pull request #297 from ONLYOFFICE/feature/refactoring-jwt-manager
Feature/refactoring jwt manager
# Conflicts:
#	CHANGELOG.md
2022-08-02 14:32:31 +03:00
0ef2a4f3fd Merge pull request #292 from ONLYOFFICE/Build(deps)/bot-recommendations
changes - ruby - raise gem version
2022-08-02 14:25:18 +03:00
675d3f318a Merge pull request #294 from ONLYOFFICE/dependabot/nuget/web/documentserver-example/csharp-mvc/Newtonsoft.Json-13.0.1
build(deps): bump Newtonsoft.Json from 12.0.3 to 13.0.1 in /web/documentserver-example/csharp-mvc
2022-08-02 14:25:18 +03:00
05512ffa23 Merge pull request #288 from ONLYOFFICE/feature/localhost-for-client
Localhost for client urls
2022-08-02 14:25:17 +03:00
2eeed5d26d Fix #287 Fix #285 Fix #284 Fix #280
Build(deps)/bot recommendations
2022-08-02 14:24:11 +03:00
9e3dbd5eb5 Merge pull request #290 from ONLYOFFICE/fix/php-convert-manager
fix - php - add substrings to string
2022-08-02 14:21:09 +03:00
efbab7c113 nodejs: fix embed link for client request 2022-08-02 14:20:48 +03:00
b8f0f6447c nodejs: remove getlocalFileUri 2022-08-02 14:20:48 +03:00
8779a90433 nodejs: fix history url for server request 2022-08-02 14:20:48 +03:00
b3162ee410 Merge pull request #278 from ONLYOFFICE/dependabot/maven/web/documentserver-example/java-spring/com.fasterxml.jackson.core-jackson-databind-2.12.6.1
build(deps): bump jackson-databind from 2.12.2 to 2.12.6.1 in /web/documentserver-example/java-spring
2022-08-02 14:18:23 +03:00
42edd5e208 Merge pull request #276 from ONLYOFFICE/dependabot/bundler/web/documentserver-example/ruby/nokogiri-1.13.4
build(deps): bump nokogiri from 1.12.5 to 1.13.4 in /web/documentserver-example/ruby
2022-08-02 14:18:23 +03:00
e041baeef7 Merge branch 'feature/extension-on-rename' into develop 2022-08-02 14:18:22 +03:00
5bf682a007 nodejs: package lock 2022-08-02 14:18:22 +03:00
6dacf49faa ruby: fix (23e616aade) 2022-08-02 14:18:22 +03:00
63c9c4242e Merge pull request #291 from ONLYOFFICE/feature/chat
Feature/chat
# Conflicts:
#	CHANGELOG.md
2022-08-02 14:18:21 +03:00
b5e345ed50 Merge branch 'feature/chat' into develop 2022-08-02 14:18:21 +03:00
33f8436d42 changelog 2022-08-02 14:18:20 +03:00
c5217242ab Merge pull request #300 from ONLYOFFICE/feature/ruby-bundle-update
ruby: bundle update
2022-08-01 14:34:39 +03:00
c910d5193b Merge remote-tracking branch 'remotes/origin/dependabot/bundler/web/documentserver-example/ruby/rails-html-sanitizer-1.4.3' into feature/ruby-bundle-update
# Conflicts:
#	web/documentserver-example/ruby/Gemfile.lock
2022-08-01 14:34:05 +03:00
58c27f8f2f ruby: bundle update 2022-08-01 12:56:57 +03:00
1ec831789b Merge pull request #298 from ONLYOFFICE/fix/notification-incorrect-file-size
Fix/notification incorrect file size
2022-07-29 17:37:36 +03:00
0510fd1354 [fix] - node.js - don't send file size limit to incoming form
Revert "nodejs: upload big file"
This reverts commit fa4c3e3258.
2022-07-29 17:31:22 +03:00
25238b5614 Merge pull request #293 from ONLYOFFICE/feature/liveview
Feature/liveview
2022-07-29 17:23:48 +03:00
901bb61883 Merge remote-tracking branch 'remotes/origin/develop' into feature/liveview
# Conflicts:
#	CHANGELOG.md
2022-07-29 17:21:54 +03:00
7f3e6c6364 Merge pull request #291 from ONLYOFFICE/feature/chat
Feature/chat
2022-07-29 17:18:24 +03:00
b3512ea0ce Merge remote-tracking branch 'remotes/origin/develop' into feature/chat
# Conflicts:
#	CHANGELOG.md
2022-07-29 17:16:54 +03:00
642a1bd19a Merge pull request #297 from ONLYOFFICE/feature/refactoring-jwt-manager
Feature/refactoring jwt manager
2022-07-29 17:13:08 +03:00
ac471588de jwt to changelog 2022-07-29 17:12:20 +03:00
17674ef5bc ruby: licenses 2022-07-29 17:12:12 +03:00
dc2ee2a997 php: jwt 2022-07-29 17:12:02 +03:00
c358fa814a csharp-mvc: jwt 2022-07-29 17:11:05 +03:00
143a73e083 csharp: jwt 2022-07-29 17:10:37 +03:00
c266592434 Merge pull request #292 from ONLYOFFICE/Build(deps)/bot-recommendations
changes - ruby - raise gem version
2022-07-29 11:55:36 +03:00
19ed666d56 Merge pull request #294 from ONLYOFFICE/dependabot/nuget/web/documentserver-example/csharp-mvc/Newtonsoft.Json-13.0.1
build(deps): bump Newtonsoft.Json from 12.0.3 to 13.0.1 in /web/documentserver-example/csharp-mvc
2022-07-29 11:53:18 +03:00
84b9202af0 Merge pull request #288 from ONLYOFFICE/feature/localhost-for-client
Localhost for client urls
2022-07-29 11:51:09 +03:00
8fb698bb75 Basque (Spain), Armenian and Malay (Malaysia) lang 2022-07-29 11:38:25 +03:00
00f46ef080 build(deps): bump rails-html-sanitizer
Bumps [rails-html-sanitizer](https://github.com/rails/rails-html-sanitizer) from 1.4.2 to 1.4.3.
- [Release notes](https://github.com/rails/rails-html-sanitizer/releases)
- [Changelog](https://github.com/rails/rails-html-sanitizer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rails/rails-html-sanitizer/compare/v1.4.2...v1.4.3)

---
updated-dependencies:
- dependency-name: rails-html-sanitizer
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-06 12:11:57 +00:00
5c194da95d [add] - java - directUrl 2022-07-04 19:46:34 +03:00
0d5cebe28e [add] - java spring - directUrl 2022-07-04 19:45:37 +03:00
dacf72cae2 [add] - csharp mvc - directUrl 2022-07-01 19:29:52 +03:00
208b8926be [add] - csharp - directUrl 2022-07-01 19:28:55 +03:00
55c4853f04 [add] - php - directUrl 2022-07-01 17:30:18 +03:00
ccae7c6a06 [add] - python - directUrl 2022-06-30 20:29:04 +03:00
dc84dd3b29 [add] - ruby - fix 2022-06-30 19:53:44 +03:00
65d3671b09 [add] - ruby - directUrl 2022-06-30 19:15:15 +03:00
1fb5ef8bfd build(deps): bump Newtonsoft.Json
Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 12.0.3 to 13.0.1.
- [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
- [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/12.0.3...13.0.1)

---
updated-dependencies:
- dependency-name: Newtonsoft.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-23 00:47:07 +00:00
b630c3802b fix - ruby - coEditing from permissions to editorConfig 2022-06-16 16:56:18 +03:00
ad3993b532 fix - ruby - coEditing from permissions to editorConfig 2022-06-16 16:52:51 +03:00
35ee61e011 fix - python - checking mode view insert edit 2022-06-16 16:48:01 +03:00
ee59ab3dfd fix - python - coEditing from permissions to editorConfig 2022-06-16 16:43:48 +03:00
500f076e38 fix - csharp - coEditing from permissions to editorConfig 2022-06-16 16:36:51 +03:00
e578f29d9d fix - csharp mvc - coEditing from permissions to editorConfig 2022-06-16 16:35:57 +03:00
9de9bc90a4 fix - java - checking mode view insert edit 2022-06-16 16:32:36 +03:00
7a9ebdbbe5 fix - java - coEditing from permissions to editorConfig 2022-06-16 16:26:03 +03:00
887089bcad add - java spring - anonymous without liveview 2022-06-16 16:11:29 +03:00
680e53823a add - java - anonymous without liveview 2022-06-15 21:08:18 +03:00
33e1489cd6 add - charp mvc - anonymous without liveview 2022-06-15 20:41:32 +03:00
8c90737bf6 add - charp - anonymous without liveview 2022-06-15 20:38:16 +03:00
e5f1bc8ed6 add - php - anonymous without liveview 2022-06-15 20:23:52 +03:00
985b179475 add - python - anonymous without liveview 2022-06-15 20:03:07 +03:00
775d15132f add - ruby - json transform 2022-06-15 19:39:00 +03:00
4a4298ca10 add - ruby - anonymous without liveview 2022-06-15 19:30:36 +03:00
cdbd264ed5 Merge branch 'feature/chat' into feature/liveview
# Conflicts:
#	CHANGELOG.md
2022-06-15 19:21:30 +03:00
e61f6cae89 changes - ruby - raise gem version 2022-06-15 19:10:58 +03:00
22039078ef Merge remote-tracking branch 'remotes/origin/develop' into feature/chat 2022-06-15 18:38:12 +03:00
62793a42ab add - java spring - anonymous without permissions.chat 2022-06-15 18:09:14 +03:00
f49f96a2c2 add - java - anonymous without permissions.chat 2022-06-14 20:16:06 +03:00
2031d65adb add - csharp mvc - anonymous without permissions.chat 2022-06-14 19:53:12 +03:00
7f54659d3b add - csharp - anonymous without permissions.chat 2022-06-14 19:50:44 +03:00
a3bc13bb6e add - php - anonymous without permissions.chat 2022-06-14 19:45:46 +03:00
29ea16c124 add - python - anonymous without permissions.chat 2022-06-14 19:37:42 +03:00
6d4c8b926e add - ruby - anonymous without permissions.chat 2022-06-14 19:25:53 +03:00
22d2031426 fix - csharp - replace with regex 2022-06-14 18:10:18 +03:00
fcc51e8154 fix - csharp-mvc - check if '/' exist + replace with regex 2022-06-14 18:08:46 +03:00
8cd85ad63c Fix #287 Fix #285 Fix #284 Fix #280
Build(deps)/bot recommendations
2022-06-14 17:20:47 +03:00
1d51688884 Merge pull request #290 from ONLYOFFICE/fix/php-convert-manager
fix - php - add substrings to string
2022-06-14 17:05:02 +03:00
2c63a85b00 fix - php - add substrings to string 2022-06-14 16:55:12 +03:00
d1545c4db4 csharp-mvc-fix folder display for localhost 2022-06-10 18:37:17 +03:00
bd8e4d6ec7 csharp-fix goback 2022-06-10 18:31:22 +03:00
e1c815b574 Fix folder display for localhost 2022-06-10 18:29:44 +03:00
4042d2bb8a Merge remote-tracking branch 'remotes/origin/dependabot/maven/web/documentserver-example/java-spring/com.google.code.gson-gson-2.8.9' into build(deps)/bot-recommendations 2022-06-10 16:14:14 +03:00
8c9d2d80bd Merge remote-tracking branch 'remotes/origin/dependabot/maven/web/documentserver-example/java/com.google.code.gson-gson-2.8.9' into build(deps)/bot-recommendations 2022-06-10 16:13:53 +03:00
3a9259d713 Merge remote-tracking branch 'remotes/origin/dependabot/bundler/web/documentserver-example/ruby/rack-2.2.3.1' into build(deps)/bot-recommendations
# Conflicts:
#	web/documentserver-example/ruby/Gemfile.lock
2022-06-10 16:13:02 +03:00
39129a537e Merge remote-tracking branch 'remotes/origin/dependabot/bundler/web/documentserver-example/ruby/nokogiri-1.13.6' into build(deps)/bot-recommendations
# Conflicts:
#	web/documentserver-example/ruby/Gemfile.lock
2022-06-10 16:07:32 +03:00
dfaf552bf8 ruby-fix - use client URL in goBack 2022-06-09 19:30:43 +03:00
cc8b6f3716 nodejs: directUrl 2022-06-09 13:23:43 +03:00
13726b3c2f nodejs: fix embed link for client request 2022-06-09 13:18:06 +03:00
8bcc15e320 nodejs: remove getlocalFileUri 2022-06-09 13:07:02 +03:00
8fca045dd7 nodejs: fix history url for server request 2022-06-09 12:15:04 +03:00
a018cc5787 Merge remote-tracking branch 'remotes/origin/master' into develop 2022-06-03 11:09:35 +03:00
054236ef8a build(deps): bump rack in /web/documentserver-example/ruby
Bumps [rack](https://github.com/rack/rack) from 2.2.3 to 2.2.3.1.
- [Release notes](https://github.com/rack/rack/releases)
- [Changelog](https://github.com/rack/rack/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rack/rack/compare/2.2.3...2.2.3.1)

---
updated-dependencies:
- dependency-name: rack
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-27 16:45:08 +00:00
05a3110c99 Remove workflow and disable build nodejs docker (#286)
* Remove workflow and disable build

* Remove Dockerfile
2022-05-27 15:34:59 +03:00
e662c765e6 build(deps): bump gson in /web/documentserver-example/java-spring
Bumps [gson](https://github.com/google/gson) from 2.8.5 to 2.8.9.
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.9)

---
updated-dependencies:
- dependency-name: com.google.code.gson:gson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-20 22:07:08 +00:00
058bb0d2e2 build(deps): bump gson in /web/documentserver-example/java
Bumps [gson](https://github.com/google/gson) from 2.8.5 to 2.8.9.
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.9)

---
updated-dependencies:
- dependency-name: com.google.code.gson:gson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-20 20:58:39 +00:00
8bafa3ff3a Add submodule-init (#283) 2022-05-19 17:02:51 +03:00
56679a3b75 Change target repo (#282)
* Change target repo

* Add latest tag
2022-05-19 15:59:11 +03:00
d4d758770f Add docs-example multiarch build (#281)
* Add multiarch build

* Cosmetic changes

* Cosmetic changes
2022-05-19 14:17:28 +03:00
ac78d1fc08 build(deps): bump nokogiri in /web/documentserver-example/ruby
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.13.3 to 1.13.6.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.13.3...v1.13.6)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-19 03:44:52 +00:00
874ebff886 Fix the launch of the example container (#279)
* Fix the launch of the example container

* Change the user home directory

* Change the command for create a user
2022-05-16 17:26:24 +03:00
070dac6878 Merge remote-tracking branch 'remotes/origin/master' into develop 2022-05-12 13:22:41 +03:00
4f2f877f0e docxf update 2022-05-12 13:22:15 +03:00
cfa0fb1b74 Merge pull request #278 from ONLYOFFICE/dependabot/maven/web/documentserver-example/java-spring/com.fasterxml.jackson.core-jackson-databind-2.12.6.1
build(deps): bump jackson-databind from 2.12.2 to 2.12.6.1 in /web/documentserver-example/java-spring
2022-04-25 16:57:39 +03:00
1d624e6831 Merge pull request #276 from ONLYOFFICE/dependabot/bundler/web/documentserver-example/ruby/nokogiri-1.13.4
build(deps): bump nokogiri from 1.12.5 to 1.13.4 in /web/documentserver-example/ruby
2022-04-25 16:56:55 +03:00
fe83e98b37 Merge branch 'feature/extension-on-rename' into develop 2022-04-25 14:27:32 +03:00
f9ea7f7b50 nodejs: package lock 2022-04-25 14:27:28 +03:00
328ea46693 format 2022-04-25 14:20:41 +03:00
41ec2742a7 csharp-mvc: with ext 2022-04-25 14:06:27 +03:00
76fc55c2d4 csharp: with ext 2022-04-25 14:04:01 +03:00
e10f3962b6 java: with ext 2022-04-25 13:28:35 +03:00
b9859ef5ca java-spring: with ext 2022-04-25 12:53:28 +03:00
1cb2b586b1 ruby: with ext 2022-04-25 11:45:21 +03:00
e5d31eebbf nodejs: fix 2022-04-25 11:43:52 +03:00
1ac40c539f python: with ext 2022-04-25 11:13:09 +03:00
371366befa nodejs: with ext 2022-04-25 10:41:59 +03:00
0bee4817e7 php: with ext 2022-04-25 09:38:12 +03:00
ad941e0ba4 ruby: fix (23e616aade) 2022-04-20 10:19:34 +03:00
93c69e51ed changelog: offline viewer for anonymous 2022-04-18 15:37:45 +03:00
8b8b7d3938 Merge branch 'feature/liveview' into develop 2022-04-18 15:35:36 +03:00
f8f01a033e nodejs: anonymous without liveview 2022-04-18 15:34:18 +03:00
f497f10913 changelog: anonymous without chat 2022-04-18 15:26:44 +03:00
8b2478ac71 Merge branch 'feature/chat' into develop 2022-04-18 15:25:42 +03:00
391c347419 nodejs: anonymous without permissions.chat 2022-04-18 15:25:04 +03:00
5a08009b7b changelog: zh-TW, pt-PT 2022-04-18 15:24:31 +03:00
4e5b65f673 changelog 2022-04-18 15:23:43 +03:00
13e3d7673b Merge pull request #275 from ONLYOFFICE/feature/new-langs-7.2
added langs
2022-04-18 15:20:53 +03:00
c0a46866ce build(deps): bump nokogiri in /web/documentserver-example/ruby
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.12.5 to 1.13.4.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/v1.13.4/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.12.5...v1.13.4)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-18 11:18:07 +00:00
e7b76729a4 build(deps): bump jackson-databind
Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.12.2 to 2.12.6.1.
- [Release notes](https://github.com/FasterXML/jackson/releases)
- [Commits](https://github.com/FasterXML/jackson/commits)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-18 11:17:36 +00:00
5cc6b4cb15 Merge pull request #277 from ONLYOFFICE/develop
Release/1.2.0
2022-04-18 14:16:23 +03:00
7a70a44bcb 1.2.0 2022-04-18 13:59:07 +03:00
ce2e7f97d6 added langs 2022-04-11 15:28:55 +03:00
e42bd53664 Merge pull request #274 from ONLYOFFICE/feature/languages-fix
languages sort fix
2022-04-11 10:42:55 +03:00
23e616aade languages sort fix 2022-04-11 10:38:26 +03:00
f035da0db4 nodejs: disable X-Powered-By 2022-04-05 15:16:45 +03:00
3e12ec4ebe Merge pull request #272 from ONLYOFFICE/feature/ignore-self-signed-certificate
Feature/ignore self signed certificate
2022-03-30 14:34:02 +03:00
589ca9b601 Merge branch 'develop' into feature/ignore-self-signed-certificate 2022-03-28 16:00:59 +03:00
32f1ec82d1 Merge pull request #271 from ONLYOFFICE/feature/uid-0-fix
Feature/uid 0 fix
2022-03-28 13:26:38 +03:00
54bb5b0a24 format 2022-03-28 13:26:17 +03:00
8274c16f6d Merge pull request #273 from ONLYOFFICE/feature/update-readme
Update README.md
2022-03-28 13:09:24 +03:00
7a982fc785 format 2022-03-28 13:09:13 +03:00
6f5800fbde Updated Readme files in examples 2022-03-28 12:05:45 +03:00
8ec632eebd csharp-mvc: function created 2022-03-28 10:12:46 +03:00
b6ca4535ce csharp: function created 2022-03-28 09:58:59 +03:00
089fc8bfa0 ruby: function created 2022-03-28 09:31:01 +03:00
0b4c17ea0a Update README.md 2022-03-25 17:57:11 +03:00
405be2847b java-spring: ignoring self-signed certificate was added 2022-03-25 16:54:04 +03:00
f809c7e525 python: certificate ignore was added 2022-03-25 13:26:00 +03:00
44061c82a9 csharp-mvc: ignore certificate in config 2022-03-24 11:24:46 +03:00
ef4e283804 csharp: ignore certificate in config 2022-03-24 10:26:31 +03:00
4b0ad1a192 csharp + csharp-mvc 2022-03-23 16:56:41 +03:00
60469b0dba java: ignore certificate in config 2022-03-23 15:39:11 +03:00
f5ac95e1cc nodejs: ignore certificate in config 2022-03-23 15:11:30 +03:00
c4c2fbb945 ruby: certificate was ignored 2022-03-23 14:25:53 +03:00
99b5fcd562 python 2022-03-23 13:29:24 +03:00
7e34067410 java 2022-03-23 12:38:38 +03:00
a44787c625 java-spring 2022-03-23 11:11:03 +03:00
105afb2c34 php 2022-03-23 10:57:33 +03:00
002f9b958e nodejs 2022-03-23 10:53:51 +03:00
56d5913808 ruby 2022-03-23 10:48:28 +03:00
6664864bed nodejs 2022-03-22 13:52:28 +03:00
6c9e6e9304 Merge pull request #268 from ONLYOFFICE/feature/language-update
Feature/language update
2022-03-22 12:21:43 +03:00
416b1fde8c Merge pull request #270 from ONLYOFFICE/feature/hide-history-for-anonymous
Feature/hide history for anonymous
2022-03-22 11:54:12 +03:00
383f240825 Merge pull request #269 from ONLYOFFICE/feature/ban-renaming-for-anonymous
Feature/ban renaming for anonymous
2022-03-22 11:48:57 +03:00
642e145142 php: certificate was ignored 2022-03-22 11:15:09 +03:00
8f09dadfa0 ruby: java-spring: bugfix 2022-03-21 17:10:11 +03:00
495f1cf49a nodejs: split filename 2022-03-21 11:18:30 +03:00
cf01b5e0ae csharp: csharp-mvc: version history button was hidden 2022-03-21 09:38:48 +03:00
0673fed928 java: java-spring: version history button was hidden 2022-03-21 09:35:58 +03:00
9b0b30a0b0 nodejs: version history button was hidden 2022-03-21 09:32:27 +03:00
200187edce python: version history button was hidden 2022-03-21 09:29:32 +03:00
23176ddf07 ruby: version history button was hidden 2022-03-21 09:27:26 +03:00
9857cef8fc php: version history button was hidden 2022-03-21 09:22:31 +03:00
204f770401 java-spring: bugfix 2022-03-18 15:58:02 +03:00
61834e3ec6 Merge branch 'feature/language-update' of github.com:ONLYOFFICE/document-server-integration into feature/language-update 2022-03-18 15:24:45 +03:00
2ca6185ac4 php: bugfix 2022-03-18 15:24:30 +03:00
e818bb978b csharp: removed rename action for anonymous 2022-03-18 15:08:20 +03:00
3a4cf5e6e6 csharp-mvc: removed rename action for anonymous 2022-03-18 15:06:46 +03:00
7ec16b90e3 java: removed rename action for anonymous 2022-03-18 15:04:28 +03:00
fcfb6efda7 java-spring: removed rename action for anonymous 2022-03-18 15:02:45 +03:00
e4c72c98d1 nodejs: removed rename action for anonymous 2022-03-18 14:59:27 +03:00
c2bbda542a python: removed rename action for anonymous 2022-03-18 14:56:17 +03:00
2c12393c78 ruby: removed rename action for anonymous 2022-03-18 14:52:59 +03:00
4e93f6ebac php: fix 2022-03-18 14:47:59 +03:00
d10ba9f773 Merge branch 'develop' into feature/ban-renaming-for-anonymous 2022-03-18 14:40:38 +03:00
a0bf7db118 php: removed rename action 2022-03-18 14:36:46 +03:00
e40e7cc41c csharp-mvc: move languages to config 2022-03-18 11:25:54 +03:00
f616655f4c csharp: move languages to config 2022-03-18 11:14:49 +03:00
4ba708631e Merge pull request #266 from ONLYOFFICE/feature/renaming-files
Feature/renaming files
2022-03-18 10:31:19 +03:00
b9c1bc0f42 java-spring: changing arguments 2022-03-18 09:50:59 +03:00
215ade01a3 java: changing arguments 2022-03-18 09:32:34 +03:00
4d25418fc8 java: move languages to config 2022-03-17 14:05:56 +03:00
4539bac5db Merge pull request #267 from ONLYOFFICE/feature/customization
Feature/customization
2022-03-17 11:10:14 +03:00
eb196613e7 format 2022-03-17 10:36:38 +03:00
7ac788f589 csharp: jwt in body 2022-03-17 10:27:47 +03:00
55119458af java-spring: move languages to config 2022-03-17 10:14:02 +03:00
3c18add1fc Merge remote-tracking branch 'remotes/origin/release/v7.1.0' into develop 2022-03-17 09:56:20 +03:00
6bf63b7166 nodejs: move languages to config 2022-03-16 16:30:56 +03:00
32df2d3e34 php: move languages to config 2022-03-16 15:41:45 +03:00
97c7859db5 ruby: move languages to config 2022-03-16 15:32:47 +03:00
492f9c7baa python: config 2022-03-16 14:58:16 +03:00
e0c0595796 removed chat 2022-03-16 13:06:37 +03:00
40b8fb88a8 Merge branch 'feature/renaming-files' of github.com:ONLYOFFICE/document-server-integration into feature/renaming-files 2022-03-16 11:36:17 +03:00
b0df0d72df java-spring: refactoring 2022-03-16 10:48:43 +03:00
1053add1d9 csharp-mvc: refactoring 2022-03-16 09:47:49 +03:00
f1fc0e5fae csharp: refactoring 2022-03-16 09:38:30 +03:00
a192c6ce1f ruby: refactoring 2022-03-15 18:45:35 +03:00
e8aec0b68c java: php: python: refactoring 2022-03-15 18:10:02 +03:00
d9667f9757 nodejs: fix 2022-03-15 15:17:19 +03:00
3a985da120 Merge branch 'feature/renaming-files' of github.com:ONLYOFFICE/document-server-integration into feature/renaming-files 2022-03-15 14:19:34 +03:00
a88f84ddac nodejs: use commandRequest 2022-03-15 14:19:16 +03:00
6525d7210f micro fix 2022-03-15 13:33:33 +03:00
6b93311ce5 customization change 2022-03-15 13:10:34 +03:00
999561ffd6 Merge branch 'feature/renaming-files' of github.com:ONLYOFFICE/document-server-integration into feature/renaming-files 2022-03-15 10:51:43 +03:00
e539c1205f python: nodejs: jwt fix 2022-03-15 10:51:26 +03:00
9a52a538cb csharp-mvc: jwt fix 2022-03-15 08:24:11 +03:00
e8038a8e88 csharp: jwt fix 2022-03-15 08:18:34 +03:00
1045b314b6 Merge pull request #265 from ONLYOFFICE/bugfix/wopi
fix wopi
2022-03-14 17:50:35 +03:00
1636732521 nodejs: fix userHost in wopi 2022-03-14 17:48:32 +03:00
daa9a5f3fa fix wopi 2022-03-14 15:49:24 +03:00
9bf3973215 csharp-mvc: meta command 2022-03-14 14:00:05 +03:00
cad2a20cdf csharp: meta command 2022-03-14 13:41:12 +03:00
82a5a68e6c java: meta command 2022-03-11 14:59:10 +03:00
0e1a580a86 refactoring 2022-03-11 14:13:09 +03:00
c09f3fc4b9 Merge branch 'feature/renaming-files' of github.com:ONLYOFFICE/document-server-integration into feature/renaming-files 2022-03-11 11:02:39 +03:00
d4d7c4e222 java-spring: meta command 2022-03-11 10:58:54 +03:00
14429c5b05 php: rename refactoring 2022-03-11 09:45:42 +03:00
131e33c6af Merge pull request #264 from ONLYOFFICE/feature/fix-mentions
Feature/fix mentions
2022-03-10 16:19:50 +03:00
8a04e5fbc4 ruby:meta command 2022-03-09 13:50:47 +03:00
1b6435a7dc python:meta command 2022-03-08 10:50:05 +03:00
b8eecab45f nodejs:meta command 2022-03-07 22:01:03 +03:00
a55cb60542 nodejs: file download url was incorrectly formed when converting file 69d2e14438 2022-03-05 16:03:13 +03:00
f7259409a2 php:jwt 2022-03-04 14:34:50 +03:00
0ea9e68c7c meta command 2022-03-04 11:15:43 +03:00
4b72e0a664 php: add request rename in doceditor + add function renamefile() in webeditor 2022-03-03 14:34:57 +03:00
f4ae62e02d nodejs: missing line for 69d2e14438 2022-03-03 11:25:38 +03:00
935377a941 all: fix link in mentions 2022-03-02 17:42:12 +03:00
3690aacb66 nodejs: fix link in mentions 2022-03-02 17:10:41 +03:00
b8b375a19a Merge pull request #263 from ONLYOFFICE/feature/scroll
fixed scrolling due to footer : ab82be9b3d
2022-03-02 16:40:13 +03:00
69d2e14438 nodejs: fixed an issue when subfolders wouldn't create if storagefolder was set to an absolute path 2022-03-02 16:27:58 +03:00
fec77a9e75 fixed scrolling due to footer : ab82be9b3d 2022-03-02 14:30:57 +03:00
f0171cbb18 Merge pull request #262 from ONLYOFFICE/feature/anonymus-without-id
new branch + anonymus without id
2022-03-02 13:55:20 +03:00
fe49aeb815 Merge pull request #260 from ONLYOFFICE/feature/mobile-upload
Feature/mobile upload
2022-03-02 13:54:16 +03:00
8416f36581 mobile-upload:centering 2022-03-02 13:48:01 +03:00
b9f3bfd2e2 new branch + anonymus without id 2022-03-02 11:16:24 +03:00
02b22e9e26 Merge remote-tracking branch 'remotes/origin/develop' into feature/mobile-upload 2022-03-01 16:01:30 +03:00
f43f08012d Merge pull request #261 from ONLYOFFICE/budfix/php-device-display
Budfix/php device display
2022-03-01 15:58:40 +03:00
1c27610e8d Ruby - fix body display 2022-03-01 15:47:24 +03:00
148caf6225 Python - fix body display 2022-03-01 15:47:11 +03:00
b24e4503bc Java Spring - fix body display 2022-03-01 15:46:53 +03:00
58378827d4 Java - fix body display 2022-03-01 15:46:34 +03:00
502f14c7be C# mvc - fix body display 2022-03-01 15:46:15 +03:00
ded2d19672 C# - fix body display 2022-03-01 15:45:55 +03:00
6116f05625 Java - Add viewport device display on index page 2022-03-01 15:45:18 +03:00
1e2a9cf4f2 Java Spring - Add viewport device display on index page 2022-03-01 15:44:56 +03:00
1d7775f25b C# - Add viewport device display on index page 2022-03-01 15:44:00 +03:00
05c7a5a6db fix body display 2022-03-01 13:51:31 +03:00
c3500e39fd Add viewport device display on index page 2022-03-01 13:50:44 +03:00
23169c6fea block height fix:upload for mobile 2022-03-01 10:45:29 +03:00
f2fddc75c6 nodejs:fix 2022-02-28 18:29:54 +03:00
f542e9dcfc csharp:upload for mobile 2022-02-28 18:27:42 +03:00
6737a7e0d0 csharp-mvc:upload for mobile 2022-02-28 18:22:31 +03:00
e9c17c55da java:upload for mobile 2022-02-28 18:20:14 +03:00
f334bf4b19 java-spring:upload for mobile 2022-02-28 18:17:52 +03:00
f2139949de nodejs:upload for mobile 2022-02-28 18:14:23 +03:00
48314b2c7f ruby:upload for mobile 2022-02-28 18:09:20 +03:00
8804844281 python:upload for mobile 2022-02-28 17:59:15 +03:00
3a21d29568 php: fix centering 2022-02-28 17:17:30 +03:00
b6a08e242d Add licenses of mimemagic on ruby (7a61fac6b7)
# Conflicts:
#	web/documentserver-example/ruby/licenses/mimemagic.license
2022-02-28 16:59:02 +03:00
596235d34b php:upload for mobile 2022-02-28 16:40:55 +03:00
254fbaccea Merge pull request #259 from ONLYOFFICE/dependabot/bundler/web/documentserver-example/ruby/nokogiri-1.13.3
build(deps): bump nokogiri from 1.12.5 to 1.13.3 in /web/documentserver-example/ruby
2022-02-28 12:03:45 +03:00
69c07a30a7 Merge remote-tracking branch 'remotes/origin/develop' into dependabot/bundler/web/documentserver-example/ruby/nokogiri-1.13.3
# Conflicts:
#	web/documentserver-example/ruby/Gemfile.lock
2022-02-28 12:02:41 +03:00
6283ff934d build(deps): bump nokogiri in /web/documentserver-example/ruby
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.12.5 to 1.13.3.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.12.5...v1.13.3)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-26 03:34:12 +00:00
db231faca0 nodejs: pdf without comment and fillform permissions 2022-02-22 14:31:14 +03:00
a3dd0394d2 nodejs: remove unused code 2022-02-22 11:46:40 +03:00
f9fd73fc7e nodejs: remove unused (aadac3cca6) 2022-02-22 11:32:06 +03:00
0931936b3c nodejs: remove unused (5c1d925d42) 2022-02-22 11:29:34 +03:00
b91b49c8fa nodejs: fix (b0a0050201) 2022-02-22 11:24:19 +03:00
b0a0050201 Merge pull request #258 from ONLYOFFICE/bugfix/non-static-docmanager
Bugfix Non static Docmanager
2022-02-22 11:06:10 +03:00
1c780a639f nodejs: don't clean tmp folder while others uploads might be happening 2022-02-16 11:55:01 +03:00
ad6ac4dedd nodejs: non static docmanager 2022-02-16 11:54:22 +03:00
8ba33f524b Merge pull request #240 from ONLYOFFICE/feature/jwtHistoryFiles
Feature/jwt history files
2022-02-15 16:32:21 +03:00
2f5b25d6ab Merge remote-tracking branch 'remotes/origin/develop' into feature/jwtHistoryFiles
# Conflicts:
#	web/documentserver-example/ruby/Gemfile.lock
2022-02-15 16:31:57 +03:00
44eef53a03 python: fixed history path building 2022-02-14 12:41:37 +03:00
08388f739c python: fixed cors issue when downloading history files 2022-02-14 12:41:14 +03:00
1d8175b88f Merge pull request #256 from ONLYOFFICE/feature/ruby-deps-version
ruby: update dependencies version
2022-02-11 13:01:44 +03:00
1400ec5a4b nodejs: fix opening history 2022-02-11 12:54:59 +03:00
e5f61ec95e php format 2022-02-11 12:34:46 +03:00
7c669cca19 mvc: fix opening history 2022-02-11 12:20:05 +03:00
81f8bd1a9b fix help 2022-02-11 11:31:00 +03:00
c4c819c513 format 2022-02-11 10:54:03 +03:00
03332b3cd9 csharp: revert coediting 2022-02-11 10:36:48 +03:00
ebc864736d Merge remote-tracking branch 'remotes/origin/develop' into feature/jwtHistoryFiles
# Conflicts:
#	web/documentserver-example/java/README.md
2022-02-11 10:22:04 +03:00
af86ec1ca3 update submodule 2022-02-11 10:19:44 +03:00
d1d9915953 Merge pull request #257 from ONLYOFFICE/feature/userInfoGroups
Feature/user info groups
2022-02-11 10:15:35 +03:00
c663bfe464 Merge remote-tracking branch 'remotes/origin/develop' into feature/userInfoGroups
# Conflicts:
#	web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/ExampleData.java
#	web/documentserver-example/java/src/main/java/helpers/Users.java
#	web/documentserver-example/php/users.php
#	web/documentserver-example/python/src/utils/users.py
#	web/documentserver-example/ruby/app/models/users.rb
2022-02-11 10:14:06 +03:00
1bb7dd152a Merge pull request #231 from ONLYOFFICE/feature/page-icons-layout
nodejs: change position of icons for mobile editor and filling forms
2022-02-11 10:10:37 +03:00
a52000fc97 java-spring: userInfoGroups 2022-02-11 01:22:15 +03:00
88b7fbf55c csharp: userInfoGroups 2022-02-11 00:43:01 +03:00
f9449f7742 csharp-mvc: userInfoGroups 2022-02-11 00:38:55 +03:00
9d2b8c4830 php: userInfoGroups 2022-02-11 00:28:22 +03:00
4068e23556 ruby: userInfoGroups 2022-02-11 00:20:29 +03:00
fc760af338 python: userInfoGroups 2022-02-11 00:00:58 +03:00
c55ab7cc75 java: userInfoGroups 2022-02-10 23:56:09 +03:00
00c9b3e2b9 nodejs: userInfoGroups to help 2022-02-10 15:01:21 +03:00
47074c588d nodejs: userInfoGroups 2022-02-10 14:25:51 +03:00
018d1bbead ruby: update dependencies version 2022-02-09 11:43:22 +03:00
82713572ab Merge pull request #255 from ONLYOFFICE/feature/update-readme
Update README.md
2022-02-09 10:59:07 +03:00
34d06235f4 format 2022-02-09 10:58:53 +03:00
468488c384 note to index page 2022-02-09 10:55:02 +03:00
ff4b387acf Update README.md 2022-02-09 10:50:20 +03:00
20012c7678 change note in readme 2022-02-09 10:17:36 +03:00
382160f2fc Merge remote-tracking branch 'remotes/origin/release/v7.1.0' into develop
# Conflicts:
#	web/documentserver-example/csharp-mvc/assets
#	web/documentserver-example/csharp/assets
#	web/documentserver-example/java-spring/src/main/resources/assets
#	web/documentserver-example/java/src/main/resources/assets
#	web/documentserver-example/nodejs/public/assets
#	web/documentserver-example/php/assets
#	web/documentserver-example/python/assets
#	web/documentserver-example/ruby/public/assets
2022-02-09 10:05:10 +03:00
761e578faf update submodule 2022-02-07 16:14:53 +03:00
7b7cbebc75 Merge pull request #254 from ONLYOFFICE/feature/changing-wopi-edit-view-icons
Node.js(wopi): Change wopi icons for editing and viewing actions
2022-02-07 15:53:47 +03:00
dbc5ebf098 Node.js(wopi): Change wopi icons for editing and viewing actions 2022-02-07 15:52:53 +03:00
c5d61b685b Merge pull request #253 from ONLYOFFICE/bugfix/xss
fix xss vulnerability
2022-02-06 16:32:39 +03:00
f3acca4b4b python: fix xss vulnerability 2022-02-06 16:31:16 +03:00
b92c4191f9 xss in lang 2022-02-06 16:25:52 +03:00
5b6f2696d2 xss in type 2022-02-06 16:16:51 +03:00
625df85b51 xss in actionLink 2022-02-06 15:52:58 +03:00
6716d38a40 support xlsb 2022-02-06 11:15:20 +03:00
84d574906d Python: remove unnecessary import 2022-02-03 17:32:26 +03:00
3c760c3136 Python: update pyjwt, fix jwtManager (remove decode) 2022-02-03 17:29:47 +03:00
bf28236d0d Python: fix urls (accidental deletion of a path saveus) 2022-02-01 17:13:27 +03:00
6d71a553be С#: add absolute path support for document history 2022-02-01 17:03:16 +03:00
fed5598294 С#: remove unnecessary construction 2022-02-01 16:00:50 +03:00
02351113e1 С# mvc: remove unnecessary functions and constructions 2022-02-01 15:55:36 +03:00
a07edeb5de Python: linux support (bug with json jwt decoding) 2022-02-01 15:19:15 +03:00
5bbc4c6232 Ruby: remove unnecessary action (version encoding) 2022-01-31 16:28:34 +03:00
770c2fe551 PHP: fix code 2022-01-31 15:03:41 +03:00
4916537977 Java-spring: fix the code 2022-01-31 15:01:39 +03:00
77ec1649a5 Java: fix the code and remove the encoding of the url version 2022-01-31 15:00:27 +03:00
204ff947c3 Python: fix code 2022-01-31 14:02:06 +03:00
d36fe2466a C#: add time for unique key 2022-01-27 11:53:10 +03:00
e927da28f5 C# mvc: add time for unique key 2022-01-27 11:52:49 +03:00
17b5c6e4c9 C#: Add history creation for the first version of the file 2022-01-27 11:50:30 +03:00
03f853dfef C# mvc: Add history creation for the first version of the file 2022-01-27 11:49:21 +03:00
1d7e65b2ba Python: fix bug with absolute storage path 2022-01-26 15:02:31 +03:00
8ebb67c925 Python: fix merge diff + prev 2022-01-26 14:59:40 +03:00
8524ff27ed Merge remote-tracking branch 'remotes/origin/develop' into feature/jwtHistoryFiles 2022-01-26 13:45:33 +03:00
7bedc4b877 Merge pull request #250 from ONLYOFFICE/feature/add-wopi-users
Node.js (wopi): Add selected user to editor
2022-01-24 13:14:40 +03:00
f25c211630 Merge pull request #251 from ONLYOFFICE/feature/filetype
Feature/filetype
2022-01-24 12:12:12 +03:00
0f4785d14f python: correct code (Support old versions) 2022-01-24 11:07:28 +03:00
288add4d45 python: correct code (Support old versions) 2022-01-24 10:56:57 +03:00
1ee492838c python: correct filetype arg 2022-01-21 16:35:33 +03:00
f9ce3d1d33 nodejs: correct filetype arg 2022-01-21 15:51:16 +03:00
5f6687571a Node.js (wopi): changing the receipt of a wopi query 2022-01-20 17:11:59 +03:00
a1e5a4d48e Node.js (wopi): Add selected user to editor 2022-01-19 19:05:21 +03:00
6e9518631f Merge pull request #246 from ONLYOFFICE/feature/add-upload-wopi
Feature/add upload wopi
2022-01-19 18:07:31 +03:00
88d8086853 Node.js (wopi): Add support InternetExplorer 2022-01-19 17:59:31 +03:00
d22f4f11ca Java-Spring: jwt prev + diff 2022-01-19 17:20:48 +03:00
29cbe66d09 Merge remote-tracking branch 'remotes/origin/develop' into feature/jwtHistoryFiles 2022-01-18 18:16:53 +03:00
c2410268eb Java: Merge jwt prev + diff 2022-01-18 17:41:59 +03:00
57cd71095d С# mvc: Merge jwt prev + diff 2022-01-18 17:00:56 +03:00
224d2bc570 С#: Merge jwt prev + diff 2022-01-18 16:25:13 +03:00
c7f18f1085 Node.js (wopi): Fix filter 2022-01-18 15:39:16 +03:00
fb05ad32ab Merge remote-tracking branch 'remotes/origin/develop' into feature/add-upload-wopi 2022-01-18 14:49:28 +03:00
bac989efd1 Node.js (wopi): Filter extensions from config that are in discovery for edit action (+ Checking the Fano condition) 2022-01-17 18:36:47 +03:00
8a203ac062 Node.js (wopi): button layout for upload 2022-01-17 18:33:49 +03:00
7e1386008b Merge pull request #249 from ONLYOFFICE/feature/wopi-layout
Feature/wopi layout
2022-01-17 15:15:10 +03:00
8ff206a411 Node.js wopi: add information when hovering over the info icon 2022-01-17 14:06:59 +03:00
83a0330725 Merge pull request #245 from ONLYOFFICE/feature/wopi-editing
Feature/wopi editing
2022-01-17 11:23:27 +03:00
c5269a53cf Merge pull request #244 from ONLYOFFICE/bugfix/customization-fix-JavaExample
fix Customization in Java and JavaSpringExample
2022-01-17 11:12:32 +03:00
f86b26928d Node.js(wopi): create a unique version code 2022-01-14 19:29:46 +03:00
f8d77947c8 Node.js(wopi): layout of the index page (delete extra info users and checkbox simple) 2022-01-14 19:28:09 +03:00
a62ac23aeb PHP: Merge jwt prev + diff (There is a bug with the history display) 2022-01-14 18:02:28 +03:00
a900183056 Merge pull request #241 from ONLYOFFICE/feature/fileTypeInsteadParsing
Feature/file type instead parsing
2022-01-14 16:52:30 +03:00
67d34f4bfa format 2022-01-14 16:52:12 +03:00
507a7f3162 Ruby: Merge jwt prev + diff 2022-01-13 18:08:40 +03:00
703281aa07 Node.js: Fix code. The direct link has been replaced with a stream output 2022-01-13 16:00:19 +03:00
aefec3e105 Python: Merge jwt prev + diff 2022-01-12 18:14:48 +03:00
8cc211b011 Node.js: Merge jwt prew + diff 2022-01-12 17:49:52 +03:00
68ec626970 C# mvc: fix code 2022-01-11 18:19:14 +03:00
065f338a79 C#: fix code 2022-01-11 18:18:54 +03:00
43548c04b9 Node.js: fix code (Made links through ready-made functions) 2022-01-11 17:52:40 +03:00
c7c95ecfbe Node.js: fix upload page (links [edit, view] ) for wopi upload files 2022-01-11 17:34:34 +03:00
064c0dcc35 C#: fix code 2022-01-11 16:42:26 +03:00
9a01f465d0 C# mvc: fix code 2022-01-11 16:42:01 +03:00
2d85a4166e Ruby: fix code 2022-01-11 15:07:19 +03:00
77c598049c I added universal content type in JavaSpringExample 2022-01-11 13:09:17 +03:00
c1baac3d6f content type Python Example FIX Commit 2022-01-11 12:58:32 +03:00
c5e30b6512 fix Application header in Node JS example 2022-01-11 12:55:19 +03:00
0fa6f43716 FixCommit content-type for Ruby 2022-01-11 12:48:28 +03:00
edc43bdf31 fix commit С# and C# MVC content type 2022-01-11 12:42:03 +03:00
f75453bf2d I fixed JWT for diff.zip Node JS Example 2022-01-11 12:35:26 +03:00
d03326a1e1 I fixed check JWT for Diff.zip in C# MVC Example 2022-01-11 11:39:43 +03:00
8be501a0ab Fix Commit for Diff.zip JWT in C# 2022-01-11 11:26:59 +03:00
a4c71eb69a JWT for diff.zip fix commit 2022-01-11 10:58:13 +03:00
132545c655 I added jwt check before giving diff in Python Example FIX Commit 2022-01-11 10:43:40 +03:00
5caaf0b1c6 Merge branch 'develop' into feature/jwtHistoryFiles 2022-01-10 19:00:27 +03:00
8f18cc8ab2 Merge branch 'feature/fileTypeInsteadParsing' of github.com:ONLYOFFICE/document-server-integration into feature/fileTypeInsteadParsing
# Conflicts:
#	web/documentserver-example/csharp-mvc/Helpers/TrackManager.cs
2022-01-10 18:49:43 +03:00
db976766cc Ruby: fix[support old version] fileType instead parsing 2022-01-10 18:47:02 +03:00
57f6028829 Python: fix[support old version] fileType instead parsing 2022-01-10 18:46:03 +03:00
05706ff038 PHP: fix[support old version] fileType instead parsing 2022-01-10 18:45:27 +03:00
9cf7ce276e Node.js: fix[support old version] fileType instead parsing 2022-01-10 18:45:03 +03:00
0b35179ef0 Java-spring: fix[support old version] fileType instead parsing 2022-01-10 18:44:35 +03:00
d396f92f4d Java : fix[support old version] fileType instead parsing 2022-01-10 18:44:01 +03:00
1e78da4cfc C#: fix[support old version] fileType instead parsing 2022-01-10 18:42:41 +03:00
a8c9c331c1 C# mvc: fix[support old version] fileType instead parsing 2022-01-10 18:41:54 +03:00
0b2e09cf1d Ruby JWT FIX for diff.zip 2022-01-10 17:40:05 +03:00
f81ae23a64 Merge branch 'feature/jwtHistoryFiles' of github.com:ONLYOFFICE/document-server-integration into feature/jwtHistoryFiles
# Conflicts:
#	web/documentserver-example/csharp-mvc/Models/FileModel.cs
#	web/documentserver-example/csharp/DocEditor.aspx.cs
#	web/documentserver-example/ruby/licenses/3rd-Party.license
2022-01-10 17:08:45 +03:00
6f90ff3391 Check JWT in JavaSpringExample 2022-01-10 16:37:54 +03:00
4f3882f892 Merge pull request #248 from ONLYOFFICE/feature/ruby-add-mimemagic
Add licenses of mimemagic on ruby
2022-01-10 16:08:31 +03:00
727418277f ruby: correct license 2022-01-10 16:08:14 +03:00
2f795de6ad Merge pull request #247 from ONLYOFFICE/feature/fileType
Feature/file type
2022-01-10 16:03:35 +03:00
bb28257a2d Merge remote-tracking branch 'remotes/origin/develop' into feature/fileType
# Conflicts:
#	web/documentserver-example/php/doceditor.php
2022-01-10 16:03:18 +03:00
379dba8b7c Merge branch 'feature/jwtForDiffZip' of https://github.com/ONLYOFFICE/document-server-integration into feature/jwtForDiffZip 2022-01-10 16:00:49 +03:00
05ea165f77 format 2022-01-10 16:00:41 +03:00
7a61fac6b7 Add licenses of mimemagic on ruby 2022-01-10 15:57:57 +03:00
31c3e050af I do check diff.zip for javaExample 2022-01-10 15:45:40 +03:00
0c677f3d65 Delete mimemagic on Ruby to do it on a new branch 2022-01-10 15:41:09 +03:00
6efa357c19 Delete mimemagic on Ruby in order to add in a new branch 2022-01-10 15:36:13 +03:00
3b33846f9d fix fileRemove and links on wopi (node.js) 2022-01-10 15:27:16 +03:00
3de8463359 Add ConverExtList and EditedExtList for wopi upload files 2022-01-10 14:18:55 +03:00
e05ead7ce6 Review and change jwt signature on python (via handler) 2022-01-10 13:01:12 +03:00
cdc8647f21 LICENSE for mimemagic on Ruby 2022-01-10 13:01:11 +03:00
c2b333fac7 fix commit 2022-01-10 13:01:11 +03:00
cae75d9888 jwt signature for prev.* files C# mvc (via handler) on Net4.8 2022-01-10 12:59:18 +03:00
ee674e6a57 jwt signature for prev.* files C# (via handler) 2022-01-10 12:57:22 +03:00
7207a9d860 jwt signature for prev.* files java-spring (via handler) 2022-01-10 12:53:41 +03:00
8cc5f685af Add link(handler) to onRequestHistoryData jwt Java 2022-01-10 12:53:41 +03:00
a61a8ccb4f jwt signature for prev.* files. Java (via handler) + README.md (Build point) 2022-01-10 12:53:41 +03:00
e857a2bed7 jwt signature for prev.* files. PHP (via handler) 2022-01-10 12:53:40 +03:00
514303d053 jwt signature for prev.* files. Ruby (by redirection) 2022-01-10 12:53:40 +03:00
7d4f511a5d jwt signature for prev.* files. Python 2022-01-10 12:53:40 +03:00
9b11e8b098 jwt signature for prev.* files node.js 2022-01-10 12:53:39 +03:00
8351905cee Merge remote-tracking branch 'remotes/origin/develop' into feature/jwtForDiffZip 2022-01-10 12:32:09 +03:00
15b7a07963 Merge pull request #242 from ONLYOFFICE/feature/bugRubyEditor
Feature/bug ruby editor
2022-01-10 12:30:47 +03:00
ef1c53d330 ruby: fix bug of displaying the editor 2022-01-10 12:30:28 +03:00
9bcb871132 nodejs: format 2022-01-10 11:22:56 +03:00
25a4b9c97b revert assets after merge d115e4092f 2022-01-10 11:07:46 +03:00
a21fbd6802 java-spring: revert format 2022-01-10 10:58:25 +03:00
c7249ab27f Add upload files for wopi on the node.js 2021-12-30 18:28:55 +03:00
450d37161b Preparing a wopi task for PR 2021-12-30 16:53:30 +03:00
ee46a77684 Removing link to "editnew" in the file line 2021-12-29 19:20:33 +03:00
3b7e3c9258 Аdd action processing ("editnew" and "edit") and Create files only through "editnew" 2021-12-29 19:20:08 +03:00
783ad9f2de fix Customization in Java and JavaSpringExample 2021-12-29 13:30:11 +03:00
78571f6c23 FixCommit 2021-12-28 18:35:52 +03:00
a5c0b9bfb1 FixCommit 2021-12-28 18:31:48 +03:00
5047e64f3b php: revert format 2021-12-28 14:32:35 +03:00
d115e4092f Merge remote-tracking branch 'remotes/origin/develop' into feature/jwtForDiffZip
# Conflicts:
#	web/documentserver-example/csharp-mvc/Models/FileModel.cs
#	web/documentserver-example/csharp/DocEditor.aspx.cs
#	web/documentserver-example/java/src/main/java/entities/FileModel.java
#	web/documentserver-example/nodejs/app.js
#	web/documentserver-example/php/common.php
#	web/documentserver-example/php/doceditor.php
#	web/documentserver-example/php/webeditor-ajax.php
#	web/documentserver-example/ruby/Gemfile
#	web/documentserver-example/ruby/app/models/document_helper.rb
2021-12-28 14:29:37 +03:00
e7a1c2c6eb c# example check JWT for diff.zip 2021-12-28 11:34:45 +03:00
85f95ba4b9 C# MVC I Added header fileName = diff.zip 2021-12-28 11:34:16 +03:00
133013dfde Check JWT for diff.zip C# test-example 2021-12-28 11:11:58 +03:00
6acdc34e10 Start C# Example for diff.zip 2021-12-27 10:29:45 +03:00
19304920d1 fileType instead parsing url to save doc in C# MVC (take fileType out of body) 2021-12-24 18:13:12 +03:00
13b3eed5ed fileType instead parsing url to save doc in C# (take fileType out of body) 2021-12-24 18:12:40 +03:00
d9c1c7e051 fileType instead parsing url to save doc in Java-Spring (take fileType out of body) 2021-12-24 17:54:41 +03:00
2d0b17e334 fileType instead parsing url to save doc in Java (take fileType out of body) 2021-12-24 17:13:28 +03:00
384381cebc fileType instead parsing url to save doc in PHP (take fileType out of body) 2021-12-24 16:52:10 +03:00
16d830baf4 [fix] fileType instead parsing url to save doc in Python (take fileType out of body) 2021-12-24 16:51:48 +03:00
efcfaf95e8 [fix] fileType instead parsing url to save doc in node.js (take fileType out of body) 2021-12-24 16:50:23 +03:00
606f7d2d44 [fix] fileType instead parsing url to save doc in Ruby (take fileType out of body) 2021-12-24 16:47:57 +03:00
357c14b6d4 Check JWT for diff.zip in Ruby Example 2021-12-23 18:43:24 +03:00
c5a2b72b39 fileType instead parsing url to save doc in Ruby (take fileType out of body) 2021-12-23 18:29:31 +03:00
dab9e4bb16 fileType instead parsing url to save doc in Python (take fileType out of body) 2021-12-23 18:24:28 +03:00
27b6cb3293 Review and change jwt signature on python (via handler) 2021-12-23 17:49:26 +03:00
058b0c4f23 fileType in body Instead Parsing url on node.js 2021-12-22 20:21:08 +03:00
05c62bbdf3 LICENSE for mimemagic on Ruby 2021-12-22 19:01:25 +03:00
425bd81f08 fix commit 2021-12-22 18:20:29 +03:00
096102fa59 Merge branch 'develop' into feature/jwtHistoryFiles 2021-12-22 17:13:10 +03:00
c612320a65 JWT for diff.zip php example - good working example 2021-12-22 14:05:19 +03:00
e0b60a6956 JWT for diff.zip php example 2021-12-22 11:06:10 +03:00
16a0846248 jwt signature for prev.* files C# mvc (via handler) on Net4.8 2021-12-21 18:24:02 +03:00
71e1b28f47 jwt signature for prev.* files C# (via handler) 2021-12-21 17:45:42 +03:00
182f5f378e I added jwt for diff.zip 2021-12-21 13:28:05 +03:00
9d3f4b2300 jwt signature for prev.* files java-spring (via handler) 2021-12-20 18:41:38 +03:00
ab3d385c61 I added JWT validation for diff.zip in JavaSpring Example 2021-12-20 14:20:15 +03:00
8d194b78a1 Update samples 2021-12-20 11:29:02 +03:00
b8e726a7be Update pptx sample 2021-12-20 11:02:24 +03:00
dfd2d49e6c Add link(handler) to onRequestHistoryData jwt Java 2021-12-17 15:39:38 +03:00
fbe0c18315 Merge pull request #238 from ONLYOFFICE/feature/update-readme
Readme
2021-12-16 18:10:38 +03:00
ec6ea72069 small fixes for readme files 2021-12-16 17:51:01 +03:00
2accdeac3b jwt signature for prev.* files. Java (via handler) + README.md (Build point) 2021-12-16 17:43:01 +03:00
63f4b6fbb6 I added jwt check before giving diff in Python Example 2021-12-15 17:37:15 +03:00
642caddae8 jwt signature for prev.* files. PHP (via handler) 2021-12-15 16:23:23 +03:00
dac09bd1e1 jwt signature for prev.* files. Ruby (by redirection) 2021-12-14 19:26:56 +03:00
c6e3af5d3b Merge pull request #236 from ONLYOFFICE/feature/csharp-server-configuration
csharp and csharp-mvc readme
2021-12-13 16:59:39 +03:00
183fb80077 jwt signature for prev.* files. Python 2021-12-13 16:53:05 +03:00
63c3337938 Merge pull request #226 from ONLYOFFICE/bugfix/java-fixes
Bugfix/java fixes
2021-12-13 16:34:08 +03:00
0268298f2b Merge remote-tracking branch 'remotes/origin/develop' into bugfix/java-fixes
# Conflicts:
#	web/documentserver-example/java-spring/README.md
2021-12-13 16:32:54 +03:00
32ea01784c Merge pull request #234 from ONLYOFFICE/bugfix/group-fix
replace group value null with empty string
2021-12-13 16:27:14 +03:00
8e4a2c6359 I added jwt check before giving diff 2021-12-13 16:21:15 +03:00
71041fea9f Merge pull request #233 from ONLYOFFICE/feature/pptx-xpath
Feature/pptx xpath
2021-12-13 16:16:54 +03:00
8b25a7a869 ruby: v 3.0 2021-12-13 16:02:48 +03:00
dd20d79236 Merge pull request #230 from ONLYOFFICE/feature/ruby-3.0
ruby 3.0 version
2021-12-13 15:47:25 +03:00
299a68e0bd Merge pull request #229 from ONLYOFFICE/bugfix/layout-fixes
fix layout
2021-12-13 15:42:15 +03:00
9ad27d2cf0 Merge pull request #216 from ONLYOFFICE/feature/change-files-folder
Feature/change files folder
2021-12-13 15:39:26 +03:00
828115e5b0 Merge remote-tracking branch 'remotes/origin/develop' into feature/change-files-folder
# Conflicts:
#	web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/documentserver/storage/LocalFileStorage.java
2021-12-13 15:38:37 +03:00
a194af0d19 jwt signature for prev.* files node.js 2021-12-10 20:29:15 +03:00
c0d240728d edit (fileType in setHistoryData for php) 2021-12-10 17:49:09 +03:00
89c0f03318 csharp: added information about the IIS components 2021-12-09 17:22:39 +03:00
bc1c9f455c fileType in setHistoryData for ruby (+ Gemfile) 2021-12-08 17:25:43 +03:00
df1a5f38c1 fileType in setHistoryData for python 2021-12-08 17:25:01 +03:00
6559c76fbd fileType in setHistoryData for php 2021-12-08 17:24:30 +03:00
a7db14811f fileType in setHistoryData for node.js 2021-12-08 17:23:37 +03:00
abffa3e75f fileType in setHistoryData for java 2021-12-08 17:23:00 +03:00
631f70148f fileType in setHistoryData for java-spring 2021-12-08 17:22:36 +03:00
c7e7c9c19d fileType in setHistoryData for C# 2021-12-08 17:21:54 +03:00
f2d4eb2a42 fileType in setHistoryData for C# mvc 2021-12-08 17:20:19 +03:00
b453aa19f0 replace group value null with empty string 2021-12-02 17:39:48 +03:00
7841822c54 delete unused block 2021-12-02 10:37:05 +03:00
f3e24a8b5e nodejs: delete unused block 2021-12-01 22:31:08 +03:00
d3b962dcb8 fix layout 2021-11-26 15:45:53 +03:00
3cee92d3a3 nodejs: change position of icons for mobile editor and filling forms 2021-11-19 16:15:58 +03:00
95ea50210f Merge remote-tracking branch 'remotes/origin/develop' into feature/change-files-folder
# Conflicts:
#	web/documentserver-example/csharp-mvc/web.appsettings.config
#	web/documentserver-example/java/src/main/java/helpers/DocumentManager.java
2021-11-18 12:54:57 +03:00
40016395a8 java-spring: update README.md, set empty server.address 2021-11-18 12:35:29 +03:00
8f2c2f96d2 java: fix docker 2021-11-17 00:10:28 +03:00
f9dbe89fd9 java-spring: fix docker, clean up application.properties 2021-11-16 18:48:52 +03:00
c3a4c0a66b java: add fields owner and uploaded for document info 2021-11-16 17:52:07 +03:00
edd423cd87 Merge remote-tracking branch 'remotes/origin/develop' into feature/change-files-folder
# Conflicts:
#	web/documentserver-example/csharp-mvc/web.appsettings.config
#	web/documentserver-example/java-spring/src/main/java/com/onlyoffice/integration/documentserver/managers/document/DefaultDocumentManager.java
2021-11-09 19:04:30 +03:00
e026a7027b java-spring: check if storage directory does not exist 2021-11-09 18:31:09 +03:00
11e8f40f8c ruby: fix embedded mode; fix media.css connect 2021-11-02 18:13:45 +03:00
bf18854ec0 csharp-mvc: fix embedded mode 2021-11-02 17:46:41 +03:00
08d1080527 csharp: fix embedded mode 2021-11-02 17:40:00 +03:00
9ca242fe82 python: fix storage path and embedded mode 2021-11-02 16:59:20 +03:00
b3c02a5afd php: fix embedded 2021-11-02 16:13:00 +03:00
ec65ebbfb8 php: layout fix 2021-11-02 16:01:39 +03:00
8544974202 java: layout fix 2021-11-02 16:01:16 +03:00
90eeae5334 php: fix file upload 2021-11-02 15:35:25 +03:00
970cfa6dd0 nodejs: fix embedded 2021-11-02 15:24:44 +03:00
f04a26a0f4 nodejs: fix file upload 2021-11-02 15:11:34 +03:00
53a58e2666 java: fix embedded mode 2021-11-02 14:33:29 +03:00
0ab0762aa5 java: remove urlUser param from config 2021-11-02 11:26:11 +03:00
4aeef2b873 php: fix highlighting of changes in history 2021-10-19 12:40:21 +03:00
60c03c1403 csharp-mvc: fix history 2021-10-19 11:41:28 +03:00
a597c37684 Merge branch 'develop' of https://github.com/ONLYOFFICE/document-server-integration into feature/change-files-folder 2021-10-17 15:38:48 +03:00
5206171a70 php: add ability to use custom path for files storage 2021-10-17 15:38:02 +03:00
375d916fe2 csharp-mvc: add ability to use custom path for files storage 2021-10-15 14:34:35 +03:00
35afb7a8fe csharp: add ability to custom path for files storage 2021-10-15 13:12:58 +03:00
8d1c4d8042 java-spring: add ability to use custom path for files storage 2021-10-14 12:28:36 +03:00
b969944ede python: update readme.md 2021-10-14 12:21:42 +03:00
da7450c732 ruby: add ability to use custom path for files storage 2021-10-14 12:19:45 +03:00
1db5e865a6 Merge remote-tracking branch 'remotes/origin/develop' into feature/change-files-folder 2021-10-14 12:11:38 +03:00
69ac7771d5 nodejs: add ability to use custom path for storage-folder 2021-09-24 17:53:59 +03:00
04f5cac85d java: fix; update README.md, add media.css to index.jsp 2021-09-24 17:51:43 +03:00
ccdd2a4cdc ruby 3.0 version 2021-09-20 12:29:55 +03:00
33140a2ca6 java: added ability to use absolute path for storage-folder in settings.properties, updated README.md 2021-09-13 18:49:38 +03:00
196 changed files with 7652 additions and 2380 deletions

41
CHANGELOG.md Normal file
View File

@ -0,0 +1,41 @@
# Change Log
- nodejs: referenceData
- option to send directUrl
## 1.4.0
- nodejs: option to send directUrl
- opening file on client by directUrl
- offline viewer for anonymous
- added hy, eu, zh-TW, ms, pt-PT
## 1.3.1
- charp: fix references
- ruby: update rails
## 1.3.0
- update empty files
- anonymous without chat
- changed jwt implementation in csharp, csharp-mvc, php, ruby
## 1.2.0
- ruby v3.0
- set filetype in setHistoryData
- read filetype from input request
- creating file on WOPI
- upload on WOPI page
- fix xss
- set userInfoGroups
- check JWT on downloading history
- upload dialog on mobile
- anonymous without id
- renaming from editor
- new skin languages
- ignore certificate
## 1.1.0
- creating docxf
- opening docxf, oform
## 1.0.0
- added java spring

View File

@ -1,10 +1,11 @@
## Integration examples
Test examples are simple document management systems that can be built into your
application for testing (please, do not use it for production without proper code
modifications).
Test examples are simple document management systems that can be built into your application for testing.
Do NOT use these integration examples on your own server without proper code modifications!
In case you enabled any of the test examples, disable it before going for production.
These examples show the way to integrate [ONLYOFFICE Docs][2] into your own website or application using one of the programming languages. The package contains examples written in .Net (C# MVC), .Net (C#), Java, Node.js, PHP and Ruby.
These examples show the way to integrate [ONLYOFFICE Docs][2] into your own website or application using one of the programming languages.
The package contains examples written in .Net (C# MVC), .Net (C#), Java, Node.js, PHP and Ruby.
You should change `http://documentserver` to your server address in these files:
* [.Net (C# MVC)](https://github.com/ONLYOFFICE/document-server-integration/tree/master/web/documentserver-example/csharp-mvc) - `web/documentserver-example/csharp-mvc/web.appsettings.config`
@ -66,6 +67,15 @@ The methods described below are available for all of the test examples.
| **Response** | **Code:** 200 OK <br />**Content on success:**<br /> `[{ "version": <file_version>, "id": <file_id>, "contentLength": <file_size_in_kilobytes>, "pureContentLength": <file_size_in_bytes>, "title": <file_name>, "updated": <last_change_date>}]`<br />**Content on error:**<br /> `"File not found"` |
| **Sample** | `curl -X GET http://localhost/files/{fileId}` |
## Important security info
Please keep in mind the following security aspects when you are using test examples:
* There is no protection of the storage from unauthorized access since there is no need for authorization.
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
## Project Information
Official website: [https://www.onlyoffice.com](https://www.onlyoffice.com/?utm_source=github&utm_medium=cpc&utm_campaign=GitHubIntegrationEx)

View File

@ -24,11 +24,15 @@ jQuery.UI - jQuery UI is an open source library of interface components —
License: MIT
License File: jQuery.UI.license
JWT - JWT (JSON Web Token) Implementation for .NET (Public Domain) (https://github.com/jwt-dotnet/jwt/)
License: MIT
License File: JWT.license
Microsoft.Web.Infrastructure - This package contains the Microsoft.Web.Infrastructure assembly that lets you dynamically register HTTP modules at run time. (https://www.microsoft.com/web/webpi/eula/aspnetmvc3update-eula.htm)
License: MS-EULA License
License File: Microsoft.Web.Infrastructure.license
Newtonsoft.Json - Json.NET is a popular high-performance JSON framework for .NET (https://licenses.nuget.org/MIT)
Newtonsoft.Json - Json.NET is a popular high-performance JSON framework for .NET (https://github.com/JamesNK/Newtonsoft.Json)
License: MIT
License File: Newtonsoft.Json.license

View File

@ -87,10 +87,6 @@
}
@media (max-width: 1008px) {
#portal-info {
width: 65vw;
}
.left-panel {
margin-left: 0;
}
@ -128,6 +124,10 @@
height: 80px;
}
.main {
height: calc(100% - 128px);
}
.main-panel {
left: 0;
padding: 48px 18px 24px;
@ -312,6 +312,9 @@
.tableRow td:first-child {
max-width: 17%;
}
#portal-info {
max-width: 60vw;
}
}
.downloadContentCellShift:after {
@ -363,6 +366,10 @@
height: 80px;
}
.main {
height: calc(100% - 128px);
}
.copy {
width: 100%;
text-align: center;
@ -436,6 +443,58 @@
display: none;
width: 1%;
}
/* Mobile Upload*/
.blockUI.blockMsg.blockPage.ui-dialog.ui-widget.ui-corner-all.ui-widget-content.ui-draggable {
width: 344px !important;
box-shadow: 0px 7px 15px rgba(85, 85, 85, 0.1);
border-radius: 2px;
top: 10% !important;
margin-left: -172px !important;
}
.ui-dialog .ui-dialog-titlebar {
padding: 0;
}
.ui-dialog .ui-dialog-content {
padding: 0 !important;
}
#mainProgress {
margin: 24px 16px 0 !important;
}
.blockTitle {
padding: 10px 10px 6px 16px !important;
font-size: 14px !important;
}
#mainProgress .describeUpload {
padding: 8px 0 !important;
}
.dialog-close {
margin: 0 !important;
}
.step-descr{
line-height: 150%;
}
.step {
line-height: 160%;
}
.buttonsMobile{
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
.button.gray{
margin: 0;
}
.button, .button:hover{
display: flex;
justify-content: center;
padding: 0 !important;
width: 144px;
height: 56px;
margin-bottom: 24px !important;
}
}
@media (max-width: 560px) and (min-width: 510px) {

View File

@ -22,6 +22,7 @@
}
body {
display: block;
background: #FFFFFF;
color: #333333;
font-family: Open Sans;
@ -71,6 +72,7 @@ header img {
}
.main {
display: table;
height: calc(100% - 112px);
min-height: 536px;
}
@ -97,6 +99,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;
@ -161,7 +167,7 @@ label .checkbox {
background-image: url("images/file_docxf.svg");
}
.create-sample {
.side-option {
color: #666666;
line-height: 24px;
}
@ -728,12 +734,9 @@ html {
width: 30vw;
min-width: 200px;
max-width: 400px;
margin-top: 20px;
}
.user-descr > b {
margin-left: 25px;
}
.portal-descr:nth-child(3) {
margin-bottom: 20px;
}

View File

@ -16,6 +16,7 @@
*
*/
using System;
using System.IO;
using System.Web.Mvc;
using OnlineEditorsExampleMVC.Helpers;
@ -31,13 +32,14 @@ namespace OnlineEditorsExampleMVC.Controllers
}
// viewing file in the editor
public ActionResult Editor(string fileName, string editorsMode, string editorsType)
public ActionResult Editor(string fileName, string editorsMode, string editorsType, string directUrl)
{
var file = new FileModel
{
Mode = editorsMode, // editor mode: edit or view
Type = editorsType, // editor type: desktop, mobile, embedded
FileName = Path.GetFileName(fileName) // file name
FileName = Path.GetFileName(fileName), // file name
IsEnabledDirectUrl = directUrl != null ? Convert.ToBoolean(directUrl) : false
};
return View("Editor", file);

View File

@ -25,6 +25,7 @@ using System.Web;
using System.Web.Configuration;
using System.Web.Script.Serialization;
using OnlineEditorsExampleMVC.Models;
using System.Net;
namespace OnlineEditorsExampleMVC.Helpers
{
@ -79,19 +80,37 @@ namespace OnlineEditorsExampleMVC.Helpers
// get the storage path of the file
public static string StoragePath(string fileName, string userAddress = null)
{
var directory = HttpRuntime.AppDomainAppPath + CurUserHostAddress(userAddress) + "\\";
var directory = "";
if (!string.IsNullOrEmpty(WebConfigurationManager.AppSettings["storage-path"]) && Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
}
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
return directory + Path.GetFileName(fileName);
return directory + (fileName.Contains("\\") ? fileName : Path.GetFileName(fileName));
}
// get the path to the forcesaved file version
public static string ForcesavePath(string fileName, string userAddress, Boolean create)
{
// create the directory to this file version
var directory = HttpRuntime.AppDomainAppPath + CurUserHostAddress(userAddress) + "\\";
var directory = "";
if (!string.IsNullOrEmpty(WebConfigurationManager.AppSettings["storage-path"]) && Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
}
if (!Directory.Exists(directory))
{
return "";
@ -172,7 +191,16 @@ namespace OnlineEditorsExampleMVC.Helpers
// get all the stored files from the user host address
public static List<FileInfo> GetStoredFiles()
{
var directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(null) + "\\";
var directory = "";
if (!string.IsNullOrEmpty(WebConfigurationManager.AppSettings["storage-path"]) && Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(null) + "\\";
}
if (!Directory.Exists(directory)) return new List<FileInfo>();
var directoryInfo = new DirectoryInfo(directory);
@ -214,7 +242,8 @@ namespace OnlineEditorsExampleMVC.Helpers
{
var uri = new UriBuilder(GetServerUrl(forDocumentServer))
{
Path = HttpRuntime.AppDomainAppVirtualPath + "/"
Path = HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ CurUserHostAddress() + "/"
+ fileName,
Query = ""
@ -228,8 +257,7 @@ namespace OnlineEditorsExampleMVC.Helpers
{
var uri = new UriBuilder(GetServerUrl(true))
{
Path = HttpRuntime.AppDomainAppVirtualPath + "/"
+ path,
Path = HttpRuntime.AppDomainAppVirtualPath + "/" + path,
Query = ""
};
@ -265,7 +293,7 @@ namespace OnlineEditorsExampleMVC.Helpers
+ "webeditor.ashx",
Query = "type=track"
+ "&fileName=" + HttpUtility.UrlEncode(fileName)
+ "&userAddress=" + HttpUtility.UrlEncode(HttpContext.Current.Request.UserHostAddress)
+ "&userAddress=" + HttpUtility.UrlEncode(CurUserHostAddress(HttpContext.Current.Request.UserHostAddress))
};
return callbackUrl.ToString();
}
@ -284,10 +312,30 @@ namespace OnlineEditorsExampleMVC.Helpers
return createUrl.ToString();
}
// get url to download a file
public static string GetDownloadUrl(string fileName)
// create the public history url
public static string GetHistoryDownloadUrl(string filename, string version, string file, Boolean isServer = true)
{
var downloadUrl = new UriBuilder(GetServerUrl(true))
var userAddress = "&userAddress=" + HttpUtility.UrlEncode(CurUserHostAddress(HttpContext.Current.Request.UserHostAddress));
var downloadUrl = new UriBuilder(GetServerUrl(isServer))
{
Path =
HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "webeditor.ashx",
Query = "type=downloadhistory"
+ "&fileName=" + HttpUtility.UrlEncode(filename)
+ userAddress
+ "&ver=" + version
+ "&file="+ file
};
return downloadUrl.ToString();
}
// get url to download a file
public static string GetDownloadUrl(string fileName, Boolean isServer = true)
{
var userAddress = isServer ? "&userAddress=" + HttpUtility.UrlEncode(CurUserHostAddress(HttpContext.Current.Request.UserHostAddress)) : "";
var downloadUrl = new UriBuilder(GetServerUrl(isServer))
{
Path =
HttpRuntime.AppDomainAppVirtualPath
@ -295,7 +343,7 @@ namespace OnlineEditorsExampleMVC.Helpers
+ "webeditor.ashx",
Query = "type=download"
+ "&fileName=" + HttpUtility.UrlEncode(fileName)
+ "&userAddress=" + HttpUtility.UrlEncode(HttpContext.Current.Request.UserHostAddress)
+ userAddress
};
return downloadUrl.ToString();
}
@ -372,5 +420,33 @@ namespace OnlineEditorsExampleMVC.Helpers
return files;
}
// enable certificate ignore
public static void VerifySSL()
{
// hack. http://ubuntuforums.org/showthread.php?t=1841740
if(WebConfigurationManager.AppSettings["files.docservice.verify-peer-off"].Equals("true")) {
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
}
}
public static Dictionary<string, string> GetLanguages()
{
var languages = new Dictionary<string, string>();
String[] couples = (WebConfigurationManager.AppSettings["files.docservice.languages"] ?? "").Split('|');
foreach (string couple in couples)
{
String[] tmp = couple.Split(':');
languages.Add(tmp[0],tmp[1]);
}
return languages;
}
public static string GetDirectUrl()
{
string isEnabledDirectUrl = HttpUtility.ParseQueryString(HttpContext.Current.Request.Url.Query).Get("directUrl");
return isEnabledDirectUrl != null ? isEnabledDirectUrl : "false";
}
}
}

View File

@ -143,6 +143,8 @@ namespace OnlineEditorsExampleMVC.Helpers
requestStream.Write(bytes, 0, bytes.Length); // and write the serialized body object to it
}
DocManagerHelper.VerifySSL();
string dataResponse;
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream()) // get the response stream

View File

@ -16,12 +16,12 @@
*
*/
using System;
using JWT;
using JWT.Algorithms;
using JWT.Builder;
using JWT.Serializers;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Web.Configuration;
using System.Web.Script.Serialization;
namespace OnlineEditorsExampleMVC.Helpers
{
@ -30,31 +30,19 @@ namespace OnlineEditorsExampleMVC.Helpers
private static readonly string Secret;
public static readonly bool Enabled;
private static readonly JavaScriptSerializer Serializer;
static JwtManager()
{
Secret = WebConfigurationManager.AppSettings["files.docservice.secret"] ?? ""; // get token secret from the config parameters
Enabled = !string.IsNullOrEmpty(Secret); // check if the token is enabled
Serializer = new JavaScriptSerializer(); // define java script serializer
}
// encode a payload object into a token using a secret key
public static string Encode(IDictionary<string, object> payload)
{
// define the hashing algorithm and the token type
var header = new Dictionary<string, object>
{
{ "alg", "HS256" },
{ "typ", "JWT" }
};
// three parts of token
var encHeader = Base64UrlEncode(Serializer.Serialize(header)); // header
var encPayload = Base64UrlEncode(Serializer.Serialize(payload)); // payload
var hashSum = Base64UrlEncode(CalculateHash(encHeader, encPayload)); // signature
return string.Format("{0}.{1}.{2}", encHeader, encPayload, hashSum);
var encoder = new JwtEncoder(new HMACSHA256Algorithm(),
new JsonNetSerializer(),
new JwtBase64UrlEncoder());
return encoder.Encode(payload, Secret);
}
// decode a token into a payload object using a secret key
@ -62,52 +50,11 @@ namespace OnlineEditorsExampleMVC.Helpers
{
if (!Enabled || string.IsNullOrEmpty(token)) return "";
var split = token.Split('.');
if (split.Length != 3) return "";
var hashSum = Base64UrlEncode(CalculateHash(split[0], split[1])); // get signature
if (hashSum != split[2]) return ""; // and check if it is equal to the signature from the token
return Base64UrlDecode(split[1]); // decode payload
}
// generate a hash code based on a key using the HMAC method
private static byte[] CalculateHash(string encHeader, string encPayload)
{
using (var hasher = new HMACSHA256(Encoding.UTF8.GetBytes(Secret)))
{
var bytes = Encoding.UTF8.GetBytes(string.Format("{0}.{1}", encHeader, encPayload));
return hasher.ComputeHash(bytes);
}
}
// encode a string into the base64 value
private static string Base64UrlEncode(string str)
{
return Base64UrlEncode(Encoding.UTF8.GetBytes(str));
}
// encode bytes into the base64 value
private static string Base64UrlEncode(byte[] bytes)
{
return Convert.ToBase64String(bytes)
.TrimEnd('=').Replace('+', '-').Replace('/', '_');
}
// decode a base64 value into the string
private static string Base64UrlDecode(string payload)
{
var b64 = payload.Replace('_', '/').Replace('-', '+');
switch (b64.Length%4)
{
case 2:
b64 += "==";
break;
case 3:
b64 += "=";
break;
}
var bytes = Convert.FromBase64String(b64);
return Encoding.UTF8.GetString(bytes);
return JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(Secret)
.MustVerifySignature()
.Decode(token);
}
}
}

View File

@ -76,7 +76,9 @@ namespace OnlineEditorsExampleMVC.Helpers
if (token != null && !token.Equals("")) // invalid signature error
{
fileData = (Dictionary<string, object>)jss.Deserialize<Dictionary<string, object>>(token)["payload"];
fileData = jss.Deserialize<Dictionary<string, object>>(token);
if (fileData.ContainsKey("payload"))
fileData = (Dictionary<string, object>)fileData["payload"];
}
else
{
@ -95,7 +97,11 @@ namespace OnlineEditorsExampleMVC.Helpers
}
var downloadUri = (string)fileData["url"];
string curExt = Path.GetExtension(fileName).ToLower(); // get current file extension
string downloadExt = Path.GetExtension(downloadUri).ToLower() ?? ""; // get the extension of the downloaded file
var downloadExt = fileData.ContainsKey("filetype")
? "." + (string)fileData["filetype"]
: Path.GetExtension(downloadUri).ToLower() ?? ""; // TODO: Delete in version 7.0 or higher. Support for versions below 7.0
var newFileName = fileName;
// convert downloaded file to the file with the current extension if these extensions aren't equal
@ -122,6 +128,8 @@ namespace OnlineEditorsExampleMVC.Helpers
}
}
DocManagerHelper.VerifySSL();
var storagePath = DocManagerHelper.StoragePath(newFileName, userAddress); // get the file path
var histDir = DocManagerHelper.HistoryDir(storagePath); // get the path to the history directory
if (!Directory.Exists(histDir)) Directory.CreateDirectory(histDir);
@ -167,7 +175,11 @@ namespace OnlineEditorsExampleMVC.Helpers
var downloadUri = (string)fileData["url"];
string curExt = Path.GetExtension(fileName).ToLower(); // get current file extension
string downloadExt = Path.GetExtension(downloadUri).ToLower(); // get the extension of the downloaded file
var downloadExt = fileData.ContainsKey("filetype")
? "." + (string)fileData["filetype"]
: Path.GetExtension(downloadUri).ToLower(); // TODO: Delete in version 7.0 or higher. Support for versions below 7.0
Boolean newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal
@ -193,6 +205,8 @@ namespace OnlineEditorsExampleMVC.Helpers
}
}
DocManagerHelper.VerifySSL();
string forcesavePath = "";
Boolean isSubmitForm = fileData["forcesavetype"].ToString().Equals("3"); // SubmitForm
@ -235,8 +249,10 @@ namespace OnlineEditorsExampleMVC.Helpers
}
// create a command request
public static void commandRequest(string method, string key)
public static void commandRequest(string method, string key, object meta = null)
{
DocManagerHelper.VerifySSL();
string documentCommandUrl = WebConfigurationManager.AppSettings["files.docservice.url.site"] + WebConfigurationManager.AppSettings["files.docservice.url.command"];
var request = (HttpWebRequest)WebRequest.Create(documentCommandUrl);
@ -248,6 +264,11 @@ namespace OnlineEditorsExampleMVC.Helpers
{ "key", key }
};
if (meta != null)
{
body.Add("meta", meta);
}
// check if a secret key to generate token exists or not
if (JwtManager.Enabled)
{
@ -300,6 +321,7 @@ namespace OnlineEditorsExampleMVC.Helpers
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path"); // file isn't specified
var req = (HttpWebRequest)WebRequest.Create(url);
req.Timeout = 5000;
using (var stream = req.GetResponse().GetResponseStream()) // get input stream of the file information from the url
{
if (stream == null) throw new Exception("stream is null");

View File

@ -30,7 +30,8 @@ namespace OnlineEditorsExampleMVC.Helpers
"Can review all the changes",
"Can perform all actions with comments",
"The file favorite state is undefined",
"Can create files from templates using data from the editor"
"Can create files from templates using data from the editor",
"Can see the information about all users"
};
static List<string> descr_user_2 = new List<string>()
@ -39,7 +40,8 @@ namespace OnlineEditorsExampleMVC.Helpers
"Can review only his own changes or changes made by users with no group",
"Can view comments, edit his own comments and comments left by users with no group. Can remove his own comments only",
"This file is marked as favorite",
"Can create new files from the editor"
"Can create new files from the editor",
"Can see the information about users from Group2 and users who dont belong to any group"
};
static List<string> descr_user_3 = new List<string>()
@ -51,7 +53,8 @@ namespace OnlineEditorsExampleMVC.Helpers
"Cant copy data from the file to clipboard",
"Cant download the file",
"Cant print the file",
"Can create new files from the editor"
"Can create new files from the editor",
"Can see the information about Group2 users"
};
static List<string> descr_user_0 = new List<string>()
@ -62,7 +65,11 @@ namespace OnlineEditorsExampleMVC.Helpers
"Can perform all actions with comments",
"The file favorite state is undefined",
"Can't mention others in comments",
"Can't create new files from the editor"
"Can't create new files from the editor",
"Cant see anyones information",
"Can't rename files from the editor",
"Can't view chat",
"View file without collaboration",
};
private static List<User> users = new List<User>() {
@ -70,10 +77,11 @@ namespace OnlineEditorsExampleMVC.Helpers
"uid-1",
"John Smith",
"smith@example.com",
null,
"",
null,
new Dictionary<string, object>(),
null,
null,
new List<string>(),
descr_user_1,
true
@ -90,6 +98,7 @@ namespace OnlineEditorsExampleMVC.Helpers
{ "edit", new List<string>() { "group-2", "" } },
{ "remove", new List<string>() { "group-2" } }
},
new List<string>() { "group-2", "" },
true,
new List<string>(),
descr_user_2,
@ -107,6 +116,7 @@ namespace OnlineEditorsExampleMVC.Helpers
{ "edit", new List<string>() { "group-2" } },
{ "remove", new List<string>() { } }
},
new List<string>() { "group-2" },
false,
new List<string>() { "copy", "download", "print" },
descr_user_3,
@ -116,9 +126,10 @@ namespace OnlineEditorsExampleMVC.Helpers
"uid-0",
null,
null,
null,
"",
null,
new Dictionary<string,object>(),
new List<string>(),
null,
new List<string>(),
descr_user_0,
@ -173,8 +184,9 @@ namespace OnlineEditorsExampleMVC.Helpers
public List<string> deniedPermissions;
public List<string> descriptions;
public bool templates;
public List<string> userInfoGroups;
public User(string id, string name, string email, string group, List<string> reviewGroups, Dictionary<string, object> commentGroups, bool? favorite, List<string> deniedPermissions, List<string> descriptions, bool templates)
public User(string id, string name, string email, string group, List<string> reviewGroups, Dictionary<string, object> commentGroups, List<string> userInfoGroups, bool? favorite, List<string> deniedPermissions, List<string> descriptions, bool templates)
{
this.id = id;
this.name = name;
@ -186,6 +198,7 @@ namespace OnlineEditorsExampleMVC.Helpers
this.deniedPermissions = deniedPermissions;
this.descriptions = descriptions;
this.templates = templates;
this.userInfoGroups = userInfoGroups;
}
}
}

103
web/documentserver-example/csharp-mvc/Models/FileModel.cs Normal file → Executable file
View File

@ -21,6 +21,7 @@ using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.Configuration;
using System.Web.Mvc;
using System.Web.Script.Serialization;
using OnlineEditorsExampleMVC.Helpers;
@ -32,6 +33,7 @@ namespace OnlineEditorsExampleMVC.Models
{
public string Mode { get; set; } // editor mode
public string Type { get; set; } // editor type
public bool IsEnabledDirectUrl { get; set; } // is enabled direct url
// get file url for Document Server
public string FileUri
@ -42,7 +44,7 @@ namespace OnlineEditorsExampleMVC.Models
// get file url for user
public string FileUriUser
{
get { return DocManagerHelper.GetFileUri(FileName, false); }
get { return Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ? DownloadUrl + "&dmode=emb" : DocManagerHelper.GetFileUri(FileName, false); }
}
public string FileName { get; set; } // file name
@ -96,6 +98,7 @@ namespace OnlineEditorsExampleMVC.Models
var actionLink = request.GetOrDefault("actionLink", null); // get the action link (comment or bookmark) if it exists
var actionData = string.IsNullOrEmpty(actionLink) ? null : jss.DeserializeObject(actionLink); // get action data for the action link
var directUrl = DocManagerHelper.GetDownloadUrl(FileName, false);
var createUrl = DocManagerHelper.GetCreateUrl(FileUtility.GetFileType(FileName));
var templatesImageUrl = DocManagerHelper.GetTemplateImageUrl(FileUtility.GetFileType(FileName)); // image url for templates
var templates = new List<Dictionary<string, string>>
@ -124,6 +127,7 @@ namespace OnlineEditorsExampleMVC.Models
{
{ "title", FileName },
{ "url", DownloadUrl },
{ "directUrl", IsEnabledDirectUrl ? directUrl : "" },
{ "fileType", ext.Trim('.') },
{ "key", Key },
{
@ -147,8 +151,10 @@ namespace OnlineEditorsExampleMVC.Models
{ "modifyFilter", editorsMode != "filter" },
{ "modifyContentControl", editorsMode != "blockcontent" },
{ "review", canEdit && (editorsMode == "edit" || editorsMode == "review") },
{ "chat", !user.id.Equals("uid-0") },
{ "reviewGroups", user.reviewGroups },
{ "commentGroups", user.commentGroups }
{ "commentGroups", user.commentGroups },
{ "userInfoGroups", user.userInfoGroups }
}
}
}
@ -160,13 +166,18 @@ namespace OnlineEditorsExampleMVC.Models
{ "mode", mode },
{ "lang", request.Cookies.GetOrDefault("ulang", "en") },
{ "callbackUrl", CallbackUrl }, // absolute URL to the document storage service
{ "coEditing", editorsMode == "view" && user.id.Equals("uid-0") ?
new Dictionary<string, object>{
{"mode", "strict"},
{"change", false}
} : null },
{ "createUrl", !user.id.Equals("uid-0") ? createUrl : null },
{ "templates", user.templates ? templates : null },
{
// the user currently viewing or editing the document
"user", new Dictionary<string, object>
{
{ "id", user.id },
{ "id", !user.id.Equals("uid-0") ? user.id : null },
{ "name", user.name },
{ "group", user.group }
}
@ -175,9 +186,9 @@ namespace OnlineEditorsExampleMVC.Models
// the parameters for the embedded document type
"embedded", new Dictionary<string, object>
{
{ "saveUrl", FileUriUser }, // the absolute URL that will allow the document to be saved onto the user personal computer
{ "embedUrl", FileUriUser }, // the absolute URL to the document serving as a source file for the document embedded into the web page
{ "shareUrl", FileUriUser }, // the absolute URL that will allow other users to share this document
{ "saveUrl", directUrl }, // the absolute URL that will allow the document to be saved onto the user personal computer
{ "embedUrl", directUrl }, // the absolute URL to the document serving as a source file for the document embedded into the web page
{ "shareUrl", directUrl }, // the absolute URL that will allow other users to share this document
{ "toolbarDocked", "top" } // the place for the embedded viewer toolbar (top or bottom)
}
},
@ -186,13 +197,14 @@ namespace OnlineEditorsExampleMVC.Models
"customization", new Dictionary<string, object>
{
{ "about", true }, // the About section display
{ "comments", true },
{ "feedback", true }, // the Feedback & Support menu button display
{ "forcesave", false }, // adds the request for the forced file saving to the callback handler
{ "submitForm", submitForm }, // if the Submit form button is displayed or not
{
"goback", new Dictionary<string, object> // settings for the Open file location menu button and upper right corner button
{
{ "url", url.Action("Index", "Home") } // the absolute URL to the website address which will be opened when clicking the Open file location menu button
{ "url", DocManagerHelper.GetServerUrl(false) } // the absolute URL to the website address which will be opened when clicking the Open file location menu button
}
}
}
@ -214,7 +226,8 @@ namespace OnlineEditorsExampleMVC.Models
// get the document history
public void GetHistory(out string history, out string historyData)
{
{
var storagePath = WebConfigurationManager.AppSettings["storage-path"];
var jss = new JavaScriptSerializer();
var histDir = DocManagerHelper.HistoryDir(DocManagerHelper.StoragePath(FileName, null));
@ -253,9 +266,31 @@ namespace OnlineEditorsExampleMVC.Models
}
}
var ext = Path.GetExtension(FileName).ToLower();
dataObj.Add("fileType", ext.Replace(".", ""));
dataObj.Add("key", key);
// write file url to the data object
dataObj.Add("url", i == currentVersion ? FileUri : DocManagerHelper.GetPathUri(Directory.GetFiles(verDir, "prev.*")[0].Substring(HttpRuntime.AppDomainAppPath.Length)));
string prevFileUrl;
string directPrevFileUrl;
if (Path.IsPathRooted(storagePath) && !string.IsNullOrEmpty(storagePath))
{
prevFileUrl = i == currentVersion ? DocManagerHelper.GetHistoryDownloadUrl(FileName, i.ToString(), "prev" + ext)
: DocManagerHelper.GetDownloadUrl(Directory.GetFiles(verDir, "prev.*")[0].Replace(storagePath + "\\", ""));
directPrevFileUrl = i == currentVersion ? DocManagerHelper.GetHistoryDownloadUrl(FileName, i.ToString(), "prev" + ext, false)
: DocManagerHelper.GetDownloadUrl(Directory.GetFiles(verDir, "prev.*")[0].Replace(storagePath + "\\", ""), false);
}
else {
prevFileUrl = i == currentVersion ? FileUri
: DocManagerHelper.GetHistoryDownloadUrl(FileName, i.ToString(), "prev" + ext);
directPrevFileUrl = i == currentVersion ? DocManagerHelper.GetHistoryDownloadUrl(FileName, i.ToString(), "prev" + ext, false)
: DocManagerHelper.GetDownloadUrl(Directory.GetFiles(verDir, "prev.*")[0].Replace(storagePath + "\\", ""), false);
}
dataObj.Add("url", prevFileUrl);
if (IsEnabledDirectUrl)
{
dataObj.Add("directUrl", directPrevFileUrl);
}
dataObj.Add("version", i);
if (i > 1) // check if the version number is greater than 1 (the file was modified)
{
@ -273,12 +308,19 @@ namespace OnlineEditorsExampleMVC.Models
obj.Add("user", change.Count > 0 ? change["user"] : null);
var prev = (Dictionary<string, object>)histData[(i - 2).ToString()]; // get the history data from the previous file version
dataObj.Add("previous", new Dictionary<string, object>() { // write information about previous file version to the data object
dataObj.Add("previous", IsEnabledDirectUrl ? new Dictionary<string, object>() { // write information about previous file version to the data object with direct url
{ "fileType", prev["fileType"] },
{ "key", prev["key"] }, // write key and url information about previous file version
{ "url", prev["url"] },
{ "directUrl", prev["directUrl"] },
} : new Dictionary<string, object>() { // write information about previous file version to the data object without direct url
{ "fileType", prev["fileType"] },
{ "key", prev["key"] }, // write key and url information about previous file version
{ "url", prev["url"] },
});
// write the path to the diff.zip archive with differences in this file version
dataObj.Add("changesUrl", DocManagerHelper.GetPathUri(Path.Combine(DocManagerHelper.VersionDir(histDir, i - 1), "diff.zip").Substring(HttpRuntime.AppDomainAppPath.Length)));
var changesUrl = DocManagerHelper.GetHistoryDownloadUrl(FileName, (i - 1).ToString(), "diff.zip");
dataObj.Add("changesUrl", changesUrl);
}
if(JwtManager.Enabled)
{
@ -313,6 +355,14 @@ namespace OnlineEditorsExampleMVC.Models
Query = "type=assets&fileName=" + HttpUtility.UrlEncode("sample.docx")
};
var directCompareFileUrl = new UriBuilder(DocManagerHelper.GetServerUrl(false))
{
Path = HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "webeditor.ashx",
Query = "type=assets&fileName=" + HttpUtility.UrlEncode("sample.docx")
};
// create an object with the information about the compared file
var dataCompareFile = new Dictionary<string, object>
{
@ -320,6 +370,11 @@ namespace OnlineEditorsExampleMVC.Models
{ "url", compareFileUrl.ToString() }
};
if (IsEnabledDirectUrl)
{
dataCompareFile.Add("directUrl", directCompareFileUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var compareFileToken = JwtManager.Encode(dataCompareFile); // encode the dataCompareFile object into the token
@ -342,6 +397,13 @@ namespace OnlineEditorsExampleMVC.Models
+ "Content\\images\\logo.png"
};
var directMailMergeUrl = new UriBuilder(DocManagerHelper.GetServerUrl(false))
{
Path = HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "Content\\images\\logo.png"
};
// create a logo config
var logoConfig = new Dictionary<string, object>
{
@ -349,6 +411,11 @@ namespace OnlineEditorsExampleMVC.Models
{ "url", mailMergeUrl.ToString()}
};
if (IsEnabledDirectUrl)
{
logoConfig.Add("directUrl", directMailMergeUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var token = JwtManager.Encode(logoConfig); // encode logoConfig into the token
@ -373,6 +440,15 @@ namespace OnlineEditorsExampleMVC.Models
Query = "type=csv"
};
var directMailMergeUrl = new UriBuilder(DocManagerHelper.GetServerUrl(false))
{
Path =
HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "webeditor.ashx",
Query = "type=csv"
};
// create a mail merge config
var mailMergeConfig = new Dictionary<string, object>
{
@ -380,6 +456,11 @@ namespace OnlineEditorsExampleMVC.Models
{ "url", mailMergeUrl.ToString()}
};
if (IsEnabledDirectUrl)
{
mailMergeConfig.Add("directUrl", directMailMergeUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var mailmergeToken = JwtManager.Encode(mailMergeConfig); // encode mailMergeConfig into the token

View File

@ -55,7 +55,7 @@ namespace OnlineEditorsExampleMVC.Models
// spreadsheet extensions
public static readonly List<string> ExtsSpreadsheet = new List<string>
{
".xls", ".xlsx", ".xlsm",
".xls", ".xlsx", ".xlsm", ".xlsb",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv"
};

View File

@ -13,7 +13,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OnlineEditorsExampleMVC</RootNamespace>
<AssemblyName>OnlineEditorsExampleMVC</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort />
@ -43,6 +43,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="JWT, Version=9.0.0.0, Culture=neutral, PublicKeyToken=6f98bca0f40f2ecf, processorArchitecture=MSIL">
<HintPath>packages\JWT.9.0.3\lib\net46\JWT.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
@ -50,49 +53,49 @@
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Services" />
<Reference Include="Antlr3.Runtime">
<Reference Include="Antlr3.Runtime, Version=3.5.0.2, Culture=neutral, PublicKeyToken=eb42632606e9261f, processorArchitecture=MSIL">
<HintPath>packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
</Reference>
<Reference Include="EntityFramework">
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure">
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Formatting">
<Reference Include="System.Net.Http.Formatting, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Web.Helpers">
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http">
<Reference Include="System.Web.Http, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost">
<Reference Include="System.Web.Http.WebHost, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebApi.WebHost.5.2.7\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc">
<Reference Include="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Optimization">
<Reference Include="System.Web.Optimization, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor">
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages">
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment">
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor">
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="WebGrease">
<Reference Include="WebGrease, Version=1.6.5135.21930, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\WebGrease.1.6.0\lib\WebGrease.dll</HintPath>
</Reference>
</ItemGroup>
@ -182,10 +185,12 @@
<Content Include="assets\AUTHORS.md" />
<Content Include="assets\LICENSE" />
<Content Include="assets\new\new.docx" />
<Content Include="assets\new\new.docxf" />
<Content Include="assets\new\new.pptx" />
<Content Include="assets\new\new.xlsx" />
<Content Include="assets\sample\csv.csv" />
<Content Include="assets\sample\sample.docx" />
<Content Include="assets\sample\sample.docxf" />
<Content Include="assets\sample\sample.pptx" />
<Content Include="assets\sample\sample.xlsx" />
<None Include="packages.config" />

View File

@ -2,22 +2,25 @@
This example will help you integrate ONLYOFFICE Docs into your web application written in .Net (C# MVC).
It is aimed at testing the editors. Please, do not use it for production without proper modifications.
**Please note**: It is intended for testing purposes and demonstrating functionality of the editors. Do NOT use this integration example on your own server without proper code modifications! In case you enabled the test example, disable it before going for production.
## Step 1. Install ONLYOFFICE Docs
Download and install ONLYOFFICE Docs (packaged as Document Server).
Download and install ONLYOFFICE Docs (packaged as Document Server).
See the detailed guide to learn how to install Document Server [for Windows](https://helpcenter.onlyoffice.com/installation/docs-developer-install-windows.aspx), [for Linux](https://helpcenter.onlyoffice.com/installation/docs-developer-install-ubuntu.aspx), or [for Docker](https://helpcenter.onlyoffice.com/server/developer-edition/docker/docker-installation.aspx).
## Step 2. Download the .Net (C# MVC) code for the editors integration
Download the [.Net (C# MVC) example](https://api.onlyoffice.com/editors/demopreview) from our site.
You need to connnect the editors to your website. Specify path to the editors installation in the *settings.config* file:
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *settings.config* file:
```
<add key="storage-path" value=""/>
<add key="files.docservice.url.site" value="https://documentserver/" />
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-path** is the path where files will be created and stored. You can set an absolute path.
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) in the *DocEditor.aspx* file.
## Step 3. Install the prerequisites
@ -25,31 +28,41 @@ If you want to experiment with the editor configuration, modify the [parameters]
* **Microsoft .NET Framework**: version 4.5 (download it from the [official Microsoft website](https://www.microsoft.com/en-US/download/details.aspx?id=30653));
* **Internet Information Services**: version 7 or later.
Configure the IIS components for the server to work correctly:
1. Open Windows features:
**Start** -> **Control Panel** -> **Programs** -> **Programs and Features** -> **Turn Windows features on or off**
2. In the opened window, find **Internet Information Services** and choose all the necessary features. To do this, open the **World Wide Web Services** list and check the following components:
* **Application Development Features**: .NET Extensibility 4.8, ASP.NET 4.8, ISAPI Extensions, ISAPI Filters,
* **Common HTTP Features**: Default Document,
* **Security**: Request Filtering.
## Step 4. Run your website with the editors
1. Run the Internet Information Service (IIS) Manager:
**Start** -> **Control Panel** -> **System and Security** -> **Administrative Tools** -> **Internet Information Services (IIS) Manager**
2. Add your website in the IIS Manager.
On the **Connections** panel right-click the **Sites** node in the tree, then click **Add Website**.
![add](screenshots/add.png)
3. In the **Add Website** dialog box specify the name of the folder with the .Net (C# MVC) project in the **Site name** box.
Specify the path to the folder with your project in the **Physical Path** box.
Specify the unique value used only for this website in the **Port** box.
![sitename](screenshots/sitename.png)
4. Check for the .NET platform version specified in IIS Manager for you website. Choose **v4.0.** version.
**Application Pools** -> right-click the platform name -> **Set application Pool defaults** -> **.NET CLR version**
![platform](screenshots/platform.png)
5. Browse your website with the IIS Manager:
Right-click the site -> **Manage Website** -> **Browse**
![browse](screenshots/browse.png)
## Step 5. Check accessibility
@ -57,3 +70,12 @@ If you want to experiment with the editor configuration, modify the [parameters]
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## Important security info
Please keep in mind the following security aspects when you are using test examples:
* There is no protection of the storage from unauthorized access since there is no need for authorization.
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.

View File

@ -16,11 +16,24 @@
*
*/
var directUrl;
if (typeof jQuery != "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function () {
window.location = "?directUrl=" + jq(this).prop("checked");
});
jq(function () {
jq('#fileupload').fileupload({
dataType: 'json',
@ -219,7 +232,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?fileName=" + fileId;
var url = UrlEditor + "?fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -227,7 +240,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?editorsMode=view&fileName=" + fileId;
var url = UrlEditor + "?editorsMode=view&fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -235,7 +248,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?editorsType=embedded&editorsMode=embedded&fileName=" + fileId;
var url = UrlEditor + "?editorsType=embedded&editorsMode=embedded&fileName=" + fileId + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -289,6 +302,17 @@ if (typeof jQuery != "undefined") {
}
};
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
};
var fileList = jq("tr.tableRow");
var mouseIsOverTooltip = false;
@ -304,7 +328,7 @@ if (typeof jQuery != "undefined") {
});
}
} else {
jq(".info").mouseover(function (event) {
jq("#info").mouseover(function (event) {
if (fileList.length > 0) {
if (hideTooltipTimeout != null) {
clearTimeout(hideTooltipTimeout);

View File

@ -46,6 +46,7 @@
<script type="text/javascript" language="javascript">
var docEditor;
var config;
var innerAlert = function (message, inEditor) {
if (console && console.log)
@ -107,10 +108,14 @@
// the meta information of the document is changed via the meta command
var onMetaChange = function (event) {
var favorite = !!event.data.favorite;
var title = document.title.replace(/^\☆/g, "");
document.title = (favorite ? "☆" : "") + title;
docEditor.setFavorite(favorite); // change the Favorite icon state
if (event.data.favorite) {
var favorite = !!event.data.favorite;
var title = document.title.replace(/^\☆/g, "");
document.title = (favorite ? "☆" : "") + title;
docEditor.setFavorite(favorite); // change the Favorite icon state
}
innerAlert("onMetaChange: " + JSON.stringify(event.data));
};
// the user is trying to insert an image by clicking the Image from Storage button
@ -146,7 +151,7 @@
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "webeditor.ashx?type=saveas");
xhr.setRequestHeader( 'Content-Type', 'application/json');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
xhr.onload = function () {
innerAlert(xhr.responseText);
@ -154,7 +159,26 @@
}
};
var config = <%= Model.GetDocConfig(Request, Url) %>;
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
innerAlert("onRequestRename: " + JSON.stringify(event.data));
var newfilename = event.data;
var data = {
newfilename: newfilename,
dockey: config.document.key,
ext: config.document.fileType
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "webeditor.ashx?type=rename");
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
xhr.onload = function () {
innerAlert(xhr.responseText);
}
};
config = <%= Model.GetDocConfig(Request, Url) %>;
config.width = "100%";
config.height = "100%";
@ -174,42 +198,49 @@
<% string hist, histData; %>
<% Model.GetHistory(out hist, out histData); %>
<% if (!string.IsNullOrEmpty(hist) && !string.IsNullOrEmpty(histData))
{ %>
// the user is trying to show the document version history
config.events['onRequestHistory'] = function () {
docEditor.refreshHistory(<%= hist %>); // show the document version history
};
// the user is trying to click the specific document version in the document version history
config.events['onRequestHistoryData'] = function (event) {
var ver = event.data;
var histData = <%= histData %>;
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
};
// the user is trying to go back to the document from viewing the document version history
config.events['onRequestHistoryClose '] = function () {
document.location.reload();
};
<% } %>
<% string usersForMentions; %>
<% Model.GetUsersMentions(Request, out usersForMentions); %>
<% if (!string.IsNullOrEmpty(usersForMentions))
// add mentions for not anonymous users
{ %>
config.events['onRequestUsers'] = function () {
docEditor.setUsers({ // set a list of users to mention in the comments
"users": <%= usersForMentions%>
});
};
// the user is mentioned in a comment
config.events['onRequestSendNotify'] = function (event) {
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
var data = JSON.stringify(event.data);
innerAlert("onRequestSendNotify: " + data);
};
<% } %>
if (config.editorConfig.user.id) {
<% if (!string.IsNullOrEmpty(hist) && !string.IsNullOrEmpty(histData))
{ %>
// the user is trying to show the document version history
config.events['onRequestHistory'] = function () {
docEditor.refreshHistory(<%= hist %>); // show the document version history
};
// the user is trying to click the specific document version in the document version history
config.events['onRequestHistoryData'] = function (event) {
var ver = event.data;
var histData = <%= histData %>;
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
};
// the user is trying to go back to the document from viewing the document version history
config.events['onRequestHistoryClose '] = function () {
document.location.reload();
};
<% } %>
// add mentions for not anonymous users
<% if (!string.IsNullOrEmpty(usersForMentions))
{ %>
config.events['onRequestUsers'] = function () {
docEditor.setUsers({ // set a list of users to mention in the comments
"users": <%= usersForMentions %>
});
};
<% } %>
// the user is mentioned in a comment
config.events['onRequestSendNotify'] = function (event) {
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
var data = JSON.stringify(event.data);
innerAlert("onRequestSendNotify: " + data);
};
// prevent file renaming for anonymous users
config.events['onRequestRename'] = onRequestRename;
}
if (config.editorConfig.createUrl) {
config.events.onRequestSaveAs = onRequestSaveAs;
};

View File

@ -4,6 +4,7 @@
<%@ Import Namespace="System.Web.Configuration" %>
<%@ Import Namespace="OnlineEditorsExampleMVC.Helpers" %>
<%@ Import Namespace="OnlineEditorsExampleMVC.Models" %>
<%@ Import Namespace="System.Collections.Generic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@ -69,7 +70,7 @@
<a class="try-editor form" data-type="docxf">Form template</a>
</li>
</ul>
<label class="create-sample">
<label class="side-option">
<input id="createSample" class="checkbox" type="checkbox" />With sample content
</label>
</div>
@ -85,11 +86,11 @@
<tr>
<td valign="middle">
<span class="select-user">Username</span>
<img class="info" src="content/images/info.svg" />
<img id="info" src="content/images/info.svg" />
<select class="select-user" id="user">
<% foreach (User user in Users.getAllUsers())
{ %>
<option value=<%= user.id %> ><%= user.name.IsEmpty() ? "Anonymous" : user.name %></option>
<option value="<%= user.id %>"><%= user.name.IsEmpty() ? "Anonymous" : user.name %></option>
<% } %>
</select>
</td>
@ -98,40 +99,22 @@
<td valign="middle">
<span class="select-user">Language editors interface</span>
<select class="select-user" id="language">
<option value="en">English</option>
<option value="be">Belarusian</option>
<option value="bg">Bulgarian</option>
<option value="ca">Catalan</option>
<option value="zh">Chinese</option>
<option value="cs">Czech</option>
<option value="da">Danish</option>
<option value="nl">Dutch</option>
<option value="fi">Finnish</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="el">Greek</option>
<option value="hu">Hungarian</option>
<option value="id">Indonesian</option>
<option value="it">Italian</option>
<option value="ja">Japanese</option>
<option value="ko">Korean</option>
<option value="lv">Latvian</option>
<option value="lo">Lao</option>
<option value="nb">Norwegian</option>
<option value="pl">Polish</option>
<option value="pt">Portuguese</option>
<option value="ro">Romanian</option>
<option value="ru">Russian</option>
<option value="sk">Slovak</option>
<option value="sl">Slovenian</option>
<option value="sv">Swedish</option>
<option value="es">Spanish</option>
<option value="tr">Turkish</option>
<option value="uk">Ukrainian</option>
<option value="vi">Vietnamese</option>
<% Dictionary<string, string> languages = DocManagerHelper.GetLanguages();
foreach (var lang in languages)
{ %>
<option value="<%= lang.Key %>"><%= lang.Value %></option>
<% } %>
</select>
</td>
</tr>
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="content/images/info.svg" />
</label>
</td>
</tr>
</tbody>
</table>
</div>
@ -139,12 +122,13 @@
<td class="section">
<div class="main-panel">
<% var storedFiles = DocManagerHelper.GetStoredFiles(); %>
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "block" %>">
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "table-cell" %>">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
<br /> You may upload your own documents for testing using the "<b>Upload file</b>" button and <b>selecting</b> the necessary files on your PC.
</span>
<span class="portal-descr">Please do NOT use this integration example on your own server without proper code modifications, it is intended for testing purposes only. In case you enabled this test example, disable it before going for production.</span>
<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())
{ %>
@ -180,54 +164,52 @@
<tbody>
<% foreach (var storedFile in storedFiles)
{
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
var isEnabledDirectUrl = DocManagerHelper.GetDirectUrl();
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
var docType = FileUtility.GetFileType(storedFile.Name).ToString().ToLower();
var ext = Path.GetExtension(storedFile.Name).ToLower();
var canEdit = DocManagerHelper.EditedExts.Contains(ext);
var isFillFormDoc = DocManagerHelper.FillFormExts.Contains(ext);
%>
<tr class="tableRow" title="<%= storedFile.Name %> [<%= DocManagerHelper.GetFileVersion(storedFile.Name, HttpContext.Current.Request.UserHostAddress) %>]">
<tr class="tableRow" title="<%= storedFile.Name %> [<%= DocManagerHelper.GetFileVersion(storedFile.Name, HttpContext.Current.Request.UserHostAddress.Replace(':', '_')) %>]">
<td class="contentCells">
<a class="stored-edit <%= docType %>" href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name }) %>" target="_blank">
<a class="stored-edit <%= docType %>" href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, directUrl = isEnabledDirectUrl }) %>" target="_blank">
<span><%= storedFile.Name %></span>
</a>
</td>
<% if (canEdit) { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "edit" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "edit", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "edit" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "edit", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<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" }) %>" target="_blank">
<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" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "review", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
</a>
</td>
<% } else if (docType == "cell") { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "filter" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "filter", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" />
</a>
</td>
<% } %>
<% if (docType != "word" && docType != "cell") { %>
<td class="contentCells contentCells-icon contentCellsEmpty"></td>
<% } %>
<% if (docType == "word") { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "blockcontent" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "blockcontent", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
</a>
</td>
@ -239,7 +221,7 @@
<% } %>
<% if (isFillFormDoc) { %>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -249,7 +231,7 @@
<% } else if (isFillFormDoc) { %>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "fillForms" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/mobile-fill-forms.svg" alt="Open in editor for filling in forms for mobile devices" title="Open in editor for filling in forms for mobile devices"/>
</a>
</td>
@ -257,7 +239,7 @@
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -265,17 +247,17 @@
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
<% } %>
<td class="contentCells contentCells-icon firstContentCellViewers">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "view" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "view", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "view" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "view", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "embedded", editorsMode = "embedded" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "embedded", editorsMode = "embedded", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>
@ -328,10 +310,8 @@
<span class="step-descr">They are loaded only once, they will be cached on your computer.</span>
<input type="hidden" name="hiddenFileName" id="hiddenFileName" />
<br />
<br />
<span class="progress-descr">Note the speed of all operations depends on your connection quality and server location.</span>
<br />
<br />
<div class="error-message">
<b>Upload error: </b><span></span>
<br />
@ -340,10 +320,12 @@
</div>
<iframe id="embeddedView" src="" height="345px" width="432px" frameborder="0" scrolling="no" allowtransparency></iframe>
<br />
<div id="beginEdit" class="button orange disable">Edit</div>
<div id="beginView" class="button gray disable">View</div>
<div id="beginEmbedded" class="button gray disable">Embedded view</div>
<div id="cancelEdit" class="button gray">Cancel</div>
<div class="buttonsMobile">
<div id="beginEdit" class="button orange disable">Edit</div>
<div id="beginView" class="button gray disable">View</div>
<div id="beginEmbedded" class="button gray disable">Embedded view</div>
<div id="cancelEdit" class="button gray">Cancel</div>
</div>
</div>
<span id="loadScripts" data-docs="<%= WebConfigurationManager.AppSettings["files.docservice.url.site"] + WebConfigurationManager.AppSettings["files.docservice.url.preloader"] %>"></span>

View File

@ -26,11 +26,11 @@
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
@ -39,20 +39,28 @@
</handlers>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="52428800"/>
<requestLimits maxAllowedContentLength="52428800" />
</requestFiltering>
</security>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
@ -63,7 +71,4 @@
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
</configuration>

View File

@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Linq;
using System.Net;
using System.Web;
@ -46,6 +47,9 @@ namespace OnlineEditorsExampleMVC
case "download":
Download(context);
break;
case "downloadhistory":
DownloadHistory(context);
break;
case "convert":
Convert(context);
break;
@ -67,6 +71,9 @@ namespace OnlineEditorsExampleMVC
case "saveas":
SaveAs(context);
break;
case "rename":
Rename(context);
break;
}
}
@ -110,6 +117,8 @@ namespace OnlineEditorsExampleMVC
var req = (HttpWebRequest)WebRequest.Create(fileUrl);
DocManagerHelper.VerifySSL();
using (var stream = req.GetResponse().GetResponseStream())
{
@ -148,6 +157,8 @@ namespace OnlineEditorsExampleMVC
context.Response.ContentType = "text/plain";
try
{
DocManagerHelper.VerifySSL();
var httpPostedFile = context.Request.Files[0];
string fileName;
@ -247,6 +258,8 @@ namespace OnlineEditorsExampleMVC
var req = (HttpWebRequest)WebRequest.Create(newFileUri);
DocManagerHelper.VerifySSL();
using (var stream = req.GetResponse().GetResponseStream()) // get response stream of the converting file
{
if (stream == null) throw new Exception("Stream is null");
@ -300,7 +313,7 @@ namespace OnlineEditorsExampleMVC
var userAddress = context.Request["userAddress"];
var fileName = Path.GetFileName(context.Request["fileName"]);
var status = (TrackerStatus) (int) fileData["status"]; // get status from the request body
var saved = 1; // editing
var saved = 0;
switch (status)
{
case TrackerStatus.Editing:
@ -357,7 +370,7 @@ namespace OnlineEditorsExampleMVC
return;
}
context.Response.Write("{\"error\":0}");
context.Response.Write("{\"error\":" + saved + "}");
}
// remove a file
@ -443,10 +456,12 @@ namespace OnlineEditorsExampleMVC
{
try
{
var fileName = Path.GetFileName(context.Request["fileName"]);
var fileName = Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ? context.Request["fileName"]
: Path.GetFileName(context.Request["fileName"]);
var userAddress = context.Request["userAddress"];
var isEmbedded = context.Request["dmode"];
if (JwtManager.Enabled)
if (JwtManager.Enabled && isEmbedded == null)
{
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
@ -492,5 +507,88 @@ namespace OnlineEditorsExampleMVC
{
get { return false; }
}
// download a history file
private static void DownloadHistory(HttpContext context)
{
try
{
var fileName = Path.GetFileName(context.Request["fileName"]);
var userAddress = Path.GetFileName(context.Request["userAddress"]);
var version = System.Convert.ToInt32(context.Request["ver"]);
var file = Path.GetFileName(context.Request["file"]);
if (JwtManager.Enabled)
{
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
if (context.Request.Headers.AllKeys.Contains(JWTheader, StringComparer.InvariantCultureIgnoreCase))
{
var headerToken = context.Request.Headers.Get(JWTheader).Substring("Bearer ".Length);
string token = JwtManager.Decode(headerToken);
if (token == null || token.Equals(""))
{
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
context.Response.Write("JWT validation failed");
return;
}
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
context.Response.Write("JWT validation failed");
return;
}
}
var histPath = DocManagerHelper.HistoryDir(DocManagerHelper.StoragePath(fileName, userAddress));
var filePath = Path.Combine(DocManagerHelper.VersionDir(histPath, version), file); // get the path to document version
download(filePath, context);
}
catch (Exception)
{
context.Response.Write("{ \"error\": \"File not found!\"}");
}
}
// rename a file
private static void Rename(HttpContext context)
{
// read request body
context.Response.ContentType = "text/plain";
string fileData;
try
{
using (var receiveStream = context.Request.InputStream)
using (var readStream = new StreamReader(receiveStream))
{
fileData = readStream.ReadToEnd();
if (string.IsNullOrEmpty(fileData)) context.Response.Write("{\"error\":\"Request stream is empty\"}");
}
}
catch (Exception e)
{
throw new HttpException((int)HttpStatusCode.BadRequest, e.Message);
}
var jss = new JavaScriptSerializer();
var body = jss.Deserialize<Dictionary<string, object>>(fileData);
var newFileName = (string) body["newfilename"];
var docKey = (string) body["dockey"];
var origExt = '.' + (string) body["ext"];
var curExt = Path.GetExtension(newFileName).ToLower();
if (string.Compare(origExt, curExt, true) != 0)
{
newFileName += origExt;
}
var meta = new Dictionary<string, object>() {
{ "title", newFileName }
};
TrackManager.commandRequest("meta", docKey, meta);
context.Response.Write("{ \"result\": \"OK\"}");
}
}
}

View File

@ -24,11 +24,15 @@ jQuery.UI - jQuery UI is an open source library of interface components —
License: MIT
License File: jQuery.UI.license
JWT - JWT (JSON Web Token) Implementation for .NET (Public Domain) (https://github.com/jwt-dotnet/jwt/)
License: MIT
License File: JWT.license
Microsoft.Web.Infrastructure - This package contains the Microsoft.Web.Infrastructure assembly that lets you dynamically register HTTP modules at run time. (https://www.microsoft.com/web/webpi/eula/aspnetmvc3update-eula.htm)
License: MS-EULA License
License File: Microsoft.Web.Infrastructure.license
Newtonsoft.Json - Json.NET is a popular high-performance JSON framework for .NET (https://licenses.nuget.org/MIT)
Newtonsoft.Json - Json.NET is a popular high-performance JSON framework for .NET (https://github.com/JamesNK/Newtonsoft.Json)
License: MIT
License File: Newtonsoft.Json.license

View File

@ -0,0 +1,21 @@
# Public Domain
Written by John Sheehan (http://john-sheehan.com)
This work is public domain.
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law.
For more information, please visit: http://creativecommons.org/publicdomain/zero/1.0/
# MIT
Copyright (c) 2019 Jwt.Net Maintainers and Contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
For more information, please visit: https://opensource.org/licenses/MIT

View File

@ -1,16 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Antlr" version="3.5.0.2" targetFramework="net45" />
<package id="EntityFramework" version="6.4.4" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net45" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.7" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.7" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net45" />
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net45" />
<package id="WebGrease" version="1.6.0" targetFramework="net45" />
<package id="Antlr" version="3.5.0.2" targetFramework="net48" />
<package id="EntityFramework" version="6.4.4" targetFramework="net48" />
<package id="JWT" version="9.0.3" targetFramework="net48" />
<package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net48" />
<package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net48" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net48" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net48" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.7" targetFramework="net48" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.7" targetFramework="net48" />
<package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net48" />
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net48" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net48" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net48" />
<package id="WebGrease" version="1.6.0" targetFramework="net48" />
</packages>

View File

@ -1,18 +1,23 @@
<?xml version="1.0"?>
<?xml version="1.0"?>
<appSettings>
<clear />
<add key="version" value="1.1.0"/>
<add key="version" value="1.4.0"/>
<add key="filesize-max" value="52428800"/>
<add key="storage-path" value=""/>
<add key="files.docservice.fillform-docs" value=".oform|.docx"/>
<add key="files.docservice.viewed-docs" value=".pdf|.djvu|.xps|.oxps"/>
<add key="files.docservice.edited-docs" value=".docx|.xlsx|.csv|.pptx|.txt|.docxf"/>
<add key="files.docservice.convert-docs" value=".docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2"/>
<add key="files.docservice.convert-docs" value=".docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xlsb|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2"/>
<add key="files.docservice.timeout" value="120000" />
<add key="files.docservice.secret" value="" />
<add key="files.docservice.header" value="Authorization" />
<add key="files.docservice.verify-peer-off" value="true"/>
<add key="files.docservice.languages" value="en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese"/>
<add key="files.docservice.url.site" value="http://documentserver/"/>
<add key="files.docservice.url.converter" value="ConvertService.ashx"/>

View File

@ -19,3 +19,11 @@ License File: jQuery.iframe-transport.license
jQuery.UI - jQuery UI is an open source library of interface components — interactions, full-featured widgets, and animation effects — based on the stellar jQuery javascript library . Each component is built according to jQuery's event-driven architecture (find something, manipulate it) and is themeable, making it easy for developers of any skill level to integrate and extend into their own code. (https://jquery.org/license/)
License: MIT
License File: jQuery.UI.license
JWT - JWT (JSON Web Token) Implementation for .NET (Public Domain) (https://github.com/jwt-dotnet/jwt/)
License: MIT
License File: JWT.license
Newtonsoft.Json - Json.NET is a popular high-performance JSON framework for .NET (https://github.com/JamesNK/Newtonsoft.Json)
License: MIT
License File: Newtonsoft.Json.license

View File

@ -87,10 +87,6 @@
}
@media (max-width: 1008px) {
#portal-info {
width: 65vw;
}
.left-panel {
margin-left: 0;
}
@ -128,6 +124,10 @@
height: 80px;
}
.main {
height: calc(100% - 128px);
}
.main-panel {
left: 0;
padding: 48px 18px 24px;
@ -312,6 +312,9 @@
.tableRow td:first-child {
max-width: 17%;
}
#portal-info {
max-width: 60vw;
}
}
.downloadContentCellShift:after {
@ -363,6 +366,10 @@
height: 80px;
}
.main {
height: calc(100% - 128px);
}
.copy {
width: 100%;
text-align: center;
@ -436,6 +443,58 @@
display: none;
width: 1%;
}
/* Mobile Upload*/
.blockUI.blockMsg.blockPage.ui-dialog.ui-widget.ui-corner-all.ui-widget-content.ui-draggable {
width: 344px !important;
box-shadow: 0px 7px 15px rgba(85, 85, 85, 0.1);
border-radius: 2px;
top: 10% !important;
margin-left: -172px !important;
}
.ui-dialog .ui-dialog-titlebar {
padding: 0;
}
.ui-dialog .ui-dialog-content {
padding: 0 !important;
}
#mainProgress {
margin: 24px 16px 0 !important;
}
.blockTitle {
padding: 10px 10px 6px 16px !important;
font-size: 14px !important;
}
#mainProgress .describeUpload {
padding: 8px 0 !important;
}
.dialog-close {
margin: 0 !important;
}
.step-descr{
line-height: 150%;
}
.step {
line-height: 160%;
}
.buttonsMobile{
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
.button.gray{
margin: 0;
}
.button, .button:hover{
display: flex;
justify-content: center;
padding: 0 !important;
width: 144px;
height: 56px;
margin-bottom: 24px !important;
}
}
@media (max-width: 560px) and (min-width: 510px) {

View File

@ -22,6 +22,7 @@ html {
}
body {
display: block;
background: #FFFFFF;
color: #333333;
font-family: Open Sans;
@ -71,6 +72,7 @@ header img {
}
.main {
display: table;
height: calc(100% - 112px);
min-height: 536px;
}
@ -97,6 +99,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;
@ -161,7 +167,7 @@ label .checkbox {
background-image: url("images/file_docxf.svg");
}
.create-sample {
.side-option {
color: #666666;
line-height: 24px;
}
@ -732,12 +738,9 @@ html {
width: 30vw;
min-width: 200px;
max-width: 400px;
margin-top: 20px;
}
.user-descr > b {
margin-left: 25px;
}
.portal-descr:nth-child(3) {
margin-bottom: 20px;
}

View File

@ -5,12 +5,14 @@
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="System.Web.Configuration" %>
<%@ Import Namespace="OnlineEditorsExample" %>
<%@ Import Namespace="System.Collections.Generic" %>
<!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" />
<title>ONLYOFFICE</title>
<!--
*
@ -71,7 +73,7 @@
<a class="try-editor form" data-type="docxf">Form template</a>
</li>
</ul>
<label class="create-sample">
<label class="side-option">
<input id="createSample" class="checkbox" type="checkbox" />With sample content
</label>
</div>
@ -99,40 +101,22 @@
<td valign="middle">
<span class="select-user">Language editors interface</span>
<select class="select-user" id="language">
<option value="en">English</option>
<option value="be">Belarusian</option>
<option value="bg">Bulgarian</option>
<option value="ca">Catalan</option>
<option value="zh">Chinese</option>
<option value="cs">Czech</option>
<option value="da">Danish</option>
<option value="nl">Dutch</option>
<option value="fi">Finnish</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="el">Greek</option>
<option value="hu">Hungarian</option>
<option value="id">Indonesian</option>
<option value="it">Italian</option>
<option value="ja">Japanese</option>
<option value="ko">Korean</option>
<option value="lv">Latvian</option>
<option value="lo">Lao</option>
<option value="nb">Norwegian</option>
<option value="pl">Polish</option>
<option value="pt">Portuguese</option>
<option value="ro">Romanian</option>
<option value="ru">Russian</option>
<option value="sk">Slovak</option>
<option value="sl">Slovenian</option>
<option value="sv">Swedish</option>
<option value="es">Spanish</option>
<option value="tr">Turkish</option>
<option value="uk">Ukrainian</option>
<option value="vi">Vietnamese</option>
<% Dictionary<string, string> languages = GetLanguages();
foreach (var lang in languages)
{ %>
<option value="<%= lang.Key %>"><%= lang.Value %></option>
<% } %>
</select>
</td>
</tr>
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="app_themes/images/info.svg" />
</label>
</td>
</tr>
</tbody>
</table>
</div>
@ -140,12 +124,13 @@
<td class="section">
<% var storedFiles = GetStoredFiles(); %>
<div class="main-panel">
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "block" %>">
<div id="portal-info" style="display: <%= storedFiles.Any() ? "none" : "table-cell" %>">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
<br /> You may upload your own documents for testing using the "<b>Upload file</b>" button and <b>selecting</b> the necessary files on your PC.
</span>
<span class="portal-descr">Please do NOT use this integration example on your own server without proper code modifications, it is intended for testing purposes only. In case you enabled this test example, disable it before going for production.</span>
<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())
{ %>
@ -181,14 +166,15 @@
<tbody>
<% foreach (var storedFile in storedFiles)
{
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
var directUrlParam = GetDirectUrlParam();
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name) + directUrlParam;
var ext = Path.GetExtension(storedFile.Name).ToLower();
var docType = DocumentType(storedFile.Name);
var canEdit = EditedExts.Contains(ext);
var isFillFormDoc = FillFormsExts.Contains(ext);
%>
<tr class="tableRow" title="<%= storedFile.Name %> [<%= GetFileVersion(storedFile.Name, HttpContext.Current.Request.UserHostAddress) %>]">
<tr class="tableRow" title="<%= storedFile.Name %> [<%= GetFileVersion(storedFile.Name, HttpContext.Current.Request.UserHostAddress.Replace(':','_')) %>]">
<td class="contentCells">
<a class="stored-edit <%= docType %>" href="<%= editUrl %>" target="_blank">
<span><%= storedFile.Name %></span>
@ -223,9 +209,6 @@
</a>
</td>
<% } %>
<%if (docType != "word" && docType != "cell") { %>
<td class="contentCells contentCells-icon contentCellsEmpty"></td>
<% } %>
<% if (docType == "word") { %>
<td class="contentCells contentCells-icon">
<a href="<%= editUrl + "&editorsType=desktop&editorsMode=blockcontent" %>" target="_blank">
@ -329,10 +312,8 @@
<span class="step-descr">They are loaded only once, they will be cached on your computer.</span>
<input type="hidden" name="hiddenFileName" id="hiddenFileName" />
<br />
<br />
<span class="progress-descr">Note the speed of all operations depends on your connection quality and server location.</span>
<br />
<br />
<div class="error-message">
<b>Upload error: </b><span></span>
<br />
@ -341,10 +322,12 @@
</div>
<iframe id="embeddedView" src="" height="345px" width="432px" frameborder="0" scrolling="no" allowtransparency></iframe>
<br />
<div id="beginEdit" class="button orange disable">Edit</div>
<div id="beginView" class="button gray disable">View</div>
<div id="beginEmbedded" class="button gray disable">Embedded view</div>
<div id="cancelEdit" class="button gray">Cancel</div>
<div class="buttonsMobile">
<div id="beginEdit" class="button orange disable">Edit</div>
<div id="beginView" class="button gray disable">View</div>
<div id="beginEmbedded" class="button gray disable">Embedded view</div>
<div id="cancelEdit" class="button gray">Cancel</div>
</div>
</div>
<span id="loadScripts" data-docs="<%= UrlPreloadScripts %>"></span>

View File

@ -35,7 +35,7 @@ namespace OnlineEditorsExample
// the spreadsheet extension list
public static readonly List<string> ExtsSpreadsheet = new List<string>
{
".xls", ".xlsx", ".xlsm",
".xls", ".xlsx", ".xlsm", ".xlsb",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv"
};
@ -78,7 +78,9 @@ namespace OnlineEditorsExample
{
get
{
return
return Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ?
WebConfigurationManager.AppSettings["storage-path"] + "/"
:
HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ WebConfigurationManager.AppSettings["storage-path"]
@ -144,18 +146,52 @@ namespace OnlineEditorsExample
// get the storage path of the given file
public static string StoragePath(string fileName, string userAddress)
{
var directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
var directory = "";
if (Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
}
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory); // if the file directory doesn't exist, make it
}
return directory + Path.GetFileName(fileName);
return directory + (fileName.Contains("\\") ? fileName : Path.GetFileName(fileName));
}
// get the path to the history file version
public static string HistoryPath(string fileName, string userAddress, string version, string file)
{
var directory = "";
if (Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
}
var filepath = directory + Path.GetFileName(fileName) + "-hist" + "\\" + version + "\\" + file;
return filepath;
}
// get the path to the forcesaved file version
public static string ForcesavePath(string fileName, string userAddress, Boolean create)
{
var directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
var directory = "";
if (Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(userAddress) + "\\";
}
if (!Directory.Exists(directory)) // the directory with host address doesn't exist
{
return "";
@ -317,11 +353,7 @@ namespace OnlineEditorsExample
try
{
// hack. http://ubuntuforums.org/showthread.php?t=1841740
if (IsMono)
{
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
}
VerifySSL();
using (var stream = req.GetResponse().GetResponseStream()) // get response stream of the uploading file
{
@ -384,11 +416,7 @@ namespace OnlineEditorsExample
var req = (HttpWebRequest)WebRequest.Create(fileUrl);
// hack. http://ubuntuforums.org/showthread.php?t=1841740
if (IsMono)
{
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
}
VerifySSL();
using (var stream = req.GetResponse().GetResponseStream())
{
@ -457,7 +485,7 @@ namespace OnlineEditorsExample
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "webeditor.ashx";
fileUrl.Query = "type=download&fileName=" + HttpUtility.UrlEncode(_fileName)
+ "&userAddress=" + HttpUtility.UrlEncode(HttpContext.Current.Request.UserHostAddress);
+ "&userAddress=" + HttpUtility.UrlEncode(CurUserHostAddress(HttpContext.Current.Request.UserHostAddress));
// get the url to the converted file
string newFileUri;
@ -472,11 +500,7 @@ namespace OnlineEditorsExample
var req = (HttpWebRequest)WebRequest.Create(newFileUri);
// hack. http://ubuntuforums.org/showthread.php?t=1841740
if (IsMono)
{
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
}
VerifySSL();
using (var stream = req.GetResponse().GetResponseStream()) // get response stream of the converting file
{
@ -528,7 +552,16 @@ namespace OnlineEditorsExample
// get all the stored files from the folder
protected static List<FileInfo> GetStoredFiles()
{
var directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(null) + "\\";
var directory = "";
if (Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]))
{
directory = WebConfigurationManager.AppSettings["storage-path"] + "\\";
}
else
{
directory = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"] + CurUserHostAddress(null) + "\\";
}
if (!Directory.Exists(directory)) return new List<FileInfo>();
var directoryInfo = new DirectoryInfo(directory); // read the user host directory contents
@ -571,5 +604,33 @@ namespace OnlineEditorsExample
return files;
}
// enable certificate ignore
public static void VerifySSL()
{
// hack. http://ubuntuforums.org/showthread.php?t=1841740
if(WebConfigurationManager.AppSettings["files.docservice.verify-peer-off"].Equals("true")) {
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
}
}
public static Dictionary<string, string> GetLanguages()
{
var languages = new Dictionary<string, string>();
String[] couples = (WebConfigurationManager.AppSettings["files.docservice.languages"] ?? "").Split('|');
foreach (string couple in couples)
{
String[] tmp = couple.Split(':');
languages.Add(tmp[0],tmp[1]);
}
return languages;
}
public static string GetDirectUrlParam()
{
string isEnabledDirectUrl = HttpUtility.ParseQueryString(HttpContext.Current.Request.Url.Query).Get("directUrl");
return "&directUrl=" + (isEnabledDirectUrl != null ? isEnabledDirectUrl : "false");
}
}
}

View File

@ -64,6 +64,7 @@
<script type="text/javascript" language="javascript">
var docEditor;
var config;
var innerAlert = function (message, inEditor) {
if (console && console.log)
@ -125,10 +126,14 @@
// the meta information of the document is changed via the meta command
var onMetaChange = function (event) {
var favorite = !!event.data.favorite;
var title = document.title.replace(/^\☆/g, "");
document.title = (favorite ? "☆" : "") + title;
docEditor.setFavorite(favorite); // change the Favorite icon state
if (event.data.favorite) {
var favorite = !!event.data.favorite;
var title = document.title.replace(/^\☆/g, "");
document.title = (favorite ? "☆" : "") + title;
docEditor.setFavorite(favorite); // change the Favorite icon state
}
innerAlert("onMetaChange: " + JSON.stringify(event.data));
};
// the user is trying to insert an image by clicking the Image from Storage button
@ -158,7 +163,7 @@
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "webeditor.ashx?type=saveas");
xhr.setRequestHeader( 'Content-Type', 'application/json');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
xhr.onload = function () {
innerAlert(xhr.responseText);
@ -166,7 +171,26 @@
}
};
var config = <%= DocConfig %>;
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
innerAlert("onRequestRename: " + JSON.stringify(event.data));
var newfilename = event.data;
var data = {
newfilename: newfilename,
dockey: config.document.key,
ext: config.document.fileType
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "webeditor.ashx?type=rename");
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
xhr.onload = function () {
innerAlert(xhr.responseText);
}
};
config = <%= DocConfig %>;
config.width = "100%";
config.height = "100%";
@ -184,37 +208,42 @@
"onRequestMailMergeRecipients": onRequestMailMergeRecipients,
};
<% if (!string.IsNullOrEmpty(History) && !string.IsNullOrEmpty(HistoryData))
{ %>
config.events['onRequestHistory'] = function () { // the user is trying to show the document version history
docEditor.refreshHistory(<%= History %>); // show the document version history
};
config.events['onRequestHistoryData'] = function (event) { // the user is trying to click the specific document version in the document version history
var ver = event.data;
var histData = <%= HistoryData %>;
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
};
config.events['onRequestHistoryClose '] = function () { // the user is trying to go back to the document from viewing the document version history
document.location.reload();
};
<% } %>
if (config.editorConfig.user.id) {
<% if (!string.IsNullOrEmpty(History) && !string.IsNullOrEmpty(HistoryData))
{ %>
config.events['onRequestHistory'] = function () { // the user is trying to show the document version history
docEditor.refreshHistory(<%= History %>); // show the document version history
};
config.events['onRequestHistoryData'] = function (event) { // the user is trying to click the specific document version in the document version history
var ver = event.data;
var histData = <%= HistoryData %>;
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
};
config.events['onRequestHistoryClose '] = function () { // the user is trying to go back to the document from viewing the document version history
document.location.reload();
};
<% } %>
// add mentions for not anonymous users
<% if (!string.IsNullOrEmpty(UsersForMentions))
{ %>
config.events['onRequestUsers'] = function () {
docEditor.setUsers({ // set a list of users to mention in the comments
"users": <%= UsersForMentions %>
});
};
<% } %>
// the user is mentioned in a comment
config.events['onRequestSendNotify'] = function (event) {
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
var data = JSON.stringify(event.data);
innerAlert("onRequestSendNotify: " + data);
};
// prevent file renaming for anonymous users
config.events['onRequestRename'] = onRequestRename;
}
<% if (!string.IsNullOrEmpty(UsersForMentions))
{ %>
// add mentions for not anonymous users
config.events['onRequestUsers'] = function () {
docEditor.setUsers({ // set a list of users to mention in the comments
"users": <%= UsersForMentions %>
});
};
// the user is mentioned in a comment
config.events['onRequestSendNotify'] = function (event) {
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
var data = JSON.stringify(event.data);
innerAlert("onRequestSendNotify: " + data);
};
<% } %>
if (config.editorConfig.createUrl) {
config.events.onRequestSaveAs = onRequestSaveAs;
};

134
web/documentserver-example/csharp/DocEditor.aspx.cs Normal file → Executable file
View File

@ -41,7 +41,7 @@ namespace OnlineEditorsExample
// get url to the original file for Document Server
public static string FileUriUser
{
get { return _Default.FileUri(FileName, false); }
get { return Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ? getDownloadUrl(FileName) + "&dmode=emb" : _Default.FileUri(FileName, false); }
}
protected string Key
@ -81,7 +81,7 @@ namespace OnlineEditorsExample
+ "webeditor.ashx";
callbackUrl.Query = "type=track"
+ "&fileName=" + HttpUtility.UrlEncode(FileName)
+ "&userAddress=" + HttpUtility.UrlEncode(HttpContext.Current.Request.UserHostAddress);
+ "&userAddress=" + HttpUtility.UrlEncode(_Default.CurUserHostAddress(HttpContext.Current.Request.UserHostAddress));
return callbackUrl.ToString();
}
}
@ -100,20 +100,18 @@ namespace OnlineEditorsExample
}
// get url to download a file
public static string getDownloadUrl
public static string getDownloadUrl(string fileName, Boolean isServer = true)
{
get
{
var downloadUrl = new UriBuilder(_Default.GetServerUrl(true));
var userAddress = isServer ? "&userAddress=" + HttpUtility.UrlEncode(_Default.CurUserHostAddress(HttpContext.Current.Request.UserHostAddress)) : "";
var downloadUrl = new UriBuilder(_Default.GetServerUrl(isServer));
downloadUrl.Path =
HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "webeditor.ashx";
downloadUrl.Query = "type=download"
+ "&fileName=" + HttpUtility.UrlEncode(FileName)
+ "&userAddress=" + HttpUtility.UrlEncode(HttpContext.Current.Request.UserHostAddress);
+ "&fileName=" + HttpUtility.UrlEncode(fileName)
+ userAddress;
return downloadUrl.ToString();
}
}
// loading a page
@ -168,6 +166,7 @@ namespace OnlineEditorsExample
var actionLink = Request.GetOrDefault("actionLink", null); // get the action link (comment or bookmark) if it exists
var actionData = string.IsNullOrEmpty(actionLink) ? null : jss.DeserializeObject(actionLink); // get action data for the action link
var directUrl = getDownloadUrl(FileName, false);
var createUrl = getCreateUrl(DocumentType, editorsType);
var templatesImageUrl = GetTemplateImageUrl(ext); // image url for templates
var templates = new List<Dictionary<string, string>>
@ -195,7 +194,8 @@ namespace OnlineEditorsExample
"document", new Dictionary<string, object>
{
{ "title", FileName },
{ "url", getDownloadUrl },
{ "url", getDownloadUrl(FileName) },
{ "directUrl", IsEnabledDirectUrl() ? directUrl : "" },
{ "fileType", ext.Trim('.') },
{ "key", Key },
{
@ -219,8 +219,10 @@ namespace OnlineEditorsExample
{ "modifyFilter", editorsMode != "filter" },
{ "modifyContentControl", editorsMode != "blockcontent" },
{ "review", canEdit && (editorsMode == "edit" || editorsMode == "review") },
{ "chat", !user.id.Equals("uid-0") },
{ "reviewGroups", user.reviewGroups },
{ "commentGroups", user.commentGroups }
{ "commentGroups", user.commentGroups },
{ "userInfoGroups", user.userInfoGroups }
}
}
}
@ -232,13 +234,18 @@ namespace OnlineEditorsExample
{ "mode", mode },
{ "lang", Request.Cookies.GetOrDefault("ulang", "en") },
{ "callbackUrl", CallbackUrl }, // absolute URL to the document storage service
{ "coEditing", editorsMode == "view" && user.id.Equals("uid-0") ?
new Dictionary<string, object>{
{"mode", "strict"},
{"change", false}
} : null },
{ "createUrl", !user.id.Equals("uid-0") ? createUrl : null },
{ "templates", user.templates ? templates : null },
{
// the user currently viewing or editing the document
"user", new Dictionary<string, object>
{
{ "id", user.id },
{ "id", !user.id.Equals("uid-0") ? user.id : null },
{ "name", user.name },
{ "group", user.group }
}
@ -247,9 +254,9 @@ namespace OnlineEditorsExample
// the parameters for the embedded document type
"embedded", new Dictionary<string, object>
{
{ "saveUrl", FileUriUser }, // the absolute URL that will allow the document to be saved onto the user personal computer
{ "embedUrl", FileUriUser }, // the absolute URL to the document serving as a source file for the document embedded into the web page
{ "shareUrl", FileUriUser }, // the absolute URL that will allow other users to share this document
{ "saveUrl", directUrl }, // the absolute URL that will allow the document to be saved onto the user personal computer
{ "embedUrl", directUrl }, // the absolute URL to the document serving as a source file for the document embedded into the web page
{ "shareUrl", directUrl }, // the absolute URL that will allow other users to share this document
{ "toolbarDocked", "top" } // the place for the embedded viewer toolbar (top or bottom)
}
},
@ -258,6 +265,7 @@ namespace OnlineEditorsExample
"customization", new Dictionary<string, object>
{
{ "about", true }, // the About section display
{ "comments", true },
{ "feedback", true }, // the Feedback & Support menu button display
{ "forcesave", false }, // adds the request for the forced file saving to the callback handler
{ "submitForm", submitForm }, // if the Submit form button is displayed or not
@ -318,6 +326,7 @@ namespace OnlineEditorsExample
// get the document history
private void GetHistory(out Dictionary<string, object> history, out Dictionary<string, object> historyData)
{
var storagePath = WebConfigurationManager.AppSettings["storage-path"];
var jss = new JavaScriptSerializer();
var histDir = _Default.HistoryDir(_Default.StoragePath(FileName, null));
@ -355,8 +364,25 @@ namespace OnlineEditorsExample
}
}
var ext = Path.GetExtension(FileName).ToLower();
dataObj.Add("fileType", ext.Replace(".", ""));
dataObj.Add("key", key);
dataObj.Add("url", i == currentVersion ? FileUri : MakePublicUrl(Directory.GetFiles(verDir, "prev.*")[0])); // write file url to the data object
// write file url to the data object
var directPrevFileUrl = i == currentVersion ? _Default.FileUri(FileName, false) : MakePublicHistoryUrl(FileName, i.ToString(), "prev" + ext, false);
var prevFileUrl = i == currentVersion ? FileUri : MakePublicHistoryUrl(FileName, i.ToString(), "prev" + ext);
if (Path.IsPathRooted(storagePath))
{
prevFileUrl = i == currentVersion ? getDownloadUrl(FileName) : getDownloadUrl(Directory.GetFiles(verDir, "prev.*")[0].Replace(storagePath + "\\", ""));
directPrevFileUrl = i == currentVersion ? getDownloadUrl(FileName, false) : getDownloadUrl(Directory.GetFiles(verDir, "prev.*")[0].Replace(storagePath + "\\", ""), false);
}
dataObj.Add("url", prevFileUrl); // write file url to the data object
if (IsEnabledDirectUrl())
{
dataObj.Add("directUrl", directPrevFileUrl); // write direct url to the data object
}
dataObj.Add("version", i);
if (i > 1) // check if the version number is greater than 1 (the file was modified)
{
@ -374,12 +400,22 @@ namespace OnlineEditorsExample
obj.Add("user", change.Count > 0 ? change["user"] : null);
var prev = (Dictionary<string, object>)histData[(i - 2).ToString()]; // get the history data from the previous file version
dataObj.Add("previous", new Dictionary<string, object>() { // write information about previous file version to the data object
Dictionary<string, object> dataPrev = new Dictionary<string, object>() { // write information about previous file version to the data object
{ "fileType", prev["fileType"] },
{ "key", prev["key"] }, // write key and url information about previous file version
{ "url", prev["url"] },
});
{ "url", prev["url"] }
};
if (IsEnabledDirectUrl())
{
dataPrev.Add("directUrl", prev["directUrl"]);
}
dataObj.Add("previous", dataPrev);
// write the path to the diff.zip archive with differences in this file version
dataObj.Add("changesUrl", MakePublicUrl(Path.Combine(_Default.VersionDir(histDir, i - 1), "diff.zip")));
var changesUrl = MakePublicHistoryUrl(FileName, (i - 1).ToString(), "diff.zip");
dataObj.Add("changesUrl", changesUrl);
}
if (JwtManager.Enabled)
{
@ -409,6 +445,11 @@ namespace OnlineEditorsExample
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "App_Themes\\images\\logo.png";
var DirectImageUrl = new UriBuilder(_Default.GetServerUrl(false));
DirectImageUrl.Path = HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "App_Themes\\images\\logo.png";
// create a logo config
Dictionary<string, object> logoConfig = new Dictionary<string, object>
{
@ -416,6 +457,11 @@ namespace OnlineEditorsExample
{ "url", InsertImageUrl.ToString()}
};
if (IsEnabledDirectUrl())
{
logoConfig.Add("directUrl", DirectImageUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var insImageToken = JwtManager.Encode(logoConfig); // encode logoConfig into the token
@ -435,6 +481,12 @@ namespace OnlineEditorsExample
+ "webeditor.ashx";
compareFileUrl.Query = "type=assets&fileName=" + HttpUtility.UrlEncode("sample.docx");
var DirectFileUrl = new UriBuilder(_Default.GetServerUrl(false));
DirectFileUrl.Path = HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "webeditor.ashx";
DirectFileUrl.Query = "type=assets&fileName=" + HttpUtility.UrlEncode("sample.docx");
// create an object with the information about the compared file
Dictionary<string, object> dataCompareFile = new Dictionary<string, object>
{
@ -442,6 +494,11 @@ namespace OnlineEditorsExample
{ "url", compareFileUrl.ToString() }
};
if (IsEnabledDirectUrl())
{
dataCompareFile.Add("directUrl", DirectFileUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var compareFileToken = JwtManager.Encode(dataCompareFile); // encode the dataCompareFile object into the token
@ -462,6 +519,13 @@ namespace OnlineEditorsExample
+ "webeditor.ashx";
mailmergeUrl.Query = "type=csv";
var DirectMailMergeUrl = new UriBuilder(_Default.GetServerUrl(false));
DirectMailMergeUrl.Path =
HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "webeditor.ashx";
DirectMailMergeUrl.Query = "type=csv";
// create a mail merge config
Dictionary<string, object> mailMergeConfig = new Dictionary<string, object>
{
@ -469,6 +533,11 @@ namespace OnlineEditorsExample
{ "url", mailmergeUrl.ToString() }
};
if (IsEnabledDirectUrl())
{
mailMergeConfig.Add("directUrl", DirectMailMergeUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var mailmergeToken = JwtManager.Encode(mailMergeConfig); // encode mailMergeConfig into the token
@ -503,10 +572,26 @@ namespace OnlineEditorsExample
// create the public url
private string MakePublicUrl(string fullPath)
{
var root = HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"];
var root = Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ? WebConfigurationManager.AppSettings["storage-path"]
: HttpRuntime.AppDomainAppPath + WebConfigurationManager.AppSettings["storage-path"];
return _Default.GetServerUrl(true) + fullPath.Substring(root.Length).Replace(Path.DirectorySeparatorChar, '/');
}
// create the public history url
private string MakePublicHistoryUrl(string filename, string version, string file, Boolean isServer = true)
{
var userAddress = isServer ? "&userAddress=" + HttpUtility.UrlEncode(_Default.CurUserHostAddress(HttpContext.Current.Request.UserHostAddress)) : "";
var fileUrl = new UriBuilder(_Default.GetServerUrl(isServer));
fileUrl.Path = HttpRuntime.AppDomainAppVirtualPath
+ (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
+ "webeditor.ashx";
fileUrl.Query = "type=downloadhistory&fileName=" + HttpUtility.UrlEncode(filename)
+ "&ver=" + version + "&file=" + file
+ userAddress;
return fileUrl.ToString();
}
// create demo document
private static void Try(string type, string sample, HttpRequest request)
{
@ -554,5 +639,12 @@ namespace OnlineEditorsExample
{ "name", uname }
}));
}
// get direct url flag
private static bool IsEnabledDirectUrl()
{
string isEnabledDirectUrl = HttpUtility.ParseQueryString(HttpContext.Current.Request.Url.Query).Get("directUrl");
return isEnabledDirectUrl != null ? Convert.ToBoolean(isEnabledDirectUrl) : false;
}
}
}

View File

@ -145,11 +145,7 @@ namespace ASC.Api.DocumentConverter
requestStream.Write(bytes, 0, bytes.Length); // and write the serialized body object to it
}
// hack. http://ubuntuforums.org/showthread.php?t=1841740
if (_Default.IsMono)
{
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
}
_Default.VerifySSL();
string dataResponse;
using (var response = request.GetResponse())

View File

@ -16,12 +16,12 @@
*
*/
using System;
using JWT;
using JWT.Algorithms;
using JWT.Builder;
using JWT.Serializers;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Web.Configuration;
using System.Web.Script.Serialization;
namespace OnlineEditorsExample
{
@ -30,31 +30,19 @@ namespace OnlineEditorsExample
private static readonly string Secret;
public static readonly bool Enabled;
private static readonly JavaScriptSerializer Serializer;
static JwtManager()
{
Secret = WebConfigurationManager.AppSettings["files.docservice.secret"] ?? ""; // get token secret from the config parameters
Enabled = !string.IsNullOrEmpty(Secret); // check if the token is enabled
Serializer = new JavaScriptSerializer(); // define java script serializer
}
// encode a payload object into a token using a secret key
public static string Encode(IDictionary<string, object> payload)
{
// define the hashing algorithm and the token type
var header = new Dictionary<string, object>
{
{ "alg", "HS256" },
{ "typ", "JWT" }
};
// three parts of token
var encHeader = Base64UrlEncode(Serializer.Serialize(header)); // header
var encPayload = Base64UrlEncode(Serializer.Serialize(payload)); // payload
var hashSum = Base64UrlEncode(CalculateHash(encHeader, encPayload)); // signature
return string.Format("{0}.{1}.{2}", encHeader, encPayload, hashSum);
var encoder = new JwtEncoder(new HMACSHA256Algorithm(),
new JsonNetSerializer(),
new JwtBase64UrlEncoder());
return encoder.Encode(payload, Secret);
}
// decode a token into a payload object using a secret key
@ -62,52 +50,11 @@ namespace OnlineEditorsExample
{
if (!Enabled || string.IsNullOrEmpty(token)) return "";
var split = token.Split('.');
if (split.Length != 3) return "";
var hashSum = Base64UrlEncode(CalculateHash(split[0], split[1])); // get signature
if (hashSum != split[2]) return ""; // and check if it is equal to the signature from the token
return Base64UrlDecode(split[1]); // decode payload
}
// generate a hash code based on a key using the HMAC method
private static byte[] CalculateHash(string encHeader, string encPayload)
{
using (var hasher = new HMACSHA256(Encoding.UTF8.GetBytes(Secret)))
{
var bytes = Encoding.UTF8.GetBytes(string.Format("{0}.{1}", encHeader, encPayload));
return hasher.ComputeHash(bytes);
}
}
// encode a string into the base64 value
private static string Base64UrlEncode(string str)
{
return Base64UrlEncode(Encoding.UTF8.GetBytes(str));
}
// encode bytes into the base64 value
private static string Base64UrlEncode(byte[] bytes)
{
return Convert.ToBase64String(bytes)
.TrimEnd('=').Replace('+', '-').Replace('/', '_');
}
// decode a base64 value into the string
private static string Base64UrlDecode(string payload)
{
var b64 = payload.Replace('_', '/').Replace('-', '+');
switch (b64.Length%4)
{
case 2:
b64 += "==";
break;
case 3:
b64 += "=";
break;
}
var bytes = Convert.FromBase64String(b64);
return Encoding.UTF8.GetString(bytes);
return JwtBuilder.Create()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(Secret)
.MustVerifySignature()
.Decode(token);
}
}
}

View File

@ -11,7 +11,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OnlineEditorsExample</RootNamespace>
<AssemblyName>OnlineEditorsExample</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
@ -23,6 +23,8 @@
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<TargetFrameworkProfile />
<Use64BitIISExpress />
<UseGlobalApplicationHostFile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -44,27 +46,33 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="JWT, Version=9.0.0.0, Culture=neutral, PublicKeyToken=6f98bca0f40f2ecf, processorArchitecture=MSIL">
<HintPath>packages\JWT.9.0.3\lib\net46\JWT.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Web.Infrastructure">
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Helpers">
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor">
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.Services" />
<Reference Include="System.Web.WebPages">
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment">
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor">
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
</ItemGroup>
@ -153,10 +161,12 @@
<Content Include="assets\AUTHORS.md" />
<Content Include="assets\LICENSE" />
<Content Include="assets\new\new.docx" />
<Content Include="assets\new\new.docxf" />
<Content Include="assets\new\new.pptx" />
<Content Include="assets\new\new.xlsx" />
<Content Include="assets\sample\csv.csv" />
<Content Include="assets\sample\sample.docx" />
<Content Include="assets\sample\sample.docxf" />
<Content Include="assets\sample\sample.pptx" />
<Content Include="assets\sample\sample.xlsx" />
<None Include="packages.config" />

View File

@ -2,11 +2,11 @@
This example will help you integrate ONLYOFFICE Docs into your web application written in .Net (C#).
It is aimed at testing the editors. Please, do not use it for production without proper modifications.
**Please note**: It is intended for testing purposes and demonstrating functionality of the editors. Do NOT use this integration example on your own server without proper code modifications! In case you enabled the test example, disable it before going for production.
## Step 1. Install ONLYOFFICE Docs
Download and install ONLYOFFICE Docs (packaged as Document Server).
Download and install ONLYOFFICE Docs (packaged as Document Server).
See the detailed guide to learn how to install Document Server [for Windows](https://helpcenter.onlyoffice.com/installation/docs-developer-install-windows.aspx), [for Linux](https://helpcenter.onlyoffice.com/installation/docs-developer-install-ubuntu.aspx), or [for Docker](https://helpcenter.onlyoffice.com/server/developer-edition/docker/docker-installation.aspx).
@ -14,11 +14,12 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
Download the [.Net (C#) example](https://api.onlyoffice.com/editors/demopreview) from our site.
Connect the editors to your website by specifying the path to the editors installation in the *settings.config* file:
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *settings.config* file:
```
<add key="storage-path" value=""/>
<add key="files.docservice.url.site" value="https://documentserver/" />
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-path** is the path where files will be created and stored. You can set an absolute path.
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) in the *DocEditor.aspx* file.
@ -28,13 +29,23 @@ Check that your system meets the requirements:
* **Microsoft .NET Framework**: version 4.5 (download it from the [official Microsoft website](https://www.microsoft.com/en-US/download/details.aspx?id=30653));
* **Internet Information Services**: version 7 or later.
Configure the IIS components for the server to work correctly:
1. Open Windows features:
**Start** -> **Control Panel** -> **Programs** -> **Programs and Features** -> **Turn Windows features on or off**
2. In the opened window, find **Internet Information Services** and choose all the necessary features. To do this, open the **World Wide Web Services** list and check the following components:
* **Application Development Features**: .NET Extensibility 4.8, ASP.NET 4.8, ISAPI Extensions, ISAPI Filters,
* **Common HTTP Features**: Default Document,
* **Security**: Request Filtering.
## Step 4. Run your website with the editors
1. Run the Internet Information Service (IIS) Manager:
**Start** -> **Control Panel** -> **System and Security** -> **Administrative Tools** -> **Internet Information Services (IIS) Manager**
2. Add your website in the IIS Manager.
On the **Connections** panel right-click the **Sites** node in the tree, then click **Add Website**.
![add](screenshots/add.png)
@ -46,7 +57,7 @@ Check that your system meets the requirements:
![sitename](screenshots/sitename.png)
4. Check for the .NET platform version specified in IIS Manager for you website. Choose **v4.0.** version.
**Application Pools** -> right-click the platform name -> **Set application Pool defaults** -> **.NET CLR version**
![platform](screenshots/platform.png)
@ -61,3 +72,12 @@ Check that your system meets the requirements:
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
Make sure that the Document Server in its turn has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
## Important security info
Please keep in mind the following security aspects when you are using test examples:
* There is no protection of the storage from unauthorized access since there is no need for authorization.
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.

View File

@ -78,7 +78,9 @@ namespace OnlineEditorsExample
if (token != null && !token.Equals("")) // invalid signature error
{
fileData = (Dictionary<string, object>)jss.Deserialize<Dictionary<string, object>>(token)["payload"];
fileData = jss.Deserialize<Dictionary<string, object>>(token);
if (fileData.ContainsKey("payload"))
fileData = (Dictionary<string, object>)fileData["payload"];
}
else
{
@ -97,7 +99,11 @@ namespace OnlineEditorsExample
}
var downloadUri = (string)fileData["url"];
var curExt = Path.GetExtension(fileName).ToLower(); // get current file extension
var downloadExt = Path.GetExtension(downloadUri).ToLower() ?? ""; // get the extension of the downloaded file
var downloadExt = fileData.ContainsKey("filetype")
? "." + (string)fileData["filetype"]
: Path.GetExtension(downloadUri).ToLower() ?? ""; // TODO: Delete in version 7.0 or higher. Support for versions below 7.0
var newFileName = fileName;
// convert downloaded file to the file with the current extension if these extensions aren't equal
@ -124,11 +130,7 @@ namespace OnlineEditorsExample
}
}
// hack. http://ubuntuforums.org/showthread.php?t=1841740
if (_Default.IsMono)
{
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
}
_Default.VerifySSL();
var storagePath = _Default.StoragePath(newFileName, userAddress); // get the file path
var histDir = _Default.HistoryDir(storagePath); // get the path to the history directory
@ -175,7 +177,11 @@ namespace OnlineEditorsExample
var downloadUri = (string)fileData["url"];
string curExt = Path.GetExtension(fileName).ToLower(); // get current file extension
string downloadExt = Path.GetExtension(downloadUri).ToLower(); // get the extension of the downloaded file
var downloadExt = fileData.ContainsKey("filetype")
? "." + (string)fileData["filetype"]
: Path.GetExtension(downloadUri).ToLower(); // TODO: Delete in version 7.0 or higher. Support for versions below 7.0
Boolean newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal
@ -201,11 +207,7 @@ namespace OnlineEditorsExample
}
}
// hack. http://ubuntuforums.org/showthread.php?t=1841740
if (_Default.IsMono)
{
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
}
_Default.VerifySSL();
string forcesavePath = "";
Boolean isSubmitForm = fileData["forcesavetype"].ToString().Equals("3"); // SubmitForm
@ -250,8 +252,10 @@ namespace OnlineEditorsExample
}
// create a command request
public static void commandRequest(string method, string key)
public static void commandRequest(string method, string key, object meta = null)
{
_Default.VerifySSL();
string documentCommandUrl = WebConfigurationManager.AppSettings["files.docservice.url.site"] + WebConfigurationManager.AppSettings["files.docservice.url.command"];
var request = (HttpWebRequest)WebRequest.Create(documentCommandUrl);
@ -263,13 +267,18 @@ namespace OnlineEditorsExample
{ "key", key }
};
if (meta != null)
{
body.Add("meta", meta);
}
// check if a secret key to generate token exists or not
if (JwtManager.Enabled)
{
var payload = new Dictionary<string, object>
{
{ "payload", body }
};
{
{ "payload", body }
};
var payloadToken = JwtManager.Encode(payload); // encode a payload object into a header token
var bodyToken = JwtManager.Encode(body); // encode body into a body token
@ -315,6 +324,7 @@ namespace OnlineEditorsExample
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path"); // file isn't specified
var req = (HttpWebRequest)WebRequest.Create(url);
req.Timeout = 5000;
using (var stream = req.GetResponse().GetResponseStream()) // get input stream of the file information from the url
{
if (stream == null) throw new Exception("stream is null");

View File

@ -29,7 +29,8 @@ namespace OnlineEditorsExample
"Can review all the changes",
"Can perform all actions with comments",
"The file favorite state is undefined",
"Can create files from templates using data from the editor"
"Can create files from templates using data from the editor",
"Can see the information about all users"
};
static List<string> descr_user_2 = new List<string>()
@ -38,19 +39,21 @@ namespace OnlineEditorsExample
"Can review only his own changes or changes made by users with no group",
"Can view comments, edit his own comments and comments left by users with no group. Can remove his own comments only",
"This file is marked as favorite",
"Can create new files from the editor"
"Can create new files from the editor",
"Can see the information about users from Group2 and users who dont belong to any group"
};
static List<string> descr_user_3 = new List<string>()
{
"Belongs to Group3",
"Can review changes made by Group2 users",
"Can view comments left by Group2 and Group3 users. Can edit comments left by Group2 users",
"Can view comments left by Group2 and Group3 users. Can edit comments left by the Group2 users",
"This file isnt marked as favorite",
"Cant copy data from the file to clipboard",
"Cant download the file",
"Cant print the file",
"Can create new files from the editor"
"Can create new files from the editor",
"Can see the information about Group2 users"
};
static List<string> descr_user_0 = new List<string>()
@ -61,7 +64,11 @@ namespace OnlineEditorsExample
"Can perform all actions with comments",
"The file favorite state is undefined",
"Can't mention others in comments",
"Can't create new files from the editor"
"Can't create new files from the editor",
"Cant see anyones information",
"Can't rename files from the editor",
"Can't view chat",
"View file without collaboration",
};
private static List<User> users = new List<User>() {
@ -69,10 +76,11 @@ namespace OnlineEditorsExample
"uid-1",
"John Smith",
"smith@example.com",
null,
"",
null,
new Dictionary<string, object>(),
null,
null,
new List<string>(),
descr_user_1,
true
@ -89,6 +97,7 @@ namespace OnlineEditorsExample
{ "edit", new List<string>() { "group-2", "" } },
{ "remove", new List<string>() { "group-2" } }
},
new List<string>() { "group-2", "" },
true,
new List<string>(),
descr_user_2,
@ -106,6 +115,7 @@ namespace OnlineEditorsExample
{ "edit", new List<string>() { "group-2" } },
{ "remove", new List<string>() { } }
},
new List<string>() { "group-2" },
false,
new List<string>() { "copy", "download", "print" },
descr_user_3,
@ -115,9 +125,10 @@ namespace OnlineEditorsExample
"uid-0",
null,
null,
null,
"",
null,
new Dictionary<string, object>(),
new List<string>(),
null,
new List<string>(),
descr_user_0,
@ -173,8 +184,9 @@ namespace OnlineEditorsExample
public List<string> deniedPermissions;
public List<string> descriptions;
public bool templates;
public List<string> userInfoGroups;
public User(string id, string name, string email, string group, List<string> reviewGroups, Dictionary<string, object> commentGroups, bool? favorite, List<string> deniedPermissions, List<string> descriptions, bool templates)
public User(string id, string name, string email, string group, List<string> reviewGroups, Dictionary<string, object> commentGroups, List<string> userInfoGroups, bool? favorite, List<string> deniedPermissions, List<string> descriptions, bool templates)
{
this.id = id;
this.name = name;
@ -186,6 +198,7 @@ namespace OnlineEditorsExample
this.deniedPermissions = deniedPermissions;
this.descriptions = descriptions;
this.templates = templates;
this.userInfoGroups = userInfoGroups;
}
}
}

View File

@ -1,28 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings configSource="settings.config"/>
<appSettings configSource="settings.config" />
<system.web>
<httpRuntime maxRequestLength="51200"/>
<compilation debug="true" targetFramework="4.5"/>
<authentication mode="Windows"/>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
<httpRuntime maxRequestLength="51200" />
<compilation debug="true" targetFramework="4.5" />
<authentication mode="Windows" />
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="52428800"/>
<requestLimits maxAllowedContentLength="52428800" />
<denyUrlSequences>
<add sequence=".."/>
<add sequence=".." />
</denyUrlSequences>
<hiddenSegments>
<remove segment="App_Data"/>
<remove segment="App_Data" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -44,6 +44,9 @@ namespace OnlineEditorsExample
case "download":
Download(context);
break;
case "downloadhistory":
DownloadHistory(context);
break;
case "convert":
Convert(context);
break;
@ -65,6 +68,9 @@ namespace OnlineEditorsExample
case "saveas":
SaveAs(context);
break;
case "rename":
Rename(context);
break;
}
}
@ -135,7 +141,7 @@ namespace OnlineEditorsExample
var userAddress = context.Request["userAddress"];
var fileName = Path.GetFileName(context.Request["fileName"]);
var status = (TrackerStatus) (int) fileData["status"]; // get status from the request body
var saved = 1; // editing
var saved = 0;
switch (status)
{
case TrackerStatus.Editing:
@ -191,7 +197,7 @@ namespace OnlineEditorsExample
context.Response.Write("{\"error\":" + saved + "}");
return;
}
context.Response.Write("{\"error\":0}");
context.Response.Write("{\"error\":" + saved + "}");
}
// remove a file
@ -201,7 +207,7 @@ namespace OnlineEditorsExample
try
{
var fileName = Path.GetFileName(context.Request["fileName"]);
var path = _Default.StoragePath(fileName, HttpUtility.UrlEncode(HttpContext.Current.Request.UserHostAddress));
var path = _Default.StoragePath(fileName, HttpUtility.UrlEncode(_Default.CurUserHostAddress(HttpContext.Current.Request.UserHostAddress)));
var histDir = _Default.HistoryDir(path);
if (File.Exists(path)) File.Delete(path); // delete file
@ -271,10 +277,11 @@ namespace OnlineEditorsExample
{
try
{
var fileName = Path.GetFileName(context.Request["fileName"]);
var fileName = Path.IsPathRooted(WebConfigurationManager.AppSettings["storage-path"]) ? context.Request["fileName"] : Path.GetFileName(context.Request["fileName"]);
var userAddress = Path.GetFileName(context.Request["userAddress"]);
var isEmbedded = context.Request["dmode"];
if (JwtManager.Enabled)
if (JwtManager.Enabled && isEmbedded == null)
{
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
@ -321,5 +328,86 @@ namespace OnlineEditorsExample
{
get { return false; }
}
private static void DownloadHistory(HttpContext context)
{
try
{
var fileName = Path.GetFileName(context.Request["fileName"]);
var userAddress = Path.GetFileName(context.Request["userAddress"]);
var version = Path.GetFileName(context.Request["ver"]);
var file = Path.GetFileName(context.Request["file"]);
if (JwtManager.Enabled)
{
string JWTheader = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
if (context.Request.Headers.AllKeys.Contains(JWTheader, StringComparer.InvariantCultureIgnoreCase))
{
var headerToken = context.Request.Headers.Get(JWTheader).Substring("Bearer ".Length);
string token = JwtManager.Decode(headerToken);
if (token == null || token.Equals(""))
{
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
context.Response.Write("JWT validation failed");
return;
}
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
context.Response.Write("JWT validation failed");
return;
}
}
var filePath = _Default.HistoryPath(fileName, userAddress, version, file); // get the path to the force saved document version
download(filePath, context);
}
catch (Exception)
{
context.Response.Write("{ \"error\": \"File not found!\"}");
}
}
// rename a file
private static void Rename(HttpContext context)
{
string fileData;
try
{
using (var receiveStream = context.Request.InputStream)
using (var readStream = new StreamReader(receiveStream))
{
fileData = readStream.ReadToEnd();
if (string.IsNullOrEmpty(fileData)) return;
}
}
catch (Exception e)
{
throw new HttpException((int)HttpStatusCode.BadRequest, e.Message);
}
var jss = new JavaScriptSerializer();
var body = jss.Deserialize<Dictionary<string, object>>(fileData);
var newFileName = (string) body["newfilename"];
var docKey = (string) body["dockey"];
var origExt = '.' + (string) body["ext"];
var curExt = Path.GetExtension(newFileName).ToLower();
if (string.Compare(origExt, curExt, true) != 0)
{
newFileName += origExt;
}
var meta = new Dictionary<string, object>() {
{ "title", newFileName }
};
TrackManager.commandRequest("meta", docKey, meta);
context.Response.Write("{ \"result\": \"OK\"}");
}
}
}

View File

@ -19,3 +19,11 @@ License File: jQuery.iframe-transport.license
jQuery.UI - jQuery UI is an open source library of interface components — interactions, full-featured widgets, and animation effects — based on the stellar jQuery javascript library . Each component is built according to jQuery's event-driven architecture (find something, manipulate it) and is themeable, making it easy for developers of any skill level to integrate and extend into their own code. (https://jquery.org/license/)
License: MIT
License File: jQuery.UI.license
JWT - JWT (JSON Web Token) Implementation for .NET (Public Domain) (https://github.com/jwt-dotnet/jwt/)
License: MIT
License File: JWT.license
Newtonsoft.Json - Json.NET is a popular high-performance JSON framework for .NET (https://github.com/JamesNK/Newtonsoft.Json)
License: MIT
License File: Newtonsoft.Json.license

View File

@ -0,0 +1,21 @@
# Public Domain
Written by John Sheehan (http://john-sheehan.com)
This work is public domain.
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law.
For more information, please visit: http://creativecommons.org/publicdomain/zero/1.0/
# MIT
Copyright (c) 2019 Jwt.Net Maintainers and Contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
For more information, please visit: https://opensource.org/licenses/MIT

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2007 James Newton-King
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="JWT" version="9.0.3" targetFramework="net48" />
<package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net48" />
<package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net48" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net48" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net48" />
</packages>

View File

@ -16,11 +16,24 @@
*
*/
var directUrl;
if (typeof jQuery != "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function () {
window.location = "?directUrl=" + jq(this).prop("checked");
});
jq(function () {
jq('#fileupload').fileupload({
dataType: 'json',
@ -219,7 +232,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.aspx?fileID=" + fileId;
var url = "doceditor.aspx?fileID=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -227,7 +240,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.aspx?editorsMode=view&fileID=" + fileId;
var url = "doceditor.aspx?editorsMode=view&fileID=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -235,7 +248,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.aspx?editorsType=embedded&editorsMode=embedded&fileID=" + fileId;
var url = "doceditor.aspx?editorsType=embedded&editorsMode=embedded&fileID=" + fileId + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -288,6 +301,17 @@ if (typeof jQuery != "undefined") {
}
};
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
};
var fileList = jq("tr.tableRow");
var mouseIsOverTooltip = false;
@ -303,7 +327,7 @@ if (typeof jQuery != "undefined") {
});
}
} else {
jq(".info").mouseover(function (event) {
jq("#info").mouseover(function (event) {
if (fileList.length > 0) {
if (hideTooltipTimeout != null) {
clearTimeout(hideTooltipTimeout);

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<clear />
<add key="version" value="1.1.0"/>
<add key="version" value="1.4.0"/>
<add key="filesize-max" value="52428800"/>
<add key="storage-path" value=""/>
@ -9,10 +9,13 @@
<add key="files.docservice.fillform-docs" value=".oform|.docx"/>
<add key="files.docservice.viewed-docs" value=".pdf|.djvu|.xps|.oxps"/>
<add key="files.docservice.edited-docs" value=".docx|.xlsx|.csv|.pptx|.txt|.docxf"/>
<add key="files.docservice.convert-docs" value=".docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2"/>
<add key="files.docservice.convert-docs" value=".docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xlsb|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2"/>
<add key="files.docservice.timeout" value="120000" />
<add key="files.docservice.secret" value="" />
<add key="files.docservice.header" value="Authorization" />
<add key="files.docservice.verify-peer-off" value="true"/>
<add key="files.docservice.languages" value="en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese"/>
<add key="files.docservice.url.site" value="http://documentserver/"/>

View File

@ -1,17 +1,18 @@
## Overview
This example will help you integrate ONLYOFFICE Docs into your web application written in Java
with Spring Boot.
with Spring Boot.
Spring Boot has a lot of functionality, but its most significant features are: dependency management,
auto-configuration, and built-in servlet containers.
It is aimed at testing the editors. Please, do not use it for production without proper modifications.
**Please note**: It is intended for testing purposes and demonstrating functionality of the editors. Do NOT use this integration example on your own server without proper code modifications! In case you enabled the test example, disable it before going for production.
## For Windows
### Step 1. Install ONLYOFFICE Docs
Download and install ONLYOFFICE Docs (packaged as Document Server).
Download and install ONLYOFFICE Docs (packaged as Document Server).
See the detailed guide to learn how to install Document Server [for Windows](https://helpcenter.onlyoffice.com/installation/docs-developer-install-windows.aspx).
@ -19,16 +20,15 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
Download the [Java-Spring example](https://api.onlyoffice.com/editors/demopreview) from our site.
To connect the editors to your website, specify the path to the editors installation, server address and port in the *\src\main\resources\application.properties* file:
To connect the editors to your website, specify the path to the editors installation, server port and the path to the storage folder in the *\src\main\resources\application.properties* file:
```
server.address=address
files.storage=
server.port=port
files.docservice.url.site=https://documentserver/
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
**address** is the address of the server or comment this line to use localhost, **port** is the any available port.
where the **documentserver** is the name of the server with the ONLYOFFICE Docs installed, **port** is any available port and **files.storage** is the path where files will be created and stored (in the project folder by default). You can set an absolute path. For example, *D:\\\\folder*. Please note that on Windows OS the double backslash must be used as a separator.
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) it the *\src\main\resources\editor.html* file.
@ -65,11 +65,11 @@ To run the Java example code, install the Java version 11 appropriate for your O
```
echo %JAVA_HOME%
```
2. Set the **MAVEN_HOME** environment variable:
Unzip the downloaded archive with the maven to any directory, it will be something like this:
```
C:\apache-maven-3.8.1
```
@ -87,7 +87,7 @@ To run the Java example code, install the Java version 11 appropriate for your O
Add C:\apache-maven-3.8.1\bin to the PATH system variable:
In system variables, find PATH, clicks on the Edit... button. In “Edit environment variable” dialog, clicks on the New button and add this C:\apache-maven-3.8.1\bin
Check if the variable created successfully by **echo** command in the **Command Prompt**:
```
@ -112,8 +112,6 @@ To run the Java example code, install the Java version 11 appropriate for your O
```
http://server.address:server.port/
```
### Step 6. Check accessibility
@ -151,8 +149,8 @@ See the detailed guide to learn how to install Document Server [for Linux](https
```
git clone https://github.com/ONLYOFFICE/document-server-integration.git
```
3. Change the current directory for the project directory:
a) from archive
@ -173,13 +171,13 @@ See the detailed guide to learn how to install Document Server [for Linux](https
Edit the following lines:
```
server.address=address
files.storage=
server.port=port
files.docservice.url.site=https://documentserver/
```
Where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
**address** is the address of the server or comment this line to use localhost, **port** is the any available port.
where the **documentserver** is the name of the server with the ONLYOFFICE Docs installed, **port** is any available port and **files.storage** is the path where files will be created and stored (in the project folder by default). You can set an absolute path.
5. Install **Maven**:
@ -192,19 +190,18 @@ See the detailed guide to learn how to install Document Server [for Linux](https
```
mvn package
```
7. Start Java-Spring example:
```
./mvnw spring-boot:run
```
8. Open your browser using **server.address** and **server.port**:
```
http://server.address:server.port/
```
### Step 3. Check accessibility
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
@ -222,13 +219,12 @@ Make sure that the Document Server has access to the server with the example ins
2. Edit the following lines:
```
server.address=address
files.storage=
server.port=port
files.docservice.url.site=https://documentserver/
```
Where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
**address** is the address of the server or comment this line to use localhost, **port** is the any available port.
where the **documentserver** is the name of the server with the ONLYOFFICE Docs installed, **port** is any available port and **files.storage** is the path where files will be created and stored (in the project folder by default). You can set an absolute path.
3. Run the next command in the java example directory:
@ -236,7 +232,16 @@ Make sure that the Document Server has access to the server with the example ins
docker-compose up
```
4. Open your browser using **server.address** and **server.port**:
```
http://server.address:server.port/
```
## Important security info
Please keep in mind the following security aspects when you are using test examples:
* There is no protection of the storage from unauthorized access since there is no need for authorization.
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.

View File

@ -7,7 +7,9 @@ services:
image: maven:3.8.1
working_dir: /java-spring
volumes:
- .:/java-spring
- .:/java-spring
ports:
- 4000:4000
command: mvn clean spring-boot:run

9
web/documentserver-example/java-spring/pom.xml Executable file → Normal file
View File

@ -48,7 +48,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>com.inversoft</groupId>
@ -61,10 +61,15 @@
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.2</version>
<version>2.13.4.2</version>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>

View File

@ -40,7 +40,11 @@ public class ExampleData {
"Can perform all actions with comments",
"The file favorite state is undefined",
"Can't mention others in comments",
"Can't create new files from the editor"
"Can't create new files from the editor",
"Cant see anyones information",
"Can't rename files from the editor",
"Can't view chat",
"View file without collaboration"
);
List<String> description_user_1 = List.of( // the description for user 1
"File author by default",
@ -48,14 +52,18 @@ public class ExampleData {
"He can review all the changes",
"He can do everything with the comments",
"The file favorite state is undefined",
"Can create a file from a template with data from the editor"
"Can create a file from a template with data from the editor",
"Can see the information about all users",
"Can view chat"
);
List<String> description_user_2 = List.of( // the description for user 2
"He belongs to Group2",
"He can review only his own changes or the changes made by the users who dont belong to any of the groups",
"He can view every comment, edit his comments and the comments left by the users who don't belong to any of the groups and remove only his comments",
"This file is favorite",
"Can create a file from an editor"
"Can create a file from an editor",
"Can see the information about users from Group2 and users who dont belong to any group",
"Can view chat"
);
List<String> description_user_3 = List.of( // the description for user 3
"He belongs to Group3",
@ -65,21 +73,28 @@ public class ExampleData {
"He cant copy data from the file into the clipboard",
"He cant download the file",
"He cant print the file",
"Can create a file from an editor"
"Can create a file from an editor",
"Can see the information about Group2 users",
"Can view chat"
);
userService.createUser("John Smith", "smith@example.com", // create user 1 with the specified parameters
description_user_1, null, List.of(FilterState.NULL.toString()),
description_user_1, "", List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()), null);
List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()),
null, true);
userService.createUser("Mark Pottato", "pottato@example.com", // create user 2 with the specified parameters
description_user_2, "group-2", List.of("","group-2"), List.of(FilterState.NULL.toString()),
List.of("group-2", ""), List.of("group-2"), true);
List.of("group-2", ""), List.of("group-2"), List.of("group-2", ""), true,
true);
userService.createUser("Hamish Mitchell", "mitchell@example.com", // create user 3 with the specified parameters
description_user_3, "group-3", List.of("group-2"), List.of("group-2", "group-3"),
List.of("group-2"), new ArrayList<>(), false);
List.of("group-2"), new ArrayList<>(), List.of("group-2"), false,
true);
userService.createUser("Anonymous",null, // create user 0 with the specified parameters
description_user_0,null, List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()), null);
description_user_0,"", List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()), new ArrayList<>(),null,
false);
}
}

View File

@ -30,15 +30,23 @@ 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();
@ -58,6 +66,17 @@ 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

View File

@ -26,7 +26,6 @@ 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.documentserver.models.enums.Language;
import com.onlyoffice.integration.documentserver.models.enums.Type;
import com.onlyoffice.integration.documentserver.models.filemodel.FileModel;
import com.onlyoffice.integration.services.UserServices;
@ -53,6 +52,9 @@ public class EditorController {
@Value("${files.docservice.url.api}")
private String docserviceApiUrl;
@Value("${files.docservice.languages}")
private String langs;
@Autowired
private FileStoragePathBuilder storagePathBuilder;
@ -77,16 +79,25 @@ public class EditorController {
@RequestParam(value = "action", required = false) String actionParam,
@RequestParam(value = "type", required = false) String typeParam,
@RequestParam(value = "actionLink", required = false) String actionLink,
@RequestParam(value = "directUrl", required = false, defaultValue = "false") Boolean directUrl,
@CookieValue(value = "uid") String uid,
@CookieValue(value = "ulang") String lang,
Model model) throws JsonProcessingException {
Action action = Action.edit;
Type type = Type.desktop;
Language language = Language.en;
Locale locale = new Locale("en");
if(actionParam != null) action = Action.valueOf(actionParam);
if(typeParam != null) type = Type.valueOf(typeParam);
if(lang != null) language = Language.valueOf(lang);
List<String> langsAndKeys = Arrays.asList(langs.split("\\|"));
for (String langAndKey : langsAndKeys) {
String[] couple = langAndKey.split(":");
if (couple[0].equals(lang)) {
String[] langAndCountry = couple[0].split("-");
locale = new Locale(langAndCountry[0], langAndCountry.length > 1 ? langAndCountry[1] : "");
}
}
Optional<User> optionalUser = userService.findUserById(Integer.parseInt(uid));
@ -101,10 +112,11 @@ public class EditorController {
.builder()
.fileName(fileName)
.type(type)
.lang(language)
.lang(locale.toLanguageTag())
.action(action)
.user(user)
.actionData(actionLink)
.isEnableDirectUrl(directUrl)
.build()
);
@ -112,9 +124,9 @@ public class EditorController {
model.addAttribute("model", fileModel); // add file model with the default parameters to the original model
model.addAttribute("fileHistory", historyManager.getHistory(fileModel.getDocument())); // get file history and add it to the model
model.addAttribute("docserviceApiUrl",docserviceSite + docserviceApiUrl); // create the document service api URL and add it to the model
model.addAttribute("dataInsertImage", getInsertImage()); // get an image and add it to the model
model.addAttribute("dataCompareFile", getCompareFile()); // get a document for comparison and add it to the model
model.addAttribute("dataMailMergeRecipients", getMailMerge()); // get recipients data for mail merging and add it to the model
model.addAttribute("dataInsertImage", getInsertImage(directUrl)); // get an image and add it to the model
model.addAttribute("dataCompareFile", getCompareFile(directUrl)); // get a document for comparison and add it to the model
model.addAttribute("dataMailMergeRecipients", getMailMerge(directUrl)); // get recipients data for mail merging and add it to the model
model.addAttribute("usersForMentions", getUserMentions(uid)); // get user data for mentions and add it to the model
return "editor.html";
}
@ -134,10 +146,13 @@ public class EditorController {
}
@SneakyThrows
private String getInsertImage() { // get an image that will be inserted into the document
private String getInsertImage(Boolean directUrl) { // get an image that will be inserted into the document
Map<String, Object> dataInsertImage = new HashMap<>();
dataInsertImage.put("fileType", "png");
dataInsertImage.put("url", storagePathBuilder.getServerUrl(true) + "/css/img/logo.png");
if (directUrl) {
dataInsertImage.put("directUrl", storagePathBuilder.getServerUrl(false) + "/css/img/logo.png");
}
// check if the document token is enabled
if(jwtManager.tokenEnabled()){
@ -148,10 +163,13 @@ public class EditorController {
}
@SneakyThrows
private String getCompareFile(){ // get a document that will be compared with the current document
private String getCompareFile(Boolean directUrl) { // get a document that will be compared with the current document
Map<String, Object> dataCompareFile = new HashMap<>();
dataCompareFile.put("fileType", "docx");
dataCompareFile.put("url", storagePathBuilder.getServerUrl(true) + "/assets?name=sample.docx");
if (directUrl) {
dataCompareFile.put("directUrl", storagePathBuilder.getServerUrl(false) + "/assets?name=sample.docx");
}
// check if the document token is enabled
if(jwtManager.tokenEnabled()){
@ -162,10 +180,13 @@ public class EditorController {
}
@SneakyThrows
private String getMailMerge(){
private String getMailMerge(Boolean directUrl) {
Map<String, Object> dataMailMergeRecipients = new HashMap<>(); // get recipients data for mail merging
dataMailMergeRecipients.put("fileType", "csv");
dataMailMergeRecipients.put("url", storagePathBuilder.getServerUrl(true) + "/csv");
if (directUrl) {
dataMailMergeRecipients.put("directUrl", storagePathBuilder.getServerUrl(false) + "/csv");
}
// check if the document token is enabled
if(jwtManager.tokenEnabled()){

View File

@ -31,6 +31,7 @@ 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 org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -61,6 +62,12 @@ public class FileController {
@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
@ -79,6 +86,8 @@ public class FileController {
private ObjectMapper objectMapper;
@Autowired
private ServiceConverter serviceConverter;
@Autowired
private CallbackManager callbackManager;
// create user metadata
private String createUserMetadata(String uid, String fullFileName) {
@ -104,6 +113,18 @@ public class FileController {
.body(resource);
}
// download data from the specified history file
private ResponseEntity<Resource> downloadFileHistory(String fileName, String version, String file){
Resource resource = storageMutator.loadFileAsResourceHistory(fileName,version,file); // load the specified file as a resource
String contentType = "application/octet-stream";
// create a response with the content type, header and body with the file data
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
@PostMapping("/upload")
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file, // upload a file
@ -143,7 +164,7 @@ public class FileController {
public String convert(@RequestBody Converter body, // convert a file
@CookieValue("uid") String uid, @CookieValue("ulang") String lang){
String fileName = body.getFileName(); // get file name
String fileUri = documentManager.getDownloadUrl(fileName); // get URL for downloading a file with the specified name
String fileUri = documentManager.getDownloadUrl(fileName, true); // get URL for downloading a file with the specified name
String filePass = body.getFilePass() != null ? body.getFilePass() : null; // get file password if it exists
String fileExt = fileUtility.getFileExtension(fileName); // get file extension
DocumentType type = fileUtility.getDocumentType(fileName); // get document type (word, cell or slide)
@ -202,6 +223,29 @@ public class FileController {
}
}
@GetMapping("/downloadhistory")
public ResponseEntity<Resource> downloadHistory(HttpServletRequest request,// download a file
@RequestParam("fileName") String fileName,
@RequestParam("ver") String version,
@RequestParam("file") String file){ // history file
try{
// check if a token is enabled or not
if(jwtManager.tokenEnabled()){
String header = request.getHeader(documentJwtHeader == null // get the document JWT header
|| documentJwtHeader.isEmpty() ? "Authorization" : documentJwtHeader);
if(header != null && !header.isEmpty()){
String token = header.replace("Bearer ", ""); // token is the header without the Bearer prefix
jwtManager.readToken(token); // read the token
}else {
return null;
}
}
return downloadFileHistory(fileName,version,file); // download data from the specified file
} catch(Exception e){
return null;
}
}
@GetMapping(path = "${url.download}")
public ResponseEntity<Resource> download(HttpServletRequest request, // download a file
@RequestParam("fileName") String fileName){
@ -321,4 +365,32 @@ public class FileController {
return "{ \"error\" : 1, \"message\" : \"" + e.getMessage() + "\"}";
}
}
@PostMapping("/rename")
@ResponseBody
public String rename(@RequestBody JSONObject body) {
String newfilename = (String) body.get("newfilename");
String dockey = (String) body.get("dockey");
String origExt = "." + (String) body.get("ext");
String curExt = newfilename;
if(newfilename.indexOf(".") != -1) {
curExt = (String) fileUtility.getFileExtension(newfilename);
}
if(origExt.compareTo(curExt) != 0) {
newfilename += origExt;
}
HashMap<String, String> meta = new HashMap<>();
meta.put("title", newfilename);
try {
callbackManager.commandRequest("meta", dockey, meta);
return "result ok";
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
}
}

View File

@ -64,13 +64,25 @@ public class IndexController {
@Value("${url.editor}")
private String urlEditor;
@Value("${files.docservice.languages}")
private String langs;
@GetMapping("${url.index}")
public String index(Model model){
public String index(@RequestParam(value = "directUrl", required = false) Boolean directUrl,
Model model){
java.io.File[] files = storageMutator.getStoredFiles(); // get all the stored files from the storage
List<String> docTypes = new ArrayList<>();
List<Boolean> filesEditable = new ArrayList<>();
List<String> versions = new ArrayList<>();
List<Boolean> isFillFormDoc = new ArrayList<>();
List<String> langsAndKeys = Arrays.asList(langs.split("\\|"));
Map<String, String> languages = new LinkedHashMap<>();
langsAndKeys.forEach((str) -> {
String[] couple = str.split(":");
languages.put(couple[0], couple[1]);
});
List<User> users = userService.findAll(); // get a list of all the users
@ -95,6 +107,8 @@ public class IndexController {
model.addAttribute("datadocs", docserviceSite+docservicePreloader);
model.addAttribute("tooltip", tooltip);
model.addAttribute("users", users);
model.addAttribute("languages", languages);
model.addAttribute("directUrl", directUrl);
return "index.html";
}

View File

@ -39,7 +39,7 @@ public class EditCallback implements Callback {
if (!body.getUsers().contains(user)) { // if this user is not specified in the body
String key = body.getKey(); // get document key
try {
callbackManager.commandRequest("forcesave", key); // create a command request to forcibly save the document being edited without closing it
callbackManager.commandRequest("forcesave", key, null); // create a command request to forcibly save the document being edited without closing it
} catch (Exception e) {
e.printStackTrace();
result = 1;

View File

@ -19,9 +19,10 @@
package com.onlyoffice.integration.documentserver.managers.callback;
import com.onlyoffice.integration.dto.Track;
import java.util.HashMap;
public interface CallbackManager { // specify the callback manager functions
void processSave(Track body, String fileName); // file saving process
void commandRequest(String method, String key); // create a command request
void commandRequest(String method, String key, HashMap meta); // create a command request
void processForceSave(Track body, String fileName); // file force saving process
}

View File

@ -76,8 +76,15 @@ public class DefaultCallbackManager implements CallbackManager {
URL uri = new URL(url);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
connection.setConnectTimeout(5000);
InputStream stream = connection.getInputStream(); // get input stream of the file information from the URL
int statusCode = connection.getResponseCode();
if (statusCode != 200) { // checking status code
connection.disconnect();
throw new RuntimeException("Document editing service returned status: " + statusCode);
}
if (stream == null) {
connection.disconnect();
throw new RuntimeException("Input stream is null");
@ -94,7 +101,10 @@ public class DefaultCallbackManager implements CallbackManager {
String newFileName = fileName;
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
String downloadExt = fileUtility.getFileExtension(downloadUri); // get an extension of the downloaded file
String downloadExt = "." + body.getFiletype(); // get an extension of the downloaded file
// Todo [Delete in version 7.0 or higher]
if (downloadExt != "." + null) downloadExt = fileUtility.getFileExtension(downloadUri); // Support for versions below 7.0
//TODO: Refactoring
if (!curExt.equals(downloadExt)) { // convert downloaded file to the file with the current extension if these extensions aren't equal
@ -150,16 +160,20 @@ public class DefaultCallbackManager implements CallbackManager {
//TODO: Replace (String method) with (Enum method)
@SneakyThrows
public void commandRequest(String method, String key) { // create a command request
public void commandRequest(String method, String key, HashMap meta) { // create a command request
String DocumentCommandUrl = docserviceUrlSite + docserviceUrlCommand;
URL url = new URL(DocumentCommandUrl);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
HashMap<String, Object> params = new HashMap<>();
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;
if (jwtManager.tokenEnabled()) // check if a secret key to generate token exists or not
{
@ -212,7 +226,11 @@ public class DefaultCallbackManager implements CallbackManager {
String downloadUri = body.getUrl();
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
String downloadExt = fileUtility.getFileExtension(downloadUri); // get an extension of the downloaded file
String downloadExt = "."+body.getFiletype(); // get an extension of the downloaded file
// Todo [Delete in version 7.0 or higher]
if (downloadExt != "."+null) downloadExt = fileUtility.getFileExtension(downloadUri); // Support for versions below 7.0
Boolean newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal

View File

@ -45,6 +45,8 @@ 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}")
@ -93,6 +95,9 @@ public class DefaultDocumentManager implements DocumentManager {
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());
@ -104,6 +109,27 @@ public class DefaultDocumentManager implements DocumentManager {
}
}
// get file URL
public String getHistoryFileUrl(String fileName, Integer version, String file, 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(String fileName)
{
@ -123,15 +149,15 @@ public class DefaultDocumentManager implements DocumentManager {
}
// get URL to download a file
public String getDownloadUrl(String fileName) {
String serverPath = storagePathBuilder.getServerUrl(true);
public String getDownloadUrl(String fileName, 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="
+ URLEncoder.encode(storageAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
+ userAddress;
return serverPath + query;
}

View File

@ -25,8 +25,9 @@ import java.util.Map;
public interface DocumentManager {
String getCorrectName(String fileName); // get a file name with an index if the file with such a name already exists
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); // get URL to download a file
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
String versionDir(String path, Integer version, boolean historyPath); // get the path to the file version by the history path and file version

View File

@ -87,9 +87,14 @@ public class DefaultHistoryManager implements HistoryManager {
obj.put("user", user);
}
dataObj.put("fileType", fileUtility.getFileExtension(document.getTitle()).replace(".", ""));
dataObj.put("key", key);
dataObj.put("url", i == curVer ? document.getUrl() :
documentManager.getFileUri(documentManager.versionDir(histDir, i, true) + File.separator + "prev" + fileUtility.getFileExtension(document.getTitle()), true));
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
@ -105,11 +110,16 @@ public class DefaultHistoryManager implements HistoryManager {
Map<String, Object> prev = (Map<String, Object>) histData.get(Integer.toString(i - 2)); // get the history data from the previous file version
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"));
}
dataObj.put("previous", prevInfo); // write information about previous file version to the data object
// write the path to the diff.zip archive with differences in this file version
dataObj.put("changesUrl", documentManager.getFileUri(documentManager.versionDir(histDir, i - 1, true) + File.separator + "diff.zip", true));
Integer verdiff = i - 1;
dataObj.put("changesUrl", documentManager.getHistoryFileUrl(document.getTitle(), verdiff, "diff.zip", true));
}
if (jwtManager.tokenEnabled()) dataObj.put("token", jwtManager.createToken(dataObj));

View File

@ -34,7 +34,6 @@ public class Customization { // the parameters which allow to customize the edi
@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 chat = true; // if the Chat menu button is displayed or hidden
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)
@ -44,4 +43,6 @@ public class Customization { // the parameters which allow to customize the edi
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 = false; // if the Submit form button is displayed or hidden
private Boolean about = true;
private Boolean feedback =true;
}

View File

@ -20,7 +20,6 @@ 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;
@ -30,8 +29,6 @@ import javax.annotation.PostConstruct;
@Component
@Scope("prototype")
@Getter
@Setter
public class Goback { // the settings for the Open file location menu button and upper right corner button
@Autowired
@ -39,10 +36,12 @@ public class Goback { // the settings for the Open file location menu button an
@Value("${url.index}")
private String indexMapping;
@Getter
private String url; // the absolute URL to the website address which will be opened when clicking the Open file location menu button
@PostConstruct
private void init(){
this.url = storagePathBuilder.getServerUrl(false)+indexMapping;
private void init() {
this.url = storagePathBuilder.getServerUrl(false) + indexMapping;
}
}

View File

@ -25,6 +25,7 @@ public enum Action {
embedded,
filter,
comment,
chat,
fillForms,
blockcontent
}

View File

@ -1,53 +0,0 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* 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 Language {
en,
de,
ru,
pl,
be,
bg,
ca,
zh,
cs,
da,
nl,
fi,
fr,
el,
hu,
id,
it,
ja,
ko,
lv,
lo,
nb,
pt,
ro,
sk,
sl,
sv,
es,
tr,
uk,
vi
}

View File

@ -39,4 +39,5 @@ public class Document { // the parameters pertaining to the document (title, ur
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;
}

View File

@ -20,7 +20,6 @@ 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.Language;
import com.onlyoffice.integration.documentserver.models.enums.Mode;
import lombok.*;
import org.springframework.beans.factory.annotation.Autowired;
@ -38,12 +37,13 @@ import java.util.List;
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 Language lang; // the editor interface language
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

View File

@ -43,8 +43,11 @@ public class Permission extends AbstractModel { // the permission for the docum
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;
}

View File

@ -16,6 +16,7 @@ public interface FileStorageMutator {
boolean writeToFile(String pathName, String payload); // write the payload to the file
boolean moveFile(Path source, Path destination); // move a file to the specified destination
Resource loadFileAsResource(String fileName); // load file as a resource
Resource loadFileAsResourceHistory(String fileName,String version,String file); // load file as a resource
File[] getStoredFiles(); // get a collection of all the stored files
void createMeta(String fileName, String uid, String uname); // create the file meta information
boolean createOrUpdateFile(Path path, InputStream stream); // create or update a file

View File

@ -85,10 +85,18 @@ public class LocalFileStorage implements FileStorageMutator, FileStoragePathBuil
// get the storage directory
public String getStorageLocation(){
String serverPath = System.getProperty("user.dir"); // get the path to the server
String directory = serverPath // create the storage directory
+ File.separator + storageFolder
+ File.separator + this.storageAddress
+ File.separator;
String directory; // create the storage directory
if (Paths.get(this.storageAddress).isAbsolute()) {
directory = this.storageAddress + File.separator;
} else {
directory = serverPath
+ File.separator + storageFolder
+ File.separator + this.storageAddress
+ File.separator;
}
if (!Files.exists(Paths.get(directory))) {
createDirectory(Paths.get(directory));
}
return directory;
}
@ -238,6 +246,20 @@ public class LocalFileStorage implements FileStorageMutator, FileStoragePathBuil
return null;
}
public Resource loadFileAsResourceHistory(String fileName,String version,String file){
String fileLocation = getStorageLocation() + fileName + "-hist" + File.separator + version + File.separator + file; // get it by the file name
try {
Path filePath = Paths.get(fileLocation); // get the path to the file location
Resource resource = new UrlResource(filePath.toUri()); // convert the file path to URL
if(resource.exists()) return resource;
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
// get a collection of all the stored files
public File[] getStoredFiles()
{

View File

@ -0,0 +1,59 @@
package com.onlyoffice.integration.documentserver.util;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.springframework.stereotype.Component;
/**
* Disables and enables certificate and host-name checking in
* HttpsURLConnection, the default JVM implementation of the HTTPS/TLS protocol.
* Has no effect on implementations such as Apache Http Client, Ok Http.
*/
@Component
public final class SSLUtils {
private final HostnameVerifier jvmHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
private final HostnameVerifier trivialHostnameVerifier = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession sslSession) {
return true;
}
};
private final TrustManager[] UNQUESTIONING_TRUST_MANAGER = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
public void turnOffSslChecking() throws NoSuchAlgorithmException, KeyManagementException {
HttpsURLConnection.setDefaultHostnameVerifier(trivialHostnameVerifier);
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, UNQUESTIONING_TRUST_MANAGER, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
public void turnOnSslChecking() throws KeyManagementException, NoSuchAlgorithmException {
HttpsURLConnection.setDefaultHostnameVerifier(jvmHostnameVerifier);
// Return it to the initial state (discovered by reflection, now hardcoded)
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, null, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
}

View File

@ -59,7 +59,7 @@ public class DefaultFileUtility implements FileUtility {
// spreadsheet extensions
private List<String> ExtsSpreadsheet = Arrays.asList(
".xls", ".xlsx", ".xlsm",
".xls", ".xlsx", ".xlsm", ".xlsb",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv");

View File

@ -95,6 +95,13 @@ public class DefaultServiceConverter implements ServiceConverter
}
connection.connect();
int statusCode = connection.getResponseCode();
if (statusCode != 200) { // checking status code
connection.disconnect();
throw new RuntimeException("Convertation service returned status: " + statusCode);
}
try (OutputStream os = connection.getOutputStream()) {
os.write(bodyByte); // write bytes to the output stream
os.flush(); // force write data to the output stream that can be cached in the current thread

View File

@ -38,6 +38,7 @@ public class Permission extends AbstractEntity {
private Boolean modifyFilter = true;
private Boolean modifyContentControl = true;
private Boolean review = true;
private Boolean chat = true;
private Boolean templates=true;
@ManyToMany
private List<Group> reviewGroups;
@ -47,4 +48,6 @@ public class Permission extends AbstractEntity {
private List<Group> commentsEditGroups;
@ManyToMany
private List<Group> commentsRemoveGroups;
@ManyToMany
private List<Group> userInfoGroups;
}

View File

@ -54,5 +54,6 @@ public class PermissionsMapper extends AbstractMapper<Permission, com.onlyoffice
source.getCommentsRemoveGroups().stream().map(g -> g.getName()).collect(Collectors.toList())
)
);
destination.setUserInfoGroups(source.getUserInfoGroups().stream().map(g -> g.getName()).collect(Collectors.toList()));
}
}

View File

@ -36,13 +36,17 @@ public class PermissionServices {
public Permission createPermission(List<Group> reviewGroups,
List<Group> commentViewGroups,
List<Group> commentEditGroups,
List<Group> commentRemoveGroups){
List<Group> commentRemoveGroups,
List<Group> userInfoGroups,
Boolean chat){
Permission permission = new Permission();
permission.setReviewGroups(reviewGroups); // define the groups whose changes the user can accept/reject
permission.setCommentsViewGroups(commentViewGroups); // defines the groups whose comments the user can view
permission.setCommentsEditGroups(commentEditGroups); // defines the groups whose comments the user can edit
permission.setCommentsRemoveGroups(commentRemoveGroups); // defines the groups whose comments the user can remove
permission.setUserInfoGroups(userInfoGroups);
permission.setChat(chat);
permissionRepository.save(permission); // save new permissions

View File

@ -56,7 +56,9 @@ public class UserServices {
List<String> reviewGroups,
List<String> viewGroups,
List<String> editGroups,
List<String> removeGroups, Boolean favoriteDoc){
List<String> removeGroups,
List<String> userInfoGroups, Boolean favoriteDoc,
Boolean chat){
User newUser = new User();
newUser.setName(name); // set the user name
newUser.setEmail(email); // set the user email
@ -68,9 +70,10 @@ public class UserServices {
List<Group> commentGroupsView = groupServices.createGroups(viewGroups); // defines the groups whose comments the user can view
List<Group> commentGroupsEdit = groupServices.createGroups(editGroups); // defines the groups whose comments the user can edit
List<Group> commentGroupsRemove = groupServices.createGroups(removeGroups); // defines the groups whose comments the user can remove
List<Group> usInfoGroups = groupServices.createGroups(userInfoGroups);
Permission permission = permissionService
.createPermission(groupsReview, commentGroupsView, commentGroupsEdit, commentGroupsRemove); // specify permissions for the current user
.createPermission(groupsReview, commentGroupsView, commentGroupsEdit, commentGroupsRemove, usInfoGroups, chat); // specify permissions for the current user
newUser.setPermissions(permission);
userRepository.save(newUser); // save a new user

View File

@ -53,8 +53,9 @@ public class DefaultDocumentConfigurer implements DocumentConfigurer<DefaultDocu
Permission permission = wrapper.getPermission(); // get the permission parameter from the document wrapper
document.setTitle(fileName); // set the title to the document config
document.setUrl(documentManager.getDownloadUrl(fileName)); // set the URL to download a file to the document config
document.setUrl(documentManager.getDownloadUrl(fileName, true)); // set the URL to download a file to the document config
document.setUrlUser(documentManager.getFileUri(fileName, false)); // set the file URL to the document config
document.setDirectUrl(wrapper.getIsEnableDirectUrl() ? documentManager.getDownloadUrl(fileName, false) : "");
document.setFileType(fileUtility.getFileExtension(fileName).replace(".","")); // set the file type to the document config
document.getInfo().setFavorite(wrapper.getFavorite()); // set the favorite parameter to the document config

View File

@ -82,10 +82,14 @@ public class DefaultEditorConfigConfigurer implements EditorConfigConfigurer<Def
config.setLang(wrapper.getLang()); // set the language to the editorConfig
Boolean canEdit = wrapper.getCanEdit(); // check if the file of the specified type can be edited or not
Action action = wrapper.getAction(); // get the action parameter from the editorConfig wrapper
config.setCoEditing(action.equals(Action.view) && userIsAnon ? new HashMap<String, Object>() {{
put("mode", "strict");
put("change", false);
}} : null);
defaultCustomizationConfigurer.configure(config.getCustomization(), DefaultCustomizationWrapper.builder() // define the customization configurer
.action(action)
.user(wrapper.getUser())
.user(userIsAnon ? null : wrapper.getUser())
.build());
config.setMode(canEdit && !action.equals(Action.view) ? Mode.edit : Mode.view);
config.setUser(mapper.toModel(wrapper.getUser()));

View File

@ -37,7 +37,7 @@ public class DefaultEmbeddedConfigurer implements EmbeddedConfigurer<DefaultEmbe
public void configure(Embedded embedded, DefaultEmbeddedWrapper wrapper){ // define the embedded configurer
if(wrapper.getType().equals(Type.embedded)) { // check if the type from the embedded wrapper is embedded
String url = documentManager.getFileUri(wrapper.getFileName(), false); // get file URL of the specified file
String url = documentManager.getDownloadUrl(wrapper.getFileName(), false); // get file URL of the specified file
embedded.setEmbedUrl(url); // set the embedURL parameter to the embedded config (the absolute URL to the document serving as a source file for the document embedded into the web page)
embedded.setSaveUrl(url); // set the saveURL parameter to the embedded config (the absolute URL that will allow the document to be saved onto the user personal computer)
embedded.setShareUrl(url); // set the shareURL parameter to the embedded config (the absolute URL that will allow other users to share this document)

View File

@ -80,6 +80,7 @@ public class DefaultFileConfigurer implements FileConfigurer<DefaultFileWrapper>
.fileName(fileName)
.permission(updatePermissions(userPermissions, action, canEdit))
.favorite(wrapper.getUser().getFavorite())
.isEnableDirectUrl(wrapper.getIsEnableDirectUrl())
.build();
defaultDocumentConfigurer.configure(fileModel.getDocument(), documentWrapper); // define the document configurer

View File

@ -28,4 +28,5 @@ public class DefaultDocumentWrapper {
private Permission permission;
private String fileName;
private Boolean favorite;
private Boolean isEnableDirectUrl;
}

View File

@ -20,7 +20,6 @@ package com.onlyoffice.integration.services.configurers.wrappers;
import com.onlyoffice.integration.documentserver.models.enums.Action;
import com.onlyoffice.integration.entities.User;
import com.onlyoffice.integration.documentserver.models.enums.Language;
import com.onlyoffice.integration.documentserver.models.enums.Type;
import lombok.Builder;
import lombok.Getter;
@ -33,8 +32,9 @@ public class DefaultFileWrapper {
private String fileName;
private Type type;
private User user;
private Language lang;
private String lang;
private Action action;
private String actionData;
private Boolean canEdit;
private Boolean isEnableDirectUrl;
}

View File

@ -1,6 +1,6 @@
server.version=1.1.0
server.version=1.4.0
server.address=127.0.0.1
server.address=
server.port=4000
filesize-max=5242880
@ -11,7 +11,7 @@ files.storage.folder=documents
files.docservice.fillforms-docs=.oform|.docx
files.docservice.viewed-docs=.pdf|.djvu|.xps|.oxps
files.docservice.edited-docs=.docx|.xlsx|.csv|.pptx|.txt|.docxf
files.docservice.convert-docs=.docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2
files.docservice.convert-docs=.docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xlsb|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2
files.docservice.timeout=120000
files.docservice.history.postfix=-hist
@ -25,6 +25,10 @@ files.docservice.url.example=
files.docservice.secret=
files.docservice.header=Authorization
files.docservice.verify-peer-off=true
files.docservice.languages=en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese
spring.datasource.url=jdbc:h2:mem:usersdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa

View File

@ -129,6 +129,10 @@
height: 80px;
}
.main {
height: calc(100% - 128px);
}
.left-panel {
width: 90%;
}
@ -367,6 +371,10 @@
height: 80px;
}
.main {
height: calc(100% - 128px);
}
.copy {
width: 100%;
text-align: center;
@ -440,6 +448,58 @@
display: none;
width: 1%;
}
/* Mobile Upload*/
.blockUI.blockMsg.blockPage.ui-dialog.ui-widget.ui-corner-all.ui-widget-content.ui-draggable {
width: 344px !important;
box-shadow: 0px 7px 15px rgba(85, 85, 85, 0.1);
border-radius: 2px;
top: 10% !important;
margin-left: -172px !important;
}
.ui-dialog .ui-dialog-titlebar {
padding: 0;
}
.ui-dialog .ui-dialog-content {
padding: 0 !important;
}
#mainProgress {
margin: 24px 16px 0 !important;
}
.blockTitle {
padding: 10px 10px 6px 16px !important;
font-size: 14px !important;
}
#mainProgress .describeUpload {
padding: 8px 0 !important;
}
.dialog-close {
margin: 0 !important;
}
.step-descr{
line-height: 150%;
}
.step {
line-height: 160%;
}
.buttonsMobile{
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
.button.gray{
margin: 0;
}
.button, .button:hover{
display: flex;
justify-content: center;
padding: 0 !important;
width: 144px;
height: 56px;
margin-bottom: 24px !important;
}
}
@media (max-width: 560px) and (min-width: 510px) {

View File

@ -22,7 +22,7 @@ html {
}
body {
display: inline-table;
display: block;
background: #FFFFFF;
color: #333333;
font-family: Open Sans;
@ -72,6 +72,7 @@ header img {
}
.main{
display: table;
height: calc(100% - 112px);
min-height: 536px;
}
@ -98,6 +99,10 @@ header img {
width: 896px;
}
#portal-info {
max-width: 65vw;
}
.portal-name {
color: #FF6F3D;
font-size: 24px;
@ -162,7 +167,7 @@ label .checkbox {
background-image: url("img/file_docxf.svg");
}
.create-sample {
.side-option {
color: #666666;
line-height: 24px;
}
@ -740,12 +745,9 @@ html {
width: 30vw;
min-width: 200px;
max-width: 400px;
margin-top: 20px;
}
.user-descr > b {
margin-left: 25px;
}
.portal-descr:nth-child(3) {
margin-bottom: 20px;
}

View File

@ -16,11 +16,24 @@
*
*/
var directUrl;
if (typeof jQuery !== "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function() {
window.location = "?directUrl=" + jq(this).prop("checked");
});
jq(function () {
jq("#fileupload").fileupload({
dataType: "json",
@ -228,7 +241,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?action=edit&fileName=" + fileId;
var url = UrlEditor + "?action=edit&fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
@ -236,7 +249,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?action=view&fileName=" + fileId;
var url = UrlEditor + "?action=view&fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
@ -244,7 +257,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?type=embedded&action=embedded&fileName=" + fileId;
var url = UrlEditor + "?type=embedded&action=embedded&fileName=" + fileId + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -300,6 +313,17 @@ if (typeof jQuery !== "undefined") {
}
};
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
};
jq("#portal-info")[0].innerHTML += jq("#portal-info")[0].attributes.tooltip.value;
var fileList = jq("tr.tableRow");
@ -317,7 +341,7 @@ if (typeof jQuery !== "undefined") {
});
}
} else {
jq(".info").mouseover(function (event) {
jq("#info").mouseover(function (event) {
if (fileList.length > 0) {
if (hideTooltipTimeout != null) {
clearTimeout(hideTooltipTimeout);

View File

@ -30,6 +30,7 @@
<script th:inline="javascript">
var docEditor;
var config;
var innerAlert = function (message, inEditor) {
if (console && console.log)
@ -90,10 +91,13 @@
// the meta information of the document is changed via the meta command
var onMetaChange = function (event) {
var favorite = !!event.data.favorite;
var title = document.title.replace(/^\☆/g, "");
document.title = (favorite ? "☆" : "") + title;
docEditor.setFavorite(favorite);
if (event.data.favorite) {
var favorite = !!event.data.favorite;
var title = document.title.replace(/^\☆/g, "");
document.title = (favorite ? "☆" : "") + title;
docEditor.setFavorite(favorite);
}
innerAlert("onMetaChange: " + JSON.stringify(event.data));
};
@ -115,7 +119,7 @@
docEditor.setMailMergeRecipients([[${dataMailMergeRecipients}]]);
};
var config = [[${model}]];
config = [[${model}]];
if (config.editorConfig.user.name == "Anonymous") {
config.editorConfig.user.name = "";
@ -130,7 +134,7 @@
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "saveas");
xhr.setRequestHeader( 'Content-Type', 'application/json');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
xhr.onload = function () {
innerAlert(xhr.responseText);
@ -138,6 +142,24 @@
}
};
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
innerAlert("onRequestRename: " + JSON.stringify(event.data));
var newfilename = event.data;
var data = {
newfilename: newfilename,
dockey: config.document.key,
ext: config.document.fileType
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "rename");
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
xhr.onload = function () {
innerAlert(xhr.responseText);
}
};
config.width = "100%";
config.height = "100%";
config.events = {
@ -158,24 +180,23 @@
var historyData = histArray[1];
var usersForMentions = [[${usersForMentions}]];
if (hist && historyData) {
// the user is trying to show the document version history
config.events['onRequestHistory'] = function () {
docEditor.refreshHistory(JSON.parse(hist)); // show the document version history
};
// the user is trying to click the specific document version in the document version history
config.events['onRequestHistoryData'] = function (event) {
var ver = event.data;
var histData = historyData;
docEditor.setHistoryData(JSON.parse(histData)[ver - 1]); // send the link to the document for viewing the version history
};
// the user is trying to go back to the document from viewing the document version history
config.events['onRequestHistoryClose'] = function () {
document.location.reload();
};
}
if(usersForMentions){
if (config.editorConfig.user.id != 4) {
if (hist && historyData) {
// the user is trying to show the document version history
config.events['onRequestHistory'] = function () {
docEditor.refreshHistory(JSON.parse(hist)); // show the document version history
};
// the user is trying to click the specific document version in the document version history
config.events['onRequestHistoryData'] = function (event) {
var ver = event.data;
var histData = historyData;
docEditor.setHistoryData(JSON.parse(histData)[ver - 1]); // send the link to the document for viewing the version history
};
// the user is trying to go back to the document from viewing the document version history
config.events['onRequestHistoryClose'] = function () {
document.location.reload();
};
}
// add mentions for not anonymous users
config.events['onRequestUsers'] = function () {
docEditor.setUsers({ // set a list of users to mention in the comments
@ -184,10 +205,12 @@
};
// the user is mentioned in a comment
config.events['onRequestSendNotify'] = function (event) {
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
var data = JSON.stringify(event.data);
innerAlert("onRequestSendNotify: " + data);
};
// prevent file renaming for anonymous users
config.events['onRequestRename'] = onRequestRename;
}
if (config.editorConfig.createUrl) {

View File

@ -2,6 +2,7 @@
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width" />
<!--
*
* (c) Copyright Ascensio System SIA 2021
@ -58,7 +59,7 @@
<a class="try-editor form" data-type="docxf">Form template</a>
</li>
</ul>
<label class="create-sample">
<label class="side-option">
<input id="createSample" class="checkbox" type="checkbox" />With sample content
</label>
</div>
@ -74,7 +75,7 @@
<tr>
<td valign="middle">
<span class="select-user">Username</span>
<img class="info" src="css/img/info.svg"/>
<img id="info" class="info" src="css/img/info.svg"/>
<select class="select-user" id="user">
<option th:each="user : ${users}"
th:value="${user.id}"
@ -86,40 +87,20 @@
<td valign="middle">
<span class="select-user">Language editors interface</span>
<select class="select-user" id="language">
<option value="en" selected="selected">English</option>
<option value="be">Belarusian</option>
<option value="bg">Bulgarian</option>
<option value="ca">Catalan</option>
<option value="zh">Chinese</option>
<option value="cs">Czech</option>
<option value="da">Danish</option>
<option value="nl">Dutch</option>
<option value="fi">Finnish</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="el">Greek</option>
<option value="hu">Hungarian</option>
<option value="id">Indonesian</option>
<option value="it">Italian</option>
<option value="ja">Japanese</option>
<option value="ko">Korean</option>
<option value="lv">Latvian</option>
<option value="lo">Lao</option>
<option value="nb">Norwegian</option>
<option value="pl">Polish</option>
<option value="pt">Portuguese</option>
<option value="ro">Romanian</option>
<option value="ru">Russian</option>
<option value="sk">Slovak</option>
<option value="sl">Slovenian</option>
<option value="sv">Swedish</option>
<option value="es">Spanish</option>
<option value="tr">Turkish</option>
<option value="uk">Ukrainian</option>
<option value="vi">Vietnamese</option>
<option th:each="language: ${languages}"
th:value="${language.key}"
th:text="${language.value}"/>
</select>
</td>
</tr>
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="css/img/info.svg" />
</label>
</td>
</tr>
</tbody>
</table>
</div>
@ -127,12 +108,13 @@
</td>
<td class="section">
<div class="main-panel">
<div id="portal-info" th:attr="tooltip=${tooltip}" th:style="${not #lists.isEmpty(files)} ? 'display: none' : 'display: block' ">
<div id="portal-info" th:attr="tooltip=${tooltip}" th:style="${not #lists.isEmpty(files)} ? 'display: none' : 'display: table-cell' ">
<span class="portal-name">ONLYOFFICE Document Editors Welcome!</span>
<span class="portal-descr">
Get started with a demo-sample of ONLYOFFICE Document Editors, the first html5-based editors.
<br /> You may upload your own documents for testing using the "<b>Upload file</b>" button and <b>selecting</b> the necessary files on your PC.
</span>
<span class="portal-descr">Please do NOT use this integration example on your own server without proper code modifications, it is intended for testing purposes only. In case you enabled this test example, disable it before going for production.</span>
<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>
</div>
<th:block th:if="${not #lists.isEmpty(files)}">
@ -155,46 +137,50 @@
<tr th:each="file,iState : ${files}" class="tableRow" th:title="${files[iState.index].getName() + versions[iState.index]}">
<td class="contentCells">
<a class="stored-edit" th:classappend="${docTypes[iState.index]}"
th:href="@{/editor(fileName=${files[iState.index].getName()})}" target="_blank">
th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()}, __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<span th:text="${files[iState.index].getName()}"></span>
</a>
</td>
<th:block th:if="${filesEditable[iState.index]}">
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='edit')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='edit', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='edit')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='edit', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='comment')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='comment', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
</a>
</td>
<div th:if="${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='review')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='review', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
</a>
</td>
</div>
<div th:if="${docTypes[iState.index]} eq 'cell'">
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='filter')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='filter', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" />
</a>
</td>
</div>
<div th:if="${docTypes[iState.index]} eq 'slide'">
<td class="contentCells contentCells-icon contentCellsEmpty"></td>
</div>
<div th:if="${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='blockcontent')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='blockcontent', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
</a>
</td>
@ -207,7 +193,8 @@
</div>
<div th:if="${isFillFormDoc[iState.index]}">
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -219,7 +206,8 @@
<th:block th:if="${isFillFormDoc[iState.index] and not filesEditable[iState.index]}">
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='fillForms')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='fillForms', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/mobile-fill-forms.svg" alt="Open in editor for filling in forms for mobile devices" title="Open in editor for filling in forms for mobile devices" />
</a>
</td>
@ -227,7 +215,8 @@
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -236,17 +225,20 @@
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
</th:block>
<td class="contentCells contentCells-icon firstContentCellViewers">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='view')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='view', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='view')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='view', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='embedded',action='embedded')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='embedded',action='embedded', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>
@ -298,10 +290,8 @@
<span class="step-descr">They are loaded only once, they will be cached on your computer.</span>
<input type="hidden" name="hiddenFileName" id="hiddenFileName" />
<br />
<br />
<span class="progress-descr">Note the speed of all operations depends on your connection quality and server location.</span>
<br />
<br />
<div class="error-message">
<b>Upload error: </b><span></span>
<br />
@ -310,10 +300,12 @@
</div>
<iframe id="embeddedView" src="" height="345px" width="432px" frameborder="0" scrolling="no" allowtransparency></iframe>
<br />
<div id="beginEdit" class="button orange disable">Edit</div>
<div id="beginView" class="button gray disable">View</div>
<div id="beginEmbedded" class="button gray disable">Embedded view</div>
<div id="cancelEdit" class="button gray">Cancel</div>
<div class="buttonsMobile">
<div id="beginEdit" class="button orange disable">Edit</div>
<div id="beginView" class="button gray disable">View</div>
<div id="beginEmbedded" class="button gray disable">Embedded view</div>
<div id="cancelEdit" class="button gray">Cancel</div>
</div>
</div>
<span id="loadScripts" th:attr="data-docs=${datadocs}"></span>
@ -346,5 +338,21 @@
<script type="text/javascript" src="scripts/jquery.dropdownToggle.js"></script>
<script type="text/javascript" src="scripts/jscript.js"></script>
<script type="text/javascript" src="scripts/converter.js"></script>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
var lang = document.cookie
.split('; ')
.find((row) => row.startsWith('ulang='))
?.split('=')[1];
var languages = Array.from(document.getElementById("language").options).map(e => e.value)
if (!languages.includes(lang)) {
lang = "en";
}
document.getElementById("language").value=lang;
});
</script>
</body>
</html>

View File

@ -0,0 +1,9 @@
FROM maven:3.6.1-jdk-8-alpine AS MVN_BLDR
COPY pom.xml /tmp/
COPY src /tmp/src/
WORKDIR /tmp/
RUN mvn package
FROM tomcat:alpine
RUN rm -fr /usr/local/tomcat/webapps/ROOT
COPY --from=MVN_BLDR /tmp/target/*.war $CATALINA_HOME/webapps/ROOT.war

View File

@ -1,14 +1,14 @@
## Overview
This example will help you integrate ONLYOFFICE Docs into your web application written in Java.
This example will help you integrate ONLYOFFICE Docs into your web application written in Java.
It is aimed at testing the editors. Please, do not use it for production without proper modifications.
**Please note**: It is intended for testing purposes and demonstrating functionality of the editors. Do NOT use this integration example on your own server without proper code modifications! In case you enabled the test example, disable it before going for production.
## For Windows
### Step 1. Install ONLYOFFICE Docs
Download and install ONLYOFFICE Docs (packaged as Document Server).
Download and install ONLYOFFICE Docs (packaged as Document Server).
See the detailed guide to learn how to [install Document Server for Windows](https://helpcenter.onlyoffice.com/installation/docs-developer-install-windows.aspx).
@ -16,13 +16,14 @@ See the detailed guide to learn how to [install Document Server for Windows](htt
Download the [Java example](https://api.onlyoffice.com/editors/demopreview) from our site.
To connect the editors to your website, specify the path to the editors installation in the *\src\main\resources\settings.properties* file:
To connect the editors to your website, specify the path to the editors installation and the path to the storage folder in the *\src\main\resources\settings.properties* file:
```
storage-folder = app_data
files.docservice.url.site=https://documentserver/
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-folder** is the path where files will be created and stored. You can set an absolute path. For example, *D:\\\\folder*. Please note that on Windows OS the double backslash must be used as a separator.
If you want to experiment with the editor configuration, modify the [parameters](https://api.onlyoffice.com/editors/advanced) in the *\src\main\webapp\editor.jsp* file.
@ -96,7 +97,7 @@ To run the Java example code, install the Java version appropriate for your OS a
2. Tomcat Web Application Manager will request the **username** and the **password:**
![author](screenshots/author.jpg)
Specify user data in *tomcat-users.xml* file in the Apache Tomcat installation folder. Define the **manager-gui** user role, specify the **user name** and **password** values:
@ -106,18 +107,22 @@ To run the Java example code, install the Java version appropriate for your OS a
<user username="tomcat" password="tomcat" roles="manager-gui"/>
</tomcat-users>
```
3. Upload the Java project in Tomcat Web Application Manager. For that click **Choose File** in the **WAR file to deploy** section and find the *.war* file in the Java project folder, then click **Deploy**.
3. Build the project using the following commands
```
mvn clean
mvn package
```
4. Upload the Java project in Tomcat Web Application Manager. For that click **Choose File** in the **WAR file to deploy** section and find the *.war* file in the Java project folder, then click **Deploy**.
![upload-app](screenshots/upload-app.jpg)
![war-file](screenshots/war-file.jpg)
4. You will see the project in the **Application List**:
5. You will see the project in the **Application List**:
![manager-app](screenshots/manager-app.jpg)
5. Click the link with the application name to run it.
6. Click the link with the application name to run it.
### Step 6. Check accessibility
@ -163,13 +168,17 @@ See the detailed guide to learn how to [install Document Server for Linux](https
nano src/main/resources/settings.properties
```
Edit the following line:
Edit the following lines:
```
storage-folder = app_data
files.docservice.url.site=https://documentserver/
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-folder** is the path where files will be created and stored. Please note that you must have read and write permissions to the folder. If you do not have them, please use the next command:
```
sudo chmod -R ugo+rw /{path}
```
5. Install **Maven**:
@ -238,13 +247,14 @@ Make sure that the Document Server has access to the server with the example ins
nano src/main/resources/settings.properties
```
2. Edit the following line:
2. Edit the following lines:
```
storage-folder = app_data
files.docservice.url.site=https://documentserver/
```
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed.
where the **documentserver** is the name of the server with the ONLYOFFICE Document Server installed and the **storage-folder** is the path where files will be created and stored.
3. Run the next command in the Java example directory:
@ -253,3 +263,12 @@ Make sure that the Document Server has access to the server with the example ins
```
4. After it, all the *bin* files will be passed to the *./target* folder.
## Important security info
Please keep in mind the following security aspects when you are using test examples:
* There is no protection of the storage from unauthorized access since there is no need for authorization.
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.

View File

@ -1,7 +1,9 @@
version: '3'
services:
build:
image: maven:3.6
volumes:
- .:/java
command: mvn -f /java package
java-intg-ex:
build:
context: ./
dockerfile: Dockerfile
ports:
- 8080:8080

View File

@ -29,7 +29,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>com.inversoft</groupId>
@ -45,8 +45,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<source>8</source>
<target>8</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>

View File

@ -47,6 +47,7 @@ public class EditorServlet extends HttpServlet
String fileName = FileUtility.GetFileName(request.getParameter("fileName"));
String fileExt = request.getParameter("fileExt");
String sample = request.getParameter("sample");
Boolean isEnableDirectUrl = Boolean.valueOf(request.getParameter("directUrl"));
// check if there is sample data in the request
Boolean sampleData = (sample == null || sample.isEmpty()) ? false : sample.toLowerCase().equals("true");
@ -70,24 +71,33 @@ public class EditorServlet extends HttpServlet
}
// create file model (get all the necessary parameters from cookies)
FileModel file = new FileModel(fileName, cm.getCookie("ulang"), request.getParameter("actionLink"), user);
FileModel file = new FileModel(fileName, cm.getCookie("ulang"), request.getParameter("actionLink"), user, isEnableDirectUrl);
// change type parameter if needed
file.changeType(request.getParameter("mode"), request.getParameter("type"), user);
file.changeType(request.getParameter("mode"), request.getParameter("type"), user, fileName);
// an image that will be inserted into the document
Map<String, Object> dataInsertImage = new HashMap<>();
dataInsertImage.put("fileType", "png");
dataInsertImage.put("url", DocumentManager.GetServerUrl(true) + "/css/img/logo.png");
if (isEnableDirectUrl) {
dataInsertImage.put("directUrl", DocumentManager.GetServerUrl(false) + "/css/img/logo.png");
}
// a document that will be compared with the current document
Map<String, Object> dataCompareFile = new HashMap<>();
dataCompareFile.put("fileType", "docx");
dataCompareFile.put("url", DocumentManager.GetServerUrl(true) + "/IndexServlet?type=assets&name=sample.docx");
if (isEnableDirectUrl) {
dataCompareFile.put("directUrl", DocumentManager.GetServerUrl(false) + "/IndexServlet?type=assets&name=sample.docx");
}
// recipients data for mail merging
Map<String, Object> dataMailMergeRecipients = new HashMap<>();
dataMailMergeRecipients.put("fileType", "csv");
dataMailMergeRecipients.put("url", DocumentManager.GetServerUrl(true) + "/IndexServlet?type=csv");
if (isEnableDirectUrl) {
dataMailMergeRecipients.put("directUrl", DocumentManager.GetServerUrl(false) + "/IndexServlet?type=csv");
}
// users data for mentions
List<Map<String, Object>> usersForMentions = Users.getUsersForMentions(user.id);

View File

@ -29,6 +29,7 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import helpers.*;
public class GlobalServletContextListener implements ServletContextListener
{
@ -70,16 +71,19 @@ public class GlobalServletContextListener implements ServletContextListener
SSLContext sc;
try
{
// register the all-trusting trust manager for HTTPS
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
catch (NoSuchAlgorithmException | KeyManagementException ex)
{
if(!ConfigManager.GetProperty("files.docservice.verify-peer-off").isEmpty()) {
try
{
// register the all-trusting trust manager for HTTPS
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
catch (NoSuchAlgorithmException | KeyManagementException ex)
{
}
}
// create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier()

View File

@ -29,6 +29,8 @@ import java.util.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
@ -36,7 +38,9 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import entities.FileType;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
@ -45,6 +49,7 @@ import org.primeframework.jwt.Verifier;
import org.primeframework.jwt.domain.JWT;
import org.primeframework.jwt.hmac.HMACVerifier;
@WebServlet(name = "IndexServlet", urlPatterns = {"/IndexServlet"})
@MultipartConfig
public class IndexServlet extends HttpServlet
@ -72,6 +77,10 @@ public class IndexServlet extends HttpServlet
break;
case "download":
Download(request, response, writer);
break;
case "downloadhistory":
DownloadHistory(request, response, writer);
break;
case "convert":
Convert(request, response, writer);
break;
@ -93,6 +102,9 @@ public class IndexServlet extends HttpServlet
case "saveas":
SaveAs(request, response, writer);
break;
case "rename":
Rename(request, response, writer);
break;
}
}
@ -222,7 +234,7 @@ public class IndexServlet extends HttpServlet
String fileName = FileUtility.GetFileName((String) body.get("filename"));
String lang = cm.getCookie("ulang");
String filePass = body.get("filePass") != null ? (String) body.get("filePass") : null;
String fileUri = DocumentManager.GetDownloadUrl(fileName);
String fileUri = DocumentManager.GetDownloadUrl(fileName, true);
String fileExt = FileUtility.GetFileExtension(fileName);
FileType fileType = FileUtility.GetFileType(fileName);
String internalFileExt = DocumentManager.GetInternalExtension(fileType);
@ -317,7 +329,7 @@ public class IndexServlet extends HttpServlet
if (users.indexOf(user) == -1) {
String key = (String) body.get("key");
try {
TrackManager.commandRequest("forcesave", key); // create a command request with the forcesave method
TrackManager.commandRequest("forcesave", key, null); // create a command request with the forcesave method
} catch (Exception e) {
e.printStackTrace();
}
@ -430,14 +442,53 @@ public class IndexServlet extends HttpServlet
download(filePath.toString(), response, writer);
}
// download a file from history
private static void DownloadHistory(HttpServletRequest request, HttpServletResponse response, PrintWriter writer)
{
try {
if (DocumentManager.TokenEnabled()) {
String DocumentJwtHeader = ConfigManager.GetProperty("files.docservice.header");
String header = (String) request.getHeader(DocumentJwtHeader == null || DocumentJwtHeader.isEmpty() ? "Authorization" : DocumentJwtHeader);
if (header != null && !header.isEmpty()) {
String token = header.startsWith("Bearer ") ? header.substring(7) : header;
try {
Verifier verifier = HMACVerifier.newVerifier(DocumentManager.GetTokenSecret());
JWT jwt = JWT.getDecoder().decode(token, verifier);
} catch (Exception e) {
response.sendError(403, "JWT validation failed");
return;
}
} else {
response.sendError(403, "JWT validation failed");
return;
}
}
String fileName = FileUtility.GetFileName(request.getParameter("fileName"));
String userAddress = request.getParameter("userAddress");
String ver = request.getParameter("ver"); // Document version
String file = request.getParameter("file"); // File. If not defined, then Prev.*
String filePath = DocumentManager.HistoryPath(fileName, userAddress, ver, file);
download(filePath, response, writer);
} catch (Exception e) {
writer.write("{ \"error\": \"File not found\"}");
}
}
// download a file
private static void Download(HttpServletRequest request, HttpServletResponse response, PrintWriter writer)
{
try {
String fileName = FileUtility.GetFileName(request.getParameter("fileName"));
String userAddress = request.getParameter("userAddress");
String isEmbedded = request.getParameter("dmode");
if (DocumentManager.TokenEnabled()) {
if (DocumentManager.TokenEnabled() && isEmbedded == null) {
String DocumentJwtHeader = ConfigManager.GetProperty("files.docservice.header");
@ -508,6 +559,43 @@ public class IndexServlet extends HttpServlet
}
}
// rename a file
private static void Rename(HttpServletRequest request, HttpServletResponse response, PrintWriter writer) {
try {
Scanner scanner = new Scanner(request.getInputStream());
scanner.useDelimiter("\\A");
String bodyString = scanner.hasNext() ? scanner.next() : "";
scanner.close();
JSONParser parser = new JSONParser();
JSONObject body = (JSONObject) parser.parse(bodyString);
String newfilename = (String) body.get("newfilename");
String dockey = (String) body.get("dockey");
String origExt = "." + (String) body.get("ext");
String curExt = newfilename;
if(newfilename.indexOf(".") != -1) {
curExt = (String) FileUtility.GetFileExtension(newfilename);
}
if(origExt.compareTo(curExt) != 0) {
newfilename += origExt;
}
HashMap<String, String> meta = new HashMap<>();
meta.put("title", newfilename);
TrackManager.commandRequest("meta", dockey, meta);
} catch (Exception e) {
e.printStackTrace();
writer.write("{ \"error\" : 1, \"message\" : \"" + e.getMessage() + "\"}");
}
}
// process get request
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

View File

@ -20,16 +20,14 @@ package entities;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import helpers.DocumentManager;
import helpers.FileUtility;
import helpers.ServiceConverter;
import helpers.Users;
import helpers.*;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.*;
public class FileModel
@ -42,7 +40,7 @@ public class FileModel
public String token;
// create file model
public FileModel(String fileName, String lang, String actionData, User user)
public FileModel(String fileName, String lang, String actionData, User user, Boolean isEnableDirectUrl)
{
if (fileName == null) fileName = "";
fileName = fileName.trim(); // remove extra spaces in the file name
@ -53,8 +51,8 @@ public class FileModel
// set the document parameters
document = new Document();
document.title = fileName;
document.url = DocumentManager.GetDownloadUrl(fileName); // get file url
document.urlUser = DocumentManager.GetFileUri(fileName, false);
document.url = DocumentManager.GetDownloadUrl(fileName, true); // get file url
document.directUrl = isEnableDirectUrl ? DocumentManager.GetDownloadUrl(fileName, false) : ""; // get direct url
document.fileType = FileUtility.GetFileExtension(fileName).replace(".", ""); // get file extension from the file name
// generate document key
document.key = ServiceConverter.GenerateRevisionId(DocumentManager.CurUserHostAddress(null) + "/" + fileName + "/" + Long.toString(new File(DocumentManager.StoragePath(fileName, null)).lastModified()));
@ -80,6 +78,12 @@ public class FileModel
// set the editor config parameters
editorConfig = new EditorConfig(actionData);
editorConfig.callbackUrl = DocumentManager.GetCallback(fileName); // get callback url
editorConfig.coEditing = mode.equals("view") && user.id.equals("uid-0") ?
new HashMap<String, Object>() {{
put("mode", "strict");
put("change", false);
}} : null;
if (lang != null) editorConfig.lang = lang; // write language parameter to the config
@ -87,18 +91,18 @@ public class FileModel
editorConfig.templates = user.templates ? templates : null;
// write user information to the config (id, name and group)
editorConfig.user.id = user.id;
editorConfig.user.id = !user.id.equals("uid-0") ? user.id : null;
editorConfig.user.name = user.name;
editorConfig.user.group = user.group;
// write the absolute URL to the file location
editorConfig.customization.goback.url = DocumentManager.GetServerUrl(false) + "/IndexServlet";
changeType(mode, type, user);
changeType(mode, type, user, fileName);
}
// change the document type
public void changeType(String _mode, String _type, User user)
public void changeType(String _mode, String _type, User user, String fileName)
{
if (_mode != null) mode = _mode;
if (_type != null) type = _type;
@ -119,12 +123,12 @@ public class FileModel
// set document permissions
document.permissions = new Permissions(mode, type, canEdit, user);
if (type.equals("embedded")) InitDesktop(); // set parameters for the embedded document
if (type.equals("embedded")) InitDesktop(fileName); // set parameters for the embedded document
}
public void InitDesktop()
public void InitDesktop(String fileName)
{
editorConfig.InitDesktop(document.urlUser);
editorConfig.InitDesktop(DocumentManager.GetDownloadUrl(fileName, false) + "&dmode=emb");
}
// generate document token
@ -167,7 +171,7 @@ public class FileModel
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
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)
@ -178,8 +182,12 @@ public class FileModel
obj.put("user", user);
}
dataObj.put("fileType", FileUtility.GetFileExtension(document.title).substring(1));
dataObj.put("key", key);
dataObj.put("url", i == curVer ? document.url : DocumentManager.GetPathUri(verDir + File.separator + "prev" + FileUtility.GetFileExtension(document.title)));
dataObj.put("url", i == curVer ? document.url : DocumentManager.GetDownloadHistoryUrl(document.title, i, "prev" + FileUtility.GetFileExtension(document.title), true));
if (!document.directUrl.equals("")) {
dataObj.put("directUrl", i == curVer ? document.url : DocumentManager.GetDownloadHistoryUrl(document.title, i, "prev" + FileUtility.GetFileExtension(document.title), false));
}
dataObj.put("version", i);
if (i > 1) { //check if the version number is greater than 1
@ -195,11 +203,14 @@ public class FileModel
Map<String, Object> prev = (Map<String, Object>) histData.get(Integer.toString(i - 2)); // get the history data from the previous file version
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"));
dataObj.put("previous", prevInfo); // write information about previous file version to the data object
// write the path to the diff.zip archive with differences in this file version
dataObj.put("changesUrl", DocumentManager.GetPathUri(DocumentManager.VersionDir(histDir, i - 1) + File.separator + "diff.zip"));
Integer verdiff = i - 1;
String changesUrl = DocumentManager.GetDownloadHistoryUrl(document.title, verdiff, "diff.zip", true);
dataObj.put("changesUrl", changesUrl);
}
if (DocumentManager.TokenEnabled())
@ -246,7 +257,7 @@ public class FileModel
{
public String title;
public String url;
public String urlUser;
public String directUrl;
public String fileType;
public String key;
public Info info;
@ -265,8 +276,11 @@ public class FileModel
public Boolean modifyFilter;
public Boolean modifyContentControl;
public Boolean review;
public Boolean chat;
public List<String> reviewGroups;
public CommentGroups commentGroups;
public List<String> userInfoGroups;
//public Gson gson = new Gson();
// defines what can be done with a document
public Permissions(String mode, String type, Boolean canEdit, User user)
@ -280,15 +294,24 @@ public class FileModel
modifyFilter = !mode.equals("filter");
modifyContentControl = !mode.equals("blockcontent");
review = canEdit && (mode.equals("edit") || mode.equals("review"));
chat = !user.id.equals("uid-0");
reviewGroups = user.reviewGroups;
commentGroups = user.commentGroups;
userInfoGroups = user.userInfoGroups;
}
}
// the Favorite icon state
public class Info
{
public String owner = "Me";
public Boolean favorite;
public String uploaded = getDate();
private String getDate() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE MMM dd yyyy", Locale.US);
return simpleDateFormat.format(new Date());
}
}
// the editor config parameters
public class EditorConfig
@ -296,6 +319,7 @@ public class FileModel
public HashMap<String, Object> actionLink = null;
public String mode = "edit";
public String callbackUrl;
public HashMap<String, Object> coEditing = null;
public String lang = "en";
public String createUrl;
public List<Map<String, String>> templates;
@ -338,9 +362,15 @@ public class FileModel
public Goback goback;
public Boolean forcesave;
public Boolean submitForm;
public Boolean about;
public Boolean comments;
public Boolean feedback;
public Customization()
{
about = true;
comments = true;
feedback = true;
forcesave = false;
goback = new Goback();
}

View File

@ -31,8 +31,9 @@ public class User {
public List<String> deniedPermissions;
public List<String> descriptions;
public Boolean templates;
public List<String> userInfoGroups;
public User(String id, String name, String email, String group, List<String> reviewGroups, CommentGroups commentGroups,
public User(String id, String name, String email, String group, List<String> reviewGroups, CommentGroups commentGroups, List<String> userInfoGroups,
Boolean favorite, List<String> deniedPermissions, List<String> descriptions, Boolean templates) {
this.id = id;
this.name = name;
@ -44,5 +45,6 @@ public class User {
this.deniedPermissions = deniedPermissions;
this.descriptions = descriptions;
this.templates = templates;
this.userInfoGroups = userInfoGroups;
}
}

View File

@ -130,7 +130,20 @@ public class DocumentManager
String hostAddress = CurUserHostAddress(userAddress); // get current user host address
String serverPath = request.getSession().getServletContext().getRealPath(""); // get the server url
String storagePath = ConfigManager.GetProperty("storage-folder"); // get the storage directory
String directory = serverPath + storagePath + File.separator + hostAddress + File.separator;
File f = new File(storagePath);
if (f.isAbsolute()) {
if (!f.exists()) {
if (Files.isWritable(Paths.get(storagePath.substring(0, storagePath.lastIndexOf(File.separator))))) {
f.mkdirs();
} else {
throw new SecurityException("No write permission to path: " + f.toPath());
}
} else if (f.exists() && f.isFile()) {
throw new SecurityException("The path to the file is specified instead of the folder");
}
}
String directory = !f.isAbsolute() ? serverPath + storagePath + File.separator + hostAddress + File.separator : storagePath + File.separator;
File file = new File(directory);
@ -151,6 +164,22 @@ public class DocumentManager
return directory + FileUtility.GetFileName(fileName);
}
// get the path to history file
public static String HistoryPath(String fileName, String userAddress, String version, String file)
{
String hostAddress = CurUserHostAddress(userAddress);
String serverPath = request.getSession().getServletContext().getRealPath("");
String storagePath = ConfigManager.GetProperty("storage-folder");
String directory = serverPath + storagePath + File.separator + hostAddress + File.separator;
if (new File(storagePath).isAbsolute()) {
directory = FilesRootPath(userAddress);
}
directory = directory + fileName + "-hist" + File.separator + version + File.separator + file;
return directory;
}
// get the path to the forcesaved file version
public static String ForcesavePath(String fileName, String userAddress, Boolean create)
{
@ -320,13 +349,20 @@ public class DocumentManager
{
String serverPath = GetServerUrl(forDocumentServer);
String storagePath = ConfigManager.GetProperty("storage-folder");
File f = new File(storagePath);
String hostAddress = CurUserHostAddress(null);
String filePath = serverPath + "/" + storagePath + "/" + hostAddress + "/" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()).replace("+", "%20");
if (f.isAbsolute() && f.isFile()) {
filePath = GetDownloadUrl(fileName, true);
if (!Files.isWritable(f.toPath())) {
throw new SecurityException("No write permission to path: " + f.toPath());
}
}
return filePath;
}
catch (UnsupportedEncodingException e)
catch (Exception e)
{
return "";
}
@ -414,12 +450,31 @@ public class DocumentManager
}
// get url to download a file
public static String GetDownloadUrl(String fileName) {
String serverPath = GetServerUrl(true);
public static String GetDownloadUrl(String fileName, Boolean forDocumentServer) {
String serverPath = GetServerUrl(forDocumentServer);
String hostAddress = CurUserHostAddress(null);
try
{
String query = "?type=download&fileName=" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()) + "&userAddress=" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
String userAddress = forDocumentServer ? "&userAddress=" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString()) : "";
String query = "?type=download&fileName=" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()) + userAddress;
return serverPath + "/IndexServlet" + query;
}
catch (UnsupportedEncodingException e)
{
return "";
}
}
// get url to download a file to History prev.*
public static String GetDownloadHistoryUrl(String fileName, Integer version, String file, Boolean forDocumentServer) {
String serverPath = GetServerUrl(forDocumentServer);
String hostAddress = CurUserHostAddress(null);
try
{
String userAddress = forDocumentServer ? "&userAddress=" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString()) : "";
String query = "?type=downloadhistory&fileName=" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()) + userAddress;
query = query + "&ver=" + version + "&file=" + URLEncoder.encode(file, java.nio.charset.StandardCharsets.UTF_8.toString());
return serverPath + "/IndexServlet" + query;
}
@ -515,4 +570,19 @@ public class DocumentManager
{
return ConfigManager.GetProperty("files.docservice.secret");
}
// get languages
public static Map<String, String> GetLanguages()
{
String langs = ConfigManager.GetProperty("files.docservice.languages");
List<String> langsAndKeys = Arrays.asList(langs.split("\\|"));
Map<String, String> languages = new LinkedHashMap<>();
langsAndKeys.forEach((str) -> {
String[] couple = str.split(":");
languages.put(couple[0], couple[1]);
});
return languages;
}
}

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