// get a document which will be compared with the current document
        private Dictionary <string, object> GetCompareFile()
        {
            // get the path to the compared file
            var compareFileUrl = new UriBuilder(_Default.GetServerUrl(true));

            compareFileUrl.Path = HttpRuntime.AppDomainAppVirtualPath
                                  + (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
                                  + "webeditor.ashx";
            compareFileUrl.Query = "type=assets&fileName=" + HttpUtility.UrlEncode("sample.docx");

            // create an object with the information about the compared file
            Dictionary <string, object> dataCompareFile = new Dictionary <string, object>
            {
                { "fileType", "docx" },
                { "url", compareFileUrl.ToString() }
            };

            if (JwtManager.Enabled)                                        // if the secret key to generate token exists
            {
                var compareFileToken = JwtManager.Encode(dataCompareFile); // encode the dataCompareFile object into the token
                dataCompareFile.Add("token", compareFileToken);            // and add it to the dataCompareFile object
            }

            return(dataCompareFile);
        }
        // get a mail merge config
        private Dictionary <string, object> GetMailMergeConfig()
        {
            // get the path to the recipients data for mail merging
            var mailmergeUrl = new UriBuilder(_Default.GetServerUrl(true));

            mailmergeUrl.Path =
                HttpRuntime.AppDomainAppVirtualPath
                + (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
                + "webeditor.ashx";
            mailmergeUrl.Query = "type=csv";

            // create a mail merge config
            Dictionary <string, object> mailMergeConfig = new Dictionary <string, object>
            {
                { "fileType", "csv" },
                { "url", mailmergeUrl.ToString() }
            };

            if (JwtManager.Enabled)                                      // if the secret key to generate token exists
            {
                var mailmergeToken = JwtManager.Encode(mailMergeConfig); // encode mailMergeConfig into the token
                mailMergeConfig.Add("token", mailmergeToken);            // and add it to the mail merge config
            }

            return(mailMergeConfig);
        }
        private Dictionary <string, object> GetLogoConfig()
        {
            var InsertImageUrl = new UriBuilder(_Default.GetServerUrl(true));

            InsertImageUrl.Path = HttpRuntime.AppDomainAppVirtualPath
                                  + (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
                                  + "App_Themes\\images\\logo.png";

            Dictionary <string, object> logoConfig = new Dictionary <string, object>
            {
                { "fileType", "png" },
                { "url", InsertImageUrl.ToString() }
            };

            if (JwtManager.Enabled)
            {
                var insImageToken = JwtManager.Encode(logoConfig);
                logoConfig.Add("token", insImageToken);
            }

            return(logoConfig);
        }
        private Dictionary <string, object> GetCompareFile()
        {
            var compareFileUrl = new UriBuilder(_Default.GetServerUrl(true));

            compareFileUrl.Path = HttpRuntime.AppDomainAppVirtualPath
                                  + (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
                                  + "webeditor.ashx";
            compareFileUrl.Query = "type=assets&fileName=" + HttpUtility.UrlEncode("sample.docx");

            Dictionary <string, object> dataCompareFile = new Dictionary <string, object>
            {
                { "fileType", "docx" },
                { "url", compareFileUrl.ToString() }
            };

            if (JwtManager.Enabled)
            {
                var compareFileToken = JwtManager.Encode(dataCompareFile);
                dataCompareFile.Add("token", compareFileToken);
            }

            return(dataCompareFile);
        }
        // get a logo config
        private Dictionary <string, object> GetLogoConfig()
        {
            // get the path to the logo image
            var InsertImageUrl = new UriBuilder(_Default.GetServerUrl(true));

            InsertImageUrl.Path = HttpRuntime.AppDomainAppVirtualPath
                                  + (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
                                  + "App_Themes\\images\\logo.png";

            // create a logo config
            Dictionary <string, object> logoConfig = new Dictionary <string, object>
            {
                { "fileType", "png" },
                { "url", InsertImageUrl.ToString() }
            };

            if (JwtManager.Enabled)                                // if the secret key to generate token exists
            {
                var insImageToken = JwtManager.Encode(logoConfig); // encode logoConfig into the token
                logoConfig.Add("token", insImageToken);            // and add it to the logo config
            }

            return(logoConfig);
        }
        private Dictionary <string, object> GetMailMergeConfig()
        {
            var mailmergeUrl = new UriBuilder(_Default.GetServerUrl(true));

            mailmergeUrl.Path =
                HttpRuntime.AppDomainAppVirtualPath
                + (HttpRuntime.AppDomainAppVirtualPath.EndsWith("/") ? "" : "/")
                + "webeditor.ashx";
            mailmergeUrl.Query = "type=csv";

            Dictionary <string, object> mailMergeConfig = new Dictionary <string, object>
            {
                { "fileType", "csv" },
                { "url", mailmergeUrl.ToString() }
            };

            if (JwtManager.Enabled)
            {
                var mailmergeToken = JwtManager.Encode(mailMergeConfig);
                mailMergeConfig.Add("token", mailmergeToken);
            }

            return(mailMergeConfig);
        }
        // get the document history
        private void GetHistory(out Dictionary <string, object> history, out Dictionary <string, object> historyData)
        {
            var storagePath = WebConfigurationManager.AppSettings["storage-path"];
            var jss         = new JavaScriptSerializer();
            var histDir     = _Default.HistoryDir(_Default.StoragePath(FileName, null));

            history     = null;
            historyData = null;

            if (_Default.GetFileVersion(histDir) > 0)  // if the file was modified (the file version is greater than 0)
            {
                var currentVersion = _Default.GetFileVersion(histDir);
                var hist           = new List <Dictionary <string, object> >();
                var histData       = new Dictionary <string, object>();

                for (var i = 1; i <= currentVersion; i++)  // run through all the file versions
                {
                    var obj     = new Dictionary <string, object>();
                    var dataObj = new Dictionary <string, object>();
                    var verDir  = _Default.VersionDir(histDir, i);                                           // get the path to the given file version

                    var key = i == currentVersion ? Key : File.ReadAllText(Path.Combine(verDir, "key.txt")); // get document key

                    obj.Add("key", key);
                    obj.Add("version", i);

                    if (i == 1)                                                   // check if the version number is equal to 1
                    {
                        var infoPath = Path.Combine(histDir, "createdInfo.json"); // get meta data of this file

                        if (File.Exists(infoPath))
                        {
                            var info = jss.Deserialize <Dictionary <string, object> >(File.ReadAllText(infoPath));
                            obj.Add("created", info["created"]);  // write meta information to the object (user information and creation date)
                            obj.Add("user", new Dictionary <string, object>()
                            {
                                { "id", info["id"] },
                                { "name", info["name"] },
                            });
                        }
                    }

                    var ext = Path.GetExtension(FileName).ToLower();
                    dataObj.Add("fileType", ext.Replace(".", ""));
                    dataObj.Add("key", key);
                    // write file url to the data object
                    var prevFileUrl = i == currentVersion ? FileUri : MakePublicHistoryUrl(FileName, i.ToString(), "prev" + ext);
                    if (Path.IsPathRooted(storagePath))
                    {
                        prevFileUrl = i == currentVersion?getDownloadUrl(FileName) : getDownloadUrl(Directory.GetFiles(verDir, "prev.*")[0].Replace(storagePath + "\\", ""));
                    }

                    dataObj.Add("url", prevFileUrl); // write file url to the data object
                    dataObj.Add("version", i);
                    if (i > 1)                       // check if the version number is greater than 1 (the file was modified)
                    {
                        // get the path to the changes.json file
                        var changes      = jss.Deserialize <Dictionary <string, object> >(File.ReadAllText(Path.Combine(_Default.VersionDir(histDir, i - 1), "changes.json")));
                        var changesArray = (ArrayList)changes["changes"];
                        var change       = changesArray.Count > 0
                            ? (Dictionary <string, object>)changesArray[0]
                            : new Dictionary <string, object>();

                        // write information about changes to the object
                        obj.Add("changes", change.Count > 0 ? changes["changes"] : null);
                        obj.Add("serverVersion", changes["serverVersion"]);
                        obj.Add("created", change.Count > 0 ? change["created"] : null);
                        obj.Add("user", change.Count > 0 ? change["user"] : null);

                        var prev = (Dictionary <string, object>)histData[(i - 2).ToString()]; // get the history data from the previous file version
                        dataObj.Add("previous", new Dictionary <string, object>()             // write information about previous file version to the data object
                        {
                            { "fileType", prev["fileType"] },
                            { "key", prev["key"] },  // write key and url information about previous file version
                            { "url", prev["url"] },
                        });
                        // write the path to the diff.zip archive with differences in this file version
                        var changesUrl = MakePublicHistoryUrl(FileName, (i - 1).ToString(), "diff.zip");
                        dataObj.Add("changesUrl", changesUrl);
                    }
                    if (JwtManager.Enabled)
                    {
                        var token = JwtManager.Encode(dataObj);
                        dataObj.Add("token", token);
                    }
                    hist.Add(obj);                             // add object dictionary to the hist list
                    histData.Add((i - 1).ToString(), dataObj); // write data object information to the history data
                }

                // write history information about the current file version to the history object
                history = new Dictionary <string, object>()
                {
                    { "currentVersion", currentVersion },
                    { "history", hist }
                };
                historyData = histData;
            }
        }
        // loading a page
        protected void Page_Load(object sender, EventArgs e)
        {
            // get file url
            var externalUrl = Request["fileUrl"];

            if (!string.IsNullOrEmpty(externalUrl))
            {
                // and upload the file by the file url and the request
                FileName = _Default.DoUpload(externalUrl, Request);
            }
            else  // if it doesn't exist
            {
                // get file name
                FileName = Path.GetFileName(Request["fileID"]);
            }

            // get file type
            var type = Request["type"];

            if (!string.IsNullOrEmpty(type))
            {
                // create demo document of a specified file type
                Try(type, Request["sample"], Request);
                Response.Redirect("doceditor.aspx?fileID=" + HttpUtility.UrlEncode(FileName));
            }

            // get file extension
            var ext = Path.GetExtension(FileName).ToLower();

            // get editor mode or set the default one (edit)
            var editorsMode = Request.GetOrDefault("editorsMode", "edit");

            var canEdit     = _Default.EditedExts.Contains(ext); // check if this file can be edited
            var editorsType = Request.GetOrDefault("editorsType", "desktop");

            var id   = Request.Cookies.GetOrDefault("uid", null);
            var user = Users.getUser(id);  // get the user

            if ((!canEdit && editorsMode.Equals("edit") || editorsMode.Equals("fillForms")) && _Default.FillFormsExts.Contains(ext))
            {
                editorsMode = "fillForms";
                canEdit     = true;
            }
            var submitForm = editorsMode.Equals("fillForms") && id.Equals("uid-1") && false; // check if the Submit form button is displayed or hidden
            var mode       = canEdit && editorsMode != "view" ? "edit" : "view";             // get the editor opening mode (edit or view)

            var jss = new JavaScriptSerializer();

            // favorite icon state
            bool?favorite = user.favorite;

            var actionLink = Request.GetOrDefault("actionLink", null);                                    // get the action link (comment or bookmark) if it exists
            var actionData = string.IsNullOrEmpty(actionLink) ? null : jss.DeserializeObject(actionLink); // get action data for the action link

            var createUrl         = getCreateUrl(DocumentType, editorsType);
            var templatesImageUrl = GetTemplateImageUrl(ext); // image url for templates
            var templates         = new List <Dictionary <string, string> >
            {
                new Dictionary <string, string>()
                {
                    { "image", "" },
                    { "title", "Blank" },
                    { "url", createUrl }
                },
                new Dictionary <string, string>()
                {
                    { "image", templatesImageUrl },
                    { "title", "With sample content" },
                    { "url", createUrl + "&sample=true" }
                }
            };

            // specify the document config
            var config = new Dictionary <string, object>
            {
                { "type", editorsType },
                { "documentType", DocumentType },
                {
                    "document", new Dictionary <string, object>
                    {
                        { "title", FileName },
                        { "url", getDownloadUrl(FileName) },
                        { "fileType", ext.Trim('.') },
                        { "key", Key },
                        {
                            "info", new Dictionary <string, object>
                            {
                                { "owner", "Me" },
                                { "uploaded", DateTime.Now.ToShortDateString() },
                                { "favorite", favorite }
                            }
                        },
                        {
                            // the permission for the document to be edited and downloaded or not
                            "permissions", new Dictionary <string, object>
                            {
                                { "comment", editorsMode != "view" && editorsMode != "fillForms" && editorsMode != "embedded" && editorsMode != "blockcontent" },
                                { "copy", !user.deniedPermissions.Contains("copy") },
                                { "download", !user.deniedPermissions.Contains("download") },
                                { "edit", canEdit&& (editorsMode == "edit" || editorsMode == "view" || editorsMode == "filter" || editorsMode == "blockcontent") },
                                { "print", !user.deniedPermissions.Contains("print") },
                                { "fillForms", editorsMode != "view" && editorsMode != "comment" && editorsMode != "embedded" && editorsMode != "blockcontent" },
                                { "modifyFilter", editorsMode != "filter" },
                                { "modifyContentControl", editorsMode != "blockcontent" },
                                { "review", canEdit&& (editorsMode == "edit" || editorsMode == "review") },
                                { "reviewGroups", user.reviewGroups },
                                { "commentGroups", user.commentGroups },
                                { "userInfoGroups", user.userInfoGroups }
                            }
                        }
                    }
                },
                {
                    "editorConfig", new Dictionary <string, object>
                    {
                        { "actionLink", actionData },
                        { "mode", mode },
                        { "lang", Request.Cookies.GetOrDefault("ulang", "en") },
                        { "callbackUrl", CallbackUrl },          // absolute URL to the document storage service
                        { "createUrl", !user.id.Equals("uid-0") ? createUrl : null },
                        { "templates", user.templates ? templates : null },
                        {
                            // the user currently viewing or editing the document
                            "user", new Dictionary <string, object>
                            {
                                { "id", !user.id.Equals("uid-0") ? user.id : null },
                                { "name", user.name },
                                { "group", user.group }
                            }
                        },
                        {
                            // the parameters for the embedded document type
                            "embedded", new Dictionary <string, object>
                            {
                                { "saveUrl", FileUriUser },             // the absolute URL that will allow the document to be saved onto the user personal computer
                                { "embedUrl", FileUriUser },            // the absolute URL to the document serving as a source file for the document embedded into the web page
                                { "shareUrl", FileUriUser },            // the absolute URL that will allow other users to share this document
                                { "toolbarDocked", "top" }              // the place for the embedded viewer toolbar (top or bottom)
                            }
                        },
                        {
                            // the parameters for the editor interface
                            "customization", new Dictionary <string, object>
                            {
                                { "about", true },                                               // the About section display
                                { "comments", true },
                                { "feedback", true },                                            // the Feedback & Support menu button display
                                { "forcesave", false },                                          // adds the request for the forced file saving to the callback handler
                                { "submitForm", submitForm },                                    // if the Submit form button is displayed or not
                                {
                                    "goback", new Dictionary <string, object>                    // settings for the Open file location menu button and upper right corner button
                                    {
                                        { "url", _Default.GetServerUrl(false) + "default.aspx" } // the absolute URL to the website address which will be opened when clicking the Open file location menu button
                                    }
                                }
                            }
                        }
                    }
                }
            };

            // if the secret key to generate token exists
            if (JwtManager.Enabled)
            {
                // encode the document config into a token
                var token = JwtManager.Encode(config);
                config.Add("token", token);
            }

            DocConfig = jss.Serialize(config);

            try
            {
                // a logo which will be inserted into the document
                Dictionary <string, object> logoConfig = GetLogoConfig();
                InsertImageConfig = jss.Serialize(logoConfig).Replace("{", "").Replace("}", "");

                // a document which will be compared with the current document
                Dictionary <string, object> compareFile = GetCompareFile();
                CompareFileData = jss.Serialize(compareFile);

                // recipient data for mail merging
                Dictionary <string, object> mailMergeConfig = GetMailMergeConfig();
                DataMailMergeRecipients = jss.Serialize(mailMergeConfig);

                // get users for mentions
                List <Dictionary <string, object> > usersData = Users.getUsersForMentions(user.id);
                UsersForMentions = !user.id.Equals("uid-0") ? jss.Serialize(usersData) : null;

                Dictionary <string, object> hist;
                Dictionary <string, object> histData;

                // get the document history
                GetHistory(out hist, out histData);
                if (hist != null && histData != null)
                {
                    History     = jss.Serialize(hist);
                    HistoryData = jss.Serialize(histData);
                }
            }
            catch { }
        }
        public static void commandRequest(string method, string key)
        {
            string documentCommandUrl = WebConfigurationManager.AppSettings["files.docservice.url.site"] + WebConfigurationManager.AppSettings["files.docservice.url.command"];

            var request = (HttpWebRequest)WebRequest.Create(documentCommandUrl);

            request.Method      = "POST";
            request.ContentType = "application/json";

            var body = new Dictionary <string, object>()
            {
                { "c", method },
                { "key", key }
            };

            if (JwtManager.Enabled)
            {
                var payload = new Dictionary <string, object>
                {
                    { "payload", body }
                };

                var    payloadToken = JwtManager.Encode(payload);
                var    bodyToken    = JwtManager.Encode(body);
                string JWTheader    = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
                request.Headers.Add(JWTheader, "Bearer " + payloadToken);

                body.Add("token", bodyToken);
            }

            var bytes = Encoding.UTF8.GetBytes(new JavaScriptSerializer().Serialize(body));

            request.ContentLength = bytes.Length;
            using (var requestStream = request.GetRequestStream())
            {
                requestStream.Write(bytes, 0, bytes.Length);
            }

            string dataResponse;

            using (var response = request.GetResponse())
                using (var stream = response.GetResponseStream())
                {
                    if (stream == null)
                    {
                        throw new Exception("Response is null");
                    }

                    using (var reader = new StreamReader(stream))
                    {
                        dataResponse = reader.ReadToEnd();
                    }
                }

            var jss         = new JavaScriptSerializer();
            var responseObj = jss.Deserialize <Dictionary <string, object> >(dataResponse);

            if (!responseObj["error"].ToString().Equals("0"))
            {
                throw new Exception(dataResponse);
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            var externalUrl = Request["fileUrl"];

            if (!string.IsNullOrEmpty(externalUrl))
            {
                FileName = _Default.DoUpload(externalUrl, Request);
            }
            else
            {
                FileName = Request["fileID"];
            }

            var type = Request["type"];

            if (!string.IsNullOrEmpty(type))
            {
                Try(type, Request["sample"], Request);
                Response.Redirect("doceditor.aspx?fileID=" + HttpUtility.UrlEncode(FileName));
            }

            var ext = Path.GetExtension(FileName);

            var editorsMode = Request["editorsMode"] ?? "edit";

            var canEdit = _Default.EditedExts.Contains(ext);
            var mode    = canEdit && editorsMode != "view" ? "edit" : "view";

            var config = new Dictionary <string, object>
            {
                { "type", Request["editorsType"] ?? "desktop" },
                { "documentType", _Default.DocumentType(FileName) },
                {
                    "document", new Dictionary <string, object>
                    {
                        { "title", FileName },
                        { "url", FileUri },
                        { "fileType", ext.Trim('.') },
                        { "key", Key },
                        {
                            "info", new Dictionary <string, object>
                            {
                                { "author", "Me" },
                                { "created", DateTime.Now.ToShortDateString() }
                            }
                        },
                        {
                            "permissions", new Dictionary <string, object>
                            {
                                { "comment", editorsMode != "view" && editorsMode != "fillForms" && editorsMode != "embedded" && editorsMode != "blockcontent" },
                                { "download", true },
                                { "edit", canEdit&& (editorsMode == "edit" || editorsMode == "filter") || editorsMode == "blockcontent" },
                                { "fillForms", editorsMode != "view" && editorsMode != "comment" && editorsMode != "embedded" && editorsMode != "blockcontent" },
                                { "modifyFilter", editorsMode != "filter" },
                                { "modifyContentControl", editorsMode != "blockcontent" },
                                { "review", editorsMode == "edit" || editorsMode == "review" }
                            }
                        }
                    }
                },
                {
                    "editorConfig", new Dictionary <string, object>
                    {
                        { "mode", mode },
                        { "lang", Request.Cookies["ulang"]?.Value ?? "en" },
                        { "callbackUrl", CallbackUrl },
                        {
                            "user", new Dictionary <string, object>
                            {
                                { "id", Request.Cookies["uid"]?.Value ?? "uid-1" },
                                { "name", Request.Cookies["uname"]?.Value ?? "John Smith" }
                            }
                        },
                        {
                            "embedded", new Dictionary <string, object>
                            {
                                { "saveUrl", FileUri },
                                { "embedUrl", FileUri },
                                { "shareUrl", FileUri },
                                { "toolbarDocked", "top" }
                            }
                        },
                        {
                            "customization", new Dictionary <string, object>
                            {
                                { "about", true },
                                { "feedback", true },
                                {
                                    "goback", new Dictionary <string, object>
                                    {
                                        { "url", _Default.Host + "default.aspx" }
                                    }
                                }
                            }
                        }
                    }
                }
            };

            if (JwtManager.Enabled)
            {
                var token = JwtManager.Encode(config);
                config.Add("token", token);
            }

            var jss = new JavaScriptSerializer();

            DocConfig = jss.Serialize(config);

            try
            {
                GetHistory(out var hist, out var histData);
                if (hist != null && histData != null)
                {
                    History     = jss.Serialize(hist);
                    HistoryData = jss.Serialize(histData);
                }
            }
            catch { }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            var externalUrl = Request["fileUrl"];

            if (!string.IsNullOrEmpty(externalUrl))
            {
                FileName = _Default.DoUpload(externalUrl, Request);
            }
            else
            {
                FileName = Path.GetFileName(Request["fileID"]);
            }

            var type = Request["type"];

            if (!string.IsNullOrEmpty(type))
            {
                Try(type, Request["sample"], Request);
                Response.Redirect("doceditor.aspx?fileID=" + HttpUtility.UrlEncode(FileName));
            }

            var ext = Path.GetExtension(FileName);

            var editorsMode = Request.GetOrDefault("editorsMode", "edit");

            var canEdit    = _Default.EditedExts.Contains(ext);
            var mode       = canEdit && editorsMode != "view" ? "edit" : "view";
            var submitForm = canEdit && (editorsMode.Equals("edit") || editorsMode.Equals("fillForms"));

            var           userId       = Request.Cookies.GetOrDefault("uid", "uid-1");
            var           uname        = userId.Equals("uid-0") ? null : Request.Cookies.GetOrDefault("uname", "John Smith");
            string        userGroup    = null;
            List <string> reviewGroups = null;

            if (userId.Equals("uid-2"))
            {
                userGroup    = "group-2";
                reviewGroups = new List <string>()
                {
                    "group-2", ""
                };
            }
            if (userId.Equals("uid-3"))
            {
                userGroup    = "group-3";
                reviewGroups = new List <string>()
                {
                    "group-2"
                };
            }

            var jss = new JavaScriptSerializer();

            object favorite = null;

            if (!string.IsNullOrEmpty(Request.Cookies.GetOrDefault("uid", null)))
            {
                favorite = Request.Cookies.GetOrDefault("uid", null).Equals("uid-2");
            }

            var actionLink = Request.GetOrDefault("actionLink", null);
            var actionData = string.IsNullOrEmpty(actionLink) ? null : jss.DeserializeObject(actionLink);

            var config = new Dictionary <string, object>
            {
                { "type", Request.GetOrDefault("editorsType", "desktop") },
                { "documentType", documentType },
                {
                    "document", new Dictionary <string, object>
                    {
                        { "title", FileName },
                        { "url", FileUri },
                        { "fileType", ext.Trim('.') },
                        { "key", Key },
                        {
                            "info", new Dictionary <string, object>
                            {
                                { "owner", "Me" },
                                { "uploaded", DateTime.Now.ToShortDateString() },
                                { "favorite", favorite }
                            }
                        },
                        {
                            "permissions", new Dictionary <string, object>
                            {
                                { "comment", editorsMode != "view" && editorsMode != "fillForms" && editorsMode != "embedded" && editorsMode != "blockcontent" },
                                { "download", true },
                                { "edit", canEdit&& (editorsMode == "edit" || editorsMode == "filter") || editorsMode == "blockcontent" },
                                { "fillForms", editorsMode != "view" && editorsMode != "comment" && editorsMode != "embedded" && editorsMode != "blockcontent" },
                                { "modifyFilter", editorsMode != "filter" },
                                { "modifyContentControl", editorsMode != "blockcontent" },
                                { "review", editorsMode == "edit" || editorsMode == "review" },
                                { "reviewGroups", reviewGroups }
                            }
                        }
                    }
                },
                {
                    "editorConfig", new Dictionary <string, object>
                    {
                        { "actionLink", actionData },
                        { "mode", mode },
                        { "lang", Request.Cookies.GetOrDefault("ulang", "en") },
                        { "callbackUrl", CallbackUrl },
                        {
                            "user", new Dictionary <string, object>
                            {
                                { "id", userId },
                                { "name", uname },
                                { "group", userGroup }
                            }
                        },
                        {
                            "embedded", new Dictionary <string, object>
                            {
                                { "saveUrl", FileUriUser },
                                { "embedUrl", FileUriUser },
                                { "shareUrl", FileUriUser },
                                { "toolbarDocked", "top" }
                            }
                        },
                        {
                            "customization", new Dictionary <string, object>
                            {
                                { "about", true },
                                { "feedback", true },
                                { "forcesave", false },
                                { "submitForm", submitForm },
                                {
                                    "goback", new Dictionary <string, object>
                                    {
                                        { "url", _Default.GetServerUrl(false) + "default.aspx" }
                                    }
                                }
                            }
                        }
                    }
                }
            };

            if (JwtManager.Enabled)
            {
                var token = JwtManager.Encode(config);
                config.Add("token", token);
            }

            DocConfig = jss.Serialize(config);

            try
            {
                Dictionary <string, object> logoConfig = GetLogoConfig();
                InsertImageConfig = jss.Serialize(logoConfig).Replace("{", "").Replace("}", "");

                Dictionary <string, object> compareFile = GetCompareFile();
                compareFileData = jss.Serialize(compareFile);

                Dictionary <string, object> mailMergeConfig = GetMailMergeConfig();
                dataMailMergeRecipients = jss.Serialize(mailMergeConfig);


                Dictionary <string, object> hist;
                Dictionary <string, object> histData;

                GetHistory(out hist, out histData);
                if (hist != null && histData != null)
                {
                    History     = jss.Serialize(hist);
                    HistoryData = jss.Serialize(histData);
                }
            }
            catch { }
        }
        private void GetHistory(out Dictionary <string, object> history, out Dictionary <string, object> historyData)
        {
            var jss     = new JavaScriptSerializer();
            var histDir = _Default.HistoryDir(_Default.StoragePath(FileName, null));

            history     = null;
            historyData = null;

            if (_Default.GetFileVersion(histDir) > 0)
            {
                var currentVersion = _Default.GetFileVersion(histDir);
                var hist           = new List <Dictionary <string, object> >();
                var histData       = new Dictionary <string, object>();

                for (var i = 1; i <= currentVersion; i++)
                {
                    var obj     = new Dictionary <string, object>();
                    var dataObj = new Dictionary <string, object>();
                    var verDir  = _Default.VersionDir(histDir, i);

                    var key = i == currentVersion ? Key : File.ReadAllText(Path.Combine(verDir, "key.txt"));

                    obj.Add("key", key);
                    obj.Add("version", i);

                    if (i == 1)
                    {
                        var infoPath = Path.Combine(histDir, "createdInfo.json");

                        if (File.Exists(infoPath))
                        {
                            var info = jss.Deserialize <Dictionary <string, object> >(File.ReadAllText(infoPath));
                            obj.Add("created", info["created"]);
                            obj.Add("user", new Dictionary <string, object>()
                            {
                                { "id", info["id"] },
                                { "name", info["name"] },
                            });
                        }
                    }

                    dataObj.Add("key", key);
                    dataObj.Add("url", i == currentVersion ? FileUri : MakePublicUrl(Directory.GetFiles(verDir, "prev.*")[0]));
                    dataObj.Add("version", i);
                    if (i > 1)
                    {
                        var changes = jss.Deserialize <Dictionary <string, object> >(File.ReadAllText(Path.Combine(_Default.VersionDir(histDir, i - 1), "changes.json")));
                        var change  = ((Dictionary <string, object>)((ArrayList)changes["changes"])[0]);

                        obj.Add("changes", changes["changes"]);
                        obj.Add("serverVersion", changes["serverVersion"]);
                        obj.Add("created", change["created"]);
                        obj.Add("user", change["user"]);

                        var prev = (Dictionary <string, object>)histData[(i - 2).ToString()];
                        dataObj.Add("previous", new Dictionary <string, object>()
                        {
                            { "key", prev["key"] },
                            { "url", prev["url"] },
                        });
                        dataObj.Add("changesUrl", MakePublicUrl(Path.Combine(_Default.VersionDir(histDir, i - 1), "diff.zip")));
                    }
                    if (JwtManager.Enabled)
                    {
                        var token = JwtManager.Encode(dataObj);
                        dataObj.Add("token", token);
                    }
                    hist.Add(obj);
                    histData.Add((i - 1).ToString(), dataObj);
                }

                history = new Dictionary <string, object>()
                {
                    { "currentVersion", currentVersion },
                    { "history", hist }
                };
                historyData = histData;
            }
        }
        // create a command request
        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);

            request.Method      = "POST";
            request.ContentType = "application/json";

            var body = new Dictionary <string, object>()
            {
                { "c", method },
                { "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 }
                };

                var    payloadToken = JwtManager.Encode(payload);         // encode a payload object into a header token
                var    bodyToken    = JwtManager.Encode(body);            // encode body into a body token
                string JWTheader    = WebConfigurationManager.AppSettings["files.docservice.header"].Equals("") ? "Authorization" : WebConfigurationManager.AppSettings["files.docservice.header"];
                request.Headers.Add(JWTheader, "Bearer " + payloadToken); // add a header Authorization with a header token and Authorization prefix in it

                body.Add("token", bodyToken);
            }

            var bytes = Encoding.UTF8.GetBytes(new JavaScriptSerializer().Serialize(body));

            request.ContentLength = bytes.Length;
            using (var requestStream = request.GetRequestStream())
            {
                // write bytes to the output stream
                requestStream.Write(bytes, 0, bytes.Length);
            }

            string dataResponse;

            using (var response = request.GetResponse())  // get the response
                using (var stream = response.GetResponseStream())
                {
                    if (stream == null)
                    {
                        throw new Exception("Response is null");
                    }

                    using (var reader = new StreamReader(stream))
                    {
                        dataResponse = reader.ReadToEnd(); // and read it
                    }
                }

            // convert stream to json string
            var jss         = new JavaScriptSerializer();
            var responseObj = jss.Deserialize <Dictionary <string, object> >(dataResponse);

            if (!responseObj["error"].ToString().Equals("0"))
            {
                throw new Exception(dataResponse);
            }
        }