Skip to content
This repository was archived by the owner on Apr 15, 2026. It is now read-only.

Commit 9a936fc

Browse files
committed
Optimized JWT unit tests
1 parent cb42dbd commit 9a936fc

1 file changed

Lines changed: 37 additions & 13 deletions

File tree

tests/unit/Services/SessionServiceTest.php

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,77 +80,84 @@ public static function provideJWTs(): array
8080
[
8181
// JWT with invalid private key signed
8282
'https://pro-1.frontendapi.cloud.corbado.io',
83-
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() + 100, time() + 100, $invalidPrivateKey),
83+
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() + 100, time() + 100, $invalidPrivateKey, 'RS256'),
8484
false,
8585
ValidationException::CODE_JWT_INVALID_SIGNATURE
8686
],
87+
[
88+
// JWT with alg 'none'
89+
'https://pro-1.frontendapi.cloud.corbado.io',
90+
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() + 100, time() + 100, $invalidPrivateKey, 'NONE'),
91+
false,
92+
ValidationException::CODE_JWT_INVALID_DATA
93+
],
8794
[
8895
// Not before (nfb) in future
8996
'https://pro-1.frontendapi.cloud.corbado.io',
90-
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() + 100, time() + 100, $privateKey),
97+
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() + 100, time() + 100, $privateKey, 'RS256'),
9198
false,
9299
ValidationException::CODE_JWT_BEFORE
93100
],
94101
[
95102
// Expired (exp)
96103
'https://pro-1.frontendapi.cloud.corbado.io',
97-
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() - 100, time() - 100, $privateKey),
104+
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() - 100, time() - 100, $privateKey, 'RS256'),
98105
false,
99106
ValidationException::CODE_JWT_EXPIRED
100107
],
101108
[
102109
// Empty issuer (iss)
103110
'https://pro-1.frontendapi.cloud.corbado.io',
104-
self::generateJWT('', time() + 100, time() - 100, $privateKey),
111+
self::generateJWT('', time() + 100, time() - 100, $privateKey, 'RS256'),
105112
false,
106113
ValidationException::CODE_JWT_ISSUER_EMPTY
107114
],
108115
[
109116
// Invalid issuer (iss)
110117
'https://pro-1.frontendapi.cloud.corbado.io',
111-
self::generateJWT('https://pro-2.frontendapi.cloud.corbado.io', time() + 100, time() - 100, $privateKey),
118+
self::generateJWT('https://pro-2.frontendapi.cloud.corbado.io', time() + 100, time() - 100, $privateKey, 'RS256'),
112119
false,
113120
ValidationException::CODE_JWT_ISSUER_MISMATCH
114121
],
115122
[
116123
// Invalid issuer (iss)
117124
'https://pro-1.frontendapi.corbado.io',
118-
self::generateJWT('https://pro-2.frontendapi.cloud.corbado.io', time() + 100, time() - 100, $privateKey),
125+
self::generateJWT('https://pro-2.frontendapi.cloud.corbado.io', time() + 100, time() - 100, $privateKey, 'RS256'),
119126
false,
120127
ValidationException::CODE_JWT_ISSUER_MISMATCH
121128
],
122129
[
123130
// Invalid issuer (iss)
124131
'https://pro-1.frontendapi.cloud.corbado.io',
125-
self::generateJWT('https://pro-2.frontendapi.corbado.io', time() + 100, time() - 100, $privateKey),
132+
self::generateJWT('https://pro-2.frontendapi.corbado.io', time() + 100, time() - 100, $privateKey, 'RS256'),
126133
false,
127134
ValidationException::CODE_JWT_ISSUER_MISMATCH
128135
],
129136
[
130137
// Success with new Frontend API URL
131138
'https://pro-1.frontendapi.cloud.corbado.io',
132-
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() + 100, time() - 100, $privateKey),
139+
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() + 100, time() - 100, $privateKey, 'RS256'),
133140
true,
134141
0
135142
],
136143
[
137144
// Success with old Frontend API URL in JWT
138145
'https://pro-1.frontendapi.cloud.corbado.io',
139-
self::generateJWT('https://pro-1.frontendapi.corbado.io', time() + 100, time() - 100, $privateKey),
146+
self::generateJWT('https://pro-1.frontendapi.corbado.io', time() + 100, time() - 100, $privateKey, 'RS256'),
140147
true,
141148
0
142149
],
143150
[
144151
// Success with old Frontend API URL in config
145152
'https://pro-1.frontendapi.corbado.io',
146-
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() + 100, time() - 100, $privateKey),
153+
self::generateJWT('https://pro-1.frontendapi.cloud.corbado.io', time() + 100, time() - 100, $privateKey, 'RS256'),
147154
true,
148155
0
149156
],
150157
[
151158
// Success with CNAME
152159
'https://auth.acme.com',
153-
self::generateJWT('https://auth.acme.com', time() + 100, time() - 100, $privateKey),
160+
self::generateJWT('https://auth.acme.com', time() + 100, time() - 100, $privateKey, 'RS256'),
154161
true,
155162
0
156163
]
@@ -304,7 +311,7 @@ public function commit(): bool
304311
/**
305312
* @throws Exception
306313
*/
307-
private static function generateJWT(string $iss, int $exp, int $nbf, string $privateKey): string
314+
private static function generateJWT(string $iss, int $exp, int $nbf, string $privateKey, string $alg): string
308315
{
309316
$payload = [
310317
'iss' => $iss,
@@ -318,6 +325,23 @@ private static function generateJWT(string $iss, int $exp, int $nbf, string $pri
318325
'orig' => 'orig',
319326
];
320327

321-
return JWT::encode($payload, $privateKey, 'RS256', 'kid123');
328+
if ($alg === 'NONE') {
329+
$encodedHeader = json_encode(['typ' => 'JWT', 'alg' => 'none']);
330+
if ($encodedHeader === false) {
331+
throw new Exception('json_encode() failed');
332+
}
333+
334+
$encodedPayload = json_encode($payload);
335+
if ($encodedPayload === false) {
336+
throw new Exception('json_encode() failed');
337+
}
338+
339+
$base64UrlHeader = rtrim(strtr(base64_encode($encodedHeader), '+/', '-_'), '=');
340+
$base64UrlPayload = rtrim(strtr(base64_encode($encodedPayload), '+/', '-_'), '=');
341+
342+
return $base64UrlHeader . '.' . $base64UrlPayload . '.';
343+
}
344+
345+
return JWT::encode($payload, $privateKey, $alg, 'kid123');
322346
}
323347
}

0 commit comments

Comments
 (0)