Commit Graph

123 Commits (327348be02fe27499bcd7575cfd89f8bbd4cb72b)

Author SHA1 Message Date
Your Name 327348be02 Send Pixelfed User-Agent on federated account deletion deliveries 3 weeks ago
Shlee 9c5be0e271
Merge pull request #7136 from shleeable/fix/custom-filter-rate-limit-ttl
Fix custom filter rate-limit counter never expiring
3 weeks ago
Your Name 63e3c95fae Fix custom filter rate-limit counter never expiring 3 weeks ago
Your Name afcb68c183 Fix registration form redirecting when max_users is falsy 3 weeks ago
Shlee daf83fd564
Merge pull request #7132 from shleeable/fix/pat-renew-kill-switch
Enforce pat_enabled kill-switch on personal access token renew
3 weeks ago
Shlee a546c4982a
Merge pull request #7133 from shleeable/fix/remote-auth-domain-compatible-guard
Fix isDomainCompatible throwing on non-json beagle response
3 weeks ago
Your Name d51cf4ccc9 Fix isDomainCompatible throwing on non-json beagle response 3 weeks ago
Your Name d2b11a71b3 Enforce pat_enabled kill-switch on personal access token renew 3 weeks ago
Shlee 13a441af93
Merge pull request #7131 from shleeable/fix/login-activity-groupby
Fix login activity groupBy returning stale rows and 500 on strict DBs
3 weeks ago
Your Name 3cb5b6e1ff Fix login activity groupBy returning stale rows and 500 on strict DBs 3 weeks ago
Your Name fe70cd1155 Fix directory listing reporting oauth and activitypub flags always true 3 weeks ago
Shlee aa152372c9
Merge pull request #7121 from shleeable/fix/status-remote-update-ssrf
Harden remote status update media fetch against SSRF
3 weeks ago
Shlee 18ba2dc932
Merge pull request #7119 from shleeable/fix/hashtag-follow-null-profile
Guard hashtag follow against null profile for soft-deleted accounts
3 weeks ago
Shlee 1cb56f0ba0
Merge pull request #7120 from shleeable/fix/inbox-keyid-host-validation
Validate publicKey.id host on inbox actor ingest
3 weeks ago
Shlee b30b711097
Merge pull request #7122 from shleeable/fix/reclaim-username-orphan-profile
Scope reclaim-username profile deletion and fail on surviving orphan
3 weeks ago
Shlee 3b8d7b8d1f
Merge pull request #7123 from shleeable/fix/poll-vote-scope-authz
Enforce poll scope authorization on vote endpoint
3 weeks ago
Shlee 0900509c27
Merge pull request #7124 from shleeable/fix/collection-store-visibility-required
Require visibility on collection store to match NOT NULL schema
3 weeks ago
Shlee b43a5f99d7
Merge pull request #7125 from shleeable/fix/statusdelete-trashed-profile
Fix StatusDelete crashing on soft-deleted owning profile
3 weeks ago
Shlee 3f63b245bc
Merge pull request #7126 from shleeable/fix/admin-instance-stats-postgres-guard
Fix admin instance stats endpoint 404 on Postgres via strict is_admin boolean check
3 weeks ago
Shlee fe8c53ddd7
Merge pull request #7127 from shleeable/fix/favourites-pagination-off-by-one
Fix favourites pagination skipping one favourite per page
3 weeks ago
Your Name a286509622 Require visibility on collection store to match NOT NULL schema 3 weeks ago
Your Name a8a7a430d7 Enforce poll scope authorization on vote endpoint 3 weeks ago
Your Name a1724a4b1c Scope reclaim-username profile deletion and fail on surviving orphan 3 weeks ago
Your Name e79135a771 Fix favourites pagination skipping one favourite per page boundary 3 weeks ago
Your Name 856f2f8f2d Harden remote status update media fetch against SSRF 3 weeks ago
Your Name 8258a5a5f8 Guard hashtag follow against null profile for soft-deleted accounts 3 weeks ago
Your Name 1905da723d Validate publicKey.id host on inbox actor ingest to prevent key_id poisoning 3 weeks ago
Your Name df1e771f93 Fix admin instance stats endpoint 404 on Postgres via strict is_admin check 3 weeks ago
Your Name 6e7419bb96 Fix StatusDelete crashing on soft-deleted owning profile 3 weeks ago
Your Name 3b951d41d8 Fix accounts statuses max_id pagination returning duplicate boundary status 3 weeks ago
Daniel Supernault 48750f7079
Fix test 3 weeks ago
Your Name 6d8ad3885a Convert string class references to ::class
Applies the ::class conversion from pixelfed-staging PR #9 (patch 1/21),
formatted with Pint (short imported ::class form). Excludes the
ModelNamespaceMigrationTest namespace assertions, which intentionally
compare against literal namespace strings.
4 weeks ago
Your Name 6b14b229d1 Fix media storage migration crash when no .env file exists
The media storage migration commands read/parsed the .env file directly to
check and flip PF_ENABLE_CLOUD. In containerized deploys there is no .env on
disk (config is injected via env vars), so updateEnvFile() threw
'file_get_contents(.env): Failed to open stream' and the scheduled command
exited 1.

