docs: document page locking and prior security fixes

README, the changelog and the built-in welcome page were missing the
page-lock feature and the bootstrap/LoginRateLimiter/Logger hardening
from the earlier security audit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Geoff Moore
2026-10-02 12:11:09 +01:00
co-authored by Claude Sonnet 5
parent 83ae3a08ff
commit bc4730eb30
3 changed files with 23 additions and 6 deletions
+10 -2
View File
@@ -29,7 +29,8 @@ Further technical documentation:
deleted pages can be recovered from the Dashboard.
* Page Management: Search, duplicate, rename, and delete editable HTML pages, including pages in subdirectories. The New page section of the Pages dialogue is a
three-step wizard (template, page name, navigation group); the new page stays a private draft until it is published. Any page can
be offered as a template with Create Template.
be offered as a template with Create Template. Administrators can Lock a page to stop editors publishing, saving a draft, or
scheduling changes to it; administrators are never restricted by a lock.
* Media Library: Upload images, documents, video, and audio; they are sorted into Imagery, Documents, Video, and Audio by file
extension. Reuse them from the editor's Media library button, maintain alternative text or link text, see usage counts, and
remove files. Executables and files containing code are refused.
@@ -137,7 +138,7 @@ There are two roles:
| Role | Can do |
| --- | --- |
| `editor` | Edit content, save drafts, upload images, publish or schedule pages, and restore revisions or deleted pages. Cannot change the site structure or manage users. |
| `administrator` | Everything an editor can, plus creating new pages, duplicate, rename and delete pages, templates, navigation menus, shared content, site scan, deleting media, and managing users. |
| `administrator` | Everything an editor can, plus creating new pages, duplicate, rename, delete and lock pages, templates, navigation menus, shared content, site scan, deleting media, and managing users. |
The former `publisher` role is now part of `editor`; existing `publisher` assignments are treated as `editor`. Users without an
explicit valid role receive `editor`, the least powerful role.
@@ -286,6 +287,13 @@ Templates are the files in `cms/templates/` plus any page you choose **Create Te
is used live (later edits to it show in new pages), and the **Delete** action in the template list deletes a template file or
stops using a page as a template (the page is kept).
### Locking Pages
Administrators can **Lock** a page from the Pages list to stop editors publishing, saving a draft, or scheduling a change to
it; a **Locked** badge shows next to the page name for everyone. Administrators are never restricted by a lock, and locking
is independent of Create Template, Duplicate, Rename, and Delete, which were already administrator-only. A lock follows a
page when it is renamed, is cleared when the page is deleted, and is never copied onto a duplicate.
### Subfolder Installs
The site can live in a subfolder such as `http://localhost/neocms/`. The URL prefix (`basePath`) and the folder that contains
+1
View File
@@ -41,6 +41,7 @@
<h2>Pages and revisions</h2>
<p>Administrators can create, duplicate, rename, and delete pages. The <strong>New page</strong> section under the list in <strong>Pages</strong> is a three-step wizard: choose a template, name the page (the filename is generated for you), then choose a navigation group. The new page stays a private draft until it is published; publishing creates the file and adds it to the chosen menu.</p>
<p>Use <strong>Create Template</strong> on any page in the list to offer it as a template, and Delete in the template list to stop offering one. Editors can restore earlier revisions from <strong>Tools</strong>.</p>
<p>Administrators can also <strong>Lock</strong> a page to stop editors publishing, saving a draft, or scheduling changes to it; administrators are never restricted by a lock.</p>
<p>Deleted pages retain a restorable snapshot: editors can bring one back with <strong>Recover</strong> in the <strong>Dashboard</strong>'s Deleted pages list, because accidents should be reversible rather than memorable.</p>
</section>
+12 -4
View File
@@ -22,6 +22,12 @@ This round builds on pull request #39 (site scan, editor workflow, subfolder sup
- **Pages as templates**: each row in the page list has a "Create Template" action (administrators). The page is then offered in New Page beside the files in `cms/templates/`; the new page is a private copy with its title replaced. Renaming or deleting a template page keeps the list in step.
- **Template list**: the New Page template and navigation-group lists use the page-table styling; each template has a Delete action (a template file is deleted; a page used as a template is only unmarked).
- **Device preview**: the Desktop/Tablet/Mobile buttons are icons (with tooltips and accessible names) and the active one is highlighted.
- **Lock pages**: administrators can lock a page from the Pages list to stop editors publishing, saving a draft, or scheduling a change to it, without restricting administrators themselves. A "Locked" badge shows on the page for everyone; the Lock/Unlock action sits beside Create Template, Duplicate, Rename and Delete. State is stored in `cms/data/pagelocks.json`, keyed by page URI, and follows a page through rename (cleared on delete, never copied by Duplicate). New action `lockPage`; `getPages` items gain `locked`.
### Fixed
- **Verbose PHP errors**: `display_errors` and `display_startup_errors` are now disabled in `bootstrap.php`, so an uncaught engine error can never leak a stack trace or filesystem path to a client; every error still reaches PHP's own error log.
- **Unbounded login-throttling state**: `LoginRateLimiter` now caps tracked address/identity buckets at 20,000, evicting the least recently active first, so a distributed flood of distinct addresses or login names cannot grow `login-attempts.json` without bound.
- **Audit-log pruning cost**: `Logger` now prunes expired audit logs probabilistically (1-in-100 constructions) instead of scanning the whole logs directory on every single request.
### Migration notes
- New Page is now a section of the Pages dialogue (there is no New Page toolbar button).
@@ -30,13 +36,15 @@ This round builds on pull request #39 (site scan, editor workflow, subfolder sup
- Media: new uploads are named `slug-8hex.ext` and accept documents, video and audio; existing 32-hex image names keep working. Copy the updated `uploads/.htaccess` (outside `cms/`).
- New optional setting `dataDirectory`: set it to a folder outside the web root on live sites. The default `cms/data/` keeps working.
- Navigation menus can no longer be created from the CMS; they are discovered by the site scan (existing menus are kept). New pages are private drafts until published.
- New API actions: `users`, `saveProfile`, `changePassword`, `saveUser`, `inviteUser`, `blockUser`, `deleteUser`, `newPage` (changed), `discardNewPage`, `setPageTemplate`, `deleteTemplate`, `deleteMenu`; the dashboard response gains `deleted` and `notices`; `media` items gain `category`, `ext` and `original`.
- New API actions: `users`, `saveProfile`, `changePassword`, `saveUser`, `inviteUser`, `blockUser`, `deleteUser`, `newPage` (changed), `discardNewPage`, `setPageTemplate`, `deleteTemplate`, `deleteMenu`, `lockPage`; the dashboard response gains `deleted` and `notices`; `media` items gain `category`, `ext` and `original`; `getPages` items gain `locked`.
### Verification
- The updated integration suite (`tests/run.php`, included in this contribution) passes, covering concurrency, site scan and tagging, menus, new pages
and templates, deleted-page recovery, users and roles, invitations, media type checks, and audit-log cases. Upstream's earlier `tests/run.php` expects
behaviour that has intentionally changed (editors cannot publish, menus can be created, New Page copies immediately), so the updated suite replaces it.
On Windows the Linux-only permission assertions are skipped.
and templates, deleted-page recovery, users and roles, invitations, media type checks, page locking (lock/unlock, rename moves the lock, delete clears
it, duplicate never copies it), and audit-log cases. Upstream's earlier `tests/run.php` expects behaviour that has intentionally changed (editors
cannot publish, menus can be created, New Page copies immediately), so the updated suite replaces it. On Windows the Linux-only permission assertions
are skipped.
- A self-review security audit found no critical or high-severity issues; the three fixes above address its medium/low findings.
## Merged in pull request #39