-
Notifications
You must be signed in to change notification settings - Fork 786
Fix ClientController::store() breaking change introduced via #1745 #1860
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…1745 ```php - if (Passport::$hashesClientSecrets) { - return ['plainSecret' => $client->plainSecret] + $client->toArray(); - } + $client->secret = $client->plainSecret; return $client->makeVisible('secret'); ``` This change obviously breaks usages that previously relied on the return type array with the additional 'plainSecret' data. E.g., the old Vue components used the plainSecret to present that to the user so that he could save it, etc. Since hashing is now mandatory, I restored the previous behavior without the now obsolete `Passport::$hashesClientSecrets` check: ```php return ['plainSecret' => $client->plainSecret] + $client->toArray(); ``` I also updated the tests. I know it looks a bit fishy but I had not much choice since it's a unit test … (didn't want to make too big of a change out of this … it's deprecated anyways …)
* Store a new client. | ||
*/ | ||
public function store(Request $request): Client | ||
public function store(Request $request): array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BC change!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hafezdivandari it has been array|Client before:
passport/src/Http/Controllers/ClientController.php
Lines 76 to 78 in 89d2594
* @return \Laravel\Passport\Client|array | |
*/ | |
public function store(Request $request) |
You updated it to just Client via ef122ad#diff-6656ea7db3c71aee64d3cec3512c61d176630ed9f86a2b7359565fd3bfd57aa3 ignoring that people may already rely on the array etc.
In my book thats a breaking change introduced by you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That PR was on a major release 12 to 13 where breaking changes are expected to happen, but this PR is on a patch release!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes of course, but was this breaking change intended? Looked like a mistake to me and upgrade.md does not mention such a BC, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Want me to add a note in the https://github.com/laravel/passport/blob/13.x/UPGRADE.md#json-api-deprecation section + update the Client
model to move towards your suggested solution in #1860 (comment) instead? It would still break old upgraded apps but at least the plain_secret
is available so it would be an easy fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH I see no good reason to change anything here, because secret
will now contain the plain secret value that’s only visible right after creating a new client. The change on array|Client
to stricter return type Client
was intended, and still makes sense (We have already explained the return type changes on the upgrade guide). However if you insist to include plain_secret
too, my suggestion is to append it. That's just my suggestion and the final decision is for maintainers to make.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback @hafezdivandari
because secret will now contain the plain secret value that’s only visible right after creating a new client.
Unfortunately that's not true. My first attempt was to update the old Vue components to use secret
directly, expecting it to return the plain secret in that case. However, it didn't.
// \Laravel\Passport\Client::secret
protected function secret(): Attribute
{
return Attribute::make(
set: function (?string $value): ?string {
$this->plainSecret = $value;
return $this->castAttributeAsHashedString('secret', $value);
},
);
}
As you can see, it is getting hashed immediately in the setter. I don't think, we can leave it as is tbh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, let me write a test for it and think for a solution, in the meantime, please mark this PR as draft.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Marked as draft. Thank you for jumping in and taking care. 🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$client->secret = $client->plainSecret; | ||
|
||
return $client->makeVisible('secret'); | ||
return ['plainSecret' => $client->plainSecret] + $client->toArray(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return ['plainSecret' => $client->plainSecret] + $client->toArray(); | |
$client->secret = $client->plainSecret; | |
return $client->makeVisible('secret')->mergeAppends(['plain_secret']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about this as well. However, it's again breaking existing code bases like mine with no good reason. This is deprecated code. Why change the behavior now just because you want to have the Client return type over array?
By the way: I think this will throw BadMethodCallException Call to undefined method Laravel\Passport\Client::getPlainSecretAttribute()
; \Laravel\Passport\Client::$plainSecret
is a property. It's not a getter.
Fixes
ClientController::store()
breaking change introduced via #1745This change obviously breaks usages that previously relied on the return type array with the additional
plainSecret
data. E.g., the old Vue components usedplainSecret
to present that to the user so that he could save it, etc. Since hashing is now mandatory, I restored the previous behavior without the now obsoletePassport::$hashesClientSecrets
check:I also updated the tests. I know it looks a bit fishy but I had not much choice since it's a unit test … (didn't want to make too big of a change out of this … it's deprecated anyways …)