Commit Graph

2050 Commits (3be6dbf5477673d7613d5403cc1b000f62c9da53)

Author SHA1 Message Date
Your Name 302edf09d5 refactor: rename PixelfedUsername rule to ValidUsername
Pure rename of the App\Rules\PixelfedUsername validation rule to
App\Rules\ValidUsername for a clearer, more idiomatic name. Updates
the class, filename, test, and all 8 controller call sites. No
behavior change.
4 weeks ago
Your Name 7c5d93e96b refactor: consolidate username validation into PixelfedUsername rule
Replace 7 duplicated inline username validation closures across 6
controllers (ApiV1Dot1, RemoteAuth, CuratedRegister, AdminInvite x2,
AppRegister, Auth/Register) with the existing PixelfedUsername rule.

Add the 'must contain at least one alphabetical character' check to
the rule so all call sites share consistent, stricter validation.

Add PixelfedUsernameTest covering all validation branches.
4 weeks ago
Daniel Supernault e3a2640704
Fix endsWith. Closes #6904 4 weeks ago
Your Name e7b70c6084 refactor: extract duplicate patterns into shared methods
1. Add FractalService with static item() and collection() helpers
   replacing 22 call sites that repeated the 4-line Fractal Manager
   + ArraySerializer boilerplate.

2. Add AccountInterstitial::createFromStatus() factory method
   consolidating 4 identical 15-line blocks that create interstitials
   with status metadata.

3. Add NotificationService::createNotification() to handle the
   repeated pattern of creating, caching, and registering a
   notification in the recipient's feed.

4. Add NotificationService::firstOrCreateNotification() for
   idempotent notifications (share/boost, mention) that should
   only notify once per actor+action+item combination.
4 weeks ago
Shlee f018004b56
Merge pull request #6892 from pixelfed/refactor/move-models-to-namespace
Refactor/move models to namespace
4 weeks ago
Shlee b4afda12d5
Merge pull request #6889 from pixelfed/refactor/status-delete-http-client
refactor: replace Guzzle pool with Laravel HTTP client in StatusDelete
4 weeks ago
Your Name c0cde2f682 refactor: move 52 legacy models from App\ to App\Models\
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
4 weeks ago
Your Name a142db87b4 polish 4 weeks ago
Your Name 2b1c9c818b polish 4 weeks ago
Your Name 17a5b5c3de fix: resolve 6 Larastan errors in controller return types
- DeckController: add missing View contract import
- CuratedRegisterController::proceed(): add default switch case
- GroupController::reportAction(): add default switch case
- InstallController::checkDatabase/precheckDatabase: add missing return
4 weeks ago
Your Name 54cfdf3c2b refactor: add return type declarations to controller methods
Adds explicit return type declarations to 498 controller methods
across 88 files. Types inferred from return statements:

- JsonResponse for response()->json() returns
- RedirectResponse for redirect()/back() returns
- View (contract) for view() returns
- Response for response() returns
- void for methods with no return value
- array for array returns
- string/int/bool for scalar returns

Also fixes 3 methods with incorrect bare returns:
- AvatarController::deleteAvatar - bare return → json response
- ImportPostController::checkPermissions - bare return → true
- RemoteAuthController::accountToId - bare return → empty array
4 weeks ago
Daniel Supernault 33dce75f2c
Pint app/ 4 weeks ago
Your Name 4320231c1f fix: replace deprecated $request->get() with $request->input()
Symfony 8.0 removes Request::get(). Laravel 13 will support Symfony 8,
so these 11 usages would break on upgrade. Using $request->input()
which checks both query string and request body (same behavior as the
old get() method).
4 weeks ago
Your Name f54e6280bc comment dead code 4 weeks ago
Your Name ea2d054a40 Revert "fix: remove dead publicApi/homeApi methods from TimelineController"
This reverts commit 8cf5321566.
4 weeks ago
Your Name 8cf5321566 fix: remove dead publicApi/homeApi methods from TimelineController
- publicApi referenced non-existent StatusTimelineTransformer class
- Neither method is routed anywhere
- Removes unused imports (Fractal, Cache, Status, Profile, UserFilter)
4 weeks ago
Your Name 5a364be58b fix: remove deprecated Passport::personalAccessClientId() and enableImplicitGrant()
- Remove Passport::personalAccessClientId() (removed in Passport v13, auto-discovers now)
- Remove Passport::enableImplicitGrant() (legacy grant, no clients use it)
- Flatten config instance.oauth.pat to pat_enabled (remove dead pat.id key)
- Add OAUTH_PAT_ENABLED=false to .env.example and .env.docker.example
- Show swal alert when PATs disabled instead of hidden API error
- Improve store() error handling to surface 403 messages in the UI
- Remove OAUTH_PAT_ID row from admin diagnostics blade
4 weeks ago
Shlee 3c6280111e
Update AccountController.php 4 weeks ago
Your Name ffcef3eb2d fix: replace Auth facade with $request->user() in request-scoped classes
Replace Auth::user() with $request->user() and Auth::check() with
$request->user() !== null (or ! $request->user()) across all
controllers and middleware that have access to the request object.

This resolves 99 larastan.noAuthFacadeInRequestScope errors and
improves Octane compatibility.

For protected helper methods without $request in scope, uses the
request() helper instead.

Methods that previously lacked a Request parameter but used Auth
facade now accept Request $request via Laravel's auto-injection.
4 weeks ago
Your Name 97929f0876 fix: resolve str_ends_with TypeError in RegisterController
PHP's str_ends_with() only accepts a string needle, not an array.
The username validation was passing an array of extensions which
caused a TypeError on every registration attempt.

Replace with a loop over a configurable array of disallowed extensions,
making it easy to add new entries.

Also updates RegisterTest to properly test the registration flow
including the RT anti-bot token and age verification fields.
4 weeks ago
Your Name 8a2649b3ff feat: add critical path test suite and fix auth/config issues
Test Infrastructure:
- Modernize phpunit.xml (bootstrap, source block, Laravel 12 env vars)
- Configure tests/Pest.php with pest()->extend(TestCase::class)->in('Feature')
- Add docker-compose.test.yml (Redis for test suite)
- Add composer test/test:quick scripts
- Rename CACHE_DRIVER to CACHE_STORE across config (backwards compatible)
- Update .env.testing for in-memory SQLite + Docker Redis

Test Coverage (190 tests):
- CriticalRoutes: public routes, auth routes, API endpoints, middleware, schedule
- Auth/LoginTest: login, logout, rate limiting, redirect behavior
- Auth/RegisterTest: registration flow, validation, disabled registration
- Auth/PasswordResetTest: reset request, token validation, password update
- Auth/TwoFactorTest: 2FA checkpoint, setup behind password confirmation
- Auth/PasswordConfirmationTest: sudo mode flow via Laravel password.confirm
- Api/ScopeTest: scope enforcement, public endpoints, admin access

Bugs Fixed:
- Fix unauthenticated API returning 500 instead of 401 (AuthenticationException
  not handled in custom exception renderer in bootstrap/app.php)
- Replace custom DangerZone middleware with Laravel password.confirm
- Add HasFactory trait to Profile model for test factories

Bugs Documented (known-bugs group):
- Registration crashes with str_ends_with TypeError (RegisterController:82)
- OAuth routes use legacy array syntax causing ReflectionFunction TypeError
4 weeks ago
Your Name 1617734907 Revert "Merge pull request #6851 from pixelfed/fix/phpstan-auth-request-scope-2"
This reverts commit ce4baf6995, reversing
changes made to 9235cb979a.
4 weeks ago
Your Name 0939f495bb fix: replace Auth facade with $request->user() in request-scoped classes
Replace Auth::user() with $request->user() and Auth::check() with
$request->user() !== null (or ! $request->user()) across all
controllers and middleware that have access to the request object.

This resolves 99 larastan.noAuthFacadeInRequestScope errors and
improves Octane compatibility.

For protected helper methods without $request in scope, uses the
request() helper instead.

Methods that previously lacked a Request parameter but used Auth
facade now accept Request $request via Laravel's auto-injection.
4 weeks ago
Your Name e7ef58969c fix: resolve undefined $status variable in GroupsPostController::deletePost
Replace all references to non-existent $status with $gp (the GroupPost
instance already in scope). This was a bug where the closure variable
name was changed but references inside the method body were not updated.
4 weeks ago
Your Name 7c964f3b4f fix: replace backslash-prefixed facade calls with imported references
Replace \Cache::, \Log::, \DB:: calls with their imported facade
equivalents. The backslash-prefix relies on global aliases which
PHPStan cannot resolve, causing class.notFound errors.
4 weeks ago
Shlee 58a34056ca
Update TimelineController.php 4 weeks ago
Shlee b7626891df
Merge pull request #6845 from pixelfed/fix/phpstan-variable-undefined
fix: resolve undefined variable bugs (phpstan variable.undefined)
4 weeks ago
Your Name e7ba43e2e1 fix: add missing use imports to resolve phpstan class.notFound errors
Add missing imports for Log, Cache, DB, FollowerService, StatusService,
LikeService, ReblogService, UserFilterService, AdminProfile, OauthClient,
and fix StatusTimelineTransformer reference (class didn't exist, replaced
with StatusTransformer).
4 weeks ago
Your Name ccd75dd903 fix: resolve undefined variable bugs (phpstan variable.undefined)
- AdminReportController: fix closure param name and remove reference to
  undefined $meta variable
- GroupsPostController: replace $status with $gp (the actual GroupPost
  variable in scope)
- PortfolioController: replace undefined $metadata with null
- DeleteWorker: remove Cache::set() call with undefined $key
4 weeks ago
Your Name 58efefb878 fix: add missing FeedUnfollowPipeline import
Add missing use statement for FeedUnfollowPipeline in PrivacySettings
and FollowerObserver. These caused PHPStan internal errors blocking
full analysis.
4 weeks ago
Your Name c807a8524c refactor: replace short facade aliases with fully-qualified imports
Convert all 273 short facade alias imports (e.g. 'use Cache;') to their
fully-qualified class names (e.g. 'use Illuminate\Support\Facades\Cache;')
across 193 files.