- Check the live setting via config_cache('pixelfed.cloud_storage') like the
  rest of the app, instead of parsing .env.
- Make the .env write best-effort in ManagesMediaStorageEnv: skip gracefully
  when the file is missing or read-only, and still apply the runtime + DB
  config-cache updates (the load-bearing changes on a hot server).
- Apply the same fix to the sibling unstable:MediaMoveStorageCloudToLocal.
- Add a regression test covering the no-.env container scenario.
4 weeks ago
Shlee 003953eb3e
Merge pull request #7045 from pixelfed/perf/follower-service-following-ids
Deduplocation: add FollowerService::getFollowingIds for common function
4 weeks ago
Your Name 667f6e2fc9 Extract following-ids lookup into FollowerService::getFollowingIds
The Cache::remember('profile:following:'.$pid, ...) block that plucks
following_id and appends the caller's own id was copy-pasted across four
call sites, with inconsistent TTLs (1440 minutes vs 1209600 seconds).

Add FollowerService::getFollowingIds($pid), which owns the cache key that
add()/remove() already invalidate, and use it from InternalApiController,
PublicApiController, ApiV1Controller and HashtagUnfollowPipeline. Removes
the now-unused Follower/Cache imports left behind.

Adds a test covering the followed-ids-plus-self result and the
follows-nobody case.
4 weeks ago
Your Name c4e5b96d25 Stream deletions with cursor and batch notification lookups in delete jobs
The status- and account-deletion jobs loaded whole collections with
->get() and then looped, running a per-row Notification lookup inside
each iteration.

- StatusDelete / RemoteStatusDelete: resolve associated DirectMessage and
  MediaTag ids, fetch their notifications in a single whereIn query,
  clear each via cursor (NotificationService::del must run per row for
  cache/redis cleanup), then bulk delete the DMs and media tags.
- DeleteAccountPipeline / DeleteRemoteProfilePipeline: stream Story and
  Collection deletions with cursor() instead of loading every row into
  memory. Per-row file unlink and item deletes are preserved.

Adds StatusDeleteCleanupTest covering DM + notification cleanup, media
tag + notification cleanup, and the no-associations case.
4 weeks ago
Your Name e4e12fad7c Extract duplicated blocked-id and duplicate-shortcode query patterns
Two query patterns were copy-pasted across several call sites:

- The 'users who blocked me, plus myself' list used to filter profile
  search (UserFilter::whereFilterableId($pid)->pluck('user_id')->push($pid))
  appeared in ComposeController (x2) and DirectMessageController. Extracted
  to UserFilterService::searchExcludedProfileIds(). Note this is the
  inverse of blocks() (who I blocked), so it is a distinct method.

- CustomEmoji duplicate detection (groupBy('shortcode')->havingRaw(
  'count(*) > 1')) appeared three times in AdminController. Extracted to a
  CustomEmoji::duplicateShortcodes() query scope.

Adds tests for both. No behaviour change.
4 weeks ago
Shlee 7ad550d2f7
Merge pull request #7037 from pixelfed/perf/seasonal-sql-aggregation
Compute Year-in-Review averages in SQL instead of in PHP
4 weeks ago
Your Name cd873c8976 Compute Year-in-Review averages in SQL instead of in PHP
SeasonalController::getData computed the average posts/likes per profile
by grouping in SQL, then pulling every grouped row into a collection and
calling ->pluck('count')->avg() in PHP. This loaded one row per profile
into memory just to average.

