User tests: Successful: Unsuccessful:
Pull Request resolves #47370
This PR implements a secure, time-limited token-based preview system that allows administrators to preview articles regardless of their publishing date or published state, even when "Shared Sessions" is disabled in Global Configuration.
Key changes:
#__content_preview_tokens to store preview tokens with expiration&preview=1 and a unique tokenisAdminPreview() validation method in the frontend ArticleModel to verify valid preview requestsPrerequisites:
Test Scenario 1: Future-dated article preview
Test Scenario 2: Unpublished article preview
Test Scenario 3: Regular frontend access (regression)
preview=1 parameter)When "Shared Sessions" is disabled:
When "Shared Sessions" is disabled:
1. New Database Table (#__content_preview_tokens)
CREATE TABLE IF NOT EXISTS `#__content_preview_tokens` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`token` VARCHAR(64) NOT NULL,
`user_id` INT(11) NOT NULL,
`article_id` INT(11) NOT NULL,
`expires` DATETIME NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_token` (`token`),
KEY `idx_article` (`article_id`),
KEY `idx_expires` (`expires`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;2. Token Generation (administrator/components/com_content/src/View/Article/HtmlView.php)
random_bytes(16)&preview=1&preview_token={token} to both standard preview and accessibility (jooa11y) preview links3. Token Validation (components/com_content/src/Model/ArticleModel.php)
preview=1 parameter in the requestcore.edit.state permissiontrue only if all validation passes4. Filter Bypass Logic
publish_up/publish_down) are skipped when isAdminPreview() returns trueisAdminPreview() returns trueisAdminPreview() returns true| Attack Vector | Mitigation |
|---|---|
| Token guessing | 128-bit entropy (2^128 possibilities) makes brute force infeasible |
| Token interception | 5-minute expiration limits the attack window |
| Token replay | Expired tokens are deleted; each preview generates a new token |
| Unauthorized user | Token is tied to the generating user's ID and requires core.edit.state permission |
| Shared links | Users without edit permissions cannot use another user's preview token |
Testing performed:
Database installation:
The table creation query was tested via phpMyAdmin on an existing Joomla installation.
Note on branch targeting:
I understand that bug fixes are typically made against the 5.4 branch, while new features target 6.2. However, since my solution introduces a new database table and implements a token-based preview system (which adds new functionality to the core), I believe this could be a feature rather than a pure bug fix. Therefore, I have developed this against the 6.2 branch. If the maintainers prefer this to be backported or handled differently, I'm happy to adjust accordingly.
Please select:
| Status | New | ⇒ | Pending |
| Category | ⇒ | Administration com_content Front End SQL Installation |
| Labels |
Added:
PR-6.2-dev
|
||
| Category | Administration com_content Front End SQL Installation | ⇒ | Administration com_content Front End SQL Installation Postgresql |
| Category | Administration com_content Front End SQL Installation Postgresql | ⇒ | SQL Administration com_admin Postgresql com_content Front End Installation |
As you can see from the test this breaks on postgres as you have only updated the installation sql for mysql - you need to do the same change for postgres
You also need to have update sql for existing installations
Hello, thanks for the help!
I have just updated postgresql and sql for existing installations.
| Title |
|
||||||
Accessibility check (jooa11y) is not currently working with the same token mechanism, if this PR is accepted I might follow up with another PR to solve its issue.
That would need to be fixed with this issue
Accessibility check (jooa11y) is not currently working with the same token mechanism, if this PR is accepted I might follow up with another PR to solve its issue.
That would need to be fixed with this issue
Hello, I found out that accessibility check is not working at 6.2 dev.
The 404 error appears using the original code even at published articles. If it is supposed to work, then probably latest updates broke it.
When I was tracing I found an error Dispatcher not set in Joomla\CMS\Plugin\CMSPlugin, it's because of Deprecated getDispatcher(), when I changed it I found another error and so on.

That would need to be fixed with this issue
Hello, could you please confirm if the accessibility check is not working as it is for me now? (please check my last comment).
If yes, should I try to fix it in this pr? I just thought it would be a little bit out of scope for this issue. I can work on it, but I don't know if this would be correct. So, I am waiting for directions.
I will leave it to others with more architecture experience to comment on the code.
From a user experiece this works well and is a good and useful addition to Joomla
I will leave it to others with more architecture experience to comment on the code.
From a user experiece this works well and is a good and useful addition to Joomla
Thanks! I appreciate that.
Happy to work with Joomla!
I have also fixed another bug yesterday
and made a new PR. I will appreciate feedback.
As you can see from the test this breaks on postgres as you have only updated the installation sql for mysql - you need to do the same change for postgres
You also need to have update sql for existing installations