mirror of
https://github.com/ONLYOFFICE/document-server-integration.git
synced 2026-04-07 14:06:11 +08:00
Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 05a3110c99 | |||
| 8bafa3ff3a | |||
| 56679a3b75 | |||
| d4d758770f | |||
| 874ebff886 | |||
| 4f2f877f0e | |||
| 5cc6b4cb15 | |||
| 7a70a44bcb | |||
| e42bd53664 | |||
| 23e616aade | |||
| f035da0db4 | |||
| 3e12ec4ebe | |||
| 589ca9b601 | |||
| 32f1ec82d1 | |||
| 54bb5b0a24 | |||
| 8274c16f6d | |||
| 7a982fc785 | |||
| 6f5800fbde | |||
| 8ec632eebd | |||
| b6ca4535ce | |||
| 089fc8bfa0 | |||
| 0b4c17ea0a | |||
| 405be2847b | |||
| f809c7e525 | |||
| 44061c82a9 | |||
| ef4e283804 | |||
| 4b0ad1a192 | |||
| 60469b0dba | |||
| f5ac95e1cc | |||
| c4c2fbb945 | |||
| 99b5fcd562 | |||
| 7e34067410 | |||
| a44787c625 | |||
| 105afb2c34 | |||
| 002f9b958e | |||
| 56d5913808 | |||
| 6664864bed | |||
| 6c9e6e9304 | |||
| 416b1fde8c | |||
| 383f240825 | |||
| 642e145142 | |||
| 8f09dadfa0 | |||
| 495f1cf49a | |||
| cf01b5e0ae | |||
| 0673fed928 | |||
| 9b0b30a0b0 | |||
| 200187edce | |||
| 23176ddf07 | |||
| 9857cef8fc | |||
| 204f770401 | |||
| 61834e3ec6 | |||
| 2ca6185ac4 | |||
| e818bb978b | |||
| 3a4cf5e6e6 | |||
| 7ec16b90e3 | |||
| fcfb6efda7 | |||
| e4c72c98d1 | |||
| c2bbda542a | |||
| 2c12393c78 | |||
| 4e93f6ebac | |||
| d10ba9f773 | |||
| a0bf7db118 | |||
| e40e7cc41c | |||
| f616655f4c | |||
| 4ba708631e | |||
| b9c1bc0f42 | |||
| 215ade01a3 | |||
| 4d25418fc8 | |||
| 4539bac5db | |||
| eb196613e7 | |||
| 7ac788f589 | |||
| 55119458af | |||
| 3c18add1fc | |||
| 6bf63b7166 | |||
| 32df2d3e34 | |||
| 97c7859db5 | |||
| 492f9c7baa | |||
| e0c0595796 | |||
| 40b8fb88a8 | |||
| b0df0d72df | |||
| 1053add1d9 | |||
| f1fc0e5fae | |||
| a192c6ce1f | |||
| e8aec0b68c | |||
| d9667f9757 | |||
| 3a985da120 | |||
| a88f84ddac | |||
| 6525d7210f | |||
| 6b93311ce5 | |||
| 999561ffd6 | |||
| e539c1205f | |||
| 9a52a538cb | |||
| e8038a8e88 | |||
| 1045b314b6 | |||
| 1636732521 | |||
| daa9a5f3fa | |||
| 9bf3973215 | |||
| cad2a20cdf | |||
| 82a5a68e6c | |||
| 0e1a580a86 | |||
| c09f3fc4b9 | |||
| d4d7c4e222 | |||
| 14429c5b05 | |||
| 131e33c6af | |||
| 8a04e5fbc4 | |||
| 1b6435a7dc | |||
| b8eecab45f | |||
| f7259409a2 | |||
| 0ea9e68c7c | |||
| 4b72e0a664 | |||
| 935377a941 | |||
| 3690aacb66 |
@ -67,6 +67,15 @@ The methods described below are available for all of the test examples.
|
||||
| **Response** | **Code:** 200 OK <br />**Content on success:**<br /> `[{ "version": <file_version>, "id": <file_id>, "contentLength": <file_size_in_kilobytes>, "pureContentLength": <file_size_in_bytes>, "title": <file_name>, "updated": <last_change_date>}]`<br />**Content on error:**<br /> `"File not found"` |
|
||||
| **Sample** | `curl -X GET http://localhost/files/{fileId}` |
|
||||
|
||||
## Important security info
|
||||
|
||||
Please keep in mind the following security aspects when you are using test examples:
|
||||
|
||||
* There is no protection of the storage from unauthorized access since there is no need for authorization.
|
||||
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
|
||||
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
|
||||
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
|
||||
|
||||
## Project Information
|
||||
|
||||
Official website: [https://www.onlyoffice.com](https://www.onlyoffice.com/?utm_source=github&utm_medium=cpc&utm_campaign=GitHubIntegrationEx)
|
||||
|
||||
@ -25,6 +25,7 @@ using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Script.Serialization;
|
||||
using OnlineEditorsExampleMVC.Models;
|
||||
using System.Net;
|
||||
|
||||
namespace OnlineEditorsExampleMVC.Helpers
|
||||
{
|
||||
@ -416,5 +417,27 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
// enable certificate ignore
|
||||
public static void VerifySSL()
|
||||
{
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if(WebConfigurationManager.AppSettings["files.docservice.verify-peer-off"].Equals("true")) {
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, string> GetLanguages()
|
||||
{
|
||||
var languages = new Dictionary<string, string>();
|
||||
String[] couples = (WebConfigurationManager.AppSettings["files.docservice.languages"] ?? "").Split('|');
|
||||
foreach (string couple in couples)
|
||||
{
|
||||
String[] tmp = couple.Split(':');
|
||||
languages.Add(tmp[0],tmp[1]);
|
||||
}
|
||||
return languages;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -143,6 +143,8 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
requestStream.Write(bytes, 0, bytes.Length); // and write the serialized body object to it
|
||||
}
|
||||
|
||||
DocManagerHelper.VerifySSL();
|
||||
|
||||
string dataResponse;
|
||||
using (var response = request.GetResponse())
|
||||
using (var stream = response.GetResponseStream()) // get the response stream
|
||||
|
||||
@ -76,7 +76,9 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
|
||||
if (token != null && !token.Equals("")) // invalid signature error
|
||||
{
|
||||
fileData = (Dictionary<string, object>)jss.Deserialize<Dictionary<string, object>>(token)["payload"];
|
||||
fileData = jss.Deserialize<Dictionary<string, object>>(token);
|
||||
if (fileData.ContainsKey("payload"))
|
||||
fileData = (Dictionary<string, object>)fileData["payload"];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -126,6 +128,8 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
}
|
||||
}
|
||||
|
||||
DocManagerHelper.VerifySSL();
|
||||
|
||||
var storagePath = DocManagerHelper.StoragePath(newFileName, userAddress); // get the file path
|
||||
var histDir = DocManagerHelper.HistoryDir(storagePath); // get the path to the history directory
|
||||
if (!Directory.Exists(histDir)) Directory.CreateDirectory(histDir);
|
||||
@ -201,6 +205,8 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
}
|
||||
}
|
||||
|
||||
DocManagerHelper.VerifySSL();
|
||||
|
||||
string forcesavePath = "";
|
||||
Boolean isSubmitForm = fileData["forcesavetype"].ToString().Equals("3"); // SubmitForm
|
||||
|
||||
@ -243,8 +249,10 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
}
|
||||
|
||||
// create a command request
|
||||
public static void commandRequest(string method, string key)
|
||||
public static void commandRequest(string method, string key, object meta = null)
|
||||
{
|
||||
DocManagerHelper.VerifySSL();
|
||||
|
||||
string documentCommandUrl = WebConfigurationManager.AppSettings["files.docservice.url.site"] + WebConfigurationManager.AppSettings["files.docservice.url.command"];
|
||||
|
||||
var request = (HttpWebRequest)WebRequest.Create(documentCommandUrl);
|
||||
@ -256,6 +264,11 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
{ "key", key }
|
||||
};
|
||||
|
||||
if (meta != null)
|
||||
{
|
||||
body.Add("meta", meta);
|
||||
}
|
||||
|
||||
// check if a secret key to generate token exists or not
|
||||
if (JwtManager.Enabled)
|
||||
{
|
||||
|
||||
@ -66,7 +66,8 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
"The file favorite state is undefined",
|
||||
"Can't mention others in comments",
|
||||
"Can't create new files from the editor",
|
||||
"Can’t see anyone’s information"
|
||||
"Can’t see anyone’s information",
|
||||
"Can't rename files from the editor"
|
||||
};
|
||||
|
||||
private static List<User> users = new List<User>() {
|
||||
|
||||
1
web/documentserver-example/csharp-mvc/Models/FileModel.cs
Normal file → Executable file
1
web/documentserver-example/csharp-mvc/Models/FileModel.cs
Normal file → Executable file
@ -188,6 +188,7 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
"customization", new Dictionary<string, object>
|
||||
{
|
||||
{ "about", true }, // the About section display
|
||||
{ "comments", true },
|
||||
{ "feedback", true }, // the Feedback & Support menu button display
|
||||
{ "forcesave", false }, // adds the request for the forced file saving to the callback handler
|
||||
{ "submitForm", submitForm }, // if the Submit form button is displayed or not
|
||||
|
||||
@ -70,3 +70,12 @@ Configure the IIS components for the server to work correctly:
|
||||
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
|
||||
|
||||
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
|
||||
|
||||
## Important security info
|
||||
|
||||
Please keep in mind the following security aspects when you are using test examples:
|
||||
|
||||
* There is no protection of the storage from unauthorized access since there is no need for authorization.
|
||||
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
|
||||
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
|
||||
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
|
||||
@ -46,6 +46,7 @@
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
var docEditor;
|
||||
var config;
|
||||
|
||||
var innerAlert = function (message, inEditor) {
|
||||
if (console && console.log)
|
||||
@ -107,10 +108,14 @@
|
||||
|
||||
// the meta information of the document is changed via the meta command
|
||||
var onMetaChange = function (event) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
if (event.data.favorite) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
}
|
||||
|
||||
innerAlert("onMetaChange: " + JSON.stringify(event.data));
|
||||
};
|
||||
|
||||
// the user is trying to insert an image by clicking the Image from Storage button
|
||||
@ -146,7 +151,7 @@
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "webeditor.ashx?type=saveas");
|
||||
xhr.setRequestHeader( 'Content-Type', 'application/json');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
@ -154,7 +159,25 @@
|
||||
}
|
||||
};
|
||||
|
||||
var config = <%= Model.GetDocConfig(Request, Url) %>;
|
||||
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
|
||||
innerAlert("onRequestRename: " + JSON.stringify(event.data));
|
||||
|
||||
var newfilename = event.data;
|
||||
var data = {
|
||||
newfilename: newfilename,
|
||||
dockey: config.document.key,
|
||||
};
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "webeditor.ashx?type=rename");
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
}
|
||||
};
|
||||
|
||||
config = <%= Model.GetDocConfig(Request, Url) %>;
|
||||
|
||||
config.width = "100%";
|
||||
config.height = "100%";
|
||||
@ -174,42 +197,49 @@
|
||||
|
||||
<% string hist, histData; %>
|
||||
<% Model.GetHistory(out hist, out histData); %>
|
||||
<% if (!string.IsNullOrEmpty(hist) && !string.IsNullOrEmpty(histData))
|
||||
{ %>
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(<%= hist %>); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = <%= histData %>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose '] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
<% } %>
|
||||
|
||||
<% string usersForMentions; %>
|
||||
<% Model.GetUsersMentions(Request, out usersForMentions); %>
|
||||
<% if (!string.IsNullOrEmpty(usersForMentions))
|
||||
// add mentions for not anonymous users
|
||||
{ %>
|
||||
config.events['onRequestUsers'] = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
"users": <%= usersForMentions%>
|
||||
});
|
||||
};
|
||||
// the user is mentioned in a comment
|
||||
config.events['onRequestSendNotify'] = function (event) {
|
||||
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
<% } %>
|
||||
|
||||
|
||||
if (config.editorConfig.user.id) {
|
||||
<% if (!string.IsNullOrEmpty(hist) && !string.IsNullOrEmpty(histData))
|
||||
{ %>
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(<%= hist %>); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = <%= histData %>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose '] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
<% } %>
|
||||
|
||||
// add mentions for not anonymous users
|
||||
<% if (!string.IsNullOrEmpty(usersForMentions))
|
||||
{ %>
|
||||
config.events['onRequestUsers'] = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
"users": <%= usersForMentions %>
|
||||
});
|
||||
};
|
||||
<% } %>
|
||||
|
||||
// the user is mentioned in a comment
|
||||
config.events['onRequestSendNotify'] = function (event) {
|
||||
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
// prevent file renaming for anonymous users
|
||||
config.events['onRequestRename'] = onRequestRename;
|
||||
}
|
||||
|
||||
if (config.editorConfig.createUrl) {
|
||||
config.events.onRequestSaveAs = onRequestSaveAs;
|
||||
};
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
<%@ Import Namespace="System.Web.Configuration" %>
|
||||
<%@ Import Namespace="OnlineEditorsExampleMVC.Helpers" %>
|
||||
<%@ Import Namespace="OnlineEditorsExampleMVC.Models" %>
|
||||
<%@ Import Namespace="System.Collections.Generic" %>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
@ -89,7 +90,7 @@
|
||||
<select class="select-user" id="user">
|
||||
<% foreach (User user in Users.getAllUsers())
|
||||
{ %>
|
||||
<option value=<%= user.id %> ><%= user.name.IsEmpty() ? "Anonymous" : user.name %></option>
|
||||
<option value="<%= user.id %>"><%= user.name.IsEmpty() ? "Anonymous" : user.name %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
</td>
|
||||
@ -98,37 +99,11 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<select class="select-user" id="language">
|
||||
<option value="en">English</option>
|
||||
<option value="be">Belarusian</option>
|
||||
<option value="bg">Bulgarian</option>
|
||||
<option value="ca">Catalan</option>
|
||||
<option value="zh">Chinese</option>
|
||||
<option value="cs">Czech</option>
|
||||
<option value="da">Danish</option>
|
||||
<option value="nl">Dutch</option>
|
||||
<option value="fi">Finnish</option>
|
||||
<option value="fr">French</option>
|
||||
<option value="de">German</option>
|
||||
<option value="el">Greek</option>
|
||||
<option value="hu">Hungarian</option>
|
||||
<option value="id">Indonesian</option>
|
||||
<option value="it">Italian</option>
|
||||
<option value="ja">Japanese</option>
|
||||
<option value="ko">Korean</option>
|
||||
<option value="lv">Latvian</option>
|
||||
<option value="lo">Lao</option>
|
||||
<option value="nb">Norwegian</option>
|
||||
<option value="pl">Polish</option>
|
||||
<option value="pt">Portuguese</option>
|
||||
<option value="ro">Romanian</option>
|
||||
<option value="ru">Russian</option>
|
||||
<option value="sk">Slovak</option>
|
||||
<option value="sl">Slovenian</option>
|
||||
<option value="sv">Swedish</option>
|
||||
<option value="es">Spanish</option>
|
||||
<option value="tr">Turkish</option>
|
||||
<option value="uk">Ukrainian</option>
|
||||
<option value="vi">Vietnamese</option>
|
||||
<% Dictionary<string, string> languages = DocManagerHelper.GetLanguages();
|
||||
foreach (var lang in languages)
|
||||
{ %>
|
||||
<option value="<%= lang.Key %>"><%= lang.Value %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Web;
|
||||
@ -70,6 +71,9 @@ namespace OnlineEditorsExampleMVC
|
||||
case "saveas":
|
||||
SaveAs(context);
|
||||
break;
|
||||
case "rename":
|
||||
Rename(context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,6 +117,8 @@ namespace OnlineEditorsExampleMVC
|
||||
|
||||
var req = (HttpWebRequest)WebRequest.Create(fileUrl);
|
||||
|
||||
DocManagerHelper.VerifySSL();
|
||||
|
||||
using (var stream = req.GetResponse().GetResponseStream())
|
||||
{
|
||||
|
||||
@ -151,6 +157,8 @@ namespace OnlineEditorsExampleMVC
|
||||
context.Response.ContentType = "text/plain";
|
||||
try
|
||||
{
|
||||
DocManagerHelper.VerifySSL();
|
||||
|
||||
var httpPostedFile = context.Request.Files[0];
|
||||
string fileName;
|
||||
|
||||
@ -250,6 +258,8 @@ namespace OnlineEditorsExampleMVC
|
||||
|
||||
var req = (HttpWebRequest)WebRequest.Create(newFileUri);
|
||||
|
||||
DocManagerHelper.VerifySSL();
|
||||
|
||||
using (var stream = req.GetResponse().GetResponseStream()) // get response stream of the converting file
|
||||
{
|
||||
if (stream == null) throw new Exception("Stream is null");
|
||||
@ -541,5 +551,36 @@ namespace OnlineEditorsExampleMVC
|
||||
context.Response.Write("{ \"error\": \"File not found!\"}");
|
||||
}
|
||||
}
|
||||
|
||||
// rename a file
|
||||
private static void Rename(HttpContext context)
|
||||
{
|
||||
// read request body
|
||||
context.Response.ContentType = "text/plain";
|
||||
string fileData;
|
||||
try
|
||||
{
|
||||
using (var receiveStream = context.Request.InputStream)
|
||||
using (var readStream = new StreamReader(receiveStream))
|
||||
{
|
||||
fileData = readStream.ReadToEnd();
|
||||
if (string.IsNullOrEmpty(fileData)) context.Response.Write("{\"error\":\"Request stream is empty\"}");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new HttpException((int)HttpStatusCode.BadRequest, e.Message);
|
||||
}
|
||||
|
||||
var jss = new JavaScriptSerializer();
|
||||
var body = jss.Deserialize<Dictionary<string, object>>(fileData);
|
||||
var newFileName = (string) body["newfilename"];
|
||||
var docKey = (string) body["dockey"];
|
||||
var meta = new Dictionary<string, object>() {
|
||||
{ "title", newFileName }
|
||||
};
|
||||
TrackManager.commandRequest("meta", docKey, meta);
|
||||
context.Response.Write("{ \"result\": \"OK\"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Submodule web/documentserver-example/csharp-mvc/assets updated: af97a54226...1d601d84c4
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml version="1.0"?>
|
||||
<appSettings>
|
||||
<clear />
|
||||
<add key="version" value="1.1.0"/>
|
||||
<add key="version" value="1.2.0"/>
|
||||
|
||||
<add key="filesize-max" value="52428800"/>
|
||||
<add key="storage-path" value=""/>
|
||||
@ -14,6 +14,10 @@
|
||||
<add key="files.docservice.secret" value="" />
|
||||
<add key="files.docservice.header" value="Authorization" />
|
||||
|
||||
<add key="files.docservice.verify-peer-off" value="true"/>
|
||||
|
||||
<add key="files.docservice.languages" value="en:English|az:Azerbaijani|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|nb:Norwegian|pl:Polish|pt:Portuguese|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese"/>
|
||||
|
||||
<add key="files.docservice.url.site" value="http://documentserver/"/>
|
||||
|
||||
<add key="files.docservice.url.converter" value="ConvertService.ashx"/>
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
<%@ Import Namespace="System.Linq" %>
|
||||
<%@ Import Namespace="System.Web.Configuration" %>
|
||||
<%@ Import Namespace="OnlineEditorsExample" %>
|
||||
<%@ Import Namespace="System.Collections.Generic" %>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
@ -100,37 +101,11 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<select class="select-user" id="language">
|
||||
<option value="en">English</option>
|
||||
<option value="be">Belarusian</option>
|
||||
<option value="bg">Bulgarian</option>
|
||||
<option value="ca">Catalan</option>
|
||||
<option value="zh">Chinese</option>
|
||||
<option value="cs">Czech</option>
|
||||
<option value="da">Danish</option>
|
||||
<option value="nl">Dutch</option>
|
||||
<option value="fi">Finnish</option>
|
||||
<option value="fr">French</option>
|
||||
<option value="de">German</option>
|
||||
<option value="el">Greek</option>
|
||||
<option value="hu">Hungarian</option>
|
||||
<option value="id">Indonesian</option>
|
||||
<option value="it">Italian</option>
|
||||
<option value="ja">Japanese</option>
|
||||
<option value="ko">Korean</option>
|
||||
<option value="lv">Latvian</option>
|
||||
<option value="lo">Lao</option>
|
||||
<option value="nb">Norwegian</option>
|
||||
<option value="pl">Polish</option>
|
||||
<option value="pt">Portuguese</option>
|
||||
<option value="ro">Romanian</option>
|
||||
<option value="ru">Russian</option>
|
||||
<option value="sk">Slovak</option>
|
||||
<option value="sl">Slovenian</option>
|
||||
<option value="sv">Swedish</option>
|
||||
<option value="es">Spanish</option>
|
||||
<option value="tr">Turkish</option>
|
||||
<option value="uk">Ukrainian</option>
|
||||
<option value="vi">Vietnamese</option>
|
||||
<% Dictionary<string, string> languages = GetLanguages();
|
||||
foreach (var lang in languages)
|
||||
{ %>
|
||||
<option value="<%= lang.Key %>"><%= lang.Value %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -353,11 +353,7 @@ namespace OnlineEditorsExample
|
||||
|
||||
try
|
||||
{
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if (IsMono)
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
}
|
||||
VerifySSL();
|
||||
|
||||
using (var stream = req.GetResponse().GetResponseStream()) // get response stream of the uploading file
|
||||
{
|
||||
@ -420,11 +416,7 @@ namespace OnlineEditorsExample
|
||||
|
||||
var req = (HttpWebRequest)WebRequest.Create(fileUrl);
|
||||
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if (IsMono)
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
}
|
||||
VerifySSL();
|
||||
|
||||
using (var stream = req.GetResponse().GetResponseStream())
|
||||
{
|
||||
@ -508,11 +500,7 @@ namespace OnlineEditorsExample
|
||||
|
||||
var req = (HttpWebRequest)WebRequest.Create(newFileUri);
|
||||
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if (IsMono)
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
}
|
||||
VerifySSL();
|
||||
|
||||
using (var stream = req.GetResponse().GetResponseStream()) // get response stream of the converting file
|
||||
{
|
||||
@ -616,5 +604,27 @@ namespace OnlineEditorsExample
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
// enable certificate ignore
|
||||
public static void VerifySSL()
|
||||
{
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if(WebConfigurationManager.AppSettings["files.docservice.verify-peer-off"].Equals("true")) {
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, string> GetLanguages()
|
||||
{
|
||||
var languages = new Dictionary<string, string>();
|
||||
String[] couples = (WebConfigurationManager.AppSettings["files.docservice.languages"] ?? "").Split('|');
|
||||
foreach (string couple in couples)
|
||||
{
|
||||
String[] tmp = couple.Split(':');
|
||||
languages.Add(tmp[0],tmp[1]);
|
||||
}
|
||||
return languages;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -64,6 +64,7 @@
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
var docEditor;
|
||||
var config;
|
||||
|
||||
var innerAlert = function (message, inEditor) {
|
||||
if (console && console.log)
|
||||
@ -125,10 +126,14 @@
|
||||
|
||||
// the meta information of the document is changed via the meta command
|
||||
var onMetaChange = function (event) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
if (event.data.favorite) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
}
|
||||
|
||||
innerAlert("onMetaChange: " + JSON.stringify(event.data));
|
||||
};
|
||||
|
||||
// the user is trying to insert an image by clicking the Image from Storage button
|
||||
@ -158,7 +163,7 @@
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "webeditor.ashx?type=saveas");
|
||||
xhr.setRequestHeader( 'Content-Type', 'application/json');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
@ -166,7 +171,25 @@
|
||||
}
|
||||
};
|
||||
|
||||
var config = <%= DocConfig %>;
|
||||
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
|
||||
innerAlert("onRequestRename: " + JSON.stringify(event.data));
|
||||
|
||||
var newfilename = event.data;
|
||||
var data = {
|
||||
newfilename: newfilename,
|
||||
dockey: config.document.key,
|
||||
};
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "webeditor.ashx?type=rename");
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
}
|
||||
};
|
||||
|
||||
config = <%= DocConfig %>;
|
||||
|
||||
config.width = "100%";
|
||||
config.height = "100%";
|
||||
@ -184,37 +207,42 @@
|
||||
"onRequestMailMergeRecipients": onRequestMailMergeRecipients,
|
||||
};
|
||||
|
||||
<% if (!string.IsNullOrEmpty(History) && !string.IsNullOrEmpty(HistoryData))
|
||||
{ %>
|
||||
config.events['onRequestHistory'] = function () { // the user is trying to show the document version history
|
||||
docEditor.refreshHistory(<%= History %>); // show the document version history
|
||||
};
|
||||
config.events['onRequestHistoryData'] = function (event) { // the user is trying to click the specific document version in the document version history
|
||||
var ver = event.data;
|
||||
var histData = <%= HistoryData %>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
config.events['onRequestHistoryClose '] = function () { // the user is trying to go back to the document from viewing the document version history
|
||||
document.location.reload();
|
||||
};
|
||||
<% } %>
|
||||
if (config.editorConfig.user.id) {
|
||||
<% if (!string.IsNullOrEmpty(History) && !string.IsNullOrEmpty(HistoryData))
|
||||
{ %>
|
||||
config.events['onRequestHistory'] = function () { // the user is trying to show the document version history
|
||||
docEditor.refreshHistory(<%= History %>); // show the document version history
|
||||
};
|
||||
config.events['onRequestHistoryData'] = function (event) { // the user is trying to click the specific document version in the document version history
|
||||
var ver = event.data;
|
||||
var histData = <%= HistoryData %>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
config.events['onRequestHistoryClose '] = function () { // the user is trying to go back to the document from viewing the document version history
|
||||
document.location.reload();
|
||||
};
|
||||
<% } %>
|
||||
|
||||
// add mentions for not anonymous users
|
||||
<% if (!string.IsNullOrEmpty(UsersForMentions))
|
||||
{ %>
|
||||
config.events['onRequestUsers'] = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
"users": <%= UsersForMentions %>
|
||||
});
|
||||
};
|
||||
<% } %>
|
||||
|
||||
// the user is mentioned in a comment
|
||||
config.events['onRequestSendNotify'] = function (event) {
|
||||
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
// prevent file renaming for anonymous users
|
||||
config.events['onRequestRename'] = onRequestRename;
|
||||
}
|
||||
|
||||
<% if (!string.IsNullOrEmpty(UsersForMentions))
|
||||
{ %>
|
||||
// add mentions for not anonymous users
|
||||
config.events['onRequestUsers'] = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
"users": <%= UsersForMentions %>
|
||||
});
|
||||
};
|
||||
// the user is mentioned in a comment
|
||||
config.events['onRequestSendNotify'] = function (event) {
|
||||
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
<% } %>
|
||||
|
||||
if (config.editorConfig.createUrl) {
|
||||
config.events.onRequestSaveAs = onRequestSaveAs;
|
||||
};
|
||||
|
||||
1
web/documentserver-example/csharp/DocEditor.aspx.cs
Normal file → Executable file
1
web/documentserver-example/csharp/DocEditor.aspx.cs
Normal file → Executable file
@ -256,6 +256,7 @@ namespace OnlineEditorsExample
|
||||
"customization", new Dictionary<string, object>
|
||||
{
|
||||
{ "about", true }, // the About section display
|
||||
{ "comments", true },
|
||||
{ "feedback", true }, // the Feedback & Support menu button display
|
||||
{ "forcesave", false }, // adds the request for the forced file saving to the callback handler
|
||||
{ "submitForm", submitForm }, // if the Submit form button is displayed or not
|
||||
|
||||
@ -145,11 +145,7 @@ namespace ASC.Api.DocumentConverter
|
||||
requestStream.Write(bytes, 0, bytes.Length); // and write the serialized body object to it
|
||||
}
|
||||
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if (_Default.IsMono)
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
}
|
||||
_Default.VerifySSL();
|
||||
|
||||
string dataResponse;
|
||||
using (var response = request.GetResponse())
|
||||
|
||||
@ -72,3 +72,12 @@ Configure the IIS components for the server to work correctly:
|
||||
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
|
||||
|
||||
Make sure that the Document Server in its turn has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
|
||||
|
||||
## Important security info
|
||||
|
||||
Please keep in mind the following security aspects when you are using test examples:
|
||||
|
||||
* There is no protection of the storage from unauthorized access since there is no need for authorization.
|
||||
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
|
||||
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
|
||||
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
|
||||
@ -78,7 +78,9 @@ namespace OnlineEditorsExample
|
||||
|
||||
if (token != null && !token.Equals("")) // invalid signature error
|
||||
{
|
||||
fileData = (Dictionary<string, object>)jss.Deserialize<Dictionary<string, object>>(token)["payload"];
|
||||
fileData = jss.Deserialize<Dictionary<string, object>>(token);
|
||||
if (fileData.ContainsKey("payload"))
|
||||
fileData = (Dictionary<string, object>)fileData["payload"];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -128,11 +130,7 @@ namespace OnlineEditorsExample
|
||||
}
|
||||
}
|
||||
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if (_Default.IsMono)
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
}
|
||||
_Default.VerifySSL();
|
||||
|
||||
var storagePath = _Default.StoragePath(newFileName, userAddress); // get the file path
|
||||
var histDir = _Default.HistoryDir(storagePath); // get the path to the history directory
|
||||
@ -209,11 +207,7 @@ namespace OnlineEditorsExample
|
||||
}
|
||||
}
|
||||
|
||||
// hack. http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if (_Default.IsMono)
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback += (s, ce, ca, p) => true;
|
||||
}
|
||||
_Default.VerifySSL();
|
||||
|
||||
string forcesavePath = "";
|
||||
Boolean isSubmitForm = fileData["forcesavetype"].ToString().Equals("3"); // SubmitForm
|
||||
@ -258,8 +252,10 @@ namespace OnlineEditorsExample
|
||||
}
|
||||
|
||||
// create a command request
|
||||
public static void commandRequest(string method, string key)
|
||||
public static void commandRequest(string method, string key, object meta = null)
|
||||
{
|
||||
_Default.VerifySSL();
|
||||
|
||||
string documentCommandUrl = WebConfigurationManager.AppSettings["files.docservice.url.site"] + WebConfigurationManager.AppSettings["files.docservice.url.command"];
|
||||
|
||||
var request = (HttpWebRequest)WebRequest.Create(documentCommandUrl);
|
||||
@ -271,13 +267,18 @@ namespace OnlineEditorsExample
|
||||
{ "key", key }
|
||||
};
|
||||
|
||||
if (meta != null)
|
||||
{
|
||||
body.Add("meta", meta);
|
||||
}
|
||||
|
||||
// check if a secret key to generate token exists or not
|
||||
if (JwtManager.Enabled)
|
||||
{
|
||||
var payload = new Dictionary<string, object>
|
||||
{
|
||||
{ "payload", body }
|
||||
};
|
||||
{
|
||||
{ "payload", body }
|
||||
};
|
||||
|
||||
var payloadToken = JwtManager.Encode(payload); // encode a payload object into a header token
|
||||
var bodyToken = JwtManager.Encode(body); // encode body into a body token
|
||||
|
||||
@ -65,7 +65,8 @@ namespace OnlineEditorsExample
|
||||
"The file favorite state is undefined",
|
||||
"Can't mention others in comments",
|
||||
"Can't create new files from the editor",
|
||||
"Can’t see anyone’s information"
|
||||
"Can’t see anyone’s information",
|
||||
"Can't rename files from the editor"
|
||||
};
|
||||
|
||||
private static List<User> users = new List<User>() {
|
||||
|
||||
@ -68,6 +68,9 @@ namespace OnlineEditorsExample
|
||||
case "saveas":
|
||||
SaveAs(context);
|
||||
break;
|
||||
case "rename":
|
||||
Rename(context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,5 +371,34 @@ namespace OnlineEditorsExample
|
||||
context.Response.Write("{ \"error\": \"File not found!\"}");
|
||||
}
|
||||
}
|
||||
|
||||
// rename a file
|
||||
private static void Rename(HttpContext context)
|
||||
{
|
||||
string fileData;
|
||||
try
|
||||
{
|
||||
using (var receiveStream = context.Request.InputStream)
|
||||
using (var readStream = new StreamReader(receiveStream))
|
||||
{
|
||||
fileData = readStream.ReadToEnd();
|
||||
if (string.IsNullOrEmpty(fileData)) return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new HttpException((int)HttpStatusCode.BadRequest, e.Message);
|
||||
}
|
||||
|
||||
var jss = new JavaScriptSerializer();
|
||||
var body = jss.Deserialize<Dictionary<string, object>>(fileData);
|
||||
var newFileName = (string) body["newfilename"];
|
||||
var docKey = (string) body["dockey"];
|
||||
var meta = new Dictionary<string, object>() {
|
||||
{ "title", newFileName }
|
||||
};
|
||||
TrackManager.commandRequest("meta", docKey, meta);
|
||||
context.Response.Write("{ \"result\": \"OK\"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Submodule web/documentserver-example/csharp/assets updated: af97a54226...1d601d84c4
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<appSettings>
|
||||
<clear />
|
||||
<add key="version" value="1.1.0"/>
|
||||
<add key="version" value="1.2.0"/>
|
||||
|
||||
<add key="filesize-max" value="52428800"/>
|
||||
<add key="storage-path" value=""/>
|
||||
@ -13,6 +13,9 @@
|
||||
<add key="files.docservice.timeout" value="120000" />
|
||||
<add key="files.docservice.secret" value="" />
|
||||
<add key="files.docservice.header" value="Authorization" />
|
||||
<add key="files.docservice.verify-peer-off" value="true"/>
|
||||
|
||||
<add key="files.docservice.languages" value="en:English|az:Azerbaijani|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|nb:Norwegian|pl:Polish|pt:Portuguese|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese"/>
|
||||
|
||||
<add key="files.docservice.url.site" value="http://documentserver/"/>
|
||||
|
||||
|
||||
@ -236,3 +236,12 @@ Make sure that the Document Server has access to the server with the example ins
|
||||
```
|
||||
http://server.address:server.port/
|
||||
```
|
||||
|
||||
## Important security info
|
||||
|
||||
Please keep in mind the following security aspects when you are using test examples:
|
||||
|
||||
* There is no protection of the storage from unauthorized access since there is no need for authorization.
|
||||
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
|
||||
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
|
||||
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
|
||||
@ -41,7 +41,8 @@ public class ExampleData {
|
||||
"The file favorite state is undefined",
|
||||
"Can't mention others in comments",
|
||||
"Can't create new files from the editor",
|
||||
"Can’t see anyone’s information"
|
||||
"Can’t see anyone’s information",
|
||||
"Can't rename files from the editor"
|
||||
);
|
||||
List<String> description_user_1 = List.of( // the description for user 1
|
||||
"File author by default",
|
||||
|
||||
@ -30,15 +30,23 @@ import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.util.SSLUtils;
|
||||
|
||||
@Configuration
|
||||
public class IntegrationConfiguration {
|
||||
|
||||
@Value("${files.storage}")
|
||||
private String storageAddress;
|
||||
|
||||
@Value("${files.docservice.verify-peer-off}")
|
||||
private String verifyPerrOff;
|
||||
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
|
||||
@Autowired
|
||||
private SSLUtils ssl;
|
||||
|
||||
@Bean
|
||||
public ModelMapper mapper(){ // create the model mapper
|
||||
ModelMapper mapper = new ModelMapper();
|
||||
@ -58,6 +66,17 @@ public class IntegrationConfiguration {
|
||||
@PostConstruct
|
||||
public void init(){ // initialize the storage path builder
|
||||
storagePathBuilder.configure(storageAddress.isBlank() ? null : storageAddress);
|
||||
if(!verifyPerrOff.isEmpty()) {
|
||||
try{
|
||||
if(verifyPerrOff.equals("true")) {
|
||||
ssl.turnOffSslChecking(); //the certificate will be ignored
|
||||
} else {
|
||||
ssl.turnOnSslChecking(); //the certificate will be verified
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@ -31,6 +31,7 @@ import com.onlyoffice.integration.services.UserServices;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import com.onlyoffice.integration.documentserver.util.service.ServiceConverter;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
import com.onlyoffice.integration.documentserver.managers.callback.CallbackManager;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -61,6 +62,12 @@ public class FileController {
|
||||
@Value("${filesize-max}")
|
||||
private String filesizeMax;
|
||||
|
||||
@Value("${files.docservice.url.site}")
|
||||
private String docserviceUrlSite;
|
||||
|
||||
@Value("${files.docservice.url.command}")
|
||||
private String docserviceUrlCommand;
|
||||
|
||||
@Autowired
|
||||
private FileUtility fileUtility;
|
||||
@Autowired
|
||||
@ -79,6 +86,8 @@ public class FileController {
|
||||
private ObjectMapper objectMapper;
|
||||
@Autowired
|
||||
private ServiceConverter serviceConverter;
|
||||
@Autowired
|
||||
private CallbackManager callbackManager;
|
||||
|
||||
// create user metadata
|
||||
private String createUserMetadata(String uid, String fullFileName) {
|
||||
@ -356,4 +365,22 @@ public class FileController {
|
||||
return "{ \"error\" : 1, \"message\" : \"" + e.getMessage() + "\"}";
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/rename")
|
||||
@ResponseBody
|
||||
public String rename(@RequestBody JSONObject body) {
|
||||
String newfilename = (String) body.get("newfilename");
|
||||
String dockey = (String) body.get("dockey");
|
||||
|
||||
HashMap<String, String> meta = new HashMap<>();
|
||||
meta.put("title", newfilename);
|
||||
|
||||
try {
|
||||
callbackManager.commandRequest("meta", dockey, meta);
|
||||
return "result ok";
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,6 +64,9 @@ public class IndexController {
|
||||
@Value("${url.editor}")
|
||||
private String urlEditor;
|
||||
|
||||
@Value("${files.docservice.languages}")
|
||||
private String langs;
|
||||
|
||||
@GetMapping("${url.index}")
|
||||
public String index(Model model){
|
||||
java.io.File[] files = storageMutator.getStoredFiles(); // get all the stored files from the storage
|
||||
@ -71,6 +74,14 @@ public class IndexController {
|
||||
List<Boolean> filesEditable = new ArrayList<>();
|
||||
List<String> versions = new ArrayList<>();
|
||||
List<Boolean> isFillFormDoc = new ArrayList<>();
|
||||
List<String> langsAndKeys = Arrays.asList(langs.split("\\|"));
|
||||
|
||||
Map<String, String> languages = new HashMap<>();
|
||||
|
||||
langsAndKeys.forEach((str) -> {
|
||||
String[] couple = str.split(":");
|
||||
languages.put(couple[0], couple[1]);
|
||||
});
|
||||
|
||||
List<User> users = userService.findAll(); // get a list of all the users
|
||||
|
||||
@ -95,6 +106,7 @@ public class IndexController {
|
||||
model.addAttribute("datadocs", docserviceSite+docservicePreloader);
|
||||
model.addAttribute("tooltip", tooltip);
|
||||
model.addAttribute("users", users);
|
||||
model.addAttribute("languages", languages);
|
||||
|
||||
return "index.html";
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ public class EditCallback implements Callback {
|
||||
if (!body.getUsers().contains(user)) { // if this user is not specified in the body
|
||||
String key = body.getKey(); // get document key
|
||||
try {
|
||||
callbackManager.commandRequest("forcesave", key); // create a command request to forcibly save the document being edited without closing it
|
||||
callbackManager.commandRequest("forcesave", key, null); // create a command request to forcibly save the document being edited without closing it
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
result = 1;
|
||||
|
||||
@ -19,9 +19,10 @@
|
||||
package com.onlyoffice.integration.documentserver.managers.callback;
|
||||
|
||||
import com.onlyoffice.integration.dto.Track;
|
||||
import java.util.HashMap;
|
||||
|
||||
public interface CallbackManager { // specify the callback manager functions
|
||||
void processSave(Track body, String fileName); // file saving process
|
||||
void commandRequest(String method, String key); // create a command request
|
||||
void commandRequest(String method, String key, HashMap meta); // create a command request
|
||||
void processForceSave(Track body, String fileName); // file force saving process
|
||||
}
|
||||
|
||||
@ -153,16 +153,20 @@ public class DefaultCallbackManager implements CallbackManager {
|
||||
|
||||
//TODO: Replace (String method) with (Enum method)
|
||||
@SneakyThrows
|
||||
public void commandRequest(String method, String key) { // create a command request
|
||||
public void commandRequest(String method, String key, HashMap meta) { // create a command request
|
||||
String DocumentCommandUrl = docserviceUrlSite + docserviceUrlCommand;
|
||||
|
||||
URL url = new URL(DocumentCommandUrl);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
|
||||
HashMap<String, Object> params = new HashMap<>();
|
||||
HashMap<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("c", method);
|
||||
params.put("key", key);
|
||||
|
||||
if (meta != null) {
|
||||
params.put("meta", meta);
|
||||
}
|
||||
|
||||
String headerToken;
|
||||
if (jwtManager.tokenEnabled()) // check if a secret key to generate token exists or not
|
||||
{
|
||||
|
||||
@ -34,7 +34,6 @@ public class Customization { // the parameters which allow to customize the edi
|
||||
@Autowired
|
||||
private Goback goback; // the settings for the Open file location menu button and upper right corner button
|
||||
private Boolean autosave = true; // if the Autosave menu option is enabled or disabled
|
||||
private Boolean chat = true; // if the Chat menu button is displayed or hidden
|
||||
private Boolean comments = true; // if the Comments menu button is displayed or hidden
|
||||
private Boolean compactHeader = false; // if the additional action buttons are displayed in the upper part of the editor window header next to the logo (false) or in the toolbar (true)
|
||||
private Boolean compactToolbar = false; // if the top toolbar type displayed is full (false) or compact (true)
|
||||
|
||||
@ -49,5 +49,7 @@ public enum Language {
|
||||
es,
|
||||
tr,
|
||||
uk,
|
||||
vi
|
||||
vi,
|
||||
gl,
|
||||
az
|
||||
}
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
package com.onlyoffice.integration.documentserver.util;
|
||||
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
/**
|
||||
* Disables and enables certificate and host-name checking in
|
||||
* HttpsURLConnection, the default JVM implementation of the HTTPS/TLS protocol.
|
||||
* Has no effect on implementations such as Apache Http Client, Ok Http.
|
||||
*/
|
||||
@Component
|
||||
public final class SSLUtils {
|
||||
|
||||
private final HostnameVerifier jvmHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
|
||||
|
||||
private final HostnameVerifier trivialHostnameVerifier = new HostnameVerifier() {
|
||||
public boolean verify(String hostname, SSLSession sslSession) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private final TrustManager[] UNQUESTIONING_TRUST_MANAGER = new TrustManager[] { new X509TrustManager() {
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void checkClientTrusted(X509Certificate[] certs, String authType) {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] certs, String authType) {
|
||||
}
|
||||
} };
|
||||
|
||||
public void turnOffSslChecking() throws NoSuchAlgorithmException, KeyManagementException {
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(trivialHostnameVerifier);
|
||||
// Install the all-trusting trust manager
|
||||
SSLContext sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, UNQUESTIONING_TRUST_MANAGER, null);
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
||||
}
|
||||
|
||||
public void turnOnSslChecking() throws KeyManagementException, NoSuchAlgorithmException {
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(jvmHostnameVerifier);
|
||||
// Return it to the initial state (discovered by reflection, now hardcoded)
|
||||
SSLContext sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, null, null);
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
server.version=1.1.0
|
||||
server.version=1.2.0
|
||||
|
||||
server.address=
|
||||
server.port=4000
|
||||
@ -25,6 +25,10 @@ files.docservice.url.example=
|
||||
files.docservice.secret=
|
||||
files.docservice.header=Authorization
|
||||
|
||||
files.docservice.verify-peer-off=true
|
||||
|
||||
files.docservice.languages=en:English|az:Azerbaijani|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|nb:Norwegian|pl:Polish|pt:Portuguese|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese
|
||||
|
||||
spring.datasource.url=jdbc:h2:mem:usersdb
|
||||
spring.datasource.driverClassName=org.h2.Driver
|
||||
spring.datasource.username=sa
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
<script th:inline="javascript">
|
||||
var docEditor;
|
||||
var config;
|
||||
|
||||
var innerAlert = function (message, inEditor) {
|
||||
if (console && console.log)
|
||||
@ -90,10 +91,13 @@
|
||||
|
||||
// the meta information of the document is changed via the meta command
|
||||
var onMetaChange = function (event) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite);
|
||||
if (event.data.favorite) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite);
|
||||
}
|
||||
innerAlert("onMetaChange: " + JSON.stringify(event.data));
|
||||
};
|
||||
|
||||
|
||||
@ -115,7 +119,7 @@
|
||||
docEditor.setMailMergeRecipients([[${dataMailMergeRecipients}]]);
|
||||
};
|
||||
|
||||
var config = [[${model}]];
|
||||
config = [[${model}]];
|
||||
|
||||
if (config.editorConfig.user.name == "Anonymous") {
|
||||
config.editorConfig.user.name = "";
|
||||
@ -130,7 +134,7 @@
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "saveas");
|
||||
xhr.setRequestHeader( 'Content-Type', 'application/json');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
@ -138,6 +142,23 @@
|
||||
}
|
||||
};
|
||||
|
||||
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
|
||||
innerAlert("onRequestRename: " + JSON.stringify(event.data));
|
||||
|
||||
var newfilename = event.data;
|
||||
var data = {
|
||||
newfilename: newfilename,
|
||||
dockey: config.document.key,
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "rename");
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
}
|
||||
};
|
||||
|
||||
config.width = "100%";
|
||||
config.height = "100%";
|
||||
config.events = {
|
||||
@ -158,24 +179,23 @@
|
||||
var historyData = histArray[1];
|
||||
var usersForMentions = [[${usersForMentions}]];
|
||||
|
||||
if (hist && historyData) {
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(JSON.parse(hist)); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = historyData;
|
||||
docEditor.setHistoryData(JSON.parse(histData)[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
}
|
||||
|
||||
if(usersForMentions){
|
||||
if (config.editorConfig.user.id != 4) {
|
||||
if (hist && historyData) {
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(JSON.parse(hist)); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = historyData;
|
||||
docEditor.setHistoryData(JSON.parse(histData)[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
}
|
||||
// add mentions for not anonymous users
|
||||
config.events['onRequestUsers'] = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
@ -184,10 +204,12 @@
|
||||
};
|
||||
// the user is mentioned in a comment
|
||||
config.events['onRequestSendNotify'] = function (event) {
|
||||
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
|
||||
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
// prevent file renaming for anonymous users
|
||||
config.events['onRequestRename'] = onRequestRename;
|
||||
}
|
||||
|
||||
if (config.editorConfig.createUrl) {
|
||||
|
||||
@ -87,37 +87,9 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<select class="select-user" id="language">
|
||||
<option value="en" selected="selected">English</option>
|
||||
<option value="be">Belarusian</option>
|
||||
<option value="bg">Bulgarian</option>
|
||||
<option value="ca">Catalan</option>
|
||||
<option value="zh">Chinese</option>
|
||||
<option value="cs">Czech</option>
|
||||
<option value="da">Danish</option>
|
||||
<option value="nl">Dutch</option>
|
||||
<option value="fi">Finnish</option>
|
||||
<option value="fr">French</option>
|
||||
<option value="de">German</option>
|
||||
<option value="el">Greek</option>
|
||||
<option value="hu">Hungarian</option>
|
||||
<option value="id">Indonesian</option>
|
||||
<option value="it">Italian</option>
|
||||
<option value="ja">Japanese</option>
|
||||
<option value="ko">Korean</option>
|
||||
<option value="lv">Latvian</option>
|
||||
<option value="lo">Lao</option>
|
||||
<option value="nb">Norwegian</option>
|
||||
<option value="pl">Polish</option>
|
||||
<option value="pt">Portuguese</option>
|
||||
<option value="ro">Romanian</option>
|
||||
<option value="ru">Russian</option>
|
||||
<option value="sk">Slovak</option>
|
||||
<option value="sl">Slovenian</option>
|
||||
<option value="sv">Swedish</option>
|
||||
<option value="es">Spanish</option>
|
||||
<option value="tr">Turkish</option>
|
||||
<option value="uk">Ukrainian</option>
|
||||
<option value="vi">Vietnamese</option>
|
||||
<option th:each="language: ${languages}"
|
||||
th:value="${language.key}"
|
||||
th:text="${language.value}"/>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@ -345,5 +317,10 @@
|
||||
<script type="text/javascript" src="scripts/jquery.dropdownToggle.js"></script>
|
||||
<script type="text/javascript" src="scripts/jscript.js"></script>
|
||||
<script type="text/javascript" src="scripts/converter.js"></script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('DOMContentLoaded', function(){
|
||||
document.getElementById("language").value="en";
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -263,3 +263,12 @@ Make sure that the Document Server has access to the server with the example ins
|
||||
```
|
||||
|
||||
4. After it, all the *bin* files will be passed to the *./target* folder.
|
||||
|
||||
## Important security info
|
||||
|
||||
Please keep in mind the following security aspects when you are using test examples:
|
||||
|
||||
* There is no protection of the storage from unauthorized access since there is no need for authorization.
|
||||
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
|
||||
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
|
||||
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
|
||||
@ -29,6 +29,7 @@ import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import helpers.*;
|
||||
|
||||
public class GlobalServletContextListener implements ServletContextListener
|
||||
{
|
||||
@ -70,16 +71,19 @@ public class GlobalServletContextListener implements ServletContextListener
|
||||
|
||||
SSLContext sc;
|
||||
|
||||
try
|
||||
{
|
||||
// register the all-trusting trust manager for HTTPS
|
||||
sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
||||
}
|
||||
catch (NoSuchAlgorithmException | KeyManagementException ex)
|
||||
{
|
||||
if(!ConfigManager.GetProperty("files.docservice.verify-peer-off").isEmpty()) {
|
||||
try
|
||||
{
|
||||
// register the all-trusting trust manager for HTTPS
|
||||
sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
||||
}
|
||||
catch (NoSuchAlgorithmException | KeyManagementException ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// create all-trusting host name verifier
|
||||
HostnameVerifier allHostsValid = new HostnameVerifier()
|
||||
|
||||
36
web/documentserver-example/java/src/main/java/controllers/IndexServlet.java
Normal file → Executable file
36
web/documentserver-example/java/src/main/java/controllers/IndexServlet.java
Normal file → Executable file
@ -29,6 +29,8 @@ import java.util.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.MultipartConfig;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
@ -36,7 +38,9 @@ import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
import entities.FileType;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
@ -45,6 +49,7 @@ import org.primeframework.jwt.Verifier;
|
||||
import org.primeframework.jwt.domain.JWT;
|
||||
import org.primeframework.jwt.hmac.HMACVerifier;
|
||||
|
||||
|
||||
@WebServlet(name = "IndexServlet", urlPatterns = {"/IndexServlet"})
|
||||
@MultipartConfig
|
||||
public class IndexServlet extends HttpServlet
|
||||
@ -97,6 +102,9 @@ public class IndexServlet extends HttpServlet
|
||||
case "saveas":
|
||||
SaveAs(request, response, writer);
|
||||
break;
|
||||
case "rename":
|
||||
Rename(request, response, writer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,7 +329,7 @@ public class IndexServlet extends HttpServlet
|
||||
if (users.indexOf(user) == -1) {
|
||||
String key = (String) body.get("key");
|
||||
try {
|
||||
TrackManager.commandRequest("forcesave", key); // create a command request with the forcesave method
|
||||
TrackManager.commandRequest("forcesave", key, null); // create a command request with the forcesave method
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -551,6 +559,32 @@ public class IndexServlet extends HttpServlet
|
||||
}
|
||||
}
|
||||
|
||||
// rename a file
|
||||
private static void Rename(HttpServletRequest request, HttpServletResponse response, PrintWriter writer) {
|
||||
try {
|
||||
Scanner scanner = new Scanner(request.getInputStream());
|
||||
scanner.useDelimiter("\\A");
|
||||
String bodyString = scanner.hasNext() ? scanner.next() : "";
|
||||
scanner.close();
|
||||
|
||||
JSONParser parser = new JSONParser();
|
||||
JSONObject body = (JSONObject) parser.parse(bodyString);
|
||||
|
||||
String newfilename = (String) body.get("newfilename");
|
||||
String dockey = (String) body.get("dockey");
|
||||
|
||||
HashMap<String, String> meta = new HashMap<>();
|
||||
meta.put("title", newfilename);
|
||||
|
||||
TrackManager.commandRequest("meta", dockey, meta);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
writer.write("{ \"error\" : 1, \"message\" : \"" + e.getMessage() + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// process get request
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
|
||||
@ -348,14 +348,12 @@ public class FileModel
|
||||
public Boolean forcesave;
|
||||
public Boolean submitForm;
|
||||
public Boolean about;
|
||||
public Boolean chat;
|
||||
public Boolean comments;
|
||||
public Boolean feedback;
|
||||
|
||||
public Customization()
|
||||
{
|
||||
about = true;
|
||||
chat = true;
|
||||
comments = true;
|
||||
feedback = true;
|
||||
forcesave = false;
|
||||
|
||||
15
web/documentserver-example/java/src/main/java/helpers/DocumentManager.java
Normal file → Executable file
15
web/documentserver-example/java/src/main/java/helpers/DocumentManager.java
Normal file → Executable file
@ -568,4 +568,19 @@ public class DocumentManager
|
||||
{
|
||||
return ConfigManager.GetProperty("files.docservice.secret");
|
||||
}
|
||||
|
||||
// get languages
|
||||
public static Map<String, String> GetLanguages()
|
||||
{
|
||||
String langs = ConfigManager.GetProperty("files.docservice.languages");
|
||||
List<String> langsAndKeys = Arrays.asList(langs.split("\\|"));
|
||||
|
||||
Map<String, String> languages = new HashMap<>();
|
||||
|
||||
langsAndKeys.forEach((str) -> {
|
||||
String[] couple = str.split(":");
|
||||
languages.put(couple[0], couple[1]);
|
||||
});
|
||||
return languages;
|
||||
}
|
||||
}
|
||||
8
web/documentserver-example/java/src/main/java/helpers/TrackManager.java
Normal file → Executable file
8
web/documentserver-example/java/src/main/java/helpers/TrackManager.java
Normal file → Executable file
@ -277,7 +277,7 @@ public class TrackManager {
|
||||
}
|
||||
|
||||
// create a command request
|
||||
public static void commandRequest(String method, String key) throws Exception {
|
||||
public static void commandRequest(String method, String key, HashMap meta) throws Exception {
|
||||
String DocumentCommandUrl = ConfigManager.GetProperty("files.docservice.url.site") + ConfigManager.GetProperty("files.docservice.url.command");
|
||||
|
||||
URL url = new URL(DocumentCommandUrl);
|
||||
@ -287,6 +287,10 @@ public class TrackManager {
|
||||
params.put("c", method);
|
||||
params.put("key", key);
|
||||
|
||||
if (meta != null) {
|
||||
params.put("meta", meta);
|
||||
}
|
||||
|
||||
String headerToken = "";
|
||||
if (DocumentManager.TokenEnabled()) // check if a secret key to generate token exists or not
|
||||
{
|
||||
@ -314,7 +318,7 @@ public class TrackManager {
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
os.write(bodyByte); // write bytes to the output stream
|
||||
}
|
||||
InputStream stream = connection.getInputStream();; // get input stream
|
||||
InputStream stream = connection.getInputStream(); // get input stream
|
||||
|
||||
if (stream == null)
|
||||
throw new Exception("Could not get an answer");
|
||||
|
||||
@ -64,6 +64,7 @@ public class Users {
|
||||
add("Can't mention others in comments");
|
||||
add("Can't create new files from the editor");
|
||||
add("Can’t see anyone’s information");
|
||||
add("Can't rename files from the editor");
|
||||
}};
|
||||
|
||||
private static List<User> users = new ArrayList<User>() {{
|
||||
|
||||
Submodule web/documentserver-example/java/src/main/resources/assets updated: af97a54226...1d601d84c4
@ -1,4 +1,4 @@
|
||||
version=1.1.0
|
||||
version=1.2.0
|
||||
|
||||
filesize-max=5242880
|
||||
storage-folder=app_data
|
||||
@ -16,5 +16,9 @@ files.docservice.url.api=web-apps/apps/api/documents/api.js
|
||||
files.docservice.url.preloader=web-apps/apps/api/documents/cache-scripts.html
|
||||
files.docservice.url.example=
|
||||
|
||||
files.docservice.languages=en:English|az:Azerbaijani|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|nb:Norwegian|pl:Polish|pt:Portuguese|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese
|
||||
|
||||
files.docservice.secret=
|
||||
files.docservice.header=Authorization
|
||||
files.docservice.header=Authorization
|
||||
|
||||
files.docservice.verify-peer-off=TRUE
|
||||
@ -36,6 +36,7 @@
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
var docEditor;
|
||||
var config;
|
||||
|
||||
var innerAlert = function (message, inEditor) {
|
||||
if (console && console.log)
|
||||
@ -97,10 +98,14 @@
|
||||
|
||||
// the meta information of the document is changed via the meta command
|
||||
var onMetaChange = function (event) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
if (event.data.favorite) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
}
|
||||
|
||||
innerAlert("onMetaChange: " + JSON.stringify(event.data));
|
||||
};
|
||||
|
||||
// the user is trying to insert an image by clicking the Image from Storage button
|
||||
@ -130,7 +135,7 @@
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "IndexServlet?type=saveas");
|
||||
xhr.setRequestHeader( 'Content-Type', 'application/json');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
@ -138,7 +143,24 @@
|
||||
}
|
||||
};
|
||||
|
||||
var config = JSON.parse('<%= FileModel.Serialize(Model) %>');
|
||||
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
|
||||
innerAlert("onRequestRename: " + JSON.stringify(event.data));
|
||||
|
||||
var newfilename = event.data;
|
||||
var data = {
|
||||
newfilename: newfilename,
|
||||
dockey: config.document.key,
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "IndexServlet?type=rename");
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
}
|
||||
};
|
||||
|
||||
config = JSON.parse('<%= FileModel.Serialize(Model) %>');
|
||||
config.width = "100%";
|
||||
config.height = "100%";
|
||||
config.events = {
|
||||
@ -161,37 +183,38 @@
|
||||
String usersForMentions = (String) request.getAttribute("usersForMentions");
|
||||
%>
|
||||
|
||||
<% if (!history.isEmpty() && !historyData.isEmpty()) { %>
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(<%= history %>); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = <%= historyData %>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
<% } %>
|
||||
|
||||
<% if (usersForMentions != null) { %>
|
||||
if (config.editorConfig.user.id) {
|
||||
<% if (!history.isEmpty() && !historyData.isEmpty()) { %>
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(<%= history %>); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = <%= historyData %>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
<% } %>
|
||||
// add mentions for not anonymous users
|
||||
config.events['onRequestUsers'] = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
"users": ${usersForMentions}
|
||||
"users": <%=usersForMentions%>
|
||||
});
|
||||
};
|
||||
// the user is mentioned in a comment
|
||||
config.events['onRequestSendNotify'] = function (event) {
|
||||
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
|
||||
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
<% } %>
|
||||
// prevent file renaming for anonymous users
|
||||
config.events['onRequestRename'] = onRequestRename;
|
||||
}
|
||||
|
||||
if (config.editorConfig.createUrl) {
|
||||
config.events.onRequestSaveAs = onRequestSaveAs;
|
||||
|
||||
42
web/documentserver-example/java/src/main/webapp/index.jsp
Normal file → Executable file
42
web/documentserver-example/java/src/main/webapp/index.jsp
Normal file → Executable file
@ -4,6 +4,8 @@
|
||||
<%@page import="java.util.Calendar"%>
|
||||
<%@page import="java.io.File"%>
|
||||
<%@page import="java.net.URLEncoder"%>
|
||||
<%@page import="java.util.Map.Entry"%>
|
||||
<%@page import="java.util.Map"%>
|
||||
<%@page import="helpers.Users"%>
|
||||
<%@page import="entities.User"%>
|
||||
|
||||
@ -97,37 +99,10 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<select class="select-user" id="language">
|
||||
<option value="en">English</option>
|
||||
<option value="be">Belarusian</option>
|
||||
<option value="bg">Bulgarian</option>
|
||||
<option value="ca">Catalan</option>
|
||||
<option value="zh">Chinese</option>
|
||||
<option value="cs">Czech</option>
|
||||
<option value="da">Danish</option>
|
||||
<option value="nl">Dutch</option>
|
||||
<option value="fi">Finnish</option>
|
||||
<option value="fr">French</option>
|
||||
<option value="de">German</option>
|
||||
<option value="el">Greek</option>
|
||||
<option value="hu">Hungarian</option>
|
||||
<option value="id">Indonesian</option>
|
||||
<option value="it">Italian</option>
|
||||
<option value="ja">Japanese</option>
|
||||
<option value="ko">Korean</option>
|
||||
<option value="lv">Latvian</option>
|
||||
<option value="lo">Lao</option>
|
||||
<option value="nb">Norwegian</option>
|
||||
<option value="pl">Polish</option>
|
||||
<option value="pt">Portuguese</option>
|
||||
<option value="ro">Romanian</option>
|
||||
<option value="ru">Russian</option>
|
||||
<option value="sk">Slovak</option>
|
||||
<option value="sl">Slovenian</option>
|
||||
<option value="sv">Swedish</option>
|
||||
<option value="es">Spanish</option>
|
||||
<option value="tr">Turkish</option>
|
||||
<option value="uk">Ukrainian</option>
|
||||
<option value="vi">Vietnamese</option>
|
||||
<% Map<String, String> languages = DocumentManager.GetLanguages(); %>
|
||||
<% for (Map.Entry<String, String> language : languages.entrySet()) { %>
|
||||
<option value="<%=language.getKey()%>"><%=language.getValue()%></option>
|
||||
<% } %>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@ -373,7 +348,10 @@
|
||||
var EditedExtList = "<%= String.join(",", DocumentManager.GetEditedExts()) %>";
|
||||
var UrlConverter = "IndexServlet?type=convert";
|
||||
var UrlEditor = "EditorServlet";
|
||||
</script>
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function(){
|
||||
document.getElementById("language").value="en";
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
FROM node:buster
|
||||
LABEL maintainer Ascensio System SIA <support@onlyoffice.com>
|
||||
|
||||
ENV LANG=en_US.UTF-8 \
|
||||
LANGUAGE=en_US:en \
|
||||
LC_ALL=en_US.UTF-8 \
|
||||
NODE_ENV=production-linux \
|
||||
NODE_CONFIG_DIR=/etc/onlyoffice/documentserver-example/
|
||||
|
||||
WORKDIR /var/www/onlyoffice/documentserver-example/
|
||||
COPY . /var/www/onlyoffice/documentserver-example/
|
||||
|
||||
RUN groupadd --system --gid 1001 ds && \
|
||||
useradd --system -g ds --no-create-home --shell /sbin/nologin --uid 1001 ds && \
|
||||
chown -R ds:ds /var/www/onlyoffice/documentserver-example/ && \
|
||||
mkdir -p /var/lib/onlyoffice/documentserver-example/ && \
|
||||
chown -R ds:ds /var/lib/onlyoffice/ && \
|
||||
mv files /var/lib/onlyoffice/documentserver-example/ && \
|
||||
mkdir -p /etc/onlyoffice/documentserver-example/ && \
|
||||
chown -R ds:ds /etc/onlyoffice/ && \
|
||||
mv config/* /etc/onlyoffice/documentserver-example/ && \
|
||||
npm install
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
USER ds
|
||||
|
||||
ENTRYPOINT /var/www/onlyoffice/documentserver-example/docker-entrypoint.sh npm start
|
||||
@ -146,3 +146,12 @@ See the detailed guide to learn how to [install Document Server for Linux](https
|
||||
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
|
||||
|
||||
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
|
||||
|
||||
## Important security info
|
||||
|
||||
Please keep in mind the following security aspects when you are using test examples:
|
||||
|
||||
* There is no protection of the storage from unauthorized access since there is no need for authorization.
|
||||
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
|
||||
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
|
||||
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
|
||||
23
web/documentserver-example/nodejs/app.js
Normal file → Executable file
23
web/documentserver-example/nodejs/app.js
Normal file → Executable file
@ -44,9 +44,11 @@ const cfgSignatureAuthorizationHeaderPrefix = configServer.get('token.authorizat
|
||||
const cfgSignatureSecretExpiresIn = configServer.get('token.expiresIn');
|
||||
const cfgSignatureSecret = configServer.get('token.secret');
|
||||
const urllib = require("urllib");
|
||||
const verifyPeerOff = configServer.get('verify_peer_off');
|
||||
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
||||
|
||||
if(verifyPeerOff) {
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
||||
}
|
||||
|
||||
String.prototype.hashCode = function () {
|
||||
const len = this.length;
|
||||
@ -70,6 +72,7 @@ String.prototype.format = function () {
|
||||
|
||||
|
||||
const app = express(); // create an application object
|
||||
app.disable("x-powered-by");
|
||||
app.set("views", path.join(__dirname, "views")); // specify the path to the main template
|
||||
app.set("view engine", "ejs"); // specify which template engine is used
|
||||
|
||||
@ -108,6 +111,7 @@ app.get("/", function (req, res) { // define a handler for default page
|
||||
params: req.docManager.getCustomParams(),
|
||||
users: users,
|
||||
serverUrl: req.docManager.getServerUrl(),
|
||||
languages: configServer.get('languages'),
|
||||
});
|
||||
|
||||
}
|
||||
@ -969,6 +973,21 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/rename", function (req, res) { //define a handler for renaming file
|
||||
|
||||
var newfilename = req.body.newfilename;
|
||||
var dockey = req.body.dockey;
|
||||
var meta = {title: newfilename};
|
||||
|
||||
var result = function(err, data, ress) {
|
||||
res.writeHead(200, {"Content-Type": "application/json" });
|
||||
res.write(JSON.stringify({ "result": ress }));
|
||||
res.end();
|
||||
};
|
||||
|
||||
documentService.commandRequest("meta", dockey, meta, result);
|
||||
});
|
||||
|
||||
wopiApp.registerRoutes(app);
|
||||
|
||||
// "Not found" error with 404 status
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"log": {
|
||||
"appenders": [
|
||||
{
|
||||
@ -44,6 +44,42 @@
|
||||
"authorizationHeaderPrefix": "Bearer ",
|
||||
"secret": "secret",
|
||||
"expiresIn": "5m"
|
||||
},
|
||||
"verify_peer_off": true,
|
||||
"languages": {
|
||||
"en": "English",
|
||||
"az": "Azerbaijani",
|
||||
"be": "Belarusian",
|
||||
"bg": "Bulgarian",
|
||||
"ca": "Catalan",
|
||||
"zh": "Chinese",
|
||||
"cs": "Czech",
|
||||
"da": "Danish",
|
||||
"nl": "Dutch",
|
||||
"fi": "Finnish",
|
||||
"fr": "French",
|
||||
"gl": "Galego",
|
||||
"de": "German",
|
||||
"el": "Greek",
|
||||
"hu": "Hungarian",
|
||||
"id": "Indonesian",
|
||||
"it": "Italian",
|
||||
"ja": "Japanese",
|
||||
"ko": "Korean",
|
||||
"lv": "Latvian",
|
||||
"lo": "Lao",
|
||||
"nb": "Norwegian",
|
||||
"pl": "Polish",
|
||||
"pt": "Portuguese",
|
||||
"ro": "Romanian",
|
||||
"ru": "Russian",
|
||||
"sk": "Slovak",
|
||||
"sl": "Slovenian",
|
||||
"es": "Spanish",
|
||||
"sv": "Swedish",
|
||||
"tr": "Turkish",
|
||||
"uk": "Ukrainian",
|
||||
"vi": "Vietnamese"
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
|
||||
@ -385,8 +385,8 @@ docManager.prototype.getTemplateImageUrl = function (fileType) {
|
||||
}
|
||||
|
||||
// get document key
|
||||
docManager.prototype.getKey = function (fileName) {
|
||||
const userAddress = this.curUserHostAddress();
|
||||
docManager.prototype.getKey = function (fileName, userAddress) {
|
||||
userAddress = userAddress || this.curUserHostAddress();
|
||||
let key = userAddress + this.getlocalFileUri(fileName); // get document key by adding local file url to the current user host address
|
||||
|
||||
let historyPath = this.historyPath(fileName, userAddress); // get the path to the file history
|
||||
|
||||
9
web/documentserver-example/nodejs/helpers/documentService.js
Normal file → Executable file
9
web/documentserver-example/nodejs/helpers/documentService.js
Normal file → Executable file
@ -168,13 +168,18 @@ documentService.getResponseUri = function (json) {
|
||||
};
|
||||
|
||||
// create a command request
|
||||
documentService.commandRequest = function (method, documentRevisionId, callback) {
|
||||
documentService.commandRequest = function (method, documentRevisionId, meta = null, callback) {
|
||||
|
||||
documentRevisionId = documentService.generateRevisionId(documentRevisionId); // generate the document key value
|
||||
var params = { // create a parameter object with command method and the document key value in it
|
||||
params = { // create a parameter object with command method and the document key value in it
|
||||
c: method,
|
||||
key: documentRevisionId
|
||||
};
|
||||
|
||||
if (meta) {
|
||||
params.meta = meta;
|
||||
}
|
||||
|
||||
var uri = siteUrl + configServer.get('commandUrl'); // get the absolute command url
|
||||
var headers = { // create a headers object
|
||||
'Content-Type': 'application/json'
|
||||
|
||||
@ -22,7 +22,9 @@ var fileUtility = {};
|
||||
fileUtility.getFileName = function (url, withoutExtension) {
|
||||
if (!url) return "";
|
||||
|
||||
var parts = url.split("/");
|
||||
var parts = url.split("\\");
|
||||
parts = parts.pop();
|
||||
parts = parts.split("/");
|
||||
var fileName = parts.pop(); // get the file name from the last part of the url
|
||||
fileName = fileName.split("?")[0];
|
||||
|
||||
|
||||
@ -59,6 +59,7 @@ var descr_user_0 = [
|
||||
"Can't mention others in comments",
|
||||
"Can't create new files from the editor",
|
||||
"Can’t see anyone’s information",
|
||||
"Can't rename files from the editor",
|
||||
//"Can’t submit forms"
|
||||
];
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@ const fileSystem = require("fs");
|
||||
const mime = require("mime");
|
||||
const path = require("path");
|
||||
const users = require("../users");
|
||||
const docManager = require("../docManager");
|
||||
|
||||
const actionMapping = {};
|
||||
actionMapping[reqConsts.requestType.GetFile] = getFile;
|
||||
@ -255,8 +256,8 @@ function putFile(wopi, req, res, userHost) {
|
||||
// return information about the file properties, access rights and editor settings
|
||||
function checkFileInfo(wopi, req, res, userHost) {
|
||||
let userAddress = req.docManager.curUserHostAddress(userHost);
|
||||
let version = req.docManager.getKey(wopi.id);
|
||||
|
||||
let version = req.docManager.getKey(wopi.id, userAddress);
|
||||
|
||||
let path = req.docManager.storagePath(wopi.id, userAddress);
|
||||
// add wopi query
|
||||
var query = new URLSearchParams(wopi.accessToken);
|
||||
@ -289,6 +290,7 @@ function returnLockMismatch(res, lock, reason) {
|
||||
|
||||
exports.fileRequestHandler = (req, res) => {
|
||||
let userAddress = null;
|
||||
req.docManager = new docManager(req, res);
|
||||
if (req.params['id'].includes("@")) { // if there is the "@" sign in the id parameter
|
||||
let split = req.params['id'].split("@"); // split this parameter by "@"
|
||||
req.params['id'] = split[0]; // rewrite id with the first part of the split parameter
|
||||
@ -310,5 +312,5 @@ exports.fileRequestHandler = (req, res) => {
|
||||
return;
|
||||
}
|
||||
|
||||
action(wopiData, req, res);
|
||||
action(wopiData, req, res, userAddress);
|
||||
}
|
||||
1
web/documentserver-example/nodejs/helpers/wopi/wopiRouting.js
Normal file → Executable file
1
web/documentserver-example/nodejs/helpers/wopi/wopiRouting.js
Normal file → Executable file
@ -83,6 +83,7 @@ exports.registerRoutes = function(app) {
|
||||
convertExts: configServer.get('convertedDocs'),
|
||||
editedExts: editedExts,
|
||||
fillExts: fillExts,
|
||||
languages: configServer.get('languages'),
|
||||
});
|
||||
|
||||
} catch (ex) {
|
||||
|
||||
Submodule web/documentserver-example/nodejs/public/assets updated: af97a54226...1d601d84c4
1
web/documentserver-example/nodejs/views/config.ejs
Normal file → Executable file
1
web/documentserver-example/nodejs/views/config.ejs
Normal file → Executable file
@ -48,7 +48,6 @@
|
||||
},
|
||||
"customization": {
|
||||
"about": true,
|
||||
"chat": true,
|
||||
"comments": true,
|
||||
"feedback": true,
|
||||
"forcesave": false,
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
var docEditor;
|
||||
var config;
|
||||
|
||||
var innerAlert = function (message, inEditor) {
|
||||
if (console && console.log)
|
||||
@ -56,10 +57,14 @@
|
||||
};
|
||||
|
||||
var onMetaChange = function (event) { // the meta information of the document is changed via the meta command
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
if (event.data.favorite) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
}
|
||||
|
||||
innerAlert("onMetaChange: " + JSON.stringify(event.data));
|
||||
};
|
||||
|
||||
var onRequestEditRights = function () { // the user is trying to switch the document from the viewing into the editing mode
|
||||
@ -141,7 +146,7 @@
|
||||
};
|
||||
|
||||
var onRequestSendNotify = function(event) { // the user is mentioned in a comment
|
||||
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
|
||||
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
@ -155,7 +160,7 @@
|
||||
}
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "create");
|
||||
xhr.setRequestHeader( 'Content-Type', 'application/json');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
@ -163,15 +168,29 @@
|
||||
}
|
||||
}
|
||||
|
||||
var config = {<%- include("config") %>,
|
||||
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
|
||||
innerAlert("onRequestRename: " + JSON.stringify(event.data));
|
||||
|
||||
var newfilename = event.data;
|
||||
var data = {
|
||||
newfilename: newfilename,
|
||||
dockey: config.document.key,
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "rename");
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
}
|
||||
};
|
||||
|
||||
config = {<%- include("config") %>,
|
||||
events: {
|
||||
"onAppReady": onAppReady,
|
||||
"onDocumentStateChange": onDocumentStateChange,
|
||||
"onRequestEditRights": onRequestEditRights,
|
||||
"onError": onError,
|
||||
"onRequestHistory": onRequestHistory,
|
||||
"onRequestHistoryData": onRequestHistoryData,
|
||||
"onRequestHistoryClose": onRequestHistoryClose,
|
||||
"onOutdatedVersion": onOutdatedVersion,
|
||||
"onMakeActionLink": onMakeActionLink,
|
||||
"onMetaChange": onMetaChange,
|
||||
@ -181,7 +200,11 @@
|
||||
}
|
||||
};
|
||||
|
||||
if (<%- JSON.stringify(usersForMentions) %> != null) {
|
||||
if (<%- JSON.stringify(editor.userid) %> != null) {
|
||||
config.events.onRequestHistory = onRequestHistory;
|
||||
config.events.onRequestHistoryData = onRequestHistoryData;
|
||||
config.events.onRequestHistoryClose = onRequestHistoryClose;
|
||||
config.events.onRequestRename = onRequestRename;
|
||||
config.events.onRequestUsers = onRequestUsers;
|
||||
config.events.onRequestSendNotify = onRequestSendNotify;
|
||||
}
|
||||
|
||||
34
web/documentserver-example/nodejs/views/index.ejs
Normal file → Executable file
34
web/documentserver-example/nodejs/views/index.ejs
Normal file → Executable file
@ -88,37 +88,9 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<select class="select-user" id="language">
|
||||
<option value="en">English</option>
|
||||
<option value="be">Belarusian</option>
|
||||
<option value="bg">Bulgarian</option>
|
||||
<option value="ca">Catalan</option>
|
||||
<option value="zh">Chinese</option>
|
||||
<option value="cs">Czech</option>
|
||||
<option value="da">Danish</option>
|
||||
<option value="nl">Dutch</option>
|
||||
<option value="fi">Finnish</option>
|
||||
<option value="fr">French</option>
|
||||
<option value="de">German</option>
|
||||
<option value="el">Greek</option>
|
||||
<option value="hu">Hungarian</option>
|
||||
<option value="id">Indonesian</option>
|
||||
<option value="it">Italian</option>
|
||||
<option value="ja">Japanese</option>
|
||||
<option value="ko">Korean</option>
|
||||
<option value="lv">Latvian</option>
|
||||
<option value="lo">Lao</option>
|
||||
<option value="nb">Norwegian</option>
|
||||
<option value="pl">Polish</option>
|
||||
<option value="pt">Portuguese</option>
|
||||
<option value="ro">Romanian</option>
|
||||
<option value="ru">Russian</option>
|
||||
<option value="sk">Slovak</option>
|
||||
<option value="sl">Slovenian</option>
|
||||
<option value="sv">Swedish</option>
|
||||
<option value="es">Spanish</option>
|
||||
<option value="tr">Turkish</option>
|
||||
<option value="uk">Ukrainian</option>
|
||||
<option value="vi">Vietnamese</option>
|
||||
<% Object.keys(languages).forEach(key => { %>
|
||||
<option value="<%= key %>"><%= languages[key] %></option>
|
||||
<% }) %>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
34
web/documentserver-example/nodejs/views/wopiIndex.ejs
Normal file → Executable file
34
web/documentserver-example/nodejs/views/wopiIndex.ejs
Normal file → Executable file
@ -89,37 +89,9 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<select class="select-user" id="language">
|
||||
<option value="en">English</option>
|
||||
<option value="be">Belarusian</option>
|
||||
<option value="bg">Bulgarian</option>
|
||||
<option value="ca">Catalan</option>
|
||||
<option value="zh">Chinese</option>
|
||||
<option value="cs">Czech</option>
|
||||
<option value="da">Danish</option>
|
||||
<option value="nl">Dutch</option>
|
||||
<option value="fi">Finnish</option>
|
||||
<option value="fr">French</option>
|
||||
<option value="de">German</option>
|
||||
<option value="el">Greek</option>
|
||||
<option value="hu">Hungarian</option>
|
||||
<option value="id">Indonesian</option>
|
||||
<option value="it">Italian</option>
|
||||
<option value="ja">Japanese</option>
|
||||
<option value="ko">Korean</option>
|
||||
<option value="lv">Latvian</option>
|
||||
<option value="lo">Lao</option>
|
||||
<option value="nb">Norwegian</option>
|
||||
<option value="pl">Polish</option>
|
||||
<option value="pt">Portuguese</option>
|
||||
<option value="ro">Romanian</option>
|
||||
<option value="ru">Russian</option>
|
||||
<option value="sk">Slovak</option>
|
||||
<option value="sl">Slovenian</option>
|
||||
<option value="sv">Swedish</option>
|
||||
<option value="es">Spanish</option>
|
||||
<option value="tr">Turkish</option>
|
||||
<option value="uk">Ukrainian</option>
|
||||
<option value="vi">Vietnamese</option>
|
||||
<% Object.keys(languages).forEach(key => { %>
|
||||
<option value="<%= key %>"><%= languages[key] %></option>
|
||||
<% }) %>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -180,3 +180,12 @@ See the detailed guide to learn how to [install Document Server for Linux](https
|
||||
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
|
||||
|
||||
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
|
||||
|
||||
## Important security info
|
||||
|
||||
Please keep in mind the following security aspects when you are using test examples:
|
||||
|
||||
* There is no protection of the storage from unauthorized access since there is no need for authorization.
|
||||
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
|
||||
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
|
||||
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
|
||||
Submodule web/documentserver-example/php/assets updated: af97a54226...1d601d84c4
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
$GLOBALS['version'] = "1.1.0";
|
||||
$GLOBALS['version'] = "1.2.0";
|
||||
|
||||
$GLOBALS['FILE_SIZE_MAX'] = 5242880;
|
||||
$GLOBALS['STORAGE_PATH'] = "";
|
||||
@ -24,6 +24,8 @@ $GLOBALS['DOC_SERV_COMMAND_URL'] = "coauthoring/CommandService.ashx";
|
||||
$GLOBALS['DOC_SERV_JWT_SECRET'] = "";
|
||||
$GLOBALS['DOC_SERV_JWT_HEADER'] = "Authorization";
|
||||
|
||||
$GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] = TRUE;
|
||||
|
||||
$GLOBALS['EXAMPLE_URL'] = "";
|
||||
|
||||
$GLOBALS['MOBILE_REGEX'] = "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";
|
||||
@ -44,5 +46,39 @@ $GLOBALS['ExtsDocument'] = array(".doc", ".docx", ".docm",
|
||||
".html", ".htm", ".mht", ".xml",
|
||||
".pdf", ".djvu", ".fb2", ".epub", ".xps", ".oxps", ".oform");
|
||||
|
||||
|
||||
$GLOBALS['LANGUAGES'] = array(
|
||||
'en' => 'English',
|
||||
'az' => 'Azerbaijani',
|
||||
'be' => 'Belarusian',
|
||||
'bg' => 'Bulgarian',
|
||||
'ca' => 'Catalan',
|
||||
'zh' => 'Chinese',
|
||||
'cs' => 'Czech',
|
||||
'da' => 'Danish',
|
||||
'nl' => 'Dutch',
|
||||
'fi' => 'Finnish',
|
||||
'fr' => 'French',
|
||||
'gl' => 'Galego',
|
||||
'de' => 'German',
|
||||
'el' => 'Greek',
|
||||
'hu' => 'Hungarian',
|
||||
'id' => 'Indonesian',
|
||||
'it' => 'Italian',
|
||||
'ja' => 'Japanese',
|
||||
'ko' => 'Korean',
|
||||
'lv' => 'Latvian',
|
||||
'lo' => 'Lao',
|
||||
'nb' => 'Norwegian',
|
||||
'pl' => 'Polish',
|
||||
'pt' => 'Portuguese',
|
||||
'ro' => 'Romanian',
|
||||
'ru' => 'Russian',
|
||||
'sk' => 'Slovak',
|
||||
'sl' => 'Slovenian',
|
||||
'es' => 'Spanish',
|
||||
'sv' => 'Swedish',
|
||||
'tr' => 'Turkish',
|
||||
'uk' => 'Ukrainian',
|
||||
'vi' => 'Vietnamese'
|
||||
);
|
||||
?>
|
||||
@ -131,6 +131,7 @@
|
||||
],
|
||||
"customization" => [ // the parameters for the editor interface
|
||||
"about" => true, // the About section display
|
||||
"comments" => true,
|
||||
"feedback" => true, // the Feedback & Support menu button display
|
||||
"forcesave" => false, // adds the request for the forced file saving to the callback handler when saving the document
|
||||
"submitForm" => $submitForm, // if the Submit form button is displayed or not
|
||||
@ -359,6 +360,7 @@
|
||||
<script type="text/javascript">
|
||||
|
||||
var docEditor;
|
||||
var config;
|
||||
|
||||
var innerAlert = function (message, inEditor) {
|
||||
if (console && console.log)
|
||||
@ -420,10 +422,14 @@
|
||||
|
||||
// the meta information of the document is changed via the meta command
|
||||
var onMetaChange = function (event) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
if (event.data.favorite) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
}
|
||||
|
||||
innerAlert("onMetaChange: " + JSON.stringify(event.data));
|
||||
};
|
||||
|
||||
// the user is trying to insert an image by clicking the Image from Storage button
|
||||
@ -453,7 +459,7 @@
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "webeditor-ajax.php?type=saveas");
|
||||
xhr.setRequestHeader( 'Content-Type', 'application/json');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
@ -461,6 +467,24 @@
|
||||
}
|
||||
};
|
||||
|
||||
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
|
||||
innerAlert("onRequestRename: " + JSON.stringify(event.data));
|
||||
|
||||
var newfilename = event.data;
|
||||
var data = {
|
||||
newfilename: newfilename,
|
||||
dockey: config.document.key,
|
||||
};
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "webeditor-ajax.php?type=rename");
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
}
|
||||
};
|
||||
|
||||
var сonnectEditor = function () {
|
||||
|
||||
<?php
|
||||
@ -469,7 +493,7 @@
|
||||
}
|
||||
?>
|
||||
|
||||
var config = <?php echo json_encode($config) ?>;
|
||||
config = <?php echo json_encode($config) ?>;
|
||||
|
||||
config.width = "100%";
|
||||
config.height = "100%";
|
||||
@ -492,36 +516,38 @@
|
||||
$history = $out[0];
|
||||
$historyData = $out[1];
|
||||
?>
|
||||
<?php if ($history != null && $historyData != null): ?>
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(<?php echo json_encode($history) ?>); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = <?php echo json_encode($historyData) ?>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($usersForMentions != null): ?>
|
||||
// add mentions for not anonymous users
|
||||
config.events['onRequestUsers'] = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
"users": <?php echo json_encode($usersForMentions) ?>
|
||||
});
|
||||
};
|
||||
// the user is mentioned in a comment
|
||||
config.events['onRequestSendNotify'] = function (event) {
|
||||
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
<?php if ($user->id != "uid-0"): ?>
|
||||
<?php if ($history != null && $historyData != null): ?>
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(<?php echo json_encode($history) ?>); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = <?php echo json_encode($historyData) ?>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
<?php endif; ?>
|
||||
// add mentions for not anonymous users
|
||||
config.events['onRequestUsers'] = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
"users": <?php echo json_encode($usersForMentions) ?>
|
||||
});
|
||||
};
|
||||
// the user is mentioned in a comment
|
||||
config.events['onRequestSendNotify'] = function (event) {
|
||||
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
// prevent file renaming for anonymous users
|
||||
config.events['onRequestRename'] = onRequestRename;
|
||||
<?php endif; ?>
|
||||
|
||||
if (config.editorConfig.createUrl) {
|
||||
|
||||
@ -175,7 +175,9 @@ function SendRequestToConvertService($document_uri, $from_extension, $to_extensi
|
||||
);
|
||||
|
||||
if (substr($urlToConverter, 0, strlen("https")) === "https") {
|
||||
$opts['ssl'] = array( 'verify_peer' => FALSE );
|
||||
if($GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] === TRUE) {
|
||||
$opts['ssl'] = array( 'verify_peer' => FALSE, 'verify_peer_name' => FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
|
||||
@ -100,37 +100,9 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<select class="select-user" id="language">
|
||||
<option value="en">English</option>
|
||||
<option value="be">Belarusian</option>
|
||||
<option value="bg">Bulgarian</option>
|
||||
<option value="ca">Catalan</option>
|
||||
<option value="zh">Chinese</option>
|
||||
<option value="cs">Czech</option>
|
||||
<option value="da">Danish</option>
|
||||
<option value="nl">Dutch</option>
|
||||
<option value="fi">Finnish</option>
|
||||
<option value="fr">French</option>
|
||||
<option value="de">German</option>
|
||||
<option value="el">Greek</option>
|
||||
<option value="hu">Hungarian</option>
|
||||
<option value="id">Indonesian</option>
|
||||
<option value="it">Italian</option>
|
||||
<option value="ja">Japanese</option>
|
||||
<option value="ko">Korean</option>
|
||||
<option value="lv">Latvian</option>
|
||||
<option value="lo">Lao</option>
|
||||
<option value="nb">Norwegian</option>
|
||||
<option value="pl">Polish</option>
|
||||
<option value="pt">Portuguese</option>
|
||||
<option value="ro">Romanian</option>
|
||||
<option value="ru">Russian</option>
|
||||
<option value="sk">Slovak</option>
|
||||
<option value="sl">Slovenian</option>
|
||||
<option value="sv">Swedish</option>
|
||||
<option value="es">Spanish</option>
|
||||
<option value="tr">Turkish</option>
|
||||
<option value="uk">Ukrainian</option>
|
||||
<option value="vi">Vietnamese</option>
|
||||
<?php foreach ($GLOBALS['LANGUAGES'] as $key => $language) { ?>
|
||||
<option value="<?=$key?>"><?=$language?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
9
web/documentserver-example/php/trackmanager.php
Normal file → Executable file
9
web/documentserver-example/php/trackmanager.php
Normal file → Executable file
@ -226,7 +226,7 @@ function processForceSave($data, $fileName, $userAddress) {
|
||||
}
|
||||
|
||||
// create a command request
|
||||
function commandRequest($method, $key){
|
||||
function commandRequest($method, $key, $meta = null){
|
||||
$documentCommandUrl = $GLOBALS['DOC_SERV_SITE_URL'].$GLOBALS['DOC_SERV_COMMAND_URL'];
|
||||
|
||||
$arr = [
|
||||
@ -234,6 +234,9 @@ function commandRequest($method, $key){
|
||||
"key" => $key
|
||||
];
|
||||
|
||||
if($meta)
|
||||
$arr["meta"] = $meta;
|
||||
|
||||
$headerToken = "";
|
||||
$jwtHeader = $GLOBALS['DOC_SERV_JWT_HEADER'] == "" ? "Authorization" : $GLOBALS['DOC_SERV_JWT_HEADER'];
|
||||
|
||||
@ -252,7 +255,9 @@ function commandRequest($method, $key){
|
||||
));
|
||||
|
||||
if (substr($documentCommandUrl, 0, strlen("https")) === "https") {
|
||||
$opts['ssl'] = array( 'verify_peer' => FALSE );
|
||||
if($GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] === TRUE) {
|
||||
$opts['ssl'] = array( 'verify_peer' => FALSE, 'verify_peer_name' => FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
|
||||
@ -73,7 +73,8 @@ $descr_user_0 = [
|
||||
"The file favorite state is undefined",
|
||||
"Can't mention others in comments",
|
||||
"Can't create new files from the editor",
|
||||
"Can’t see anyone’s information"
|
||||
"Can’t see anyone’s information",
|
||||
"Can't rename files from the editor"
|
||||
];
|
||||
|
||||
$users = [
|
||||
|
||||
26
web/documentserver-example/php/webeditor-ajax.php
Normal file → Executable file
26
web/documentserver-example/php/webeditor-ajax.php
Normal file → Executable file
@ -39,6 +39,16 @@ $_trackerStatus = array(
|
||||
7 => 'CorruptedForceSave'
|
||||
);
|
||||
|
||||
// ignore self-signed certificate
|
||||
if($GLOBALS['DOC_SERV_VERIFY_PEER_OFF'] === 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"])) {
|
||||
$response_array;
|
||||
@ -95,6 +105,9 @@ if (isset($_GET["type"]) && !empty($_GET["type"])) {
|
||||
$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';
|
||||
@ -452,4 +465,17 @@ function delTree($dir) {
|
||||
return rmdir($dir);
|
||||
}
|
||||
|
||||
// rename...
|
||||
function renamefile() {
|
||||
$post = json_decode(file_get_contents('php://input'), true);
|
||||
$newfilename = $post["newfilename"];
|
||||
$dockey = $post["dockey"];
|
||||
$meta = ["title" => $newfilename];
|
||||
|
||||
$commandRequest = commandRequest("meta", $dockey, $meta); // create a command request with the forcasave method
|
||||
sendlog(" CommandRequest rename: " . serialize($commandRequest), "webedior-ajax.log");
|
||||
|
||||
return array("result" => $commandRequest);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
Submodule web/documentserver-example/python/assets updated: af97a54226...1d601d84c4
@ -1,6 +1,6 @@
|
||||
import os
|
||||
|
||||
VERSION = '1.1.0'
|
||||
VERSION = '1.2.0'
|
||||
|
||||
FILE_SIZE_MAX = 5242880
|
||||
STORAGE_PATH = 'app_data'
|
||||
@ -30,6 +30,8 @@ EXAMPLE_DOMAIN = None
|
||||
DOC_SERV_JWT_SECRET = '' # the secret key for generating token
|
||||
DOC_SERV_JWT_HEADER = 'Authorization'
|
||||
|
||||
DOC_SERV_VERIFY_PEER = False
|
||||
|
||||
EXT_SPREADSHEET = [
|
||||
".xls", ".xlsx", ".xlsm", ".xlsb",
|
||||
".xlt", ".xltx", ".xltm",
|
||||
@ -51,6 +53,42 @@ EXT_DOCUMENT = [
|
||||
".pdf", ".djvu", ".fb2", ".epub", ".xps", ".oxps", ".oform"
|
||||
]
|
||||
|
||||
LANGUAGES = {
|
||||
'en': 'English',
|
||||
'az': 'Azerbaijani',
|
||||
'be': 'Belarusian',
|
||||
'bg': 'Bulgarian',
|
||||
'ca': 'Catalan',
|
||||
'zh': 'Chinese',
|
||||
'cs': 'Czech',
|
||||
'da': 'Danish',
|
||||
'nl': 'Dutch',
|
||||
'fi': 'Finnish',
|
||||
'fr': 'French',
|
||||
'gl': 'Galego',
|
||||
'de': 'German',
|
||||
'el': 'Greek',
|
||||
'hu': 'Hungarian',
|
||||
'id': 'Indonesian',
|
||||
'it': 'Italian',
|
||||
'ja': 'Japanese',
|
||||
'ko': 'Korean',
|
||||
'lv': 'Latvian',
|
||||
'lo': 'Lao',
|
||||
'nb': 'Norwegian',
|
||||
'pl': 'Polish',
|
||||
'pt': 'Portuguese',
|
||||
'ro': 'Romanian',
|
||||
'ru': 'Russian',
|
||||
'sk': 'Slovak',
|
||||
'sl': 'Slovenian',
|
||||
'es': 'Spanish',
|
||||
'sv': 'Swedish',
|
||||
'tr': 'Turkish',
|
||||
'uk': 'Ukrainian',
|
||||
'vi': 'Vietnamese'
|
||||
}
|
||||
|
||||
if os.environ.get("EXAMPLE_DOMAIN"): # generates a link for example domain
|
||||
EXAMPLE_DOMAIN = os.environ.get("EXAMPLE_DOMAIN")
|
||||
if os.environ.get("DOC_SERV"): # generates links for document server
|
||||
|
||||
9
web/documentserver-example/python/readme.md
Normal file → Executable file
9
web/documentserver-example/python/readme.md
Normal file → Executable file
@ -71,3 +71,12 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
|
||||
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
|
||||
|
||||
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
|
||||
|
||||
## Important security info
|
||||
|
||||
Please keep in mind the following security aspects when you are using test examples:
|
||||
|
||||
* There is no protection of the storage from unauthorized access since there is no need for authorization.
|
||||
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
|
||||
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
|
||||
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
|
||||
@ -41,7 +41,8 @@ urlpatterns = [
|
||||
path('remove', actions.remove),
|
||||
path('csv', actions.csv),
|
||||
path('files', actions.files),
|
||||
path('saveas', actions.saveAs)
|
||||
path('saveas', actions.saveAs),
|
||||
path('rename', actions.rename)
|
||||
]
|
||||
|
||||
urlpatterns += staticfiles_urlpatterns()
|
||||
36
web/documentserver-example/python/src/utils/docManager.py
Normal file → Executable file
36
web/documentserver-example/python/src/utils/docManager.py
Normal file → Executable file
@ -39,40 +39,6 @@ from django.http import HttpResponse, HttpResponseRedirect, FileResponse
|
||||
from src import settings
|
||||
from . import fileUtils, historyManager
|
||||
|
||||
LANGUAGES = {
|
||||
'en': 'English',
|
||||
'be': 'Belarusian',
|
||||
'bg': 'Bulgarian',
|
||||
'ca': 'Catalan',
|
||||
'zh': 'Chinese',
|
||||
'cs': 'Czech',
|
||||
'da': 'Danish',
|
||||
'nl': 'Dutch',
|
||||
'fi': 'Finnish',
|
||||
'fr': 'French',
|
||||
'de': 'German',
|
||||
'el': 'Greek',
|
||||
'hu': 'Hungarian',
|
||||
'id': 'Indonesian',
|
||||
'it': 'Italian',
|
||||
'ja': 'Japanese',
|
||||
'ko': 'Korean',
|
||||
'lv': 'Latvian',
|
||||
'lo': 'Lao',
|
||||
'nb': 'Norwegian',
|
||||
'pl': 'Polish',
|
||||
'pt': 'Portuguese',
|
||||
'ro': 'Romanian',
|
||||
'ru': 'Russian',
|
||||
'sk': 'Slovak',
|
||||
'sl': 'Slovenian',
|
||||
'es': 'Spanish',
|
||||
'sv': 'Swedish',
|
||||
'tr': 'Turkish',
|
||||
'uk': 'Ukrainian',
|
||||
'vi': 'Vietnamese'
|
||||
}
|
||||
|
||||
def isCanFillForms(ext):
|
||||
return ext in config.DOC_SERV_FILLFORMS
|
||||
|
||||
@ -253,7 +219,7 @@ def createFileResponse(response, path, req, meta):
|
||||
|
||||
# save file from the given url
|
||||
def saveFileFromUri(uri, path, req = None, meta = False):
|
||||
resp = requests.get(uri, stream=True)
|
||||
resp = requests.get(uri, stream=True, verify = config.DOC_SERV_VERIFY_PEER)
|
||||
createFileResponse(resp, path, req, meta)
|
||||
return
|
||||
|
||||
|
||||
2
web/documentserver-example/python/src/utils/serviceConverter.py
Normal file → Executable file
2
web/documentserver-example/python/src/utils/serviceConverter.py
Normal file → Executable file
@ -58,7 +58,7 @@ def getConverterUri(docUri, fromExt, toExt, docKey, isAsync, filePass = None, la
|
||||
payload['token'] = jwtManager.encode(payload) # encode a payload object into a body token
|
||||
headers[jwtHeader] = f'Bearer {headerToken}' # add a header Authorization with a header token with Authorization prefix in it
|
||||
|
||||
response = requests.post(config.DOC_SERV_SITE_URL + config.DOC_SERV_CONVERTER_URL, json=payload, headers=headers ) # send the headers and body values to the converter and write the result to the response
|
||||
response = requests.post(config.DOC_SERV_SITE_URL + config.DOC_SERV_CONVERTER_URL, json=payload, headers=headers, verify = config.DOC_SERV_VERIFY_PEER) # send the headers and body values to the converter and write the result to the response
|
||||
json = response.json()
|
||||
|
||||
return getResponseUri(json)
|
||||
|
||||
12
web/documentserver-example/python/src/utils/trackManager.py
Normal file → Executable file
12
web/documentserver-example/python/src/utils/trackManager.py
Normal file → Executable file
@ -150,7 +150,7 @@ def processForceSave(body, filename, usAddr):
|
||||
return
|
||||
|
||||
# create a command request
|
||||
def commandRequest(method, key):
|
||||
def commandRequest(method, key, meta = None):
|
||||
documentCommandUrl = config.DOC_SERV_SITE_URL + config.DOC_SERV_COMMAND_URL
|
||||
|
||||
payload = {
|
||||
@ -158,6 +158,10 @@ def commandRequest(method, key):
|
||||
'key': key
|
||||
}
|
||||
|
||||
if (meta):
|
||||
payload['meta'] = meta
|
||||
|
||||
|
||||
headers={'accept': 'application/json'}
|
||||
|
||||
if jwtManager.isEnabled(): # check if a secret key to generate token exists or not
|
||||
@ -166,8 +170,10 @@ def commandRequest(method, key):
|
||||
headers[jwtHeader] = f'Bearer {headerToken}' # add a header Authorization with a header token with Authorization prefix in it
|
||||
|
||||
payload['token'] = jwtManager.encode(payload) # encode a payload object into a body token
|
||||
|
||||
response = requests.post(documentCommandUrl, json=payload, headers=headers)
|
||||
response = requests.post(documentCommandUrl, json=payload, headers=headers, verify = config.DOC_SERV_VERIFY_PEER)
|
||||
|
||||
if (meta):
|
||||
return response
|
||||
|
||||
return
|
||||
|
||||
|
||||
@ -79,7 +79,8 @@ descr_user_0 = [
|
||||
"The file favorite state is undefined",
|
||||
"Can't mention others in comments",
|
||||
"Can't create new files from the editor",
|
||||
"Can’t see anyone’s information"
|
||||
"Can’t see anyone’s information",
|
||||
"Can't rename files from the editor"
|
||||
]
|
||||
|
||||
USERS = [
|
||||
|
||||
20
web/documentserver-example/python/src/views/actions.py
Normal file → Executable file
20
web/documentserver-example/python/src/views/actions.py
Normal file → Executable file
@ -118,7 +118,7 @@ def createNew(request):
|
||||
|
||||
# save file as...
|
||||
def saveAs(request):
|
||||
response ={}
|
||||
response = {}
|
||||
|
||||
try:
|
||||
body = json.loads(request.body)
|
||||
@ -127,7 +127,7 @@ def saveAs(request):
|
||||
|
||||
filename = docManager.getCorrectName(title, request)
|
||||
path = docManager.getStoragePath(filename, request)
|
||||
resp = requests.get(saveAsFileUrl)
|
||||
resp = requests.get(saveAsFileUrl, verify = config.DOC_SERV_VERIFY_PEER)
|
||||
|
||||
if ((len(resp.content) > config.FILE_SIZE_MAX) | (len(resp.content) <= 0)): # check if the file size exceeds the maximum size allowed (5242880)
|
||||
response.setdefault('error', 'File size is incorrect')
|
||||
@ -147,6 +147,21 @@ def saveAs(request):
|
||||
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
|
||||
# rename file
|
||||
def rename(request):
|
||||
response = {}
|
||||
|
||||
body = json.loads(request.body)
|
||||
newfilename = body['newfilename']
|
||||
dockey = body['dockey']
|
||||
meta = {'title': newfilename}
|
||||
|
||||
trackManager.commandRequest('meta', dockey, meta)
|
||||
|
||||
response.setdefault('result', trackManager.commandRequest('meta', dockey, meta).json())
|
||||
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
|
||||
# edit a file
|
||||
def edit(request):
|
||||
filename = fileUtils.getFileName(request.GET['filename'])
|
||||
@ -250,6 +265,7 @@ def edit(request):
|
||||
},
|
||||
'customization': { # the parameters for the editor interface
|
||||
'about': True, # the About section display
|
||||
'comments': True,
|
||||
'feedback': True, # the Feedback & Support menu button display
|
||||
'forcesave': False, # adds the request for the forced file saving to the callback handler
|
||||
'submitForm': submitForm, # if the Submit form button is displayed or not
|
||||
|
||||
2
web/documentserver-example/python/src/views/index.py
Normal file → Executable file
2
web/documentserver-example/python/src/views/index.py
Normal file → Executable file
@ -35,7 +35,7 @@ from src.utils import docManager
|
||||
def default(request): # default parameters that will be passed to the template
|
||||
context = {
|
||||
'users': users.USERS,
|
||||
'languages': docManager.LANGUAGES,
|
||||
'languages': config.LANGUAGES,
|
||||
'preloadurl': config.DOC_SERV_SITE_URL + config.DOC_SERV_PRELOADER_URL,
|
||||
'editExt': json.dumps(config.DOC_SERV_EDITED), # file extensions that can be edited
|
||||
'convExt': json.dumps(config.DOC_SERV_CONVERT), # file extensions that can be converted
|
||||
|
||||
74
web/documentserver-example/python/templates/editor.html
Normal file → Executable file
74
web/documentserver-example/python/templates/editor.html
Normal file → Executable file
@ -49,6 +49,7 @@
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
var docEditor;
|
||||
var config;
|
||||
|
||||
var innerAlert = function (message, inEditor) {
|
||||
if (console && console.log)
|
||||
@ -110,10 +111,14 @@
|
||||
|
||||
// the meta information of the document is changed via the meta command
|
||||
var onMetaChange = function (event) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
if (event.data.favorite) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
}
|
||||
|
||||
innerAlert("onMetaChange: " + JSON.stringify(event.data));
|
||||
};
|
||||
|
||||
// the user is trying to insert an image by clicking the Image from Storage button
|
||||
@ -145,7 +150,7 @@
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "saveas");
|
||||
xhr.setRequestHeader( 'Content-Type', 'application/json');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
@ -153,6 +158,23 @@
|
||||
}
|
||||
};
|
||||
|
||||
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
|
||||
innerAlert("onRequestRename: " + JSON.stringify(event.data));
|
||||
|
||||
var newfilename = event.data;
|
||||
var data = {
|
||||
newfilename: newfilename,
|
||||
dockey: config.document.key,
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "rename");
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
}
|
||||
};
|
||||
|
||||
var connectEditor = function () {
|
||||
|
||||
config = {{ cfg | safe }}
|
||||
@ -171,26 +193,28 @@
|
||||
"onRequestMailMergeRecipients": onRequestMailMergeRecipients,
|
||||
};
|
||||
|
||||
{% if history and historyData %}
|
||||
|
||||
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory({{ history | safe }}); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = {{ historyData | safe }};
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
if (config.editorConfig.user.id) {
|
||||
|
||||
{% endif %}
|
||||
{% if history and historyData %}
|
||||
|
||||
{% if usersForMentions %}
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory({{ history | safe }}); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = {{ historyData | safe }};
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
|
||||
{% endif %}
|
||||
|
||||
// add mentions for not anonymous users
|
||||
config.events['onRequestUsers'] = function () {
|
||||
@ -200,12 +224,14 @@
|
||||
};
|
||||
// the user is mentioned in a comment
|
||||
config.events['onRequestSendNotify'] = function (event) {
|
||||
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
|
||||
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
// prevent file renaming for anonymous users
|
||||
config.events['onRequestRename'] = onRequestRename;
|
||||
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
if (config.editorConfig.createUrl) {
|
||||
config.events.onRequestSaveAs = onRequestSaveAs;
|
||||
|
||||
9
web/documentserver-example/ruby/README.md
Normal file → Executable file
9
web/documentserver-example/ruby/README.md
Normal file → Executable file
@ -79,3 +79,12 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
|
||||
In case the example and Document Server are installed on different computers, make sure that your server with the example installed has access to the Document Server with the address which you specify instead of **documentserver** in the configuration files.
|
||||
|
||||
Make sure that the Document Server has access to the server with the example installed with the address which you specify instead of **example.com** in the configuration files.
|
||||
|
||||
## Important security info
|
||||
|
||||
Please keep in mind the following security aspects when you are using test examples:
|
||||
|
||||
* There is no protection of the storage from unauthorized access since there is no need for authorization.
|
||||
* There are no checks against parameter substitution in links, since the parameters are generated by the code according to the pre-arranged scripts.
|
||||
* There are no data checks in requests of saving the file after editing, since each test example is intended for requests only from ONLYOFFICE Document Server.
|
||||
* There are no prohibitions on using test examples from other sites, since they are intended to interact with ONLYOFFICE Document Server from another domain.
|
||||
24
web/documentserver-example/ruby/app/controllers/home_controller.rb
Normal file → Executable file
24
web/documentserver-example/ruby/app/controllers/home_controller.rb
Normal file → Executable file
@ -118,10 +118,7 @@ class HomeController < ApplicationController
|
||||
uri = URI.parse(new_file_uri) # create the request url
|
||||
http = Net::HTTP.new(uri.host, uri.port) # create a connection to the http server
|
||||
|
||||
if new_file_uri.start_with?('https')
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # set the flags for the server certificate verification at the beginning of SSL session
|
||||
end
|
||||
DocumentHelper.verify_ssl(new_file_uri, http)
|
||||
|
||||
req = Net::HTTP::Get.new(uri.request_uri) # create the get requets
|
||||
res = http.request(req)
|
||||
@ -324,10 +321,8 @@ class HomeController < ApplicationController
|
||||
uri = URI.parse(file_url) # create the request url
|
||||
http = Net::HTTP.new(uri.host, uri.port) # create a connection to the http server
|
||||
|
||||
if file_url.start_with?('https')
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # set the flags for the server certificate verification at the beginning of SSL session
|
||||
end
|
||||
DocumentHelper.verify_ssl(file_url, http)
|
||||
|
||||
req = Net::HTTP::Get.new(uri.request_uri) # create the get requets
|
||||
res = http.request(req)
|
||||
data = res.body
|
||||
@ -350,4 +345,17 @@ class HomeController < ApplicationController
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Rename...
|
||||
def rename
|
||||
body = JSON.parse(request.body.read)
|
||||
dockey = body["dockey"]
|
||||
newfilename = body["newfilename"]
|
||||
meta = {
|
||||
:title => newfilename
|
||||
}
|
||||
|
||||
json_data = TrackHelper.command_request("meta", dockey, meta)
|
||||
render plain: '{ "result" : "' + JSON.dump(json_data) + '"}'
|
||||
end
|
||||
end
|
||||
8
web/documentserver-example/ruby/app/models/document_helper.rb
Normal file → Executable file
8
web/documentserver-example/ruby/app/models/document_helper.rb
Normal file → Executable file
@ -340,7 +340,13 @@ class DocumentHelper
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
||||
# enable ignore certificate
|
||||
def verify_ssl(file_uri, http)
|
||||
if file_uri.start_with?('https') && Rails.configuration.verify_peer_off.eql?('true')
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # set the flags for the server certificate verification at the beginning of SSL session
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
8
web/documentserver-example/ruby/app/models/file_model.rb
Normal file → Executable file
8
web/documentserver-example/ruby/app/models/file_model.rb
Normal file → Executable file
@ -151,8 +151,14 @@ class FileModel
|
||||
:toolbarDocked => "top" # the place for the embedded viewer toolbar (top or bottom)
|
||||
},
|
||||
:customization => { # the parameters for the editor interface
|
||||
:about => true, # the About section display
|
||||
:comments => true,
|
||||
:feedback => true, # the Feedback & Support menu button display
|
||||
:forcesave => false, # adding the request for the forced file saving to the callback handler
|
||||
:submitForm => submitForm # the Submit form button state
|
||||
:submitForm => submitForm, # the Submit form button state
|
||||
:goback => {
|
||||
:url => DocumentHelper.get_server_url(true)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
5
web/documentserver-example/ruby/app/models/service_converter.rb
Normal file → Executable file
5
web/documentserver-example/ruby/app/models/service_converter.rb
Normal file → Executable file
@ -51,10 +51,7 @@ class ServiceConverter
|
||||
uri = URI.parse(@@document_converter_url) # create the request url
|
||||
http = Net::HTTP.new(uri.host, uri.port) # create a connection to the http server
|
||||
|
||||
if @@document_converter_url.start_with?('https')
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # set the flags for the server certificate verification at the beginning of SSL session
|
||||
end
|
||||
DocumentHelper.verify_ssl(@@document_converter_url, http)
|
||||
|
||||
http.read_timeout = @@convert_timeout
|
||||
req = Net::HTTP::Post.new(uri.request_uri) # create the post request
|
||||
|
||||
18
web/documentserver-example/ruby/app/models/track_helper.rb
Normal file → Executable file
18
web/documentserver-example/ruby/app/models/track_helper.rb
Normal file → Executable file
@ -206,14 +206,18 @@ class TrackHelper
|
||||
end
|
||||
|
||||
# send the command request
|
||||
def command_request(method, key)
|
||||
def command_request(method, key, meta = nil)
|
||||
document_command_url = Rails.configuration.urlSite + Rails.configuration.commandUrl # get the document command url
|
||||
|
||||
# create a payload object with the method and key
|
||||
payload = {
|
||||
:c => method,
|
||||
:key => key
|
||||
}
|
||||
}
|
||||
|
||||
if (meta != nil)
|
||||
payload.merge!({:meta => meta})
|
||||
end
|
||||
|
||||
data = nil
|
||||
begin
|
||||
@ -221,10 +225,7 @@ class TrackHelper
|
||||
uri = URI.parse(document_command_url) # parse the document command url
|
||||
http = Net::HTTP.new(uri.host, uri.port) # create a connection to the http server
|
||||
|
||||
if document_command_url.start_with?('https') # check if the documnent command url starts with https
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # set the flags for the server certificate verification at the beginning of SSL session
|
||||
end
|
||||
DocumentHelper.verify_ssl(document_command_url, http)
|
||||
|
||||
req = Net::HTTP::Post.new(uri.request_uri) # create the post request
|
||||
req.add_field("Content-Type", "application/json") # set headers
|
||||
@ -251,10 +252,7 @@ class TrackHelper
|
||||
uri = URI.parse(uristr) # parse the url string
|
||||
http = Net::HTTP.new(uri.host, uri.port) # create a connection to the http server
|
||||
|
||||
if uristr.start_with?('https') # check if the documnent command url starts with https
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # set the flags for the server certificate verification at the beginning of SSL session
|
||||
end
|
||||
DocumentHelper.verify_ssl(uristr, http)
|
||||
|
||||
req = Net::HTTP::Get.new(uri)
|
||||
res = http.request(req) # get the response
|
||||
|
||||
@ -72,7 +72,8 @@ class Users
|
||||
"The file favorite state is undefined",
|
||||
"Can't mention others in comments",
|
||||
"Can't create new files from the editor",
|
||||
"Can’t see anyone’s information"
|
||||
"Can’t see anyone’s information",
|
||||
"Can't rename files from the editor"
|
||||
];
|
||||
|
||||
@@users = [
|
||||
|
||||
79
web/documentserver-example/ruby/app/views/home/editor.html.erb
Normal file → Executable file
79
web/documentserver-example/ruby/app/views/home/editor.html.erb
Normal file → Executable file
@ -26,6 +26,7 @@
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
var docEditor;
|
||||
var config;
|
||||
|
||||
var innerAlert = function (message, inEditor) {
|
||||
if (console && console.log)
|
||||
@ -87,10 +88,14 @@
|
||||
|
||||
// the meta information of the document is changed via the meta command
|
||||
var onMetaChange = function (event) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
if (event.data.favorite) {
|
||||
var favorite = !!event.data.favorite;
|
||||
var title = document.title.replace(/^\☆/g, "");
|
||||
document.title = (favorite ? "☆" : "") + title;
|
||||
docEditor.setFavorite(favorite); // change the Favorite icon state
|
||||
}
|
||||
|
||||
innerAlert("onMetaChange: " + JSON.stringify(event.data));
|
||||
};
|
||||
|
||||
// the user is trying to insert an image by clicking the Image from Storage button
|
||||
@ -120,7 +125,7 @@
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "saveas");
|
||||
xhr.setRequestHeader( 'Content-Type', 'application/json');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
@ -128,9 +133,26 @@
|
||||
}
|
||||
};
|
||||
|
||||
var onRequestRename = function(event) { // the user is trying to rename file by clicking Rename... button
|
||||
innerAlert("onRequestRename: " + JSON.stringify(event.data));
|
||||
|
||||
var newfilename = event.data;
|
||||
var data = {
|
||||
newfilename: newfilename,
|
||||
dockey: config.document.key,
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "rename");
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
}
|
||||
};
|
||||
|
||||
var сonnectEditor = function () {
|
||||
|
||||
var config = <%= raw @file.get_config.to_json %>;
|
||||
config = <%= raw @file.get_config.to_json %>;
|
||||
|
||||
config.width = "100%";
|
||||
config.height = "100%";
|
||||
@ -149,27 +171,25 @@
|
||||
|
||||
<%
|
||||
history = @file.get_history
|
||||
if history %>
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(<%= raw history[:hist].to_json %>); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = <%= raw history[:histData].to_json %>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
<% end
|
||||
%>
|
||||
usersMentions = @file.get_users_mentions %>
|
||||
|
||||
<%
|
||||
usersMentions = @file.get_users_mentions
|
||||
if usersMentions %>
|
||||
if (config.editorConfig.user.id) {
|
||||
<% if history %>
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(<%= raw history[:hist].to_json %>); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = <%= raw history[:histData].to_json %>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
<% end %>
|
||||
// add mentions for not anonymous users
|
||||
config.events['onRequestUsers'] = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
@ -178,12 +198,13 @@
|
||||
};
|
||||
// the user is mentioned in a comment
|
||||
config.events['onRequestSendNotify'] = function (event) {
|
||||
event.data.actionLink = replaceActionLink(location.href, event.data.actionLink);
|
||||
event.data.actionLink = replaceActionLink(location.href, JSON.stringify(event.data.actionLink));
|
||||
var data = JSON.stringify(event.data);
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
<% end
|
||||
%>
|
||||
// prevent file renaming for anonymous users
|
||||
config.events['onRequestRename'] = onRequestRename;
|
||||
}
|
||||
|
||||
if (config.editorConfig.createUrl) {
|
||||
config.events.onRequestSaveAs = onRequestSaveAs;
|
||||
|
||||
34
web/documentserver-example/ruby/app/views/home/index.html.erb
Normal file → Executable file
34
web/documentserver-example/ruby/app/views/home/index.html.erb
Normal file → Executable file
@ -72,37 +72,9 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<select class="select-user" id="language">
|
||||
<option value="en">English</option>
|
||||
<option value="be">Belarusian</option>
|
||||
<option value="bg">Bulgarian</option>
|
||||
<option value="ca">Catalan</option>
|
||||
<option value="zh">Chinese</option>
|
||||
<option value="cs">Czech</option>
|
||||
<option value="da">Danish</option>
|
||||
<option value="nl">Dutch</option>
|
||||
<option value="fi">Finnish</option>
|
||||
<option value="fr">French</option>
|
||||
<option value="de">German</option>
|
||||
<option value="el">Greek</option>
|
||||
<option value="hu">Hungarian</option>
|
||||
<option value="id">Indonesian</option>
|
||||
<option value="it">Italian</option>
|
||||
<option value="ja">Japanese</option>
|
||||
<option value="ko">Korean</option>
|
||||
<option value="lv">Latvian</option>
|
||||
<option value="lo">Lao</option>
|
||||
<option value="nb">Norwegian</option>
|
||||
<option value="pl">Polish</option>
|
||||
<option value="pt">Portuguese</option>
|
||||
<option value="ro">Romanian</option>
|
||||
<option value="ru">Russian</option>
|
||||
<option value="sk">Slovak</option>
|
||||
<option value="sl">Slovenian</option>
|
||||
<option value="sv">Swedish</option>
|
||||
<option value="es">Spanish</option>
|
||||
<option value="tr">Turkish</option>
|
||||
<option value="uk">Ukrainian</option>
|
||||
<option value="vi">Vietnamese</option>
|
||||
<% Rails.configuration.languages.each { |key, language|%>
|
||||
<option value="<%=key %>"> <%=language %> </option>
|
||||
<% } %>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -26,7 +26,7 @@ module OnlineEditorsExampleRuby
|
||||
end
|
||||
end
|
||||
|
||||
Rails.configuration.version="1.1.0"
|
||||
Rails.configuration.version="1.2.0"
|
||||
|
||||
Rails.configuration.fileSizeMax=5242880
|
||||
Rails.configuration.storagePath="app_data"
|
||||
@ -48,5 +48,42 @@ module OnlineEditorsExampleRuby
|
||||
Rails.configuration.jwtSecret = ""
|
||||
Rails.configuration.header="Authorization"
|
||||
|
||||
Rails.configuration.verify_peer_off = "true"
|
||||
|
||||
Rails.configuration.languages={
|
||||
'en' => 'English',
|
||||
'az' => 'Azerbaijani',
|
||||
'be' => 'Belarusian',
|
||||
'bg' => 'Bulgarian',
|
||||
'ca' => 'Catalan',
|
||||
'zh' => 'Chinese',
|
||||
'cs' => 'Czech',
|
||||
'da' => 'Danish',
|
||||
'nl' => 'Dutch',
|
||||
'fi' => 'Finnish',
|
||||
'fr' => 'French',
|
||||
'gl' => 'Galego'
|
||||
'de' => 'German',
|
||||
'el' => 'Greek',
|
||||
'hu' => 'Hungarian',
|
||||
'id' => 'Indonesian',
|
||||
'it' => 'Italian',
|
||||
'ja' => 'Japanese',
|
||||
'ko' => 'Korean',
|
||||
'lv' => 'Latvian',
|
||||
'lo' => 'Lao',
|
||||
'nb' => 'Norwegian',
|
||||
'pl' => 'Polish',
|
||||
'pt' => 'Portuguese',
|
||||
'ro' => 'Romanian',
|
||||
'ru' => 'Russian',
|
||||
'sk' => 'Slovak',
|
||||
'sl' => 'Slovenian',
|
||||
'es' => 'Spanish',
|
||||
'sv' => 'Swedish',
|
||||
'tr' => 'Turkish',
|
||||
'uk' => 'Ukrainian',
|
||||
'vi' => 'Vietnamese'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@ -13,6 +13,7 @@ Rails.application.routes.draw do
|
||||
match '/csv', to: 'home#csv', via: 'get'
|
||||
match '/files', to: 'home#files', via: 'get'
|
||||
match '/saveas', to: 'home#saveas', via: 'post'
|
||||
match '/rename', to: 'home#rename', via: 'post'
|
||||
|
||||
# The priority is based upon order of creation: first created -> highest priority.
|
||||
# See how all your routes lay out with "rake routes".
|
||||
|
||||
Reference in New Issue
Block a user