Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions Jacaranda_Comments.dnn
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<dotnetnuke type="Package" version="5.0">
<packages>
<package name="Jacaranda_Comments" type="Module" version="01.01.03">
<package name="Jacaranda_Comments" type="Module" version="01.03.00">
<friendlyName>Jacaranda Comments</friendlyName>
<description>Page-level comments and replies module for DNN 10 with opt-in moderated guest posting, registered-author editing, a private per-module language filter, configurable comment length, page-aware moderator email subjects, module-aware accessible notifications, a prominent accessible CAPTCHA answer field, rate limiting, email notifications, and optional CAPTCHA.</description>
<description>Advanced page-level comments and replies module for DNN 10 with one-place portal-wide configuration, central moderation across all module instances, emergency posting controls, moderated guest posting with a secure five-minute correction window, registered-author editing, a private language filter, configurable comment length, page-aware moderator email subjects, accessible module-aware notifications, rate limiting, email notifications, and optional CAPTCHA.</description>
<owner>
<name>Trevor Forrester</name>
<organization>Forrest It Services</organization>
Expand Down Expand Up @@ -135,6 +135,26 @@
<name>01.01.03.SqlDataProvider</name>
<version>01.01.03</version>
</script>
<script type="Install">
<path>Providers\DataProviders\SqlDataProvider</path>
<name>01.02.00.SqlDataProvider</name>
<version>01.02.00</version>
</script>
<script type="Install">
<path>Providers\DataProviders\SqlDataProvider</path>
<name>01.02.01.SqlDataProvider</name>
<version>01.02.01</version>
</script>
<script type="Install">
<path>Providers\DataProviders\SqlDataProvider</path>
<name>01.02.02.SqlDataProvider</name>
<version>01.02.02</version>
</script>
<script type="Install">
<path>Providers\DataProviders\SqlDataProvider</path>
<name>01.03.00.SqlDataProvider</name>
<version>01.03.00</version>
</script>
<script type="UnInstall">
<path>Providers\DataProviders\SqlDataProvider</path>
<name>Uninstall.SqlDataProvider</name>
Expand Down Expand Up @@ -178,6 +198,15 @@
<controlType>Edit</controlType>
<viewOrder>1</viewOrder>
</moduleControl>
<moduleControl>
<controlKey>PortalSettings</controlKey>
<controlSrc>DesktopModules/Jacaranda/Comments/PortalSettings.ascx</controlSrc>
<supportsPartialRendering>False</supportsPartialRendering>
<supportsPopUps>False</supportsPopUps>
<controlTitle>Jacaranda Comments Administration</controlTitle>
<controlType>Edit</controlType>
<viewOrder>2</viewOrder>
</moduleControl>
</moduleControls>
</moduleDefinition>
</moduleDefinitions>
Expand Down
34 changes: 34 additions & 0 deletions Providers/DataProviders/SqlDataProvider/01.02.00.SqlDataProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
-- Jacaranda Comments Advanced 01.02.00
-- Adds portal-scoped central settings, emergency posting controls, portal defaults,
-- and audit information. Existing module instances remain on local settings.

