Initialer Laravel Commit für BetiX
This commit is contained in:
98
app/Auth/EncryptedUserProvider.php
Normal file
98
app/Auth/EncryptedUserProvider.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace App\Auth;
|
||||
|
||||
use Illuminate\Auth\EloquentUserProvider;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class EncryptedUserProvider extends EloquentUserProvider
|
||||
{
|
||||
/**
|
||||
* Retrieve a user by the given credentials.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
*/
|
||||
public function retrieveByCredentials(array $credentials)
|
||||
{
|
||||
// Remove any password-related keys; we never query by them
|
||||
$credentials = array_filter(
|
||||
$credentials,
|
||||
fn ($key) => ! 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 <field> 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user