mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-nostr.git
synced 2026-04-02 05:28:41 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
use App\Models\ProjectProposal;
|
||||
use App\Support\NostrAuth;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Title;
|
||||
@@ -34,15 +36,15 @@ class extends Component
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
if (NostrAuth::check()) {
|
||||
$currentPubkey = NostrAuth::pubkey();
|
||||
$currentPleb = \App\Models\EinundzwanzigPleb::query()->where('pubkey', $currentPubkey)->first();
|
||||
$nostrUser = NostrAuth::user();
|
||||
|
||||
if ($currentPleb && $currentPleb->association_status->value > 1 && $currentPleb->paymentEvents()->where('year', date('Y'))->where('paid', true)->exists()) {
|
||||
$this->isAllowed = true;
|
||||
}
|
||||
if ($nostrUser && Gate::forUser($nostrUser)->allows('create', ProjectProposal::class)) {
|
||||
$this->isAllowed = true;
|
||||
}
|
||||
|
||||
if ($currentPleb && in_array($currentPleb->npub, config('einundzwanzig.config.current_board'), true)) {
|
||||
if ($nostrUser) {
|
||||
$pleb = $nostrUser->getPleb();
|
||||
if ($pleb && in_array($pleb->npub, config('einundzwanzig.config.current_board'), true)) {
|
||||
$this->isAdmin = true;
|
||||
}
|
||||
}
|
||||
@@ -58,6 +60,18 @@ class extends Component
|
||||
|
||||
public function save(): void
|
||||
{
|
||||
Gate::forUser(NostrAuth::user())->authorize('create', ProjectProposal::class);
|
||||
|
||||
$executed = RateLimiter::attempt(
|
||||
'project-proposal-create:'.request()->ip(),
|
||||
5,
|
||||
function () {},
|
||||
);
|
||||
|
||||
if (! $executed) {
|
||||
abort(429, 'Too many requests.');
|
||||
}
|
||||
|
||||
$this->validate([
|
||||
'form.name' => 'required|string|max:255',
|
||||
'form.description' => 'required|string',
|
||||
@@ -66,15 +80,15 @@ class extends Component
|
||||
'file' => 'nullable|file|mimes:jpeg,png,jpg,gif,webp|mimetypes:image/jpeg,image/png,image/gif,image/webp|max:10240',
|
||||
]);
|
||||
|
||||
$projectProposal = ProjectProposal::query()->create([
|
||||
'name' => $this->form['name'],
|
||||
'description' => $this->form['description'],
|
||||
'support_in_sats' => (int) $this->form['support_in_sats'],
|
||||
'website' => $this->form['website'],
|
||||
'accepted' => $this->form['accepted'],
|
||||
'sats_paid' => $this->form['sats_paid'],
|
||||
'einundzwanzig_pleb_id' => \App\Models\EinundzwanzigPleb::query()->where('pubkey', NostrAuth::pubkey())->first()->id,
|
||||
]);
|
||||
$projectProposal = new ProjectProposal;
|
||||
$projectProposal->name = $this->form['name'];
|
||||
$projectProposal->description = $this->form['description'];
|
||||
$projectProposal->support_in_sats = (int) $this->form['support_in_sats'];
|
||||
$projectProposal->website = $this->form['website'];
|
||||
$projectProposal->accepted = $this->isAdmin ? $this->form['accepted'] : false;
|
||||
$projectProposal->sats_paid = $this->isAdmin ? $this->form['sats_paid'] : 0;
|
||||
$projectProposal->einundzwanzig_pleb_id = \App\Models\EinundzwanzigPleb::query()->where('pubkey', NostrAuth::pubkey())->first()->id;
|
||||
$projectProposal->save();
|
||||
|
||||
if ($this->file) {
|
||||
$projectProposal->addMedia($this->file)->toMediaCollection('main');
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
use App\Models\ProjectProposal;
|
||||
use App\Support\NostrAuth;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Title;
|
||||
@@ -39,36 +41,29 @@ class extends Component
|
||||
{
|
||||
$this->project = $projectProposal;
|
||||
|
||||
if (NostrAuth::check()) {
|
||||
$currentPubkey = NostrAuth::pubkey();
|
||||
$currentPleb = \App\Models\EinundzwanzigPleb::query()->where('pubkey', $currentPubkey)->first();
|
||||
$nostrUser = NostrAuth::user();
|
||||
|
||||
if (
|
||||
(
|
||||
$currentPleb
|
||||
&& $currentPleb->id === $this->project->einundzwanzig_pleb_id
|
||||
)
|
||||
|| in_array($currentPleb->npub, config('einundzwanzig.config.current_board'))
|
||||
) {
|
||||
$this->isAllowed = true;
|
||||
$this->form = [
|
||||
'name' => $this->project->name,
|
||||
'description' => $this->project->description,
|
||||
'support_in_sats' => (string) $this->project->support_in_sats,
|
||||
'website' => $this->project->website ?? '',
|
||||
'accepted' => (bool) $this->project->accepted,
|
||||
'sats_paid' => $this->project->sats_paid,
|
||||
];
|
||||
}
|
||||
if ($nostrUser && Gate::forUser($nostrUser)->allows('update', $this->project)) {
|
||||
$this->isAllowed = true;
|
||||
$this->form = [
|
||||
'name' => $this->project->name,
|
||||
'description' => $this->project->description,
|
||||
'support_in_sats' => (string) $this->project->support_in_sats,
|
||||
'website' => $this->project->website ?? '',
|
||||
'accepted' => (bool) $this->project->accepted,
|
||||
'sats_paid' => $this->project->sats_paid,
|
||||
];
|
||||
}
|
||||
|
||||
if ($currentPleb && in_array($currentPleb->npub, config('einundzwanzig.config.current_board'), true)) {
|
||||
$this->isAdmin = true;
|
||||
}
|
||||
if ($nostrUser && Gate::forUser($nostrUser)->allows('accept', $this->project)) {
|
||||
$this->isAdmin = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteMainImage(): void
|
||||
{
|
||||
Gate::forUser(NostrAuth::user())->authorize('update', $this->project);
|
||||
|
||||
if ($this->project->getFirstMedia('main')) {
|
||||
$this->project->getFirstMedia('main')->delete();
|
||||
}
|
||||
@@ -84,6 +79,18 @@ class extends Component
|
||||
|
||||
public function update(): void
|
||||
{
|
||||
Gate::forUser(NostrAuth::user())->authorize('update', $this->project);
|
||||
|
||||
$executed = RateLimiter::attempt(
|
||||
'project-proposal-update:'.request()->ip(),
|
||||
5,
|
||||
function () {},
|
||||
);
|
||||
|
||||
if (! $executed) {
|
||||
abort(429, 'Too many requests.');
|
||||
}
|
||||
|
||||
$this->validate([
|
||||
'form.name' => 'required|string|max:255',
|
||||
'form.description' => 'required|string',
|
||||
@@ -92,13 +99,16 @@ class extends Component
|
||||
'file' => 'nullable|file|mimes:jpeg,png,jpg,gif,webp|mimetypes:image/jpeg,image/png,image/gif,image/webp|max:10240',
|
||||
]);
|
||||
|
||||
$nostrUser = NostrAuth::user();
|
||||
$canAccept = $nostrUser && Gate::forUser($nostrUser)->allows('accept', $this->project);
|
||||
|
||||
$this->project->update([
|
||||
'name' => $this->form['name'],
|
||||
'description' => $this->form['description'],
|
||||
'support_in_sats' => (int) $this->form['support_in_sats'],
|
||||
'website' => $this->form['website'],
|
||||
'accepted' => $this->isAdmin ? (bool) $this->form['accepted'] : $this->project->accepted,
|
||||
'sats_paid' => $this->isAdmin ? $this->form['sats_paid'] : $this->project->sats_paid,
|
||||
'accepted' => $canAccept ? (bool) $this->form['accepted'] : $this->project->accepted,
|
||||
'sats_paid' => $canAccept ? $this->form['sats_paid'] : $this->project->sats_paid,
|
||||
]);
|
||||
|
||||
if ($this->file) {
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Models\ProjectProposal;
|
||||
use App\Support\NostrAuth;
|
||||
use Flux\Flux;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Component;
|
||||
|
||||
@@ -31,8 +32,6 @@ new class extends Component {
|
||||
public ?ProjectProposal $projectToDelete = null;
|
||||
|
||||
protected $listeners = [
|
||||
'nostrLoggedIn' => 'handleNostrLoggedIn',
|
||||
'nostrLoggedOut' => 'handleNostrLoggedOut',
|
||||
'confirmDeleteProject' => 'confirmDeleteProject',
|
||||
];
|
||||
|
||||
@@ -79,6 +78,8 @@ new class extends Component {
|
||||
public function delete(): void
|
||||
{
|
||||
if ($this->projectToDelete) {
|
||||
Gate::forUser(NostrAuth::user())->authorize('delete', $this->projectToDelete);
|
||||
|
||||
$this->projectToDelete->delete();
|
||||
Flux::toast('Projektunterstützung gelöscht.');
|
||||
$this->loadProjects();
|
||||
@@ -112,7 +113,7 @@ new class extends Component {
|
||||
</form>
|
||||
|
||||
<!-- Add meetup button -->
|
||||
@if($currentPleb && $currentPleb->association_status->value > 1 && $currentPleb->paymentEvents()->where('year', date('Y'))->where('paid', true)->exists())
|
||||
@if(Gate::forUser(NostrAuth::user())->allows('create', App\Models\ProjectProposal::class))
|
||||
<flux:button :href="route('association.projectSupport.create')" icon="plus" variant="primary">
|
||||
Projekt einreichen
|
||||
</flux:button>
|
||||
|
||||
@@ -4,6 +4,8 @@ use App\Livewire\Traits\WithNostrAuth;
|
||||
use App\Models\ProjectProposal;
|
||||
use App\Models\Vote;
|
||||
use App\Support\NostrAuth;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Component;
|
||||
|
||||
@@ -60,10 +62,24 @@ new class extends Component {
|
||||
|
||||
public function handleApprove(): void
|
||||
{
|
||||
if (! $this->currentPleb) {
|
||||
$nostrUser = NostrAuth::user();
|
||||
|
||||
if (! $nostrUser || ! $nostrUser->getPleb()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Gate::forUser($nostrUser)->authorize('create', [Vote::class, $this->projectProposal]);
|
||||
|
||||
$executed = RateLimiter::attempt(
|
||||
'voting:'.request()->ip(),
|
||||
10,
|
||||
function () {},
|
||||
);
|
||||
|
||||
if (! $executed) {
|
||||
abort(429, 'Too many voting attempts.');
|
||||
}
|
||||
|
||||
Vote::query()->updateOrCreate([
|
||||
'project_proposal_id' => $this->projectProposal->id,
|
||||
'einundzwanzig_pleb_id' => $this->currentPleb->id,
|
||||
@@ -75,10 +91,24 @@ new class extends Component {
|
||||
|
||||
public function handleNotApprove(): void
|
||||
{
|
||||
if (! $this->currentPleb) {
|
||||
$nostrUser = NostrAuth::user();
|
||||
|
||||
if (! $nostrUser || ! $nostrUser->getPleb()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Gate::forUser($nostrUser)->authorize('create', [Vote::class, $this->projectProposal]);
|
||||
|
||||
$executed = RateLimiter::attempt(
|
||||
'voting:'.request()->ip(),
|
||||
10,
|
||||
function () {},
|
||||
);
|
||||
|
||||
if (! $executed) {
|
||||
abort(429, 'Too many voting attempts.');
|
||||
}
|
||||
|
||||
Vote::query()->updateOrCreate([
|
||||
'project_proposal_id' => $this->projectProposal->id,
|
||||
'einundzwanzig_pleb_id' => $this->currentPleb->id,
|
||||
@@ -138,7 +168,7 @@ new class extends Component {
|
||||
</div>
|
||||
|
||||
<figure class="mb-6">
|
||||
<img class="rounded-sm h-48" src="{{ $projectProposal->getSignedMediaUrl('main') }}"
|
||||
<img class="rounded-sm h-48" src="{{ $projectProposal->getSignedMediaUrl('main', 60, 'preview') }}"
|
||||
alt="Picture">
|
||||
</figure>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user