routeIs('password.change.show', 'password.change.update')) { return $next($request); } // 現在のユーザーを取得 $ope = Auth::user(); // パスワード変更が必須か判定 if ($this->isPasswordChangeRequired($ope)) { return redirect()->route('password.change.show'); } return $next($request); } /** * パスワード変更が必須かどうかを判定 * * 初回ログイン時(ope_pass_changed_at が NULL)または * 最後変更から3ヶ月以上経過している場合、TRUE を返す * * @param \App\Models\Ope $ope * @return bool */ private function isPasswordChangeRequired($ope): bool { // パスワード変更日時が未設定(初回ログイン等) if (is_null($ope->ope_pass_changed_at)) { \Log::info('Password change required: ope_pass_changed_at is null', [ 'ope_id' => $ope->ope_id, ]); return true; } // パスワード変更から経過日数を計算 // ope_pass_changed_at は複数のフォーマットに対応 try { $changedAt = Carbon::parse($ope->ope_pass_changed_at); } catch (\Exception $e) { // パース失敗時は強制変更 \Log::warning('Failed to parse ope_pass_changed_at', [ 'ope_id' => $ope->ope_id, 'value' => $ope->ope_pass_changed_at, 'error' => $e->getMessage(), ]); return true; } $now = Carbon::now(); // 3ヶ月以上経過しているか判定 // diffInMonths は絶対値ではなく符号付きなので、abs() で絶対値を取得 $monthsDiff = abs($now->diffInMonths($changedAt)); \Log::info('Password change check', [ 'ope_id' => $ope->ope_id, 'changed_at' => $changedAt->format('Y-m-d H:i:s'), 'now' => $now->format('Y-m-d H:i:s'), 'months_diff' => $monthsDiff, 'is_required' => $monthsDiff >= 3, ]); if ($monthsDiff >= 3) { return true; } return false; } }