Compare commits

..

202 Commits

Author SHA1 Message Date
c9baa474be python-raw: add sr-only 2023-08-11 18:42:23 +04:00
48185674d4 python-raw: up html 2023-08-11 18:42:12 +04:00
dbca11e85c python-raw: move js 2023-08-11 18:41:45 +04:00
d21a732859 python-raw: move css 2023-08-11 18:40:57 +04:00
b96a6fac53 python-raw: add js 2023-08-08 14:43:34 +04:00
b01af348a7 python-raw: add html 2023-08-08 14:43:17 +04:00
c2443d3106 python-raw: add styles 2023-08-08 14:42:56 +04:00
5fa3f4c57f python-raw: add formats endpoint 2023-08-08 14:41:58 +04:00
efd7e1b6e7 python-raw: add format methods 2023-08-08 14:41:20 +04:00
259ee63eea python-raw: temp hide server 2023-08-08 14:41:00 +04:00
453b9835b7 python-raw: fix formats 2023-08-08 14:40:27 +04:00
89e6544b79 Merge branch 'feature/python-matrix-formats' into feature/python-conversion 2023-08-04 12:31:53 +04:00
32a60c09aa python: add public and private document-server urls to the compose 2023-08-02 10:49:34 +04:00
5a03024cd3 python: add support for the internal network for the track endpoint 2023-08-02 10:49:34 +04:00
cb6416c481 python: sort imports 2023-08-02 10:49:34 +04:00
55e4247687 python: add tests for proxy manager 2023-08-02 10:49:34 +04:00
a0620905b2 python: add proxy manager to resolve the document-server url 2023-08-02 10:49:34 +04:00
3fcef4096a python: remove the strict CORS hint 2023-08-02 10:49:34 +04:00
4e5349c1c4 python: add tests for specifying public and private document-server urls 2023-08-02 10:49:34 +04:00
538eec1ff3 python: add support for specifying public and private document-server urls 2023-08-02 10:49:34 +04:00
df7cfda2fb Merge pull request #429 from ONLYOFFICE/fix/java-spring-save-previous
java-spring: add a step to save the previous version of the file during processing save
2023-07-31 15:37:55 +03:00
9ebef04f3d Merge pull request #415 from ONLYOFFICE/feature/ruby-docker
ruby: add support for containerization
2023-07-31 15:36:46 +03:00
a6ed970bca Merge pull request #413 from ONLYOFFICE/feature/python-docker
python: add support for containerization
2023-07-31 15:36:06 +03:00
7f659bc95e Merge pull request #428 from ONLYOFFICE/fix/php-lint-action
php: update php lint action to latest changes
2023-07-31 09:46:00 +03:00
3c4a1c1c31 Merge pull request #425 from ONLYOFFICE/feature/php-server-configuration
php: simplify server configuration
2023-07-29 15:42:55 +03:00
2bae0567ad nodejs: fix for ie (496a150620) 2023-07-28 17:26:53 +03:00
c06f2a5a29 python: replace the previous implementation of formats 2023-07-28 18:01:05 +04:00
8aed04753c python: add tests for the format module 2023-07-28 18:01:01 +04:00
15ed02e556 python: add format module 2023-07-28 12:06:30 +04:00
fb66dc8423 python: add tests for the codable module 2023-07-28 12:06:30 +04:00
541ace8132 python: add codable module 2023-07-28 12:06:30 +04:00
8b5cebeb3f python: add document-formats submodule 2023-07-28 12:06:30 +04:00
419fbf90f9 python: update paths to the new location of templates 2023-07-27 17:10:50 +04:00
2d637b88df python: move document-templates to the assets directory 2023-07-27 17:10:50 +04:00
13e2d5b33c python: add recipes to work with docker 2023-07-27 16:12:43 +04:00
f208fe1939 python: add docker files 2023-07-27 16:12:43 +04:00
b3cc35cb5e python: add support for the ADDRESS env variable 2023-07-27 16:12:43 +04:00
8b316b0786 python: move the lint recipe to the bottom of file 2023-07-27 16:12:43 +04:00
c57fcbfd90 python: delete recipes sorting in the help recipe 2023-07-27 16:12:43 +04:00
1939b85c8c ruby: disable strict hosts policy 2023-07-27 11:26:40 +04:00
ee0ac33820 ruby: add recipes to work with docker 2023-07-27 11:26:40 +04:00
c93579d98f ruby: add docker files 2023-07-27 11:26:40 +04:00
61a9e122cd ruby: move the lint recipe to the bottom of file 2023-07-27 11:26:40 +04:00
e88a9f5bed ruby: delete recipes sorting in the help recipe 2023-07-27 11:26:40 +04:00
f1ce0fb415 ruby: rename server recipes 2023-07-27 11:26:40 +04:00
3b142d92fc php: update urls to new endpoints 2023-07-26 17:42:48 +04:00
1898da660e php: simplify server configuration 2023-07-26 17:42:48 +04:00
0629cf0797 php: add HTTPStatus enum 2023-07-26 17:42:48 +04:00
7737670a6d php: delete IIS config 2023-07-26 17:42:48 +04:00
5bdcac42e3 php: add recipes to start the server 2023-07-26 17:42:48 +04:00
4b8ffa26cc php: add fpm config 2023-07-26 17:41:53 +04:00
a4b6fcb512 java-spring: add a step to save the previous version of the file during processing save 2023-07-26 17:34:07 +04:00
523b10c979 php: update php lint action to latest changes 2023-07-26 17:03:50 +04:00
1d4bc95c29 Merge pull request #424 from ONLYOFFICE/feature/php-configuration-manager
php: add support for configuration via environment variables
2023-07-26 15:31:05 +03:00
e94a4863aa php: replace json config with configuration manager 2023-07-26 12:07:58 +04:00
edda981ab7 php: append configuration directory to test recipe 2023-07-26 12:07:55 +04:00
65ebf9a5b1 php: add configuration manager tests 2023-07-26 12:07:55 +04:00
a081cd1f06 php: add configuration manager 2023-07-26 12:07:55 +04:00
04c5ee8cd7 php: add URL tests 2023-07-26 12:07:55 +04:00
3ebf3fabee php: add URL class 2023-07-26 12:07:52 +04:00
403efc1325 php: add tests for the path absolute function 2023-07-26 11:27:50 +04:00
7deedcaa5e php: enrich Path with new methods 2023-07-26 11:27:50 +04:00
161e26dd8a Merge pull request #423 from ONLYOFFICE/feature/php-missed-tests
php: add missed path tests and rewrite path methods a bit
2023-07-26 10:21:30 +03:00
09804349fa php: update path instances due to new methods 2023-07-24 14:22:28 +04:00
83a83f4f5d php: fix make test receipt 2023-07-24 14:22:28 +04:00
79ee987003 php: add path tests 2023-07-24 14:22:28 +04:00
434484cac3 php: separate path normalization from join 2023-07-24 14:22:25 +04:00
a0bafb0e4b php: simplify path string generation 2023-07-24 12:41:43 +04:00
184aded727 php: remove path separator from constructor options 2023-07-24 12:41:40 +04:00
7db708e559 Merge pull request #422 from ONLYOFFICE/feature/php-normalize-dependencies
php: pin and normalize existing dependencies, add new ones
2023-07-21 14:42:41 +03:00
3b3116f56e php: license link 2023-07-21 14:42:18 +03:00
15c70f43d7 Merge pull request #421 from ONLYOFFICE/feature/php-restore-endpoint
php: add restore endpoint
2023-07-21 09:49:00 +03:00
39af4be045 php: restore to changelog 2023-07-21 09:48:35 +03:00
c9dc4862ed php: add ignore file 2023-07-20 16:15:46 +04:00
122d41e307 php: add lint and test recieps 2023-07-20 16:15:44 +04:00
2880db7383 php: add install recipes 2023-07-20 16:14:24 +04:00
c0f23a4fc2 php: add makefile 2023-07-20 16:14:24 +04:00
1a49d8dd03 php: normalize codesniffer config file 2023-07-20 16:14:24 +04:00
180f287c07 php: delete composer scripts 2023-07-20 16:14:24 +04:00
37c33965c8 php: move autoload to the production section 2023-07-20 16:14:24 +04:00
0861732dbe php: replace local jwt with jwt as a dependency 2023-07-20 16:14:24 +04:00
d3220c7a91 php: add phpunit 2023-07-20 16:14:24 +04:00
450cafdae3 php: move mbstring extension to production dependencies 2023-07-20 16:14:24 +04:00
62abe3e569 php: pin dependency versions 2023-07-20 16:14:24 +04:00
8b2fbff3b7 php: update lock file 2023-07-20 16:14:24 +04:00
acf243ee3e php: add restore endpoint 2023-07-19 15:29:27 +04:00
66c38ded4a php: add the common module with Path class 2023-07-19 15:29:27 +04:00
58a73190d4 Merge pull request #420 from ONLYOFFICE/fix/php-assets-path
php: fix a new path to the assets directory
2023-07-19 09:41:21 +03:00
ae7a208831 php: fix a new path to the assets directory 2023-07-18 13:52:13 +04:00
2d83f3f39c Merge pull request #419 from ONLYOFFICE/feature/ruby-restore-endpoint
ruby: add restore endpoint
2023-07-18 12:20:46 +03:00
2aed1e3a83 ruby: restore to changelog 2023-07-18 12:19:57 +03:00
001a99b502 Merge pull request #418 from ONLYOFFICE/fix/ruby-sorbet-commands
ruby: hide sorbet commands for unsupported platforms
2023-07-18 12:18:26 +03:00
a7a9f997d5 ruby: add restore endpoint 2023-07-18 10:35:31 +04:00
4c3dc96e30 Merge pull request #417 from ONLYOFFICE/fix/ruby-config-manager-typo
ruby: fix typo in config manager name
2023-07-18 09:19:46 +03:00
7fe1ae27b4 Merge pull request #416 from ONLYOFFICE/feature/ruby-configuration-manager-tests
ruby: add missed configuration manager tests
2023-07-18 09:19:09 +03:00
dce840c627 ruby: hide sorbet commands for unsupported platforms 2023-07-17 18:50:17 +04:00
4f832ac2f7 ruby: fix typo in config manager name 2023-07-17 18:42:59 +04:00
e7623e29d7 ruby: add test recipe 2023-07-17 18:26:09 +04:00
16dd8a55e5 ruby: add missed configuration manager tests 2023-07-17 18:26:09 +04:00
dca68bf0d1 ruby: add missed imports 2023-07-17 18:26:09 +04:00
f028f1ba2f ruby: add test-unit as a dependency to satisfy rake 2023-07-17 18:26:09 +04:00
5c8867dd20 ruby: move the configuration to its directory 2023-07-17 18:26:09 +04:00
27eea60fc3 Merge pull request #414 from ONLYOFFICE/feature/python-restore-endpoint
python: add restore endpoint
2023-07-17 15:12:00 +03:00
c285b49d3b python: restore to changelog 2023-07-17 15:11:28 +03:00
70c86f3054 python: add onRequestRestore callback 2023-07-14 14:55:57 +04:00
00e5466a0c python: add restore endpoint 2023-07-14 14:55:57 +04:00
12a366a28a python: sort imports 2023-07-14 14:55:12 +04:00
b4918cf493 python: delete unused imports 2023-07-14 14:55:12 +04:00
b2b21980d1 python: add error response 2023-07-14 14:55:12 +04:00
09a97c0f66 python: add tests for the http functions 2023-07-14 14:55:12 +04:00
5db65ef062 python: add functions to declare the http method for the endpoint 2023-07-14 14:55:12 +04:00
5164380336 python: add a function to find a user by his ID 2023-07-14 14:55:12 +04:00
26c5cd0a83 python: remove unused import 2023-07-14 14:55:12 +04:00
bff8c83283 Merge pull request #410 from ONLYOFFICE/feature/python-server-configuration
python: simplify server configuration
2023-07-14 10:43:29 +03:00
827bd3981f python: add missed django_settings_module 2023-07-13 17:10:10 +04:00
e8599c7c56 python: add recipes to start the server 2023-07-13 17:10:06 +04:00
0a3b951eb6 Merge pull request #412 from ONLYOFFICE/feature/ruby-respect-gitignore
ruby: respect gitignore
2023-07-13 15:25:59 +03:00
988da27e3f python: simplify server configuration 2023-07-13 16:23:09 +04:00
a697219dcf ruby: add receipt stages to generate bin files 2023-07-13 16:04:54 +04:00
7649e7f51e ruby: delete files that should be ignored 2023-07-13 16:02:24 +04:00
108b5ea317 ruby: move example-specific ignored files to the root of the example 2023-07-13 16:02:24 +04:00
4ea0760803 Merge pull request #411 from ONLYOFFICE/feature/ruby-server-configuration
ruby: simplify server configuration
2023-07-13 14:51:07 +03:00
c558098deb ruby: delete sqlite3 2023-07-13 14:48:57 +03:00
4a61093343 Merge pull request #409 from ONLYOFFICE/feature/python-configuration-manager
python: add support for configuration via environment variables
2023-07-13 14:46:34 +03:00
2af1f56aa7 ruby: delete sqlite3 as it's not used 2023-07-13 14:02:30 +04:00
6780feafa6 ruby: add recipes to start the server 2023-07-13 14:02:26 +04:00
23b4ffc104 ruby: simplify server configuration 2023-07-12 13:44:20 +04:00
46a9fffb0e 7.4 formats 2023-07-12 11:46:15 +03:00
0ccc98e83f python: standardize the format of URLs 2023-07-10 16:29:59 +04:00
7f59c15112 python: replace the global config with the configuration manager 2023-07-10 16:29:59 +04:00
455f2ee823 python: add tests for the configuration manager 2023-07-10 16:29:51 +04:00
3076a9bc0e python: add configuration manager 2023-07-10 16:05:30 +04:00
c605607b5e python: add test recipe 2023-07-10 14:52:21 +04:00
e05afc931a python: add tests for the string boolean function 2023-07-10 14:49:25 +04:00
53aeb19e2f python: add the common module with string boolean function 2023-07-10 14:46:33 +04:00
14a557be69 Merge pull request #396 from ONLYOFFICE/feature/ruby-configuration-environment
ruby: support for configuration via environment variables
2023-07-10 10:28:24 +03:00
666b6f8a03 Merge pull request #408 from ONLYOFFICE/fix/ruby-sorbet-platforms
ruby: fix sorbet installation on unsupported platforms
2023-07-07 15:33:10 +03:00
ebddc8114a ruby: fix sorbet installation on unsupported platforms 2023-07-05 12:26:00 +04:00
fa76819b2d Merge pull request #403 from ONLYOFFICE/feature/python-normalize-dependencies
python: pin and add new dependencies
2023-07-05 10:02:00 +03:00
69aa25880a python: 3rd party licenses 2023-07-05 10:00:21 +03:00
7cd79280ff python: add help, dev, lint, prod recipes to Makefile 2023-07-04 16:57:03 +04:00
4535bfe661 python: add development dependencies 2023-07-04 16:56:57 +04:00
01cabdf1e5 python: pin python version 2023-07-04 14:12:11 +04:00
8b15a0e417 python: pin dependency versions 2023-07-04 14:12:11 +04:00
451b3b7a38 ruby: standardize the format of the URIs in the configuration 2023-07-04 13:52:40 +04:00
952b495c4d ruby: support for configuration via environment variables 2023-07-04 13:52:37 +04:00
1cd3642de8 Merge pull request #407 from ONLYOFFICE/feature/reference-source
Feature/reference source
2023-07-04 12:49:58 +03:00
a4f49cb86b nodejs: change reference source to changelog 2023-07-04 12:45:15 +03:00
9ca722329f nodejs: 1.6.0 (50a4ddbd11) 2023-07-04 10:51:24 +03:00
496a150620 nodejs: onRequestReferenceSource method 2023-06-30 11:29:38 +03:00
983a92d9e0 nodejs: function for getting of file extension 2023-06-30 11:27:48 +03:00
ad94016a85 Merge remote-tracking branch 'remotes/origin/master' into develop
# Conflicts:
#	CHANGELOG.md
#	web/documentserver-example/php/functions.php
#	web/documentserver-example/php/views/DocEditorView.php
2023-06-29 11:13:23 +05:00
fcb807471f Merge pull request #406 from ONLYOFFICE/release/1.6.0
Release/1.6.0
2023-06-29 11:07:55 +05:00
50a4ddbd11 1.6.0 2023-06-29 11:00:42 +05:00
01d1dc4274 Merge pull request #405 from ONLYOFFICE/hotfix/csharp-reload-filelist-upload
Hotfix/csharp reload filelist upload
2023-06-28 11:20:58 +05:00
1447b304eb Merge pull request #404 from ONLYOFFICE/hotfix/delete-old-file-after-convert
Hotfix/delete old file after convert
2023-06-28 11:20:24 +05:00
8e79c6448f csharp: reload after click on edit or view in upload window 2023-06-27 12:08:59 +03:00
badf3c7d49 csharp-mvc: reload after click on edit or view in upload window 2023-06-27 12:08:35 +03:00
342b31f7d7 java-spring: delete original file after convert 2023-06-27 11:32:28 +03:00
0ae8f5d396 java: delete original file after convert 2023-06-27 11:09:43 +03:00
7a238c2b73 Merge branch 'release/v7.4.0' into hotfix/delete-old-file-after-convert 2023-06-27 10:55:39 +03:00
0b4c67e552 Merge branch 'hotfix/headers-charset-on-upload-convert' into release/v7.4.0 2023-06-27 12:10:42 +05:00
f5391051b1 ruby: delete original file after convert 2023-06-27 09:59:00 +03:00
01c8a940d4 csharp: fix error with convert response (6aa80c4a8c) 2023-06-26 17:33:42 +05:00
579992e40b Merge pull request #402 from ONLYOFFICE/hotfix/csharp
fixed: generating key
2023-06-26 15:42:14 +05:00
3a2218a466 Merge pull request #401 from ONLYOFFICE/hotfix/ruby-filelist-reload-fix
ruby: reload after click on edit or view in upload window
2023-06-26 15:40:55 +05:00
0ea28f525f Merge pull request #400 from ONLYOFFICE/hotfix/disable-cors-on-download
php: disable CORS on download
2023-06-26 15:40:27 +05:00
33363f6144 fixed: generating key 2023-06-26 13:01:03 +03:00
da8bdca022 ruby: reload after click on edit or view in upload window 2023-06-26 12:52:17 +03:00
c4eccc5ee8 Merge pull request #398 from ONLYOFFICE/hotfix/php-sample-key-fix
php: undefined "sample" key fix
2023-06-26 14:24:02 +05:00
ab13745cf6 Merge pull request #399 from ONLYOFFICE/hotfix/referenceData
Hotfix/reference data
2023-06-26 14:23:09 +05:00
97f07e4275 ruby: fixed directUrl property 2023-06-26 12:20:07 +03:00
7c3e250797 php: undefined "sample" key fix 2023-06-26 11:40:57 +03:00
32ab794f11 python: fixed directUrl property 2023-06-26 11:23:03 +03:00
800ef84f84 csharp: fixed directUrl property 2023-06-26 11:18:52 +03:00
a7e4036667 php: fixed directUrl property 2023-06-26 11:11:52 +03:00
4f589a7394 java: fixed directUrl property 2023-06-26 11:05:01 +03:00
a3abb58d72 java-spring: fixed directUrl property 2023-06-26 10:21:21 +03:00
17536df8e5 csharp-mvc: fixed directUrl property 2023-06-26 10:08:44 +03:00
2e8a483a0c csharp-mvc: fix error with convert response (d9a79e20d7) 2023-06-26 11:47:38 +05:00
a0aa7b4fd0 php: disable CORS on download 2023-06-23 13:38:06 +03:00
8b720beffa Merge pull request #397 from ONLYOFFICE/hotfix/java-spring
java-spring: fixed bug with update external links reference data
2023-06-23 11:36:50 +05:00
a1c286cbaa java-spring: fixed bug with update external links reference data 2023-06-23 09:05:26 +03:00
fc377b967d Merge pull request #395 from ONLYOFFICE/hotfix/disable-cors-for-download
python: disable CORS in download
2023-06-22 17:43:07 +05:00
b2de5eff4c Merge pull request #394 from ONLYOFFICE/hotfix/python-reload-file-list
python: reload file list after start of editing
2023-06-22 17:42:31 +05:00
02439f3699 Merge pull request #393 from ONLYOFFICE/hotfix/php-fixes-release-740
Hotfix/php fixes for release 7.4.0
2023-06-22 17:41:28 +05:00
2429f21a84 python: disable CORS in download 2023-06-22 12:13:36 +03:00
aa0a4b5400 php: encoded space used 2023-06-22 11:48:51 +03:00
a28300848b python: reload file list after start of editing 2023-06-22 11:22:56 +03:00
fec0e87218 php: fix warnings in editor 2023-06-22 10:46:36 +03:00
efbace1e8b php: correct name of file when downloading 2023-06-22 10:30:37 +03:00
35e479355a php: convert warning fix 2023-06-22 10:22:17 +03:00
32c91b9016 Merge pull request #392 from ONLYOFFICE/hotfix/users-permissions-fix
java: null instead of empty lists
2023-06-21 16:01:01 +05:00
183d165c00 java: null instead of empty lists 2023-06-21 12:40:35 +03:00
a996f2c3c3 Merge pull request #390 from ONLYOFFICE/hotfix/content-disposition-for-download-encode
python: filename encoding for content-disposition header
2023-06-21 13:19:06 +05:00
782243eb86 Merge pull request #391 from ONLYOFFICE/hotfix/java-spring
Hotfix/java spring
2023-06-21 13:18:15 +05:00
f058d68126 fix bug with switching from view to edit 2023-06-21 11:11:33 +03:00
a8f07fce4d fix bug with upload file size more 1MB 2023-06-21 11:11:28 +03:00
025bd1068d fix bug with file conversion 2023-06-21 11:11:17 +03:00
1da93ce071 python: filename encoding for content-disposition header 2023-06-21 09:37:26 +03:00
837e34de37 Merge pull request #389 from ONLYOFFICE/hotfix/convert-status-code-type
ruby: fix conversion service status type
2023-06-20 13:52:27 +05:00
20c4ec1b78 ruby: fix conversion service status type 2023-06-20 11:30:40 +03:00
196 changed files with 7734 additions and 3465 deletions

