Skip to content

Commit 76d6e82

Browse files
authored
fix: lint
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
1 parent 0603445 commit 76d6e82

1 file changed

Lines changed: 51 additions & 24 deletions

File tree

lib/Service/DiscoveryService.php

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -121,44 +121,71 @@ public function buildAuthorizationUrl(string $authorizationEndpoint, array $extr
121121
/**
122122
* Inspired by https://github.com/snake/moodle/compare/880462a1685...MDL-77077-master
123123
*
124-
* @param array $jwks
125-
* @param string $jwt
126-
* @return array
127-
* @throws \Exception
124+
* @param array $jwks The JSON Web Key Set
125+
* @param string $jwt The JWT token
126+
* @return array The modified JWKS
127+
* @throws \RuntimeException if no matching key is found or algorithm is unsupported
128128
*/
129129
private function fixJwksAlg(array $jwks, string $jwt): array {
130-
$jwtParts = explode('.', $jwt);
131-
$jwtHeader = json_decode(JWT::urlsafeB64Decode($jwtParts[0]), true);
132-
$kid = $jwtHeader['kid'] ?? null;
133-
$alg = $jwtHeader['alg'] ?? null;
130+
$jwtParts = explode('.', $jwt, 3);
131+
$header = json_decode(JWT::urlsafeB64Decode($jwtParts[0]), true);
132+
$kid = $header['kid'] ?? null;
133+
$alg = $header['alg'] ?? null;
134+
135+
$expectedKty = self::SUPPORTED_JWK_ALGS[$alg] ?? null;
136+
if ($expectedKty === null) {
137+
throw new \RuntimeException('Unsupported JWT alg: ' . ($alg ?? 'unknown'));
138+
}
134139

135-
if (!isset(self::SUPPORTED_JWK_ALGS[$alg])) {
136-
throw new \Exception('Unsupported JWT alg: ' . ($alg ?? 'unknown'));
140+
$keys = $jwks['keys'] ?? null;
141+
if (!is_array($keys)) {
142+
throw new \RuntimeException('Invalid JWKS: missing "keys" array');
137143
}
138144

139-
$expectedKty = self::SUPPORTED_JWK_ALGS[$alg];
145+
$matchingIndex = null;
146+
147+
foreach ($keys as $index => $key) {
148+
$keyKty = $key['kty'] ?? null;
149+
$keyUse = $key['use'] ?? null;
140150

141-
foreach ($jwks['keys'] as $index => $key) {
142-
// Skip if alg is already set
143-
if (!empty($key['alg'])) {
151+
// Skip keys with incompatible type
152+
if ($keyKty !== $expectedKty) {
144153
continue;
145154
}
146155

147-
// Match by kid if present, or by alg and kty if kid is missing
148-
if ($kid !== null && isset($key['kid']) && $key['kid'] !== $kid) {
156+
// Skip keys not intended for signature
157+
if ($keyUse !== null && $keyUse !== 'sig') {
149158
continue;
150159
}
151160

152-
// Validate algorithm compatibility
153-
if (($key['kty'] ?? null) !== $expectedKty) {
154-
continue;
161+
// If JWT has a kid, match strictly
162+
if ($kid !== null) {
163+
if (($key['kid'] ?? null) !== $kid) {
164+
continue;
165+
}
166+
$matchingIndex = $index;
167+
break;
155168
}
156169

157-
// Set alg for the matching key
158-
$jwks['keys'][$index]['alg'] = $alg;
159-
return $jwks;
170+
// If no kid, select the first compatible key
171+
if ($matchingIndex === null) {
172+
$matchingIndex = $index;
173+
}
160174
}
161-
162-
throw new \Exception('No matching key found in JWKS (alg=' . ($alg ?? 'unknown') . ', kid=' . ($kid ?? 'none') . ')');
175+
176+
if ($matchingIndex === null) {
177+
throw new \RuntimeException(sprintf(
178+
'No matching key found in JWKS (alg=%s, kid=%s)',
179+
$alg ?? 'unknown',
180+
$kid ?? 'none'
181+
));
182+
}
183+
184+
// Set 'alg' field if missing
185+
if (empty($jwks['keys'][$matchingIndex]['alg'])) {
186+
$jwks['keys'][$matchingIndex]['alg'] = $alg;
187+
}
188+
189+
return $jwks;
163190
}
164191
}

0 commit comments

Comments
 (0)