From 0960cc55dd9b7d6fb7586a96ddc9c329690e7989 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 5 Jan 2018 15:39:15 +0100 Subject: [PATCH 01/26] Updating to .NET Framework v4.7.1 --- Composite.Workflows/Composite.Workflows.csproj | 2 +- Composite/Composite.csproj | 6 +----- Composite/packages.config | 3 +-- Website/DebugBuild.Web.config | 16 ++-------------- Website/ReleaseBuild.Web.config | 16 ++-------------- Website/WebSite.csproj | 15 ++------------- Website/packages.config | 5 +---- 7 files changed, 10 insertions(+), 53 deletions(-) diff --git a/Composite.Workflows/Composite.Workflows.csproj b/Composite.Workflows/Composite.Workflows.csproj index ccb14bf104..618989f212 100644 --- a/Composite.Workflows/Composite.Workflows.csproj +++ b/Composite.Workflows/Composite.Workflows.csproj @@ -11,7 +11,7 @@ Composite Composite.Workflows {14822709-B5A1-4724-98CA-57A101D1B079};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - v4.6.1 + v4.7.1 512 SAK SAK diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index 357a785b4c..9fe3e9a7a7 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -11,7 +11,7 @@ Composite {14822709-B5A1-4724-98CA-57A101D1B079};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 - v4.6.1 + v4.7.1 SAK SAK SAK @@ -163,10 +163,6 @@ 3.5 - - False - ..\Packages\System.ValueTuple.4.3.0\lib\portable-net40+sl4+win8+wp8\System.ValueTuple.dll - ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll diff --git a/Composite/packages.config b/Composite/packages.config index eb202d024d..74aed868cf 100644 --- a/Composite/packages.config +++ b/Composite/packages.config @@ -1,4 +1,4 @@ - + @@ -18,7 +18,6 @@ - diff --git a/Website/DebugBuild.Web.config b/Website/DebugBuild.Web.config index faf345f6fa..cc15d41f19 100644 --- a/Website/DebugBuild.Web.config +++ b/Website/DebugBuild.Web.config @@ -1,4 +1,4 @@ - + @@ -29,7 +29,7 @@ - + @@ -87,18 +87,6 @@ - - - - - - - - - - - - diff --git a/Website/ReleaseBuild.Web.config b/Website/ReleaseBuild.Web.config index b3b5930b61..c271a9b782 100644 --- a/Website/ReleaseBuild.Web.config +++ b/Website/ReleaseBuild.Web.config @@ -1,4 +1,4 @@ - + @@ -29,7 +29,7 @@ - + @@ -87,18 +87,6 @@ - - - - - - - - - - - - diff --git a/Website/WebSite.csproj b/Website/WebSite.csproj index c2189c3750..8082a72447 100644 --- a/Website/WebSite.csproj +++ b/Website/WebSite.csproj @@ -11,7 +11,7 @@ Library Composite Composite.Website - v4.6.1 + v4.7.1 SAK SAK SAK @@ -28,6 +28,7 @@ + true @@ -116,12 +117,6 @@ False ..\Packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll - - ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll - - - ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll - @@ -2771,7 +2766,6 @@ - + + + $(ProjectDir)git_branch.txt + $(ProjectDir)git_commithash.txt + + + + + $([System.IO.File]::ReadAllText("$(GitBranchFile)").Trim()) + $([System.IO.File]::ReadAllText("$(GitCommitHashFile)").Trim()) + [assembly: System.Reflection.AssemblyInformationalVersion("$(GitBranch). Commit Hash: $(GitCommitHash)")] + + + + + + copy "$(TargetPath)" "$(ProjectDir)..\bin\" copy "$(TargetPath)" "$(ProjectDir)..\Website\bin\" diff --git a/Composite/Composite.csproj b/Composite/Composite.csproj index bdb821f3f8..385e2e52ca 100644 --- a/Composite/Composite.csproj +++ b/Composite/Composite.csproj @@ -253,6 +253,7 @@ + @@ -2667,11 +2668,26 @@ + + + $(ProjectDir)git_branch.txt + $(ProjectDir)git_commithash.txt + + + + + $([System.IO.File]::ReadAllText("$(GitBranchFile)").Trim()) + $([System.IO.File]::ReadAllText("$(GitCommitHashFile)").Trim()) + [assembly: System.Reflection.AssemblyInformationalVersion("$(GitBranch). Commit Hash: $(GitCommitHash)")] + + + + + + copy "$(TargetPath)" "$(ProjectDir)..\bin\" copy "$(TargetPath)" "$(ProjectDir)..\Website\bin\" From 81e385f7beb122857d866fef57bbaa18ee297a0c Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Thu, 1 Mar 2018 11:58:42 +0100 Subject: [PATCH 17/26] Fix #542 Exception in the log files when C1 tries to unpublish a data item that has been previously deleted --- .../Scheduling/DataPublishSchedulerWorkflow.cs | 14 ++++++++++---- .../Scheduling/DataUnpublishSchedulerWorkflow.cs | 16 +++++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Composite.Workflows/C1Console/Scheduling/DataPublishSchedulerWorkflow.cs b/Composite.Workflows/C1Console/Scheduling/DataPublishSchedulerWorkflow.cs index c5fa9e2081..d8506b1756 100644 --- a/Composite.Workflows/C1Console/Scheduling/DataPublishSchedulerWorkflow.cs +++ b/Composite.Workflows/C1Console/Scheduling/DataPublishSchedulerWorkflow.cs @@ -36,8 +36,14 @@ protected override void Execute() var publishSchedule = PublishScheduleHelper.GetPublishSchedule(type, DataId, LocaleName); DataFacade.Delete(publishSchedule); - var data = (IPublishControlled)DataFacade.GetDataByUniqueKey(type, DataId); - Verify.IsNotNull(data, "The data with the id '{0}' does not exist", DataId); + var data = (IPublishControlled)DataFacade.TryGetDataByUniqueKey(type, DataId); + if (data == null) + { + Log.LogWarning(LogTitle, $"Failed to find data of type '{type}' by id '{DataId}'."); + + transaction.Complete(); + return; + } dataEntityToken = data.GetDataEntityToken(); @@ -49,11 +55,11 @@ protected override void Execute() DataFacade.Update(data); - Log.LogVerbose(LogTitle, "Scheduled publishing of data with label '{0}' is complete", data.GetLabel()); + Log.LogVerbose(LogTitle, $"Scheduled publishing of data with label '{data.GetLabel()}' is complete"); } else { - Log.LogWarning(LogTitle, "Scheduled publishing of data with label '{0}' could not be done because the data is not in a publisheble state", data.GetLabel()); + Log.LogWarning(LogTitle, $"Scheduled publishing of data with label '{data.GetLabel()}' could not be done because the data is not in a publisheble state"); } transaction.Complete(); diff --git a/Composite.Workflows/C1Console/Scheduling/DataUnpublishSchedulerWorkflow.cs b/Composite.Workflows/C1Console/Scheduling/DataUnpublishSchedulerWorkflow.cs index d9be03a759..1dedbee6e5 100644 --- a/Composite.Workflows/C1Console/Scheduling/DataUnpublishSchedulerWorkflow.cs +++ b/Composite.Workflows/C1Console/Scheduling/DataUnpublishSchedulerWorkflow.cs @@ -37,10 +37,16 @@ protected override void Execute() DataFacade.Delete(unpublishSchedule); - var deletePublished = false; + var data = (IPublishControlled)DataFacade.TryGetDataByUniqueKey(type, DataId); + if (data == null) + { + Log.LogWarning(LogTitle, $"Failed to find data of type '{type}' by id '{DataId}'."); - var data = (IPublishControlled)DataFacade.GetDataByUniqueKey(type, DataId); - Verify.IsNotNull(data, "The data with the id {0} does not exist", DataId); + transaction.Complete(); + return; + } + + var deletePublished = false; dataEntityToken = data.GetDataEntityToken(); @@ -56,7 +62,7 @@ protected override void Execute() } else { - Log.LogWarning(LogTitle, "Scheduled unpublishing of data with label '{0}' could not be done because the data is not in a unpublisheble state", data.GetLabel()); + Log.LogWarning(LogTitle, $"Scheduled unpublishing of data with label '{data.GetLabel()}' could not be done because the data is not in a unpublisheble state"); } @@ -69,7 +75,7 @@ protected override void Execute() { DataFacade.Delete(deletedData, CascadeDeleteType.Disable); - Log.LogVerbose(LogTitle, "Scheduled unpublishing of data with label '{0}' is complete", deletedData.GetLabel()); + Log.LogVerbose(LogTitle, $"Scheduled unpublishing of data with label '{deletedData.GetLabel()}' is complete"); } } } From 7afa9a729114333fa400567bc35332882a212787 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Thu, 1 Mar 2018 14:28:41 +0100 Subject: [PATCH 18/26] Captcha code refactoring --- .../WebClient/Captcha/CaptchaConfiguration.cs | 75 +++++++++---------- .../Core/WebClient/Captcha/Encryption.cs | 23 ++++-- 2 files changed, 52 insertions(+), 46 deletions(-) diff --git a/Composite/Core/WebClient/Captcha/CaptchaConfiguration.cs b/Composite/Core/WebClient/Captcha/CaptchaConfiguration.cs index ac630c9367..6bdf07258b 100644 --- a/Composite/Core/WebClient/Captcha/CaptchaConfiguration.cs +++ b/Composite/Core/WebClient/Captcha/CaptchaConfiguration.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Xml; using Composite.Core.Extensions; @@ -9,59 +9,54 @@ namespace Composite.Core.WebClient.Captcha internal static class CaptchaConfiguration { private static readonly string CaptchaConfigurationFilePath = @"App_Data\Composite\Configuration\Captcha.xml"; - private static readonly object _syncRoot = new object(); - private static string _password; + public static string Password { get; } - public static string Password + static CaptchaConfiguration() { - get - { - if (_password != null) return _password; - - lock (_syncRoot) - { - if (_password != null) return _password; + string configurationFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, CaptchaConfigurationFilePath); - string configurationFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, CaptchaConfigurationFilePath); + string password = null; - if (C1File.Exists(configurationFilePath)) + if (C1File.Exists(configurationFilePath)) + { + var doc = new XmlDocument(); + try + { + using (var sr = new C1StreamReader(configurationFilePath)) { - var doc = new XmlDocument(); - try - { - using (var sr = new C1StreamReader(configurationFilePath)) - { - doc.Load(sr); - } + doc.Load(sr); + } - var passwordNode = doc.SelectSingleNode("captcha/password"); - if (passwordNode != null && !string.IsNullOrEmpty(passwordNode.InnerText)) - { - _password = passwordNode.InnerText; - } - } - catch (Exception) - { - // Do nothing - } + var passwordNode = doc.SelectSingleNode("captcha/password"); + if (!string.IsNullOrEmpty(passwordNode?.InnerText)) + { + password = passwordNode.InnerText; + } + } + catch (Exception) + { + // Do nothing + } - if (_password != null) return _password; + if (password != null) + { + Password = password; + return; + } - // Deleting configuration file - C1File.Delete(configurationFilePath); - } + // Deleting configuration file + C1File.Delete(configurationFilePath); + } - _password = Guid.NewGuid().ToString(); + password = Guid.NewGuid().ToString(); - string configFile = @" {0} ".FormatWith(_password); + string configFile = @" {0} ".FormatWith(password); - C1File.WriteAllText(configurationFilePath, configFile); + C1File.WriteAllText(configurationFilePath, configFile); - return _password; - } - } + Password = password; } } } diff --git a/Composite/Core/WebClient/Captcha/Encryption.cs b/Composite/Core/WebClient/Captcha/Encryption.cs index dc0eded538..74b7c37748 100644 --- a/Composite/Core/WebClient/Captcha/Encryption.cs +++ b/Composite/Core/WebClient/Captcha/Encryption.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Globalization; using System.IO; using System.Security.Cryptography; @@ -16,19 +16,25 @@ internal static class Encryption static Encryption() { - var md5 = MD5.Create(); - string key = Environment.MachineName + CaptchaConfiguration.Password + HostingEnvironment.ApplicationPhysicalPath; byte[] keyBytes = Encoding.UTF8.GetBytes(key); - _encryptionKey = md5.ComputeHash(keyBytes); + using (var hashAlgorithm = MD5.Create()) + { + _encryptionKey = hashAlgorithm.ComputeHash(keyBytes); + } } public static string Encrypt(string value) { Verify.ArgumentNotNullOrEmpty(value, nameof(value)); + return ByteToHexString(RijndaelEncrypt(value)); + } + + private static byte[] RijndaelEncrypt(string value) + { // Create a RijndaelManaged object // with the specified key and IV. using (var rima = new RijndaelManaged()) @@ -49,7 +55,7 @@ public static string Encrypt(string value) swEncrypt.Write(value); } // Return the encrypted bytes from the memory stream. - return ByteToHexString(msEncrypt.ToArray()); + return msEncrypt.ToArray(); } } } @@ -59,6 +65,11 @@ public static string Decrypt(string encryptedValue) Verify.ArgumentNotNullOrEmpty(encryptedValue, nameof(encryptedValue)); byte[] encodedSequence = HexStringToByteArray(encryptedValue); + return RijndaelDecrypt(encodedSequence); + } + + private static string RijndaelDecrypt(byte[] bytes) + { using (var rima = new RijndaelManaged()) { rima.Key = _encryptionKey; @@ -68,7 +79,7 @@ public static string Decrypt(string encryptedValue) ICryptoTransform decryptor = rima.CreateDecryptor(); // Create the streams used for decryption. - using (var msDecrypt = new MemoryStream(encodedSequence)) + using (var msDecrypt = new MemoryStream(bytes)) using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) using (var srDecrypt = new C1StreamReader(csDecrypt)) { From 47888e20302d1a41d6db0eea1731db8088bb3046 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Thu, 1 Mar 2018 14:32:09 +0100 Subject: [PATCH 19/26] Not using Environment.MachineName as a part of Captcha encryption key --- Composite/Core/WebClient/Captcha/Encryption.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Composite/Core/WebClient/Captcha/Encryption.cs b/Composite/Core/WebClient/Captcha/Encryption.cs index 74b7c37748..d725a15898 100644 --- a/Composite/Core/WebClient/Captcha/Encryption.cs +++ b/Composite/Core/WebClient/Captcha/Encryption.cs @@ -3,7 +3,7 @@ using System.IO; using System.Security.Cryptography; using System.Text; -using System.Web.Hosting; +using Composite.Core.Configuration; using Composite.Core.IO; @@ -16,7 +16,7 @@ internal static class Encryption static Encryption() { - string key = Environment.MachineName + CaptchaConfiguration.Password + HostingEnvironment.ApplicationPhysicalPath; + string key = InstallationInformationFacade.InstallationId + CaptchaConfiguration.Password; byte[] keyBytes = Encoding.UTF8.GetBytes(key); From 361524b875ed9a3364f1ab0e068706a3f54591e7 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 2 Mar 2018 11:36:12 +0100 Subject: [PATCH 20/26] Updating references to previous company name --- .../tinymce/plugins/compositecharmap/plugin.min.js | 6 +++--- .../tinymce/plugins/compositecomponent/plugin.min.js | 6 +++--- .../tinymce/plugins/compositefield/plugin.min.js | 4 ++-- .../tinymce/plugins/compositeimage/plugin.min.js | 4 ++-- .../tinymce/plugins/compositelink/plugin.min.js | 4 ++-- .../tinymce/plugins/compositeplugin/plugin.min.js | 4 ++-- .../tinymce/plugins/compositerendering/plugin.min.js | 4 ++-- .../tinymce/plugins/compositespellcheck/plugin.min.js | 6 +++--- .../tinymce/plugins/compositetable/plugin.min.js | 4 ++-- .../tinymce/plugins/compositetext/plugin.min.js | 4 ++-- .../visualeditor/tinymce/themes/composite/theme.min.js | 4 ++-- license.txt | 4 ++-- 12 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecharmap/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecharmap/plugin.min.js index 22fda69c3a..563452e05b 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecharmap/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecharmap/plugin.min.js @@ -17,9 +17,9 @@ new function () { */ getInfo : function() { return { - longname : "Composite Character Map Plugin", - author : "Composite A/S", - authorurl : "http://www.composite.net", + longname: "Orckestra Character Map Plugin", + author : "Orckestra A/S", + authorurl : "https://c1.orckestra.com/", infourl : null, version : tinymce.majorVersion + "." + tinymce.minorVersion }; diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecomponent/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecomponent/plugin.min.js index 8f55fbf268..9e80e6f8a3 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecomponent/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositecomponent/plugin.min.js @@ -1,4 +1,4 @@ -/** +/** * Composite plugin. */ new function () { @@ -23,8 +23,8 @@ new function () { getInfo: function () { return { longname: "Composite Component Plugin", - author: "Composite A/S", - authorurl: "http://www.composite.net", + author: "Orckestra A/S", + authorurl: "https://c1.orckestra.com/", infourl: null, version: tinymce.majorVersion + "." + tinymce.minorVersion }; diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositefield/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositefield/plugin.min.js index eaa1d522df..8e4e81c38a 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositefield/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositefield/plugin.min.js @@ -16,8 +16,8 @@ new function () { getInfo : function() { return { longname : "Composite Field Plugin", - author : "Composite A/S", - authorurl : "http://www.composite.net", + author : "Orckestra A/S", + authorurl : "https://c1.orckestra.com/", infourl : null, version : tinymce.majorVersion + "." + tinymce.minorVersion }; diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositeimage/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositeimage/plugin.min.js index 9b01d21e71..bd2ca783bd 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositeimage/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositeimage/plugin.min.js @@ -25,8 +25,8 @@ new function () { getInfo: function () { return { longname: "Composite Image Plugin", - author: "Composite A/S", - authorurl: "http://www.composite.net", + author: "Orckestra A/S", + authorurl: "https://c1.orckestra.com/", infourl: null, version: tinymce.majorVersion + "." + tinymce.minorVersion }; diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositelink/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositelink/plugin.min.js index 683f58fd43..998dc0626e 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositelink/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositelink/plugin.min.js @@ -10,8 +10,8 @@ new function () { getInfo : function() { return { longname : "Composite Link", - author : "Composite A/S", - authorurl : "http://www.composite.net", + author : "Orckestra A/S", + authorurl : "https://c1.orckestra.com/", infourl : null, version : tinymce.majorVersion + "." + tinymce.minorVersion }; diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositeplugin/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositeplugin/plugin.min.js index a4018c0bb5..8e3b49a604 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositeplugin/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositeplugin/plugin.min.js @@ -16,8 +16,8 @@ new function () { getInfo : function() { return { longname : "Composite Plugin", - author : "Composite A/S", - authorurl : "http://www.composite.net", + author : "Orckestra A/S", + authorurl : "https://c1.orckestra.com/", infourl : null, version : tinymce.majorVersion + "." + tinymce.minorVersion }; diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositerendering/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositerendering/plugin.min.js index 80da63c18b..971ef9a8af 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositerendering/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositerendering/plugin.min.js @@ -59,8 +59,8 @@ new function () { getInfo: function () { return { longname: "Composite Rendering Plugin", - author: "Composite A/S", - authorurl: "http://www.composite.net", + author: "Orckestra A/S", + authorurl: "https://c1.orckestra.com/", infourl: null, version: tinymce.majorVersion + "." + tinymce.minorVersion }; diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositespellcheck/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositespellcheck/plugin.min.js index 1e7bf9437b..1df85e262a 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositespellcheck/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositespellcheck/plugin.min.js @@ -1,4 +1,4 @@ -/** +/** * Composite plugin. This plugin does nothing, it is simply a template. */ new function () { @@ -16,8 +16,8 @@ new function () { getInfo: function () { return { longname: "Composite SpellCheck", - author: "Composite A/S", - authorurl: "http://www.composite.net", + author: "Orckestra A/S", + authorurl: "https://c1.orckestra.com/", infourl: null, version: tinymce.majorVersion + "." + tinymce.minorVersion }; diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositetable/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositetable/plugin.min.js index 77f4cab0ab..37424d8b82 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositetable/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositetable/plugin.min.js @@ -28,8 +28,8 @@ new function () { getInfo: function () { return { longname: "Composite Table Plugin", - author: "Composite A/S", - authorurl: "http://www.composite.net", + author: "Orckestra A/S", + authorurl: "https://c1.orckestra.com/", infourl: null, version: tinymce.majorVersion + "." + tinymce.minorVersion }; diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositetext/plugin.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositetext/plugin.min.js index 50623f8891..99270f97b4 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositetext/plugin.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/plugins/compositetext/plugin.min.js @@ -18,8 +18,8 @@ new function () { getInfo : function() { return { longname : "Composite Text Plugin", - author : "Composite A/S", - authorurl : "http://www.composite.net", + author : "Orckestra A/S", + authorurl : "https://c1.orckestra.com/", infourl : null, version : tinymce.majorVersion + "." + tinymce.minorVersion }; diff --git a/Website/Composite/content/misc/editors/visualeditor/tinymce/themes/composite/theme.min.js b/Website/Composite/content/misc/editors/visualeditor/tinymce/themes/composite/theme.min.js index d577c4b2f5..cfc0222d1a 100644 --- a/Website/Composite/content/misc/editors/visualeditor/tinymce/themes/composite/theme.min.js +++ b/Website/Composite/content/misc/editors/visualeditor/tinymce/themes/composite/theme.min.js @@ -36,8 +36,8 @@ new function () { this.getInfo = function() { return { longname : 'Composite theme', - author : 'Composite A/S', - authorurl : 'http://www.composite.net', + author : 'Orckestra A/S', + authorurl : 'https://c1.orckestra.com/', version : tinymce.majorVersion + "." + tinymce.minorVersion } } diff --git a/license.txt b/license.txt index 2b6efb52b7..a7f374de33 100644 --- a/license.txt +++ b/license.txt @@ -7,10 +7,10 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is owned by and the Initial Developer of the Original Code is -Composite A/S (Danish business reg.no. 21744409). All Rights Reserved +Orckestra A/S (Danish business reg.no. 21744409). All Rights Reserved Section 11 of the License is EXPRESSLY amended to include a provision stating that any dispute, including but not limited to disputes related to the enforcement -of the License, to which Composite A/S as owner of the Original Code, as Initial +of the License, to which Orckestra A/S as owner of the Original Code, as Initial Developer or in any other role, becomes a part to shall be governed by Danish law and be initiated before the Copenhagen City Court ("Københavns Byret") From 0d48d4efeed350177c2cd89d46125da86a8875e4 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 2 Mar 2018 11:39:30 +0100 Subject: [PATCH 21/26] "C1CMS.Assemblies" NuGet package now requires .NET 4.7.1 --- Package.nuspec | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Package.nuspec b/Package.nuspec index 9d74c8761c..6054b350dd 100644 --- a/Package.nuspec +++ b/Package.nuspec @@ -12,7 +12,7 @@ true Contains dll-s distributed with C1 CMS. - Copyright 2017 + Copyright 2018 C1CMS OrckestraCMS CompositeC1 cms @@ -22,15 +22,15 @@ - - - - - - - + + + + + + + - - + + From 2d7b34446b250fb80bbf5b0c0bf94b4b01cf83e5 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 2 Mar 2018 14:01:54 +0100 Subject: [PATCH 22/26] DataPackageFragmentInstaller - fixing a recently introduced setup error --- .../DataPackageFragmentInstaller.cs | 63 +++++++++++++------ 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/Composite/Core/PackageSystem/PackageFragmentInstallers/DataPackageFragmentInstaller.cs b/Composite/Core/PackageSystem/PackageFragmentInstallers/DataPackageFragmentInstaller.cs index 59feecc625..38d299cb77 100644 --- a/Composite/Core/PackageSystem/PackageFragmentInstallers/DataPackageFragmentInstaller.cs +++ b/Composite/Core/PackageSystem/PackageFragmentInstallers/DataPackageFragmentInstaller.cs @@ -32,6 +32,8 @@ public sealed class DataPackageFragmentInstaller : BasePackageFragmentInstaller private List _validationResult; private Dictionary _dataKeysToBeInstalled; + private Dictionary _dataKeysToBeInstalledByTypeId; + private Dictionary>> _missingDataReferences; private static Dictionary _pageVersionIds = new Dictionary(); @@ -41,6 +43,7 @@ public override IEnumerable Validate() { _validationResult = new List(); _dataKeysToBeInstalled = new Dictionary(); + _dataKeysToBeInstalledByTypeId = new Dictionary(); _missingDataReferences = new Dictionary>>(); if (this.Configuration.Count(f => f.Name == "Types") > 1) @@ -597,7 +600,7 @@ private void ValidateNonDynamicAddedType(DataType dataType) } - RegisterKeyToBeAdded(dataType, dataKeyPropertyCollection); + RegisterKeyToBeAdded(dataType, null, dataKeyPropertyCollection); // Checking foreign key references foreach (var foreignKeyProperty in DataAttributeFacade.GetDataReferenceProperties(dataType.InterfaceType)) @@ -632,16 +635,24 @@ private void CheckForBrokenReference(DataType refereeType, Type type, string pro // Checking key in the keys to be installed var keyValuePair = new KeyValuePair(keyPropertyName, referenceKey); - if (_missingDataReferences.ContainsKey(referredType) && _missingDataReferences[referredType].Contains(keyValuePair)) + if (_missingDataReferences.TryGetValue(referredType, out var refs) && refs.Contains(keyValuePair)) { return; } - if (_dataKeysToBeInstalled.ContainsKey(referredType) && _dataKeysToBeInstalled[referredType].KeyRegistered(refereeType, keyValuePair)) + if (_dataKeysToBeInstalled.TryGetValue(referredType, out var keys) + && keys.KeyRegistered(refereeType, keyValuePair)) { return; } + var typeId = referredType.GetImmutableTypeId(); + if (_dataKeysToBeInstalledByTypeId.TryGetValue(typeId, out var dynamicTypeKeys) + && dynamicTypeKeys.KeyRegistered(refereeType, keyValuePair)) + { + return; + } + using (GetDataScopeFromDataTypeElement(refereeType)) { if (DataFacade.TryGetDataByUniqueKey(type, propertyValue) == null) @@ -705,13 +716,26 @@ private DataScope GetDataScopeFromDataTypeElement(DataType dataType) return new DataScope(dataType.DataScopeIdentifier, locale); } - private void RegisterKeyToBeAdded(DataType dataType, DataKeyPropertyCollection dataKeyPropertyCollection) + + + private void RegisterKeyToBeAdded(DataType dataType, DataTypeDescriptor dataTypeDescriptor, DataKeyPropertyCollection dataKeyPropertyCollection) { if (dataKeyPropertyCollection.Count != 1) return; + TypeKeyInstallationData typeKeyInstallationData; - var typeKeyInstallationData = _dataKeysToBeInstalled.GetOrAdd(dataType.InterfaceType, + if (dataType.InterfaceType != null) + { + // Static types + typeKeyInstallationData = _dataKeysToBeInstalled.GetOrAdd(dataType.InterfaceType, () => new TypeKeyInstallationData(dataType.InterfaceType)); + } + else + { + // Dynamic types + typeKeyInstallationData = _dataKeysToBeInstalledByTypeId.GetOrAdd(dataTypeDescriptor.DataTypeId, + () => new TypeKeyInstallationData(dataTypeDescriptor)); + } var keyValuePair = dataKeyPropertyCollection.KeyProperties.First(); @@ -791,7 +815,7 @@ private void ValidateDynamicAddedType(DataType dataType) // TODO: implement check if the same key has already been added } - RegisterKeyToBeAdded(dataType, dataKeyPropertyCollection); + RegisterKeyToBeAdded(dataType, dataTypeDescriptor, dataKeyPropertyCollection); // Checking foreign key references foreach (var referenceField in dataTypeDescriptor.Fields.Where(f => f.ForeignKeyReferenceTypeName != null)) @@ -799,8 +823,8 @@ private void ValidateDynamicAddedType(DataType dataType) object propertyValue; if (!fieldValues.TryGetValue(referenceField.Name, out propertyValue) || propertyValue == null - || (propertyValue is Guid && (Guid)propertyValue == Guid.Empty) - || propertyValue is string && (string)propertyValue == "") + || (propertyValue is Guid guid && guid == Guid.Empty) + || (propertyValue is string str && str == "")) { continue; } @@ -857,21 +881,29 @@ private sealed class DataType /// /// Information about data keys to be installed for a given data type /// - [DebuggerDisplay("TypeKeyInstallationData {_type.FullName} . DataScopes: {_dataScopes.Count}")] + [DebuggerDisplay("TypeKeyInstallationData {_typeName} . DataScopes: {_dataScopes.Count}")] private class TypeKeyInstallationData { private const string AllLocalesKey = "all"; private readonly bool _isLocalized; private readonly bool _isPublishable; - private readonly Type _type; + private readonly string _typeName; + private readonly Dictionary>> _dataScopes = new Dictionary>>(); public TypeKeyInstallationData(Type type) { _isLocalized = DataLocalizationFacade.IsLocalized(type); _isPublishable = typeof(IPublishControlled).IsAssignableFrom(type); - _type = type; + _typeName = type.FullName; + } + + public TypeKeyInstallationData(DataTypeDescriptor typeDescriptor) + { + _isLocalized = typeDescriptor.SuperInterfaces.Contains(typeof(ILocalizedControlled)); + _isPublishable = typeDescriptor.SuperInterfaces.Contains(typeof(IPublishControlled)); + _typeName = typeDescriptor.Name; } public void RegisterKeyUsage(DataType dataType, KeyValuePair keyValuePair) @@ -909,15 +941,10 @@ private void RegisterKeyUsage(DataType dataType, string localeName, DataScopeIde { string dataScopeKey = GetDataScopeKey(publicationScope, localeName); - if (!_dataScopes.ContainsKey(dataScopeKey)) - { - _dataScopes.Add(dataScopeKey, new HashSet>()); - } - - var hashset = _dataScopes[dataScopeKey]; + var hashset = _dataScopes.GetOrAdd(dataScopeKey, () => new HashSet>()); Verify.That(!hashset.Contains(keyValuePair), "Item with the same key present twice. Data type: '{0}', field '{1}', value '{2}'", - dataType.InterfaceTypeName ?? "null", keyValuePair.Key, keyValuePair.Value ?? "null"); + dataType.InterfaceTypeName ?? dataType.InterfaceTypeName ?? "null", keyValuePair.Key, keyValuePair.Value ?? "null"); hashset.Add(keyValuePair); } From f3647172ea75f26aff558f313adde69ca10a9d34 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Fri, 2 Mar 2018 16:30:27 +0100 Subject: [PATCH 23/26] Fixing Nightwatch tests --- Website/test/e2e/pageObjects/startScreen.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Website/test/e2e/pageObjects/startScreen.js b/Website/test/e2e/pageObjects/startScreen.js index 2784e99943..b2e0dd0bae 100644 --- a/Website/test/e2e/pageObjects/startScreen.js +++ b/Website/test/e2e/pageObjects/startScreen.js @@ -18,6 +18,8 @@ module.exports = { }, close: function () { this.enter(); + this.waitForElementVisible('@closeButton', this.api.globals.timeouts.basic); + this.api.pause(1000); this.click('@closeButton'); } } From 8c9649dfb6e1706e62c99a625c56ffa1937d7eab Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 5 Mar 2018 13:25:01 +0100 Subject: [PATCH 24/26] Fixing Nightwatch tests --- Website/test/e2e/.editorconfig | 3 +++ Website/test/e2e/commands/installLocale.js | 8 +++---- Website/test/e2e/commands/uninstallLocale.js | 5 ++--- Website/test/e2e/pageObjects/content.js | 22 +++++++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 Website/test/e2e/.editorconfig diff --git a/Website/test/e2e/.editorconfig b/Website/test/e2e/.editorconfig new file mode 100644 index 0000000000..0b588114af --- /dev/null +++ b/Website/test/e2e/.editorconfig @@ -0,0 +1,3 @@ +[*.js] +indent_style = tab +indent_size = 2 \ No newline at end of file diff --git a/Website/test/e2e/commands/installLocale.js b/Website/test/e2e/commands/installLocale.js index 610f9b7cc3..58093501dc 100644 --- a/Website/test/e2e/commands/installLocale.js +++ b/Website/test/e2e/commands/installLocale.js @@ -5,19 +5,19 @@ function InstallLocale() { } InstallLocale.prototype.command = function (language, code) { - - this.client.api + + this.client.api .selectPerspective("System") .selectTreeNodeAction("Languages", "Add Language") .clickDataBySibilings("Languages") .clickLabel(language) .assertFieldValue(null, "URL mapping name", code) .clickDialogButton("OK") - + .waitForElementNotVisible("#mastercover", this.api.globals.timeouts.loading) .openTreeNode("Languages") .assertTreeNodeHasChild("Languages", language) .refresh() - + return this.client.api; }; diff --git a/Website/test/e2e/commands/uninstallLocale.js b/Website/test/e2e/commands/uninstallLocale.js index 286bd8a00b..adbb3c4067 100644 --- a/Website/test/e2e/commands/uninstallLocale.js +++ b/Website/test/e2e/commands/uninstallLocale.js @@ -5,13 +5,12 @@ function InstallLocale() { } InstallLocale.prototype.command = function (language) { - - this.client.api + this.client.api .selectPerspective("System") .openTreeNode("Languages") .selectTreeNodeAction(language, "Remove Language") .clickDialogButton("OK") - + .waitForElementNotVisible("#mastercover", this.api.globals.timeouts.loading) .openTreeNode("Languages") .assertTreeNodeHasNoChild("Languages", language) diff --git a/Website/test/e2e/pageObjects/content.js b/Website/test/e2e/pageObjects/content.js index b69a1bb663..09801dbb4a 100644 --- a/Website/test/e2e/pageObjects/content.js +++ b/Website/test/e2e/pageObjects/content.js @@ -18,20 +18,28 @@ module.exports = { commands: [ { enter: function (perspective) { - perspective = perspective || "Content"; // for backward compatibility + perspective = perspective || "Content"; // for backward compatibility + + var perspectiveButton = '#explorer explorertoolbarbutton[label="'+perspective+'"]'; + var perspectiveFrame = '#stagedecks stagedeck[data-qa*="'+perspective+'"] iframe'; + this.api.page.appWindow() .enter() - .waitForElementNotPresent('dialogcover[hidden="true"]', this.api.globals.timeouts.basic) - .waitForElementPresent('#explorer explorertoolbarbutton[label="'+perspective+'"]', this.api.globals.timeouts.basic) - .click('#explorer explorertoolbarbutton[label="'+perspective+'"]') - .waitForFrameLoad('#stagedecks stagedeck[data-qa*="'+perspective+'"] iframe', this.api.globals.timeouts.basic) - .enterFrame('#stagedecks stagedeck[data-qa*="'+perspective+'"] iframe'); + .waitForElementNotPresent('dialogcover[hidden="true"]', this.api.globals.timeouts.basic); + + this.api.pause(1000); + + this.api.page.appWindow() + .waitForElementPresent(perspectiveButton, this.api.globals.timeouts.basic) + .click(perspectiveButton) + .waitForFrameLoad(perspectiveFrame, this.api.globals.timeouts.basic) + .enterFrame(perspectiveFrame); return this; }, enterActivePerspective: function () { this.api.page.appWindow() .enter() - .enterFrame('#stagedecks stagedeck[selected="true"] iframe'); + .enterFrame('#stagedecks stagedeck[selected="true"] iframe'); return this; }, prepare: function (perspective) { From 1d6ccb7d843e741c8e28fe4c56f4cc8417ec0145 Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 5 Mar 2018 13:34:03 +0100 Subject: [PATCH 25/26] Updating version moniker to 6.4 --- Composite/Properties/SharedAssemblyInfo.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Composite/Properties/SharedAssemblyInfo.cs b/Composite/Properties/SharedAssemblyInfo.cs index d6d0f99ded..10265634b6 100644 --- a/Composite/Properties/SharedAssemblyInfo.cs +++ b/Composite/Properties/SharedAssemblyInfo.cs @@ -2,9 +2,9 @@ // General Information about the assemblies Composite and Composite.Workflows #if !InternalBuild -[assembly: AssemblyTitle("C1 CMS 6.3")] +[assembly: AssemblyTitle("C1 CMS 6.4")] #else -[assembly: AssemblyTitle("C1 CMS 6.3 (Internal Build)")] +[assembly: AssemblyTitle("C1 CMS 6.4 (Internal Build)")] #endif [assembly: AssemblyCompany("Orckestra Inc")] @@ -13,4 +13,4 @@ [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("6.3.*")] +[assembly: AssemblyVersion("6.4.*")] From 264704ee7a94f3a8b71adf3b868b09b32203194f Mon Sep 17 00:00:00 2001 From: Dmitry Dzygin Date: Mon, 5 Mar 2018 14:23:04 +0100 Subject: [PATCH 26/26] Making a nightwatch test more stable --- Website/test/e2e/commands/installLocale.js | 2 +- Website/test/e2e/commands/uninstallLocale.js | 4 ++-- Website/test/e2e/commands/waitForDialogClosed.js | 13 +++++++++++++ .../UploadAndExtractZip.js | 4 +++- 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 Website/test/e2e/commands/waitForDialogClosed.js diff --git a/Website/test/e2e/commands/installLocale.js b/Website/test/e2e/commands/installLocale.js index 58093501dc..9428ee3e7b 100644 --- a/Website/test/e2e/commands/installLocale.js +++ b/Website/test/e2e/commands/installLocale.js @@ -13,7 +13,7 @@ InstallLocale.prototype.command = function (language, code) { .clickLabel(language) .assertFieldValue(null, "URL mapping name", code) .clickDialogButton("OK") - .waitForElementNotVisible("#mastercover", this.api.globals.timeouts.loading) + .waitForDialogClosed(this.api.globals.timeouts.loading) .openTreeNode("Languages") .assertTreeNodeHasChild("Languages", language) .refresh() diff --git a/Website/test/e2e/commands/uninstallLocale.js b/Website/test/e2e/commands/uninstallLocale.js index adbb3c4067..619ab74201 100644 --- a/Website/test/e2e/commands/uninstallLocale.js +++ b/Website/test/e2e/commands/uninstallLocale.js @@ -10,10 +10,10 @@ InstallLocale.prototype.command = function (language) { .openTreeNode("Languages") .selectTreeNodeAction(language, "Remove Language") .clickDialogButton("OK") - .waitForElementNotVisible("#mastercover", this.api.globals.timeouts.loading) + .waitForDialogClosed(this.api.globals.timeouts.loading) .openTreeNode("Languages") .assertTreeNodeHasNoChild("Languages", language) - + return this.client.api; }; diff --git a/Website/test/e2e/commands/waitForDialogClosed.js b/Website/test/e2e/commands/waitForDialogClosed.js new file mode 100644 index 0000000000..2545198878 --- /dev/null +++ b/Website/test/e2e/commands/waitForDialogClosed.js @@ -0,0 +1,13 @@ +var events = require('events'); + +function WaitForDialogClosed() { + events.EventEmitter.call(this); +} + +WaitForDialogClosed.prototype.command = function (timeout) { + timeout = timeout || this.api.globals.timeouts.basic; + this.client.api.waitForElementNotVisible("#mastercover", timeout); + return this.client.api; +}; + +module.exports = WaitForDialogClosed; \ No newline at end of file diff --git a/Website/test/e2e/suite/website-zip-upload-extract/UploadAndExtractZip.js b/Website/test/e2e/suite/website-zip-upload-extract/UploadAndExtractZip.js index 8f3ec7ac63..d01778b8fb 100644 --- a/Website/test/e2e/suite/website-zip-upload-extract/UploadAndExtractZip.js +++ b/Website/test/e2e/suite/website-zip-upload-extract/UploadAndExtractZip.js @@ -12,18 +12,20 @@ module.exports = { .selectTreeNodeAction("/", "New Folder") .setFieldValue("Folder name", "ZipTest") .clickDialogButton("OK") + .waitForDialogClosed() .selectPerspective("System") .selectTreeNodeAction("ZipTest", "Upload and Extract Zip", "Upload File") .setFileFieldValue("Zip file", require('path').resolve(__dirname + '/test.zip')) .clickDialogButton("OK") + .waitForDialogClosed() .openTreeNode("ZipTest") .assertTreeNodeHasChild("ZipTest", "root.txt") .openTreeNode("subdir1") .openTreeNode("subdir2") .assertTreeNodeHasChild("subdir2", "simple.txt") - .selectTreeNodeAction("ZipTest","Delete Folder") .clickDialogButton("OK") + .waitForDialogClosed() .assertTreeNodeHasNoChild("/", "ZipTest") }, afterEach: function (browser, done) {