View File

@ -25,7 +25,5 @@ jobs:
php-version: '8.2'
tools: cs2pr, phpcs
- name: Run phpcs
run: |
phpcs --version
phpcs -q --extensions=php,module,inc,install,test,profile,theme,info --ignore=node_modules,bower_components,vendor,css,js,lib --standard=./ruleset.xml ./
- name: Lint
run: phpcs .

5
.gitignore vendored
View File

@ -22,8 +22,3 @@
/web/documentserver-example/csharp/packages
/web/documentserver-example/csharp-mvc/packages
/web/documentserver-example/java-spring/documents/
/web/documentserver-example/ruby/.bundle
/web/documentserver-example/ruby/db/*.sqlite3
/web/documentserver-example/ruby/db/*.sqlite3-journal
/web/documentserver-example/ruby/log/*
/web/documentserver-example/ruby/tmp

12
.gitmodules vendored
View File

@ -2,10 +2,6 @@
path = web/documentserver-example/java/src/main/resources/assets
url = https://github.com/ONLYOFFICE/document-templates
branch = main/en
[submodule "web/documentserver-example/python/assets"]
path = web/documentserver-example/python/assets
url = https://github.com/ONLYOFFICE/document-templates
branch = main/en
[submodule "web/documentserver-example/csharp-mvc/assets"]
path = web/documentserver-example/csharp-mvc/assets
url = https://github.com/ONLYOFFICE/document-templates
@ -38,3 +34,11 @@
path = web/documentserver-example/php/assets/document-formats
url = https://github.com/ONLYOFFICE/document-formats
branch = master
[submodule "web/documentserver-example/python/assets/document-templates"]
path = web/documentserver-example/python/assets/document-templates
url = https://github.com/ONLYOFFICE/document-templates
branch = main/en
[submodule "web/documentserver-example/python/assets/document-formats"]
path = web/documentserver-example/python/assets/document-formats
url = https://github.com/ONLYOFFICE/document-formats
branch = master

View File

@ -303,13 +303,25 @@ PHP_CodeSniffer - PHP_CodeSniffer is a set of two PHP scripts; the main phpcs sc
License: BSD-3-Clause
License File: PHP_CodeSniffer.license
PHPUnit - The PHP Unit Testing framework. (https://github.com/sebastianbergmann/phpunit/blob/main/LICENSE)
License: BSD 3-Clause
License File: phpunit.license
web/documentserver-example/python
django-stubs - PEP-484 stubs for Django. (https://github.com/typeddjango/django-stubs/blob/master/LICENSE.md)
License: MIT
License File: django-stubs.license
Django - Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. Thanks for checking it out. (https://github.com/django/django/blob/main/LICENSE)
License: BSD-3-Clause
License File: Django.license
flake8 - flake8 is a python tool that glues together pycodestyle, pyflakes, mccabe, and third-party plugins to check the style and quality of some python code. (https://github.com/PyCQA/flake8/blob/main/LICENSE)
License: MIT
License File: flake8.license
jQuery.BlockUI - The jQuery BlockUI Plugin lets you simulate synchronous behavior when using AJAX, without locking the browser. (https://github.com/malsup/blockui/)
License: MIT, GPL
License File: jQuery.BlockUI.license
@ -334,6 +346,10 @@ jQuery.UI - jQuery UI is an open source library of interface components —
License: MIT
License File: jQuery.UI.license
mypy - Optional static typing for Python. (https://github.com/python/mypy/blob/master/LICENSE)
License: MIT
License File: mypy.license
PyJWT - A Python implementation of RFC 7519. (https://github.com/jpadilla/pyjwt/blob/master/LICENSE)
License: MIT
License File: PyJWT.license
@ -346,6 +362,10 @@ requests - Requests allows you to send HTTP/1.1 requests extremely easily.
License: Apache 2.0
License File: requests.license
typeshed - Collection of library stubs for Python, with static types. (https://github.com/python/typeshed/blob/main/LICENSE)
License: Apache 2.0
License File: typeshed.license
web/documentserver-example/ruby
@ -417,10 +437,6 @@ sorbet - A fast, powerful type checker designed for Ruby. (https://github
License: Apache License 2.0
License File: sorbet.license
sqlite3 - This module allows Ruby programs to interface with the SQLite3 database engine (www.sqlite.org). (https://github.com/sparklemotion/sqlite3-ruby/blob/master/LICENSE)
License: BSD-3-Clause
License File: sqlite3.license
tapioca - The swiss army knife of RBI generation. (https://github.com/Shopify/tapioca/blob/v0.11.6/LICENSE.txt)
License: MIT
License File: tapioca.license

View File

@ -1,10 +1,16 @@
# Change Log
- nodejs: change reference source
- php: using a repo with a list of formats
- nodejs: using a repo with a list of formats
- nodejs: delete file without reloading the page
- nodejs: getting history by a separate request
- nodejs: restore from history
- python: restore from history
- ruby: restore from history
- php: restore from history
## 1.6.0
- nodejs: setUsers for region protection
- si skin languages
- fix "no" skin languages

View File

@ -220,6 +220,7 @@ namespace OnlineEditorsExampleMVC.Helpers
var fileName = GetCorrectName(demoName); // get a file name with an index if the file with such a name already exists
File.Copy(HttpRuntime.AppDomainAppPath + demoPath + demoName, StoragePath(fileName)); // copy file to the storage directory
File.SetLastWriteTime(StoragePath(fileName), DateTime.Now);
return fileName;
}

View File

@ -236,6 +236,7 @@ if (typeof jQuery != "undefined") {
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
document.location.reload();
});
jq(document).on("click", "#beginView:not(.disable)", function () {
@ -244,6 +245,7 @@ if (typeof jQuery != "undefined") {
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
document.location.reload();
});
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {

View File

@ -249,14 +249,14 @@ namespace OnlineEditorsExampleMVC
// get the url and file type of the converted file
Dictionary<string, string> newFileData;
var result = ServiceConverter.GetConvertedData(downloadUri.ToString(), extension, internalExtension, key, true, out newFileData, filePass, lang);
var newFileUri = newFileData["fileUrl"];
var newFileType = "." + newFileData["fileType"];
if (result != 100)
{
context.Response.Write("{ \"step\" : \"" + result + "\", \"filename\" : \"" + fileName + "\"}");
return;
}
var newFileUri = newFileData["fileUrl"];
var newFileType = "." + newFileData["fileType"];
// get a file name of an internal file extension with an index if the file with such a name already exists
var correctName = DocManagerHelper.GetCorrectName(Path.GetFileNameWithoutExtension(fileName) + newFileType);
@ -659,10 +659,12 @@ namespace OnlineEditorsExampleMVC
return;
}
var directUrl = (bool)body["directUrl"];
var data = new Dictionary<string, object>() {
{ "fileType", (Path.GetExtension(fileName) ?? "").ToLower() },
{ "fileType", (Path.GetExtension(fileName) ?? "").ToLower().Trim('.') },
{ "url", DocManagerHelper.GetDownloadUrl(fileName)},
{ "directUrl", DocManagerHelper.GetDownloadUrl(fileName) },
{ "directUrl", directUrl ? DocManagerHelper.GetDownloadUrl(fileName, false) : null },
{ "referenceData", new Dictionary<string, string>()
{
{ "fileKey", jss.Serialize(new Dictionary<string, object>{
@ -670,7 +672,7 @@ namespace OnlineEditorsExampleMVC
{"userAddress", HttpUtility.UrlEncode(DocManagerHelper.CurUserHostAddress(HttpContext.Current.Request.UserHostAddress))}
})
},
{"instanceId", DocManagerHelper.GetServerUrl(false) }
{ "instanceId", DocManagerHelper.GetServerUrl(false) }
}
},
{ "path", fileName }

View File

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

View File

@ -489,13 +489,13 @@ namespace OnlineEditorsExample
// get the url and file type of the converted file
Dictionary<string, string> newFileData;
var result = ServiceConverter.GetConvertedData(fileUrl.ToString() , extension, internalExtension, key, true, out newFileData, filePass, lang);
var newFileUri = newFileData["fileUrl"];
var newFileType = "." + newFileData["fileType"];
if (result != 100)
{
return "{ \"step\" : \"" + result + "\", \"filename\" : \"" + _fileName + "\"}";
}
var newFileUri = newFileData["fileUrl"];
var newFileType = "." + newFileData["fileType"];
// get a file name of an internal file extension with an index if the file with such a name already exists
var fileName = GetCorrectName(Path.GetFileNameWithoutExtension(_fileName) + newFileType);

View File

@ -632,6 +632,7 @@ namespace OnlineEditorsExample
var filePath = _Default.StoragePath(FileName, null);
File.Copy(HttpRuntime.AppDomainAppPath + demoPath + demoName, filePath); // copy this file to the storage directory
File.SetLastWriteTime(filePath, DateTime.Now);
// create a json file with file meta data
var id = request.Cookies.GetOrDefault("uid", null);

View File

@ -477,10 +477,12 @@ namespace OnlineEditorsExample
return;
}
var directUrl = (bool) body["directUrl"];
var data = new Dictionary<string, object>() {
{ "fileType", (Path.GetExtension(fileName) ?? "").ToLower() },
{ "fileType", (Path.GetExtension(fileName) ?? "").ToLower().Trim('.') },
{ "url", DocEditor.getDownloadUrl(fileName)},
{ "directUrl", DocEditor.getDownloadUrl(fileName) },
{ "directUrl", directUrl ? DocEditor.getDownloadUrl(fileName, false) : null},
{ "referenceData", new Dictionary<string, string>()
{
{ "fileKey", jss.Serialize(new Dictionary<string, object>{

View File

@ -236,6 +236,7 @@ if (typeof jQuery != "undefined") {
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
document.location.reload();
});
jq(document).on("click", "#beginView:not(.disable)", function () {
@ -244,6 +245,7 @@ if (typeof jQuery != "undefined") {
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
document.location.reload();
});
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {

View File

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

View File

@ -36,6 +36,7 @@ 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.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
@ -64,6 +65,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
@ -234,6 +236,9 @@ public class FileController {
throw new RuntimeException("Input stream is null");
}
// remove source file
storageMutator.deleteFile(fileName);
// create the converted file with input stream
storageMutator.createFile(Path.of(storagePathBuilder.getFileLocation(correctedName)), stream);
fileName = correctedName;
@ -459,18 +464,18 @@ public class FileController {
@ResponseBody
public String reference(@RequestBody final JSONObject body) {
try {
JSONParser parser = new JSONParser();
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
String userAddress = "";
String fileName = "";
if (body.containsKey("referenceData")) {
JSONObject referenceDataObj = (JSONObject) body.get("referenceData");
LinkedHashMap referenceDataObj = (LinkedHashMap) body.get("referenceData");
String instanceId = (String) referenceDataObj.get("instanceId");
if (instanceId.equals(storagePathBuilder.getServerUrl(false))) {
JSONObject fileKey = (JSONObject) referenceDataObj.get("fileKey");
JSONObject fileKey = (JSONObject) parser.parse((String) referenceDataObj.get("fileKey"));
userAddress = (String) fileKey.get("userAddress");
if (userAddress.equals(InetAddress.getLocalHost().getHostAddress())) {
fileName = (String) fileKey.get("fileName");
@ -496,18 +501,20 @@ public class FileController {
return "{ \"error\": \"File not found\"}";
}
boolean directUrl = (boolean) body.get("directUrl");
HashMap<String, Object> fileKey = new HashMap<>();
fileKey.put("fileName", fileName);
fileKey.put("userAddress", InetAddress.getLocalHost().getHostAddress());
HashMap<String, Object> referenceData = new HashMap<>();
referenceData.put("instanceId", storagePathBuilder.getServerUrl(true));
referenceData.put("fileKey", fileKey);
referenceData.put("fileKey", gson.toJson(fileKey));
HashMap<String, Object> data = new HashMap<>();
data.put("fileType", fileUtility.getFileExtension(fileName));
data.put("fileType", fileUtility.getFileExtension(fileName).replace(".", ""));
data.put("url", documentManager.getDownloadUrl(fileName, true));
data.put("directUrl", documentManager.getDownloadUrl(fileName, true));
data.put("directUrl", directUrl ? documentManager.getDownloadUrl(fileName, false) : null);
data.put("referenceData", referenceData);
data.put("path", fileName);

View File

@ -163,6 +163,8 @@ public class DefaultCallbackManager implements CallbackManager {
storageMutator.createDirectory(ver); // create the file version directory
lastVersion.toFile().renameTo(new File(versionDir + File.separator + "prev" + curExt));
saveFile(byteArrayFile, toSave); // save document file
byte[] byteArrayChanges = getDownloadFile(changesUri); // download file changes

View File

@ -106,17 +106,17 @@ public class DefaultServiceConverter implements ServiceConverter {
connection.connect();
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
}
int statusCode = connection.getResponseCode();
if (statusCode != HttpStatus.OK.value()) { // 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
}
response = connection.getInputStream(); // get the input stream
jsonString = convertStreamToString(response); // convert the response stream into a string
} finally {

View File

@ -1,4 +1,4 @@
server.version=1.5.1
server.version=1.6.0
server.address=
server.port=4000
@ -38,6 +38,8 @@ spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
hibernate.ddl-auto
spring.h2.console.enabled=true
spring.h2.console.path=/h2
spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=5MB
url.index=/
url.converter=/converter

View File

@ -52,7 +52,7 @@
// the user is trying to switch the document from the viewing into the editing mode
var onRequestEditRights = function () {
location.href = location.href.replace(RegExp("\&?action=view\&?", "i"), "");
location.href = location.href.replace(RegExp("\&?action=view", "i"), "");
};
// an error or some other specific event occurs

View File

@ -315,9 +315,9 @@ public class IndexServlet extends HttpServlet {
connection.disconnect();
// remove source file ?
// File sourceFile = new File(DocumentManager.StoragePath(fileName, null));
// sourceFile.delete();
// remove source file
File sourceFile = new File(DocumentManager.storagePath(fileName, null));
sourceFile.delete();
fileName = correctName;
@ -700,6 +700,8 @@ public class IndexServlet extends HttpServlet {
return;
}
boolean directUrl = (boolean) body.get("directUrl");
HashMap<String, Object> fileKey = new HashMap<>();
fileKey.put("fileName", fileName);
fileKey.put("userAddress", DocumentManager.curUserHostAddress(null));
@ -709,9 +711,9 @@ public class IndexServlet extends HttpServlet {
referenceData.put("fileKey", gson.toJson(fileKey));
HashMap<String, Object> data = new HashMap<>();
data.put("fileType", FileUtility.getFileExtension(fileName));
data.put("fileType", FileUtility.getFileExtension(fileName).replace(".", ""));
data.put("url", DocumentManager.getDownloadUrl(fileName, true));
data.put("directUrl", DocumentManager.getDownloadUrl(fileName, true));
data.put("directUrl", directUrl ? DocumentManager.getDownloadUrl(fileName, false) : null);
data.put("referenceData", referenceData);
data.put("path", fileName);

View File

@ -86,11 +86,11 @@ public final class Users {
true, new ArrayList<String>(), descriptionUserSecond, false));
add(new User("uid-3", "Hamish Mitchell", "mitchell@example.com",
"group-3", Arrays.asList("group-2"), new CommentGroups(Arrays.asList("group-3", "group-2"),
Arrays.asList("group-2"), new ArrayList<String>()), Arrays.asList("group-2"),
Arrays.asList("group-2"), null), Arrays.asList("group-2"),
false, Arrays.asList("copy", "download", "print"),
descriptionUserThird, false));
add(new User("uid-0", null, null,
"", null, new CommentGroups(), new ArrayList<String>(),
"", null, null, null,
null, Arrays.asList("protect"), descriptionUserZero, false));
}};

View File

@ -1,4 +1,4 @@
version=1.5.1
version=1.6.0
filesize-max=5242880
storage-folder=app_data

View File

@ -1,5 +1,5 @@
{
"version": "1.5.1",
"version": "1.6.0",
"log": {
"appenders": [
{

View File

@ -1,6 +1,6 @@
{
"name": "OnlineEditorsExampleNodeJS",
"version": "4.1.0",
"version": "1.6.0",
"private": false,
"scripts": {
"start": "node ./bin/www",

View File

@ -227,6 +227,53 @@
}
};
var onRequestReferenceSource = function (event) {
innerAlert("onRequestReferenceSource");
let xhr = new XMLHttpRequest();
xhr.open("GET", "files");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send();
xhr.onload = function () {
if (xhr.status === 200) {
innerAlert(JSON.parse(xhr.responseText));
let fileList = JSON.parse(xhr.responseText);
let firstXlsxName;
let file;
for (var i = 0; i < fileList.length; i++) {
file = fileList[i];
if (file["title"]) {
if (getFileExt(file["title"]) === "xlsx")
{
firstXlsxName = file["title"];
break;
}
}
}
if (firstXlsxName) {
let data = {
directUrl : "<%- file.directUrl %>" || false,
path : firstXlsxName
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "reference");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(data));
xhr.onload = function () {
if (xhr.status === 200) {
docEditor.setReferenceSource(JSON.parse(xhr.responseText));
} else {
innerAlert("/reference - bad status");
}
}
} else {
innerAlert("No *.xlsx files");
}
} else {
innerAlert("/files - bad status");
}
}
};
var onRequestSaveAs = function (event) { // the user is trying to save file by clicking Save Copy as... button
var title = event.data.title;
var url = event.data.url;
@ -287,6 +334,7 @@
config.events.onRequestUsers = onRequestUsers;
config.events.onRequestSendNotify = onRequestSendNotify;
config.events.onRequestReferenceData = onRequestReferenceData;
config.events.onRequestReferenceSource = onRequestReferenceSource;
}
if (config.editorConfig.createUrl) {
@ -326,6 +374,13 @@
}
};
const getFileExt = function (fileName) {
if (fileName.indexOf(".")) {
return fileName.split('.').reverse()[0];
}
return false;
};
if (window.addEventListener) {
window.addEventListener("load", connectEditor);
window.addEventListener("resize", fixSize);

View File

@ -0,0 +1,2 @@
logs
vendor

View File

@ -0,0 +1 @@
8.1.21

View File

@ -31,3 +31,7 @@ License File: jwt.license
PHP_CodeSniffer - PHP_CodeSniffer is a set of two PHP scripts; the main phpcs script that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard, and a second phpcbf script to automatically correct coding standard violations. PHP_CodeSniffer is an essential development tool that ensures your code remains clean and consistent. (https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt)
License: BSD-3-Clause
License File: PHP_CodeSniffer.license
PHPUnit - The PHP Unit Testing framework. (https://github.com/sebastianbergmann/phpunit/blob/main/LICENSE)
License: BSD 3-Clause
License File: phpunit.license

View File

@ -0,0 +1,80 @@
.DEFAULT_GOAL := help
ADDRESS := $(ADDRESS)
PORT := $(PORT)
.PHONY: help
help: # Show help message for each of the Makefile recipes.
@grep -E "^[a-z-]+: #" $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ": # "}; {printf "%s: %s\n", $$1, $$2}'
.PHONY: dev
dev: # Install development dependencies.
@composer install
.PHONY: prod
prod: # Install production dependencies.
@composer install --no-dev
ifeq ($(ADDRESS),)
server-dev: \
export ADDRESS := localhost
else
server-dev: \
export ADDRESS := $(ADDRESS)
endif
ifeq ($(PORT),)
server-dev: \
export PORT := 9000
else
server-dev: \
export PORT := $(PORT)
endif
.PHONY: server-dev
server-dev: # Start the development server on localhost at $PORT (default: 9000).
@php --server $(ADDRESS):$(PORT)
ifeq ($(ADDRESS),)
server-prod: \
export ADDRESS := 0.0.0.0
else
server-prod: \
export ADDRESS := $(ADDRESS)
endif
ifeq ($(PORT),)
server-prod: \
export PORT := 9000
else
server-prod: \
export PORT := $(PORT)
endif
.PHONY: server-prod
server-prod: # Start the production server on 0.0.0.0 at $PORT (default: 9000).
@php-fpm --fpm-config php-fpm.conf
.PHONY: lint
lint: # Lint the source code for the style.
@./vendor/bin/phpcs .
.PHONY: test
test: # Run tests recursively.
@./vendor/bin/phpunit \
--test-suffix "Tests.php" \
--display-incomplete \
--display-deprecations \
--display-errors \
--display-notices \
--display-warnings \
common
@./vendor/bin/phpunit \
--test-suffix "Tests.php" \
--display-incomplete \
--display-deprecations \
--display-errors \
--display-notices \
--display-warnings \
configuration

View File

@ -18,6 +18,8 @@
namespace OnlineEditorsExamplePhp;
use Exception;
use OnlineEditorsExamplePhp\Common\Path;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
use OnlineEditorsExamplePhp\Helpers\ConfigManager;
use OnlineEditorsExamplePhp\Helpers\ExampleUsers;
use OnlineEditorsExamplePhp\Helpers\JwtManager;
@ -47,41 +49,6 @@ function getHttpOrigin()
return $origin;
}
/**
* Set headers that prevent caching in all the browsers
*
* @return void
*/
function nocacheHeaders()
{
$headers = [
'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',
'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
'Pragma' => 'no-cache',
];
$headers['Last-Modified'] = false;
unset($headers['Last-Modified']);
// In PHP 5.3+, make sure we are not sending a Last-Modified header.
if (function_exists('header_remove')) {
@header_remove('Last-Modified');
} else {
// In PHP 5.2, send an empty Last-Modified header, but only as a
// last resort to override a header already sent. #WP23021
foreach (headers_list() as $header) {
if (0 === mb_stripos($header, 'Last-Modified')) {
$headers['Last-Modified'] = '';
break;
}
}
}
foreach ($headers as $name => $field_value) {
@header("{$name}: {$field_value}");
}
}
/**
* Save copy as...
*
@ -90,6 +57,8 @@ function nocacheHeaders()
function saveas()
{
try {
$config_manager = new ConfigurationManager();
$post = json_decode(file_get_contents('php://input'), true);
$fileurl = $post["url"];
$title = $post["title"];
@ -106,8 +75,7 @@ function saveas()
$content_length = $headers["Content-Length"];
$data = file_get_contents(str_replace(" ", "%20", $fileurl));
if ($data === false || $content_length <= 0 || $content_length >
$configManager->getConfig("fileSizeMax")) {
if ($data === false || $content_length <= 0 || $content_length > $config_manager->maximum_file_size()) {
$result["error"] = "File size is incorrect";
return $result;
}
@ -133,6 +101,8 @@ function saveas()
*/
function upload()
{
$config_manager = new ConfigurationManager();
$configManager = new ConfigManager();
if ($_FILES['files']['error'] > 0) {
$result["error"] = 'Error ' . json_encode($_FILES['files']['error']);
@ -154,7 +124,7 @@ function upload()
$ext = mb_strtolower(pathinfo($_FILES['files']['name'], PATHINFO_EXTENSION)); // get file extension
// check if the file size is correct (it should be less than the max file size, but greater than 0)
if ($filesize <= 0 || $filesize > $configManager->getConfig("fileSizeMax")) {
if ($filesize <= 0 || $filesize > $config_manager->maximum_file_size()) {
$result["error"] = 'File size is incorrect'; // if not, then an error occurs
return $result;
}
@ -203,7 +173,15 @@ function track()
return $data;
}
global $_trackerStatus;
$_trackerStatus = [
0 => 'NotFound',
1 => 'Editing',
2 => 'MustSave',
3 => 'Corrupted',
4 => 'Closed',
6 => 'MustForceSave',
7 => 'CorruptedForceSave',
];
$status = $_trackerStatus[$data->status]; // get status from the request body
$userAddress = $_GET["userAddress"];
@ -245,7 +223,7 @@ function convert()
$post = json_decode(file_get_contents('php://input'), true);
$fileName = basename($post["filename"]);
$filePass = $post["filePass"];
$lang = $_COOKIE["ulang"];
$lang = $_COOKIE["ulang"] ?? "";
$extension = mb_strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
$internalExtension = "ooxml";
$configManager = new ConfigManager();
@ -256,9 +234,8 @@ function convert()
$fileUri = $post["fileUri"];
if ($fileUri == null || $fileUri == "") {
$fileUri = serverPath(true) . '/'
. "webeditor-ajax.php"
. "?type=download"
. "&fileName=" . urlencode($fileName)
. "download"
. "?fileName=" . urlencode($fileName)
. "&userAddress=" . getClientIp();
}
$key = getDocEditorKey($fileName);
@ -391,6 +368,8 @@ function csv()
function historyDownload()
{
try {
$config_manager = new ConfigurationManager();
$fileName = basename($_GET["fileName"]); // get the file name
$userAddress = $_GET["userAddress"];
@ -400,8 +379,7 @@ function historyDownload()
$jwtManager = new JwtManager();
if ($jwtManager->isJwtEnabled()) {
$configManager = new ConfigManager();
$jwtHeader = $configManager->getConfig("docServJwtHeader") == "" ?
"Authorization" : $configManager->getConfig("docServJwtHeader");
$jwtHeader = $config_manager->jwt_header();
if (!empty(apache_request_headers()[$jwtHeader])) {
$token = $jwtManager->jwtDecode(mb_substr(
apache_request_headers()[$jwtHeader],
@ -438,17 +416,15 @@ function historyDownload()
function download()
{
try {
$configManager = new ConfigManager();
$fileName = realpath($configManager->getConfig("storagePath"))
=== $configManager->getConfig("storagePath") ?
$_GET["fileName"] : basename($_GET["fileName"]); // get the file name
$userAddress = $_GET["userAddress"];
$isEmbedded = $_GET["&dmode"];
$config_manager = new ConfigurationManager();
$fileName = $_GET["fileName"];
$userAddress = $_GET["userAddress"] ?? null;
$isEmbedded = $_GET["&dmode"] ?? null;
$jwtManager = new JwtManager();
if ($jwtManager->isJwtEnabled() && $isEmbedded == null && $userAddress) {
$jwtHeader = $configManager->getConfig("docServJwtHeader") == "" ?
"Authorization" : $configManager->getConfig("docServJwtHeader");
$jwtHeader = $config_manager->jwt_header();
if (!empty(apache_request_headers()[$jwtHeader])) {
$token = $jwtManager->jwtDecode(mb_substr(
apache_request_headers()[$jwtHeader],
@ -488,8 +464,9 @@ function downloadFile($filePath)
// write headers to the response object
@header('Content-Length: ' . filesize($filePath));
@header('Content-Disposition: attachment; filename*=UTF-8\'\'' . urldecode(basename($filePath)));
@header('Content-Disposition: attachment; filename*=UTF-8\'\'' . str_replace("+", "%20", urlencode(basename($filePath))));
@header('Content-Type: ' . mime_content_type($filePath));
@header('Access-Control-Allow-Origin: *');
if ($fd = fopen($filePath, 'rb')) {
while (!feof($fd)) {
@ -585,9 +562,9 @@ function reference()
}
$data = [
"fileType" => getInternalExtension($fileName),
"fileType" => trim(getInternalExtension($fileName), '.'),
"url" => getDownloadUrl($fileName),
"directUrl" => $post["directUrl"] ? getDownloadUrl($fileName) : getDownloadUrl($fileName, false),
"directUrl" => $post["directUrl"] ? getDownloadUrl($fileName, false) : null,
"referenceData" => [
"fileKey" => json_encode([
"fileName" => $fileName,
@ -604,3 +581,74 @@ function reference()
return $data;
}
function restore()
{
try {
$input = file_get_contents('php://input');
$body = json_decode($input);
$source_basename = $body->fileName;
$version = $body->version;
$user_id = $body->userId;
$source_file = getStoragePath($source_basename);
$history_directory = getHistoryDir($source_file);
$bumped_version = getFileVersion($history_directory);
$bumped_version_string_directory = getVersionDir($history_directory, $bumped_version);
if (!file_exists($bumped_version_string_directory)) {
mkdir($bumped_version_string_directory);
}
$bumped_version_directory = new Path($bumped_version_string_directory);
$bumped_key_file = $bumped_version_directory->join_path('key.txt');
$bumped_key_string_file = $bumped_key_file->string();
$bumped_key = getDocEditorKey($source_basename);
file_put_contents($bumped_key_string_file, $bumped_key, LOCK_EX);
$users = new ExampleUsers();
$user = $users->getUser($user_id);
$bumped_changes_file = $bumped_version_directory->join_path('changes.json');
$bumped_changes_string_file = $bumped_changes_file->string();
$bumped_changes = [
'serverVersion' => null,
'changes' => array(
[
'created' => date('Y-m-d H:i:s'),
'user' => [
'id' => $user->id,
'name' => $user->name
]
]
)
];
$bumped_changes_content = json_encode($bumped_changes, JSON_PRETTY_PRINT);
file_put_contents($bumped_changes_string_file, $bumped_changes_content, LOCK_EX);
$source_extension = pathinfo($source_basename, PATHINFO_EXTENSION);
$previous_basename = "prev.{$source_extension}";
$bumped_file = $bumped_version_directory->join_path($previous_basename);
$bumped_string_file = $bumped_file->string();
copy($source_file, $bumped_string_file);
$recovery_version_string_directory = getVersionDir($history_directory, $version);
$recovery_version_directory = new Path($recovery_version_string_directory);
$recovery_file = $recovery_version_directory->join_path($previous_basename);
$recovery_string_file = $recovery_file->string();
copy($recovery_string_file, $source_file);
return [
'error' => null,
'success' => true
];
} catch (Exception $error) {
$message = $error->getMessage();
return [
'error' => $message,
'success' => false
];
}
}

View File

@ -0,0 +1,22 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace OnlineEditorsExamplePhp\Common;
enum HTTPStatus: int {
case not_found = 404;
}

View File

@ -0,0 +1,127 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace OnlineEditorsExamplePhp\Common;
final class Path {
private string $separator = DIRECTORY_SEPARATOR;
private string $string;
public function __construct(string $path) {
$this->string = $path;
}
public function string(): string {
return $this->string;
}
public function dirname(): ?string {
$string = $this->string();
$parsed = pathinfo($string, PATHINFO_DIRNAME);
return $parsed ?: null;
}
public function basename(): ?string {
$string = $this->string();
$parsed = pathinfo($string, PATHINFO_BASENAME);
return $parsed ?: null;
}
public function extension(): ?string {
$string = $this->string();
$parsed = pathinfo($string, PATHINFO_EXTENSION);
return $parsed ?: null;
}
public function filename(): ?string {
$string = $this->string();
$parsed = pathinfo($string, PATHINFO_FILENAME);
return $parsed ?: null;
}
public function normalize(): self {
$string = $this->string();
$filtered = array();
$slugs = explode($this->separator, $string);
foreach ($slugs as $slug) {
if ($slug === '.') {
continue;
}
if ($slug === '..') {
array_pop($filtered);
continue;
}
$filtered[] = $slug;
}
$joined = implode($this->separator, $filtered);
$escaped_separator = preg_quote($this->separator, $this->separator);
$separator_regex = "/{$escaped_separator}{2,}/";
$separated = preg_replace($separator_regex, $this->separator, $joined);
return new Path($separated);
}
public function join_path(string $path): self {
$string = $this->string();
$separator =
str_ends_with($string, $this->separator) ||
str_starts_with($path, $this->separator)
? ''
: $this->separator;
return new Path("{$string}{$separator}{$path}");
}
public function absolute(): bool {
$string = $this->string();
$nt_regex = '/^[A-Za-z]:\\\\/';
if (preg_match($nt_regex, $string)) {
return true;
}
$nt_separator = '\\';
if (str_starts_with($string, $nt_separator)) {
return true;
}
$posix_separator = '/';
if (str_starts_with($string, $posix_separator)) {
return true;
}
return false;
}
public function exists(): bool {
$string = $this->string();
return file_exists($string);
}
public function contents(): string {
$string = $this->string();
return file_get_contents($string);
}
public function directory(): bool {
$string = $this->string();
return is_dir($string);
}
public function make_directory(): bool {
$string = $this->string();
return mkdir($string);
}
}

View File

@ -0,0 +1,39 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Common\Path;
final class PathAbsolutePOSIXTests extends TestCase {
public function test_recognizes_an_empty_as_a_non_absolute() {
$path = new Path('');
$absolute = $path->absolute();
$this->assertFalse($absolute);
}
public function test_recognizes_a_relative_as_a_non_absolute() {
$path = new Path('.');
$absolute = $path->absolute();
$this->assertFalse($absolute);
}
public function test_recognizes_an_absolute_as_an_absolute() {
$path = new Path('/');
$absolute = $path->absolute();
$this->assertTrue($absolute);
}
}

View File

@ -0,0 +1,84 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Common\Path;
final class PathJoinPOSIXTests extends TestCase {
public function test_joins_a_relative_to_an_empty_one() {
$path = new Path('');
$joined = $path->join_path('srv');
$this->assertEquals($joined->dirname(), '/');
$this->assertEquals($joined->basename(), 'srv');
$this->assertEquals($joined->extension(), null);
$this->assertEquals($joined->filename(), 'srv');
}
public function test_joins_a_relative_to_a_relative_one() {
$path = new Path('.');
$joined = $path->join_path('srv');
$this->assertEquals($joined->dirname(), '.');
$this->assertEquals($joined->basename(), 'srv');
$this->assertEquals($joined->extension(), null);
$this->assertEquals($joined->filename(), 'srv');
}
public function test_joins_a_relative_to_an_absolute_one() {
$path = new Path('/');
$joined = $path->join_path('srv');
$this->assertEquals($joined->dirname(), '/');
$this->assertEquals($joined->basename(), 'srv');
$this->assertEquals($joined->extension(), null);
$this->assertEquals($joined->filename(), 'srv');
}
public function test_joins_an_absolute_to_an_empty_one() {
$path = new Path('');
$joined = $path->join_path('/srv');
$this->assertEquals($joined->dirname(), '/');
$this->assertEquals($joined->basename(), 'srv');
$this->assertEquals($joined->extension(), null);
$this->assertEquals($joined->filename(), 'srv');
}
public function test_joins_an_absolute_to_a_relative_one() {
$path = new Path('.');
$joined = $path->join_path('/srv');
$this->assertEquals($joined->dirname(), '.');
$this->assertEquals($joined->basename(), 'srv');
$this->assertEquals($joined->extension(), null);
$this->assertEquals($joined->filename(), 'srv');
}
public function test_joins_an_absolute_to_an_absolute_one() {
$path = new Path('/');
$joined = $path->join_path('/srv');
$this->assertEquals($joined->dirname(), '/');
$this->assertEquals($joined->basename(), 'srv');
$this->assertEquals($joined->extension(), null);
$this->assertEquals($joined->filename(), 'srv');
}
public function test_joins_an_unnormalized() {
$path = new Path('');
$joined = $path->join_path('../srv');
$this->assertEquals($joined->dirname(), '/..');
$this->assertEquals($joined->basename(), 'srv');
$this->assertEquals($joined->extension(), null);
$this->assertEquals($joined->filename(), 'srv');
}
}

View File

@ -0,0 +1,30 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Common\Path;
final class PathNormalizePOSIXTests extends TestCase {
public function test_normalizes() {
$path = new Path('./srv///sub/.././sub/file.docx');
$normalized = $path->normalize();
$this->assertEquals($normalized->dirname(), 'srv/sub');
$this->assertEquals($normalized->basename(), 'file.docx');
$this->assertEquals($normalized->extension(), 'docx');
$this->assertEquals($normalized->filename(), 'file');
}
}

View File

@ -0,0 +1,150 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Common\Path;
final class PathStringPOSIXTests extends TestCase {
public function test_generates_with_an_empty() {
$path = new Path('');
$string = $path->string();
$this->assertEquals($string, '');
}
public function test_generates_with_an_empty_relative() {
$path = new Path('.');
$string = $path->string();
$this->assertEquals($string, '.');
}
public function test_generates_with_an_empty_absolute() {
$path = new Path('/');
$string = $path->string();
$this->assertEquals($string, '/');
}
public function test_generates_with_a_relative() {
$path = new Path('srv');
$string = $path->string();
$this->assertEquals($string, 'srv');
}
public function test_generates_with_a_relative_containing_a_directory() {
$path = new Path('srv/sub');
$string = $path->string();
$this->assertEquals($string, 'srv/sub');
}
public function test_generates_with_a_relative_containing_a_file() {
$path = new Path('srv/file.json');
$string = $path->string();
$this->assertEquals($string, 'srv/file.json');
}
public function test_generates_with_a_relative_containing_a_directory_with_a_file() {
$path = new Path('srv/sub/file.json');
$string = $path->string();
$this->assertEquals($string, 'srv/sub/file.json');
}
public function test_generates_with_an_unnormalized_relative() {
$path = new Path('srv////sub///file.json');
$string = $path->string();
$this->assertEquals($string, 'srv////sub///file.json');
}
public function test_generates_with_an_normalized_relative() {
$path = new Path('srv////sub///file.json');
$normalized = $path->normalize();
$string = $normalized->string();
$this->assertEquals($string, 'srv/sub/file.json');
}
public function test_generates_with_an_explicit_relative() {
$path = new Path('./srv');
$string = $path->string();
$this->assertEquals($string, './srv');
}
public function test_generates_with_an_explicit_relative_containing_a_directory() {
$path = new Path('./srv/sub');
$string = $path->string();
$this->assertEquals($string, './srv/sub');
}
public function test_generates_with_an_explicit_relative_containing_a_file() {
$path = new Path('./srv/file.json');
$string = $path->string();
$this->assertEquals($string, './srv/file.json');
}
public function test_generates_with_an_explicit_relative_containing_a_directory_with_a_file() {
$path = new Path('./srv/sub/file.json');
$string = $path->string();
$this->assertEquals($string, './srv/sub/file.json');
}
public function test_generates_with_an_explicit_unnormalized_relative() {
$path = new Path('./srv////sub///file.json');
$string = $path->string();
$this->assertEquals($string, './srv////sub///file.json');
}
public function test_generates_with_an_explicit_normalized_relative() {
$path = new Path('./srv////sub///file.json');
$normalized = $path->normalize();
$string = $normalized->string();
$this->assertEquals($string, 'srv/sub/file.json');
}
public function test_generates_with_an_absolute() {
$path = new Path('/srv');
$string = $path->string();
$this->assertEquals($string, '/srv');
}
public function test_generates_with_an_absolute_containing_a_directory() {
$path = new Path('/srv/sub');
$string = $path->string();
$this->assertEquals($string, '/srv/sub');
}
public function test_generates_with_an_absolute_containing_a_file() {
$path = new Path('/srv/file.json');
$string = $path->string();
$this->assertEquals($string, '/srv/file.json');
}
public function test_generates_with_an_absolute_containing_a_directory_with_a_file() {
$path = new Path('/srv/sub/file.json');
$string = $path->string();
$this->assertEquals($string, '/srv/sub/file.json');
}
public function test_generates_with_an_unnormalized_absolute() {
$path = new Path('/srv////sub///file.json');
$string = $path->string();
$this->assertEquals($string, '/srv////sub///file.json');
}
public function test_generates_with_an_normalized_absolute() {
$path = new Path('/srv////sub///file.json');
$normalized = $path->normalize();
$string = $normalized->string();
$this->assertEquals($string, '/srv/sub/file.json');
}
}

View File

@ -0,0 +1,132 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace OnlineEditorsExamplePhp\Common;
final class URL {
private string $string;
public function __construct(string $url) {
$this->string = $url;
}
public function string(): string {
return $this->string;
}
public function scheme(): ?string {
$string = $this->string();
return parse_url($string, PHP_URL_SCHEME) ?: null;
}
public function host(): ?string {
$string = $this->string();
return parse_url($string, PHP_URL_HOST) ?: null;
}
public function port(): ?int {
$string = $this->string();
return parse_url($string, PHP_URL_PORT) ?: null;
}
public function user(): ?string {
$string = $this->string();
return parse_url($string, PHP_URL_USER) ?: null;
}
public function pass(): ?string {
$string = $this->string();
return parse_url($string, PHP_URL_PASS) ?: null;
}
public function path(): ?string {
$string = $this->string();
return parse_url($string, PHP_URL_PATH) ?: null;
}
public function query(): ?string {
$string = $this->string();
return parse_url($string, PHP_URL_QUERY) ?: null;
}
public function fragment(): ?string {
$string = $this->string();
return parse_url($string, PHP_URL_FRAGMENT) ?: null;
}
public static function from_components(
?string $scheme,
?string $host,
?int $port,
?string $user,
?string $pass,
?string $path,
?string $query,
?string $fragment
): URL {
$string = '';
if ($scheme) {
$string .= "{$scheme}://";
}
if ($user) {
$string .= $user;
}
if ($pass) {
$string .= ":{$pass}@";
}
if ($host) {
$string .= $host;
}
if ($port) {
$string .= ":{$port}";
}
if ($path) {
$string .= $path;
}
if ($query) {
$string .= "?{$query}";
}
if ($fragment) {
$string .= "#{$fragment}";
}
return new URL($string);
}
public function join_path(string $path): self {
$current_path = $this->path();
$separator =
$current_path &&
(
str_ends_with($current_path, '/') ||
str_starts_with($path, '/')
) ||
!$current_path && str_starts_with($path, '/')
? ''
: '/';
$separated = "{$current_path}{$separator}{$path}";
return URL::from_components(
$this->scheme(),
$this->host(),
$this->port(),
$this->user(),
$this->pass(),
$separated,
$this->query(),
$this->fragment()
);
}
}

View File

@ -0,0 +1,42 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Common\URL;
final class URLFromComponentsTests extends TestCase {
public function test_creates() {
$url = URL::from_components(
'http',
'localhost',
8080,
'user',
'password',
'/path',
'q=value',
'fragment'
);
$this->assertEquals('http', $url->scheme());
$this->assertEquals('localhost', $url->host());
$this->assertEquals(8080, $url->port());
$this->assertEquals('user', $url->user());
$this->assertEquals('password', $url->pass());
$this->assertEquals('/path', $url->path());
$this->assertEquals('q=value', $url->query());
$this->assertEquals('fragment', $url->fragment());
}
}

View File

@ -0,0 +1,73 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Common\URL;
final class URLJoinPathTests extends TestCase {
public function test_joins_a_relative_to_an_empty_one() {
$url = new URL('http://localhost');
$joined = $url->join_path('first');
$this->assertEquals('http', $joined->scheme());
$this->assertEquals('localhost', $joined->host());
$this->assertEquals(null, $joined->port());
$this->assertEquals(null, $joined->user());
$this->assertEquals(null, $joined->pass());
$this->assertEquals('/first', $joined->path());
$this->assertEquals(null, $joined->query());
$this->assertEquals(null, $joined->fragment());
}
public function test_joins_a_relative() {
$url = new URL('http://localhost/first');
$joined = $url->join_path('second');
$this->assertEquals('http', $joined->scheme());
$this->assertEquals('localhost', $joined->host());
$this->assertEquals(null, $joined->port());
$this->assertEquals(null, $joined->user());
$this->assertEquals(null, $joined->pass());
$this->assertEquals('/first/second', $joined->path());
$this->assertEquals(null, $joined->query());
$this->assertEquals(null, $joined->fragment());
}
public function test_joins_an_absolute_to_an_empty_one() {
$url = new URL('http://localhost');
$joined = $url->join_path('/first');
$this->assertEquals('http', $joined->scheme());
$this->assertEquals('localhost', $joined->host());
$this->assertEquals(null, $joined->port());
$this->assertEquals(null, $joined->user());
$this->assertEquals(null, $joined->pass());
$this->assertEquals('/first', $joined->path());
$this->assertEquals(null, $joined->query());
$this->assertEquals(null, $joined->fragment());
}
public function test_joins_an_absolute() {
$url = new URL('http://localhost/first');
$joined = $url->join_path('/second');
$this->assertEquals('http', $joined->scheme());
$this->assertEquals('localhost', $joined->host());
$this->assertEquals(null, $joined->port());
$this->assertEquals(null, $joined->user());
$this->assertEquals(null, $joined->pass());
$this->assertEquals('/first/second', $joined->path());
$this->assertEquals(null, $joined->query());
$this->assertEquals(null, $joined->fragment());
}
}

View File

@ -0,0 +1,30 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Common\URL;
final class URLStringTests extends TestCase {
public function test_generates() {
$url = new URL('http://user:password@localhost:8080/path?q=value#fragment');
$string = $url->string();
$this->assertEquals(
'http://user:password@localhost:8080/path?q=value#fragment',
$string
);
}
}

View File

@ -1,26 +1,19 @@
{
"require": {
"ext-mbstring": "*",
"firebase/php-jwt": "^6.8.1"
},
"require-dev": {
"squizlabs/php_codesniffer": "*",
"ext-mbstring": "*"
"squizlabs/php_codesniffer": "^3.7.2",
"phpunit/phpunit": "^10.2.6"
},
"scripts": {
"code-sniffer": [
"./vendor/bin/phpcs --config-set default_standard ruleset.xml",
"./vendor/bin/phpcs --config-set colors 1"
],
"post-install-cmd": [
"@code-sniffer"
],
"post-update-cmd": [
"@code-sniffer"
]
},
"autoload-dev": {
"autoload": {
"psr-4": {
"OnlineEditorsExamplePhp\\" : "",
"OnlineEditorsExamplePhp\\Common\\": "common/",
"OnlineEditorsExamplePhp\\Configuration\\" : "configuration/",
"OnlineEditorsExamplePhp\\Helpers\\" : "helpers/",
"OnlineEditorsExamplePhp\\Views\\" : "views/",
"Firebase\\JWT\\" : "lib/jwt/"
"OnlineEditorsExamplePhp\\Views\\" : "views/"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,66 +0,0 @@
{
"version": "1.5.1",
"fileSizeMax": 5242880,
"storagePath": "",
"alone": false,
"docServTimeout": "120000",
"docServSiteUrl": "https://documentserver/",
"docServConverterUrl": "ConvertService.ashx",
"docServApiUrl": "web-apps/apps/api/documents/api.js",
"docServPreloaderUrl": "web-apps/apps/api/documents/cache-scripts.html",
"docServCommandUrl": "coauthoring/CommandService.ashx",
"docServJwtSecret": "",
"docServJwtHeader": "Authorization",
"docServJwtUseForRequest": true,
"docServVerifyPeerOff": true,
"exampleUrl": "",
"mobileRegex": "android|avantgo|playbook|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino",
"languages": {
"en": "English",
"hy": "Armenian",
"az": "Azerbaijani",
"eu": "Basque",
"be": "Belarusian",
"bg": "Bulgarian",
"ca": "Catalan",
"zh": "Chinese (Simplified)",
"zh-TW": "Chinese (Traditional)",
"cs": "Czech",
"da": "Danish",
"nl": "Dutch",
"fi": "Finnish",
"fr": "French",
"gl": "Galego",
"de": "German",
"el": "Greek",
"hu": "Hungarian",
"id": "Indonesian",
"it": "Italian",
"ja": "Japanese",
"ko": "Korean",
"lo": "Lao",
"lv": "Latvian",
"ms": "Malay (Malaysia)",
"no": "Norwegian",
"pl": "Polish",
"pt": "Portuguese (Brazil)",
"pt-PT": "Portuguese (Portugal)",
"ro": "Romanian",
"ru": "Russian",
"si": "Sinhala (Sri Lanka)",
"sk": "Slovak",
"sl": "Slovenian",
"es": "Spanish",
"sv": "Swedish",
"tr": "Turkish",
"uk": "Ukrainian",
"vi": "Vietnamese",
"aa-AA": "Test Language"
}
}

View File

@ -0,0 +1,177 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace OnlineEditorsExamplePhp\Configuration;
use OnlineEditorsExamplePhp\Common\Path;
use OnlineEditorsExamplePhp\Common\URL;
final class ConfigurationManager {
public string $version = '1.6.0';
public function example_url(): ?URL {
$url = getenv('EXAMPLE_URL');
if (!$url) {
return null;
}
return new URL($url);
}
public function document_server_url(): URL {
$url = getenv('DOCUMENT_SERVER_URL') ?: 'http://document-server';
return new URL($url);
}
public function document_server_api_url(): URL {
$server_url = $this->document_server_url();
$path = getenv('DOCUMENT_SERVER_API_PATH')
?: 'web-apps/apps/api/documents/api.js';
return $server_url->join_path($path);
}
public function document_server_preloader_url(): URL {
$server_url = $this->document_server_url();
$path = getenv('DOCUMENT_SERVER_PRELOADER_PATH')
?: 'web-apps/apps/api/documents/cache-scripts.html';
return $server_url->join_path($path);
}
public function document_server_command_url(): URL {
$server_url = $this->document_server_url();
$path = getenv('DOCUMENT_SERVER_COMMAND_PATH')
?: 'coauthoring/CommandService.ashx';
return $server_url->join_path($path);
}
public function document_server_converter_url(): URL {
$server_url = $this->document_server_url();
$path = getenv('DOCUMENT_SERVER_CONVERTER_PATH')
?: 'ConvertService.ashx';
return $server_url->join_path($path);
}
public function jwt_secret(): string {
return getenv('JWT_SECRET') ?: '';
}
public function jwt_header(): string {
return getenv('JWT_HEADER') ?: 'Authorization';
}
public function jwt_use_for_request(): bool {
$use = getenv('JWT_USE_FOR_REQUEST');
if (!$use) {
return true;
}
return filter_var($use, FILTER_VALIDATE_BOOLEAN);
}
public function ssl_verify_peer_mode_enabled(): bool {
$enabled = getenv('SSL_VERIFY_PEER_MODE_ENABLED');
if (!$enabled) {
return false;
}
return filter_var($enabled, FILTER_VALIDATE_BOOLEAN);
}
public function storage_path(): Path {
$storage_path = getenv('STORAGE_PATH') ?: 'storage';
$storage_directory = new Path($storage_path);
if ($storage_directory->absolute()) {
return $storage_directory;
}
$storage_string_directory = $storage_directory->string();
$current_directory = new Path(__DIR__);
$directory = $current_directory
->join_path('..')
->join_path($storage_string_directory);
return $directory->normalize();
}
public function single_user(): bool {
$single = getenv('SINGLE_USER');
if (!$single) {
return false;
}
return filter_var($single, FILTER_VALIDATE_BOOLEAN);
}
public function maximum_file_size(): int {
$size = getenv('MAXIMUM_FILE_SIZE');
if (!$size) {
return 5 * 1024 * 1024;
}
return intval($size);
}
public function conversion_timeout(): int {
$timeout = getenv('CONVERSION_TIMEOUT');
if (!$timeout) {
return 120 * 1000;
}
return intval($timeout);
}
/**
* @return string[]
*/
public function languages(): array {
return [
'en' => "English",
'hy' => 'Armenian',
'az' => 'Azerbaijani',
'eu' => 'Basque',
'be' => 'Belarusian',
'bg' => 'Bulgarian',
'ca' => 'Catalan',
'zh' => 'Chinese (Simplified)',
'zh-TW' => 'Chinese (Traditional)',
'cs' => 'Czech',
'da' => 'Danish',
'nl' => 'Dutch',
'fi' => 'Finnish',
'fr' => 'French',
'gl' => 'Galego',
'de' => 'German',
'el' => 'Greek',
'hu' => 'Hungarian',
'id' => 'Indonesian',
'it' => 'Italian',
'ja' => 'Japanese',
'ko' => 'Korean',
'lo' => 'Lao',
'lv' => 'Latvian',
'ms' => 'Malay (Malaysia)',
'no' => 'Norwegian',
'pl' => 'Polish',
'pt' => 'Portuguese (Brazil)',
'pt-PT' => 'Portuguese (Portugal)',
'ro' => 'Romanian',
'ru' => 'Russian',
'si' => 'Sinhala (Sri Lanka)',
'sk' => 'Slovak',
'sl' => 'Slovenian',
'es' => 'Spanish',
'sv' => 'Swedish',
'tr' => 'Turkish',
'uk' => 'Ukrainian',
'vi' => 'Vietnamese',
'aa-AA' => 'Test Language'
];
}
}

View File

@ -0,0 +1,47 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerConversionTimeoutTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$timeout = $config_manager->conversion_timeout();
$this->assertEquals(120_000, $timeout);
}
public function test_assigns_a_value_from_the_environment() {
putenv('CONVERSION_TIMEOUT=10');
$config_manager = new ConfigurationManager();
$timeout = $config_manager->conversion_timeout();
$this->assertEquals(10, $timeout);
}
}

View File

@ -0,0 +1,53 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerDocumentServerAPIURLTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$url = $config_manager->document_server_api_url();
$this->assertEquals(
'http://document-server/web-apps/apps/api/documents/api.js',
$url->string()
);
}
public function test_assigns_a_value_from_the_environment() {
putenv('DOCUMENT_SERVER_API_PATH=/api');
$config_manager = new ConfigurationManager();
$url = $config_manager->document_server_api_url();
$this->assertEquals(
'http://document-server/api',
$url->string()
);
}
}

View File

@ -0,0 +1,53 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerDocumentServerCommandURLTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$url = $config_manager->document_server_command_url();
$this->assertEquals(
'http://document-server/coauthoring/CommandService.ashx',
$url->string()
);
}
public function test_assigns_a_value_from_the_environment() {
putenv('DOCUMENT_SERVER_COMMAND_PATH=/command');
$config_manager = new ConfigurationManager();
$url = $config_manager->document_server_command_url();
$this->assertEquals(
'http://document-server/command',
$url->string()
);
}
}

View File

@ -0,0 +1,53 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerDocumentServerConverterURLTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$url = $config_manager->document_server_converter_url();
$this->assertEquals(
'http://document-server/ConvertService.ashx',
$url->string()
);
}
public function test_assigns_a_value_from_the_environment() {
putenv('DOCUMENT_SERVER_CONVERTER_PATH=/converter');
$config_manager = new ConfigurationManager();
$url = $config_manager->document_server_converter_url();
$this->assertEquals(
'http://document-server/converter',
$url->string()
);
}
}

View File

@ -0,0 +1,53 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerDocumentServerPreloaderURLTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$url = $config_manager->document_server_preloader_url();
$this->assertEquals(
'http://document-server/web-apps/apps/api/documents/cache-scripts.html',
$url->string()
);
}
public function test_assigns_a_value_from_the_environment() {
putenv('DOCUMENT_SERVER_PRELOADER_PATH=/preloader');
$config_manager = new ConfigurationManager();
$url = $config_manager->document_server_preloader_url();
$this->assertEquals(
'http://document-server/preloader',
$url->string()
);
}
}

View File

@ -0,0 +1,47 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerDocumentServerURLTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$url = $config_manager->document_server_url();
$this->assertEquals('http://document-server', $url->string());
}
public function test_assigns_a_value_from_the_environment() {
putenv('DOCUMENT_SERVER_URL=http://localhost');
$config_manager = new ConfigurationManager();
$url = $config_manager->document_server_url();
$this->assertEquals('http://localhost', $url->string());
}
}

View File

@ -0,0 +1,47 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerExampleURLTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$url = $config_manager->example_url();
$this->assertNull($url);
}
public function test_assigns_a_value_from_the_environment() {
putenv('EXAMPLE_URL=http://localhost');
$config_manager = new ConfigurationManager();
$url = $config_manager->example_url();
$this->assertEquals('http://localhost', $url->string());
}
}

View File

@ -0,0 +1,47 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerJWTHeaderTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$header = $config_manager->jwt_header();
$this->assertEquals('Authorization', $header);
}
public function test_assigns_a_value_from_the_environment() {
putenv('JWT_HEADER=Proxy-Authorization');
$config_manager = new ConfigurationManager();
$header = $config_manager->jwt_header();
$this->assertEquals('Proxy-Authorization', $header);
}
}

View File

@ -0,0 +1,47 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerJWTSecretTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$secret = $config_manager->jwt_secret();
$this->assertEquals('', $secret);
}
public function test_assigns_a_value_from_the_environment() {
putenv('JWT_SECRET=your-256-bit-secret');
$config_manager = new ConfigurationManager();
$secret = $config_manager->jwt_secret();
$this->assertEquals('your-256-bit-secret', $secret);
}
}

View File

@ -0,0 +1,47 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerJWTUseForRequest extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$use = $config_manager->jwt_use_for_request();
$this->assertTrue($use);
}
public function test_assigns_a_value_from_the_environment() {
putenv('JWT_USE_FOR_REQUEST=false');
$config_manager = new ConfigurationManager();
$use = $config_manager->jwt_use_for_request();
$this->assertFalse($use);
}
}

View File

@ -0,0 +1,47 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerMaximumFileSizeTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$size = $config_manager->maximum_file_size();
$this->assertEquals(5_242_880, $size);
}
public function test_assigns_a_value_from_the_environment() {
putenv('MAXIMUM_FILE_SIZE=10');
$config_manager = new ConfigurationManager();
$size = $config_manager->maximum_file_size();
$this->assertEquals(10, $size);
}
}

