Skip to content

Commit 185d9ad

Browse files
committed
fix: Throw exception when required keys are not set.
1 parent 0e7b35c commit 185d9ad

File tree

4 files changed

+98
-20
lines changed

4 files changed

+98
-20
lines changed

src/Payload.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ public function offsetExists($key)
205205
* @param mixed $key
206206
* @return mixed
207207
*/
208+
#[\ReturnTypeWillChange]
208209
public function offsetGet($key)
209210
{
210211
return Arr::get($this->toArray(), $key);

src/Providers/JWT/Lcobucci.php

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,21 @@
1111

1212
namespace Tymon\JWTAuth\Providers\JWT;
1313

14+
use Exception;
1415
use DateTimeImmutable;
1516
use DateTimeInterface;
16-
use Exception;
17-
use Illuminate\Support\Collection;
18-
use Lcobucci\JWT\Configuration;
1917
use Lcobucci\JWT\Signer;
20-
use Lcobucci\JWT\Signer\Ecdsa;
21-
use Lcobucci\JWT\Signer\Key\InMemory;
18+
use Lcobucci\JWT\Signer\Key;
2219
use Lcobucci\JWT\Signer\Rsa;
20+
use Lcobucci\JWT\Signer\Ecdsa;
21+
use Lcobucci\JWT\Configuration;
2322
use Lcobucci\JWT\Token\Builder;
23+
use Illuminate\Support\Collection;
24+
use Lcobucci\JWT\Signer\Key\InMemory;
2425
use Lcobucci\JWT\Token\RegisteredClaims;
25-
use Lcobucci\JWT\Validation\Constraint\SignedWith;
2626
use Tymon\JWTAuth\Contracts\Providers\JWT;
2727
use Tymon\JWTAuth\Exceptions\JWTException;
28+
use Lcobucci\JWT\Validation\Constraint\SignedWith;
2829
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
2930

3031
class Lcobucci extends Provider implements JWT
@@ -226,23 +227,55 @@ protected function isAsymmetric()
226227
* {@inheritdoc}
227228
*
228229
* @return \Lcobucci\JWT\Signer\Key
230+
*
231+
* @throws \Tymon\JWTAuth\Exceptions\JWTException
229232
*/
230233
protected function getSigningKey()
231234
{
232-
return $this->isAsymmetric()
233-
? InMemory::plainText($this->getPrivateKey(), $this->getPassphrase() ?? '')
234-
: InMemory::plainText($this->getSecret());
235+
if ($this->isAsymmetric()) {
236+
if (! $privateKey = $this->getPrivateKey()) {
237+
throw new JWTException('Private key is not set.');
238+
}
239+
240+
return $this->getKey($privateKey, $this->getPassphrase() ?? '');
241+
}
242+
243+
if (! $secret = $this->getSecret()) {
244+
throw new JWTException('Secret is not set.');
245+
}
246+
247+
return $this->getKey($secret);
235248
}
236249

237250
/**
238251
* {@inheritdoc}
239252
*
240253
* @return \Lcobucci\JWT\Signer\Key
254+
*
255+
* @throws \Tymon\JWTAuth\Exceptions\JWTException
241256
*/
242257
protected function getVerificationKey()
243258
{
244-
return $this->isAsymmetric()
245-
? InMemory::plainText($this->getPublicKey())
246-
: InMemory::plainText($this->getSecret());
259+
if ($this->isAsymmetric()) {
260+
if (! $public = $this->getPublicKey()) {
261+
throw new JWTException('Public key is not set.');
262+
}
263+
264+
return $this->getKey($public);
265+
}
266+
267+
if (! $secret = $this->getSecret()) {
268+
throw new JWTException('Secret is not set.');
269+
}
270+
271+
return $this->getKey($secret);
272+
}
273+
274+
/**
275+
* Get the signing key instance.
276+
*/
277+
protected function getKey(string $contents, string $passphrase = ''): Key
278+
{
279+
return InMemory::plainText($contents, $passphrase);
247280
}
248281
}

