diff --git a/.github/BUILD.md b/.github/BUILD.md
index 54d53275e77..de6e0aa3a5c 100644
--- a/.github/BUILD.md
+++ b/.github/BUILD.md
@@ -7,7 +7,8 @@ There are three supported build scenarios:
2. **Build to create a local DNN development website**. You'd typically not do this all the time, but only when you wish to set up a new development site or revert your development website to the current DNN repository state.
3. **Debug build**. You'd use this when changing code and testing your changes on your (previously created) development site. Note you can also "rebuild" just a part of the platform and not the entire solution for this which will speed things up for you.
-When contributing to DNN, you'd typically go through steps 2 and 3 at least and maybe 1 if you wish to run more encompassing tests. But before you delve into code, please familiarize yourself with [How to Contribute](CONTRIBUTING.md) first.
+When contributing to DNN, you'd typically go through steps 2 and 3 at least and maybe 1 if you wish to run more encompassing tests. But before you delve into code, please familiarize yourself with [How to Contribute](/CONTRIBUTING.md) first.
+
## External sources
diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md
deleted file mode 100644
index 6ec06df1381..00000000000
--- a/.github/ISSUE_TEMPLATE/bug-report.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-name: Bug Report
-about: Report a bug in DNN Platform
-labels: "Status: New"
-assignees: dnnsoftware/triage
----
-
-## Description of bug
-Provide a clear and concise description of the bug.
-
-## Steps to reproduce
-List the precise steps to reproduce the bug:
-1. Go to '...'
-2. Click on '....'
-3. Scroll to '....'
-4. See error
-
-## Current behavior
-Explain the current behavior.
-
-## Expected behavior
-Provide a clear and concise description of the expected behavior.
-
-## Screenshots
-If applicable, provide screenshots to help explain the bug.
-
-## Error information
-Provide any error information (console errors, error logs, etc.) related to this bug.
-
-## Additional context
-Provide any additional context that may be helpful in understanding and/or resolving the bug.
-
-## Affected version
-
-* [ ] 10.00.00 alpha build
-* [ ] 09.11.01 latest supported release
-
-## Affected browser
-
-* [ ] Chrome
-* [ ] Firefox
-* [ ] Safari
-* [ ] Internet Explorer 11
-* [ ] Microsoft Edge (Classic)
-* [ ] Microsoft Edge Chromium
diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
new file mode 100644
index 00000000000..feb074b2a7d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -0,0 +1,95 @@
+name: Bug Report
+description: Report a bug
+title: "[Bug]: "
+labels: ["Status: New"]
+assignees:
+ - dnnsoftware/triage
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to fill out this bug report!
+ - type: checkboxes
+ attributes:
+ label: Is there an existing issue for this?
+ description: Please search to see if an issue already exists for the bug you encountered.
+ options:
+ - label: I have searched the existing issues
+ required: true
+ - type: textarea
+ id: what-happened
+ attributes:
+ label: What happened?
+ description: Also tell us, what did you expect to happen?
+ placeholder: Tell us what you see! "A bug happened, but I was expecting this!"
+ validations:
+ required: true
+ - type: textarea
+ id: steps-to-reproduce
+ attributes:
+ label: Steps to reproduce?
+ description: List the precise steps to reproduce the bug.
+ placeholder: |
+ 1. Go to '...'
+ 2. Click on '...'
+ 3. Scroll to '...'
+ 4. See error...
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Current Behavior
+ description: A concise description of what you're experiencing.
+ validations:
+ required: false
+ - type: textarea
+ attributes:
+ label: Expected Behavior
+ description: A concise description of what you expected to happen.
+ validations:
+ required: false
+ - type: textarea
+ id: logs
+ attributes:
+ label: Relevant log output
+ description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
+ render: shell
+ - type: textarea
+ id: anything-else
+ attributes:
+ label: Anything else?
+ description: |
+ Links? References? Anything that will give us more context about the issue you are encountering!
+
+ Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
+ validations:
+ required: false
+ - type: dropdown
+ id: affected-versions
+ attributes:
+ label: Affected Versions
+ description: What versions of DNN are you running?
+ multiple: true
+ options:
+ - 10.0.0 (alpha)
+ - 9.11.2 (latest release)
+ validations:
+ required: true
+ - type: dropdown
+ id: affected-browsers
+ attributes:
+ label: What browsers are you seeing the problem on?
+ multiple: true
+ options:
+ - Firefox
+ - Chrome
+ - Safari
+ - Microsoft Edge
+ - type: checkboxes
+ id: terms
+ attributes:
+ label: Code of Conduct
+ description: By submitting this issue, you agree to follow our [Code of Conduct](/CODE_OF_CONDUCT.md)
+ options:
+ - label: I agree to follow this project's Code of Conduct
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/enhancement-request.md b/.github/ISSUE_TEMPLATE/enhancement-request.md
deleted file mode 100644
index 9897fd6162d..00000000000
--- a/.github/ISSUE_TEMPLATE/enhancement-request.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-name: Enhancement Request
-about: Request an enhancement to DNN Platform
-labels: "Status: New"
-assignees: dnnsoftware/triage
----
-
-## Description of problem
-Is your enhancement request related to a problem? Provide a clear and concise description of the problem.
-
-## Description of solution
-Provide a clear and concise description of the solution.
-
-## Description of alternatives considered
-Provide a clear and concise description of any alternative solutions considered.
-
-## Screenshots
-If applicable, provide screenshots to help explain the problem and/or enhancement.
-
-## Additional context
-Add any other context about the enhancement that may be helpful with implementation.
-
-## Affected browser
-
-* [ ] Chrome
-* [ ] Firefox
-* [ ] Safari
-* [ ] Internet Explorer
-* [ ] Edge
diff --git a/.github/ISSUE_TEMPLATE/enhancement-request.yml b/.github/ISSUE_TEMPLATE/enhancement-request.yml
new file mode 100644
index 00000000000..0d1cf721f59
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/enhancement-request.yml
@@ -0,0 +1,74 @@
+name: Enhancement Request
+description: Make an enhancement request
+title: "[Enhancement]: "
+labels: ["Status: New"]
+assignees:
+ - dnnsoftware/triage
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to fill out this enhancement request!
+ - type: checkboxes
+ id: existing-issue
+ attributes:
+ label: Is there an existing issue for this?
+ description: Please search to see if an issue already exists for the bug you encountered.
+ options:
+ - label: I have searched the existing issues
+ required: true
+ - type: textarea
+ id: description-of-problem
+ attributes:
+ label: Description of problem
+ description: Is your enhancement request related to a problem? Provide a clear and concise description of the problem.
+ validations:
+ required: true
+ - type: textarea
+ id: description-of-solution
+ attributes:
+ label: Description of solution
+ description: Provide a clear and concise description of the solution.
+ validations:
+ required: true
+ - type: textarea
+ id: alternatives-considered
+ attributes:
+ label: Description of alternatives considered
+ description: Provide a clear and concise description of any alternative solutions considered.
+ validations:
+ required: false
+ - type: textarea
+ id: anything-else
+ attributes:
+ label: Anything else?
+ description: |
+ Links? References? Anything that will give us more context about the issue you are encountering!
+
+ Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
+ validations:
+ required: false
+ - type: checkboxes
+ id: contribution-interest
+ attributes:
+ label: Do you be plan to contribute code for this enhancement?
+ description: We would like to know if you are willing to take ownership of this enhancement.
+ options:
+ - label: "Yes"
+ required: false
+ - type: checkboxes
+ id: sponsorship-interest
+ attributes:
+ label: Would you be interested in sponsoring this enhancement?
+ description: There are many developers in this community that may be willing to work on this.
+ options:
+ - label: "Yes"
+ required: false
+ - type: checkboxes
+ id: terms
+ attributes:
+ label: Code of Conduct
+ description: By submitting this issue, you agree to follow our [Code of Conduct](/CODE_OF_CONDUCT.md)
+ options:
+ - label: I agree to follow this project's Code of Conduct
+ required: true
diff --git a/.github/PULL_REQUEST_PROCESS.md b/.github/PULL_REQUEST_PROCESS.md
index 4d687fe176a..cf161e5ab65 100644
--- a/.github/PULL_REQUEST_PROCESS.md
+++ b/.github/PULL_REQUEST_PROCESS.md
@@ -6,7 +6,7 @@ The goal of this document is to set standards for the review, processing, and ap
The following items must all be true prior to a pull request being submitted to the DNN_Platform, if any of the following items are not true the pull request will be returned for edits referencing the specific missing item(s).
* Change should represent an entire solution for the issue at hand. Partial requests will NOT be processed.
-* Change should have a supporting issue logged on the DNN_Platform GitHub account, documenting the issue resolved, following the procedures outlined on the [Contribute Page](CONTRIBUTING.md)
+* Change should have a supporting issue logged on the DNN_Platform GitHub account, documenting the issue resolved, following the procedures outlined on the [Contribute Page](/CONTRIBUTING.md)
* If your change was to an area that already was covered by tests those tests must be updated. New tests for areas currently un-tested are appreciated
* **Exception**: Security items can be addressed individually, and should be initially communicated to the security@dnnsoftware.com email address for coordination
* Pull request comment should contain at a minimum the following details (When creating, a default template will also prompt you for the proper information)
diff --git a/.github/workflows/image-actions.yml b/.github/workflows/image-actions.yml
index 7f3853f3bdc..421acb4072b 100644
--- a/.github/workflows/image-actions.yml
+++ b/.github/workflows/image-actions.yml
@@ -34,7 +34,7 @@ jobs:
- name: Create Pull Request
if: | # If it's not a Pull Request then commit any changes as a new PR.
github.event_name != 'pull_request' && steps.compress_images.outputs.markdown != ''
- uses: peter-evans/create-pull-request@v4
+ uses: peter-evans/create-pull-request@v5
with:
title: Auto Compress Images
branch-suffix: timestamp
diff --git a/.github/workflows/updateVersions.yml b/.github/workflows/updateVersions.yml
index 61822c4f68d..6d3034ec86a 100644
--- a/.github/workflows/updateVersions.yml
+++ b/.github/workflows/updateVersions.yml
@@ -28,7 +28,7 @@ jobs:
run: yarn install --mode=update-lockfile --no-immutable
- name: Create Pull Request
- uses: peter-evans/create-pull-request@v4
+ uses: peter-evans/create-pull-request@v5
with:
commit-message: Updates versions as per release candidate creation
title: Updates versions as per release candidate creation
diff --git a/Build/Build.csproj b/Build/Build.csproj
index b646a37463a..e5a763a15dd 100644
--- a/Build/Build.csproj
+++ b/Build/Build.csproj
@@ -24,7 +24,7 @@
-
+ all
diff --git a/Build/Program.cs b/Build/Program.cs
index 0ef1aa76cff..6284ab6c72d 100644
--- a/Build/Program.cs
+++ b/Build/Program.cs
@@ -4,7 +4,6 @@
namespace DotNetNuke.Build
{
using System;
- using System.Reflection;
using Cake.AzurePipelines.Module;
using Cake.Frosting;
@@ -13,10 +12,10 @@ namespace DotNetNuke.Build
public class Program
{
/// The version of the Microsoft.TestPlatform NuGet package.
- internal const string MicrosoftTestPlatformVersion = "17.4.1";
+ internal const string MicrosoftTestPlatformVersion = "17.6.2";
/// The version of the NUnit3TestAdapter NuGet package.
- internal const string NUnit3TestAdapterVersion = "4.3.1";
+ internal const string NUnit3TestAdapterVersion = "4.5.0";
/// Runs the build process.
/// The arguments from the command line.
@@ -28,10 +27,10 @@ public static int Main(string[] args)
.UseLifetime()
.UseWorkingDirectory("..")
.UseModule()
- .InstallTool(new Uri("dotnet:?package=GitVersion.Tool&version=5.11.1"))
+ .InstallTool(new Uri("dotnet:?package=GitVersion.Tool&version=5.12.0"))
.InstallTool(new Uri("nuget:?package=Microsoft.TestPlatform&version=" + MicrosoftTestPlatformVersion))
.InstallTool(new Uri("nuget:?package=NUnit3TestAdapter&version=" + NUnit3TestAdapterVersion))
- .InstallTool(new Uri("nuget:?package=NuGet.CommandLine&version=6.4.0"))
+ .InstallTool(new Uri("nuget:?package=NuGet.CommandLine&version=6.5.0"))
.Run(args);
}
}
diff --git a/Build/Symbols/DotNetNuke_Symbols.dnn b/Build/Symbols/DotNetNuke_Symbols.dnn
index afe23dd0ec1..4c180c785ed 100644
--- a/Build/Symbols/DotNetNuke_Symbols.dnn
+++ b/Build/Symbols/DotNetNuke_Symbols.dnn
@@ -1,6 +1,6 @@
-
+ DNN Platform SymbolsThis package contains Debug Symbols and Intellisense files for DNN Platform.
diff --git a/DNN Platform/Admin Modules/Dnn.Modules.Console/dnn_Console.dnn b/DNN Platform/Admin Modules/Dnn.Modules.Console/dnn_Console.dnn
index 80d54c8a19f..c9523ceabda 100644
--- a/DNN Platform/Admin Modules/Dnn.Modules.Console/dnn_Console.dnn
+++ b/DNN Platform/Admin Modules/Dnn.Modules.Console/dnn_Console.dnn
@@ -1,6 +1,6 @@
-
+ ConsoleDisplay children pages as icon links for navigation.~/DesktopModules/Admin/Console/console.png
diff --git a/DNN Platform/Connectors/Azure/AzureConnector.dnn b/DNN Platform/Connectors/Azure/AzureConnector.dnn
index d3b40826c35..bae8ef3941b 100644
--- a/DNN Platform/Connectors/Azure/AzureConnector.dnn
+++ b/DNN Platform/Connectors/Azure/AzureConnector.dnn
@@ -1,6 +1,6 @@
-
+ Dnn Azure ConnectorThe Azure Connector allows you to integrate Azure as your commenting solution with the Publisher module.~/DesktopModules/Connectors/Azure/Images/icon-azure-32px.png
diff --git a/DNN Platform/Connectors/GoogleAnalytics/GoogleAnalyticsConnector.dnn b/DNN Platform/Connectors/GoogleAnalytics/GoogleAnalyticsConnector.dnn
index f2da4ab32a1..b79d4b764f7 100644
--- a/DNN Platform/Connectors/GoogleAnalytics/GoogleAnalyticsConnector.dnn
+++ b/DNN Platform/Connectors/GoogleAnalytics/GoogleAnalyticsConnector.dnn
@@ -1,6 +1,6 @@
-
+ Google Analytics ConnectorConfigure your sites Google Analytics settings.~/DesktopModules/Connectors/GoogleAnalytics/Images/GoogleAnalytics_32X32_Standard.png
diff --git a/DNN Platform/Connectors/GoogleAnalytics/Scripts/connector.js b/DNN Platform/Connectors/GoogleAnalytics/Scripts/connector.js
index 21a82adc088..b8b6147c3e4 100644
--- a/DNN Platform/Connectors/GoogleAnalytics/Scripts/connector.js
+++ b/DNN Platform/Connectors/GoogleAnalytics/Scripts/connector.js
@@ -1,132 +1,132 @@
-"use strict";
-define(["jquery", "knockout", "templatePath/scripts/config", "templatePath/scripts/PersonaBarDialog"], function ($, ko, cf) {
- var helper,
- bindViewModel,
- rootFolder,
- utility,
- appId,
- appSecret,
- container;
-
- var wasDeactivated = false;
-
- var init = function (koObject, connectionHelper, pluginFolder, util) {
-
- helper = connectionHelper;
- bindViewModel = koObject;
- rootFolder = pluginFolder;
- utility = util;
- koObject.container = ko.observable("");
-
- if (typeof dnn === "undefined") {
- window.Sys = !window.Sys ? window.top.Sys : window.Sys;
- window.dnn = !window.dnn ? window.top.dnn : window.dnn;
- window.String = !window.String ? window.top.String : window.String;
- window.String.format = !window.String.format ? window.top.String.format : window.String.format;
- }
-
- };
-
- var onSave = function (conn) {
-
- // Convert boolean to string as the API requires a dictionary of string values
- conn.configurations[2].value(conn.configurations[2].value().toString());
- conn.configurations[3].value(conn.configurations[3].value().toString());
- conn.configurations[4].value(conn.configurations[4].value().toString());
- };
-
- var onSaveComplete = function (conn, id) {
-
- // Deactivation / delete handled through the save since the delete function as
- // of v9.2.2 only works with multiple connector support. This should be
- // considered a temporary workaround until core behaviour updated.
-
- if (wasDeactivated) {
-
- // Was this just deactivated? clear the fields
- conn.onDelete(conn, null, null);
- wasDeactivated = false;
- utility.notify(utility.resx.Connectors.txt_Deleted, true);
- }
- else {
-
- conn.connected("true");
-
- if (bindViewModel.buttons().length === 1) {
-
- activateDeleteButton(conn);
- }
- utility.notify((utility.resx.Connectors || utility.resx.PersonaBar).txt_Saved, true);
- }
- };
-
- var activateDeleteButton = function (conn) {
-
- if (conn.buttons().length === 1) {
-
- conn.buttons.push({
- className: "secondarybtn",
- text: bindViewModel.resx.btnDelete,
- action: function (conn, e) {
-
- // Set the isDeactivating flag to true to override the default save behaviour
- // Temporary workaround until delete functionality on connectors is improved
- conn.configurations[6].value("true");
- wasDeactivated = true;
- conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
- }
- });
-
- }
-
- };
-
- var getActionButtons = function () {
-
-
- if (bindViewModel.connected()) {
-
- return [
- {
- className: "primarybtn",
- text: utility.resx.Connectors.btn_Save,
- action: function (conn, e) {
- conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
- }
- },
-
- {
- className: "secondarybtn",
- text: bindViewModel.resx.btnDelete,
- action: function (conn, e) {
-
- // Set the isDeactivating flag to true to override the default save behaviour
- // Temporary workaround until delete functionality on connectors is improved
- conn.configurations[6].value("true");
- wasDeactivated = true;
- conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
- }
- }
- ];
-
- } else {
-
- return [
- {
- className: "primarybtn",
- text: utility.resx.Connectors.btn_Save,
- action: function (conn, e) {
- conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
- }
- }
- ];
- }
- };
-
- return {
- init: init,
- onSave: onSave,
- getActionButtons: getActionButtons
- };
-
+"use strict";
+define(["jquery", "knockout", "templatePath/scripts/config", "templatePath/scripts/PersonaBarDialog"], function ($, ko, cf) {
+ var helper,
+ bindViewModel,
+ rootFolder,
+ utility,
+ appId,
+ appSecret,
+ container;
+
+ var wasDeactivated = false;
+
+ var init = function (koObject, connectionHelper, pluginFolder, util) {
+
+ helper = connectionHelper;
+ bindViewModel = koObject;
+ rootFolder = pluginFolder;
+ utility = util;
+ koObject.container = ko.observable("");
+
+ if (typeof dnn === "undefined") {
+ window.Sys = !window.Sys ? window.top.Sys : window.Sys;
+ window.dnn = !window.dnn ? window.top.dnn : window.dnn;
+ window.String = !window.String ? window.top.String : window.String;
+ window.String.format = !window.String.format ? window.top.String.format : window.String.format;
+ }
+
+ };
+
+ var onSave = function (conn) {
+
+ // Convert boolean to string as the API requires a dictionary of string values
+ conn.configurations[2].value(conn.configurations[2].value() || 'false');
+ conn.configurations[3].value(conn.configurations[3].value() || 'false');
+ conn.configurations[4].value(conn.configurations[4].value() || 'false');
+ };
+
+ var onSaveComplete = function (conn, id) {
+
+ // Deactivation / delete handled through the save since the delete function as
+ // of v9.2.2 only works with multiple connector support. This should be
+ // considered a temporary workaround until core behaviour updated.
+
+ if (wasDeactivated) {
+
+ // Was this just deactivated? clear the fields
+ conn.onDelete(conn, null, null);
+ wasDeactivated = false;
+ utility.notify(utility.resx.Connectors.txt_Deleted, true);
+ }
+ else {
+
+ conn.connected("true");
+
+ if (bindViewModel.buttons().length === 1) {
+
+ activateDeleteButton(conn);
+ }
+ utility.notify((utility.resx.Connectors || utility.resx.PersonaBar).txt_Saved, true);
+ }
+ };
+
+ var activateDeleteButton = function (conn) {
+
+ if (conn.buttons().length === 1) {
+
+ conn.buttons.push({
+ className: "secondarybtn",
+ text: bindViewModel.resx.btnDelete,
+ action: function (conn, e) {
+
+ // Set the isDeactivating flag to true to override the default save behaviour
+ // Temporary workaround until delete functionality on connectors is improved
+ conn.configurations[6].value("true");
+ wasDeactivated = true;
+ conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
+ }
+ });
+
+ }
+
+ };
+
+ var getActionButtons = function () {
+
+
+ if (bindViewModel.connected()) {
+
+ return [
+ {
+ className: "primarybtn",
+ text: utility.resx.Connectors.btn_Save,
+ action: function (conn, e) {
+ conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
+ }
+ },
+
+ {
+ className: "secondarybtn",
+ text: bindViewModel.resx.btnDelete,
+ action: function (conn, e) {
+
+ // Set the isDeactivating flag to true to override the default save behaviour
+ // Temporary workaround until delete functionality on connectors is improved
+ conn.configurations[6].value("true");
+ wasDeactivated = true;
+ conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
+ }
+ }
+ ];
+
+ } else {
+
+ return [
+ {
+ className: "primarybtn",
+ text: utility.resx.Connectors.btn_Save,
+ action: function (conn, e) {
+ conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
+ }
+ }
+ ];
+ }
+ };
+
+ return {
+ init: init,
+ onSave: onSave,
+ getActionButtons: getActionButtons
+ };
+
});
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleAnalytics/connector.htm b/DNN Platform/Connectors/GoogleAnalytics/connector.htm
index d441b60a58a..4332fb96751 100644
--- a/DNN Platform/Connectors/GoogleAnalytics/connector.htm
+++ b/DNN Platform/Connectors/GoogleAnalytics/connector.htm
@@ -1,32 +1,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/App_LocalResources/SharedResources.resx b/DNN Platform/Connectors/GoogleAnalytics4/App_LocalResources/SharedResources.resx
new file mode 100644
index 00000000000..94e41e34443
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/App_LocalResources/SharedResources.resx
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Delete Connection
+
+
+ Google Analytics 4 Core Connector
+
+
+ Track for Administrators:
+
+
+ Tracking Code Cannot Be Empty
+
+
+ Measurement ID:
+
+
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/Connector.css b/DNN Platform/Connectors/GoogleAnalytics4/Connector.css
new file mode 100644
index 00000000000..772981c5bd0
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/Connector.css
@@ -0,0 +1,16 @@
+#connector-CoreGoogleAnalytics4Connector > div.edit-fields > div > div, .connector-CoreGoogleAnalytics4Connector > div.edit-fields > div > div {
+ width: 100%;
+}
+
+#connector-CoreGoogleAnalytics4Connector > div.edit-fields > div > div input[type='text'], #connector-CoreGoogleAnalytics4Connector > div.edit-fields > div > div textarea, .connector-CoreGoogleAnalytics4Connector > div.edit-fields > div > div input[type='text'] {
+ width: 65% !important;
+}
+
+#connector-CoreGoogleAnalytics4Connector > div.edit-fields > div > div label, .connector-CoreGoogleAnalytics4Connector > div.edit-fields > div > div label {
+ width: 25% !important;
+}
+
+#connector-CoreGoogleAnalytics4Connector > div.edit-fields > div > div span, .connector-CoreGoogleAnalytics4Connector > div.edit-fields > div > div span {
+ font-size:0.75em;
+ font-style:italic;
+}
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/Constants.cs b/DNN Platform/Connectors/GoogleAnalytics4/Constants.cs
new file mode 100644
index 00000000000..f086580daeb
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/Constants.cs
@@ -0,0 +1,13 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information
+
+namespace DNN.Connectors.GoogleAnalytics4
+{
+ /// Lists constants used across the connector.
+ internal class Constants
+ {
+ /// The path to the resource file used for localization.
+ public const string LocalResourceFile = "~/DesktopModules/Connectors/GoogleAnalytics4/App_LocalResources/SharedResources.resx";
+ }
+}
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/Dnn.GoogleAnalytics4Connector.csproj b/DNN Platform/Connectors/GoogleAnalytics4/Dnn.GoogleAnalytics4Connector.csproj
new file mode 100644
index 00000000000..24798b94e2c
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/Dnn.GoogleAnalytics4Connector.csproj
@@ -0,0 +1,137 @@
+
+
+
+ true
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {94E12995-181A-4114-90C7-3F9557F28DE7}
+ Library
+ Properties
+ DNN.Connectors.GoogleAnalytics4
+ DNN.Connectors.GoogleAnalytics4
+ v4.7.2
+ 512
+
+
+
+ true
+ full
+ false
+ bin
+ DEBUG;TRACE
+ prompt
+ 4
+ bin\DNN.Connectors.GoogleAnalytics4.xml
+ 7
+ 1591
+ true
+
+
+ pdbonly
+ true
+ bin
+ TRACE
+ prompt
+ 4
+ bin\DNN.Connectors.GoogleAnalytics4.xml
+ 1591
+ 7
+
+
+ true
+ full
+ false
+ bin
+ DEBUG;TRACE;CLOUD;CLOUD_DEBUG
+ prompt
+ 4
+ bin\DNN.Connectors.GoogleAnalytics4.xml
+ 7
+ 1591
+
+
+ pdbonly
+ true
+ bin
+ TRACE;CLOUD;CLOUD_RELEASE
+ prompt
+ 4
+ bin\DNN.Connectors.GoogleAnalytics4.xml
+ 1591
+ 7
+
+
+
+ ..\..\..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+
+
+
+
+ ..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.9\lib\net45\System.Net.Http.Formatting.dll
+
+
+
+ ..\..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.9\lib\net45\System.Web.Http.dll
+
+
+
+
+
+
+
+
+ stylecop.json
+
+
+
+
+
+
+
+
+
+ {3cd5f6b8-8360-4862-80b6-f402892db7dd}
+ DotNetNuke.Instrumentation
+
+
+ {ee1329fe-fd88-4e1a-968c-345e394ef080}
+ DotNetNuke.Web
+
+
+ {6b29aded-7b56-4484-bea5-c0e09079535b}
+ DotNetNuke.Library
+
+
+ {b267ce88-dffc-4bd8-9962-319e79c52526}
+ DotNetNuke.Providers.FolderProviders
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/GoogleAnalytics4.config b/DNN Platform/Connectors/GoogleAnalytics4/GoogleAnalytics4.config
new file mode 100644
index 00000000000..ac2a5e390b2
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/GoogleAnalytics4.config
@@ -0,0 +1,23 @@
+
+
+
+
+ DotNetNuke.Services.Analytics.GoogleAnalytics4Engine, DotNetNuke
+ Head
+ True
+
+
+
+
+ ]]>
+
+
+
+
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/GoogleAnalytics4Connector.cs b/DNN Platform/Connectors/GoogleAnalytics4/GoogleAnalytics4Connector.cs
new file mode 100644
index 00000000000..805626b3997
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/GoogleAnalytics4Connector.cs
@@ -0,0 +1,250 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information
+
+namespace DNN.Connectors.GoogleAnalytics4
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Web;
+ using System.Xml;
+
+ using DotNetNuke.Common;
+ using DotNetNuke.Entities.Portals;
+ using DotNetNuke.Services.Analytics.Config;
+ using DotNetNuke.Services.Connections;
+ using DotNetNuke.Services.Exceptions;
+ using DotNetNuke.Services.Localization;
+
+ /// Connector to provide configuration for Google Tag Manager support.
+ public class GoogleAnalytics4Connector : IConnector
+ {
+ private const string DefaultDisplayName = "Google Analytics 4";
+
+ private string displayName;
+
+ ///
+ public string Name
+ {
+ get { return "Core Google Analytics 4 Connector"; }
+ }
+
+ ///
+ public string IconUrl
+ {
+ get { return "~/DesktopModules/Connectors/GoogleAnalytics4/Images/GoogleAnalytics4_32X32_Standard.png"; }
+ }
+
+ ///
+ public string PluginFolder
+ {
+ get { return "~/DesktopModules/Connectors/GoogleAnalytics4/"; }
+ }
+
+ ///
+ public bool IsEngageConnector
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ ///
+ public ConnectorCategories Type => ConnectorCategories.Analytics;
+
+ ///
+ // As of DNN 9.2.2 you need to support multiple to get access to the Delete Connection functionality
+ public bool SupportsMultiple => false;
+
+ ///
+ public string DisplayName
+ {
+ get => string.IsNullOrEmpty(this.displayName) ? DefaultDisplayName : this.displayName;
+ set => this.displayName = value;
+ }
+
+ ///
+ public string Id { get; set; }
+
+ ///
+ public IEnumerable GetConnectors(int portalId)
+ {
+ return new List { this };
+ }
+
+ ///
+ public void DeleteConnector(int portalId)
+ {
+ }
+
+ ///
+ public bool HasConfig(int portalId)
+ {
+ IDictionary config = this.GetConfig(portalId);
+
+ return config.ContainsKey("Ga4ID") && !string.IsNullOrEmpty(config["Ga4ID"]);
+ }
+
+ ///
+ public IDictionary GetConfig(int portalId)
+ {
+ var ga4Config = AnalyticsConfiguration.GetConfig("GoogleAnalytics4");
+ var portalSettings = new PortalSettings(portalId);
+
+ // Important, knockout handles empty strings as false and any other string as true
+ // so we need to pass empty strings when we mean false, however it passes us back the string "false"
+ // when saving the settings in the SaveConfig method, so we need to handle that case too
+ var ga4Id = string.Empty;
+ var trackForAdmin = string.Empty;
+
+ if (ga4Config != null)
+ {
+ foreach (AnalyticsSetting setting in ga4Config.Settings)
+ {
+ switch (setting.SettingName.ToLower())
+ {
+ case "ga4id":
+ ga4Id = setting.SettingValue;
+ break;
+ case "trackforadmin":
+ trackForAdmin = this.HandleCustomBoolean(setting.SettingValue);
+ break;
+ }
+ }
+ }
+
+ var configItems = new Dictionary
+ {
+ { "Ga4ID", ga4Id },
+ { "TrackAdministrators", trackForAdmin },
+ { "isDeactivating", this.HandleCustomBoolean("false") },
+ };
+
+ return configItems;
+ }
+
+ ///
+ public bool SaveConfig(int portalId, IDictionary values, ref bool validated, out string customErrorMessage)
+ {
+ // Delete / Deactivation functionality added into SaveConfig because
+ // As of DNN 9.2.2 you need to support multiple to get access to the Delete Connection functionality
+ customErrorMessage = string.Empty;
+ bool isValid;
+
+ try
+ {
+ var isDeactivating = false;
+
+ bool.TryParse(values["isDeactivating"].ToLowerInvariant(), out isDeactivating);
+
+ string ga4ID;
+ string trackForAdmin;
+
+ isValid = true;
+
+ if (isDeactivating)
+ {
+ ga4ID = null;
+ trackForAdmin = null;
+ }
+ else
+ {
+ ga4ID = values["Ga4ID"] != null ? values["Ga4ID"].ToUpperInvariant().Trim() : string.Empty;
+ trackForAdmin = values["TrackAdministrators"] != null ? values["TrackAdministrators"].ToLowerInvariant().Trim() : string.Empty;
+
+ if (string.IsNullOrEmpty(ga4ID))
+ {
+ isValid = false;
+ customErrorMessage = Localization.GetString("TrackingCodeFormat.ErrorMessage", Constants.LocalResourceFile);
+ }
+ }
+
+ if (isValid)
+ {
+ var config = new AnalyticsConfiguration
+ {
+ Settings = new AnalyticsSettingCollection(),
+ };
+
+ config.Settings.Add(new AnalyticsSetting
+ {
+ SettingName = "Ga4Id",
+ SettingValue = ga4ID,
+ });
+
+ config.Settings.Add(new AnalyticsSetting
+ {
+ SettingName = "TrackForAdmin",
+ SettingValue = trackForAdmin,
+ });
+
+ AnalyticsConfiguration.SaveConfig("GoogleAnalytics4", config);
+
+ if (!isDeactivating)
+ {
+ this.EnsureScriptInConfig();
+ }
+ }
+
+ return isValid;
+ }
+ catch (Exception ex)
+ {
+ Exceptions.LogException(ex);
+ return false;
+ }
+ }
+
+ /// Check if there's an AnalyticsEngine element in siteanalytics.config for this connector. If not, adds the default one.
+ private void EnsureScriptInConfig()
+ {
+ var applicationMappath = HttpContext.Current.Server.MapPath("\\");
+ var file = applicationMappath + "\\SiteAnalytics.config";
+ var xdoc = new XmlDocument();
+ xdoc.Load(file);
+ var found = false;
+ foreach (XmlNode engineTypeNode in xdoc.SelectNodes("/AnalyticsEngineConfig/Engines/AnalyticsEngine/EngineType"))
+ {
+ if (engineTypeNode.InnerText.Contains("DotNetNuke.Services.Analytics.GoogleAnalytics4Engine"))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ var fileGa4 = applicationMappath + "\\DesktopModules\\Connectors\\GoogleAnalytics4\\GoogleAnalytics4.config";
+ var xdocGa4 = new XmlDocument();
+ xdocGa4.Load(fileGa4);
+
+ var enginesElement = xdoc.SelectSingleNode("/AnalyticsEngineConfig/Engines");
+ foreach (XmlNode engineNode in xdocGa4.SelectNodes("/AnalyticsEngineConfig/Engines/AnalyticsEngine"))
+ {
+ var engineFrag = xdoc.CreateDocumentFragment();
+ engineFrag.InnerXml = engineNode.OuterXml;
+ enginesElement.AppendChild(engineFrag);
+ }
+
+ xdoc.Save(file);
+ }
+ }
+
+ ///
+ /// Handles custom conversion from "true" => "true"
+ /// Anything else to "" to support the strange knockout handling of string as booleans.
+ ///
+ /// The string representing a boolean.
+ /// The string representing a boolean after the correction.
+ private string HandleCustomBoolean(string value)
+ {
+ if ((value ?? string.Empty).Trim().Equals("true", StringComparison.OrdinalIgnoreCase))
+ {
+ return "true";
+ }
+
+ return string.Empty;
+ }
+ }
+}
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/GoogleAnalytics4Connector.dnn b/DNN Platform/Connectors/GoogleAnalytics4/GoogleAnalytics4Connector.dnn
new file mode 100644
index 00000000000..e51e0e3126d
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/GoogleAnalytics4Connector.dnn
@@ -0,0 +1,39 @@
+
+
+
+ Google Analytics 4 Connector
+ Configure your sites Google Analytics 4 settings.
+ ~/DesktopModules/Connectors/GoogleAnalytics4/Images/GoogleAnalytics4_32X32_Standard.png
+
+ 09.02.00
+
+
+ .NET Foundation and Contributors
+ DNN Community
+ https://dnncommunity.org
+ info@dnncommunity.org
+
+
+
+ true
+
+
+
+
+ bin
+ DNN.Connectors.GoogleAnalytics4.dll
+
+
+
+
+
+ DesktopModules\Connectors\GoogleAnalytics4
+
+ Resources.zip
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/Images/GoogleAnalytics4_32X32_Standard.png b/DNN Platform/Connectors/GoogleAnalytics4/Images/GoogleAnalytics4_32X32_Standard.png
new file mode 100644
index 00000000000..d5426ec46af
Binary files /dev/null and b/DNN Platform/Connectors/GoogleAnalytics4/Images/GoogleAnalytics4_32X32_Standard.png differ
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/License.txt b/DNN Platform/Connectors/GoogleAnalytics4/License.txt
new file mode 100644
index 00000000000..e17438a2fe5
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/License.txt
@@ -0,0 +1,23 @@
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All Rights Reserved
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/Module.build b/DNN Platform/Connectors/GoogleAnalytics4/Module.build
new file mode 100644
index 00000000000..aaaf830fb29
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/Module.build
@@ -0,0 +1,16 @@
+
+
+ $(MSBuildProjectDirectory)\..\..\..
+
+
+
+ zip
+ GoogleAnalytics4Connector
+ GoogleAnalytics4Connector
+ $(WebsitePath)\DesktopModules\Connectors\GoogleAnalytics4
+ $(WebsiteInstallPath)\Module
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/ReleaseNotes.txt b/DNN Platform/Connectors/GoogleAnalytics4/ReleaseNotes.txt
new file mode 100644
index 00000000000..409844b64bf
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/ReleaseNotes.txt
@@ -0,0 +1 @@
+There are no release notes for this version.
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/Scripts/connector.js b/DNN Platform/Connectors/GoogleAnalytics4/Scripts/connector.js
new file mode 100644
index 00000000000..650cacb2d83
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/Scripts/connector.js
@@ -0,0 +1,130 @@
+"use strict";
+define(["jquery", "knockout", "templatePath/scripts/config", "templatePath/scripts/PersonaBarDialog"], function ($, ko, cf) {
+ var helper,
+ bindViewModel,
+ rootFolder,
+ utility,
+ appId,
+ appSecret,
+ container;
+
+ var wasDeactivated = false;
+
+ var init = function (koObject, connectionHelper, pluginFolder, util) {
+
+ helper = connectionHelper;
+ bindViewModel = koObject;
+ rootFolder = pluginFolder;
+ utility = util;
+ koObject.container = ko.observable("");
+
+ if (typeof dnn === "undefined") {
+ window.Sys = !window.Sys ? window.top.Sys : window.Sys;
+ window.dnn = !window.dnn ? window.top.dnn : window.dnn;
+ window.String = !window.String ? window.top.String : window.String;
+ window.String.format = !window.String.format ? window.top.String.format : window.String.format;
+ }
+
+ };
+
+ var onSave = function (conn) {
+
+ // Convert boolean to string as the API requires a dictionary of string values
+ conn.configurations[1].value(conn.configurations[1].value() || 'false');
+ };
+
+ var onSaveComplete = function (conn, id) {
+
+ // Deactivation / delete handled through the save since the delete function as
+ // of v9.2.2 only works with multiple connector support. This should be
+ // considered a temporary workaround until core behaviour updated.
+
+ if (wasDeactivated) {
+
+ // Was this just deactivated? clear the fields
+ conn.onDelete(conn, null, null);
+ wasDeactivated = false;
+ utility.notify(utility.resx.Connectors.txt_Deleted, true);
+ }
+ else {
+
+ conn.connected("true");
+
+ if (bindViewModel.buttons().length === 1) {
+
+ activateDeleteButton(conn);
+ }
+ utility.notify((utility.resx.Connectors || utility.resx.PersonaBar).txt_Saved, true);
+ }
+ };
+
+ var activateDeleteButton = function (conn) {
+
+ if (conn.buttons().length === 1) {
+
+ conn.buttons.push({
+ className: "secondarybtn",
+ text: bindViewModel.resx.btnDelete,
+ action: function (conn, e) {
+
+ // Set the isDeactivating flag to true to override the default save behaviour
+ // Temporary workaround until delete functionality on connectors is improved
+ conn.configurations[2].value("true");
+ wasDeactivated = true;
+ conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
+ }
+ });
+
+ }
+
+ };
+
+ var getActionButtons = function () {
+
+
+ if (bindViewModel.connected()) {
+
+ return [
+ {
+ className: "primarybtn",
+ text: utility.resx.Connectors.btn_Save,
+ action: function (conn, e) {
+ conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
+ }
+ },
+
+ {
+ className: "secondarybtn",
+ text: bindViewModel.resx.btnDelete,
+ action: function (conn, e) {
+
+ // Set the isDeactivating flag to true to override the default save behaviour
+ // Temporary workaround until delete functionality on connectors is improved
+ conn.configurations[2].value("true");
+ wasDeactivated = true;
+ conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
+ }
+ }
+ ];
+
+ } else {
+
+ return [
+ {
+ className: "primarybtn",
+ text: utility.resx.Connectors.btn_Save,
+ action: function (conn, e) {
+ conn.save(conn, e, onSaveComplete.bind(this, conn, conn.id));
+ }
+ }
+ ];
+ }
+ };
+
+ return {
+ init: init,
+ onSave: onSave,
+ getActionButtons: getActionButtons
+ };
+
+});
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/app.config b/DNN Platform/Connectors/GoogleAnalytics4/app.config
new file mode 100644
index 00000000000..6838e65ce66
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/app.config
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/connector.htm b/DNN Platform/Connectors/GoogleAnalytics4/connector.htm
new file mode 100644
index 00000000000..16f0188eb4b
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/connector.htm
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleAnalytics4/packages.config b/DNN Platform/Connectors/GoogleAnalytics4/packages.config
new file mode 100644
index 00000000000..0500291e746
--- /dev/null
+++ b/DNN Platform/Connectors/GoogleAnalytics4/packages.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Connectors/GoogleTagManager/GoogleTagManagerConnector.dnn b/DNN Platform/Connectors/GoogleTagManager/GoogleTagManagerConnector.dnn
index 8e96318da07..6537df34654 100644
--- a/DNN Platform/Connectors/GoogleTagManager/GoogleTagManagerConnector.dnn
+++ b/DNN Platform/Connectors/GoogleTagManager/GoogleTagManagerConnector.dnn
@@ -1,6 +1,6 @@
-
+ Google Tag Manager ConnectorConfigure your sites Google Tag Manager settings.~/DesktopModules/Connectors/GoogleTagManager/Images/GoogleTagManager_32X32_Standard.png
diff --git a/DNN Platform/Connectors/GoogleTagManager/Scripts/connector.js b/DNN Platform/Connectors/GoogleTagManager/Scripts/connector.js
index b607cf30422..3d7c0cd79a6 100644
--- a/DNN Platform/Connectors/GoogleTagManager/Scripts/connector.js
+++ b/DNN Platform/Connectors/GoogleTagManager/Scripts/connector.js
@@ -30,7 +30,7 @@ define(["jquery", "knockout", "templatePath/scripts/config", "templatePath/scrip
var onSave = function (conn) {
// Convert boolean to string as the API requires a dictionary of string values
- conn.configurations[1].value(conn.configurations[1].value().toString());
+ conn.configurations[1].value(conn.configurations[1].value() || 'false');
};
var onSaveComplete = function (conn, id) {
diff --git a/DNN Platform/Connectors/GoogleTagManager/connector.htm b/DNN Platform/Connectors/GoogleTagManager/connector.htm
index 63b6646f85a..9aa0a9e117b 100644
--- a/DNN Platform/Connectors/GoogleTagManager/connector.htm
+++ b/DNN Platform/Connectors/GoogleTagManager/connector.htm
@@ -7,7 +7,7 @@
-
+
diff --git a/DNN Platform/Dnn.AuthServices.Jwt/Dnn.Jwt.dnn b/DNN Platform/Dnn.AuthServices.Jwt/Dnn.Jwt.dnn
index c213439dda9..de8574700fa 100644
--- a/DNN Platform/Dnn.AuthServices.Jwt/Dnn.Jwt.dnn
+++ b/DNN Platform/Dnn.AuthServices.Jwt/Dnn.Jwt.dnn
@@ -1,6 +1,6 @@
-
+ DNN JWT Auth HandlerDNN Json Web Token Authentication (JWT) library for cookie-less Mobile authentication clients
diff --git a/DNN Platform/DotNetNuke.DependencyInjection/DotNetNuke.DependencyInjection.csproj b/DNN Platform/DotNetNuke.DependencyInjection/DotNetNuke.DependencyInjection.csproj
index 841fc21605b..4e172c95e4b 100644
--- a/DNN Platform/DotNetNuke.DependencyInjection/DotNetNuke.DependencyInjection.csproj
+++ b/DNN Platform/DotNetNuke.DependencyInjection/DotNetNuke.DependencyInjection.csproj
@@ -6,6 +6,7 @@
true$(MSBuildProjectDirectory)\..\..bin/$(Configuration)/$(TargetFramework)/DotNetNuke.DependencyInjection.xml
+ latest
diff --git a/DNN Platform/DotNetNuke.DependencyInjection/LazyWrapper.cs b/DNN Platform/DotNetNuke.DependencyInjection/LazyWrapper.cs
new file mode 100644
index 00000000000..e46e47ef400
--- /dev/null
+++ b/DNN Platform/DotNetNuke.DependencyInjection/LazyWrapper.cs
@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information
+namespace DotNetNuke.DependencyInjection;
+using System;
+using Microsoft.Extensions.DependencyInjection;
+
+/// A wrapper which allows requesting via dependency injection and delaying instantiation.
+/// The type of service to conditionally instantiate.
+public class LazyWrapper : Lazy
+{
+ /// Initializes a new instance of the class.
+ /// The DI container.
+ public LazyWrapper(IServiceProvider serviceProvider)
+ : base(serviceProvider.GetService)
+ {
+ }
+}
diff --git a/DNN Platform/DotNetNuke.Web/Api/SupportedModulesAttribute.cs b/DNN Platform/DotNetNuke.Web/Api/SupportedModulesAttribute.cs
index c2763301ed9..c2731cde46f 100644
--- a/DNN Platform/DotNetNuke.Web/Api/SupportedModulesAttribute.cs
+++ b/DNN Platform/DotNetNuke.Web/Api/SupportedModulesAttribute.cs
@@ -19,6 +19,11 @@ public SupportedModulesAttribute(string supportedModules)
this.supportedModules = supportedModules.Split(new[] { ',' });
}
+ public SupportedModulesAttribute(params string[] supportedModules)
+ {
+ this.supportedModules = supportedModules;
+ }
+
///
public override bool IsAuthorized(AuthFilterContext context)
{
diff --git a/DNN Platform/DotNetNuke.WebUtility/DotNetNuke.ClientAPI.dnn b/DNN Platform/DotNetNuke.WebUtility/DotNetNuke.ClientAPI.dnn
index 188e020f4f9..6106afecd76 100644
--- a/DNN Platform/DotNetNuke.WebUtility/DotNetNuke.ClientAPI.dnn
+++ b/DNN Platform/DotNetNuke.WebUtility/DotNetNuke.ClientAPI.dnn
@@ -1,6 +1,6 @@
-
+ DotNetNuke ClientAPIThe DotNetNuke Client API is composed of both server-side and client-side code that works together to enable a simple and reliable interface for the developer to provide a rich client-side experience.
diff --git a/DNN Platform/Library/DotNetNuke.Library.csproj b/DNN Platform/Library/DotNetNuke.Library.csproj
index d9ff08e11c6..d3bc6401bf7 100644
--- a/DNN Platform/Library/DotNetNuke.Library.csproj
+++ b/DNN Platform/Library/DotNetNuke.Library.csproj
@@ -707,6 +707,7 @@
+
diff --git a/DNN Platform/Library/Framework/Reflection.cs b/DNN Platform/Library/Framework/Reflection.cs
index 2616cf7472a..107850a52d0 100644
--- a/DNN Platform/Library/Framework/Reflection.cs
+++ b/DNN Platform/Library/Framework/Reflection.cs
@@ -7,11 +7,14 @@ namespace DotNetNuke.Framework
using System.Reflection;
using System.Web.Compilation;
+ using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Framework.Providers;
using DotNetNuke.Instrumentation;
using DotNetNuke.Services.Exceptions;
+ using Microsoft.Extensions.DependencyInjection;
+
/// Library responsible for reflection.
public class Reflection
{
@@ -21,32 +24,65 @@ public class Reflection
/// The type of Object to create (data/navigation).
/// The created Object.
/// Overload for creating an object from a Provider configured in web.config.
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
public static object CreateObject(string objectProviderType)
{
return CreateObject(objectProviderType, true);
}
+ /// Creates an object.
+ /// The DI container.
+ /// The type of Object to create (data/navigation).
+ /// The created Object.
+ public static object CreateObject(IServiceProvider serviceProvider, string objectProviderType)
+ {
+ return CreateObject(serviceProvider, objectProviderType, true);
+ }
+
/// Creates an object.
/// The type of Object to create (data/navigation).
/// Caching switch.
/// The created Object.
/// Overload for creating an object from a Provider configured in web.config.
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
public static object CreateObject(string objectProviderType, bool useCache)
{
return CreateObject(objectProviderType, string.Empty, string.Empty, string.Empty, useCache);
}
+ /// Creates an object.
+ /// The DI container.
+ /// The type of Object to create (data/navigation).
+ /// Caching switch.
+ /// The created Object.
+ public static object CreateObject(IServiceProvider serviceProvider, string objectProviderType, bool useCache)
+ {
+ return CreateObject(serviceProvider, objectProviderType, string.Empty, string.Empty, string.Empty, useCache);
+ }
+
/// Creates an object.
/// The type of Object to create (data/navigation).
/// The namespace of the object to create.
/// The assembly of the object to create.
/// The created Object.
/// Overload for creating an object from a Provider including NameSpace and AssemblyName ( this allows derived providers to share the same config ).
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
public static object CreateObject(string objectProviderType, string objectNamespace, string objectAssemblyName)
{
return CreateObject(objectProviderType, string.Empty, objectNamespace, objectAssemblyName, true);
}
+ /// Creates an object.
+ /// The DI container.
+ /// The type of Object to create (data/navigation).
+ /// The namespace of the object to create.
+ /// The assembly of the object to create.
+ /// The created Object.
+ public static object CreateObject(IServiceProvider serviceProvider, string objectProviderType, string objectNamespace, string objectAssemblyName)
+ {
+ return CreateObject(serviceProvider, objectProviderType, string.Empty, objectNamespace, objectAssemblyName, true);
+ }
+
/// Creates an object.
/// The type of Object to create (data/navigation).
/// The namespace of the object to create.
@@ -54,11 +90,24 @@ public static object CreateObject(string objectProviderType, string objectNamesp
/// Caching switch.
/// The created Object.
/// Overload for creating an object from a Provider including NameSpace and AssemblyName ( this allows derived providers to share the same config ).
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
public static object CreateObject(string objectProviderType, string objectNamespace, string objectAssemblyName, bool useCache)
{
return CreateObject(objectProviderType, string.Empty, objectNamespace, objectAssemblyName, useCache);
}
+ /// Creates an object.
+ /// The DI container.
+ /// The type of Object to create (data/navigation).
+ /// The namespace of the object to create.
+ /// The assembly of the object to create.
+ /// Caching switch.
+ /// The created Object.
+ public static object CreateObject(IServiceProvider serviceProvider, string objectProviderType, string objectNamespace, string objectAssemblyName, bool useCache)
+ {
+ return CreateObject(serviceProvider, objectProviderType, string.Empty, objectNamespace, objectAssemblyName, useCache);
+ }
+
/// Creates an object.
/// The type of Object to create (data/navigation).
/// The name of the Provider.
@@ -66,11 +115,24 @@ public static object CreateObject(string objectProviderType, string objectNamesp
/// The assembly of the object to create.
/// The created Object.
/// Overload for creating an object from a Provider including NameSpace, AssemblyName and ProviderName.
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
public static object CreateObject(string objectProviderType, string objectProviderName, string objectNamespace, string objectAssemblyName)
{
return CreateObject(objectProviderType, objectProviderName, objectNamespace, objectAssemblyName, true);
}
+ /// Creates an object.
+ /// The DI container.
+ /// The type of Object to create (data/navigation).
+ /// The name of the Provider.
+ /// The namespace of the object to create.
+ /// The assembly of the object to create.
+ /// The created Object.
+ public static object CreateObject(IServiceProvider serviceProvider, string objectProviderType, string objectProviderName, string objectNamespace, string objectAssemblyName)
+ {
+ return CreateObject(serviceProvider, objectProviderType, objectProviderName, objectNamespace, objectAssemblyName, true);
+ }
+
/// Creates an object.
/// The type of Object to create (data/navigation).
/// The name of the Provider.
@@ -79,11 +141,25 @@ public static object CreateObject(string objectProviderType, string objectProvid
/// Caching switch.
/// The created Object.
/// Overload for creating an object from a Provider including NameSpace, AssemblyName and ProviderName.
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
public static object CreateObject(string objectProviderType, string objectProviderName, string objectNamespace, string objectAssemblyName, bool useCache)
{
return CreateObject(objectProviderType, objectProviderName, objectNamespace, objectAssemblyName, useCache, true);
}
+ /// Creates an object.
+ /// The DI container.
+ /// The type of Object to create (data/navigation).
+ /// The name of the Provider.
+ /// The namespace of the object to create.
+ /// The assembly of the object to create.
+ /// Caching switch.
+ /// The created Object.
+ public static object CreateObject(IServiceProvider serviceProvider, string objectProviderType, string objectProviderName, string objectNamespace, string objectAssemblyName, bool useCache)
+ {
+ return CreateObject(serviceProvider, objectProviderType, objectProviderName, objectNamespace, objectAssemblyName, useCache, true);
+ }
+
/// Creates an object.
/// The type of Object to create (data/navigation).
/// The name of the Provider.
@@ -93,9 +169,38 @@ public static object CreateObject(string objectProviderType, string objectProvid
/// Whether append provider name as part of the assembly name.
/// The created Object.
/// Overload for creating an object from a Provider including NameSpace, AssemblyName and ProviderName.
- public static object CreateObject(string objectProviderType, string objectProviderName, string objectNamespace, string objectAssemblyName, bool useCache, bool fixAssemblyName)
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
+ public static object CreateObject(
+ string objectProviderType,
+ string objectProviderName,
+ string objectNamespace,
+ string objectAssemblyName,
+ bool useCache,
+ bool fixAssemblyName)
{
- string typeName = string.Empty;
+ return CreateObject(
+ Globals.DependencyProvider,
+ objectProviderType,
+ objectProviderName,
+ objectNamespace,
+ objectAssemblyName,
+ useCache,
+ fixAssemblyName);
+ }
+
+ /// Creates an object.
+ /// The DI container.
+ /// The type of Object to create (data/navigation).
+ /// The name of the Provider.
+ /// The namespace of the object to create.
+ /// The assembly of the object to create.
+ /// Caching switch.
+ /// Whether append provider name as part of the assembly name.
+ /// The created Object.
+ /// Overload for creating an object from a Provider including NameSpace, AssemblyName and ProviderName.
+ public static object CreateObject(IServiceProvider serviceProvider, string objectProviderType, string objectProviderName, string objectNamespace, string objectAssemblyName, bool useCache, bool fixAssemblyName)
+ {
+ string typeName;
// get the provider configuration based on the type
ProviderConfiguration objProviderConfiguration = ProviderConfiguration.GetProviderConfiguration(objectProviderType);
@@ -145,7 +250,7 @@ public static object CreateObject(string objectProviderType, string objectProvid
}
}
- return CreateObject(typeName, typeName, useCache);
+ return CreateObject(serviceProvider, typeName, typeName, useCache);
}
/// Creates an object.
@@ -153,55 +258,132 @@ public static object CreateObject(string objectProviderType, string objectProvid
/// The Cache Key.
/// The created Object.
/// Overload that takes a fully-qualified typename and a Cache Key.
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
public static object CreateObject(string typeName, string cacheKey)
{
return CreateObject(typeName, cacheKey, true);
}
+ /// Creates an object.
+ /// The DI container.
+ /// The fully qualified TypeName.
+ /// The Cache Key.
+ /// The created Object.
+ public static object CreateObject(IServiceProvider serviceProvider, string typeName, string cacheKey)
+ {
+ return CreateObject(serviceProvider, typeName, cacheKey, true);
+ }
+
/// Creates an object.
/// The fully qualified TypeName.
/// The Cache Key.
/// Caching switch.
/// The created Object.
/// Overload that takes a fully-qualified typename and a Cache Key.
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
public static object CreateObject(string typeName, string cacheKey, bool useCache)
{
- return Activator.CreateInstance(CreateType(typeName, cacheKey, useCache));
+ return CreateObject(Globals.DependencyProvider, typeName, cacheKey, useCache);
+ }
+
+ /// Creates an object.
+ /// The DI container.
+ /// The fully qualified TypeName.
+ /// The Cache Key.
+ /// Caching switch.
+ /// The created Object.
+ public static object CreateObject(IServiceProvider serviceProvider, string typeName, string cacheKey, bool useCache)
+ {
+ var type = CreateType(typeName, cacheKey, useCache);
+ return CreateObject(serviceProvider, type);
}
/// Creates an object.
/// The type of object to create.
/// The created object.
/// Generic version.
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
public static T CreateObject()
{
- // dynamically create the object
- return Activator.CreateInstance();
+ return CreateObject(Globals.DependencyProvider);
+ }
+
+ /// Creates an object.
+ /// The type of object to create.
+ /// The DI container.
+ /// The created object.
+ public static T CreateObject(IServiceProvider serviceProvider)
+ {
+ try
+ {
+ return ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider);
+ }
+ catch (InvalidOperationException exception)
+ {
+ Logger.Warn($"Unable to create type via service provider: {typeof(T)}", exception);
+ return Activator.CreateInstance();
+ }
}
/// Creates an object.
/// The type of object to create.
/// The created object.
+ [Obsolete("Deprecated in DotNetNuke 9.11.3. Please use overload with IServiceProvider. Scheduled removal in v11.0.0.")]
public static object CreateObject(Type type)
{
- return Activator.CreateInstance(type);
+ return CreateObject(Globals.DependencyProvider, type);
}
+ /// Creates an object.
+ /// The DI container.
+ /// The type of object to create.
+ /// The created object.
+ public static object CreateObject(IServiceProvider serviceProvider, Type type)
+ {
+ try
+ {
+ return ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider, type);
+ }
+ catch (InvalidOperationException exception)
+ {
+ Logger.Warn($"Unable to create type via service provider: {type}", exception);
+ return Activator.CreateInstance(type);
+ }
+ }
+
+ /// Creates a type. Caches type creation for performance. Errors creating the type are logged.
+ /// The name of the type to create.
+ /// The instance or .
public static Type CreateType(string typeName)
{
return CreateType(typeName, string.Empty, true, false);
}
+ /// Creates a type. Caches type creation for performance.
+ /// The name of the type to create.
+ /// Whether to log exceptions.
+ /// The instance or .
public static Type CreateType(string typeName, bool ignoreErrors)
{
return CreateType(typeName, string.Empty, true, ignoreErrors);
}
+ /// Creates a type. Errors creating the type are logged.
+ /// The name of the type to create.
+ /// A custom cache key; otherwise is used as the key.
+ /// Whether to store the type in the cache or bypass the cache.
+ /// The instance or .
public static Type CreateType(string typeName, string cacheKey, bool useCache)
{
return CreateType(typeName, cacheKey, useCache, false);
}
+ /// Creates a type.
+ /// The name of the type to create.
+ /// A custom cache key; otherwise is used as the key.
+ /// Whether to store the type in the cache or bypass the cache.
+ /// Whether to log exceptions.
+ /// The instance or .
public static Type CreateType(string typeName, string cacheKey, bool useCache, bool ignoreErrors)
{
if (string.IsNullOrEmpty(cacheKey))
@@ -242,11 +424,18 @@ public static Type CreateType(string typeName, string cacheKey, bool useCache, b
return type;
}
+ /// Dynamically call the empty constructor for a .
+ /// The type of object to create.
+ /// An instance of the object, or if is .
public static object CreateInstance(Type type)
{
return CreateInstance(type, null);
}
+ /// Dynamically call a constructor for a .
+ /// The type of object to create.
+ /// The constructor arguments.
+ /// An instance of the object, or if is .
public static object CreateInstance(Type type, object[] args)
{
if (type != null)
@@ -259,6 +448,11 @@ public static object CreateInstance(Type type, object[] args)
}
}
+ /// Dynamically get the value of a property.
+ /// The type of .
+ /// The name of the property to get.
+ /// The object from which to read the property.
+ /// The property's value, or if is .
public static object GetProperty(Type type, string propertyName, object target)
{
if (type != null)
@@ -271,6 +465,11 @@ public static object GetProperty(Type type, string propertyName, object target)
}
}
+ /// Dynamically set the value of a property.
+ /// The type of .
+ /// The name of the property to set.
+ /// The object on which to set the property.
+ /// The input to the property.
public static void SetProperty(Type type, string propertyName, object target, object[] args)
{
if (type != null)
@@ -279,6 +478,11 @@ public static void SetProperty(Type type, string propertyName, object target, ob
}
}
+ /// Dynamically invoke a method on an object.
+ /// The type of .
+ /// The name of the method to invoke.
+ /// The object on which to invoke the method.
+ /// The input to the method.
public static void InvokeMethod(Type type, string propertyName, object target, object[] args)
{
if (type != null)
diff --git a/DNN Platform/Library/Services/Analytics/GoogleAnalytics4Engine.cs b/DNN Platform/Library/Services/Analytics/GoogleAnalytics4Engine.cs
new file mode 100644
index 00000000000..31d7bea4c3a
--- /dev/null
+++ b/DNN Platform/Library/Services/Analytics/GoogleAnalytics4Engine.cs
@@ -0,0 +1,75 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information
+namespace DotNetNuke.Services.Analytics
+{
+ using System;
+
+ using DotNetNuke.Entities.Portals;
+ using DotNetNuke.Entities.Users;
+ using DotNetNuke.Services.Analytics.Config;
+
+ ///
+ public class GoogleAnalytics4Engine : AnalyticsEngineBase
+ {
+ ///
+ public override string EngineName
+ {
+ get
+ {
+ return "GoogleAnalytics4";
+ }
+ }
+
+ ///
+ public override string RenderScript(string scriptTemplate)
+ {
+ AnalyticsConfiguration config = this.GetConfig();
+
+ if (config == null)
+ {
+ return string.Empty;
+ }
+
+ var trackingId = string.Empty;
+ var urlParameter = string.Empty;
+ var trackForAdmin = true;
+
+ foreach (AnalyticsSetting setting in config.Settings)
+ {
+ switch (setting.SettingName.ToLowerInvariant())
+ {
+ case "ga4id":
+ trackingId = setting.SettingValue;
+ break;
+ case "trackforadmin":
+ if (!bool.TryParse(setting.SettingValue, out trackForAdmin))
+ {
+ trackForAdmin = true;
+ }
+
+ break;
+ }
+ }
+
+ if (string.IsNullOrEmpty(trackingId))
+ {
+ return string.Empty;
+ }
+
+ // check whether setting to not track traffic if current user is host user or website administrator.
+ if (!trackForAdmin &&
+ (UserController.Instance.GetCurrentUserInfo().IsSuperUser
+ ||
+ (PortalSettings.Current != null &&
+ UserController.Instance.GetCurrentUserInfo().IsInRole(PortalSettings.Current.AdministratorRoleName))))
+ {
+ return string.Empty;
+ }
+
+ scriptTemplate = scriptTemplate.Replace("[GA4_ID]", trackingId);
+
+ return scriptTemplate;
+ }
+ }
+}
diff --git a/DNN Platform/Library/Services/Mail/Mail.cs b/DNN Platform/Library/Services/Mail/Mail.cs
index 60f27d27ff1..f500fe57af3 100644
--- a/DNN Platform/Library/Services/Mail/Mail.cs
+++ b/DNN Platform/Library/Services/Mail/Mail.cs
@@ -193,6 +193,13 @@ public static string SendMail(int portalId, int userId, MessageType msgType, Por
subject = "EMAIL_PASSWORD_REMINDER_USER_ISNOT_APPROVED_SUBJECT";
body = "EMAIL_PASSWORD_REMINDER_USER_ISNOT_APPROVED_BODY";
break;
+ case MessageType.PasswordReminderUserIsNotApprovedAdmin:
+ subject = "EMAIL_PASSWORD_REMINDER_USER_ISNOT_APPROVED_ADMINISTRATOR_SUBJECT";
+ body = "EMAIL_PASSWORD_REMINDER_USER_ISNOT_APPROVED_ADMINISTRATOR_BODY";
+ toUser = settings.AdministratorId;
+ admin = UserController.GetUserById(settings.PortalId, settings.AdministratorId);
+ locale = admin.Profile.PreferredLocale;
+ break;
case MessageType.UserAuthorized:
subject = "EMAIL_USER_AUTHORIZED_SUBJECT";
body = "EMAIL_USER_AUTHORIZED_BODY";
diff --git a/DNN Platform/Library/Services/Mail/MessageType.cs b/DNN Platform/Library/Services/Mail/MessageType.cs
index b7eecff170c..c77c40e79a6 100644
--- a/DNN Platform/Library/Services/Mail/MessageType.cs
+++ b/DNN Platform/Library/Services/Mail/MessageType.cs
@@ -18,5 +18,6 @@ public enum MessageType
PasswordReminderUserIsNotApproved = 9,
UserAuthorized = 10,
UserUnAuthorized = 11,
+ PasswordReminderUserIsNotApprovedAdmin = 12,
}
}
diff --git a/DNN Platform/Library/Startup.cs b/DNN Platform/Library/Startup.cs
index d54b9ec01bc..1dda82c3953 100644
--- a/DNN Platform/Library/Startup.cs
+++ b/DNN Platform/Library/Startup.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information
namespace DotNetNuke
{
+ using System;
using DotNetNuke.Abstractions;
using DotNetNuke.Abstractions.Application;
using DotNetNuke.Abstractions.Logging;
@@ -26,6 +27,8 @@ public class Startup : IDnnStartup
///
public void ConfigureServices(IServiceCollection services)
{
+ services.AddTransient(typeof(Lazy<>), typeof(LazyWrapper<>));
+
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
diff --git a/DNN Platform/Modules/CoreMessaging/CoreMessaging.dnn b/DNN Platform/Modules/CoreMessaging/CoreMessaging.dnn
index bff7ef7ef96..e81cab4e8e5 100644
--- a/DNN Platform/Modules/CoreMessaging/CoreMessaging.dnn
+++ b/DNN Platform/Modules/CoreMessaging/CoreMessaging.dnn
@@ -1,6 +1,6 @@
-
+ Message CenterCore Messaging module allows users to message each other.~/DesktopModules/CoreMessaging/Images/messaging_32X32.png
diff --git a/DNN Platform/Modules/DDRMenu/DDRMenu.dnn b/DNN Platform/Modules/DDRMenu/DDRMenu.dnn
index 32aee3cc622..d5701be9b03 100644
--- a/DNN Platform/Modules/DDRMenu/DDRMenu.dnn
+++ b/DNN Platform/Modules/DDRMenu/DDRMenu.dnn
@@ -1,6 +1,6 @@
-
+ DDR MenuDotNetNuke Navigation Provider.
diff --git a/DNN Platform/Modules/DnnExportImport/dnn_SiteExportImport.dnn b/DNN Platform/Modules/DnnExportImport/dnn_SiteExportImport.dnn
index 09c9e37f3de..0c820def322 100644
--- a/DNN Platform/Modules/DnnExportImport/dnn_SiteExportImport.dnn
+++ b/DNN Platform/Modules/DnnExportImport/dnn_SiteExportImport.dnn
@@ -1,6 +1,6 @@
-
+ Site Export ImportDotNetNuke Corporation Site Export Import LibraryImages/Files_32x32_Standard.png
diff --git a/DNN Platform/Modules/Groups/SocialGroups.dnn b/DNN Platform/Modules/Groups/SocialGroups.dnn
index 8aefaf57873..87a227c79a0 100644
--- a/DNN Platform/Modules/Groups/SocialGroups.dnn
+++ b/DNN Platform/Modules/Groups/SocialGroups.dnn
@@ -1,6 +1,6 @@
-
+ Social GroupsDotNetNuke Corporation Social Groups module~/DesktopModules/SocialGroups/Images/Social_Groups_32X32.png
diff --git a/DNN Platform/Modules/HTML/dnn_HTML.dnn b/DNN Platform/Modules/HTML/dnn_HTML.dnn
index ed7f7e0ca71..1ab7a380b42 100644
--- a/DNN Platform/Modules/HTML/dnn_HTML.dnn
+++ b/DNN Platform/Modules/HTML/dnn_HTML.dnn
@@ -1,6 +1,6 @@
-
+ HTMLThis module renders a block of HTML or Text content. The Html/Text module allows authorized users to edit the content either inline or in a separate administration page. Optional tokens can be used that get replaced dynamically during display. All versions of content are stored in the database including the ability to rollback to an older version.DesktopModules\HTML\Images\html.png
diff --git a/DNN Platform/Modules/HtmlEditorManager/dnn_HtmlEditorManager.dnn b/DNN Platform/Modules/HtmlEditorManager/dnn_HtmlEditorManager.dnn
index 8375f2fa71e..1ca7585906d 100644
--- a/DNN Platform/Modules/HtmlEditorManager/dnn_HtmlEditorManager.dnn
+++ b/DNN Platform/Modules/HtmlEditorManager/dnn_HtmlEditorManager.dnn
@@ -1,6 +1,6 @@
-
+ Html Editor ManagementImages/HtmlEditorManager_Standard_32x32.pngA module used to configure toolbar items, behavior, and other options used in the DotNetNuke HtmlEditor Provider.
diff --git a/DNN Platform/Modules/Journal/Journal.dnn b/DNN Platform/Modules/Journal/Journal.dnn
index f214b81e717..57bd7aaae75 100644
--- a/DNN Platform/Modules/Journal/Journal.dnn
+++ b/DNN Platform/Modules/Journal/Journal.dnn
@@ -1,6 +1,6 @@
-
+ JournalDotNetNuke Corporation Journal moduleDesktopModules/Journal/Images/journal_32X32.png
diff --git a/DNN Platform/Modules/MemberDirectory/MemberDirectory.dnn b/DNN Platform/Modules/MemberDirectory/MemberDirectory.dnn
index 8296bbe0d31..c05a110fb45 100644
--- a/DNN Platform/Modules/MemberDirectory/MemberDirectory.dnn
+++ b/DNN Platform/Modules/MemberDirectory/MemberDirectory.dnn
@@ -1,6 +1,6 @@
-
+ Member DirectoryThe Member Directory module displays a list of Members based on role, profile property or relationship.~/DesktopModules/MemberDirectory/Images/member_list_32X32.png
diff --git a/DNN Platform/Modules/RazorHost/Manifest.dnn b/DNN Platform/Modules/RazorHost/Manifest.dnn
index 353c2b78cc0..5bacda0243a 100644
--- a/DNN Platform/Modules/RazorHost/Manifest.dnn
+++ b/DNN Platform/Modules/RazorHost/Manifest.dnn
@@ -1,6 +1,6 @@
-
+ {0}{1}
diff --git a/DNN Platform/Modules/RazorHost/RazorHost.dnn b/DNN Platform/Modules/RazorHost/RazorHost.dnn
index 6901323290c..cdfaecc8b9d 100644
--- a/DNN Platform/Modules/RazorHost/RazorHost.dnn
+++ b/DNN Platform/Modules/RazorHost/RazorHost.dnn
@@ -1,6 +1,6 @@
-
+ Razor HostThe Razor Host module allows developers to host Razor Scripts.
diff --git a/DNN Platform/Modules/ResourceManager/ResourceManager.Web/package.json b/DNN Platform/Modules/ResourceManager/ResourceManager.Web/package.json
index d9b24952d26..d150254844e 100644
--- a/DNN Platform/Modules/ResourceManager/ResourceManager.Web/package.json
+++ b/DNN Platform/Modules/ResourceManager/ResourceManager.Web/package.json
@@ -1,6 +1,6 @@
{
"name": "dnn-resource-manager",
- "version": "9.11.1",
+ "version": "9.12.0",
"description": "Resource Manager",
"private": true,
"main": "dist/index.cjs.js",
diff --git a/DNN Platform/Modules/ResourceManager/ResourceManager.dnn b/DNN Platform/Modules/ResourceManager/ResourceManager.dnn
index 18966445aec..f0828dbf548 100644
--- a/DNN Platform/Modules/ResourceManager/ResourceManager.dnn
+++ b/DNN Platform/Modules/ResourceManager/ResourceManager.dnn
@@ -1,6 +1,6 @@
-
+ Resource ManagerThis module allows you to manage files on the server~/Images/icon_filemanager_32px.gif
diff --git a/DNN Platform/Modules/TelerikRemoval/TelerikRemoval.dnn b/DNN Platform/Modules/TelerikRemoval/TelerikRemoval.dnn
index 661f0a54d98..e3d23f69c35 100644
--- a/DNN Platform/Modules/TelerikRemoval/TelerikRemoval.dnn
+++ b/DNN Platform/Modules/TelerikRemoval/TelerikRemoval.dnn
@@ -1,6 +1,6 @@
-
+ Telerik RemovalThis module allows you to remove the DotNetNuke Telerik Web Components library from your site.
diff --git a/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Facebook/Facebook_Auth.dnn b/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Facebook/Facebook_Auth.dnn
index 88312fe1d70..5fb2baf442a 100644
--- a/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Facebook/Facebook_Auth.dnn
+++ b/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Facebook/Facebook_Auth.dnn
@@ -1,6 +1,6 @@
-
+ DotNetNuke Facebook Authentication ProjectThe DotNetNuke Facebook Authentication Project is an Authentication provider for DotNetNuke that uses
Facebook authentication to authenticate users.
diff --git a/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Google/Google_Auth.dnn b/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Google/Google_Auth.dnn
index 0bd2927bbef..0697b61c5a7 100644
--- a/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Google/Google_Auth.dnn
+++ b/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Google/Google_Auth.dnn
@@ -1,6 +1,6 @@
-
+ DotNetNuke Google Authentication ProjectThe DotNetNuke Google Authentication Project is an Authentication provider for DotNetNuke that uses
Google authentication to authenticate users.
diff --git a/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.LiveConnect/Live_Auth.dnn b/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.LiveConnect/Live_Auth.dnn
index 87c47b3dab1..95786b81213 100644
--- a/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.LiveConnect/Live_Auth.dnn
+++ b/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.LiveConnect/Live_Auth.dnn
@@ -1,6 +1,6 @@
-
+ DotNetNuke Live Authentication Project
The DotNetNuke Live Authentication Project is an Authentication provider for DotNetNuke that uses
diff --git a/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Twitter/Twitter_Auth.dnn b/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Twitter/Twitter_Auth.dnn
index ebfc8b746b9..4446512e687 100644
--- a/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Twitter/Twitter_Auth.dnn
+++ b/DNN Platform/Providers/AuthenticationProviders/DotNetNuke.Authentication.Twitter/Twitter_Auth.dnn
@@ -1,6 +1,6 @@
-
+ DotNetNuke Twitter Authentication Project
The DotNetNuke Twitter Authentication Project is an Authentication provider for DotNetNuke that uses
diff --git a/DNN Platform/Providers/CachingProviders/DotNetNuke.Providers.Caching.SimpleWebFarmCachingProvider/SimpleWebFarmCachingProvider.dnn b/DNN Platform/Providers/CachingProviders/DotNetNuke.Providers.Caching.SimpleWebFarmCachingProvider/SimpleWebFarmCachingProvider.dnn
index c602b49e848..0e29628f846 100644
--- a/DNN Platform/Providers/CachingProviders/DotNetNuke.Providers.Caching.SimpleWebFarmCachingProvider/SimpleWebFarmCachingProvider.dnn
+++ b/DNN Platform/Providers/CachingProviders/DotNetNuke.Providers.Caching.SimpleWebFarmCachingProvider/SimpleWebFarmCachingProvider.dnn
@@ -1,6 +1,6 @@
-
+ DotNetNuke Simple Web Farm Caching ProviderDotNetNuke Simple Web Farm Caching Provider
diff --git a/DNN Platform/Providers/ClientCapabilityProviders/Provider.AspNetCCP/AspNetClientCapabilityProvider.dnn b/DNN Platform/Providers/ClientCapabilityProviders/Provider.AspNetCCP/AspNetClientCapabilityProvider.dnn
index 5245cce88ff..c4b36cd9732 100644
--- a/DNN Platform/Providers/ClientCapabilityProviders/Provider.AspNetCCP/AspNetClientCapabilityProvider.dnn
+++ b/DNN Platform/Providers/ClientCapabilityProviders/Provider.AspNetCCP/AspNetClientCapabilityProvider.dnn
@@ -1,6 +1,6 @@
-
+ DotNetNuke ASP.NET Client Capability ProviderASP.NET Device Detection / Client Capability Provider~/Providers/ClientCapabilityProviders/AspNetClientCapabilityProvider/Images/mobiledevicedet_32X32.png
diff --git a/DNN Platform/Providers/FolderProviders/FolderProviders.dnn b/DNN Platform/Providers/FolderProviders/FolderProviders.dnn
index a91d69ad6ef..1810ee12666 100644
--- a/DNN Platform/Providers/FolderProviders/FolderProviders.dnn
+++ b/DNN Platform/Providers/FolderProviders/FolderProviders.dnn
@@ -1,6 +1,6 @@
-
+ DotNetNuke Folder ProvidersAzure Folder Providers for DotNetNuke.
diff --git a/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/Browser/Browser.aspx.cs b/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/Browser/Browser.aspx.cs
index 405f03c5d55..87c0f821b5f 100644
--- a/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/Browser/Browser.aspx.cs
+++ b/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/Browser/Browser.aspx.cs
@@ -791,7 +791,7 @@ protected void Page_Load(object sender, EventArgs e)
this.currentSettings,
settingsDictionary,
"DNNCKP#-1#",
- portalRoles);
+ null);
switch (this.currentSettings.SettingMode)
{
@@ -809,7 +809,7 @@ protected void Page_Load(object sender, EventArgs e)
this.currentSettings,
settingsDictionary,
"DNNCKH#",
- portalRoles);
+ null);
break;
case SettingsMode.Portal:
this.currentSettings = SettingsUtil.LoadEditorSettingsByKey(
@@ -2419,10 +2419,20 @@ private void UploadFile(HttpPostedFile file, string command)
}
else
{
- var fileUrl = string.Format(!MapUrl(uploadPhysicalPath).EndsWith("/") ? "{0}/{1}" : "{0}{1}", MapUrl(uploadPhysicalPath), fileName);
- this.Response.ClearContent();
- this.Response.ContentType = "application/json";
- this.Response.Write($"{{\"uploaded\": 1, \"fileName\": \"{fileName}\", \"url\": \"{fileUrl}\"}}");
+ // querystring parameter responseType equals "json" when the request comes from drag/drop
+ if (this.Request.QueryString["responseType"]?.Equals("json", StringComparison.InvariantCultureIgnoreCase) == true)
+ {
+ var fileUrl = string.Format(!MapUrl(uploadPhysicalPath).EndsWith("/") ? "{0}/{1}" : "{0}{1}", MapUrl(uploadPhysicalPath), fileName);
+ this.Response.ClearContent();
+ this.Response.ContentType = "application/json";
+ this.Response.Write($"{{\"uploaded\": 1, \"fileName\": \"{fileName}\", \"url\": \"{fileUrl}\"}}");
+ }
+ else
+ {
+ this.Response.Write("");
+ }
}
this.Response.End();
diff --git a/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/DNNConnect.CKEditorProvider.dnn b/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/DNNConnect.CKEditorProvider.dnn
index d5baef8d64f..72d6dc7706c 100644
--- a/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/DNNConnect.CKEditorProvider.dnn
+++ b/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/DNNConnect.CKEditorProvider.dnn
@@ -1,5 +1,5 @@
-
+ CKEditor ProviderCKEditor Provider for DNN~/Providers/HtmlEditorProviders/DNNConnect.CKE/LogoCKEditor.png
diff --git a/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/Utilities/SettingsUtil.cs b/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/Utilities/SettingsUtil.cs
index d22041be3be..a129aafbb8f 100644
--- a/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/Utilities/SettingsUtil.cs
+++ b/DNN Platform/Providers/HtmlEditorProviders/DNNConnect.CKE/Utilities/SettingsUtil.cs
@@ -267,136 +267,158 @@ internal static EditorProviderSettings LoadEditorSettingsByKey(
currentSettings.Config.CodeMirror.Theme = settingValue;
}
}
+
+ // if we don't have portalRoles, we're in host/allPortals mode
+ // so we can't filter for the roles, since they're not available
+ if ((portalRoles?.Count ?? 0) > 0)
+ {
+ List listToolbarRoles = (from RoleInfo objRole in portalRoles
+ where
+ filteredSettings.Any(
+ setting =>
+ setting.Name.Equals(
+ string.Format(
+ "{0}{2}#{1}",
+ key,
+ objRole.RoleID,
+ SettingConstants.TOOLB)))
+ where
+ !string.IsNullOrEmpty(
+ filteredSettings.FirstOrDefault(
+ s =>
+ s.Name.Equals(
+ string.Format(
+ "{0}{2}#{1}",
+ key,
+ objRole.RoleID,
+ SettingConstants.TOOLB)))
+ .Value)
+ let sToolbar =
+ filteredSettings.FirstOrDefault(
+ s =>
+ s.Name.Equals(
+ string.Format(
+ "{0}{2}#{1}",
+ key,
+ objRole.RoleID,
+ SettingConstants.TOOLB)))
+ .Value
+ select
+ new ToolbarRoles { RoleId = objRole.RoleID, Toolbar = sToolbar })
+ .ToList();
+
+ if (
+ filteredSettings.Any(
+ setting => setting.Name.Equals(string.Format("{0}{2}#{1}", key, "-1", SettingConstants.TOOLB))))
+ {
+ var settingValue =
+ filteredSettings.FirstOrDefault(
+ s => s.Name.Equals(string.Format("{0}{2}#{1}", key, "-1", SettingConstants.TOOLB)))
+ .Value;
- List listToolbarRoles = (from RoleInfo objRole in portalRoles
- where
- filteredSettings.Any(
- setting =>
- setting.Name.Equals(
- string.Format(
- "{0}{2}#{1}",
- key,
- objRole.RoleID,
- SettingConstants.TOOLB)))
- where
- !string.IsNullOrEmpty(
- filteredSettings.FirstOrDefault(
- s =>
- s.Name.Equals(
- string.Format(
- "{0}{2}#{1}",
- key,
- objRole.RoleID,
- SettingConstants.TOOLB))).Value)
- let sToolbar =
- filteredSettings.FirstOrDefault(
- s =>
- s.Name.Equals(
- string.Format(
- "{0}{2}#{1}",
- key,
- objRole.RoleID,
- SettingConstants.TOOLB))).Value
- select
- new ToolbarRoles { RoleId = objRole.RoleID, Toolbar = sToolbar })
- .ToList();
-
- if (
- filteredSettings.Any(
- setting => setting.Name.Equals(string.Format("{0}{2}#{1}", key, "-1", SettingConstants.TOOLB))))
- {
- var settingValue =
- filteredSettings.FirstOrDefault(
- s => s.Name.Equals(string.Format("{0}{2}#{1}", key, "-1", SettingConstants.TOOLB))).Value;
-
- if (!string.IsNullOrEmpty(settingValue))
- {
- listToolbarRoles.Add(new ToolbarRoles { RoleId = -1, Toolbar = settingValue });
+ if (!string.IsNullOrEmpty(settingValue))
+ {
+ listToolbarRoles.Add(new ToolbarRoles { RoleId = -1, Toolbar = settingValue });
+ }
}
- }
- currentSettings.ToolBarRoles = listToolbarRoles;
-
- var listUploadSizeRoles = (from RoleInfo objRole in portalRoles
- where
- filteredSettings.Any(
- setting =>
- setting.Name.Equals(
- string.Format(
- "{0}{1}#{2}",
- key,
- objRole.RoleID,
- SettingConstants.UPLOADFILELIMITS)))
- where
- !string.IsNullOrEmpty(
- filteredSettings.FirstOrDefault(
- s =>
- s.Name.Equals(
- string.Format(
- "{0}{1}#{2}",
- key,
- objRole.RoleID,
- SettingConstants.UPLOADFILELIMITS))).Value)
- let uploadFileLimit =
- filteredSettings.FirstOrDefault(
- s =>
- s.Name.Equals(
- string.Format(
- "{0}{1}#{2}",
- key,
- objRole.RoleID,
- SettingConstants.UPLOADFILELIMITS))).Value
- select
- new UploadSizeRoles { RoleId = objRole.RoleID, RoleName = objRole.RoleName, UploadFileLimit = Convert.ToInt32(uploadFileLimit) })
- .ToList();
-
- if (
- filteredSettings.Any(
- setting => setting.Name.Equals(string.Format("{0}{1}#{2}", key, "-1", SettingConstants.UPLOADFILELIMITS))))
- {
- var settingValue =
- filteredSettings.FirstOrDefault(
- s => s.Name.Equals(string.Format("{0}{1}#{2}", key, "-1", SettingConstants.UPLOADFILELIMITS))).Value;
+ currentSettings.ToolBarRoles = listToolbarRoles;
+
+ var listUploadSizeRoles = (from RoleInfo objRole in portalRoles
+ where
+ filteredSettings.Any(
+ setting =>
+ setting.Name.Equals(
+ string.Format(
+ "{0}{1}#{2}",
+ key,
+ objRole.RoleID,
+ SettingConstants.UPLOADFILELIMITS)))
+ where
+ !string.IsNullOrEmpty(
+ filteredSettings.FirstOrDefault(
+ s =>
+ s.Name.Equals(
+ string.Format(
+ "{0}{1}#{2}",
+ key,
+ objRole.RoleID,
+ SettingConstants.UPLOADFILELIMITS)))
+ .Value)
+ let uploadFileLimit =
+ filteredSettings.FirstOrDefault(
+ s =>
+ s.Name.Equals(
+ string.Format(
+ "{0}{1}#{2}",
+ key,
+ objRole.RoleID,
+ SettingConstants.UPLOADFILELIMITS)))
+ .Value
+ select
+ new UploadSizeRoles
+ {
+ RoleId = objRole.RoleID,
+ RoleName = objRole.RoleName,
+ UploadFileLimit = Convert.ToInt32(uploadFileLimit)
+ })
+ .ToList();
+
+ if (
+ filteredSettings.Any(
+ setting => setting.Name.Equals(
+ string.Format("{0}{1}#{2}", key, "-1", SettingConstants.UPLOADFILELIMITS))))
+ {
+ var settingValue =
+ filteredSettings.FirstOrDefault(
+ s => s.Name.Equals(
+ string.Format("{0}{1}#{2}", key, "-1", SettingConstants.UPLOADFILELIMITS)))
+ .Value;
- if (!string.IsNullOrEmpty(settingValue))
- {
- listUploadSizeRoles.Add(new UploadSizeRoles { RoleId = -1, UploadFileLimit = Convert.ToInt32(settingValue) });
+ if (!string.IsNullOrEmpty(settingValue))
+ {
+ listUploadSizeRoles.Add(
+ new UploadSizeRoles { RoleId = -1, UploadFileLimit = Convert.ToInt32(settingValue) });
+ }
}
- }
-
- currentSettings.UploadSizeRoles = listUploadSizeRoles;
- if (
- filteredSettings.Any(
- setting => setting.Name.Equals(string.Format("{0}{1}", key, SettingConstants.ROLES))))
- {
- var settingValue =
- filteredSettings.FirstOrDefault(
- s => s.Name.Equals(string.Format("{0}{1}", key, SettingConstants.ROLES))).Value;
+ currentSettings.UploadSizeRoles = listUploadSizeRoles;
- if (!string.IsNullOrEmpty(settingValue))
+ if (
+ filteredSettings.Any(
+ setting => setting.Name.Equals(string.Format("{0}{1}", key, SettingConstants.ROLES))))
{
- string sRoles = settingValue;
+ var settingValue =
+ filteredSettings.FirstOrDefault(
+ s => s.Name.Equals(string.Format("{0}{1}", key, SettingConstants.ROLES)))
+ .Value;
- currentSettings.BrowserRoles = sRoles;
+ if (!string.IsNullOrEmpty(settingValue))
+ {
+ string sRoles = settingValue;
- string[] rolesA = sRoles.Split(';');
+ currentSettings.BrowserRoles = sRoles;
- foreach (string sRoleName in rolesA)
- {
- if (Utility.IsNumeric(sRoleName))
+ string[] rolesA = sRoles.Split(';');
+
+ foreach (string sRoleName in rolesA)
{
- RoleInfo roleInfo = RoleController.Instance.GetRoleById(portalSettings.PortalId, int.Parse(sRoleName));
+ if (Utility.IsNumeric(sRoleName))
+ {
+ RoleInfo roleInfo = RoleController.Instance.GetRoleById(
+ portalSettings.PortalId,
+ int.Parse(sRoleName));
- if (roleInfo != null)
+ if (roleInfo != null)
+ {
+ roles.Add(roleInfo.RoleName);
+ }
+ }
+ else
{
- roles.Add(roleInfo.RoleName);
+ roles.Add(sRoleName);
}
}
- else
- {
- roles.Add(sRoleName);
- }
}
}
}
diff --git a/DNN Platform/Skins/Xcillion/DNN_Skin_Xcillion.dnn b/DNN Platform/Skins/Xcillion/DNN_Skin_Xcillion.dnn
index 5cc9fe699ec..2dc3547005b 100644
--- a/DNN Platform/Skins/Xcillion/DNN_Skin_Xcillion.dnn
+++ b/DNN Platform/Skins/Xcillion/DNN_Skin_Xcillion.dnn
@@ -1,6 +1,6 @@
-
+ Xcillion
@@ -29,7 +29,7 @@
-
+ Xcillion
diff --git a/DNN Platform/Tests/App.config b/DNN Platform/Tests/App.config
index e5d70ad3339..95eedde44a2 100644
--- a/DNN Platform/Tests/App.config
+++ b/DNN Platform/Tests/App.config
@@ -221,7 +221,7 @@
-
+
@@ -229,7 +229,7 @@
-
+
diff --git a/DNN Platform/Tests/DNN.Integration.Test.Framework/DNN.Integration.Test.Framework.csproj b/DNN Platform/Tests/DNN.Integration.Test.Framework/DNN.Integration.Test.Framework.csproj
index 48cc3743fda..552d13ffd7b 100644
--- a/DNN Platform/Tests/DNN.Integration.Test.Framework/DNN.Integration.Test.Framework.csproj
+++ b/DNN Platform/Tests/DNN.Integration.Test.Framework/DNN.Integration.Test.Framework.csproj
@@ -1,6 +1,6 @@
-
+
@@ -64,8 +64,8 @@
..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.9\lib\net45\System.Net.Http.Formatting.dll
-
- ..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+
+ ..\..\..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
@@ -143,7 +143,7 @@
-
+
diff --git a/DNN Platform/Tests/DNN.Integration.Test.Framework/app.config b/DNN Platform/Tests/DNN.Integration.Test.Framework/app.config
index eac412fe488..2c0cf2cdc75 100644
--- a/DNN Platform/Tests/DNN.Integration.Test.Framework/app.config
+++ b/DNN Platform/Tests/DNN.Integration.Test.Framework/app.config
@@ -10,6 +10,10 @@
+
+
+
+
diff --git a/DNN Platform/Tests/DNN.Integration.Test.Framework/packages.config b/DNN Platform/Tests/DNN.Integration.Test.Framework/packages.config
index a9088b21258..52935cfafa9 100644
--- a/DNN Platform/Tests/DNN.Integration.Test.Framework/packages.config
+++ b/DNN Platform/Tests/DNN.Integration.Test.Framework/packages.config
@@ -9,8 +9,8 @@
-
+
-
+
\ No newline at end of file
diff --git a/DNN Platform/Tests/DotNetNuke.Tests.AspNetCCP/App.config b/DNN Platform/Tests/DotNetNuke.Tests.AspNetCCP/App.config
index 4331fbdb811..9bd1f3aaa66 100644
--- a/DNN Platform/Tests/DotNetNuke.Tests.AspNetCCP/App.config
+++ b/DNN Platform/Tests/DotNetNuke.Tests.AspNetCCP/App.config
@@ -14,6 +14,10 @@
+
+
+
+
\ No newline at end of file
diff --git a/DNN Platform/Tests/DotNetNuke.Tests.AspNetCCP/DotNetNuke.Tests.AspNetCCP.csproj b/DNN Platform/Tests/DotNetNuke.Tests.AspNetCCP/DotNetNuke.Tests.AspNetCCP.csproj
index 144835bf063..dc4eee72287 100644
--- a/DNN Platform/Tests/DotNetNuke.Tests.AspNetCCP/DotNetNuke.Tests.AspNetCCP.csproj
+++ b/DNN Platform/Tests/DotNetNuke.Tests.AspNetCCP/DotNetNuke.Tests.AspNetCCP.csproj
@@ -1,6 +1,6 @@
-
+ Debug
@@ -58,8 +58,8 @@
-
- ..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+
+ ..\..\..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll..\..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
@@ -118,7 +118,7 @@
-
+
diff --git a/DNN Platform/Tests/DotNetNuke.Tests.Web/packages.config b/DNN Platform/Tests/DotNetNuke.Tests.Web/packages.config
index bfd53b42cb4..9e501fa0571 100644
--- a/DNN Platform/Tests/DotNetNuke.Tests.Web/packages.config
+++ b/DNN Platform/Tests/DotNetNuke.Tests.Web/packages.config
@@ -10,9 +10,9 @@
-
+
-
+
\ No newline at end of file
diff --git a/DNN Platform/Website/App_GlobalResources/GlobalResources.resx b/DNN Platform/Website/App_GlobalResources/GlobalResources.resx
index 3ec0c024b52..50af1eff426 100644
--- a/DNN Platform/Website/App_GlobalResources/GlobalResources.resx
+++ b/DNN Platform/Website/App_GlobalResources/GlobalResources.resx
@@ -1361,9 +1361,8 @@ Sincerely,
Dear [User:DisplayName],
-You have requested a Password Reset Token from [Portal:PortalName], but Your account is pending approval.
-
-Password can be reset after account is approved.
+You have requested a Password Reset Token from [Portal:PortalName], but your account is pending approval.
+The administrator for [Portal:PortalName] has been notified for review and will issue another password reset email if your account is approved.
Sincerely,
[Portal:PortalName]
@@ -1374,6 +1373,18 @@ Sincerely,
[Portal:PortalName] Password Reminder
+
+
+The following user has requested a Password Reset Token from [Portal:PortalName], but the user account is pending approval.
+User Name: [User:UserName]
+Display Name: [User:DisplayName]
+
+After reviewing this user, if the account is authorized, resend the user a password reset email.
+
+
+
+ [Portal:PortalName] Password Reminder requested for unapproved User [User:Username]
+
{0} - 503 Service Unavailable
diff --git a/DNN Platform/Website/Providers/DataProviders/SqlDataProvider/09.12.00.SqlDataProvider b/DNN Platform/Website/Providers/DataProviders/SqlDataProvider/09.12.00.SqlDataProvider
new file mode 100644
index 00000000000..343b722cfe1
--- /dev/null
+++ b/DNN Platform/Website/Providers/DataProviders/SqlDataProvider/09.12.00.SqlDataProvider
@@ -0,0 +1,9 @@
+/************************************************************/
+/***** SqlDataProvider *****/
+/***** *****/
+/***** *****/
+/***** Note: To manually execute this script you must *****/
+/***** perform a search and replace operation *****/
+/***** for {databaseOwner} and {objectQualifier} *****/
+/***** *****/
+/************************************************************/
diff --git a/DNN Platform/Website/admin/Containers/Icon.ascx.cs b/DNN Platform/Website/admin/Containers/Icon.ascx.cs
index 5734a6e8678..8d70bb90167 100644
--- a/DNN Platform/Website/admin/Containers/Icon.ascx.cs
+++ b/DNN Platform/Website/admin/Containers/Icon.ascx.cs
@@ -11,17 +11,16 @@ namespace DotNetNuke.UI.Containers
using DotNetNuke.Services.FileSystem;
using DotNetNuke.UI.Skins;
- /// Project : DotNetNuke
- /// Class : DotNetNuke.UI.Containers.Icon
- ///
///
/// Contains the attributes of an Icon.
/// These are read into the PortalModuleBase collection as attributes for the icons within the module controls.
///
public partial class Icon : SkinObjectBase
{
+ /// Gets or sets the border width of the icon.
public string BorderWidth { get; set; }
+ /// Gets or sets the CSS class on the img element.
public string CssClass { get; set; }
///
@@ -42,21 +41,25 @@ protected override void OnLoad(EventArgs e)
}
this.Visible = false;
- if ((this.ModuleControl != null) && (this.ModuleControl.ModuleContext.Configuration != null))
+ if (this.ModuleControl?.ModuleContext.Configuration == null)
{
- var iconFile = this.GetIconFileUrl();
- if (!string.IsNullOrEmpty(iconFile))
- {
- if (Globals.IsAdminControl())
- {
- iconFile = $"~/DesktopModules/{this.ModuleControl.ModuleContext.Configuration.DesktopModule.FolderName}/{iconFile}";
- }
+ return;
+ }
+
+ var iconFile = this.GetIconFileUrl();
+ if (string.IsNullOrEmpty(iconFile))
+ {
+ return;
+ }
- this.imgIcon.ImageUrl = iconFile;
- this.imgIcon.AlternateText = this.ModuleControl.ModuleContext.Configuration.ModuleTitle;
- this.Visible = true;
- }
+ if (!iconFile.StartsWith("~", StringComparison.Ordinal) && Globals.IsAdminControl())
+ {
+ iconFile = $"~/DesktopModules/{this.ModuleControl.ModuleContext.Configuration.DesktopModule.FolderName}/{iconFile}";
}
+
+ this.imgIcon.ImageUrl = iconFile;
+ this.imgIcon.AlternateText = this.ModuleControl.ModuleContext.Configuration.ModuleTitle;
+ this.Visible = true;
}
catch (Exception exc)
{
@@ -67,7 +70,7 @@ protected override void OnLoad(EventArgs e)
private string GetIconFileUrl()
{
var iconFile = this.ModuleControl.ModuleContext.Configuration.IconFile;
- if (string.IsNullOrEmpty(iconFile) || iconFile.StartsWith("~"))
+ if (string.IsNullOrEmpty(iconFile) || iconFile.StartsWith("~", StringComparison.Ordinal))
{
return iconFile;
}
diff --git a/DNN Platform/Website/admin/Security/SendPassword.ascx.cs b/DNN Platform/Website/admin/Security/SendPassword.ascx.cs
index 943b7b4b1f8..0c2d54e5dee 100644
--- a/DNN Platform/Website/admin/Security/SendPassword.ascx.cs
+++ b/DNN Platform/Website/admin/Security/SendPassword.ascx.cs
@@ -243,6 +243,7 @@ protected void OnSendPasswordClick(object sender, EventArgs e)
if (this.user.Membership.Approved == false)
{
Mail.SendMail(this.user, MessageType.PasswordReminderUserIsNotApproved, this.PortalSettings);
+ Mail.SendMail(this.user, MessageType.PasswordReminderUserIsNotApprovedAdmin, this.PortalSettings);
canSend = false;
}
diff --git a/DNN_Platform.sln b/DNN_Platform.sln
index 5b674d1cb56..6d7d9e510cb 100644
--- a/DNN_Platform.sln
+++ b/DNN_Platform.sln
@@ -571,6 +571,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetNuke.Tests.Modules",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetNuke.Maintenance", "DNN Platform\DotNetNuke.Maintenance\DotNetNuke.Maintenance.csproj", "{1D5A98BD-F8E0-45F7-B26D-270D9023629D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dnn.GoogleAnalytics4Connector", "DNN Platform\Connectors\GoogleAnalytics4\Dnn.GoogleAnalytics4Connector.csproj", "{94E12995-181A-4114-90C7-3F9557F28DE7}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Cloud_Debug|Any CPU = Cloud_Debug|Any CPU
@@ -2085,6 +2087,30 @@ Global
{1D5A98BD-F8E0-45F7-B26D-270D9023629D}.Release-Net45|Any CPU.Build.0 = Release|Any CPU
{1D5A98BD-F8E0-45F7-B26D-270D9023629D}.Release-Net45|x86.ActiveCfg = Release|Any CPU
{1D5A98BD-F8E0-45F7-B26D-270D9023629D}.Release-Net45|x86.Build.0 = Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Cloud_Debug|Any CPU.ActiveCfg = Cloud_Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Cloud_Debug|Any CPU.Build.0 = Cloud_Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Cloud_Debug|x86.ActiveCfg = Cloud_Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Cloud_Debug|x86.Build.0 = Cloud_Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Cloud_Release|Any CPU.ActiveCfg = Cloud_Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Cloud_Release|Any CPU.Build.0 = Cloud_Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Cloud_Release|x86.ActiveCfg = Cloud_Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Cloud_Release|x86.Build.0 = Cloud_Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Debug|x86.Build.0 = Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Debug-Net45|Any CPU.ActiveCfg = Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Debug-Net45|Any CPU.Build.0 = Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Debug-Net45|x86.ActiveCfg = Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Debug-Net45|x86.Build.0 = Debug|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Release|x86.ActiveCfg = Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Release|x86.Build.0 = Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Release-Net45|Any CPU.ActiveCfg = Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Release-Net45|Any CPU.Build.0 = Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Release-Net45|x86.ActiveCfg = Release|Any CPU
+ {94E12995-181A-4114-90C7-3F9557F28DE7}.Release-Net45|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2205,6 +2231,7 @@ Global
{21ACF0F1-2A5F-47D2-A0F4-09C95ACF8ABA} = {FDDC95FE-3341-4AED-A93E-7A5DF85A55C2}
{EEFFEA77-4FA5-4498-9A9C-1BDBD6436E43} = {88E649D7-1379-430F-B794-1F3B9B442C80}
{1D5A98BD-F8E0-45F7-B26D-270D9023629D} = {29273BE6-1AA8-4970-98A0-41BFFEEDA67B}
+ {94E12995-181A-4114-90C7-3F9557F28DE7} = {9A986091-4238-4804-8C86-6A9A005F72C2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {46B6A641-57EB-4B19-B199-23E6FC2AB40B}
diff --git a/Dnn.AdminExperience/ClientSide/AdminLogs.Web/package.json b/Dnn.AdminExperience/ClientSide/AdminLogs.Web/package.json
index 4eabd4ce4f1..b8c1391a943 100644
--- a/Dnn.AdminExperience/ClientSide/AdminLogs.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/AdminLogs.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "admin-logs",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"lint": "eslint --fix"
},
"devDependencies": {
@@ -14,7 +14,7 @@
"@babel/plugin-transform-object-assign": "^7.0.0",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"array.prototype.find": "2.0.4",
"array.prototype.findindex": "2.0.2",
"babel-loader": "8.0.6",
diff --git a/Dnn.AdminExperience/ClientSide/Bundle.Web/package.json b/Dnn.AdminExperience/ClientSide/Bundle.Web/package.json
index c6f9d6e6767..535c251a503 100644
--- a/Dnn.AdminExperience/ClientSide/Bundle.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Bundle.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "export-bundle",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production --progress",
"debug": "set NODE_ENV=debug&&webpack --mode production --progress",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --config webpack.config.js --profile --json > stats.json&&webpack-bundle-analyzer stats.json",
"lint": "eslint --fix"
},
@@ -66,6 +66,6 @@
"webpack-dev-server": "4.11.1"
},
"dependencies": {
- "@dnnsoftware/dnn-react-common": "9.11.1"
+ "@dnnsoftware/dnn-react-common": "9.12.0"
}
}
diff --git a/Dnn.AdminExperience/ClientSide/Dnn.React.Common/package.json b/Dnn.AdminExperience/ClientSide/Dnn.React.Common/package.json
index a1fa6989453..8893463edc6 100644
--- a/Dnn.AdminExperience/ClientSide/Dnn.React.Common/package.json
+++ b/Dnn.AdminExperience/ClientSide/Dnn.React.Common/package.json
@@ -1,6 +1,6 @@
{
"name": "@dnnsoftware/dnn-react-common",
- "version": "9.11.1",
+ "version": "9.12.0",
"description": "DNN React Component Library",
"main": "dist/dnn-react-common.min.js",
"repository": {
diff --git a/Dnn.AdminExperience/ClientSide/Extensions.Web/package.json b/Dnn.AdminExperience/ClientSide/Extensions.Web/package.json
index 2b3f794dd02..343d8c98513 100644
--- a/Dnn.AdminExperience/ClientSide/Extensions.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Extensions.Web/package.json
@@ -1,18 +1,18 @@
{
"name": "extensions",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer"
},
"devDependencies": {
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"babel-loader": "8.0.6",
"babel-plugin-transform-object-assign": "6.22.0",
"babel-plugin-transform-object-rest-spread": "6.26.0",
diff --git a/Dnn.AdminExperience/ClientSide/Licensing.Web/package.json b/Dnn.AdminExperience/ClientSide/Licensing.Web/package.json
index 4a8a8f1b64b..a10d9c074a0 100644
--- a/Dnn.AdminExperience/ClientSide/Licensing.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Licensing.Web/package.json
@@ -1,18 +1,18 @@
{
"name": "licensing",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer"
},
"devDependencies": {
"@babel/core": "^7.1.6",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"array.prototype.find": "2.0.4",
"array.prototype.findindex": "2.0.2",
"babel-loader": "8.0.6",
diff --git a/Dnn.AdminExperience/ClientSide/Pages.Web/package.json b/Dnn.AdminExperience/ClientSide/Pages.Web/package.json
index fd4e980b8f6..35eceb142c3 100644
--- a/Dnn.AdminExperience/ClientSide/Pages.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Pages.Web/package.json
@@ -1,6 +1,6 @@
{
"name": "pages",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"start": "npm run webpack",
@@ -8,7 +8,7 @@
"test:watch": "jest --watch",
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -23,7 +23,7 @@
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"@types/knockout": "^3.4.66",
"@types/redux": "3.6.31",
"babel-eslint": "^10.0.1",
diff --git a/Dnn.AdminExperience/ClientSide/Prompt.Web/package.json b/Dnn.AdminExperience/ClientSide/Prompt.Web/package.json
index e0d25860990..be17d841b3b 100644
--- a/Dnn.AdminExperience/ClientSide/Prompt.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Prompt.Web/package.json
@@ -1,12 +1,12 @@
{
"name": "prompt",
- "version": "9.11.1",
+ "version": "9.12.0",
"description": "DNN Prompt",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=analyze&&webpack-dev-server -d --port 8100 --hot --inline --content-base dist/ --history-api-fallback",
"test": "jest",
"lint": "eslint --fix"
@@ -15,7 +15,7 @@
"@babel/core": "^7.1.6",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"array.prototype.find": "2.0.4",
"array.prototype.findindex": "2.0.2",
"babel-eslint": "^10.0.1",
diff --git a/Dnn.AdminExperience/ClientSide/Roles.Web/package.json b/Dnn.AdminExperience/ClientSide/Roles.Web/package.json
index 1b8e664cde9..35e30d66dc2 100644
--- a/Dnn.AdminExperience/ClientSide/Roles.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Roles.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "roles",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -13,7 +13,7 @@
"@babel/core": "^7.1.6",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"array.prototype.find": "^2.0.0",
"array.prototype.findindex": "^2.0.0",
"babel-loader": "^8.0.6",
diff --git a/Dnn.AdminExperience/ClientSide/Security.Web/package.json b/Dnn.AdminExperience/ClientSide/Security.Web/package.json
index 751c41aa12a..be55c41dbf4 100644
--- a/Dnn.AdminExperience/ClientSide/Security.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Security.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "security-settings",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -15,7 +15,7 @@
"@babel/plugin-transform-react-jsx": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"babel-loader": "8.0.6",
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
"create-react-class": "^15.6.3",
diff --git a/Dnn.AdminExperience/ClientSide/Seo.Web/package.json b/Dnn.AdminExperience/ClientSide/Seo.Web/package.json
index 2fa2b9f4d6d..a51c59fe94d 100644
--- a/Dnn.AdminExperience/ClientSide/Seo.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Seo.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "seo",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -14,7 +14,7 @@
"@babel/plugin-proposal-object-rest-spread": "^7.2.0",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"array.prototype.find": "2.0.4",
"array.prototype.findindex": "2.0.2",
"babel-loader": "8.0.6",
diff --git a/Dnn.AdminExperience/ClientSide/Servers.Web/package.json b/Dnn.AdminExperience/ClientSide/Servers.Web/package.json
index 5bf510b6c77..1da5005e2f9 100644
--- a/Dnn.AdminExperience/ClientSide/Servers.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Servers.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "servers",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -14,7 +14,7 @@
"@babel/plugin-proposal-object-rest-spread": "^7.2.0",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"@types/redux": "^3.6.31",
"babel-loader": "8.0.6",
"babel-plugin-transform-object-assign": "6.22.0",
diff --git a/Dnn.AdminExperience/ClientSide/SiteGroups.Web/package.json b/Dnn.AdminExperience/ClientSide/SiteGroups.Web/package.json
index a4744c33fe2..9aa958b1428 100644
--- a/Dnn.AdminExperience/ClientSide/SiteGroups.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/SiteGroups.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "dnn-sitegroups",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -15,7 +15,7 @@
"@babel/plugin-transform-object-assign": "7.12.13",
"@babel/preset-env": "7.1.6",
"@babel/preset-react": "7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"babel-loader": "8.0.6",
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
"babel-polyfill": "6.26.0",
diff --git a/Dnn.AdminExperience/ClientSide/SiteImportExport.Web/package.json b/Dnn.AdminExperience/ClientSide/SiteImportExport.Web/package.json
index 0ac7e4bc3be..4bc533e2464 100644
--- a/Dnn.AdminExperience/ClientSide/SiteImportExport.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/SiteImportExport.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "site-import-export",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -15,7 +15,7 @@
"@babel/plugin-transform-react-jsx": "^7.2.0",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"babel-eslint": "^10.0.1",
"babel-loader": "8.0.6",
"babel-plugin-transform-class-properties": "^6.22.0",
diff --git a/Dnn.AdminExperience/ClientSide/SiteSettings.Web/package.json b/Dnn.AdminExperience/ClientSide/SiteSettings.Web/package.json
index d83025eb560..2d7d202c3e1 100644
--- a/Dnn.AdminExperience/ClientSide/SiteSettings.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/SiteSettings.Web/package.json
@@ -1,13 +1,13 @@
{
"name": "site-settings",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"test": "jest",
"test:watch": "jest --watch",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -17,7 +17,7 @@
"@babel/plugin-transform-react-jsx": "^7.2.0",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"array.prototype.find": "2.0.4",
"array.prototype.findindex": "2.0.2",
"babel-loader": "^8.0.6",
diff --git a/Dnn.AdminExperience/ClientSide/SiteSettings.Web/src/components/editLanguagePanel/index.jsx b/Dnn.AdminExperience/ClientSide/SiteSettings.Web/src/components/editLanguagePanel/index.jsx
index c1a22a4c483..0c6c77d5ae0 100644
--- a/Dnn.AdminExperience/ClientSide/SiteSettings.Web/src/components/editLanguagePanel/index.jsx
+++ b/Dnn.AdminExperience/ClientSide/SiteSettings.Web/src/components/editLanguagePanel/index.jsx
@@ -134,7 +134,7 @@ class EditLanguagePanel extends Component {
value: "Host"
},
{
- label: props.portalName,
+ label: resx.get("Portal"),
value: "Portal"
}
];
diff --git a/Dnn.AdminExperience/ClientSide/Sites.Web/package.json b/Dnn.AdminExperience/ClientSide/Sites.Web/package.json
index 9af739041fc..43507ad7f7e 100644
--- a/Dnn.AdminExperience/ClientSide/Sites.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Sites.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "sites",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -15,7 +15,7 @@
"@babel/plugin-transform-object-assign": "7.12.13",
"@babel/preset-env": "7.1.6",
"@babel/preset-react": "7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"babel-loader": "8.0.6",
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
"babel-polyfill": "6.26.0",
diff --git a/Dnn.AdminExperience/ClientSide/Sites.Web/src/_exportables/package.json b/Dnn.AdminExperience/ClientSide/Sites.Web/src/_exportables/package.json
index 0bcdc8d95ad..2c5fa1c7a67 100644
--- a/Dnn.AdminExperience/ClientSide/Sites.Web/src/_exportables/package.json
+++ b/Dnn.AdminExperience/ClientSide/Sites.Web/src/_exportables/package.json
@@ -1,11 +1,11 @@
{
"name": "dnn-sites-list-view",
- "version": "9.11.1",
+ "version": "9.12.0",
"description": "DNN Sites List View",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "set NODE_ENV=production&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch"
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch"
},
"license": "UNLICENSED",
"devDependencies": {
@@ -14,7 +14,7 @@
"@babel/plugin-transform-object-assign": "7.12.13",
"@babel/preset-env": "7.1.6",
"@babel/preset-react": "7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"babel-loader": "8.0.4",
"babel-plugin-transform-react-remove-prop-types": "0.4.20",
"babel-polyfill": "6.26.0",
diff --git a/Dnn.AdminExperience/ClientSide/TaskScheduler.Web/package.json b/Dnn.AdminExperience/ClientSide/TaskScheduler.Web/package.json
index b12dcd6fa61..d742092f1c6 100644
--- a/Dnn.AdminExperience/ClientSide/TaskScheduler.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/TaskScheduler.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "task-scheduler",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -14,7 +14,7 @@
"@babel/plugin-proposal-object-rest-spread": "^7.2.0",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"array.prototype.find": "2.0.4",
"array.prototype.findindex": "2.0.2",
"babel-loader": "8.0.6",
diff --git a/Dnn.AdminExperience/ClientSide/Themes.Web/package.json b/Dnn.AdminExperience/ClientSide/Themes.Web/package.json
index 2c4b8b8c5b1..ddcaf01211f 100644
--- a/Dnn.AdminExperience/ClientSide/Themes.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Themes.Web/package.json
@@ -1,11 +1,11 @@
{
"name": "themes",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -14,7 +14,7 @@
"@babel/plugin-proposal-object-rest-spread": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"babel-loader": "8.0.6",
"babel-plugin-transform-object-assign": "6.22.0",
"babel-plugin-transform-object-rest-spread": "6.26.0",
diff --git a/Dnn.AdminExperience/ClientSide/Users.Web/package.json b/Dnn.AdminExperience/ClientSide/Users.Web/package.json
index d0b65ef87d8..823abde4ee9 100644
--- a/Dnn.AdminExperience/ClientSide/Users.Web/package.json
+++ b/Dnn.AdminExperience/ClientSide/Users.Web/package.json
@@ -1,13 +1,13 @@
{
"name": "users",
- "version": "9.11.1",
+ "version": "9.12.0",
"private": true,
"scripts": {
"start": "npm run webpack",
"test": "jest",
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch",
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch",
"analyze": "set NODE_ENV=production&&webpack --mode production --json | webpack-bundle-size-analyzer",
"lint": "eslint --fix"
},
@@ -52,7 +52,7 @@
"webpack-dev-server": "4.11.1"
},
"dependencies": {
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"localization": "^1.0.2",
"react-widgets": "^4.4.6"
}
diff --git a/Dnn.AdminExperience/ClientSide/Users.Web/src/_exportables/package.json b/Dnn.AdminExperience/ClientSide/Users.Web/src/_exportables/package.json
index 554bd31ae65..f75183c2fc8 100644
--- a/Dnn.AdminExperience/ClientSide/Users.Web/src/_exportables/package.json
+++ b/Dnn.AdminExperience/ClientSide/Users.Web/src/_exportables/package.json
@@ -1,13 +1,13 @@
{
"name": "dnn-users-exportables",
- "version": "9.11.1",
+ "version": "9.12.0",
"description": "DNN Users Exportables",
"scripts": {
"start": "npm run webpack",
"test": "echo \"Error: no test specified\" && exit 1",
"build": "set NODE_ENV=production&&webpack --mode production",
"debug": "set NODE_ENV=debug&&webpack --mode production",
- "watch": "set NODE_ENV=debug & webpack --mode=development --progress --colors --watch"
+ "watch": "set NODE_ENV=debug & webpack --mode=development --progress --watch"
},
"license": "UNLICENSED",
"devDependencies": {
@@ -16,7 +16,7 @@
"@babel/plugin-transform-react-jsx": "^7.1.6",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
- "@dnnsoftware/dnn-react-common": "9.11.1",
+ "@dnnsoftware/dnn-react-common": "9.12.0",
"babel-loader": "8.0.6",
"create-react-class": "^15.6.3",
"css-loader": "2.1.1",
diff --git a/Dnn.AdminExperience/ClientSide/Users.Web/src/_exportables/src/components/UserTable/DetailRow/index.jsx b/Dnn.AdminExperience/ClientSide/Users.Web/src/_exportables/src/components/UserTable/DetailRow/index.jsx
index 32c02bdba9c..cb7b37eb666 100644
--- a/Dnn.AdminExperience/ClientSide/Users.Web/src/_exportables/src/components/UserTable/DetailRow/index.jsx
+++ b/Dnn.AdminExperience/ClientSide/Users.Web/src/_exportables/src/components/UserTable/DetailRow/index.jsx
@@ -133,18 +133,26 @@ class DetailsRow extends Component {
userColumns = userColumns.concat([
{
index: 5,
- content: x.index===5).size} className={"user-names" + (user.isDeleted ? " deleted" : "") }>
-