View File

@ -0,0 +1,47 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerSSLTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$enabled = $config_manager->ssl_verify_peer_mode_enabled();
$this->assertFalse($enabled);
}
public function test_assigns_a_value_from_the_environment() {
putenv('SSL_VERIFY_PEER_MODE_ENABLED=true');
$config_manager = new ConfigurationManager();
$enabled = $config_manager->ssl_verify_peer_mode_enabled();
$this->assertTrue($enabled);
}
}

View File

@ -0,0 +1,47 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerSingleUserTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$single = $config_manager->single_user();
$this->assertFalse($single);
}
public function test_assigns_a_value_from_the_environment() {
putenv('SINGLE_USER=true');
$config_manager = new ConfigurationManager();
$single = $config_manager->single_user();
$this->assertTrue($single);
}
}

View File

@ -0,0 +1,56 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerStoragePathTests extends TestCase {
public array $env;
public function __construct(string $name) {
$this->env = getenv();
parent::__construct($name);
}
protected function setUp(): void {
foreach ($this->env as $key => $value) {
putenv("{$key}={$value}");
}
}
public function test_assigns_a_default_value() {
$config_manager = new ConfigurationManager();
$path = $config_manager->storage_path();
$this->assertTrue($path->absolute());
$this->assertEquals($path->basename(), 'storage');
}
public function test_assigns_a_relative_path_from_the_environment() {
putenv('STORAGE_PATH=directory');
$config_manager = new ConfigurationManager();
$path = $config_manager->storage_path();
$this->assertTrue($path->absolute());
$this->assertEquals($path->basename(), 'directory');
}
public function test_assigns_an_absolute_path_from_the_environment() {
putenv('STORAGE_PATH=/directory');
$config_manager = new ConfigurationManager();
$path = $config_manager->storage_path();
$this->assertEquals($path->string(), '/directory');
}
}

