Skip to content

Commit

Permalink
Purge user tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
mmarchois committed Jan 30, 2025
1 parent 21edf9b commit 236086d
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 21 deletions.
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
web: bin/run
worker: bash -c "set -e; while true ; do php bin/console messenger:consume async --memory-limit=256M --limit=50 ; done"
postdeploy: make scalingo-postdeploy
scheduler: node vendor/node_modules/.bin/node-cron
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"prefer-stable": true,
"require": {
"php": "~8.2.3",
"dragonmantank/cron-expression": "^3.3",
"ext-ctype": "*",
"ext-iconv": "*",
"doctrine/doctrine-bundle": "^2.7",
Expand Down
137 changes: 130 additions & 7 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions cron.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"0 0 * * *": "php bin/console app:purge:user_tokens"
}
24 changes: 12 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/Domain/User/Repository/TokenRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ public function add(Token $token): Token;

public function remove(Token $token): void;

public function deleteExpiredTokens(): void;

public function findOneByTokenAndType(string $token, string $type): ?Token;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@

namespace App\Infrastructure\Persistence\Doctrine\Repository\User;

use App\Application\DateUtilsInterface;
use App\Domain\User\Repository\TokenRepositoryInterface;
use App\Domain\User\Token;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

final class TokenRepository extends ServiceEntityRepository implements TokenRepositoryInterface
{
public function __construct(ManagerRegistry $registry)
{
public function __construct(
ManagerRegistry $registry,
private DateUtilsInterface $dateUtils,
) {
parent::__construct($registry, Token::class);
}

Expand Down Expand Up @@ -42,4 +45,16 @@ public function findOneByTokenAndType(string $token, string $type): ?Token
->getOneOrNullResult()
;
}

public function deleteExpiredTokens(): void
{
$this->createQueryBuilder('t')
->delete()
->where('t.expirationDate < :now')
->setParameters([
'now' => $this->dateUtils->getNow(),
])
->getQuery()
->execute();
}
}
32 changes: 32 additions & 0 deletions src/Infrastructure/Symfony/Command/PurgeUserTokensCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace App\Infrastructure\Symfony\Command;

use App\Domain\User\Repository\TokenRepositoryInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(
name: 'app:purge:user_tokens',
description: 'Purge user tokens that have expired',
hidden: false,
)]
class PurgeUserTokensCommand extends Command
{
public function __construct(
private TokenRepositoryInterface $tokenRepository,
) {
parent::__construct();
}

public function execute(InputInterface $input, OutputInterface $output): int
{
$this->tokenRepository->deleteExpiredTokens();

return Command::SUCCESS;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace App\Tests\Integration\Infrastructure\Symfony\Command;

use App\Infrastructure\Symfony\Command\PurgeUserTokensCommand;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Console\Tester\CommandTester;

final class PurgeUserTokensCommandTest extends KernelTestCase
{
public function testExecute(): void
{
self::bootKernel();

$container = static::getContainer();

$command = $container->get(PurgeUserTokensCommand::class);
$commandTester = new CommandTester($command);
$commandTester->execute([]);
$commandTester->assertCommandIsSuccessful();
}
}

0 comments on commit 236086d

Please sign in to comment.