mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-nostr.git
synced 2026-01-27 06:33:18 +00:00
✨ Refactor NIP-05 verification: extract handle-fetching logic into reusable NostrFetcherTrait and enhance UI to display all verified handles with improved feedback.
This commit is contained in:
@@ -12,6 +12,37 @@ use swentel\nostr\Subscription\Subscription;
|
|||||||
|
|
||||||
trait NostrFetcherTrait
|
trait NostrFetcherTrait
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Get all NIP-05 handles for a given pubkey from nostr.json
|
||||||
|
*
|
||||||
|
* @param string $pubkey The public key in hex format
|
||||||
|
* @return array Array of handles associated with the pubkey
|
||||||
|
*/
|
||||||
|
public function getNip05HandlesForPubkey(string $pubkey): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$response = \Illuminate\Support\Facades\Http::get(
|
||||||
|
'https://einundzwanzig.space/.well-known/nostr.json',
|
||||||
|
);
|
||||||
|
$data = $response->json();
|
||||||
|
|
||||||
|
if (! isset($data['names'])) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$handles = [];
|
||||||
|
foreach ($data['names'] as $handle => $handlePubkey) {
|
||||||
|
if ($handlePubkey === $pubkey) {
|
||||||
|
$handles[] = $handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $handles;
|
||||||
|
} catch (\Exception) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function fetchProfile($npubs)
|
public function fetchProfile($npubs)
|
||||||
{
|
{
|
||||||
$hex = collect([]);
|
$hex = collect([]);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ return [
|
|||||||
/**
|
/**
|
||||||
* Use this setting to specify the site name that will be used in OpenGraph tags.
|
* Use this setting to specify the site name that will be used in OpenGraph tags.
|
||||||
*/
|
*/
|
||||||
'site_name' => 'Einundzwanzig Verein',
|
'site_name' => 'EINUNDZWANZIG Verein',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this setting to specify the path to the sitemap of your website. This exact path will outputted, so
|
* Use this setting to specify the path to the sitemap of your website. This exact path will outputted, so
|
||||||
@@ -75,7 +75,7 @@ return [
|
|||||||
* Use this setting to provide a suffix that will be added after the title on each page.
|
* Use this setting to provide a suffix that will be added after the title on each page.
|
||||||
* If you don't want a suffix, you should specify an empty string.
|
* If you don't want a suffix, you should specify an empty string.
|
||||||
*/
|
*/
|
||||||
'suffix' => ' - Einundzwanzig Verein',
|
'suffix' => ' - EINUNDZWANZIG Verein',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this setting to provide a custom title for the homepage. We will not use the suffix on the homepage,
|
* Use this setting to provide a custom title for the homepage. We will not use the suffix on the homepage,
|
||||||
|
|||||||
@@ -26,10 +26,10 @@
|
|||||||
<flux:header sticky class="bg-zinc-50 dark:bg-zinc-900 border-b border-zinc-200 dark:border-zinc-700">
|
<flux:header sticky class="bg-zinc-50 dark:bg-zinc-900 border-b border-zinc-200 dark:border-zinc-700">
|
||||||
<flux:sidebar.toggle class="lg:hidden" icon="bars-2" inset="left"/>
|
<flux:sidebar.toggle class="lg:hidden" icon="bars-2" inset="left"/>
|
||||||
|
|
||||||
<flux:brand href="/" name="Einundzwanzig" class="max-lg:hidden dark:hidden">
|
<flux:brand href="/" name="EINUNDZWANZIG" class="max-lg:hidden dark:hidden">
|
||||||
<img src="{{ asset('einundzwanzig-alpha.jpg') }}" alt="Logo" class="h-6 w-6">
|
<img src="{{ asset('einundzwanzig-alpha.jpg') }}" alt="Logo" class="h-6 w-6">
|
||||||
</flux:brand>
|
</flux:brand>
|
||||||
<flux:brand href="/" name="Einundzwanzig" class="max-lg:hidden! hidden dark:flex">
|
<flux:brand href="/" name="EINUNDZWANZIG" class="max-lg:hidden! hidden dark:flex">
|
||||||
<img src="{{ asset('einundzwanzig-alpha.jpg') }}" alt="Logo" class="h-6 w-6">
|
<img src="{{ asset('einundzwanzig-alpha.jpg') }}" alt="Logo" class="h-6 w-6">
|
||||||
</flux:brand>
|
</flux:brand>
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
<flux:sidebar.header>
|
<flux:sidebar.header>
|
||||||
<flux:sidebar.brand
|
<flux:sidebar.brand
|
||||||
href="/"
|
href="/"
|
||||||
name="Einundzwanzig"
|
name="EINUNDZWANZIG"
|
||||||
>
|
>
|
||||||
<img src="{{ asset('einundzwanzig-alpha.jpg') }}" alt="Logo" class="h-6 w-6">
|
<img src="{{ asset('einundzwanzig-alpha.jpg') }}" alt="Logo" class="h-6 w-6">
|
||||||
</flux:sidebar.brand>
|
</flux:sidebar.brand>
|
||||||
|
|||||||
@@ -2,11 +2,14 @@
|
|||||||
|
|
||||||
use App\Models\EinundzwanzigPleb;
|
use App\Models\EinundzwanzigPleb;
|
||||||
use App\Support\NostrAuth;
|
use App\Support\NostrAuth;
|
||||||
|
use App\Traits\NostrFetcherTrait;
|
||||||
use Flux\Flux;
|
use Flux\Flux;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
new class extends Component
|
new class extends Component
|
||||||
{
|
{
|
||||||
|
use NostrFetcherTrait;
|
||||||
|
|
||||||
public ?EinundzwanzigPleb $currentPleb = null;
|
public ?EinundzwanzigPleb $currentPleb = null;
|
||||||
|
|
||||||
public ?string $currentPubkey = null;
|
public ?string $currentPubkey = null;
|
||||||
@@ -21,6 +24,8 @@ new class extends Component
|
|||||||
|
|
||||||
public bool $nip05HandleMismatch = false;
|
public bool $nip05HandleMismatch = false;
|
||||||
|
|
||||||
|
public array $nip05VerifiedHandles = [];
|
||||||
|
|
||||||
protected $listeners = [
|
protected $listeners = [
|
||||||
'nostrLoggedIn' => 'handleNostrLoggedIn',
|
'nostrLoggedIn' => 'handleNostrLoggedIn',
|
||||||
'nostrLoggedOut' => 'handleNostrLoggedOut',
|
'nostrLoggedOut' => 'handleNostrLoggedOut',
|
||||||
@@ -40,27 +45,17 @@ new class extends Component
|
|||||||
if ($this->currentPleb->nip05_handle) {
|
if ($this->currentPleb->nip05_handle) {
|
||||||
$this->nip05Handle = $this->currentPleb->nip05_handle;
|
$this->nip05Handle = $this->currentPleb->nip05_handle;
|
||||||
|
|
||||||
// Verify NIP-05 handle against nostr.json
|
// Get all NIP-05 handles for current pubkey
|
||||||
try {
|
$this->nip05VerifiedHandles = $this->getNip05HandlesForPubkey($this->currentPubkey);
|
||||||
$response = \Illuminate\Support\Facades\Http::get(
|
|
||||||
'https://einundzwanzig.space/.well-known/nostr.json',
|
if (count($this->nip05VerifiedHandles) > 0) {
|
||||||
);
|
|
||||||
$data = $response->json();
|
|
||||||
if (isset($data['names'])) {
|
|
||||||
foreach ($data['names'] as $handle => $pubkey) {
|
|
||||||
if ($pubkey === $this->currentPubkey) {
|
|
||||||
$this->nip05Verified = true;
|
$this->nip05Verified = true;
|
||||||
$this->nip05VerifiedHandle = $handle;
|
$this->nip05VerifiedHandle = $this->nip05VerifiedHandles[0];
|
||||||
|
|
||||||
// Check if verified handle differs from database handle
|
// Check if verified handle differs from database handle
|
||||||
if ($handle !== $this->nip05Handle) {
|
if (! in_array($this->nip05Handle, $this->nip05VerifiedHandles, true)) {
|
||||||
$this->nip05HandleMismatch = true;
|
$this->nip05HandleMismatch = true;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (\Exception) {
|
|
||||||
// Silently fail if nostr.json is not accessible
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +116,7 @@ new class extends Component
|
|||||||
$this->nip05Verified = false;
|
$this->nip05Verified = false;
|
||||||
$this->nip05VerifiedHandle = null;
|
$this->nip05VerifiedHandle = null;
|
||||||
$this->nip05HandleMismatch = false;
|
$this->nip05HandleMismatch = false;
|
||||||
|
$this->nip05VerifiedHandles = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -251,25 +247,33 @@ new class extends Component
|
|||||||
|
|
||||||
<!-- NIP-05 Verification Status -->
|
<!-- NIP-05 Verification Status -->
|
||||||
@if($nip05Verified)
|
@if($nip05Verified)
|
||||||
@if($nip05HandleMismatch)
|
<flux:callout variant="success" icon="check-circle" class="mt-4">
|
||||||
<flux:callout variant="warning" icon="exclamation-triangle" class="mt-4">
|
|
||||||
<p class="font-medium text-zinc-800 dark:text-zinc-100">
|
<p class="font-medium text-zinc-800 dark:text-zinc-100">
|
||||||
Dein aktiviertes Handle ist <br><strong class="break-all">{{ $nip05VerifiedHandle }}@einundzwanzig.space</strong>
|
Du hast {{ count($nip05VerifiedHandles) }} aktiv{{ count($nip05VerifiedHandles) > 1 ? 'ierte' : 'isiert' }}e{{ count($nip05VerifiedHandles) > 1 ? ' Handles' : 'es Handle' }} für deinen Pubkey!
|
||||||
</p>
|
</p>
|
||||||
|
@if($nip05HandleMismatch)
|
||||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 mt-1">
|
<p class="text-sm text-zinc-600 dark:text-zinc-400 mt-1">
|
||||||
Die Synchronisation zu <strong class="break-all">{{ $nip05Handle }}@einundzwanzig.space</strong> wird automatisch im Hintergrund durchgeführt.
|
Die Synchronisation zu <strong class="break-all">{{ $nip05Handle }}@einundzwanzig.space</strong> wird automatisch im Hintergrund durchgeführt.
|
||||||
</p>
|
</p>
|
||||||
</flux:callout>
|
|
||||||
@else
|
|
||||||
<flux:callout variant="success" icon="check-circle" class="mt-4">
|
|
||||||
<p class="font-medium text-zinc-800 dark:text-zinc-100">
|
|
||||||
Dein Handle <strong class="break-all">{{ $nip05VerifiedHandle }}@einundzwanzig.space</strong> ist aktiv verifiziert!
|
|
||||||
</p>
|
|
||||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 mt-1">
|
|
||||||
Dein Handle ist in der NIP-05 Konfiguration eingetragen und bereit für die Verwendung.
|
|
||||||
</p>
|
|
||||||
</flux:callout>
|
|
||||||
@endif
|
@endif
|
||||||
|
</flux:callout>
|
||||||
|
|
||||||
|
<!-- List of all active handles -->
|
||||||
|
<div class="mt-4 p-4 bg-white/50 dark:bg-zinc-800/50 rounded border border-zinc-200 dark:border-zinc-600">
|
||||||
|
<p class="text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">
|
||||||
|
Deine aktivierten Handles:
|
||||||
|
</p>
|
||||||
|
<ul class="space-y-2">
|
||||||
|
@foreach($nip05VerifiedHandles as $handle)
|
||||||
|
<li class="flex items-center gap-2 text-sm">
|
||||||
|
<span class="break-all text-zinc-800 dark:text-zinc-200 font-mono">
|
||||||
|
{{ $handle }}@einundzwanzig.space
|
||||||
|
</span>
|
||||||
|
<flux:badge color="green" size="xs">OK</flux:badge>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
@elseif($nip05Handle)
|
@elseif($nip05Handle)
|
||||||
<flux:callout variant="secondary" icon="information-circle" class="mt-4">
|
<flux:callout variant="secondary" icon="information-circle" class="mt-4">
|
||||||
<p class="font-medium text-zinc-800 dark:text-zinc-100">
|
<p class="font-medium text-zinc-800 dark:text-zinc-100">
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
use App\Livewire\Forms\ApplicationForm;
|
use App\Livewire\Forms\ApplicationForm;
|
||||||
use App\Models\EinundzwanzigPleb;
|
use App\Models\EinundzwanzigPleb;
|
||||||
use App\Support\NostrAuth;
|
use App\Support\NostrAuth;
|
||||||
|
use App\Traits\NostrFetcherTrait;
|
||||||
use Flux\Flux;
|
use Flux\Flux;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use swentel\nostr\Event\Event as NostrEvent;
|
use swentel\nostr\Event\Event as NostrEvent;
|
||||||
@@ -17,6 +18,8 @@ use swentel\nostr\Subscription\Subscription;
|
|||||||
|
|
||||||
new class extends Component
|
new class extends Component
|
||||||
{
|
{
|
||||||
|
use NostrFetcherTrait;
|
||||||
|
|
||||||
public ApplicationForm $form;
|
public ApplicationForm $form;
|
||||||
|
|
||||||
public bool $no = false;
|
public bool $no = false;
|
||||||
@@ -35,6 +38,8 @@ new class extends Component
|
|||||||
|
|
||||||
public bool $nip05HandleMismatch = false;
|
public bool $nip05HandleMismatch = false;
|
||||||
|
|
||||||
|
public array $nip05VerifiedHandles = [];
|
||||||
|
|
||||||
public array $yearsPaid = [];
|
public array $yearsPaid = [];
|
||||||
|
|
||||||
public array $events = [];
|
public array $events = [];
|
||||||
@@ -71,27 +76,17 @@ new class extends Component
|
|||||||
if ($this->currentPleb->nip05_handle) {
|
if ($this->currentPleb->nip05_handle) {
|
||||||
$this->nip05Handle = $this->currentPleb->nip05_handle;
|
$this->nip05Handle = $this->currentPleb->nip05_handle;
|
||||||
|
|
||||||
// Verify NIP-05 handle against nostr.json
|
// Get all NIP-05 handles for the current pubkey
|
||||||
try {
|
$this->nip05VerifiedHandles = $this->getNip05HandlesForPubkey($this->currentPubkey);
|
||||||
$response = \Illuminate\Support\Facades\Http::get(
|
|
||||||
'https://einundzwanzig.space/.well-known/nostr.json',
|
if (count($this->nip05VerifiedHandles) > 0) {
|
||||||
);
|
|
||||||
$data = $response->json();
|
|
||||||
if (isset($data['names'])) {
|
|
||||||
foreach ($data['names'] as $handle => $pubkey) {
|
|
||||||
if ($pubkey === $this->currentPubkey) {
|
|
||||||
$this->nip05Verified = true;
|
$this->nip05Verified = true;
|
||||||
$this->nip05VerifiedHandle = $handle;
|
$this->nip05VerifiedHandle = $this->nip05VerifiedHandles[0];
|
||||||
|
|
||||||
// Check if verified handle differs from database handle
|
// Check if verified handle differs from database handle
|
||||||
if ($handle !== $this->nip05Handle) {
|
if (! in_array($this->nip05Handle, $this->nip05VerifiedHandles, true)) {
|
||||||
$this->nip05HandleMismatch = true;
|
$this->nip05HandleMismatch = true;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (\Exception) {
|
|
||||||
// Silently fail if nostr.json is not accessible
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->no = $this->currentPleb->no_email;
|
$this->no = $this->currentPleb->no_email;
|
||||||
@@ -468,25 +463,33 @@ new class extends Component
|
|||||||
|
|
||||||
<!-- NIP-05 Verification Status -->
|
<!-- NIP-05 Verification Status -->
|
||||||
@if($nip05Verified)
|
@if($nip05Verified)
|
||||||
@if($nip05HandleMismatch)
|
<flux:callout variant="success" icon="check-circle" class="mt-4">
|
||||||
<flux:callout variant="warning" icon="exclamation-triangle" class="mt-4">
|
|
||||||
<p class="font-medium text-zinc-800 dark:text-zinc-100">
|
<p class="font-medium text-zinc-800 dark:text-zinc-100">
|
||||||
Dein aktiviertes Handle ist <br><strong class="break-all">{{ $nip05VerifiedHandle }}@einundzwanzig.space</strong>
|
Du hast {{ count($nip05VerifiedHandles) }} aktiv{{ count($nip05VerifiedHandles) > 1 ? 'ierte' : 'isiert' }}e{{ count($nip05VerifiedHandles) > 1 ? ' Handles' : 'es Handle' }} für deinen Pubkey!
|
||||||
</p>
|
</p>
|
||||||
|
@if($nip05HandleMismatch)
|
||||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 mt-1">
|
<p class="text-sm text-zinc-600 dark:text-zinc-400 mt-1">
|
||||||
Die Synchronisation zu <strong class="break-all">{{ $nip05Handle }}@einundzwanzig.space</strong> wird automatisch im Hintergrund durchgeführt.
|
Die Synchronisation zu <strong class="break-all">{{ $nip05Handle }}@einundzwanzig.space</strong> wird automatisch im Hintergrund durchgeführt.
|
||||||
</p>
|
</p>
|
||||||
</flux:callout>
|
|
||||||
@else
|
|
||||||
<flux:callout variant="success" icon="check-circle" class="mt-4">
|
|
||||||
<p class="font-medium text-zinc-800 dark:text-zinc-100">
|
|
||||||
Dein Handle <strong class="break-all">{{ $nip05VerifiedHandle }}@einundzwanzig.space</strong> ist aktiv verifiziert!
|
|
||||||
</p>
|
|
||||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 mt-1">
|
|
||||||
Dein Handle ist in der NIP-05 Konfiguration eingetragen und bereit für die Verwendung.
|
|
||||||
</p>
|
|
||||||
</flux:callout>
|
|
||||||
@endif
|
@endif
|
||||||
|
</flux:callout>
|
||||||
|
|
||||||
|
<!-- List of all active handles -->
|
||||||
|
<div class="mt-4 p-4 bg-white/50 dark:bg-zinc-800/50 rounded border border-zinc-200 dark:border-zinc-600">
|
||||||
|
<p class="text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">
|
||||||
|
Deine aktivierten Handles:
|
||||||
|
</p>
|
||||||
|
<ul class="space-y-2">
|
||||||
|
@foreach($nip05VerifiedHandles as $handle)
|
||||||
|
<li class="flex items-center gap-2 text-sm">
|
||||||
|
<span class="break-all text-zinc-800 dark:text-zinc-200 font-mono">
|
||||||
|
{{ $handle }}@einundzwanzig.space
|
||||||
|
</span>
|
||||||
|
<flux:badge color="green" size="xs">OK</flux:badge>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
@elseif($nip05Handle)
|
@elseif($nip05Handle)
|
||||||
<flux:callout variant="secondary" icon="information-circle" class="mt-4">
|
<flux:callout variant="secondary" icon="information-circle" class="mt-4">
|
||||||
<p class="font-medium text-zinc-800 dark:text-zinc-100">
|
<p class="font-medium text-zinc-800 dark:text-zinc-100">
|
||||||
|
|||||||
Reference in New Issue
Block a user