divineomega/symfony-password-exposed-bundle
Installation:
composer require jord-jd/symfony-password-exposed-bundle
Ensure DivineOmega\PasswordExposedBundle\DivineOmegaPasswordExposedBundle::class is registered in config/bundles.php.
Enable in Config:
Add to config/packages/divineomega_password_exposed.yaml:
password_exposed:
enable: true
First Use Case:
Inject the PasswordExposedCheckerInterface into a controller/service and call isExposed():
use JordJD\PasswordExposed\Interfaces\PasswordExposedCheckerInterface;
public function checkPassword(PasswordExposedCheckerInterface $checker): bool
{
return $checker->isExposed('user_password_here');
}
jord-jd/password_exposed for API details (e.g., rate limits, hash prefixes).cache.app (default) for cached responses.Password Validation in Registration/Login:
public function register(Request $request, PasswordExposedCheckerInterface $checker)
{
$password = $request->request->get('password');
if ($checker->isExposed($password)) {
throw new \RuntimeException('Password exposed in a breach. Choose another.');
}
// Proceed with registration...
}
Bulk Checks (e.g., Password Reset): Use a loop with error handling for rate limits:
foreach ($userPasswords as $password) {
try {
$isExposed = $checker->isExposed($password);
$results[$password] = $isExposed;
} catch (RateLimitExceededException $e) {
// Retry or log
}
}
Custom HTTP Client: Override the default client for proxies/debugging:
password_exposed:
http_client: symfony.http_client
UserPasswordHasher events.use JordJD\PasswordExposed\Validator\Constraints\PasswordExposed;
#[PasswordExposed]
private $password;
Rate Limits:
cache_lifetime: 2592000 = 30 days).RateLimitExceededException gracefully (e.g., queue retries).Hash Prefixes:
$hashPrefix = substr(sha1('password'), 0, 5); // e.g., "5baa6"
Case Sensitivity:
"Passw0rd" vs "passw0rd").False Positives:
"123456") may appear in breach data. Combine with other checks (e.g., zxcvbn complexity).Enable Logging:
password_exposed:
enable: true
Check Symfony logs for API responses/errors.
Disable in Dev:
password_exposed:
enable: "%kernel.debug%" # Disables in dev mode
Custom Cache:
Override cache.app to use Redis/Memcached for high traffic:
password_exposed:
cache: cache.redis
Mock API for Tests:
Use a custom HttpClient to mock responses:
$client = new MockHttpClient([
new Response(200, [], '{"Count":0}')
]);
$container->set('password_exposed.http_client', $client);
Extend Checker:
Implement PasswordExposedCheckerInterface to add local breach checks:
class CustomChecker implements PasswordExposedCheckerInterface {
public function isExposed(string $password): bool {
return $this->apiChecker->isExposed($password) || $this->localCheck($password);
}
}
How can I help you explore Laravel packages today?