! str_contains($key, 'password'), ARRAY_FILTER_USE_KEY ); // Handle the common Fortify username alias `login` (email or username) if (array_key_exists('login', $credentials)) { $login = $credentials['login']; unset($credentials['login']); // prevent accidental `where login = ?` } // If there are no identifier credentials and no `login`, fall back to the // currently authenticated user (used by Fortify confirm-password flow). if ((empty($credentials)) && (!isset($login) || $login === null || $login === '')) { $currentId = Auth::id(); if ($currentId) { return $this->retrieveById($currentId); } return null; } $query = $this->newModelQuery(); // If a generic `login` was provided, match against blind indexes for email/username if (isset($login) && is_string($login) && $login !== '') { if (strlen($login) === 64 && ctype_xdigit($login)) { // Already a sha256 hash $query->where(function ($q) use ($login) { $q->where('email_index', $login) ->orWhere('username_index', $login); }); } else { $hash = hash('sha256', $login); $query->where(function ($q) use ($hash) { $q->where('email_index', $hash) ->orWhere('username_index', $hash); }); } } // Apply any remaining credential filters safely foreach ($credentials as $key => $value) { // Skip empty scalars to avoid `WHERE IS NULL` and unknown columns if ($value === null || (is_string($value) && $value === '')) { continue; } if (is_array($value) || $value instanceof Arrayable) { // Only use whereIn for known lookup keys if (in_array($key, ['id', 'email', 'username', 'email_index', 'username_index'], true)) { $query->whereIn($key, $value); } continue; } if ($key === 'email') { // Accept either plaintext email (hashed) or a precomputed hash if (strlen($value) === 64 && ctype_xdigit($value)) { $query->where('email_index', $value); } else { $query->where('email_index', hash('sha256', $value)); } } elseif ($key === 'username') { // Use blind index for username lookup $query->where('username_index', hash('sha256', $value)); } elseif (in_array($key, ['id', 'email_index', 'username_index'], true)) { // Allow direct lookups on safe columns only $query->where($key, $value); } else { // Ignore unknown/non-whitelisted keys to avoid querying non-existent columns continue; } } return $query->first(); } }