src/Providers/JWT/Provider.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public function getKeys()
133133
/**
134134
* Get the public key used to sign tokens with an asymmetric algorithm.
135135
*
136-
* @return resource|string|null
136+
* @return string|null
137137
*/
138138
public function getPublicKey()
139139
{
@@ -143,7 +143,7 @@ public function getPublicKey()
143143
/**
144144
* Get the private key used to sign tokens with an asymmetric algorithm.
145145
*
146-
* @return resource|string|null
146+
* @return string|null
147147
*/
148148
public function getPrivateKey()
149149
{
@@ -164,7 +164,7 @@ public function getPassphrase()
164164
/**
165165
* Get the key used to sign the tokens.
166166
*
167-
* @return resource|string|null
167+
* @return string|null
168168
*/
169169
protected function getSigningKey()
170170
{
@@ -174,7 +174,7 @@ protected function getSigningKey()
174174
/**
175175
* Get the key used to verify the tokens.
176176
*
177-
* @return resource|string|null
177+
* @return string|null
178178
*/
179179
protected function getVerificationKey()
180180
{

tests/Providers/JWT/LcobucciTest.php

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,24 +146,68 @@ public function it_should_throw_a_token_invalid_exception_when_the_token_could_n
146146
$this->expectException(TokenInvalidException::class);
147147
$this->expectExceptionMessage('Could not decode token:');
148148

149-
$this->getProvider('secret', 'HS256')->decode('foo.bar.baz');
149+
$this->getProvider('secret', Provider::ALGO_HS256)->decode('foo.bar.baz');
150150
}
151151

152152
/** @test */
153-
public function it_should_throw_a_exception_when_the_algorithm_passed_is_invalid()
153+
public function it_should_throw_an_exception_when_the_algorithm_passed_is_invalid()
154154
{
155155
$this->expectException(JWTException::class);
156156
$this->expectExceptionMessage('The given algorithm could not be found');
157157

158158
$this->getProvider('secret', 'INVALID_ALGO')->decode('foo.bar.baz');
159159
}
160160

161+
/** @test */
162+
public function it_should_throw_an_exception_when_no_symmetric_key_is_provided_when_encoding()
163+
{
164+
$this->expectException(JWTException::class);
165+
$this->expectExceptionMessage('Secret is not set.');
166+
167+
$this->getProvider(null, Provider::ALGO_HS256)->encode(['sub' => 1]);
168+
}
169+
170+
/** @test */
171+
public function it_should_throw_an_exception_when_no_symmetric_key_is_provided_when_decoding()
172+
{
173+
$this->expectException(JWTException::class);
174+
$this->expectExceptionMessage('Secret is not set.');
175+
176+
$this->getProvider(null, Provider::ALGO_HS256)->decode('foo.bar.baz');
177+
}
178+
179+
/** @test */
180+
public function it_should_throw_an_exception_when_no_asymmetric_public_key_is_provided()
181+
{
182+
$this->expectException(JWTException::class);
183+
$this->expectExceptionMessage('Public key is not set.');
184+
185+
$this->getProvider(
186+
'does_not_matter',
187+
Provider::ALGO_RS256,
188+
['private' => $this->getDummyPrivateKey(), 'public' => null]
189+
)->decode('foo.bar.baz');
190+
}
191+
192+
/** @test */
193+
public function it_should_throw_an_exception_when_no_asymmetric_private_key_is_provided()
194+
{
195+
$this->expectException(JWTException::class);
196+
$this->expectExceptionMessage('Private key is not set.');
197+
198+
$this->getProvider(
199+
'does_not_matter',
200+
Provider::ALGO_RS256,
201+
['private' => null, 'public' => $this->getDummyPublicKey()]
202+
)->encode(['sub' => 1]);
203+
}
204+
161205
/** @test */
162206
public function it_should_return_the_public_key()
163207
{
164208
$provider = $this->getProvider(
165209
'does_not_matter',
166-
'RS256',
210+
Provider::ALGO_RS256,
167211
$keys = ['private' => $this->getDummyPrivateKey(), 'public' => $this->getDummyPublicKey()]
168212
);
169213

@@ -175,7 +219,7 @@ public function it_should_return_the_keys()
175219
{
176220
$provider = $this->getProvider(
177221
'does_not_matter',
178-
'RS256',
222+
Provider::ALGO_RS256,
179223
$keys = ['private' => $this->getDummyPrivateKey(), 'public' => $this->getDummyPublicKey()]
180224
);
181225

0 commit comments

Comments
 (0)