Wrap the grouped per-profile counts in a subquery and let the database
compute AVG(count), returning a single value. Also drops the invalid
SELECT * with GROUP BY (ONLY_FULL_GROUP_BY) by selecting count(*) only.

Adds a test verifying the average-of-per-profile-counts and its
exclusions (remote, wrong type, out-of-range date), plus the empty case.
4 weeks ago
Shlee 660880eac7
Merge pull request #7036 from pixelfed/fix/remote-auth-http-timeout
Add timeout, retry and error handling to remote auth HTTP calls
4 weeks ago
Your Name 2ad6e28318 Add timeout, retry and error handling to remote auth HTTP calls
RemoteAuthService::getVerifyCredentials, getFollowing and getToken made
outbound HTTP requests to a user-controlled remote instance during the
Mastodon login flow with no timeout, no retry and no exception handling.
A slow or hostile instance could hang the request or surface an uncaught
exception.

Wrap all three in timeout(20)->retry(3, 750) with try/catch that returns
false on failure, matching the existing pattern in isDomainCompatible().
Callers already treat a falsy return as a failure; add the missing guard
at the one verify_credentials call site that accessed the result array
without checking it first.

Adds RemoteAuthServiceTest covering connection failure, server error and
success paths.
4 weeks ago
Your Name fbfd26d775 Mark direct messages read with a single bulk update
DirectMessageController@read fetched every matching DirectMessage and
saved each one individually in a loop, issuing one UPDATE per row. On an
active thread this is N queries.

Pluck the matching ids and perform a single bulk update, preserving the
existing response (the list of affected message ids) and updated_at
behaviour.

Adds regression tests covering the marked-read ids, the status_id lower
bound, and sender isolation.
4 weeks ago
Your Name 29280cd950 Fix silent failure in avatar upload endpoints
AvatarController@store and BaseApiController@avatarUpdate wrapped the
upload flow in an empty catch(\Exception) block and returned a success
response even when the upload or save failed.

Log the exception and return a real error response (500 JSON for the
API endpoint, a redirect with validation errors for the web endpoint).

Adds regression tests covering the failure path, the success path, and
non-image rejection.
4 weeks ago
Daniel Supernault c19fd269b1
Lint 4 weeks ago
Daniel Supernault 584ce27f71
Add Sanctum support 4 weeks ago
Your Name 9214e9680a Add admin:resyncemoji command to re-download remote emoji locally
Adds CustomEmojiService::resync() which re-fetches a remote custom emoji's
media from its origin (image_remote_url) via the SSRF-hardened
SecureMediaFetchService and stores it locally under public/{media_path},
reusing the existing headCheck validation and cache busting.

The admin:resyncemoji command takes a comma-separated list of emoji
filenames, looks each up by media_path, and resyncs remote ones. Supports
--missingonly, --dry-run and --force.
4 weeks ago
Your Name d456b7b64a Add structured metadata to MediaDeletePipeline skip/failure logs
Replace interpolated log strings with structured context (media/status/profile/
user ids, mime, size, order, paths, hls_path, remote flag, timestamps) so
operators can trace why orphan-purge deletions are skipped or fail.
4 weeks ago
Your Name 0df4c7117d Add domain-mismatch metadata to Announce status fetch and stop noisy ERROR logs
storeStatus() now throws with JSON metadata (checked id/url hosts, expected
rule, and the full activity payload) when status domains mismatch. The Announce
inbox handler catches this, logs the context at debug level, and returns
gracefully instead of surfacing a full production ERROR stack trace.
4 weeks ago
Your Name b6d645a4d4 fix: delete superseded image/thumbnail files instead of orphaning them
Image::handleImageTransform derives the output filename from the current
media_path and applies the encoder's output extension. When that differs from
what is already stored (heic/avif -> jpg, or a thumbnail regenerated to a new
extension), the new file landed at a different path and the previous file was
left orphaned in the media directory — the source of the leftover _thumb files
under public/m/_v2.

Capture the path each transform supersedes and delete it after a successful
write (only when the new output path differs, so we never delete what we just
wrote). Remove the stale MediaDeleteLeafCleanupTest whose source change is not
in the tree.
4 weeks ago
Your Name fce75030e0 refactor: simplify storage:maintenance flags and make it quiet by default
- Drop --except (--only already covers task selection)
- Quiet by default; per-root/per-item and summary lines now require -v/--verbose
- Errors are always shown regardless of verbosity
- Document the command in the console README
4 weeks ago