Skip to content

[Command] Clear invalid refresh tokens #428

Description

@mpiot

Describe the bug
The command gesdinet:jwt:clear do not work as expected, always return the message 'There were no invalid tokens to revoke.', but delete the batch-size quantity of tokens only (need to be run multiple times).

To Reproduce
Steps to reproduce the behavior:

  1. Execute bin/console gesdinet:jwt:clear
  2. See database with more than 1000 tokens to clear

Expected behavior
The command should remove all the invalid tokens in one time.
The list of deleted token is propbably not interesting, eg: in my case the command remove approx 12 500 tokens (emmory consumption, unreadable list).

Fix
This fix keep the list of tokens, just update Gesdinet\JWTRefreshTokenBundle\Doctrine\RefreshTokenManager (https://github.com/markitosgv/JWTRefreshTokenBundle/blob/master/src/Doctrine/RefreshTokenManager.php).

Before:

    public function revokeAllInvalidBatch(?DateTimeInterface $datetime = null, ?int $batchSize = null, int $offset = 0, bool $andFlush = true): array
    {
        $batchSize ??= $this->defaultBatchSize;
        $count = 0;

        do {
            $invalidTokens = $this->repository->findInvalidBatch($datetime, $batchSize, $offset);

            foreach ($invalidTokens as $invalidToken) {
                $this->objectManager->remove($invalidToken);
                ++$count;
            }

            if ($andFlush && !empty($invalidToken)) {
                $this->objectManager->flush();
                $this->objectManager->clear();
            }

            $offset += $batchSize;
        } while (!empty($invalidTokens));

        return $invalidTokens ?? [];
    }

After:

    public function revokeAllInvalidBatch(?DateTimeInterface $datetime = null, ?int $batchSize = null, int $offset = 0, bool $andFlush = true): array
    {
        $batchSize ??= $this->defaultBatchSize;
        $revokedTokens = [];

        do {
            $invalidTokens = $this->repository->findInvalidBatch($datetime, $batchSize, $offset);

            foreach ($invalidTokens as $invalidToken) {
                $this->objectManager->remove($invalidToken);
                $revokedTokens[] = $invalidToken;
            }

            if ($andFlush && !empty($invalidTokens)) {
                $this->objectManager->flush();
            }
        } while (!empty($invalidTokens));

        return $revokedTokens;
    }
  1. Remove the $count, probably used before to simply return the number of removed token instead a whole list of tokens
  2. Add a $revokedTokens variable to store removed entries (else the list is not full)
  3. Remove ++$count;, replace it by $revokedTokens[] = $invalidToken;
  4. In the condition, check on $invalidTokens and not $invalidToken
  5. In the condition, remove the clear method $this->objectManager->clear(); (can be kept, not incidence)
  6. Remove the offset update: $offset += $batchSize;, because of flush, no need to move the windows, always start to 0

I don´t know if the goal is to keep the list or not, some infos like $offset appear not usefull for methods revokeAllInvalidBatch in the class and the interface since the intermediate flush usage (batching).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions