Files
mahak-authenticate-bridge/vendor/firebase/php-jwt/tests/ReadmeTest.php
T
2026-05-28 18:44:36 +03:30

202 lines
6.0 KiB
PHP

<?php
namespace Firebase\JWT;
use PHPUnit\Framework\TestCase;
class ReadmeTest extends TestCase
{
private const CODEBLOCK_REGEX = '/^(?m)(\s*)(`{3,}|~{3,})[ \t]*(.*?)\n([\s\S]*?)\1\2\s*$/m';
private array $payload = [
'iss' => 'example.org',
'aud' => 'example.com',
'iat' => 1356999524,
'nbf' => 1357000000,
];
public function testExample()
{
$codeblock = $this->extractCodeBlock('Example');
$output = $codeblock->invoke();
$header = ['typ' => 'JWT', 'alg' => 'HS256'];
$this->assertEquals(
print_r((object) $this->payload, true) . print_r((object) $header, true),
$output
);
}
public function testExampleEncodeDecodeHeaders()
{
$codeblock = $this->extractCodeBlock('Example encode/decode headers');
$output = $codeblock->invoke();
$header = [
'typ' => 'JWT',
'x-forwarded-for' => 'www.google.com',
'alg' => 'HS256',
];
$this->assertEquals(
print_r($header, true),
$output
);
}
public function testExampleWithRS256()
{
$codeblock = $this->extractCodeBlock('Example with RS256 (openssl)');
$output = $codeblock->invoke();
$this->assertStringContainsString(
"Decode:\n" . print_r($this->payload, true),
$output
);
}
public function testExampleWithPassphrase()
{
$codeblock = $this->extractCodeBlock('Example with a passphrase');
$codeblock->replace('[YOUR_PASSPHRASE]', 'passphrase');
$codeblock->replace(
'/path/to/key-with-passphrase.pem',
__DIR__ . '/data/rsa-with-passphrase.pem'
);
$output = $codeblock->invoke();
$this->assertStringContainsString(
"Decode:\n" . print_r($this->payload, true),
$output
);
}
public function testExampleWithEdDSA()
{
$codeblock = $this->extractCodeBlock('Example with EdDSA (libsodium and Ed25519 signature)');
$output = $codeblock->invoke();
$this->assertStringContainsString(
"Decode:\n" . print_r($this->payload, true),
$output
);
}
public function testExampleWithMultipleKeys()
{
$codeblock = $this->extractCodeBlock('Example with multiple keys');
$keys = [
'$privateRsKey' => 'rsa1-private.pem',
'$publicRsKey' => 'rsa1-public.pub',
'$privateEcKey' => 'ed25519-1.sec',
'$publicEcKey' => 'ed25519-1.pub',
];
foreach ($keys as $varName => $keyFile) {
$codeblock->replace(
\sprintf('// %s = \'...\'', $varName),
\sprintf('%s = file_get_contents(\'%s/data/%s\')', $varName, __DIR__, $keyFile)
);
}
$output = $codeblock->invoke();
$this->assertStringContainsString(
"Decode 1:\n" . print_r($this->payload, true),
$output
);
$this->assertStringContainsString(
"Decode 2:\n" . print_r($this->payload, true),
$output
);
}
public function testUsingJWKs()
{
$codeblock = $this->extractCodeBlock('Using JWKs');
$privateKey = file_get_contents(__DIR__ . '/data/rsa1-private.pem');
$jwt = JWT::encode($this->payload, $privateKey, 'RS256', 'jwk1');
$keysJson = file_get_contents(__DIR__ . '/data/rsa-jwkset.json');
$jwkSet = json_decode($keysJson, true);
$codeblock->replace('$jwt', \sprintf("'%s'", $jwt));
$codeblock->replace(
'[\'keys\' => []]',
var_export($jwkSet, true)
);
$output = $codeblock->invoke();
$this->assertEquals(
print_r((object) $this->payload, true),
$output
);
}
public function testUsingCachedKeySets()
{
// We must accept a failure because we are not signing the keys
// This is the farthest we can go without retreiving an actual JWT
// or hosting our own JWKs url.
$this->expectException(SignatureInvalidException::class);
$this->expectExceptionMessage('Signature verification failed');
$codeblock = $this->extractCodeBlock('Using Cached Key Sets');
$privateKey = file_get_contents(__DIR__ . '/data/ecdsa256-private.pem');
$jwt = JWT::encode($this->payload, $privateKey, 'ES256', '_xiGEQ');
$codeblock->replace('eyJhbGci...', $jwt);
$codeblock->invoke();
}
private function extractCodeBlock(string $header)
{
// Normalize line endings to \n to make regex handling consistent across platforms
$markdown = str_replace(["\r\n", "\r"], "\n", file_get_contents(__DIR__ . '/../README.md'));
// find by header
$pattern = '/^#+\s*' . preg_quote($header, '/') . '\s*\n([\s\S]*?)(?=^#+.*$|\Z)/m';
if (!preg_match($pattern, $markdown, $matches)) {
throw new \Exception('Header "' . $header . '" not found in README.md');
}
$markdown = trim($matches[1]);
// extract fenced codeblock
if (!preg_match_all(self::CODEBLOCK_REGEX, $markdown, $matches, PREG_SET_ORDER)) {
throw new \Exception('No code block found in README.md under header "' . $header . '"');
}
$codeblock = $matches[0][4];
return new class($codeblock) {
public function __construct(public string $codeblock)
{
}
public function invoke()
{
try {
ob_start();
eval($this->codeblock);
return ob_get_clean();
} catch (\Exception $e) {
ob_end_clean();
throw $e;
}
}
public function replace($old, $new)
{
$this->codeblock = str_replace($old, $new, $this->codeblock);
}
};
}
}