Repository navigation
v1.7.0
Added
- Restore commands:
notifier:database-restoreandnotifier:storage-restore. Pull this site's own backups back down from the control plane and apply them — for bootstrapping a new node, disaster recovery, or refreshing staging. Restore is authenticated with a separateNOTIFIER_RESTORE_TOKEN, never the backup code, so leaking the credential that uploads backups cannot also be used to download them; an install with no restore token configured cannot restore at all. Both commands support--list,--dry-run,--id=(defaults to the newest backup) and, in production, require--force; the database restore additionally asks you to type the database name to confirm and dumps the current database to a pre-restore snapshot first (skip with--no-snapshot). Storage restore is additive — it overwrites files with matching paths but never deletes anything the backup predates. - Restore is hardened against a hostile or compromised control plane. A downloaded archive is verified against the SHA-256 checksum the server recorded at upload time (the listing copy and the response header must agree, and both must match the bytes on disk) before anything is applied. The extractor refuses an archive whose entries are not encrypted, caps the extracted size to defuse zip bombs, and rejects path-traversal (zip-slip) and absolute-path entries. A restored SQL dump is scanned for client-side directives (
\!,system,source,\copy…) and refused before a single byte reaches the database client, closing an RCE path through a poisoned dump. features.backupsis now a real toggle. The heartbeat manifest has always advertised abackupsflag, but the key it reads was never defined inconfig/notifier.php, so it was hard-wired totrueand could not be turned off. The key now exists and is driven byNOTIFIER_BACKUPS_ENABLED, letting a site that intentionally does not back up say so to the control plane instead of appearing to be a silent failure.
Changed
- Announcement config fallbacks now match the shipped defaults.
AnnouncementsServicefell back tofalseforfeatures.announcementsand60forannouncements.failure_cache_ttl, whileconfig/notifier.phpshipstrueand300. The in-code fallbacks were aligned with the config. These fallbacks only apply when the key is absent entirely — a site whose published config predates these keys will now default announcements to on (still a no-op untilNOTIFIER_URLis set) and cache a failed fetch for 5 minutes instead of 1.
Removed
- Dead code in
BackupTypeEnum.values()andvalidationRule()had no callers — request validation goes throughRule::enum— and were removed.
Internal
- CI matrix now also covers PHP 8.5 + Laravel 12, the one supported combination that was untested.
- CHANGELOG compare links, README badge and
VERSION_MANAGEMENT.mdcorrected;TODO.mdrefreshed against the actual state of the code.
What's Changed
- ci(deps): bump the actions group across 1 directory with 2 updates by @dependabot[bot] in #21
- feat: notifier:database-restore & notifier:storage-restore by @ludwigtomas in #22
New Contributors
- @dependabot[bot] made their first contribution in #21
Full Changelog: v1.6.2...v1.7.0