mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-nostr.git
synced 2026-03-23 19:08:41 +00:00
- ✨ Refactor edit.blade.php to handle admin-specific fields (accepted and sats_paid) through conditional logic.
- 📦 Upgrade Laravel framework, Livewire, and dependencies to ensure compatibility with version `13.1.1`.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Auth;
|
||||
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
|
||||
class NostrUser implements Authenticatable
|
||||
@@ -13,7 +14,7 @@ class NostrUser implements Authenticatable
|
||||
public function __construct(string $pubkey)
|
||||
{
|
||||
$this->pubkey = $pubkey;
|
||||
$this->pleb = \App\Models\EinundzwanzigPleb::query()
|
||||
$this->pleb = EinundzwanzigPleb::query()
|
||||
->where('pubkey', $pubkey)
|
||||
->first();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands\Nostr;
|
||||
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use App\Models\Event;
|
||||
use App\Traits\NostrEventRendererTrait;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -35,7 +36,7 @@ class FetchEvents extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$plebs = \App\Models\EinundzwanzigPleb::query()
|
||||
$plebs = EinundzwanzigPleb::query()
|
||||
->get();
|
||||
|
||||
$subscription = new Subscription;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands\Nostr;
|
||||
|
||||
use App\Models\Event;
|
||||
use App\Traits\NostrEventRendererTrait;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Broadcast;
|
||||
@@ -29,7 +30,7 @@ class RenderAllEvents extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$events = \App\Models\Event::query()
|
||||
$events = Event::query()
|
||||
->get();
|
||||
|
||||
foreach ($events as $event) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Livewire\Traits;
|
||||
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use App\Support\NostrAuth;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Livewire\Attributes\On;
|
||||
@@ -32,7 +33,7 @@ trait WithNostrAuth
|
||||
NostrAuth::login($pubkey);
|
||||
|
||||
$this->currentPubkey = $pubkey;
|
||||
$this->currentPleb = \App\Models\EinundzwanzigPleb::query()
|
||||
$this->currentPleb = EinundzwanzigPleb::query()
|
||||
->where('pubkey', $pubkey)
|
||||
->first();
|
||||
|
||||
|
||||
@@ -22,13 +22,10 @@ class ProjectProposal extends Model implements HasMedia
|
||||
|
||||
/** @var list<string> */
|
||||
protected $fillable = [
|
||||
'einundzwanzig_pleb_id',
|
||||
'name',
|
||||
'description',
|
||||
'support_in_sats',
|
||||
'website',
|
||||
'accepted',
|
||||
'sats_paid',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Auth\NostrUser;
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use App\Models\ProjectProposal;
|
||||
|
||||
class ProjectProposalPolicy
|
||||
@@ -87,7 +88,7 @@ class ProjectProposalPolicy
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \App\Models\EinundzwanzigPleb $pleb
|
||||
* @param EinundzwanzigPleb $pleb
|
||||
*/
|
||||
private function isBoardMember(object $pleb): bool
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Traits;
|
||||
|
||||
use App\Models\Profile;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use swentel\nostr\Filter\Filter;
|
||||
use swentel\nostr\Key\Key;
|
||||
use swentel\nostr\Message\RequestMessage;
|
||||
@@ -21,7 +22,7 @@ trait NostrFetcherTrait
|
||||
public function getNip05HandlesForPubkey(string $pubkey): array
|
||||
{
|
||||
try {
|
||||
$response = \Illuminate\Support\Facades\Http::get(
|
||||
$response = Http::get(
|
||||
'https://einundzwanzig.space/.well-known/nostr.json',
|
||||
);
|
||||
$data = $response->json();
|
||||
|
||||
@@ -4,6 +4,7 @@ use App\Services\SecurityMonitor;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Sentry\Laravel\Integration;
|
||||
|
||||
return Application::configure(basePath: dirname(__DIR__))
|
||||
@@ -16,7 +17,7 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
)
|
||||
->withMiddleware(function (Middleware $middleware) {
|
||||
$middleware->api(prepend: [
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
|
||||
ThrottleRequests::class.':api',
|
||||
]);
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions) {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<?php
|
||||
|
||||
use App\Providers\AppServiceProvider;
|
||||
use App\Providers\NostrAuthServiceProvider;
|
||||
|
||||
return [
|
||||
App\Providers\AppServiceProvider::class,
|
||||
AppServiceProvider::class,
|
||||
// App\Providers\FolioServiceProvider::class, // Disabled - laravel/folio package removed during Laravel 12 upgrade
|
||||
App\Providers\NostrAuthServiceProvider::class,
|
||||
NostrAuthServiceProvider::class,
|
||||
];
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
"akuechler/laravel-geoly": "^1.0",
|
||||
"archtechx/enums": "^1.1",
|
||||
"calebporzio/sushi": "^2.5",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/framework": "^13.0",
|
||||
"laravel/nightwatch": "^1.22",
|
||||
"laravel/reverb": "^1.0",
|
||||
"laravel/tinker": "^2.9",
|
||||
"laravel/tinker": "^3.0",
|
||||
"livewire/flux": "^2.10",
|
||||
"livewire/flux-pro": "^2.10",
|
||||
"livewire/livewire": "^4.0",
|
||||
@@ -27,7 +27,7 @@
|
||||
"sentry/sentry-laravel": "^4.9",
|
||||
"simplesoftwareio/simple-qrcode": "^4.2",
|
||||
"spatie/image": "^3.7",
|
||||
"spatie/laravel-backup": "^9.1",
|
||||
"spatie/laravel-backup": "^10.0",
|
||||
"spatie/laravel-ciphersweet": "^1.6",
|
||||
"spatie/laravel-google-fonts": "^1.4",
|
||||
"spatie/laravel-markdown": "^2.5",
|
||||
@@ -39,7 +39,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
"laravel/boost": "^1.8",
|
||||
"laravel/boost": "^2.0",
|
||||
"laravel/pail": "^1.2",
|
||||
"laravel/pint": "^1.13",
|
||||
"mockery/mockery": "^1.6",
|
||||
|
||||
737
composer.lock
generated
737
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
@@ -66,7 +68,7 @@ return [
|
||||
'providers' => [
|
||||
'users' => [
|
||||
'driver' => 'eloquent',
|
||||
'model' => env('AUTH_MODEL', App\Models\User::class),
|
||||
'model' => env('AUTH_MODEL', User::class),
|
||||
],
|
||||
'nostr' => [
|
||||
'driver' => 'nostr',
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
<?php
|
||||
|
||||
use Spatie\Backup\Notifications\Notifiable;
|
||||
use Spatie\Backup\Notifications\Notifications\BackupHasFailedNotification;
|
||||
use Spatie\Backup\Notifications\Notifications\BackupWasSuccessfulNotification;
|
||||
use Spatie\Backup\Notifications\Notifications\CleanupHasFailedNotification;
|
||||
use Spatie\Backup\Notifications\Notifications\CleanupWasSuccessfulNotification;
|
||||
use Spatie\Backup\Notifications\Notifications\HealthyBackupWasFoundNotification;
|
||||
use Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFoundNotification;
|
||||
use Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy;
|
||||
use Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays;
|
||||
use Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes;
|
||||
|
||||
return [
|
||||
|
||||
'backup' => [
|
||||
@@ -196,19 +207,19 @@ return [
|
||||
*/
|
||||
'notifications' => [
|
||||
'notifications' => [
|
||||
\Spatie\Backup\Notifications\Notifications\BackupHasFailedNotification::class => ['mail'],
|
||||
\Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFoundNotification::class => ['mail'],
|
||||
\Spatie\Backup\Notifications\Notifications\CleanupHasFailedNotification::class => ['mail'],
|
||||
\Spatie\Backup\Notifications\Notifications\BackupWasSuccessfulNotification::class => ['mail'],
|
||||
\Spatie\Backup\Notifications\Notifications\HealthyBackupWasFoundNotification::class => ['mail'],
|
||||
\Spatie\Backup\Notifications\Notifications\CleanupWasSuccessfulNotification::class => ['mail'],
|
||||
BackupHasFailedNotification::class => ['mail'],
|
||||
UnhealthyBackupWasFoundNotification::class => ['mail'],
|
||||
CleanupHasFailedNotification::class => ['mail'],
|
||||
BackupWasSuccessfulNotification::class => ['mail'],
|
||||
HealthyBackupWasFoundNotification::class => ['mail'],
|
||||
CleanupWasSuccessfulNotification::class => ['mail'],
|
||||
],
|
||||
|
||||
/*
|
||||
* Here you can specify the notifiable to which the notifications should be sent. The default
|
||||
* notifiable will use the variables specified in this config file.
|
||||
*/
|
||||
'notifiable' => \Spatie\Backup\Notifications\Notifiable::class,
|
||||
'notifiable' => Notifiable::class,
|
||||
|
||||
'mail' => [
|
||||
'to' => 'your@example.com',
|
||||
@@ -257,8 +268,8 @@ return [
|
||||
'name' => env('APP_NAME', 'laravel-backup'),
|
||||
'disks' => ['backups'],
|
||||
'health_checks' => [
|
||||
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1,
|
||||
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000,
|
||||
MaximumAgeInDays::class => 1,
|
||||
MaximumStorageInMegabytes::class => 5000,
|
||||
],
|
||||
],
|
||||
|
||||
@@ -284,7 +295,7 @@ return [
|
||||
* No matter how you configure it the default strategy will never
|
||||
* delete the newest backup.
|
||||
*/
|
||||
'strategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
|
||||
'strategy' => DefaultStrategy::class,
|
||||
|
||||
'default_strategy' => [
|
||||
/*
|
||||
|
||||
@@ -105,4 +105,17 @@ return [
|
||||
|
||||
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Serializable Classes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option allows you to specify which classes may be unserialized from
|
||||
| the cache to help prevent PHP deserialization gadget chain attacks.
|
||||
| Set to false to allow no classes to be unserialized from cache.
|
||||
|
|
||||
*/
|
||||
|
||||
'serializable_classes' => false,
|
||||
|
||||
];
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<?php
|
||||
|
||||
use PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v4\ExportToCsv;
|
||||
use PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v4\ExportToXLS;
|
||||
use PowerComponents\LivewirePowerGrid\Themes\Tailwind;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
@@ -11,7 +15,7 @@ return [
|
||||
| Configure here the theme of your choice.
|
||||
*/
|
||||
|
||||
'theme' => \PowerComponents\LivewirePowerGrid\Themes\Tailwind::class,
|
||||
'theme' => Tailwind::class,
|
||||
// 'theme' => \PowerComponents\LivewirePowerGrid\Themes\Bootstrap5::class,
|
||||
|
||||
/*
|
||||
@@ -130,12 +134,12 @@ return [
|
||||
'exportable' => [
|
||||
'default' => 'openspout_v4',
|
||||
'openspout_v4' => [
|
||||
'xlsx' => \PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v4\ExportToXLS::class,
|
||||
'csv' => \PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v4\ExportToCsv::class,
|
||||
'xlsx' => ExportToXLS::class,
|
||||
'csv' => ExportToCsv::class,
|
||||
],
|
||||
'openspout_v3' => [
|
||||
'xlsx' => \PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v3\ExportToXLS::class,
|
||||
'csv' => \PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v3\ExportToCsv::class,
|
||||
'xlsx' => PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v3\ExportToXLS::class,
|
||||
'csv' => PowerComponents\LivewirePowerGrid\Components\Exports\OpenSpout\v3\ExportToCsv::class,
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Spatie\LaravelMarkdown\MarkdownRenderer;
|
||||
|
||||
return [
|
||||
'code_highlighting' => [
|
||||
/*
|
||||
@@ -64,7 +66,7 @@ return [
|
||||
*
|
||||
* More info: https://spatie.be/docs/laravel-markdown/v1/advanced-usage/customizing-the-rendering-process
|
||||
*/
|
||||
'renderer_class' => Spatie\LaravelMarkdown\MarkdownRenderer::class,
|
||||
'renderer_class' => MarkdownRenderer::class,
|
||||
|
||||
/*
|
||||
* These extensions should be added to the markdown environment. A valid
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Spatie\ImageOptimizer\Optimizers\Avifenc;
|
||||
use Spatie\ImageOptimizer\Optimizers\Cwebp;
|
||||
use Spatie\ImageOptimizer\Optimizers\Gifsicle;
|
||||
use Spatie\ImageOptimizer\Optimizers\Jpegoptim;
|
||||
use Spatie\ImageOptimizer\Optimizers\Optipng;
|
||||
use Spatie\ImageOptimizer\Optimizers\Pngquant;
|
||||
use Spatie\ImageOptimizer\Optimizers\Svgo;
|
||||
use Spatie\MediaLibrary\Conversions\ImageGenerators\Avif;
|
||||
use Spatie\MediaLibrary\Conversions\ImageGenerators\Image;
|
||||
use Spatie\MediaLibrary\Conversions\ImageGenerators\Pdf;
|
||||
use Spatie\MediaLibrary\Conversions\ImageGenerators\Svg;
|
||||
use Spatie\MediaLibrary\Conversions\ImageGenerators\Video;
|
||||
use Spatie\MediaLibrary\Conversions\ImageGenerators\Webp;
|
||||
use Spatie\MediaLibrary\Conversions\Jobs\PerformConversionsJob;
|
||||
use Spatie\MediaLibrary\Downloaders\DefaultDownloader;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
use Spatie\MediaLibrary\ResponsiveImages\Jobs\GenerateResponsiveImagesJob;
|
||||
use Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred;
|
||||
use Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\FileSizeOptimizedWidthCalculator;
|
||||
use Spatie\MediaLibrary\Support\FileNamer\DefaultFileNamer;
|
||||
use Spatie\MediaLibrary\Support\FileRemover\DefaultFileRemover;
|
||||
use Spatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator;
|
||||
use Spatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator;
|
||||
use Spatie\MediaLibraryPro\Models\TemporaryUpload;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
@@ -39,7 +64,7 @@ return [
|
||||
/*
|
||||
* The fully qualified class name of the media model.
|
||||
*/
|
||||
'media_model' => Spatie\MediaLibrary\MediaCollections\Models\Media::class,
|
||||
'media_model' => Media::class,
|
||||
|
||||
/*
|
||||
* When enabled, media collections will be serialised using the default
|
||||
@@ -54,7 +79,7 @@ return [
|
||||
*
|
||||
* This model is only used in Media Library Pro (https://medialibrary.pro)
|
||||
*/
|
||||
'temporary_upload_model' => Spatie\MediaLibraryPro\Models\TemporaryUpload::class,
|
||||
'temporary_upload_model' => TemporaryUpload::class,
|
||||
|
||||
/*
|
||||
* When enabled, Media Library Pro will only process temporary uploads that were uploaded
|
||||
@@ -71,17 +96,17 @@ return [
|
||||
/*
|
||||
* This is the class that is responsible for naming generated files.
|
||||
*/
|
||||
'file_namer' => Spatie\MediaLibrary\Support\FileNamer\DefaultFileNamer::class,
|
||||
'file_namer' => DefaultFileNamer::class,
|
||||
|
||||
/*
|
||||
* The class that contains the strategy for determining a media file's path.
|
||||
*/
|
||||
'path_generator' => Spatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator::class,
|
||||
'path_generator' => DefaultPathGenerator::class,
|
||||
|
||||
/*
|
||||
* The class that contains the strategy for determining how to remove files.
|
||||
*/
|
||||
'file_remover_class' => Spatie\MediaLibrary\Support\FileRemover\DefaultFileRemover::class,
|
||||
'file_remover_class' => DefaultFileRemover::class,
|
||||
|
||||
/*
|
||||
* Here you can specify which path generator should be used for the given class.
|
||||
@@ -96,7 +121,7 @@ return [
|
||||
* When urls to files get generated, this class will be called. Use the default
|
||||
* if your files are stored locally above the site root or on s3.
|
||||
*/
|
||||
'url_generator' => Spatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator::class,
|
||||
'url_generator' => DefaultUrlGenerator::class,
|
||||
|
||||
/*
|
||||
* Moves media on updating to keep path consistent. Enable it only with a custom
|
||||
@@ -116,34 +141,34 @@ return [
|
||||
* the optimizers that will be used by default.
|
||||
*/
|
||||
'image_optimizers' => [
|
||||
Spatie\ImageOptimizer\Optimizers\Jpegoptim::class => [
|
||||
Jpegoptim::class => [
|
||||
'-m85', // set maximum quality to 85%
|
||||
'--force', // ensure that progressive generation is always done also if a little bigger
|
||||
'--strip-all', // this strips out all text information such as comments and EXIF data
|
||||
'--all-progressive', // this will make sure the resulting image is a progressive one
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Pngquant::class => [
|
||||
Pngquant::class => [
|
||||
'--force', // required parameter for this package
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Optipng::class => [
|
||||
Optipng::class => [
|
||||
'-i0', // this will result in a non-interlaced, progressive scanned image
|
||||
'-o2', // this set the optimization level to two (multiple IDAT compression trials)
|
||||
'-quiet', // required parameter for this package
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Svgo::class => [
|
||||
Svgo::class => [
|
||||
'--disable=cleanupIDs', // disabling because it is known to cause troubles
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Gifsicle::class => [
|
||||
Gifsicle::class => [
|
||||
'-b', // required parameter for this package
|
||||
'-O3', // this produces the slowest but best results
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Cwebp::class => [
|
||||
Cwebp::class => [
|
||||
'-m 6', // for the slowest compression method in order to get the best compression.
|
||||
'-pass 10', // for maximizing the amount of analysis pass.
|
||||
'-mt', // multithreading for some speed improvements.
|
||||
'-q 90', // quality factor that brings the least noticeable changes.
|
||||
],
|
||||
Spatie\ImageOptimizer\Optimizers\Avifenc::class => [
|
||||
Avifenc::class => [
|
||||
'-a cq-level=23', // constant quality level, lower values mean better quality and greater file size (0-63).
|
||||
'-j all', // number of jobs (worker threads, "all" uses all available cores).
|
||||
'--min 0', // min quantizer for color (0-63).
|
||||
@@ -159,12 +184,12 @@ return [
|
||||
* These generators will be used to create an image of media files.
|
||||
*/
|
||||
'image_generators' => [
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Image::class,
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Webp::class,
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Avif::class,
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Pdf::class,
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Svg::class,
|
||||
Spatie\MediaLibrary\Conversions\ImageGenerators\Video::class,
|
||||
Image::class,
|
||||
Webp::class,
|
||||
Avif::class,
|
||||
Pdf::class,
|
||||
Svg::class,
|
||||
Video::class,
|
||||
],
|
||||
|
||||
/*
|
||||
@@ -192,8 +217,8 @@ return [
|
||||
* your custom jobs extend the ones provided by the package.
|
||||
*/
|
||||
'jobs' => [
|
||||
'perform_conversions' => Spatie\MediaLibrary\Conversions\Jobs\PerformConversionsJob::class,
|
||||
'generate_responsive_images' => Spatie\MediaLibrary\ResponsiveImages\Jobs\GenerateResponsiveImagesJob::class,
|
||||
'perform_conversions' => PerformConversionsJob::class,
|
||||
'generate_responsive_images' => GenerateResponsiveImagesJob::class,
|
||||
],
|
||||
|
||||
/*
|
||||
@@ -201,7 +226,7 @@ return [
|
||||
* This is particularly useful when the url of the image is behind a firewall and
|
||||
* need to add additional flags, possibly using curl.
|
||||
*/
|
||||
'media_downloader' => Spatie\MediaLibrary\Downloaders\DefaultDownloader::class,
|
||||
'media_downloader' => DefaultDownloader::class,
|
||||
|
||||
/*
|
||||
* When using the addMediaFromUrl method the SSL is verified by default.
|
||||
@@ -232,7 +257,7 @@ return [
|
||||
*
|
||||
* https://docs.spatie.be/laravel-medialibrary/v9/advanced-usage/generating-responsive-images
|
||||
*/
|
||||
'width_calculator' => Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\FileSizeOptimizedWidthCalculator::class,
|
||||
'width_calculator' => FileSizeOptimizedWidthCalculator::class,
|
||||
|
||||
/*
|
||||
* By default rendering media to a responsive image will add some javascript and a tiny placeholder.
|
||||
@@ -245,7 +270,7 @@ return [
|
||||
* This class will generate the tiny placeholder used for progressive image loading. By default
|
||||
* the media library will use a tiny blurred jpg image.
|
||||
*/
|
||||
'tiny_placeholder_generator' => Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\Blurred::class,
|
||||
'tiny_placeholder_generator' => Blurred::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Enums\AssociationStatus;
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\EinundzwanzigPleb>
|
||||
* @extends Factory<EinundzwanzigPleb>
|
||||
*/
|
||||
class EinundzwanzigPlebFactory extends Factory
|
||||
{
|
||||
@@ -20,14 +22,14 @@ class EinundzwanzigPlebFactory extends Factory
|
||||
'pubkey' => $this->faker->sha256(),
|
||||
'npub' => $this->faker->word(),
|
||||
'email' => $this->faker->safeEmail(),
|
||||
'association_status' => \App\Enums\AssociationStatus::DEFAULT,
|
||||
'association_status' => AssociationStatus::DEFAULT,
|
||||
];
|
||||
}
|
||||
|
||||
public function active(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'association_status' => \App\Enums\AssociationStatus::ACTIVE,
|
||||
'association_status' => AssociationStatus::ACTIVE,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -35,13 +37,13 @@ class EinundzwanzigPlebFactory extends Factory
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'npub' => config('einundzwanzig.config.current_board')[0],
|
||||
'association_status' => \App\Enums\AssociationStatus::HONORARY,
|
||||
'association_status' => AssociationStatus::HONORARY,
|
||||
]);
|
||||
}
|
||||
|
||||
public function withPaidCurrentYear(): static
|
||||
{
|
||||
return $this->afterCreating(function (\App\Models\EinundzwanzigPleb $pleb) {
|
||||
return $this->afterCreating(function (EinundzwanzigPleb $pleb) {
|
||||
$pleb->paymentEvents()->create([
|
||||
'year' => date('Y'),
|
||||
'amount' => 21000,
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Election;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Election>
|
||||
* @extends Factory<Election>
|
||||
*/
|
||||
class ElectionFactory extends Factory
|
||||
{
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Enums\NewsCategory;
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use App\Models\Notification;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Notification>
|
||||
* @extends Factory<Notification>
|
||||
*/
|
||||
class NotificationFactory extends Factory
|
||||
{
|
||||
@@ -19,8 +22,8 @@ class NotificationFactory extends Factory
|
||||
return [
|
||||
'name' => $this->faker->sentence(3),
|
||||
'description' => $this->faker->paragraph(),
|
||||
'category' => $this->faker->randomElement(\App\Enums\NewsCategory::cases()),
|
||||
'einundzwanzig_pleb_id' => \App\Models\EinundzwanzigPleb::factory(),
|
||||
'category' => $this->faker->randomElement(NewsCategory::cases()),
|
||||
'einundzwanzig_pleb_id' => EinundzwanzigPleb::factory(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,19 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use App\Models\PaymentEvent;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\PaymentEvent>
|
||||
* @extends Factory<PaymentEvent>
|
||||
*/
|
||||
class PaymentEventFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'einundzwanzig_pleb_id' => \App\Models\EinundzwanzigPleb::factory(),
|
||||
'einundzwanzig_pleb_id' => EinundzwanzigPleb::factory(),
|
||||
'year' => fake()->year(),
|
||||
'event_id' => fake()->uuid(),
|
||||
'amount' => 21000,
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use App\Models\ProjectProposal;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\ProjectProposal>
|
||||
* @extends Factory<ProjectProposal>
|
||||
*/
|
||||
class ProjectProposalFactory extends Factory
|
||||
{
|
||||
@@ -17,7 +19,7 @@ class ProjectProposalFactory extends Factory
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'einundzwanzig_pleb_id' => \App\Models\EinundzwanzigPleb::factory(),
|
||||
'einundzwanzig_pleb_id' => EinundzwanzigPleb::factory(),
|
||||
'name' => $this->faker->sentence(3),
|
||||
'description' => $this->faker->paragraph(),
|
||||
'support_in_sats' => $this->faker->numberBetween(10000, 1000000),
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
|
||||
* @extends Factory<User>
|
||||
*/
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
|
||||
@@ -107,10 +107,15 @@ class extends Component
|
||||
'description' => $this->form['description'],
|
||||
'support_in_sats' => (int) $this->form['support_in_sats'],
|
||||
'website' => $this->form['website'],
|
||||
'accepted' => $canAccept ? (bool) $this->form['accepted'] : $this->project->accepted,
|
||||
'sats_paid' => $canAccept ? $this->form['sats_paid'] : $this->project->sats_paid,
|
||||
]);
|
||||
|
||||
// Update admin-only fields directly if user has permission
|
||||
if ($canAccept) {
|
||||
$this->project->accepted = (bool) $this->form['accepted'];
|
||||
$this->project->sats_paid = $this->form['sats_paid'];
|
||||
$this->project->save();
|
||||
}
|
||||
|
||||
if ($this->file) {
|
||||
$this->project->addMedia($this->file)->toMediaCollection('main');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Support\NostrAuth;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
@@ -41,7 +42,7 @@ Route::get('media/{media}', function (Media $media, Request $request) {
|
||||
->middleware('signed');
|
||||
|
||||
Route::post('logout', function () {
|
||||
\App\Support\NostrAuth::logout();
|
||||
NostrAuth::logout();
|
||||
Session::flush();
|
||||
|
||||
return redirect('/');
|
||||
|
||||
@@ -22,15 +22,15 @@ beforeEach(function () {
|
||||
'event_id' => 'test_event_'.Str::random(40),
|
||||
]);
|
||||
|
||||
$this->project = ProjectProposal::query()->create([
|
||||
'einundzwanzig_pleb_id' => $this->pleb->id,
|
||||
'name' => 'Original Project',
|
||||
'description' => 'Original Description',
|
||||
'support_in_sats' => 21000,
|
||||
'website' => 'https://original.example.com',
|
||||
'accepted' => false,
|
||||
'sats_paid' => 0,
|
||||
]);
|
||||
$this->project = new ProjectProposal;
|
||||
$this->project->einundzwanzig_pleb_id = $this->pleb->id;
|
||||
$this->project->name = 'Original Project';
|
||||
$this->project->description = 'Original Description';
|
||||
$this->project->support_in_sats = 21000;
|
||||
$this->project->website = 'https://original.example.com';
|
||||
$this->project->accepted = false;
|
||||
$this->project->sats_paid = 0;
|
||||
$this->project->save();
|
||||
|
||||
// Get board member pubkeys from config
|
||||
$this->boardMember = EinundzwanzigPleb::query()->create([
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Models\ProjectProposal;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
it('serves original media via signed route', function () {
|
||||
@@ -9,7 +10,7 @@ it('serves original media via signed route', function () {
|
||||
$project = ProjectProposal::factory()->create();
|
||||
|
||||
$project->addMedia(
|
||||
\Illuminate\Http\UploadedFile::fake()->image('test.jpg', 100, 100)
|
||||
UploadedFile::fake()->image('test.jpg', 100, 100)
|
||||
)->toMediaCollection('main');
|
||||
|
||||
$media = $project->getFirstMedia('main');
|
||||
@@ -25,7 +26,7 @@ it('serves conversion media via signed route when conversion parameter is provid
|
||||
$project = ProjectProposal::factory()->create();
|
||||
|
||||
$project->addMedia(
|
||||
\Illuminate\Http\UploadedFile::fake()->image('test.jpg', 500, 500)
|
||||
UploadedFile::fake()->image('test.jpg', 500, 500)
|
||||
)->toMediaCollection('main');
|
||||
|
||||
$media = $project->getFirstMedia('main');
|
||||
@@ -44,7 +45,7 @@ it('falls back to original when conversion does not exist', function () {
|
||||
$project = ProjectProposal::factory()->create();
|
||||
|
||||
$project->addMedia(
|
||||
\Illuminate\Http\UploadedFile::fake()->image('test.jpg', 100, 100)
|
||||
UploadedFile::fake()->image('test.jpg', 100, 100)
|
||||
)->toMediaCollection('main');
|
||||
|
||||
$media = $project->getFirstMedia('main');
|
||||
@@ -63,7 +64,7 @@ it('rejects unsigned media requests', function () {
|
||||
$project = ProjectProposal::factory()->create();
|
||||
|
||||
$project->addMedia(
|
||||
\Illuminate\Http\UploadedFile::fake()->image('test.jpg', 100, 100)
|
||||
UploadedFile::fake()->image('test.jpg', 100, 100)
|
||||
)->toMediaCollection('main');
|
||||
|
||||
$media = $project->getFirstMedia('main');
|
||||
@@ -77,7 +78,7 @@ it('generates signed url with conversion parameter', function () {
|
||||
$project = ProjectProposal::factory()->create();
|
||||
|
||||
$project->addMedia(
|
||||
\Illuminate\Http\UploadedFile::fake()->image('test.jpg', 500, 500)
|
||||
UploadedFile::fake()->image('test.jpg', 500, 500)
|
||||
)->toMediaCollection('main');
|
||||
|
||||
$urlWithoutConversion = $project->getSignedMediaUrl('main');
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Auth\NostrUser;
|
||||
use App\Enums\AssociationStatus;
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use App\Models\Election;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
@@ -77,7 +78,7 @@ it('allows active member to vote in an election', function () {
|
||||
|
||||
it('allows honorary member to vote in an election', function () {
|
||||
$pleb = EinundzwanzigPleb::factory()->create([
|
||||
'association_status' => \App\Enums\AssociationStatus::HONORARY,
|
||||
'association_status' => AssociationStatus::HONORARY,
|
||||
]);
|
||||
$election = Election::factory()->create();
|
||||
$nostrUser = new NostrUser($pleb->pubkey);
|
||||
@@ -87,7 +88,7 @@ it('allows honorary member to vote in an election', function () {
|
||||
|
||||
it('denies passive member from voting in an election', function () {
|
||||
$pleb = EinundzwanzigPleb::factory()->create([
|
||||
'association_status' => \App\Enums\AssociationStatus::PASSIVE,
|
||||
'association_status' => AssociationStatus::PASSIVE,
|
||||
]);
|
||||
$election = Election::factory()->create();
|
||||
$nostrUser = new NostrUser($pleb->pubkey);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Auth\NostrUser;
|
||||
use App\Enums\AssociationStatus;
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use App\Models\ProjectProposal;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
@@ -48,7 +49,7 @@ it('denies creation for active member without paid membership', function () {
|
||||
|
||||
it('denies creation for passive member without paid membership', function () {
|
||||
$pleb = EinundzwanzigPleb::factory()->create([
|
||||
'association_status' => \App\Enums\AssociationStatus::PASSIVE,
|
||||
'association_status' => AssociationStatus::PASSIVE,
|
||||
]);
|
||||
$nostrUser = new NostrUser($pleb->pubkey);
|
||||
|
||||
@@ -57,7 +58,7 @@ it('denies creation for passive member without paid membership', function () {
|
||||
|
||||
it('allows passive member with paid membership to create project proposals', function () {
|
||||
$pleb = EinundzwanzigPleb::factory()->withPaidCurrentYear()->create([
|
||||
'association_status' => \App\Enums\AssociationStatus::PASSIVE,
|
||||
'association_status' => AssociationStatus::PASSIVE,
|
||||
]);
|
||||
$nostrUser = new NostrUser($pleb->pubkey);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use App\Models\EinundzwanzigPleb;
|
||||
use App\Models\ProjectProposal;
|
||||
use App\Models\Vote;
|
||||
use App\Support\NostrAuth;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Livewire\Livewire;
|
||||
@@ -46,7 +47,7 @@ test('voting actions are rate limited after 10 attempts', function () {
|
||||
RateLimiter::attempt('voting:127.0.0.1', 10, function () {});
|
||||
}
|
||||
|
||||
Livewire::test('association.project-support.show', ['projectProposal' => $project->slug])
|
||||
Livewire::test('association.project-support.show', ['projectProposal' => $project])
|
||||
->call('handleApprove')
|
||||
->assertStatus(429);
|
||||
});
|
||||
@@ -93,7 +94,7 @@ test('project proposal update is rate limited after 5 attempts', function () {
|
||||
RateLimiter::attempt('project-proposal-update:127.0.0.1', 5, function () {});
|
||||
}
|
||||
|
||||
Livewire::test('association.project-support.form.edit', ['projectProposal' => $project->slug])
|
||||
Livewire::test('association.project-support.form.edit', ['projectProposal' => $project])
|
||||
->set('form.name', 'Updated Name')
|
||||
->call('update')
|
||||
->assertStatus(429);
|
||||
@@ -105,11 +106,11 @@ test('voting works within rate limit', function () {
|
||||
|
||||
NostrAuth::login($pleb->pubkey);
|
||||
|
||||
Livewire::test('association.project-support.show', ['projectProposal' => $project->slug])
|
||||
Livewire::test('association.project-support.show', ['projectProposal' => $project])
|
||||
->call('handleApprove')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$vote = \App\Models\Vote::query()
|
||||
$vote = Vote::query()
|
||||
->where('project_proposal_id', $project->id)
|
||||
->where('einundzwanzig_pleb_id', $pleb->id)
|
||||
->first();
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Test Case
|
||||
@@ -12,8 +15,8 @@
|
||||
*/
|
||||
|
||||
uses(
|
||||
Tests\TestCase::class,
|
||||
Illuminate\Foundation\Testing\RefreshDatabase::class,
|
||||
TestCase::class,
|
||||
RefreshDatabase::class,
|
||||
)->in('Feature');
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user