diff --git a/Archive/cloudscribeTemplate_8.6_net80_bs5_vs2022.vsix b/Archive/cloudscribeTemplate_8.6_net80_bs5_vs2022.vsix
new file mode 100644
index 0000000..9434b0c
Binary files /dev/null and b/Archive/cloudscribeTemplate_8.6_net80_bs5_vs2022.vsix differ
diff --git a/Content/WebApp/Config/DataProtection.cs b/Content/WebApp/Config/DataProtection.cs
index 2b8a839..b9c3170 100644
--- a/Content/WebApp/Config/DataProtection.cs
+++ b/Content/WebApp/Config/DataProtection.cs
@@ -23,9 +23,10 @@ IWebHostEnvironment environment
// if you move an app to different hosting and the keys change then you would have
// to update those settings again from the Administration UI
- // for IIS hosting you should use a powershell script to create a keyring in the registry
- // per application pool and use a different application pool per app
- // https://docs.microsoft.com/en-us/aspnet/core/publishing/iis#data-protection
+ // For modern IIS hosting, the default location of keys is now within the file system of the Application Pool user:
+ // "C:\Users\[your-app-pool-name]\AppData\Local\ASP.NET\DataProtection-Keys\*.xml
+ // You should use a different application pool per app.
+ // See also:
// https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?tabs=aspnetcore2x
if (environment.IsProduction())
{
diff --git a/Content/WebApp/GlobalResources/CloudscribeCore.cy.resx b/Content/WebApp/GlobalResources/CloudscribeCore.cy.resx
index ade8869..f4e5fb7 100644
--- a/Content/WebApp/GlobalResources/CloudscribeCore.cy.resx
+++ b/Content/WebApp/GlobalResources/CloudscribeCore.cy.resx
@@ -2240,4 +2240,16 @@
Arhoswch tra bod y rhaglen yn ailgychwyn...
+
+ Methwyd diweddaru - gweler y gwallau dilysu isod.
+
+
+ Mae'r Enw Arddangos eisoes yn cael ei ddefnyddio gan ddefnyddiwr arall.
+
+
+ Ni all Enw Arddangos gynnwys HTML, tagiau sgript, na chynnwys gweithredadwy.
+
+
+ Rhaid i Enw Arddangos fod yn 100 nod neu lai.
+
\ No newline at end of file
diff --git a/Content/WebApp/GlobalResources/CloudscribeCore.en-GB.resx b/Content/WebApp/GlobalResources/CloudscribeCore.en-GB.resx
index e54ec31..229ac16 100644
--- a/Content/WebApp/GlobalResources/CloudscribeCore.en-GB.resx
+++ b/Content/WebApp/GlobalResources/CloudscribeCore.en-GB.resx
@@ -1886,4 +1886,16 @@
Please wait while the application restarts...
+
+ Update failed - please see the validation errors below.
+
+
+ Display Name is already in use by another user.
+
+
+ Display Name cannot contain HTML, script tags, or executable content.
+
+
+ Display Name must be 100 characters or fewer.
+
\ No newline at end of file
diff --git a/Content/WebApp/GlobalResources/CloudscribeCore.en-US.resx b/Content/WebApp/GlobalResources/CloudscribeCore.en-US.resx
index 2f94680..0f5594d 100644
--- a/Content/WebApp/GlobalResources/CloudscribeCore.en-US.resx
+++ b/Content/WebApp/GlobalResources/CloudscribeCore.en-US.resx
@@ -1858,4 +1858,16 @@
Please wait while the application restarts...
+
+ Update failed - please see the validation errors below.
+
+
+ Display Name is already in use by another user.
+
+
+ Display Name cannot contain HTML, script tags, or executable content.
+
+
+ Display Name must be 100 characters or fewer.
+
\ No newline at end of file
diff --git a/Content/WebApp/GlobalResources/CloudscribeCore.resx b/Content/WebApp/GlobalResources/CloudscribeCore.resx
index 119d3e5..c6ff1ff 100644
--- a/Content/WebApp/GlobalResources/CloudscribeCore.resx
+++ b/Content/WebApp/GlobalResources/CloudscribeCore.resx
@@ -1946,4 +1946,16 @@
Please wait while the application restarts...
+
+ Update failed - please see the validation errors below.
+
+
+ Display Name is already in use by another user.
+
+
+ Display Name cannot contain HTML, script tags, or executable content.
+
+
+ Display Name must be 100 characters or fewer.
+
\ No newline at end of file
diff --git a/Content/WebApp/WebApp.csproj b/Content/WebApp/WebApp.csproj
index 2d99409..9a9f700 100644
--- a/Content/WebApp/WebApp.csproj
+++ b/Content/WebApp/WebApp.csproj
@@ -43,312 +43,312 @@
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
diff --git a/Content/WebApp/app-scss/_variables.scss b/Content/WebApp/app-scss/_variables.scss
index 86c891e..b3b27b7 100644
--- a/Content/WebApp/app-scss/_variables.scss
+++ b/Content/WebApp/app-scss/_variables.scss
@@ -2,9 +2,11 @@
$mybrand: #03378d;
+// Bootstrap 5 Variables - this file was brought forward from old usage of BS4, but now we're using BS5
+// - should all be backwards compatible.
-// Bootstrap 4 Variables
-// Every Sass variable in Bootstrap 4 includes the !default flag allowing you to override the variables default value in your own Sass without modifying Bootstrap source code.
+
+// Every Sass variable in Bootstrap includes the !default flag allowing you to override the variables default value in your own Sass without modifying Bootstrap source code.
// Uncomment variables as needed, modify their values in this file as needed but don't uncomment ones that you don't need to customize.
// If a variable has already been assigned, then it wont be re-assigned by the default values in Bootstrap.
diff --git a/Content/WebApp/package.json b/Content/WebApp/package.json
index 3e69ca8..48b3cf2 100644
--- a/Content/WebApp/package.json
+++ b/Content/WebApp/package.json
@@ -3,54 +3,54 @@
"version": "1.0.0",
"private": true,
"devDependencies": {
- "@fortawesome/fontawesome-free": "^5.15.4",
+ "@fortawesome/fontawesome-free": "5.15.4",
"bootstrap": "5.1.3",
- "clean-css": "^5.2.2",
- "cssnano": "^7.0.6",
- "gulp": "^5.0.0",
- "gulp-cli": "^3.0.0",
- "gulp-concat": "^2.6.1",
- "gulp-connect": "^5.7.0",
- "gulp-postcss": "^10.0.0",
- "gulp-rename": "^2.0.0",
- "gulp-sass": "^5.1.0",
- "gulp-uglify": "^3.0.2",
- "merge-stream": "^2.0.0",
- "smartmenus": "^1.1.1",
- "smartmenus-bootstrap-4": "^0.1.0",
- "sass": "^1.53.0"
+ "clean-css": "5.2.2",
+ "cssnano": "7.0.6",
+ "gulp": "5.0.0",
+ "gulp-cli": "3.0.0",
+ "gulp-concat": "2.6.1",
+ "gulp-connect": "5.7.0",
+ "gulp-postcss": "10.0.0",
+ "gulp-rename": "2.0.0",
+ "gulp-sass": "5.1.0",
+ "gulp-uglify": "3.0.2",
+ "merge-stream": "2.0.0",
+ "smartmenus": "1.1.1",
+ "smartmenus-bootstrap-4": "0.1.0",
+ "sass": "1.53.0"
//#if (React)
,
- "@types/react": "^19.0.3",
- "@types/react-dom": "^19.0.2",
- "@types/webpack-env": "^1.13.0",
- "ts-loader": "^8.0.2",
- "css-loader": "^7.1.2",
- "typescript": "^4.2.4",
- "webpack": "^5.97.1",
- "webpack-cli": "^6.0.1",
- "webpack-merge": "^5.1.3",
- "prettier": "^3.4.2",
- "eslint": "^9.17.0",
- "react": "^19.0.0",
- "react-dom": "^19.0.0",
- "react-hook-form": "^7.54.2",
- "react-router": "^7.1.3",
- "style-loader": "^4.0.0",
- "yup": "^1.6.1",
- "@tanstack/react-query": "^5.64.2",
- "axios": "^1.7.9",
- "@reduxjs/toolkit": "^2.5.1",
- "react-redux": "^9.2.0",
- "webpack-livereload-plugin": "^3.0.2"
+ "@types/react": "19.0.3",
+ "@types/react-dom": "19.0.2",
+ "@types/webpack-env": "1.13.0",
+ "ts-loader": "8.0.2",
+ "css-loader": "7.1.2",
+ "typescript": "4.2.4",
+ "webpack": "5.97.1",
+ "webpack-cli": "6.0.1",
+ "webpack-merge": "5.1.3",
+ "prettier": "3.4.2",
+ "eslint": "9.17.0",
+ "react": "19.0.0",
+ "react-dom": "19.0.0",
+ "react-hook-form": "7.54.2",
+ "react-router": "7.1.3",
+ "style-loader": "4.0.0",
+ "yup": "1.6.1",
+ "@tanstack/react-query": "5.64.2",
+ "axios": "1.7.9",
+ "@reduxjs/toolkit": "2.5.1",
+ "react-redux": "9.2.0",
+ "webpack-livereload-plugin": "3.0.2"
//#endif
}
//#if (React)
,
"scripts": {
- "build-tsx-react": "(set NODE_OPTIONS=--openssl-legacy-provider) && webpack",
- "watch-tsx-react": "(set NODE_OPTIONS=--openssl-legacy-provider) && webpack --watch",
+ "build-tsx-react": "webpack",
+ "watch-tsx-react": "webpack --watch",
"format": "prettier ./Scripts/React/**/* --write",
"lint": "eslint ./Scripts/React/**/* --fix"
}
diff --git a/Content/WebApp/readme.html b/Content/WebApp/readme.html
index 1193b04..c784c59 100644
--- a/Content/WebApp/readme.html
+++ b/Content/WebApp/readme.html
@@ -75,7 +75,7 @@
Next Steps
Data Protection
- Be sure to see the comments in Startup.cs about data protection and how to configure the storage location of data protection keys.
+ Be sure to see the comments in DataProtection.cs about data protection and how to configure the storage location of data protection keys.
Data protection keys are used to encrypt some settings that are persisted to data storage such as the password for SMTP, and the "secrets"
for social authentication.
diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index 2def039..4f0eb58 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -1,5 +1,52 @@
## Release Notes
+### version 8.6.0 - November 2025
+
+#### **Breaking Changes**
+
+- **[cloudscribe.TalkAbout #85](https://github.com/GreatHouseBarn/cloudscribe.TalkAbout/issues/85) & [#90](https://github.com/GreatHouseBarn/cloudscribe.TalkAbout/issues/90)**: Comments System Summernote Editor - replaced Markdown editor with Summernote HTML editor in commenting system. **Breaking change** requires manual updates to local partial view overrides (CommentWrapperPartial.cshtml, CommentScriptsPartial.cshtml, CommentStylePartial.cshtml) and appsettings.json configuration. Legacy Markdown comments are preserved and automatically converted to HTML on first edit (one-way migration). CommentThread table now central to comment organization. Bootstrap4 views deprecated. Fixed PostgreSQL/MySQL/SQLite migration issues. Expect approximately half-day manual work for sites with custom comment view overrides. See upgrade documentation for detailed partial view changes required.
+
+#### **Security Improvements**
+
+- **[cloudscribe.TalkAbout #98](https://github.com/GreatHouseBarn/cloudscribe.TalkAbout/issues/98)**: Server-Side Posting Protection - added server-side enforcement of configuration parameters to prevent unauthorized comment and forum posting. Ensures anonymous users cannot bypass client-side restrictions to post when anonymous posting is disabled. Includes unit tests for validation logic. Reviewed EF Core usage to ensure protection against SQL injection in posted comment data.
+
+#### **New Features**
+
+- **[cloudscribe.Commerce #82](https://github.com/GreatHouseBarn/cloudscribe.Commerce/issues/82)**: Forms & Surveys reCAPTCHA Support - added reCAPTCHA validation to Forms & Surveys system. Each form can be configured to require reCAPTCHA for unauthenticated users, respecting site-wide cloudscribe Core reCAPTCHA settings for both visible and invisible modes. Addresses spam prevention in public-facing forms.
+- **[cloudscribe.TalkAbout #53](https://github.com/GreatHouseBarn/cloudscribe.TalkAbout/issues/53)**: Comment Administration Dashboard - added comprehensive administrative page for viewing and managing all comments across the site at `/talkadmin/administercomments`. Features include sorting, filtering, and search capabilities for comments, with direct links to the page/post where each comment was made. Default sorting by date (most recent first). Protected by `CommentModerationPolicy` authorization policy. Edit and delete operations are performed on the original page where the comment was posted, maintaining context.
+- **[cloudscribe.TalkAbout #95](https://github.com/GreatHouseBarn/cloudscribe.TalkAbout/issues/95)**: Email Comment Authors - added ability for moderators to email users directly from the comment administration page. New "Email user" button in `/talkadmin/administercomments` allows moderators to compose and send plain-text emails to comment authors. Includes contextual link back to the original comment page (when approved). Respects per-project moderator authorization policies. Fully localized with new ResX strings.
+- **[#921](https://github.com/cloudscribe/cloudscribe/issues/921)**: Role Copying with Authorization Policies - added ability to copy roles in role management. When copying a role, any dynamic authorization policies referencing the original role are automatically updated to also reference the new role. User specifies new role name during copy operation. New role starts empty (no users). Excludes system "Administrators" role from copying. Works seamlessly with or without dynamic authorization policies installed.
+
+#### **Enhancements**
+
+- **[cloudscribe.TalkAbout #75](https://github.com/GreatHouseBarn/cloudscribe.TalkAbout/issues/75)**: Visible reCAPTCHA Support - added support for visible/checkbox reCAPTCHA in the TalkAbout commenting system. Previously only invisible reCAPTCHA was supported with hardcoded implementation. Now respects cloudscribe Core reCAPTCHA settings and supports both visible and invisible modes, matching the behavior of the core login system.
+- **[cloudscribe.TalkAbout #79](https://github.com/GreatHouseBarn/cloudscribe.TalkAbout/issues/79)**: Forum Visible reCAPTCHA Support - added support for visible/checkbox reCAPTCHA in the TalkAbout forums system. Forums no longer hard-code invisible reCAPTCHA and now respect cloudscribe Core reCAPTCHA settings for both visible and invisible modes.
+- **[#1243](https://github.com/cloudscribe/cloudscribe/issues/1243)**: IP Address Restrictions Authorization - added dedicated `IPAddressRestrictionPolicy` to protect IP address restriction management endpoints. Updated navigation configuration to use `AdminMenuPolicy` instead of `AdminPolicy` for IP restriction admin menu items. Tested compatibility with template systems without dynamic authorization policies installed.
+- **[#1241](https://github.com/cloudscribe/cloudscribe/issues/1241)**: IP Address Restrictions Configuration - added ability to enable or disable IP address restriction feature via configuration. New `SiteConfigOptions.EnableIpAddressRestrictions` setting in appsettings.json allows administrators to disable the feature when not needed. Defaults to enabled (true) for backward compatibility.
+
+#### **Bug Fixes**
+
+- **[cloudscribe.TalkAbout #74](https://github.com/GreatHouseBarn/cloudscribe.TalkAbout/issues/74)**: reCAPTCHA Validation - fixed missing server-side reCAPTCHA verification when anonymous users submit comments. Ensures proper validation to prevent spam attempts. Also resolved race condition issues in reCAPTCHA initialization.
+- **[cloudscribe.TalkAbout #80](https://github.com/GreatHouseBarn/cloudscribe.TalkAbout/issues/80)**: Forum reCAPTCHA Validation - fixed missing server-side reCAPTCHA verification for anonymous forum posts. Analogous fix to comment system to ensure proper spam prevention.
+- **[cloudscribe.TalkAbout #67](https://github.com/GreatHouseBarn/cloudscribe.TalkAbout/issues/67)**: Duplicate CommentSystemSettings Records - fixed issue where duplicate rows were incorrectly created in csta_CommentSystemSettings table. Resolved confusion between Id, ProjectId, and TenantId fields where lookups now consistently use TenantId. Prevents creation of hundreds/thousands of duplicate configuration rows while preserving existing comment data.
+- **[cloudscribe.Messaging #81](https://github.com/GreatHouseBarn/cloudscribe.Messaging/issues/81)**: Newsletter Sign-up Widget reCAPTCHA - fixed hard-coded invisible reCAPTCHA in newsletter sign-up widget. Widget now respects cloudscribe Core settings for both visible and invisible reCAPTCHA modes.
+- **[cloudscribe.dynamic-authorization-policy #30](https://github.com/cloudscribe/dynamic-authorization-policy/issues/30)**: Role Removal from Policies - fixed UI bug where roles could not be reliably removed from authorization policies. Resolved indexing issue that caused sporadic failures when de-selecting roles and saving policy changes.
+- **[#1245](https://github.com/cloudscribe/cloudscribe/issues/1245)**: IP Address Restrictions Multi-Tenancy - fixed critical bug where first tenant's IP restrictions would incorrectly apply to all tenants due to cache key missing tenant ID component. Also resolved thread locking issue caused by synchronous data access in constructor. Service changed from Transient to Scoped registration. IP restrictions now work independently per tenant.
+- **[#1197](https://github.com/cloudscribe/cloudscribe/issues/1197)**: IP Restriction UI Address Display - fixed incorrect IP address display in IP restriction admin UI. Previously used historical login data from cs_user_location table which could be outdated or wrong when users switch devices, VPNs, or have dynamic IP changes. Now retrieves current IP address directly from HTTPContext for accurate real-time display.
+
+#### **UI/UX Improvements**
+
+- **[#1058](https://github.com/cloudscribe/cloudscribe/issues/1058)**: User Display Name Editing - added ability for users to edit their display name on the `/manage/userinfo` page. Previously users could only edit first and last name, but display name (used throughout the system including TalkAbout comments) was only editable by administrators. Includes uniqueness enforcement per tenant, character validation with international character support, and HTML sanitization.
+
+#### **Developer Tools & Features**
+
+- **[cloudscribe.dynamic-authorization-policy #46](https://github.com/cloudscribe/dynamic-authorization-policy/issues/46)**: Policy Definition Documentation - clarified the relationship between Roles and Claims in policy definitions. Documentation now explicitly states that Roles use OR logic (user needs ANY role), Claims use AND logic (user needs ALL claims), and when both are specified, users must satisfy both requirements (be in ANY role AND have ALL claims).
+- **[#1231](https://github.com/cloudscribe/cloudscribe/issues/1231)**: IdentityServer Integration Tests - added comprehensive integration tests for IdentityServer4 authentication and authorization. Tests cover client credentials grant type flow, JWT token validation, and role-based authorization. Updated to use modern Microsoft.AspNetCore.Authentication.JwtBearer (v8.x) library instead of deprecated IdentityServer4.AccessTokenValidation (v3). Includes published test harness page for live validation testing.
+
+---
+
+
+
### version 8.5.0 - September 2025
#### **Major Licensing Change**
diff --git a/cloudscribe.templates.nuspec b/cloudscribe.templates.nuspec
index 270d847..101c0ef 100644
--- a/cloudscribe.templates.nuspec
+++ b/cloudscribe.templates.nuspec
@@ -2,7 +2,7 @@
cloudscribe.templates
- 8.5.0
+ 8.6.0
cloudscribe Project Templates
Joe Audette
Project template for starting new web application projects with cloudscribe library components
diff --git a/cloudscribeTemplate/source.extension.vsixmanifest b/cloudscribeTemplate/source.extension.vsixmanifest
index 0817766..a329ecc 100644
--- a/cloudscribeTemplate/source.extension.vsixmanifest
+++ b/cloudscribeTemplate/source.extension.vsixmanifest
@@ -1,7 +1,7 @@
-
+
cloudscribe Project Template
A Visual Studio extension that makes it easy to start new web application projects using cloudscribe libraries
https://www.cloudscribe.com/docs/introduction