View File

@ -0,0 +1,26 @@
<?php
//
// (c) Copyright Ascensio System SIA 2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use PHPUnit\Framework\TestCase;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class ConfigurationManagerTests extends TestCase {
public function test_corresponds_the_latest_version() {
$config_manager = new ConfigurationManager();
$this->assertEquals('1.6.0', $config_manager->version);
}
}

View File

@ -1,26 +0,0 @@
<?php
/**
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace OnlineEditorsExamplePhp;
use OnlineEditorsExamplePhp\Views\DocEditorView;
require_once dirname(__FILE__) . '/functions.php';
require_once dirname(__FILE__) . '/vendor/autoload.php';
$docEditorView = new DocEditorView($_REQUEST);
$docEditorView->render();

View File

@ -18,6 +18,7 @@
namespace OnlineEditorsExamplePhp;
use Exception;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
use OnlineEditorsExamplePhp\Helpers\ConfigManager;
use OnlineEditorsExamplePhp\Helpers\ExampleUsers;
use OnlineEditorsExamplePhp\Helpers\JwtManager;
@ -92,10 +93,10 @@ function getClientIp()
*/
function serverPath($forDocumentServer = null)
{
$configManager = new ConfigManager();
return $forDocumentServer && $configManager->getConfig("storagePath") != null
&& $configManager->getConfig("exampleUrl") != ""
? $configManager->getConfig("exampleUrl")
$config_manager = new ConfigurationManager();
$example_url = $config_manager->example_url();
return $forDocumentServer && $example_url
? $example_url->string()
: (getScheme() . '://' . $_SERVER['HTTP_HOST']);
}
@ -108,11 +109,8 @@ function serverPath($forDocumentServer = null)
*/
function getCurUserHostAddress($userAddress = null)
{
$configManager = new ConfigManager();
if ($configManager->getConfig("alone")) {
if (empty($configManager->getConfig("storagePath"))) {
return "Storage";
}
$config_manager = new ConfigurationManager();
if ($config_manager->single_user()) {
return "";
}
if (is_null($userAddress)) {
@ -222,39 +220,21 @@ function getScheme()
*/
function getStoragePath($fileName, $userAddress = null)
{
$configManager = new ConfigManager();
$storagePath = trim(
str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $configManager->getConfig("storagePath")),
DIRECTORY_SEPARATOR
);
if (!empty($storagePath) && !file_exists($storagePath) && !is_dir($storagePath)) {
mkdir($storagePath);
$config_manager = new ConfigurationManager();
$storage_path = $config_manager->storage_path();
if (!$storage_path->exists()) {
$storage_path->make_directory();
}
if (realpath($storagePath) === $storagePath) {
$directory = $storagePath;
} else {
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath;
$user_ip = getCurUserHostAddress($userAddress);
$user_directory = $storage_path->join_path($user_ip);
if (!$user_directory->exists()) {
$user_directory->make_directory();
}
if ($storagePath != "") {
$directory = $directory . DIRECTORY_SEPARATOR;
// if the file directory doesn't exist, make it
if (!file_exists($directory) && !is_dir($directory)) {
mkdir($directory);
}
}
if (realpath($storagePath) !== $storagePath) {
$directory = $directory . getCurUserHostAddress($userAddress) . DIRECTORY_SEPARATOR;
}
if (!file_exists($directory) && !is_dir($directory)) {
mkdir($directory);
}
sendlog("getStoragePath result: " . $directory . basename($fileName), "common.log");
return realpath($storagePath) === $storagePath ? $directory . $fileName : $directory . basename($fileName);
$file = $user_directory->join_path($fileName);
return $file->string();
}
/**
@ -268,43 +248,30 @@ function getStoragePath($fileName, $userAddress = null)
*/
function getForcesavePath($fileName, $userAddress, $create)
{
$configManager = new ConfigManager();
$storagePath = trim(
str_replace(
['/', '\\'],
DIRECTORY_SEPARATOR,
$configManager->getConfig("storagePath")
),
DIRECTORY_SEPARATOR
);
$config_manager = new ConfigurationManager();
$storage_path = $config_manager->storage_path();
// create the directory to this file version
if (realpath($storagePath) === $storagePath) {
$directory = $storagePath . DIRECTORY_SEPARATOR;
} else {
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath . getCurUserHostAddress($userAddress) .
DIRECTORY_SEPARATOR;
$user_ip = getCurUserHostAddress($userAddress);
$user_directory = $storage_path->join_path($user_ip);
if (!$user_directory->exists()) {
return '';
}
if (!is_dir($directory)) {
return "";
$history_directory = $user_directory->join_path("{$fileName}-hist");
if (!$history_directory->exists()) {
if ($create) {
$history_directory->make_directory();
} else {
return '';
}
}
// create the directory to the history of this file version
$directory = $directory . $fileName . "-hist" . DIRECTORY_SEPARATOR;
if (!$create && !is_dir($directory)) {
return "";
$file = $history_directory->join_path($fileName);
if (!$file->exists() && !$create) {
return '';
}
if (!file_exists($directory) && !is_dir($directory)) {
mkdir($directory);
}
$directory = $directory . $fileName;
if (!$create && !file_exists($directory)) {
return "";
}
return $directory;
return $file->string();
}
/**
@ -370,38 +337,21 @@ function getFileVersion($histDir)
function getStoredFiles()
{
$configManager = new ConfigManager();
$storagePath = trim(str_replace(
['/', '\\'],
DIRECTORY_SEPARATOR,
$configManager->getConfig("storagePath")
), DIRECTORY_SEPARATOR);
if (!empty($storagePath) && !file_exists($storagePath) && !is_dir($storagePath)) {
mkdir($storagePath);
$config_manager = new ConfigurationManager();
$storage_path = $config_manager->storage_path();
if (!$storage_path->exists()) {
$storage_path->make_directory();
}
if (realpath($storagePath) === $storagePath) {
$directory = $storagePath;
} else {
$directory = __DIR__ . DIRECTORY_SEPARATOR . $storagePath;
$user_ip = getCurUserHostAddress();
$user_directory = $storage_path->join_path($user_ip);
if (!$user_directory->exists()) {
$user_directory->make_directory();
}
// get the storage path and check if it exists
$result = [];
if ($storagePath != "") {
$directory = $directory . DIRECTORY_SEPARATOR;
if (!file_exists($directory) && !is_dir($directory)) {
return $result;
}
}
if (realpath($storagePath) !== $storagePath) {
$directory = $directory . getCurUserHostAddress() . DIRECTORY_SEPARATOR;
}
if (!file_exists($directory) && !is_dir($directory)) {
return $result;
}
$directory = $user_directory->string();
$cdir = scandir($directory); // get all the files and folders from the directory
$result = [];
@ -432,21 +382,8 @@ function getStoredFiles()
*/
function getVirtualPath($forDocumentServer)
{
$configManager = new ConfigManager();
$storagePath = trim(str_replace(
['/', '\\'],
'/',
$configManager->getConfig("storagePath")
), '/');
$storagePath = $storagePath != "" ? $storagePath . '/' : "";
if (realpath($storagePath) === $storagePath) {
$virtPath = serverPath($forDocumentServer) . '/' . $storagePath . '/';
} else {
$virtPath = serverPath($forDocumentServer) . '/' . $storagePath . getCurUserHostAddress() . '/';
}
sendlog("getVirtualPath virtPath: " . $virtPath, "common.log");
return $virtPath;
$server_url = serverPath($forDocumentServer);
return $server_url . '/' . getCurUserHostAddress() . '/';
}
/**
@ -689,6 +626,8 @@ function sendRequestToConvertService(
$filePass,
$lang
) {
$config_manager = new ConfigurationManager();
if (empty($from_extension)) {
$path_parts = pathinfo($document_uri);
$from_extension = mb_strtolower($path_parts['extension']);
@ -707,9 +646,7 @@ function sendRequestToConvertService(
// generate document token
$document_revision_id = generateRevisionId($document_revision_id);
$configManager = new ConfigManager();
$urlToConverter = $configManager->getConfig("docServSiteUrl").
$configManager->getConfig("docServConverterUrl");
$urlToConverter = $config_manager->document_server_converter_url()->string();
$arr = [
"async" => $is_async,
@ -724,8 +661,7 @@ function sendRequestToConvertService(
// add header token
$headerToken = "";
$jwtHeader = $configManager->getConfig("docServJwtHeader") ==
"" ? "Authorization" : $configManager->getConfig("docServJwtHeader");
$jwtHeader = $config_manager->jwt_header();
$jwtManager = new JwtManager();
if ($jwtManager->isJwtEnabled() && $jwtManager->tokenUseForRequest()) {
@ -738,7 +674,7 @@ function sendRequestToConvertService(
// request parameters
$opts = ['http' => [
'method' => 'POST',
'timeout' => $configManager->getConfig("docServTimeout"),
'timeout' => $config_manager->conversion_timeout(),
'header' => "Content-type: application/json\r\n" .
"Accept: application/json\r\n" .
(empty($headerToken) ? "" : $jwtHeader.": Bearer $headerToken\r\n"),
@ -747,7 +683,7 @@ function sendRequestToConvertService(
];
if (mb_substr($urlToConverter, 0, mb_strlen("https")) === "https") {
if ($configManager->getConfig("docServVerifyPeerOff") === true) {
if ($config_manager->ssl_verify_peer_mode_enabled()) {
$opts['ssl'] = ['verify_peer' => false, 'verify_peer_name' => false];
}
}
@ -888,9 +824,12 @@ function getResponseUri($document_response, &$response_uri)
*/
function tryGetDefaultByType($createExt, $user)
{
$demoName = (isset($_GET["sample"]) ? "sample." : "new.") . $createExt;
$demoPath = "assets" . DIRECTORY_SEPARATOR . "document-templates" . DIRECTORY_SEPARATOR
. (isset($_GET["sample"]) ? "sample" : "new") . DIRECTORY_SEPARATOR;
$sample = isset($_GET["sample"]) && $_GET["sample"];
$demoName = ($sample ? "sample." : "new.") . $createExt;
$demoPath =
"assets" . DIRECTORY_SEPARATOR .
"document-templates" . DIRECTORY_SEPARATOR .
($sample ? "sample" : "new") . DIRECTORY_SEPARATOR;
$demoFilename = GetCorrectName($demoName);
if (!@copy(dirname(__FILE__) . DIRECTORY_SEPARATOR . $demoPath . $demoName, getStoragePath($demoFilename))) {
@ -914,9 +853,8 @@ function tryGetDefaultByType($createExt, $user)
function getCallbackUrl($fileName)
{
return serverPath(true) . '/'
. "webeditor-ajax.php"
. "?type=track"
. "&fileName=" . urlencode($fileName)
. "track"
. "?fileName=" . urlencode($fileName)
. "&userAddress=" . getClientIp();
}
@ -933,10 +871,9 @@ function getCreateUrl($fileName, $uid, $type)
{
$ext = trim(getInternalExtension($fileName), '.');
return serverPath(false) . '/'
. "doceditor.php"
. "editor"
. "?fileExt=" . $ext
. "&user=" . $uid
. "&type=" . $type;
. "&user=" . $uid;
}
/**
@ -953,9 +890,8 @@ function getHistoryDownloadUrl($fileName, $version, $file, $isServer = true)
{
$userAddress = $isServer ? "&userAddress=" . getClientIp() : "";
return serverPath($isServer) . '/'
. "webeditor-ajax.php"
. "?type=history"
. "&fileName=" . urlencode($fileName)
. "history"
. "?fileName=" . urlencode($fileName)
. "&ver=" . $version
. "&file=" . urlencode($file)
. $userAddress;
@ -973,9 +909,8 @@ function getDownloadUrl($fileName, $isServer = true)
{
$userAddress = $isServer ? "&userAddress=" . getClientIp() : "";
return serverPath($isServer) . '/'
. "webeditor-ajax.php"
. "?type=download"
. "&fileName=" . urlencode($fileName)
. "download"
. "?fileName=" . urlencode($fileName)
. $userAddress;
}
@ -992,8 +927,6 @@ function getDownloadUrl($fileName, $isServer = true)
*/
function getHistory($filename, $filetype, $docKey, $fileuri, $isEnableDirectUrl)
{
$configManager = new ConfigManager();
$storagePath = $configManager->getConfig("storagePath");
$histDir = getHistoryDir(getStoragePath($filename)); // get the path to the file history
if (getFileVersion($histDir) > 0) { // check if the file was modified (the file version is greater than 0)
@ -1034,13 +967,11 @@ function getHistory($filename, $filetype, $docKey, $fileuri, $isEnableDirectUrl)
$directUrl = $i == $curVer ? fileUri($filename, false) :
getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, false);
$prevFileUrl = $i == $curVer ? $fileuri : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
if (realpath($storagePath) === $storagePath) {
$prevFileUrl = $i == $curVer ? getDownloadUrl($filename) :
getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
if ($isEnableDirectUrl) {
$directUrl = $i == $curVer ? getDownloadUrl($filename, false) :
getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, false);
}
$prevFileUrl = $i == $curVer ? getDownloadUrl($filename) :
getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
if ($isEnableDirectUrl) {
$directUrl = $i == $curVer ? getDownloadUrl($filename, false) :
getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, false);
}
$dataObj["url"] = $prevFileUrl; // write file url to the data object

View File

@ -20,20 +20,13 @@ namespace OnlineEditorsExamplePhp\Helpers;
final class ConfigManager
{
private mixed $config;
private mixed $configFormats;
public function __construct()
{
$this->config = json_decode($this->getConfigurationJson());
$this->configFormats = json_decode($this->getConfigurationFromatsJson());
}
private function getConfigurationJson(): bool|string
{
return file_exists("./config.json") ? file_get_contents("./config.json") : false;
}
private function getConfigurationFromatsJson(): bool|string
{
return file_exists("./assets/document-formats/onlyoffice-docs-formats.json")
@ -41,18 +34,6 @@ final class ConfigManager
: false;
}
/**
* @param string|null $configName
* @return mixed
*/
public function getConfig(string $configName = null): mixed
{
if ($configName) {
return $this->config->$configName ?? "";
}
return $this->config;
}
public function getSuppotredFormats(): mixed
{
return $this->configFormats;

View File

@ -18,6 +18,10 @@ namespace OnlineEditorsExamplePhp\Helpers;
* limitations under the License.
*/
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
final class JwtManager
{
/**
@ -27,8 +31,8 @@ final class JwtManager
*/
public function isJwtEnabled(): bool
{
$configManager = new ConfigManager();
return !empty($configManager->getConfig("docServJwtSecret"));
$config_manager = new ConfigurationManager();
return !empty($config_manager->jwt_secret());
}
/**
@ -38,8 +42,8 @@ final class JwtManager
*/
public function tokenUseForRequest(): bool
{
$configManager = new ConfigManager();
return $configManager->getConfig("docServJwtUseForRequest") ?: false;
$config_manager = new ConfigurationManager();
return $config_manager->jwt_use_for_request() ?: false;
}
/**
@ -51,8 +55,8 @@ final class JwtManager
*/
public function jwtEncode($payload)
{
$configManager = new ConfigManager();
return \Firebase\JWT\JWT::encode($payload, $configManager->getConfig("docServJwtSecret"));
$config_manager = new ConfigurationManager();
return JWT::encode($payload, $config_manager->jwt_secret(), 'HS256');
}
/**
@ -64,12 +68,11 @@ final class JwtManager
*/
public function jwtDecode($token)
{
$configManager = new ConfigManager();
$config_manager = new ConfigurationManager();
try {
$payload = \Firebase\JWT\JWT::decode(
$payload = JWT::decode(
$token,
$configManager->getConfig("docServJwtSecret"),
["HS256"]
new Key($config_manager->jwt_secret(), 'HS256')
);
} catch (\UnexpectedValueException $e) {
$payload = "";

View File

@ -17,10 +17,140 @@
namespace OnlineEditorsExamplePhp;
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/ajax.php';
require_once __DIR__ . '/functions.php';
require_once __DIR__ . '/trackmanager.php';
use OnlineEditorsExamplePhp\Common\HTTPStatus;
use OnlineEditorsExamplePhp\Common\URL;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
use OnlineEditorsExamplePhp\Views\DocEditorView;
use OnlineEditorsExamplePhp\Views\IndexView;
require_once dirname(__FILE__) . '/functions.php';
require_once dirname(__FILE__) . '/vendor/autoload.php';
function configure() {
$config_manager = new ConfigurationManager();
if ($config_manager->ssl_verify_peer_mode_enabled()) {
// Ignore self-signed certificate.
stream_context_set_default([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false
]
]);
}
}
$indexView = new IndexView($_REQUEST);
$indexView->render();
function routers() {
// TODO: delete fallback.
// In theory, the content type of the response should be declared inside the
// router function. However, this statement isn't true for all routers, and
// it's also not true for all branches in all routers. Therefore, we are
// setting the default content type for all routers here.
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-cache, must-revalidate, max-age=0');
header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');
header('Pragma: no-cache');
@header_remove('Last-Modified');
header('X-Content-Type-Options: nosniff');
header('X-Robots-Tag: noindex');
$url = new URL($_SERVER['REQUEST_URI']);
sendlog($url->string(), 'webedior-ajax.log');
$path = $url->path();
if (!$path || $path === '/') {
header('Content-Type: text/html; charset=utf-8');
$view = new IndexView($_REQUEST);
$view->render();
return;
}
if (str_starts_with($path, '/editor')) {
header('Content-Type: text/html; charset=utf-8');
$view = new DocEditorView($_REQUEST);
$view->render();
return;
}
if (str_starts_with($path, '/assets')) {
$response = assets();
$response['status'] = 'success';
echo json_encode($response);
return;
}
if (str_starts_with($path, '/convert')) {
$response = convert();
$response['status'] = 'success';
echo json_encode($response);
return;
}
if (str_starts_with($path, '/csv')) {
$response = csv();
$response['status'] = 'success';
echo json_encode($response);
return;
}
if (str_starts_with($path, '/delete')) {
$response = delete();
$response['status'] = isset($response['error']) ? 'error' : 'success';
echo json_encode($response);
return;
}
if (str_starts_with($path, '/download')) {
$response = download();
$response['status'] = 'success';
echo json_encode($response);
return;
}
if (str_starts_with($path, '/files')) {
$response = files();
echo json_encode($response);
return;
}
if (str_starts_with($path, '/history')) {
$response = historyDownload();
$response['status'] = 'success';
echo json_encode($response);
return;
}
if (str_starts_with($path, '/reference')) {
$response = reference();
$response['status'] = 'success';
echo json_encode($response);
return;
}
if (str_starts_with($path, '/rename')) {
$response = renamefile();
$content = json_encode($response);
echo $content;
return;
}
if (str_starts_with($path, '/restore')) {
$response = restore();
echo json_encode($response);
return;
}
if (str_starts_with($path, '/saveas')) {
$response = saveas();
$response['status'] = 'success';
echo json_encode($response);
return;
}
if (str_starts_with($path, '/track')) {
$response = track();
$response['status'] = 'success';
echo json_encode($response);
return;
}
if (str_starts_with($path, '/upload')) {
$response = upload();
$response['status'] = isset($response['error']) ? 'error' : 'success';
echo json_encode($response);
return;
}
http_response_code(HTTPStatus::not_found->value);
}
configure();
routers();

View File

@ -125,7 +125,7 @@ if (typeof jQuery != "undefined") {
jq("#filePass").val("");
timer = setTimeout(function () {
var requestAddress = "webeditor-ajax.php?type=convert&user=" + user;
var requestAddress = "convert?user=" + user;
jq.ajax({
async: true,
@ -247,7 +247,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.php?fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
var url = "editor?fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -256,7 +256,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.php?action=view&fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
var url = "editor?action=view&fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -265,7 +265,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.php?type=embedded&fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
var url = "editor?type=embedded&fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -297,7 +297,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", ".delete-file", function () {
var fileName = jq(this).attr("data");
var requestAddress = "webeditor-ajax.php?type=delete&fileName=" + fileName;
var requestAddress = "delete?fileName=" + fileName;
jq.ajax({
async: true,

View File

@ -1,7 +0,0 @@
<?php
namespace Firebase\JWT;
class BeforeValidException extends \UnexpectedValueException
{
}

View File

@ -1,7 +0,0 @@
<?php
namespace Firebase\JWT;
class ExpiredException extends \UnexpectedValueException
{
}

View File

@ -1,370 +0,0 @@
<?php
namespace Firebase\JWT;
use \DomainException;
use \InvalidArgumentException;
use \UnexpectedValueException;
use \DateTime;
/**
* JSON Web Token implementation, based on this spec:
* http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
*
* PHP version 5
*
* @category Authentication
* @package Authentication_JWT
* @author Neuman Vong <neuman@twilio.com>
* @author Anant Narayanan <anant@php.net>
* @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
* @link https://github.com/firebase/php-jwt
*/
class JWT
{
/**
* When checking nbf, iat or expiration times,
* we want to provide some extra leeway time to
* account for clock skew.
*/
public static $leeway = 0;
/**
* Allow the current timestamp to be specified.
* Useful for fixing a value within unit testing.
*
* Will default to PHP time() value if null.
*/
public static $timestamp = null;
public static $supported_algs = array(
'HS256' => array('hash_hmac', 'SHA256'),
'HS512' => array('hash_hmac', 'SHA512'),
'HS384' => array('hash_hmac', 'SHA384'),
'RS256' => array('openssl', 'SHA256'),
);
/**
* Decodes a JWT string into a PHP object.
*
* @param string $jwt The JWT
* @param string|array $key The key, or map of keys.
* If the algorithm used is asymmetric, this is the public key
* @param array $allowed_algs List of supported verification algorithms
* Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
*
* @return object The JWT's payload as a PHP object
*
* @throws UnexpectedValueException Provided JWT was invalid
* @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed
* @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf'
* @throws BeforeValidException Provided JWT is trying to be used before it's been created as defined by 'iat'
* @throws ExpiredException Provided JWT has since expired, as defined by the 'exp' claim
*
* @uses jsonDecode
* @uses urlsafeB64Decode
*/
public static function decode($jwt, $key, $allowed_algs = array())
{
$timestamp = is_null(static::$timestamp) ? time() : static::$timestamp;
if (empty($key)) {
throw new InvalidArgumentException('Key may not be empty');
}
if (!is_array($allowed_algs)) {
throw new InvalidArgumentException('Algorithm not allowed');
}
$tks = explode('.', $jwt);
if (count($tks) != 3) {
throw new UnexpectedValueException('Wrong number of segments');
}
list($headb64, $bodyb64, $cryptob64) = $tks;
if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) {
throw new UnexpectedValueException('Invalid header encoding');
}
if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) {
throw new UnexpectedValueException('Invalid claims encoding');
}
$sig = static::urlsafeB64Decode($cryptob64);
if (empty($header->alg)) {
throw new UnexpectedValueException('Empty algorithm');
}
if (empty(static::$supported_algs[$header->alg])) {
throw new UnexpectedValueException('Algorithm not supported');
}
if (!in_array($header->alg, $allowed_algs)) {
throw new UnexpectedValueException('Algorithm not allowed');
}
if (is_array($key) || $key instanceof \ArrayAccess) {
if (isset($header->kid)) {
$key = $key[$header->kid];
} else {
throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
}
}
// Check the signature
if (!static::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
throw new SignatureInvalidException('Signature verification failed');
}
// Check if the nbf if it is defined. This is the time that the
// token can actually be used. If it's not yet that time, abort.
if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
);
}
// Check that this token has been created before 'now'. This prevents
// using tokens that have been created for later use (and haven't
// correctly used the nbf claim).
if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
);
}
// Check if this token has expired.
if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
throw new ExpiredException('Expired token');
}
return $payload;
}
/**
* Converts and signs a PHP object or array into a JWT string.
*
* @param object|array $payload PHP object or array
* @param string $key The secret key.
* If the algorithm used is asymmetric, this is the private key
* @param string $alg The signing algorithm.
* Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
* @param mixed $keyId
* @param array $head An array with header elements to attach
*
* @return string A signed JWT
*
* @uses jsonEncode
* @uses urlsafeB64Encode
*/
public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null)
{
$header = array('typ' => 'JWT', 'alg' => $alg);
if ($keyId !== null) {
$header['kid'] = $keyId;
}
if ( isset($head) && is_array($head) ) {
$header = array_merge($head, $header);
}
$segments = array();
$segments[] = static::urlsafeB64Encode(static::jsonEncode($header));
$segments[] = static::urlsafeB64Encode(static::jsonEncode($payload));
$signing_input = implode('.', $segments);
$signature = static::sign($signing_input, $key, $alg);
$segments[] = static::urlsafeB64Encode($signature);
return implode('.', $segments);
}
/**
* Sign a string with a given key and algorithm.
*
* @param string $msg The message to sign
* @param string|resource $key The secret key
* @param string $alg The signing algorithm.
* Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
*
* @return string An encrypted message
*
* @throws DomainException Unsupported algorithm was specified
*/
public static function sign($msg, $key, $alg = 'HS256')
{
if (empty(static::$supported_algs[$alg])) {
throw new DomainException('Algorithm not supported');
}
list($function, $algorithm) = static::$supported_algs[$alg];
switch($function) {
case 'hash_hmac':
return hash_hmac($algorithm, $msg, $key, true);
case 'openssl':
$signature = '';
$success = openssl_sign($msg, $signature, $key, $algorithm);
if (!$success) {
throw new DomainException("OpenSSL unable to sign data");
} else {
return $signature;
}
}
}
/**
* Verify a signature with the message, key and method. Not all methods
* are symmetric, so we must have a separate verify and sign method.
*
* @param string $msg The original message (header and body)
* @param string $signature The original signature
* @param string|resource $key For HS*, a string key works. for RS*, must be a resource of an openssl public key
* @param string $alg The algorithm
*
* @return bool
*
* @throws DomainException Invalid Algorithm or OpenSSL failure
*/
private static function verify($msg, $signature, $key, $alg)
{
if (empty(static::$supported_algs[$alg])) {
throw new DomainException('Algorithm not supported');
}
list($function, $algorithm) = static::$supported_algs[$alg];
switch($function) {
case 'openssl':
$success = openssl_verify($msg, $signature, $key, $algorithm);
if (!$success) {
throw new DomainException("OpenSSL unable to verify data: " . openssl_error_string());
} else {
return $signature;
}
case 'hash_hmac':
default:
$hash = hash_hmac($algorithm, $msg, $key, true);
if (function_exists('hash_equals')) {
return hash_equals($signature, $hash);
}
$len = min(static::safeStrlen($signature), static::safeStrlen($hash));
$status = 0;
for ($i = 0; $i < $len; $i++) {
$status |= (ord($signature[$i]) ^ ord($hash[$i]));
}
$status |= (static::safeStrlen($signature) ^ static::safeStrlen($hash));
return ($status === 0);
}
}
/**
* Decode a JSON string into a PHP object.
*
* @param string $input JSON string
*
* @return object Object representation of JSON string
*
* @throws DomainException Provided string was invalid JSON
*/
public static function jsonDecode($input)
{
if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) {
/** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you
* to specify that large ints (like Steam Transaction IDs) should be treated as
* strings, rather than the PHP default behaviour of converting them to floats.
*/
$obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
} else {
/** Not all servers will support that, however, so for older versions we must
* manually detect large ints in the JSON string and quote them (thus converting
*them to strings) before decoding, hence the preg_replace() call.
*/
$max_int_length = strlen((string) PHP_INT_MAX) - 1;
$json_without_bigints = preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input);
$obj = json_decode($json_without_bigints);
}
if (function_exists('json_last_error') && $errno = json_last_error()) {
static::handleJsonError($errno);
} elseif ($obj === null && $input !== 'null') {
throw new DomainException('Null result with non-null input');
}
return $obj;
}
/**
* Encode a PHP object into a JSON string.
*
* @param object|array $input A PHP object or array
*
* @return string JSON representation of the PHP object or array
*
* @throws DomainException Provided object could not be encoded to valid JSON
*/
public static function jsonEncode($input)
{
$json = json_encode($input);
if (function_exists('json_last_error') && $errno = json_last_error()) {
static::handleJsonError($errno);
} elseif ($json === 'null' && $input !== null) {
throw new DomainException('Null result with non-null input');
}
return $json;
}
/**
* Decode a string with URL-safe Base64.
*
* @param string $input A Base64 encoded string
*
* @return string A decoded string
*/
public static function urlsafeB64Decode($input)
{
$remainder = strlen($input) % 4;
if ($remainder) {
$padlen = 4 - $remainder;
$input .= str_repeat('=', $padlen);
}
return base64_decode(strtr($input, '-_', '+/'));
}
/**
* Encode a string with URL-safe Base64.
*
* @param string $input The string you want encoded
*
* @return string The base64 encode of what you passed in
*/
public static function urlsafeB64Encode($input)
{
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}
/**
* Helper method to create a JSON error.
*
* @param int $errno An error number from json_last_error()
*
* @return void
*/
private static function handleJsonError($errno)
{
$messages = array(
JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON'
);
throw new DomainException(
isset($messages[$errno])
? $messages[$errno]
: 'Unknown JSON error: ' . $errno
);
}
/**
* Get the number of bytes in cryptographic strings.
*
* @param string
*
* @return int
*/
private static function safeStrlen($str)
{
if (function_exists('mb_strlen')) {
return mb_strlen($str, '8bit');
}
return strlen($str);
}
}

View File

@ -1,30 +0,0 @@
Copyright (c) 2011, Neuman Vong
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Neuman Vong nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,7 +0,0 @@
<?php
namespace Firebase\JWT;
class SignatureInvalidException extends \UnexpectedValueException
{
}

View File

@ -31,3 +31,7 @@ License File: jwt.license
PHP_CodeSniffer - PHP_CodeSniffer is a set of two PHP scripts; the main phpcs script that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard, and a second phpcbf script to automatically correct coding standard violations. PHP_CodeSniffer is an essential development tool that ensures your code remains clean and consistent. (https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt)
License: BSD-3-Clause
License File: PHP_CodeSniffer.license
PHPUnit - The PHP Unit Testing framework. (https://github.com/sebastianbergmann/phpunit/blob/main/LICENSE)
License: BSD 3-Clause
License File: phpunit.license

View File

@ -1,27 +1,29 @@
Copyright (c) 2004, Jamis Buck (jamis@jamisbuck.org)
BSD 3-Clause License
Copyright (c) 2001-2023, Sebastian Bergmann
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,13 @@
[global]
daemonize = no
[www]
user = www-data
group = www-data
listen = ${ADDRESS}:${PORT}
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
clear_env = no

View File

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<ruleset name="Custom Standard">
<description>A custom coding standard</description>
<rule ref="PSR2"/>
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="120"/>
<property name="absoluteLineLimit" value="0"/>
</properties>
</rule>
</ruleset>

View File

@ -1,14 +0,0 @@
<?xml version="1.0"?>
<ruleset name="CustomRuleset">
<description>This standard changes the line length</description>
<!-- Insert all sniff from PSR2 standard -->
<rule ref="PSR2"/>
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="120"/>
<property name="absoluteLineLimit" value="0"/>
</properties>
</rule>
</ruleset>

View File

@ -103,7 +103,7 @@
event.data.directUrl = !!config.document.directUrl;
let xhr = new XMLHttpRequest();
xhr.open("POST", "webeditor-ajax.php?type=reference");
xhr.open("POST", "reference");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(event.data));
xhr.onload = function () {
@ -161,7 +161,7 @@
url: url
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "webeditor-ajax.php?type=saveas");
xhr.open("POST", "saveas");
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
xhr.onload = function () {
@ -181,7 +181,7 @@
};
let xhr = new XMLHttpRequest();
xhr.open("POST", "webeditor-ajax.php?type=rename");
xhr.open("POST", "rename");
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
xhr.onload = function () {
@ -189,6 +189,27 @@
}
};
function onRequestRestore(event) {
const query = new URLSearchParams(window.location.search)
const config = {config}
const payload = {
fileName: query.get('fileID'),
version: event.data.version,
userId: query.get('user') || config.editorConfig.user.id
}
const request = new XMLHttpRequest()
request.open("PUT", 'restore')
request.send(JSON.stringify(payload))
request.onload = function () {
if (request.status != 200) {
response = JSON.parse(request.response)
innerAlert(response.error)
return
}
document.location.reload();
}
}
var сonnectEditor = function () {
{fileNotFoundAlert}
@ -208,6 +229,7 @@
'onRequestCompareFile': onRequestCompareFile,
'onRequestMailMergeRecipients': onRequestMailMergeRecipients,
'onRequestReferenceData': onRequestReferenceData,
'onRequestRestore': onRequestRestore
};
{history}

View File

@ -35,19 +35,19 @@
<ul class="try-editor-list clearFix">
<li>
<a class="try-editor word reload-page" target="_blank"
href="doceditor.php?fileExt=docx&user={user}">Document</a>
href="editor?fileExt=docx&user={user}">Document</a>
</li>
<li>
<a class="try-editor cell reload-page" target="_blank"
href="doceditor.php?fileExt=xlsx&user={user}">Spreadsheet</a>
href="editor?fileExt=xlsx&user={user}">Spreadsheet</a>
</li>
<li>
<a class="try-editor slide reload-page" target="_blank"
href="doceditor.php?fileExt=pptx&user={user}">Presentation</a>
href="editor?fileExt=pptx&user={user}">Presentation</a>
</li>
<li>
<a class="try-editor form reload-page" target="_blank"
href="doceditor.php?fileExt=docxf&user={user}">Form template</a>
href="editor?fileExt=docxf&user={user}">Form template</a>
</li>
</ul>
<label class="side-option">
@ -58,7 +58,7 @@
<div class="upload-panel clearFix">
<a class="file-upload">Upload file
<input type="file" id="fileupload" name="files"
data-url="webeditor-ajax.php?type=upload&user={user}" />
data-url="upload?user={user}" />
</a>
</div>

View File

@ -18,6 +18,7 @@
namespace OnlineEditorsExamplePhp;
use Exception;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
use OnlineEditorsExamplePhp\Helpers\ConfigManager;
use OnlineEditorsExamplePhp\Helpers\JwtManager;
@ -28,6 +29,8 @@ use OnlineEditorsExamplePhp\Helpers\JwtManager;
*/
function readBody()
{
$config_manager = new ConfigurationManager();
$result["error"] = 0;
$configManager = new ConfigManager();
$jwtManager = new JwtManager();
@ -53,8 +56,7 @@ function readBody()
$inHeader = false;
$data = "";
$jwtHeader = $configManager->getConfig("docServJwtHeader") ==
"" ? "Authorization" : $configManager->getConfig("docServJwtHeader");
$jwtHeader = $config_manager->jwt_header();
if (!empty($data["token"])) { // if the document token is in the data
$data = $jwtManager->jwtDecode($data["token"]); // decode it
@ -290,10 +292,10 @@ function processForceSave($data, $fileName, $userAddress)
*/
function commandRequest($method, $key, $meta = null)
{
$configManager = new ConfigManager();
$config_manager = new ConfigurationManager();
$jwtManager = new JwtManager();
$documentCommandUrl = $configManager->getConfig("docServSiteUrl").
$configManager->getConfig("docServCommandUrl");
$documentCommandUrl = $config_manager->document_server_command_url()->string();
$arr = [
"c" => $method,
@ -305,8 +307,7 @@ function commandRequest($method, $key, $meta = null)
}
$headerToken = "";
$jwtHeader = $configManager->getConfig("docServJwtHeader") == "" ? "Authorization" :
$configManager->getConfig("docServJwtHeader");
$jwtHeader = $config_manager->jwt_header();
// check if a secret key to generate token exists or not
if ($jwtManager->isJwtEnabled() && $jwtManager->tokenUseForRequest()) {
@ -326,7 +327,7 @@ function commandRequest($method, $key, $meta = null)
]];
if (mb_substr($documentCommandUrl, 0, mb_strlen("https")) === "https") {
if ($configManager->getConfig("docServVerifyPeerOff") === true) {
if ($config_manager->ssl_verify_peer_mode_enabled()) {
$opts['ssl'] = ['verify_peer' => false, 'verify_peer_name' => false];
}
}

View File

@ -17,6 +17,7 @@
namespace OnlineEditorsExamplePhp\Views;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
use OnlineEditorsExamplePhp\Helpers\ConfigManager;
use OnlineEditorsExamplePhp\Helpers\ExampleUsers;
use OnlineEditorsExamplePhp\Helpers\JwtManager;
@ -39,17 +40,21 @@ final class DocEditorView extends View
public function __construct($request, $tempName = "docEditor")
{
parent::__construct($tempName);
$config_manager = new ConfigurationManager();
$externalUrl = $request["fileUrl"] ?? "";
$confgManager = new ConfigManager();
$jwtManager = new JwtManager();
$userList = new ExampleUsers();
$fileId = $request["fileID"] ?? "";
$user = $userList->getUser($request["user"]);
$isEnableDirectUrl = isset($request["directUrl"]) ? filter_var($request["directUrl"], FILTER_VALIDATE_BOOLEAN)
: false;
if (!empty($externalUrl)) {
$filename = doUpload($externalUrl);
} else { // if the file url doesn't exist, get file name and file extension
$filename = basename($request["fileID"] ?? "");
$filename = basename($fileId);
}
$createExt = $request["fileExt"] ?? "";
@ -58,15 +63,12 @@ final class DocEditorView extends View
$filename = tryGetDefaultByType($createExt, $user);
// create the demo file url
$new_url = "doceditor.php?fileID=" . $filename . "&user=" . $request["user"];
$new_url = "editor?fileID=" . $filename . "&user=" . $request["user"];
header('Location: ' . $new_url, true);
exit;
}
$fileuri = fileUri($filename, true);
$fileuriUser = realpath($confgManager->getConfig("storagePath")) ===
$confgManager->getConfig("storagePath") ?
getDownloadUrl($filename) . "&dmode=emb" : fileUri($filename);
$directUrl = getDownloadUrl($filename, false);
$docKey = getDocEditorKey($filename);
$filetype = mb_strtolower(pathinfo($filename, PATHINFO_EXTENSION));
@ -199,21 +201,21 @@ final class DocEditorView extends View
// a document for comparing
$dataCompareFile = $isEnableDirectUrl ? [
"fileType" => "docx",
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx",
"directUrl" => serverPath(false) . "/webeditor-ajax.php?type=assets&name=sample.docx",
"url" => serverPath(true) . "/assets?name=sample.docx",
"directUrl" => serverPath(false) . "/assets?name=sample.docx",
] : [
"fileType" => "docx",
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx",
"url" => serverPath(true) . "/assets?name=sample.docx",
];
// recipients data for mail merging
$dataMailMergeRecipients = $isEnableDirectUrl ? [
"fileType" => "csv",
"url" => serverPath(true) . "/webeditor-ajax.php?type=csv",
"directUrl" => serverPath(false) . "/webeditor-ajax.php?type=csv",
"url" => serverPath(true) . "/csv",
"directUrl" => serverPath(false) . "/csv",
] : [
"fileType" => "csv",
"url" => serverPath(true) . "/webeditor-ajax.php?type=csv",
"url" => serverPath(true) . "/csv",
];
// users data for mentions
@ -265,7 +267,7 @@ final class DocEditorView extends View
}
$this->tagsValues = [
"docType" => getDocumentType($filename),
"apiUrl" => $confgManager->getConfig("docServSiteUrl").$confgManager->getConfig("docServApiUrl"),
"apiUrl" => $config_manager->document_server_api_url()->string(),
"dataInsertImage" => mb_strimwidth(
json_encode($dataInsertImage),
1,

View File

@ -50,40 +50,40 @@ class IndexStoredListView extends View
)
).']">';
$layout .= ' <td class="contentCells"><a class="stored-edit '.
$storeFile->documentType.'" href="doceditor.php?fileID='.
$storeFile->documentType.'" href="editor?fileID='.
urlencode($storeFile->name).
'&user='.$user.
$directUrlArg .'" target="_blank">'.'<span>'.$storeFile->name.'</span></a></td>';
if ($storeFile->canEdit) {
$layout .= ' <td class="contentCells contentCells-icon"> <a href="doceditor.php?fileID='.
$layout .= ' <td class="contentCells contentCells-icon"> <a href="editor?fileID='.
urlencode($storeFile->name).'&user=' . htmlentities($user).$directUrlArg.
'&action=edit&type=desktop" target="_blank">'.
'<img src="css/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="doceditor.php?fileID='.
' <td class="contentCells contentCells-icon"> <a href="editor?fileID='.
urlencode($storeFile->name).'&user=' . htmlentities($user).$directUrlArg.
'&action=edit&type=mobile" target="_blank">'.
'<img src="css/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="doceditor.php?fileID='.
' <td class="contentCells contentCells-icon"> <a href="editor?fileID='.
urlencode($storeFile->name).'&user='.htmlentities($user).$directUrlArg.
'&action=comment&type=desktop" target="_blank">'.
' <img src="css/images/comment.svg" alt="Open in editor for comment"'.
' title="Open in editor for comment" /></a></td>';
if ($storeFile->documentType == "word") {
$layout .= '<td class="contentCells contentCells-icon"> <a href="doceditor.php?fileID='.
$layout .= '<td class="contentCells contentCells-icon"> <a href="editor?fileID='.
urlencode($storeFile->name).'&user='.htmlentities($user).$directUrlArg.
'&action=review&type=desktop" target="_blank">'.
' <img src="css/images/review.svg" alt="Open in editor for review"'.
' title="Open in editor for review" /></a></td>'.
' <td class="contentCells contentCells-icon "> <a href="doceditor.php?fileID='.
' <td class="contentCells contentCells-icon "> <a href="editor?fileID='.
urlencode($storeFile->name).'&user='.htmlentities($user).$directUrlArg.
'&action=blockcontent&type=desktop" target="_blank">'.
' <img src="css/images/block-content.svg"'.
' alt="Open in editor without content control modification"'.
' title="Open in editor without content control modification"</a></td>';
} elseif ($storeFile->documentType == "cell") {
$layout .= '<td class="contentCells contentCells-icon"> <a href="doceditor.php?fileID='.
$layout .= '<td class="contentCells contentCells-icon"> <a href="editor?fileID='.
urlencode($storeFile->name).'&user='.htmlentities($user).$directUrlArg.
'&action=filter&type=desktop" target="_blank">'.
' <img src="css/images/filter.svg" alt="Open in editor without access to change the filter"'.
@ -95,7 +95,7 @@ class IndexStoredListView extends View
if ($storeFile->isFillFormDoc) {
$layout.= ' <td class="contentCells contentCells-shift contentCells-icon'.
' firstContentCellShift">'.
' <a href="doceditor.php?fileID='.urlencode($storeFile->name).
' <a href="editor?fileID='.urlencode($storeFile->name).
'&user='.htmlentities($user).$directUrlArg.
'&action=fillForms&type=desktop" target="_blank">'.
' <img src="css/images/fill-forms.svg" alt="Open in editor for filling in forms"'.
@ -105,7 +105,7 @@ class IndexStoredListView extends View
'firstContentCellShift"></td>';
}
} elseif ($storeFile->isFillFormDoc) {
$layout .= '<td class="contentCells contentCells-icon"> <a href="doceditor.php?fileID='.
$layout .= '<td class="contentCells contentCells-icon"> <a href="editor?fileID='.
urlencode($storeFile->name).'&user='.htmlentities($user).$directUrlArg.
'&action=fillForms&type=desktop" target="_blank">'.
' <img src="css/images/mobile-fill-forms.svg" alt="Open in editor for filling in forms'.
@ -114,7 +114,7 @@ class IndexStoredListView extends View
'<td class="contentCells contentCells-icon"></td>'.
'<td class="contentCells contentCells-icon"></td>'.
'<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">'.
'<a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).
'<a href="editor?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).
$directUrlArg.'&action=fillForms&type=desktop" target="_blank">'.
'<img src="css/images/fill-forms.svg" alt="Open in editor for filling in forms"'.
' title="Open in editor for filling in forms"/></a></td>';
@ -123,22 +123,22 @@ class IndexStoredListView extends View
'contentCellsEmpty" colspan="6"></td>';
}
$layout .= '<td class="contentCells contentCells-icon firstContentCellViewers">'.
' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).
' <a href="editor?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).
$directUrlArg.'&action=view&type=desktop" target="_blank">'.
' <img src="css/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="doceditor.php?fileID='.
' <td class="contentCells contentCells-icon"> <a href="editor?fileID='.
urlencode($storeFile->name).'&user='.htmlentities($user).$directUrlArg.
'&action=view&type=mobile" target="_blank">'.
' <img src="css/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="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).
' <a href="editor?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).
$directUrlArg.'&action=embedded&type=embedded" target="_blank">'.
' <img src="css/images/embeded.svg" alt="Open in embedded mode"'.
' title="Open in embedded mode" /></a>'.
' <td class="contentCells contentCells-icon contentCells-shift downloadContentCellShift">'.
'<a href="webeditor-ajax.php?type=download&fileName='.urlencode($storeFile->name).'">'.
'<a href="download?fileName='.urlencode($storeFile->name).'">'.
' <img class="icon-download" src="css/images/download.svg" alt="Download" title="Download"'.
' /></a></td>'.
'<td class="contentCells contentCells-icon contentCells-shift">'.

View File

@ -17,6 +17,7 @@
namespace OnlineEditorsExamplePhp\Views;
use OnlineEditorsExamplePhp\Configuration\ConfigurationManager;
use OnlineEditorsExamplePhp\Helpers\ConfigManager;
use OnlineEditorsExamplePhp\Helpers\ExampleUsers;
use function OnlineEditorsExamplePhp\getStoredFiles;
@ -61,8 +62,8 @@ final class IndexView extends View
private function getLanguageListOptionsLayout()
{
$layout = "";
$configManager = new ConfigManager();
foreach ($configManager->getConfig("languages") as $key => $language) {
$config_manager = new ConfigurationManager();
foreach ($config_manager->languages() as $key => $language) {
$layout .= '<option value="'.$key.'">'.$language.'</option>'.PHP_EOL;
}
return $layout;
@ -100,16 +101,12 @@ final class IndexView extends View
private function getPreloaderUrl()
{
$configManager = new ConfigManager();
return $configManager->getConfig("docServSiteUrl").
$configManager->getConfig("docServPreloaderUrl");
$config_manager = new ConfigurationManager();
return $config_manager->document_server_preloader_url()->string();
}
private function getEditButton()
{
$configManager = new ConfigManager();
return $configManager->getConfig("mode") != "view" ?
'<div id="beginEdit" class="button orange disable">Edit</div>' : "";
return '<div id="beginEdit" class="button orange disable">Edit</div>';
}
}

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<customErrors mode="Off"/>
</system.web>
<system.webServer>
<defaultDocument enabled="true" />
<httpErrors errorMode="Detailed"/>
<urlCompression doDynamicCompression="false"/>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>

View File

@ -1,120 +0,0 @@
<?php
/**
* (c) Copyright Ascensio System SIA 2023
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace OnlineEditorsExamplePhp;
use OnlineEditorsExamplePhp\Helpers\ConfigManager;
/**
* WebEditor AJAX Process Execution.
*/
require_once dirname(__FILE__) . '/ajax.php';
require_once dirname(__FILE__) . '/functions.php';
require_once dirname(__FILE__) . '/trackmanager.php';
require_once dirname(__FILE__) . '/vendor/autoload.php';
$configManager = new ConfigManager();
// define tracker status
$_trackerStatus = [
0 => 'NotFound',
1 => 'Editing',
2 => 'MustSave',
3 => 'Corrupted',
4 => 'Closed',
6 => 'MustForceSave',
7 => 'CorruptedForceSave',
];
// ignore self-signed certificate
if ($configManager->getConfig("docServVerifyPeerOff") === true) {
stream_context_set_default([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
],
]);
}
// check if type value exists
if (isset($_GET["type"]) && !empty($_GET["type"])) {
@header('Content-Type: application/json; charset==utf-8');
@header('X-Robots-Tag: noindex');
@header('X-Content-Type-Options: nosniff');
// set headers that prevent caching in all the browsers
nocacheHeaders();
// write the request result to the log file
sendlog(serialize($_GET), "webedior-ajax.log");
$type = $_GET["type"];
// switch case for type value
switch ($type) {
case "upload":
$response_array = upload();
$response_array['status'] = isset($response_array['error']) ? 'error' : 'success';
die(json_encode($response_array));
case "download":
$response_array = download();
$response_array['status'] = 'success';
die(json_encode($response_array));
case "history":
$response_array = historyDownload();
$response_array['status'] = 'success';
die(json_encode($response_array));
case "convert":
$response_array = convert();
$response_array['status'] = 'success';
die(json_encode($response_array));
case "track":
$response_array = track();
$response_array['status'] = 'success';
die(json_encode($response_array));
case "delete":
$response_array = delete();
$response_array['status'] = 'success';
die(json_encode($response_array));
case "assets":
$response_array = assets();
$response_array['status'] = 'success';
die(json_encode($response_array));
case "csv":
$response_array = csv();
$response_array['status'] = 'success';
die(json_encode($response_array));
case "reference":
$response_array = reference();
$response_array['status'] = 'success';
die(json_encode($response_array));
case "files":
$response_array = files();
die(json_encode($response_array));
case "saveas":
$response_array = saveas();
$response_array['status'] = 'success';
die(json_encode($response_array));
case "rename":
$response_array = renamefile();
die(json_encode($response_array));
default:
$response_array['status'] = 'error';
$response_array['error'] = '404 Method not found';
die(json_encode($response_array));
}
}

View File

@ -1,3 +1,3 @@
*.egg-info
build
storage/*
storage

View File

@ -1,9 +1,17 @@
ONLYOFFICE Applications example uses code from the following 3rd party projects:
django-stubs - PEP-484 stubs for Django. (https://github.com/typeddjango/django-stubs/blob/master/LICENSE.md)
License: MIT
License File: django-stubs.license
Django - Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. Thanks for checking it out. (https://github.com/django/django/blob/main/LICENSE)
License: BSD-3-Clause
License File: Django.license
flake8 - flake8 is a python tool that glues together pycodestyle, pyflakes, mccabe, and third-party plugins to check the style and quality of some python code. (https://github.com/PyCQA/flake8/blob/main/LICENSE)
License: MIT
License File: flake8.license
jQuery.BlockUI - The jQuery BlockUI Plugin lets you simulate synchronous behavior when using AJAX, without locking the browser. (https://github.com/malsup/blockui/)
License: MIT, GPL
License File: jQuery.BlockUI.license
@ -28,7 +36,7 @@ jQuery.UI - jQuery UI is an open source library of interface components —
License: MIT
License File: jQuery.UI.license
mypy - Optional static typing for Python. (https://github.com/python/mypy/raw/v1.4.1/LICENSE)
mypy - Optional static typing for Python. (https://github.com/python/mypy/blob/master/LICENSE)
License: MIT
License File: mypy.license
@ -36,10 +44,6 @@ PyJWT - A Python implementation of RFC 7519. (https://github.com/jpadill
License: MIT
License File: PyJWT.license
pylint - It's not just a linter that annoys you! (https://github.com/pylint-dev/pylint/raw/v2.17.4/LICENSE)
License: GPL v2
License File: pylint.license
python-magic - python-magic is a Python interface to the libmagic file type identification library. (https://github.com/ahupp/python-magic/blob/master/LICENSE)
License: MIT
License File: python-magic.license
@ -47,3 +51,7 @@ License File: python-magic.license
requests - Requests allows you to send HTTP/1.1 requests extremely easily. Theres no need to manually add query strings to your URLs, or to form-encode your PUT & POST data — but nowadays, just use the json method! (https://github.com/psf/requests/blob/main/LICENSE)
License: Apache 2.0
License File: requests.license
typeshed - Collection of library stubs for Python, with static types. (https://github.com/python/typeshed/blob/main/LICENSE)
License: Apache 2.0
License File: typeshed.license

View File

@ -1,13 +1,19 @@
FROM python:3.11.4-alpine3.18 as example
FROM python:3.11.4-alpine3.18 AS example-base
WORKDIR /srv
COPY . .
RUN \
apk update && \
apk add --no-cache \
libmagic \
make && \
make prod
CMD ["make", "prod-server"]
make
FROM nginx:1.23.4-alpine3.17 as proxy
FROM example-base AS example-dev
RUN make dev
CMD ["make", "server-dev"]
FROM example-base AS example-prod
RUN make prod
CMD ["make", "server-prod"]
FROM nginx:1.23.4-alpine3.17 AS proxy
COPY proxy/nginx.conf /etc/nginx/nginx.conf

View File

@ -1,39 +1,55 @@
.DEFAULT_GOAL := help
.PHONY: help
help: # Show help message for each of the Makefile recipes.
help: # Show help message for each of the Makefile recipes.
@grep -E "^[a-z-]+: #" $(MAKEFILE_LIST) | \
sort | \
awk 'BEGIN {FS = ": # "}; {printf "%s: %s\n", $$1, $$2}'
.PHONY: dev
dev: # Install development dependencies.
dev: # Install development dependencies.
@pip install --editable .[development]
.PHONY: dev-server
dev-server: \
export DEBUG := true
dev-server: # Start the development server on localhost at $PORT (default: 8000).
@python manage.py runserver
.PHONY: lint
lint: # Lint the source code for style and check for types.
@pylint --recursive=y .
@mypy .
.PHONY: prod
prod: # Install production dependencies.
prod: # Install production dependencies.
@pip install .
.PHONY: prod-server
prod-server: # Start the production server on 0.0.0.0 at $PORT (default: 8000).
.PHONY: server-dev
server-dev: # Start the development server on localhost at $PORT (default: 8000).
@python manage.py runserver
.PHONY: test
test: # Recursively run the tests.
@python -m unittest ./src/**/*_tests.py
.PHONY: server-prod
server-prod: \
export DEBUG := false
server-prod: # Start the production server on 0.0.0.0 at $PORT (default: 8000).
@python manage.py runserver
.PHONY: up
up: # Build and up docker containers.
@docker-compose build
@docker-compose up -d
.PHONY: compose-dev
compose-dev: # Up containers in a development environment.
@docker-compose \
--file compose-base.yml \
--file compose-dev.yml \
build
@docker-compose \
--file compose-base.yml \
--file compose-dev.yml \
up --detach
.PHONY: compose-prod
compose-prod: # Up containers in a production environment.
@docker-compose \
--file compose-base.yml \
--file compose-prod.yml \
build
@docker-compose \
--file compose-base.yml \
--file compose-prod.yml \
up --detach
.PHONY: lint
lint: # Lint the source code for style and check for types.
@flake8
@mypy .
.PHONY: test
test: # Recursively run the tests.
@python -m unittest ./src/**/*_tests.py

View File

@ -0,0 +1,33 @@
version: "3.8"
services:
# document-server:
# container_name: document-server
# image: onlyoffice/documentserver:7.3.3.50
# expose:
# - "80"
# environment:
# - JWT_SECRET=your-256-bit-secret
example:
container_name: example
build:
context: .
expose:
- "80"
environment:
- ADDRESS=0.0.0.0
- DOCUMENT_SERVER_PRIVATE_URL=http://proxy:8080
- DOCUMENT_SERVER_PUBLIC_URL=http://localhost:8080
- EXAMPLE_URL=http://proxy
- JWT_SECRET=your-256-bit-secret
- PORT=80
proxy:
container_name: proxy
build:
context: .
target: proxy
ports:
- "80:80"
- "8080:8080"

View File

@ -0,0 +1,6 @@
version: "3.8"
services:
example:
build:
target: example-dev

View File

@ -0,0 +1,6 @@
version: "3.8"
services:
example:
build:
target: example-prod

View File

@ -1,9 +1,17 @@
ONLYOFFICE Applications example uses code from the following 3rd party projects:
django-stubs - PEP-484 stubs for Django. (https://github.com/typeddjango/django-stubs/blob/master/LICENSE.md)
License: MIT
License File: django-stubs.license
Django - Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. Thanks for checking it out. (https://github.com/django/django/blob/main/LICENSE)
License: BSD-3-Clause
License File: Django.license
flake8 - flake8 is a python tool that glues together pycodestyle, pyflakes, mccabe, and third-party plugins to check the style and quality of some python code. (https://github.com/PyCQA/flake8/blob/main/LICENSE)
License: MIT
License File: flake8.license
jQuery.BlockUI - The jQuery BlockUI Plugin lets you simulate synchronous behavior when using AJAX, without locking the browser. (https://github.com/malsup/blockui/)
License: MIT, GPL
License File: jQuery.BlockUI.license
@ -28,7 +36,7 @@ jQuery.UI - jQuery UI is an open source library of interface components —
License: MIT
License File: jQuery.UI.license
mypy - Optional static typing for Python. (https://github.com/python/mypy/raw/v1.4.1/LICENSE)
mypy - Optional static typing for Python. (https://github.com/python/mypy/blob/master/LICENSE)
License: MIT
License File: mypy.license
@ -36,10 +44,6 @@ PyJWT - A Python implementation of RFC 7519. (https://github.com/jpadill
License: MIT
License File: PyJWT.license
pylint - It's not just a linter that annoys you! (https://github.com/pylint-dev/pylint/raw/v2.17.4/LICENSE)
License: GPL v2
License File: pylint.license
python-magic - python-magic is a Python interface to the libmagic file type identification library. (https://github.com/ahupp/python-magic/blob/master/LICENSE)
License: MIT
License File: python-magic.license
@ -47,3 +51,7 @@ License File: python-magic.license
requests - Requests allows you to send HTTP/1.1 requests extremely easily. Theres no need to manually add query strings to your URLs, or to form-encode your PUT & POST data — but nowadays, just use the json method! (https://github.com/psf/requests/blob/main/LICENSE)
License: Apache 2.0
License File: requests.license
typeshed - Collection of library stubs for Python, with static types. (https://github.com/python/typeshed/blob/main/LICENSE)
License: Apache 2.0
License File: typeshed.license

View File

@ -0,0 +1,8 @@
Copyright (c) Maxim Kurnikov.
All rights reserved.
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

@ -0,0 +1,22 @@
== Flake8 License (MIT) ==
Copyright (C) 2011-2013 Tarek Ziade <tarek@ziade.org>
Copyright (C) 2012-2016 Ian Cordasco <graffatcolmingov@gmail.com>
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,340 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -0,0 +1,237 @@
The "typeshed" project is licensed under the terms of the Apache license, as
reproduced below.
= = = = =
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
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.
= = = = =
Parts of typeshed are licensed under different licenses (like the MIT
license), reproduced below.
= = = = =
The MIT License
Copyright (c) 2015 Jukka Lehtosalo 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.
= = = = =

View File

@ -1,41 +1,52 @@
from os import environ
from pathlib import Path
from sys import argv
from uuid import uuid1
from mimetypes import add_type
from django import setup
from django.conf import settings
from django.core.management import execute_from_command_line
from django.core.management.commands.runserver import Command as RunServer
from django.conf.urls.static import static
from django.urls import path
from src.history import HistoryController
from src.common import string
from src.views import actions, index
def debug():
env = environ.get('DEBUG')
if env is None:
return False
if env == 'true':
return True
return False
return string.boolean(env, True)
def address():
env = environ.get('ADDRESS')
if env is not None:
return env
if settings.DEBUG:
return '127.0.0.1'
return RunServer.default_addr
return '0.0.0.0'
def port():
env = environ.get('PORT')
return env or '8000'
if env:
return int(env)
return RunServer.default_port
def configuration():
file = Path(__file__)
base_dir = file.parent
static_root = base_dir.joinpath('static')
static_url = f'{static_root.name}/'
return {
'ALLOWED_HOSTS': [
'*'
],
'BASE_DIR': f'{base_dir}',
'DEBUG': debug(),
'MIDDLEWARE': [
'src.utils.historyManager.CorsHeaderMiddleware'
],
'ROOT_URLCONF': __name__,
'SECRET_KEY': uuid1(),
'STATIC_URL': 'static/',
'STATIC_ROOT': f'{static_root}',
'STATIC_URL': static_url,
'TEMPLATES': [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
@ -47,8 +58,7 @@ def configuration():
}
def routers():
history = HistoryController()
return [
main = [
path('', index.default),
path('convert', actions.convert),
path('create', actions.createNew),
@ -57,37 +67,25 @@ def routers():
path('downloadhistory', actions.downloadhistory),
path('edit', actions.edit),
path('files', actions.files),
path('formats-convertible', actions.formats_convertible),
path('reference', actions.reference),
path('remove', actions.remove),
path('rename', actions.rename),
path('restore', actions.restore),
path('saveas', actions.saveAs),
path('track', actions.track),
path('upload', actions.upload),
path(
'history/<str:source_basename>',
history.history
),
path(
'history/<str:source_basename>/<int:version>/data',
history.data
),
path(
'history/<str:source_basename>/<int:version>/download/<str:basename>',
history.download
),
path(
'history/<str:source_basename>/<int:version>/restore',
history.restore
)
path('upload', actions.upload)
]
main += static(
settings.STATIC_URL,
document_root=settings.STATIC_ROOT
)
return main
add_type('text/javascript', '.js', True)
settings.configure(**configuration())
urlpatterns = routers()
RunServer.default_addr = address()
# False positive: the default_port isn't an int, it's a str.
RunServer.default_port = port() # type: ignore # noqa: E261
RunServer.default_port = port()
setup()
if __name__ == '__main__':

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