Forums Bug Reports Thread

RSS feed-URL Copy button silently fails with no fallback or toast when clipboard API is unavailable

Patrick Bass · Jun 6 · 9 · 1 Locked
[Minor] [Normal Priority] [Bug Fixed] [Always Reproduces]
🚀 OP Jun 6, 2026 9:35pm

Area: Account (re-run) (audit p1r) · Surface: /account/rss · Dimension: law1-polish · Severity: minor

The recruit dashboard does this correctly (clipboard with a Promise rejection handler that shows App.toast 'Could not copy — select the link and Ctrl-C'), but the RSS settings copy button uses a fire-and-forget inline onclick that (a) lies by showing 'Copied' even on failure and (b) can throw an uncaught TypeError when navigator.clipboard is missing. The RSS URL contains a private token, so a user who thinks they copied it but didn't will paste an empty/old value into their reader.

Evidence

platform/templates/account/rss.php:34-37: `<button type="button" ... onclick="var el=document.getElementById('rssUrl'); el.select(); navigator.clipboard.writeText(el.value); this.textContent='Copied';">`. The button text flips to 'Copied' unconditionally before navigator.clipboard.writeText resolves, and there is no .catch and no fallback. On non-HTTPS contexts or browsers where navigator.clipboard is undefined, this throws and the URL is never copied, yet the button still says 'Copied'.

Suggested fix. Mirror the recruit/dashboard.php pattern: guard navigator.clipboard, only flip the label to 'Copied' inside .then(), and on rejection show App.toast('Could not copy — select the URL and Ctrl-C', 'warning'). Move it out of inline onclick into the nonce'd script block.

Filed by the automated tenant-app audit and adversarially evidence-verified. Status: verified. Open — not yet actioned.


Patrick Bass
@mobieus

🚀 Jun 7, 2026 5:49am

Resolved — fixed and deployed. Commit ea9f0311e960, shipped dev-first then to all tenants on 2026-06-06.

Removed the inline onclick from #copyRssBtn and moved copy logic into a nonce'd <script> block (inside the ob_start buffer). It guards navigator.clipboard via a copyText() helper, flips the button label to 'Copied' only inside .then() success (restoring the icon+label after 1.5s), and on rejection calls App.toast('Could not copy — select the URL and Ctrl-C', 'warning'), mirroring recruit/dashboard.php.

Status: fixed. Thread closed and locked.


Patrick Bass
@mobieus

Log in or register to reply to this thread.