Commit Graph

188 Commits (e36d42f668bde333cfae6ae9b95e1e101d3771d0)

Author SHA1 Message Date
Your Name ed71baaab3 Add notification epoch inline fallback test (#7162)
getEpochId() now computes a bounded epoch inline on cache miss (oldest
notification within the window) instead of returning 1, which would turn
every notification query into a full-table scan until the async pipeline
repopulates the cache. Adds coverage for the recent-id fallback and the
no-recent-notifications case. (Code change committed alongside the #7195
NotificationService edits.)
2 weeks ago
Your Name c0f29d4a4b Fix web notifications not loading (#7195)
Notification status hydration compared item_type strictly against
Status::class (App\Models\Status). Rows created before the App\ ->
App\Models\ namespace migration store the legacy 'App\Status' morph-map
alias, so the comparison failed and favourite/comment/mention
notifications came back with no attached status. The web UI filters those
out client-side but keeps paginating (response never empty), leaving the
infinite-scroll loader spinning forever.

- NotificationTransformer + Mastodon NotificationTransformer: match both
  the legacy alias and the current FQCN when hydrating status.
- NotificationService::buildNotification: same alias-aware deleted-item guard.
- NotificationService::getMaxPage/getMinPage: filter out unrenderable
  notifications (status-type without a hydrated status) so the endpoint
  never returns rows the UI discards, fixing pagination termination; warn
  on unexpected notification types.
- Tests for transformer hydration (legacy + current), renderable filtering,
  the unexpected-type warning, and pagination termination.
2 weeks ago
Your Name 6ffdc53dee polish 2 weeks ago
Your Name 341351c47e Remove sha256 verification from MediaMoveStorageLocalToCloud
original_sha256 is the pre-optimization upload hash and can never match the
optimized local file, so comparing against it is not a valid integrity
check for migration. Drop the --verify-sha256 option and the checksum step
entirely; verify now relies on cloud-object existence and size parity.
2 weeks ago
Your Name 441a94e731 Make original_sha256 verify opt-in in MediaMoveStorageLocalToCloud
original_sha256 is the hash of the file as originally uploaded, but the
async optimize pipeline (ImageResize/ImageUpdate) rewrites the local file
in place and never updates that column. Verifying the current local bytes
against it made every optimized image fail with sha256_mismatch, so the
migration reported moved=0 and exited 1.

Add a --verify-sha256 flag (off by default) that gates the checksum step.
By default verify relies on cloud-object existence and size parity, which
is the only signal that actually describes the uploaded copy. Add tests
covering both the default (migrates) and opt-in (fails) paths.
2 weeks ago
Your Name 8aa3144745 Fix story video upload probe path (#7203)
apiV1Add passed an absolute path to FFMpeg::open(), which laravel-ffmpeg
resolves relative to the local disk root, producing a doubled path and an
ffprobe 'Unable to probe / No such file or directory' failure.

Open the file via the disk instead: FFMpeg::fromDisk('local')->open($path)
for local storage, and an on-demand local disk rooted at the temp dir for
cloud storage.

Adds feature tests that pin the disk-relative path resolution.
2 weeks ago
Shlee 07367c4ea2
Update UserStorageServiceTest.php 2 weeks ago
Your Name 888fa1bc30 Fix tests 2 weeks ago
Shlee 289251985a
Merge pull request #7199 from pixelfed/fix/story-publish-validation-exception
Laravel 13 Prep: Stop swallowing overlay ValidationException into a generic 500
2 weeks ago
Your Name 62d3bc8406 Stop swallowing overlay ValidationException into a generic 500
publishNext() throws ValidationException::withMessages() for invalid
story overlays (bad text/hashtag/mention/url/type), but the enclosing
catch (\Exception $e) caught it too, since ValidationException extends
Exception. Clients got a generic 500 "Failed to create story" instead
of the intended 422 with field-level errors, and the log was flooded
with ordinary user-input validation failures logged as server errors.
Catch ValidationException separately, roll back, and rethrow it so
Laravel's exception handler renders the normal 422 response.
2 weeks ago
Your Name 8fa18ff8c6 Fix dangling DB transactions in CustomFilterController
store() and update() open a manual DB::beginTransaction() but had early
return paths (duplicate keyword, keyword not found, per-filter keyword
limit) that hit neither DB::commit() nor the catch block's rollback,
leaving the transaction open past the end of the request. Add the
missing DB::rollBack() call on each early-exit branch, matching the
manual-transaction pattern used elsewhere in the app.
2 weeks ago
Your Name 255bdaa2a0 Use LazilyRefreshDatabase instead of plain RefreshDatabase in tests
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>
2 weeks ago
Shlee 84df3de562
Update StoryExpireRemoteCacheTest.php 2 weeks ago
Daniel Supernault 7a5192481c
Fix StoryExpireRemoteCacheTest 2 weeks ago
Your Name ce073ffc92 Merge remote-tracking branch 'origin/staging' into feature/honeypot-spam-protection
# Conflicts:
#	routes/web.php
2 weeks ago
Your Name 08a442e661 Rewrite 2FA tests for the pending-login refactor
The 2FA flow moved from a middleware-gated i/auth/checkpoint model to a
pending-login model (auth.pending session, POST /login/2fa, /login?step=2fa
challenge). The old tests referenced the removed route and dead session keys
(2fa.session.active, 2fa.attempts) and failed with 404s.

Rewritten against the new code as source of truth:
- Checkpoint test: throttle assertion retargeted to the login/2fa route;
  failed-verification audit log now driven through a pending 2FA session.
- Logout-session test: asserts auth.pending is cleared and the user stays a
  guest after MAX_2FA_ATTEMPTS failures (replacing the old flag cleanup).
- TwoFactorTest: challenge-redirect and challenge-page cases rewritten around
  the login flow; setup/recovery password-confirmation cases unchanged.
- MiddlewarePipelineTest: 2FA is enforced at login, not per-request, so an
  authenticated 2FA user browses normally.

Full suite: 715 passed.
2 weeks ago
Your Name 007f97f987 Expand test coverage for storage_used improvements
- Suspended/missing user guards for get, increase, decrement, recalculate
- Staleness window boundary (fresh at N-1h, stale at N+1h)
- Sub-1000-byte rounding on increase/decrement (floor to KB)
- Command --stale filter (only recomputes stale/never-calculated users) and
  missing --user id failure
- Migration dispatches the backfill job to the low queue (Bus::fake)
2 weeks ago
Your Name 5a9c235922 Backfill storage_used on upgrade via queued job + data migration
Repair accounts whose storage counter drifted before the self-heal logic
existed (#7169). A data migration dispatches RecalculateAllUserStoragePipeline
to the low queue so the deploy is not blocked while every user is recomputed
from source. The job is unique and idempotent, so re-runs are harmless.

- RecalculateAllUserStoragePipeline: chunked recalc of all active users
- Migration dispatches the job (no inline heavy work during deploy)
- Test covers bulk recalculation from actual media
2 weeks ago
Your Name 61a1c30756 Self-heal stale storage_used on read to unblock stuck accounts
UserStorageService::get() now recalculates from source when the cached
counter is missing or older than STALE_AFTER_HOURS, instead of returning a
possibly-inflated cached value. This is what unblocks a user stuck at the
account size limit: the limit check on their next upload attempt reads the
freshly recalculated real usage rather than the drifted value (#7169).

The upload flow reads get() and enforces the limit BEFORE the write-path
heal runs, so a blocked user could never self-heal via upload/delete alone.
Healing on read closes that gap and makes the scheduled reconciler a
belt-and-suspenders safety net rather than a requirement.

A fresh counter is still trusted as-is (no per-read SUM). Adds tests for the
stale-get recompute and fresh-get trust paths.
2 weeks ago
Your Name 26d3e8bb8e Self-heal stale storage_used on upload/delete hot path
Make increaseStorageUsed/decrementStorageUsed recalculate from source when
the cached counter is older than STALE_AFTER_HOURS (168h) or never
calculated, so an affected user is corrected the next time they upload or
delete without waiting for the nightly reconciler. Callers save/delete the
media row before calling these, so the from-source recalc already reflects
the change and the incremental delta is skipped on the recalc path.

- Add UserStorageService::STALE_AFTER_HOURS and isStale() helper (no extra
  query: reads the already-loaded model), with defensive Carbon parsing
- Cast users.storage_used_updated_at to datetime so freshness comparisons
  work on a Carbon instance
- Add tests for stale/fresh/never-calculated increase and decrement paths
2 weeks ago
Your Name 6496904293 Fix account storage limit not freeing on media deletion (#7169)
users.storage_used only ever grew: uploads incremented it but no deletion
path decremented it, so users hit the account size limit even when their
real media usage was well below it.

- Decrement storage_used in MediaDeletePipeline when media is removed
- Add UserStorageService::increaseStorageUsed / decrementStorageUsed as the
  fast, symmetric hot-path counter updates (floor-based, clamped at zero)
- Refactor the 6 upload call sites to use increaseStorageUsed instead of
  duplicated inline writes (also fixes ceil/floor drift vs the reconciler)
- Add (user_id, size) covering index so per-user SUM(size) is not a full
  table scan (INPLACE/LOCK=NONE, skipped on sqlite)
- Add user:storage:recalculate command to repair affected accounts, with a
  daily --stale=168 scheduled reconciler to correct any drift
- Add regression tests for the pipeline and UserStorageService
2 weeks ago
Shlee 5d38faa257
Merge pull request #7166 from shleeable/fix/dangerzone-logout-clear-2fa-session
Invalidate session on DangerZone forced logout to clear 2FA state
2 weeks ago
Your Name 58e8a4922d Invalidate session on DangerZone forced logout to clear 2FA state 2 weeks ago
Shlee e60082b9b9
Merge pull request #7165 from shleeable/fix/media-blocklist-indexed-lookup
Use indexed query for media blocklist lookups and allow removing inactive hashes
2 weeks ago
Your Name e8f2b06afe Use indexed query for media blocklist lookups and allow removing inactive hashes 2 weeks ago
Shlee 9cf879d375
Merge pull request #7163 from shleeable/fix/status-lexer-no-autolink-fanout
Deliver posts regardless of profile no_autolink flag
2 weeks ago
Your Name 9e14151228 Deliver posts regardless of profile no_autolink flag 2 weeks ago
Your Name 742c1a6bc8 Require dangerzone sudo mode on curated register, shadow filter and page admin controllers 2 weeks ago
Your Name 68becbe2cc lint 2 weeks ago
Shlee 97b5d2f180
Merge pull request #7159 from shleeable/fix/directory-exclude-private-profiles
Exclude private profiles from public directory and clear suggestable on going private
2 weeks ago
Your Name 1581863093 Exclude private profiles from public directory and clear suggestable on going private 2 weeks ago
Shlee 903c191f10
Merge pull request #7158 from shleeable/fix/2fa-logout-session-cleanup
Clear 2FA session state on forced logout after failed attempts
2 weeks ago
Your Name 97f1a097ff Clear 2FA session state on forced logout after failed attempts 2 weeks ago
Shlee eaadf425f2
Merge pull request #7157 from shleeable/fix/dangerzone-oidc-per-user
Scope DangerZone OIDC sudo bypass to OIDC-registered users
2 weeks ago
Your Name 7483a4b05b Scope DangerZone OIDC sudo bypass to OIDC-registered users 2 weeks ago
Shlee 72f0990dd8
Merge pull request #7156 from shleeable/fix/network-timeline-null-account
Filter null-account statuses from non-cached network timeline
2 weeks ago
Shlee e65a17c175
Merge pull request #7155 from shleeable/fix/get-or-fetch-remote-profile-fallback
Fall back to stored profile when remote refresh fails
2 weeks ago
Your Name 917a13d4a7 Filter null-account statuses from non-cached network timeline 2 weeks ago
Your Name 73fb5ed696 Fall back to stored profile when remote refresh fails 2 weeks ago
Your Name 444c796bac Trigger StatusHashtag observer on deletion to keep cached_count accurate 2 weeks ago
Shlee 5bd33640fe
Merge pull request #7151 from shleeable/fix/status-dedupe-deterministic
Deterministically keep earliest status per uri in dedupe command
2 weeks ago
Your Name e360fab619 Deterministically keep earliest status per uri in dedupe command 2 weeks ago
Shlee 189408edf0
Merge pull request #7149 from shleeable/fix/authorize-interaction-intended-redirect
Use intended-redirect session for authorize_interaction guest login
2 weeks ago
Your Name 0234a305ae Use intended-redirect session for authorize_interaction guest login 2 weeks ago
Your Name 1ffda3eba9 Federate unlike before deleting Like so retries can deliver 2 weeks ago
Your Name eb9bd11303 Apply Pint lint fixes to session test files 2 weeks ago
Shlee 46fb9613e3
Merge pull request #7146 from shleeable/fix/2fa-checkpoint-throttle
Rate limit and audit-log 2FA checkpoint verification
2 weeks ago
Your Name 8cebb24c04 Rate limit and audit-log 2FA checkpoint verification 2 weeks ago
Shlee 0ebe1f8fb1
Merge pull request #7145 from shleeable/fix/media-blocklist-check-before-store
Check media blocklist before storing uploads to prevent orphaned files
2 weeks ago
Your Name ec6827bae2 Check media blocklist before storing uploads to prevent orphaned files 2 weeks ago