Find the valid tokens of a model, without knowing a token - #9
Merged
Conversation
A "forgot password" flow has to know whether the user still has a pin
that is valid before it sends a new one, and until now that meant
walking `temporaryTokens` and calling `isValid()` on every one of them:
every lookup of the package needed the token itself.
`HasTemporaryTokens` answers it now, for every token of the model or for
one type of them:
$user->hasValidTemporaryToken('reset-password');
$user->validTemporaryTokens('reset-password');
The builder answers the same questions with `hasAnyValidToken()` and
`findValidTokens()`, and without a related item it looks at the tokens
of every model. Both are named for what they ask -- is there *any* valid
token -- because they ignore the unique id: `findValidToken()` and
`isValid()` stay the way to validate a token you have.
The query of the repository was built around the token it looked for.
It takes the model and the type now, and the token is a filter the two
lookups of a single token add, so that the same scoping serves both.
Closes #6
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #6.
Every lookup of the package needed the token itself, so a "forgot password" flow that wants to know whether the user
still has a usable pin had to walk
temporaryTokensand callisValid()on each one, as @paulo-hortelan described inthe issue.
What a model can answer now
The type is optional: without one, every token of the model is looked at.
The builder answers the same questions, and without a related item it looks at the tokens of every model:
They are named for what they ask — is there any valid token — because they ignore
setUniqueId().findValidToken()andisValid()stay the way to validate a token you have, and a note in the readme says so.Changes
HasTemporaryTokens:validTemporaryTokens(?string $type = null)andhasValidTemporaryToken(?string $type = null).Builder(through theValidationconcern, so the facade has them too):findValidTokens()andhasAnyValidToken().TokensRepository:findValidTokens(?string $type, ?Model $tokenable)andhasAnyValidToken(?string $type, ?Model $tokenable).Its private query was built around the token it looked for; it takes the model and the type now, and the token is a
filter that the two single-token lookups add, so the same scoping (and the same "has to use the trait" check) serves
every lookup.
TokenBuilderfacade: the two new methods are annotated.Model reference section for the trait; the changelog has an entry.
No existing signature or behaviour changed, so this is additive.
Tests
14 tests were added, in the repository, the validation concern, a new
HasTemporaryTokensTestand the readme flow of areset pin end to end — including that an expired one and a used up one do not count, that the tokens of another user or
of another type do not count, and that the unique id is not part of the lookup.
make ci(coding style, PHPStan level 7, test suite) is green: 69 tests, 200 assertions, and coverage ofsrc/is at100%.
🤖 Generated with Claude Code