From 4b9fbf3f3411bb161128bad5fdeba4d8f86cd1f1 Mon Sep 17 00:00:00 2001 From: Myles Date: Tue, 12 May 2026 09:51:57 +1200 Subject: [PATCH] fix(cp): cast user id to string in ResolvesUserId trait MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The trait declares a `: string` return type, but Statamic's `User::current()->id()` returns int under the Eloquent users driver (only string under the file driver). With `declare(strict_types=1)` this raises a TypeError on every request that lands in DashboardController::index() or TokenController, breaking the entire `/cp/mcp` panel for sites using Statamic's Eloquent driver. Cast at the trait boundary so the contract holds regardless of driver. The PHPDoc `@var string` annotation was incorrect under Eloquent — removed in favour of an explicit cast. Adds a Pest unit test that mocks `User::current()` to return both int and string ids, covering the file driver, the Eloquent driver, and the unauthenticated case. --- .../CP/Concerns/ResolvesUserId.php | 8 ++-- .../CP/Concerns/ResolvesUserIdTest.php | 48 +++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 tests/Unit/Http/Controllers/CP/Concerns/ResolvesUserIdTest.php diff --git a/src/Http/Controllers/CP/Concerns/ResolvesUserId.php b/src/Http/Controllers/CP/Concerns/ResolvesUserId.php index 26752a5..538f8be 100644 --- a/src/Http/Controllers/CP/Concerns/ResolvesUserId.php +++ b/src/Http/Controllers/CP/Concerns/ResolvesUserId.php @@ -15,9 +15,9 @@ private function resolveUserId(): string { $user = User::current(); - /** @var string $userId */ - $userId = $user ? $user->id() : ''; - - return $userId; + // Cast to string: Statamic's User->id() returns string under the file + // users driver but int under the Eloquent driver. The trait's return + // type contract (and downstream token storage) requires string. + return $user ? (string) $user->id() : ''; } } diff --git a/tests/Unit/Http/Controllers/CP/Concerns/ResolvesUserIdTest.php b/tests/Unit/Http/Controllers/CP/Concerns/ResolvesUserIdTest.php new file mode 100644 index 0000000..5ffc576 --- /dev/null +++ b/tests/Unit/Http/Controllers/CP/Concerns/ResolvesUserIdTest.php @@ -0,0 +1,48 @@ +id() returns an int (Eloquent driver)', function () { + $user = Mockery::mock(StatamicUserContract::class, Authenticatable::class); + $user->shouldReceive('id')->andReturn(42); + + User::shouldReceive('current')->andReturn($user); + + $result = (new ResolvesUserIdSubject)->resolveUserId(); + + expect($result)->toBe('42'); +}); + +it('returns the user id as a string when User->id() returns a string (file driver)', function () { + $user = Mockery::mock(StatamicUserContract::class, Authenticatable::class); + $user->shouldReceive('id')->andReturn('019357a0-7f6a-7000-a1b2-deadbeef0000'); + + User::shouldReceive('current')->andReturn($user); + + $result = (new ResolvesUserIdSubject)->resolveUserId(); + + expect($result)->toBe('019357a0-7f6a-7000-a1b2-deadbeef0000'); +}); + +it('returns an empty string when no user is authenticated', function () { + User::shouldReceive('current')->andReturn(null); + + $result = (new ResolvesUserIdSubject)->resolveUserId(); + + expect($result)->toBe(''); +});