Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Password Reset Persistence Orm Bundle Laravel Package

dcs/password-reset-persistence-orm-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle Add to composer.json:

    "require": {
        "dcs/password-reset-persistence-orm-bundle": "^1.0"
    }
    

    Run composer update.

  2. Enable the Bundle Add to config/bundles.php:

    return [
        // ...
        Damianociarla\DCSPasswordResetPersistenceORMBundle\DCSPasswordResetPersistenceORMBundle::class => ['all' => true],
    ];
    
  3. Configure Database Run migrations (if provided) or manually create a password_reset table:

    CREATE TABLE password_reset (
        id INT AUTO_INCREMENT PRIMARY KEY,
        email VARCHAR(255) NOT NULL,
        token VARCHAR(255) NOT NULL,
        expires_at DATETIME NOT NULL,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP
    );
    
  4. First Use Case: Persisting a Reset Request Inject the service and use it in a controller:

    use Damianociarla\DCSPasswordResetPersistenceORMBundle\Service\PasswordResetPersistenceService;
    
    public function requestReset(PasswordResetPersistenceService $resetService) {
        $resetService->createResetRequest('user@example.com', 'abc123', new \DateTime('+1 hour'));
    }
    

Implementation Patterns

Core Workflows

  1. Storing Reset Requests

    $resetService->createResetRequest(
        $email,
        $token, // Unique, secure token (e.g., from Symfony's `PasswordResetTokenGenerator`)
        $expiresAt // \DateTimeInterface
    );
    
  2. Fetching a Reset Request

    $resetRequest = $resetService->findResetRequest($token);
    if ($resetRequest && $resetRequest->getExpiresAt() > new \DateTime()) {
        // Valid request
    }
    
  3. Deleting a Used Request

    $resetService->deleteResetRequest($token);
    

Integration with Symfony’s Security

  • Token Generation Use Symfony’s PasswordResetTokenGenerator to create tokens:

    $tokenGenerator = $this->container->get('security.token_generator');
    $token = $tokenGenerator->generateToken();
    
  • Event Listeners Listen to ResetPasswordAuthenticationSuccessEvent to auto-delete tokens post-reset:

    public function onPasswordResetSuccess(ResetPasswordAuthenticationSuccessEvent $event) {
        $resetService->deleteResetRequest($event->getToken());
    }
    

Customizing the Entity

Extend the default PasswordReset entity (if needed):

use Damianociarla\DCSPasswordResetPersistenceORMBundle\Entity\PasswordReset as BasePasswordReset;

class CustomPasswordReset extends BasePasswordReset {
    // Add custom fields/methods
}

Update config/packages/dcs_password_reset_persistence_orm.yaml:

dcs_password_reset_persistence_orm:
    entity: App\Entity\CustomPasswordReset

Gotchas and Tips

Pitfalls

  1. Token Collisions

    • Ensure tokens are globally unique (e.g., combine user ID + random string).
    • Avoid reusing tokens after deletion.
  2. Timezone Issues

    • expires_at uses the server’s timezone. Normalize with:
      $expiresAt = (new \DateTime('+1 hour'))->setTimezone(new \DateTimeZone('UTC'));
      
  3. Missing Migrations

    • The bundle doesn’t auto-create tables. Manually run migrations or use DoctrineFixturesBundle.
  4. Race Conditions

    • Use findAndDeleteResetRequest($token) (if available) to atomically fetch+delete:
      $resetRequest = $resetService->findAndDeleteResetRequest($token);
      

Debugging

  • Check for Stale Tokens Query the DB for expired tokens:

    SELECT * FROM password_reset WHERE expires_at < NOW();
    
  • Log Token Generation Add a listener to log tokens for debugging:

    $resetService->createResetRequest($email, $token, $expiresAt);
    $this->logger->debug('Generated token', ['token' => $token]);
    

Extension Points

  1. Custom Queries Extend the repository to add methods (e.g., find by email):

    // src/Repository/CustomPasswordResetRepository.php
    public function findByEmail($email) {
        return $this->createQueryBuilder('pr')
            ->andWhere('pr.email = :email')
            ->setParameter('email', $email)
            ->getQuery()
            ->getOneOrNullResult();
    }
    
  2. Event Dispatching Trigger events (e.g., ResetRequestCreatedEvent) in the service:

    $event = new ResetRequestCreatedEvent($resetRequest);
    $this->eventDispatcher->dispatch($event, ResetRequestCreatedEvent::NAME);
    
  3. Rate Limiting Add a reset_requests table to track attempts per email/IP:

    // Pseudocode
    if ($this->isRateLimited($email)) {
        throw new \RuntimeException('Too many reset requests.');
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver