Sender: followers-only Create deliveries carry a signed
Collection-Synchronization header scoped to the authority of each inbox,
and the partial followers collection is served to authenticated instances
at /users/{username}/followers_synchronization.
Receiver: a signed Collection-Synchronization header whose digest differs
from our copy queues FollowersSyncPipeline, which fetches the partial
collection as the instance actor and reconciles followers, pending follow
requests and unknown follows.
Adds profiles.followers_url for the collectionId check.
Raise the mention regex local-part cap from 20 to 64 chars. The prior cap
silently dropped long usernames from autolinking/mentions, and for remote
handles it truncated the username and dropped the @domain, turning a remote
mention into a broken local one. Adds extensive lexer coverage.
Add tests/Unit/SnowflakeServiceTest.php covering SnowflakeService::next()
and byDate(). Datacenter/worker ids are pinned via config so ids are fully
deterministic and the sequence behaviour is assertable rather than
probabilistic.
Regression coverage for the stale-sequence bug (duplicate seq on the first
two ids -> UNIQUE constraint collisions):
- first two ids use distinct sequence values
- consecutive calls yield a strictly increasing sequence (1,2,3,...)
- a 100-id burst minted in the same frozen millisecond is fully unique
- an explicit reproduction contrasting old (1,1) vs fixed (1,2) sequences
Also covers: datacenter/worker bit encoding, sequence wraparound at 4095,
cache reseeding on missing/non-numeric counters, timestamp bit encoding,
and byDate() delegation/ordering. Verified these fail on the pre-fix code
(6 failing) and pass on the fix (14 passing).
Aligns with the app's dominant convention (84 files vs 10). Avoids
running migrations for tests that never touch the database.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Normalize JSON-LD compacted single attachments (a bare object instead of a
one-item array) in getAttachments(), and route verifyAttachments() through it
so validation and import share one normalization path.
Includes PR #6589's tests plus additional edge-case coverage: list-form
preservation, bare-input normalization, and guards for missing/empty/scalar
attachments.
The remote media path validated URLs only as strings (Helpers::validateUrl
normalizes the host + checks a ban list) and then downloaded them with
Http::head + file_get_contents($url), which resolve DNS themselves and
follow redirects with no private-IP checks and no address pinning. A remote
actor whose icon.url redirected to an internal address (e.g. 172.18.0.1 or
169.254.169.254) made the queue worker fetch internal content and, for
image responses, republish it at a public avatar URL. No account required.
Fixes:
- Add SecureMediaFetchService: validates URL, resolves + rejects non-global
IPs (fail-closed), pins the connection to the validated IP via
CURLOPT_RESOLVE, disables auto-redirects with per-hop re-validation, and
enforces https-only + a byte cap. Mirrors the ActivityPubFetchService
hardening from CVE-2026-71246.
- Route MediaStorageService head()/fetchAvatar()/remoteToCloud() through it,
removing the bare Http::head and file_get_contents($url) sinks.
- validateUrl(): when DNS verification is enabled, reject hosts that resolve
into reserved ranges, closing the metadata.google.internal bypass.
- Harden adjacent same-class sinks: CustomEmojiService (emoji doc + image +
head), FetchCacheService/webfinger, and DiscoverActor.
- Add regression tests (tests/Unit/ActivityPub/SsrfUrlValidationTest.php).
Move all Eloquent models from the app/ root directory to app/Models/
for consistency with modern Laravel conventions. The project already had
54 models in App\Models; this migrates the remaining 52 legacy models.
Changes:
- Move 52 model files from app/ to app/Models/
- Update namespace declarations in each model
- Update all ~1000 import references across the codebase
- Add Relation::morphMap() in AppServiceProvider for backward
compatibility with existing polymorphic database records
- Add missing HasSnowflakePrimary imports for models that relied
on same-namespace resolution