From 68a717ac309bc44634f0b8f0dfcd044b84aa968d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 04:41:10 +0000 Subject: [PATCH 1/2] Refactor: Use `#[CurrentUser]` attribute instead of `auth()->user()` and `$request->user()` Replaced usages of `auth()->user()` and `$request->user()` with the new `#[CurrentUser]` attribute from Laravel 11. Updated custom validation rules, Livewire components, routes, and controllers to use dependency injection. Co-authored-by: yilanboy <27554321+yilanboy@users.noreply.github.com> --- ...neratePasskeyRegisterOptionsController.php | 17 ++++++++------- .../Auth/VerifyEmailController.php | 10 +++++---- app/Rules/MatchOldPassword.php | 9 +++++++- .../\342\232\241create-modal.blade.php" | 19 +++++++++++------ .../\342\232\241edit-modal.blade.php" | 16 ++++++++++---- .../layouts/\342\232\241header.blade.php" | 21 ++++++++++++------- .../\342\232\241index.blade.php" | 12 +++++++---- .../password/\342\232\241edit.blade.php" | 2 +- routes/api.php | 6 ++++-- 9 files changed, 75 insertions(+), 37 deletions(-) diff --git a/app/Http/Controllers/Api/GeneratePasskeyRegisterOptionsController.php b/app/Http/Controllers/Api/GeneratePasskeyRegisterOptionsController.php index 33b0c17f..c8d6ce18 100644 --- a/app/Http/Controllers/Api/GeneratePasskeyRegisterOptionsController.php +++ b/app/Http/Controllers/Api/GeneratePasskeyRegisterOptionsController.php @@ -5,10 +5,11 @@ namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; +use App\Models\User; use App\Services\Serializer; use Cose\Algorithms; +use Illuminate\Container\Attributes\CurrentUser; use Illuminate\Http\JsonResponse; -use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Session; use Illuminate\Support\Str; @@ -23,7 +24,7 @@ class GeneratePasskeyRegisterOptionsController extends Controller { - public function __invoke(Request $request, Serializer $serializer): JsonResponse|string + public function __invoke(#[CurrentUser] User $user, Serializer $serializer): JsonResponse|string { // 建立一個信賴方實體 // id 是網站的網域名稱 @@ -37,13 +38,13 @@ public function __invoke(Request $request, Serializer $serializer): JsonResponse // id 必須是唯一的,通常是用戶的 ID 或 UUID // 需要注意的是,name 不可以使用用戶的敏感資訊,例如 email 或電話號碼 $userEntity = new PublicKeyCredentialUserEntity( - name: $request->user()->name, - id: (string) $request->user()->id, - displayName: $request->user()->name + name: $user->name, + id: (string) $user->id, + displayName: $user->name ); } catch (InvalidDataException $e) { Log::error('無法建立 Webauthn 用戶實體', [ - 'user_id' => $request->user()->id, + 'user_id' => $user->id, 'exception' => $e->getMessage(), ]); @@ -81,7 +82,7 @@ public function __invoke(Request $request, Serializer $serializer): JsonResponse ); } catch (InvalidDataException $e) { Log::error('無法建立 Webauthn 註冊選項', [ - 'user_id' => $request->user()->id, + 'user_id' => $user->id, 'exception' => $e->getMessage(), ]); @@ -95,7 +96,7 @@ public function __invoke(Request $request, Serializer $serializer): JsonResponse $optionsJson = $serializer->toJson($options); } catch (SerializerExceptionInterface $e) { Log::error('Webauthn 註冊選項序列化失敗', [ - 'user_id' => $request->user()->id, + 'user_id' => $user->id, 'exception' => $e->getMessage(), ]); diff --git a/app/Http/Controllers/Auth/VerifyEmailController.php b/app/Http/Controllers/Auth/VerifyEmailController.php index 4f878cb9..3e750864 100644 --- a/app/Http/Controllers/Auth/VerifyEmailController.php +++ b/app/Http/Controllers/Auth/VerifyEmailController.php @@ -5,7 +5,9 @@ namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; +use App\Models\User; use Illuminate\Auth\Events\Verified; +use Illuminate\Container\Attributes\CurrentUser; use Illuminate\Foundation\Auth\EmailVerificationRequest; use Illuminate\Http\RedirectResponse; @@ -14,14 +16,14 @@ class VerifyEmailController extends Controller /** * Mark the authenticated user's email address as verified. */ - public function __invoke(EmailVerificationRequest $request): RedirectResponse + public function __invoke(EmailVerificationRequest $request, #[CurrentUser] User $user): RedirectResponse { - if ($request->user()->hasVerifiedEmail()) { + if ($user->hasVerifiedEmail()) { return redirect()->intended('/?verified=1'); } - if ($request->user()->markEmailAsVerified()) { - event(new Verified($request->user())); + if ($user->markEmailAsVerified()) { + event(new Verified($user)); } return redirect()->intended('/?verified=1'); diff --git a/app/Rules/MatchOldPassword.php b/app/Rules/MatchOldPassword.php index 03600b0f..b212979c 100644 --- a/app/Rules/MatchOldPassword.php +++ b/app/Rules/MatchOldPassword.php @@ -4,13 +4,20 @@ namespace App\Rules; +use App\Models\User; use Closure; +use Illuminate\Container\Attributes\CurrentUser; use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Support\Facades\Hash; use Illuminate\Translation\PotentiallyTranslatedString; class MatchOldPassword implements ValidationRule { + public function __construct( + #[CurrentUser] + protected ?User $user = null + ) {} + /** * Run the validation rule. * @@ -18,7 +25,7 @@ class MatchOldPassword implements ValidationRule */ public function validate(string $attribute, mixed $value, Closure $fail): void { - if (! Hash::check($value, auth()->user()->password)) { + if (! Hash::check($value, $this->user->password)) { $fail('舊密碼錯誤'); } } diff --git "a/resources/views/components/comments/\342\232\241create-modal.blade.php" "b/resources/views/components/comments/\342\232\241create-modal.blade.php" index 76491bd9..504ba88a 100644 --- "a/resources/views/components/comments/\342\232\241create-modal.blade.php" +++ "b/resources/views/components/comments/\342\232\241create-modal.blade.php" @@ -5,9 +5,11 @@ use App\Livewire\Forms\CommentForm; use App\Models\Comment; use App\Models\Post; +use App\Models\User; use App\Notifications\NewComment; use App\Rules\Captcha; use App\Traits\MarkdownConverter; +use Illuminate\Container\Attributes\CurrentUser; use Livewire\Attributes\Locked; use Livewire\Component; @@ -24,10 +26,15 @@ public bool $previewIsEnable = false; - public function mount(): void - { + public ?User $currentUser = null; + + public function mount( + #[CurrentUser] + ?User $user + ): void { + $this->currentUser = $user; $this->form->post_id = $this->postId; - $this->form->user_id = auth()->id(); + $this->form->user_id = $user?->id; } public function save(): void @@ -78,8 +85,8 @@ public function save(): void 'body' => $comment->body, 'created_at' => $comment->created_at->toDateTimeString(), 'updated_at' => $comment->updated_at->toDateTimeString(), - 'user_name' => auth()->check() ? auth()->user()->name : null, - 'user_gravatar_url' => auth()->check() ? get_gravatar(auth()->user()->email) : null, + 'user_name' => $this->currentUser !== null ? $this->currentUser->name : null, + 'user_gravatar_url' => $this->currentUser !== null ? get_gravatar($this->currentUser->email) : null, 'children_count' => 0, ], ); @@ -198,7 +205,7 @@ class="space-y-2" >
- {{ auth()->check() ? auth()->user()->name : '訪客' }} + {{ $this->currentUser !== null ? $this->currentUser->name : '訪客' }} {{ now()->format('Y 年 m 月 d 日') }}
diff --git "a/resources/views/components/comments/\342\232\241edit-modal.blade.php" "b/resources/views/components/comments/\342\232\241edit-modal.blade.php" index 94d675b9..91fae3cc 100644 --- "a/resources/views/components/comments/\342\232\241edit-modal.blade.php" +++ "b/resources/views/components/comments/\342\232\241edit-modal.blade.php" @@ -4,8 +4,10 @@ use App\Livewire\Forms\CommentForm; use App\Models\Comment; +use App\Models\User; use App\Traits\MarkdownConverter; use Illuminate\Auth\Access\AuthorizationException; +use Illuminate\Container\Attributes\CurrentUser; use Livewire\Component; new class extends Component @@ -21,9 +23,15 @@ public bool $previewIsEnable = false; - public function mount(): void - { - if (! auth()->check()) { + public ?User $currentUser = null; + + public function mount( + #[CurrentUser] + ?User $user + ): void { + $this->currentUser = $user; + + if ($this->currentUser === null) { throw new Exception(message: 'Edit modal part component requires authentication.'); } } @@ -129,7 +137,7 @@ class="relative space-y-2" wire:show="previewIsEnable" >
- {{ auth()->user()->name }} + {{ $this->currentUser->name }} {{ now()->format('Y 年 m 月 d 日') }}
diff --git "a/resources/views/components/layouts/\342\232\241header.blade.php" "b/resources/views/components/layouts/\342\232\241header.blade.php" index 4b398af2..bb901262 100644 --- "a/resources/views/components/layouts/\342\232\241header.blade.php" +++ "b/resources/views/components/layouts/\342\232\241header.blade.php" @@ -4,7 +4,9 @@ use App\Livewire\Actions\Logout; use App\Models\Category; +use App\Models\User; use App\Services\SettingService; +use Illuminate\Container\Attributes\CurrentUser; use Illuminate\Support\Facades\Cache; use Livewire\Component; @@ -14,8 +16,13 @@ public bool $showRegisterButton; - public function mount(): void - { + public ?User $currentUser = null; + + public function mount( + #[CurrentUser] + ?User $user + ): void { + $this->currentUser = $user; $this->categories = Cache::remember('categories', now()->addDay(), function () { return Category::all(['id', 'name', 'icon'])->map(fn (Category $category) => [ 'id' => $category->id, @@ -60,7 +67,7 @@ public function logout(Logout $logout): void @endscript @php - $hasUnreadNotifications = auth()->check() && auth()->user()->unreadNotifications()->exists(); + $hasUnreadNotifications = $this->currentUser !== null && $this->currentUser->unreadNotifications()->exists(); @endphp
Open user menu @@ -347,7 +354,7 @@ class="flex text-sm rounded-full focus:ring-2 focus:ring-white focus:ring-offset Open user menu @@ -366,12 +373,12 @@ class="absolute right-0 top-12" 新增文章 - + 個人資訊 - + 設定 diff --git "a/resources/views/pages/notifications/\342\232\241index.blade.php" "b/resources/views/pages/notifications/\342\232\241index.blade.php" index d4ef24e9..9f83c1e8 100644 --- "a/resources/views/pages/notifications/\342\232\241index.blade.php" +++ "b/resources/views/pages/notifications/\342\232\241index.blade.php" @@ -2,6 +2,8 @@ declare(strict_types=1); +use App\Models\User; +use Illuminate\Container\Attributes\CurrentUser; use Livewire\Attributes\Title; use Livewire\Component; use Livewire\WithPagination; @@ -10,12 +12,14 @@ { use WithPagination; - public function render() - { - auth()->user()->unreadNotifications->markAsRead(); + public function render( + #[CurrentUser] + User $user + ) { + $user->unreadNotifications->markAsRead(); return $this->view([ - 'notifications' => auth()->user()->notifications()->paginate(20), + 'notifications' => $user->notifications()->paginate(20), ])->title('我的通知'); } }; diff --git "a/resources/views/pages/settings/users/password/\342\232\241edit.blade.php" "b/resources/views/pages/settings/users/password/\342\232\241edit.blade.php" index 1cd3befa..ae643fcb 100644 --- "a/resources/views/pages/settings/users/password/\342\232\241edit.blade.php" +++ "b/resources/views/pages/settings/users/password/\342\232\241edit.blade.php" @@ -31,7 +31,7 @@ protected function rules(): array $passwordRule = Password::min(8)->letters()->mixedCase()->numbers(); return [ - 'current_password' => ['required', new MatchOldPassword()], + 'current_password' => ['required', app(MatchOldPassword::class)], 'new_password' => ['required', 'confirmed', $passwordRule], ]; } diff --git a/routes/api.php b/routes/api.php index caa9cc7b..77693d92 100644 --- a/routes/api.php +++ b/routes/api.php @@ -6,6 +6,8 @@ use App\Http\Controllers\Api\ShowLatestPostController; use App\Http\Controllers\Api\TwitterOembedController; use App\Http\Controllers\Api\UploadImageController; +use App\Models\User; +use Illuminate\Container\Attributes\CurrentUser; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; @@ -20,8 +22,8 @@ | */ -Route::middleware('auth:sanctum')->get('user', function (Request $request) { - return $request->user(); +Route::middleware('auth:sanctum')->get('user', function (#[CurrentUser] User $user) { + return $user; }); Route::get('/passkeys/register-options', GeneratePasskeyRegisterOptionsController::class) From 57299c58c80cf7bb2aa1e6f71ef666da30c6f854 Mon Sep 17 00:00:00 2001 From: Allen Date: Mon, 29 Jun 2026 16:32:58 +0800 Subject: [PATCH 2/2] chore: rollback some changes --- .../Auth/VerifyEmailController.php | 10 ++++---- app/Rules/MatchOldPassword.php | 9 +------ .../\342\232\241create-modal.blade.php" | 16 +++++-------- .../\342\232\241edit-modal.blade.php" | 8 ++----- .../layouts/\342\232\241header.blade.php" | 24 ++++++++----------- .../password/\342\232\241edit.blade.php" | 2 +- routes/api.php | 1 - 7 files changed, 24 insertions(+), 46 deletions(-) diff --git a/app/Http/Controllers/Auth/VerifyEmailController.php b/app/Http/Controllers/Auth/VerifyEmailController.php index 3e750864..4f878cb9 100644 --- a/app/Http/Controllers/Auth/VerifyEmailController.php +++ b/app/Http/Controllers/Auth/VerifyEmailController.php @@ -5,9 +5,7 @@ namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; -use App\Models\User; use Illuminate\Auth\Events\Verified; -use Illuminate\Container\Attributes\CurrentUser; use Illuminate\Foundation\Auth\EmailVerificationRequest; use Illuminate\Http\RedirectResponse; @@ -16,14 +14,14 @@ class VerifyEmailController extends Controller /** * Mark the authenticated user's email address as verified. */ - public function __invoke(EmailVerificationRequest $request, #[CurrentUser] User $user): RedirectResponse + public function __invoke(EmailVerificationRequest $request): RedirectResponse { - if ($user->hasVerifiedEmail()) { + if ($request->user()->hasVerifiedEmail()) { return redirect()->intended('/?verified=1'); } - if ($user->markEmailAsVerified()) { - event(new Verified($user)); + if ($request->user()->markEmailAsVerified()) { + event(new Verified($request->user())); } return redirect()->intended('/?verified=1'); diff --git a/app/Rules/MatchOldPassword.php b/app/Rules/MatchOldPassword.php index b212979c..03600b0f 100644 --- a/app/Rules/MatchOldPassword.php +++ b/app/Rules/MatchOldPassword.php @@ -4,20 +4,13 @@ namespace App\Rules; -use App\Models\User; use Closure; -use Illuminate\Container\Attributes\CurrentUser; use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Support\Facades\Hash; use Illuminate\Translation\PotentiallyTranslatedString; class MatchOldPassword implements ValidationRule { - public function __construct( - #[CurrentUser] - protected ?User $user = null - ) {} - /** * Run the validation rule. * @@ -25,7 +18,7 @@ public function __construct( */ public function validate(string $attribute, mixed $value, Closure $fail): void { - if (! Hash::check($value, $this->user->password)) { + if (! Hash::check($value, auth()->user()->password)) { $fail('舊密碼錯誤'); } } diff --git "a/resources/views/components/comments/\342\232\241create-modal.blade.php" "b/resources/views/components/comments/\342\232\241create-modal.blade.php" index 504ba88a..ab761e6c 100644 --- "a/resources/views/components/comments/\342\232\241create-modal.blade.php" +++ "b/resources/views/components/comments/\342\232\241create-modal.blade.php" @@ -26,18 +26,14 @@ public bool $previewIsEnable = false; - public ?User $currentUser = null; - - public function mount( - #[CurrentUser] - ?User $user - ): void { + public function mount(#[CurrentUser] ?User $user): void + { $this->currentUser = $user; $this->form->post_id = $this->postId; $this->form->user_id = $user?->id; } - public function save(): void + public function save(#[CurrentUser] ?User $user): void { $this->validate( rules: [ @@ -85,8 +81,8 @@ public function save(): void 'body' => $comment->body, 'created_at' => $comment->created_at->toDateTimeString(), 'updated_at' => $comment->updated_at->toDateTimeString(), - 'user_name' => $this->currentUser !== null ? $this->currentUser->name : null, - 'user_gravatar_url' => $this->currentUser !== null ? get_gravatar($this->currentUser->email) : null, + 'user_name' => $user?->name, + 'user_gravatar_url' => $user !== null ? get_gravatar($user->email) : null, 'children_count' => 0, ], ); @@ -205,7 +201,7 @@ class="space-y-2" >
- {{ $this->currentUser !== null ? $this->currentUser->name : '訪客' }} + {{ auth()->check() ? auth()->user()->name : '訪客' }} {{ now()->format('Y 年 m 月 d 日') }}
diff --git "a/resources/views/components/comments/\342\232\241edit-modal.blade.php" "b/resources/views/components/comments/\342\232\241edit-modal.blade.php" index 91fae3cc..0311202e 100644 --- "a/resources/views/components/comments/\342\232\241edit-modal.blade.php" +++ "b/resources/views/components/comments/\342\232\241edit-modal.blade.php" @@ -23,15 +23,11 @@ public bool $previewIsEnable = false; - public ?User $currentUser = null; - public function mount( #[CurrentUser] ?User $user ): void { - $this->currentUser = $user; - - if ($this->currentUser === null) { + if ($user === null) { throw new Exception(message: 'Edit modal part component requires authentication.'); } } @@ -137,7 +133,7 @@ class="relative space-y-2" wire:show="previewIsEnable" >
- {{ $this->currentUser->name }} + {{ auth()->user()->name }} {{ now()->format('Y 年 m 月 d 日') }}
diff --git "a/resources/views/components/layouts/\342\232\241header.blade.php" "b/resources/views/components/layouts/\342\232\241header.blade.php" index bb901262..1e003d0d 100644 --- "a/resources/views/components/layouts/\342\232\241header.blade.php" +++ "b/resources/views/components/layouts/\342\232\241header.blade.php" @@ -6,7 +6,6 @@ use App\Models\Category; use App\Models\User; use App\Services\SettingService; -use Illuminate\Container\Attributes\CurrentUser; use Illuminate\Support\Facades\Cache; use Livewire\Component; @@ -16,13 +15,8 @@ public bool $showRegisterButton; - public ?User $currentUser = null; - - public function mount( - #[CurrentUser] - ?User $user - ): void { - $this->currentUser = $user; + public function mount(): void + { $this->categories = Cache::remember('categories', now()->addDay(), function () { return Category::all(['id', 'name', 'icon'])->map(fn (Category $category) => [ 'id' => $category->id, @@ -66,8 +60,9 @@ public function logout(Logout $logout): void @endscript + @php - $hasUnreadNotifications = $this->currentUser !== null && $this->currentUser->unreadNotifications()->exists(); + $hasUnreadNotifications = auth()->check() && auth()->user()->unreadNotifications()->exists(); @endphp
Open user menu @@ -241,7 +236,7 @@ class="lg:hidden bg-zinc-50 dark:bg-zinc-800" id="mobile-header" >
-
+
{{-- category dropdown menu toggle --}} @@ -373,12 +368,13 @@ class="absolute right-0 top-12" 新增文章 - + 個人資訊 - + 設定 diff --git "a/resources/views/pages/settings/users/password/\342\232\241edit.blade.php" "b/resources/views/pages/settings/users/password/\342\232\241edit.blade.php" index ae643fcb..79f29c4a 100644 --- "a/resources/views/pages/settings/users/password/\342\232\241edit.blade.php" +++ "b/resources/views/pages/settings/users/password/\342\232\241edit.blade.php" @@ -31,7 +31,7 @@ protected function rules(): array $passwordRule = Password::min(8)->letters()->mixedCase()->numbers(); return [ - 'current_password' => ['required', app(MatchOldPassword::class)], + 'current_password' => ['required', new MatchOldPassword], 'new_password' => ['required', 'confirmed', $passwordRule], ]; } diff --git a/routes/api.php b/routes/api.php index 77693d92..ae9d30bf 100644 --- a/routes/api.php +++ b/routes/api.php @@ -8,7 +8,6 @@ use App\Http\Controllers\Api\UploadImageController; use App\Models\User; use Illuminate\Container\Attributes\CurrentUser; -use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; /*