IF NOT EXISTS (
SELECT 1
FROM sys.objects
WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}JacarandaCommentsPortalSettings]')
AND type = N'U'
)
BEGIN
CREATE TABLE {databaseOwner}[{objectQualifier}JacarandaCommentsPortalSettings] (
[PortalId] INT NOT NULL,
[PostingEnabled] BIT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_PostingEnabled] DEFAULT ((1)),
[GuestPostingEnabled] BIT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_GuestPostingEnabled] DEFAULT ((1)),
[DefaultAllowGuestComments] BIT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_AllowGuests] DEFAULT ((0)),
[DefaultRequireApprovalForNonEditors] BIT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_RequireApproval] DEFAULT ((1)),
[DefaultEnableLanguageFilter] BIT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_LanguageFilter] DEFAULT ((0)),
[DefaultBlockedLanguageTerms] NVARCHAR(MAX) NULL,
[DefaultMaximumCommentLength] INT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_MaxLength] DEFAULT ((4000)),
[DefaultEnableRateLimiting] BIT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_RateLimiting] DEFAULT ((1)),
[DefaultRateLimitSeconds] INT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_RateSeconds] DEFAULT ((60)),
[DefaultRateLimitMaxPosts] INT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_RatePosts] DEFAULT ((5)),
[DefaultRateLimitWindowMinutes] INT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_RateWindow] DEFAULT ((15)),
[DefaultEnableCaptcha] BIT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_Captcha] DEFAULT ((0)),
[DefaultEnableNotifications] BIT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_Notifications] DEFAULT ((0)),
[DefaultNotificationEmailAddresses] NVARCHAR(2000) NULL,
[DefaultIncludeCommentTextInNotifications] BIT NOT NULL CONSTRAINT [DF_{objectQualifier}JCPS_IncludeText] DEFAULT ((1)),
[ModifiedOnDate] DATETIME NULL,
[ModifiedByUserId] INT NULL,
CONSTRAINT [PK_{objectQualifier}JacarandaCommentsPortalSettings] PRIMARY KEY CLUSTERED ([PortalId] ASC)
);
END
GO
18 changes: 18 additions & 0 deletions Providers/DataProviders/SqlDataProvider/01.02.02.SqlDataProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- Jacaranda Comments Advanced 01.02.02
-- Adds a hashed guest edit credential for the five-minute guest correction window.
-- Existing guest comments remain non-editable because their token hash is NULL.

IF EXISTS (
SELECT 1
FROM sys.objects
WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}JacarandaComments]')
AND type = N'U'
)
BEGIN
IF COL_LENGTH('{databaseOwner}{objectQualifier}JacarandaComments', 'GuestEditTokenHash') IS NULL
BEGIN
ALTER TABLE {databaseOwner}[{objectQualifier}JacarandaComments]
ADD [GuestEditTokenHash] NVARCHAR(64) NULL;
END
END
GO
20 changes: 20 additions & 0 deletions Providers/DataProviders/SqlDataProvider/01.03.00.SqlDataProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- Jacaranda Comments Advanced 01.03.00
-- Adds the one-time portal central-configuration activation flag.
-- Existing Advanced 01.02.x module settings continue to operate until an
-- Administrator explicitly activates central configuration.

IF EXISTS (
SELECT 1
FROM sys.objects
WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}JacarandaCommentsPortalSettings]')
AND type = N'U'
)
BEGIN
IF COL_LENGTH('{databaseOwner}{objectQualifier}JacarandaCommentsPortalSettings', 'CentralSettingsActive') IS NULL
BEGIN
ALTER TABLE {databaseOwner}[{objectQualifier}JacarandaCommentsPortalSettings]
ADD [CentralSettingsActive] BIT NOT NULL
CONSTRAINT [DF_{objectQualifier}JCPS_CentralActive] DEFAULT ((0));
END
END
GO
11 changes: 11 additions & 0 deletions Providers/DataProviders/SqlDataProvider/Uninstall.SqlDataProvider
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
IF EXISTS (
SELECT 1
FROM sys.objects
WHERE object_id = OBJECT_ID(N'{databaseOwner}[{objectQualifier}JacarandaCommentsPortalSettings]')
AND type = N'U'
)
BEGIN
DROP TABLE {databaseOwner}[{objectQualifier}JacarandaCommentsPortalSettings];
END
GO

