4 Commits
Author SHA1 Message Date
SvenandClaude Opus 5.5 08dda0ea96 Let a deployment pull request through without an issue of its own (#183)
A milestone branch on its way to main (milestone/v0.4.0, #182) collects
work that was agreed and reviewed piece by piece, each piece closing its
own issue. It has no issue of its own to name, and listing the pieces'
issues only works once each has landed, so the required linked-issue
check refused it. `deployment` joins `bug`, `chore` and `dependencies` as
a label that needs none.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 13:17:01 +02:00
Svenandpmdevelopment 55a6d67a48 Give the PHP time limit back after every test (#89)
A streaming controller's set_time_limit() outlived its test in the single PHPUnit process and killed slower runs part-way. A PHPUnit extension resets it after every test.

Co-authored-by: pmdevelopment <4947485+pmdevelopment@users.noreply.github.com>
2026-10-15 14:49:28 +02:00
SvenandClaude Opus 5.5 c6cd81ba15 Keep the importmap's packages between CI runs, and retry their fetch (#132)
Every job of the E2E workflow ran `composer install`, whose post-install
importmap:install fetched all 45 packages from cdn.jsdelivr.net: about 270
requests per run. jsDelivr builds a `+esm` bundle on request, and now and
then one times out ("Idle timeout reached for .../openpgp@6.3.2/+esm",
"Failed to connect to cdn.jsdelivr.net"), which failed the job before a
test ran.

assets/vendor/ is now cached, keyed by importmap.php. importmap:install
skips a package already there at the version importmap.php names, so the
CDN is asked once per change to the importmap. When it still fails, the
install is tried up to three times; a retry finds vendor/ in place and
only reruns the scripts.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:04:37 +02:00
4d705a56da Keep remember-me tokens on the server, so signing out holds (#104)
* Keep remember-me tokens on the server, so signing out holds

A remember-me cookie that carries only its own signature stays valid
until it expires, and signing out only asks the browser to delete it.
A request already on its way with it - the page's own background
fetches - reached the server after the sign-out and signed the person
straight back in.

The tokens are kept on the server now (Symfony's DoctrineTokenProvider,
table rememberme_token), one per device. Signing out deletes this
device's token, so a late cookie opens nothing; other devices stay
signed in. Symfony's CacheTokenVerifier keeps parallel requests that
rotate the token from looking like theft.

Existing signed cookies are no longer read: people who relied on "Keep
me signed in" sign in once more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Say what remember-me is now, wherever it was described

Remember-me moved from a signed cookie to tokens kept on the server, and
five places still said "signature-based, not stored": the handbook's
security page, the config-backup page's account of why APP_SECRET stays
behind, and three comments beside the code that depends on it. English
and German both.

RememberMeAcrossRestoreTest proved its point against SignatureHasher,
which the firewall no longer uses. It now asserts what the property rests
on today: the firewall holds the persistent handler, and a backup taken
while a token row exists carries neither its series nor its value.

One test added for the claim the docs repeat: a changed password ends the
cookie, because the token carries a digest of the hash it was issued under.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Paul Lützner <mail@pluetzner.de>
2026-10-13 17:18:43 +02:00