You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

66 lines
2.7 KiB

<?php
declare(strict_types=1);
namespace App\Tests\Security;
use App\Security\NostrAuthenticator;
use App\Service\NostrKeyHelper;
use PHPUnit\Framework\TestCase;
use swentel\nostr\Event\Event;
use swentel\nostr\Key\Key;
use swentel\nostr\Sign\Sign;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
/**
* Unit tests for {@see NostrAuthenticator} (no full HTTP stack / DB: no nsec parameter, no Docker MySQL).
*/
class NostrAuthenticatorTest extends TestCase
{
public function testValidNostrEventReturnsPassport(): void
{
$nsec = (new Key())->convertPrivateKeyToBech32((new Key())->generatePrivateKey());
$token = 'Nostr '.$this->signedAuthEventBase64($nsec);
$request = Request::create('/login', 'GET', [], [], [], ['HTTP_AUTHORIZATION' => $token]);
$out = (new NostrAuthenticator(new NostrKeyHelper()))->authenticate($request);
$this->assertInstanceOf(SelfValidatingPassport::class, $out);
}
public function testInvalidAuthorizationHeaderThrows(): void
{
$this->expectException(AuthenticationException::class);
$request = Request::create('/login', 'GET', [], [], [], [
'HTTP_AUTHORIZATION' => 'InvalidHeader',
]);
(new NostrAuthenticator(new NostrKeyHelper()))->authenticate($request);
}
public function testExpiredEventThrows(): void
{
$this->expectException(AuthenticationException::class);
$this->expectExceptionMessage('Expired');
$expiredToken = 'Nostr eyJjcmVhdGVkX2F0IjoxNzMzMzIxMzUyLCJraW5kIjoyNzIzNSwidGFncyI6W1sidSIsImh0dHBzOi8vbG9jYWxob3N0L2xvZ2luIl0sWyJtZXRob2QiLCJHRVQiXV0sImNvbnRlbnQiOiIiLCJwdWJrZXkiOiJkNDc1Y2U0YjM5Nzc1MDcxMzBmNDJjN2Y4NjM0NmVmOTM2ODAwZjNhZTc0ZDVlY2Y4MDg5MjgwY2RjMTkyM2U5IiwiaWQiOiJhYjA4NGM1NWQ5Y2UzMDliN2UxNzIyZGI2ODNjZTc2ZDg5NGNjN2QyYTIzZTRkNWUyMTUyYTM2Y2M2ODI1MTQ5Iiwic2lnIjoiOWI1Yjk2YjhkN2U2ZGM4YWU3ZmM4NjU2ZTE0NDVlZjkwYzc1YWQxNzZkYTRmNmNhMjI0NTRkNTJjNTk3ZTBmNjYwZjAwZjE3MmIxYjMzYzM4YTg2Y2U0YTBiMTdmMDgwMWEyNzJmZmVmYWU0NmY2OTgzZGZjYjRlM2YyZDgwZGYifQ==';
$request = Request::create('/login', 'GET', [], [], [], [
'HTTP_AUTHORIZATION' => $expiredToken,
]);
(new NostrAuthenticator(new NostrKeyHelper()))->authenticate($request);
}
private function signedAuthEventBase64(string $nsec): string
{
$note = new Event();
$note->setContent('');
$note->setKind(27235);
$note->setTags([
['u', 'https://localhost/login'],
['method', 'POST'],
]);
(new Sign())->signEvent($note, $nsec);
return base64_encode($note->toJson());
}
}