IF EXISTS (
SELECT 1
FROM sys.objects
Expand Down
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,27 @@ Jacaranda Comments is a lightweight DNN 10 comments module built for the Bootstr
Install the versioned `Jacaranda_Comments_XX.XX.XX_Install.zip` file through DNN Extensions. The source ZIP is for review and development and is not the DNN installation package.

Current package version: **01.00.19**. Test the install package before committing the repository update.

Add a secure five-minute correction window for guest comments and replies while they are still awaiting moderation.

Changes:

Allow guests to edit the text of their own pending comment or reply for up to five minutes after the original submission
Keep the five-minute window tied to the original posting time so editing does not restart the timer
End guest editing immediately when a submission is approved, deleted, guest posting is disabled, or all posting is disabled
Restrict guest editing to comment/reply text only; guest display name and private email remain unchanged
Generate a cryptographically random guest-edit credential and store only its SHA-256 hash with the comment
Keep the raw guest-edit credential out of the database, URLs, query strings, hidden fields, rendered HTML, and moderator emails
Do not use guest name, email, IP address, user-agent, rate-limit key, or Comment ID alone as proof of ownership
Revalidate PortalId, TabId, ModuleId, guest ownership, moderation status, deletion status, token hash, and five-minute expiry during the database update
Keep corrected guest submissions pending moderation
Re-run the private language filter after a guest correction
Preserve the existing 15-minute editing window for registered users
Preserve portal-wide moderation, emergency switches, CAPTCHA, rate limiting, language filtering, email notifications, approval, deletion, and security-token validation
Add GuestEditTokenHash to support secure guest correction
Add and register the 01.02.02 SqlDataProvider upgrade script
Update the manifest, release notes, documentation, resources, and package files

Existing guest comments are not made editable by this upgrade. Only new guest submissions created after 01.02.02 receive the secure correction capability.

This release is part of the Jacaranda Comments Advanced branch. The stable Simple edition remains separate on the main branch.
86 changes: 86 additions & 0 deletions README_01.02.00.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
Jacaranda Comments Advanced 01.02.00

Purpose
-------
This is the Advanced release line of Jacaranda Comments. It begins from the stable
01.01.03 code base and adds portal-scoped central administration while preserving
the page-specific nature of each comments module instance.

Repository branch
-----------------
- Stable Simple edition: main branch, version 01.01.03.
- Advanced edition: advanced-settings branch, version 01.02.00.
- This is an alternative upgrade line, not a second side-by-side DNN module.
- It keeps the existing DNN package identity, folder and database tables so an
Advanced installation upgrades an existing Jacaranda Comments installation.
- Do not install the Simple and Advanced packages alternately on a production site
without first testing the change on staging and taking a full backup.

Safe upgrade behaviour
----------------------
Existing module instances continue using their current local settings after the
upgrade. No module begins inheriting portal defaults until an administrator
deliberately enables the inheritance option for that instance.

Access
------
- Site-wide settings are available only to DNN superusers and members of the
current portal's built-in Administrators role.
- No new DNN security role is created.
- The central panel repeats the server-side permission check even when its
navigation link is hidden.
- Every save requires the module's anti-CSRF security token and validated POST values.

Emergency controls
------------------
- Allow new comments and replies anywhere on this portal.
- Allow guest posting anywhere on this portal.
- Emergency switches apply to every Jacaranda Comments instance in the current portal.
- Disabling all posting leaves existing comments visible and keeps moderation actions available.
- Disabling guest posting does not disable registered-user posting.

Portal defaults
---------------
Administrators can define portal defaults for:
- Guest commenting
- Moderation
- Private language filtering and terms
- Maximum comment length
- Rate limiting
- CAPTCHA
- Email notifications and recipients
- Inclusion of comment text in notification emails

Per-module inheritance
----------------------
- A new “Use site-wide Jacaranda Comments defaults for this module” setting is off by default.
- Existing modules keep their local settings after upgrade.
- When inheritance is enabled, local values remain stored but are ignored.
- Switching inheritance off restores the module's previously saved local settings.
- Emergency portal switches always take priority.

Audit and portal isolation
--------------------------
- Central settings are keyed by PortalId.
- Portal administrators can affect only their own portal; superusers retain host-level access.
- The central panel records the UTC modification date and DNN user ID.
- Each module settings page shows the current emergency-control state and whether it is inherited or local.

Database changes
----------------
The 01.02.00 upgrade creates the portal-scoped JacarandaCommentsPortalSettings table.
Existing comments and module settings are not altered.

Installation
------------
1. Back up the DNN database and website files.
2. Confirm the currently installed Jacaranda Comments version is 01.01.03 or earlier.
3. Upload Jacaranda_Comments_Advanced_01.02.00_Install.zip through DNN Extensions.
4. Confirm existing modules still use their local settings.
5. Sign in as a portal administrator or superuser and open Site-wide Comments Settings from a module instance.
6. Save conservative portal defaults.
7. Enable inheritance on one test module only.
8. Test registered and guest posting, replies, editing, moderation, language filtering, CAPTCHA, rate limiting and email.
9. Test both emergency switches and restore them afterward.
10. Confirm ordinary module editors and registered users cannot open the central panel.
11. Check the DNN Event Viewer.
84 changes: 84 additions & 0 deletions README_01.02.02.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
Jacaranda Comments Advanced 01.02.02

Purpose
-------
This Advanced maintenance release gives guest authors a short correction window
without weakening the existing registered-user or moderation security model.

Repository branch
-----------------
- Stable Simple edition: main branch, version 01.01.03.
- Advanced edition: advanced-settings branch, version 01.02.02.
- Advanced retains the existing DNN package identity and upgrades the existing
Jacaranda Comments module rather than installing side by side.

Five-minute guest correction window
-----------------------------------
A guest who submits a comment or reply may correct only the submitted text for
up to five minutes from the original CreatedOnDate, provided the submission is
still awaiting moderation.

Guest name and private email cannot be changed through the correction workflow.
The five-minute period never restarts after an edit. Moderator approval, deletion,
expiry of the original five minutes, disabling guest posting, or disabling all
posting immediately prevents further guest correction. Approval and deletion also
clear the stored token hash.

Guest ownership security
------------------------
- A cryptographically strong random guest-edit credential is created server-side
in the ASP.NET session for the current portal/page/module context.
- Only a SHA-256 hash of that credential is stored with a new guest submission.
- The raw credential is never written to the database, URL, hidden form fields,
rendered HTML, email notifications, or public output.
- Guest ownership is never inferred from display name, email address, IP address,
user-agent text, CommentId alone, or the guest rate-limit key.
- Edit permission is checked before loading the edit form and is repeated in the
parameterised SQL UPDATE itself.
- The UPDATE requires UserId IS NULL, the current portal/page/module scope, the
matching token hash, IsDeleted = 0, IsApproved = 0, and the original five-minute
CreatedOnDate window.

Guest visibility during correction
----------------------------------
While the credential is valid, a guest can see their own still-pending recent
submission on the originating module and receives an Edit action. Reply is not
offered on a still-pending submission. This limited visibility ends when the
five-minute window expires or the submission is approved. Approved comments remain
publicly visible under the normal module rules.

Moderation and notifications
----------------------------
Guest corrections always remain pending. A guest can never turn a pending comment
into an approved one. The private language filter is re-evaluated against the
corrected text, edit audit time is recorded, and moderator notification email can
report the corrected guest submission using the existing private guest email
protection/decryption path.

Database change
---------------
01.02.02 adds one nullable column to JacarandaComments:

GuestEditTokenHash NVARCHAR(64) NULL

Existing comments are not modified. Existing guest submissions have no edit token
hash and therefore do not become retrospectively editable.

Recommended test
----------------
1. Back up the DNN database and website files.
2. Upgrade an Advanced 01.02.01 test site using the 01.02.02 Install ZIP.
3. Enable guest posting on one test module.
4. Submit a guest comment and confirm it remains pending but is visible to the
same guest browser with an Edit action.
5. Edit only the comment text within five minutes and confirm the correction saves.
6. Confirm the guest display name and email are not editable during correction.
7. Confirm the corrected item remains pending and the moderator notification is sent.
8. Approve a fresh guest submission within five minutes and confirm its Edit action
disappears immediately for the guest.
9. Submit another guest comment, wait more than five minutes, and confirm editing is
no longer available.
10. Confirm editing at minute four does not create a new five-minute window.
11. Confirm another browser/session cannot edit the guest submission.
12. Recheck registered-user 15-minute editing, central moderation, CAPTCHA, language
filtering, rate limiting, approval, deletion, and the DNN Event Viewer.
Loading