This resolves 643 PHPStan 'class.notFound' errors caused by the static
analyzer being unable to resolve global aliases, and aligns with modern
Laravel conventions. It also unblocks removing the aliases array from
config/app.php in a future change.

All 107 tests pass.
4 weeks ago
Your Name 98267eb26f refactor: replace deprecated str_random() with Str::random()
str_random() is a deprecated helper from laravel/helpers that was
missed in the initial helpers removal. Replace all 18 call sites
with the modern Str::random() equivalent.
4 weeks ago
Your Name edb4368b08 refactor: replace deprecated laravel/helpers with native alternatives
Replace all deprecated helper function calls:
- str_slug() → Str::slug()
- starts_with() → str_starts_with()
- ends_with() → str_ends_with()
- array_first() → Arr::first()
- array_last() → Arr::last()
- array_flatten() → Arr::flatten()

Remove laravel/helpers package from composer.json as it is no longer
needed and will not be maintained for Laravel 13.
4 weeks ago
Daniel Supernault 8f1e475407
Fix typo 4 weeks ago
Daniel Supernault 7937d91c37
Update ApiV1Controller, add is_suggestable to update_credentials endpoint 4 weeks ago
Daniel Supernault 4e2e49f843
Update ApiV1Controller, add show_atom support to update_credentials endpoint 4 weeks ago
Your Name 79541afaa0 Merge origin/staging, resolve conflicts keeping matomo/device-detector over jenssegers/agent 4 weeks ago
Shlee 80738385ba
Merge pull request #6777 from pixelfed/fix/pat-creation-500-6630
Fix: Bounce error on PAT when OAUTH_PAT_ENABLED is false
4 weeks ago
Shlee 06e3351e92
Merge pull request #6778 from pixelfed/fix/prevent-pat-client-deletion-6630
Fix: Improve the web UX for deleting the OAuth Client and PAT
4 weeks ago
Shlee fb655f1308
Merge pull request #6782 from ashleyhull-versent/shift-179490
Laravel Shift Preshift
4 weeks ago
Ashley Hull ab07a705e6
Merge branch 'dev' into shift-179490 4 weeks ago
Shlee 68dca50973
Merge pull request #6774 from pixelfed/fix/oauth-scope-bypass-remove-follower-6643
Fix: OAuth accountRemoveFollowById to check token.
4 weeks ago
Shlee 20123ff5ba
Merge pull request #6773 from pixelfed/fix/first-follower-pagination-6695
Fix: Show first follower/following record excluded from previous API responses
4 weeks ago
Your Name 552a55c2d2 Upgrade images to v4 4 weeks ago
Daniel Supernault 91645faeee
Lint 4 weeks ago
Daniel Supernault e1235dfd75
Fix ApiV1Controller, ensure follow notifications have an account 4 weeks ago
Your Name 53759e3ad6 Prevent deletion of personal access OAuth client
Fixes #6630 (partial — deletion causing broken PAT)

If a user deletes the OAuth client that serves as the personal access
client, all PAT creation breaks for the entire instance with a 500 error.

Changes:
- Add custom OAuthClientController@destroy that checks if the client
  has the personal_access grant type before allowing deletion
- Returns 403 with a clear error message if deletion is blocked
- Add confirmation dialog before client deletion in the frontend
- Add error handling to show server error messages to the user

This prevents accidental destruction of the PAT infrastructure.
4 weeks ago
Your Name 1ab677a526 Handle PAT creation gracefully when not configured
Fixes #6630 (partial — PAT 500 error)

Previously, POST /oauth/personal-access-tokens would throw an unhandled
RuntimeException (HTTP 500) when:
- OAUTH_PAT_ENABLED is false (the default), or
- No personal access client exists in the database

Now the endpoint:
1. Returns 403 with a clear message if PAT is disabled in config
2. Catches RuntimeException from the token factory and returns 500
   with an actionable error message instead of a stack trace
4 weeks ago
Your Name 822e9c98cb Fix OAuth scope bypass on remove_from_followers endpoint
Fixes #6643

The POST /api/v1/accounts/{id}/remove_from_followers endpoint was missing
the token existence check (! $request->user()->token()). While the
tokenCan('follow') scope check was already present, the missing token
guard meant unauthenticated token-less requests could potentially bypass
the scope enforcement.

Added the standard guard pattern consistent with accountFollowById and
accountUnfollowById endpoints.

Also adds tests verifying:
- Read-only tokens are denied (403)
- Follow-scoped tokens succeed (200)
- Unauthenticated requests are denied (403)
4 weeks ago
Your Name 396cf2d861 Fix first follower/following record excluded from API responses
Fixes #6695

When no pagination params are provided, the default min_id was set to 1
and the query used 'id > 1', which excluded the very first follower row
(id=1) on fresh instances.

Changed default min_id from 1 to 0 and switched the direction check from
truthy evaluation to !== null, so the query becomes 'id > 0' which
correctly includes all records.
4 weeks ago