From 6a103cee972789430edba89150e29576e669347d Mon Sep 17 00:00:00 2001 From: Roardom Date: Sat, 25 Jan 2025 09:41:14 +0000 Subject: [PATCH] refactor: use laravel notifications for system user private messages --- .../Commands/AutoRemoveExpiredDonors.php | 10 ++- .../Commands/AutoRemovePersonalFreeleech.php | 9 +-- .../Commands/AutoRewardResurrection.php | 6 +- app/Http/Controllers/TorrentController.php | 13 ++-- .../Controllers/User/ApikeyController.php | 6 +- .../Controllers/User/PasskeyController.php | 6 +- .../Controllers/User/PasswordController.php | 6 +- .../Controllers/User/RsskeyController.php | 6 +- .../User/TransactionController.php | 7 +- .../Controllers/User/WarningController.php | 18 ++--- app/Http/Livewire/SimilarTorrent.php | 19 +---- app/Http/Livewire/UserWarnings.php | 30 +++----- .../SystemNotificationInterface.php | 27 +++++++ app/Listeners/RegisteredListener.php | 6 +- app/Models/User.php | 26 ------- app/Notifications/ApikeyReset.php | 52 ++++++++++++++ .../Channels/SystemNotificationChannel.php | 43 +++++++++++ app/Notifications/DonationExpired.php | 52 ++++++++++++++ app/Notifications/NewWelcome.php | 52 ++++++++++++++ app/Notifications/PasskeyReset.php | 52 ++++++++++++++ app/Notifications/PasswordUpdate.php | 52 ++++++++++++++ .../PersonalFreeleechCreated.php | 52 ++++++++++++++ .../PersonalFreeleechDeleted.php | 52 ++++++++++++++ app/Notifications/ResurrectionCompleted.php | 59 +++++++++++++++ app/Notifications/RsskeyReset.php | 52 ++++++++++++++ app/Notifications/TorrentDeleted.php | 63 ++++++++++++++++ app/Notifications/TorrentsDeleted.php | 71 +++++++++++++++++++ app/Notifications/WarningCreated.php | 56 +++++++++++++++ app/Notifications/WarningDeactivated.php | 57 +++++++++++++++ app/Notifications/WarningTorrentDeleted.php | 57 +++++++++++++++ app/Notifications/WarningsDeactivated.php | 56 +++++++++++++++ app/Notifications/WarningsDeleted.php | 56 +++++++++++++++ 32 files changed, 1007 insertions(+), 122 deletions(-) create mode 100644 app/Interfaces/SystemNotificationInterface.php create mode 100644 app/Notifications/ApikeyReset.php create mode 100644 app/Notifications/Channels/SystemNotificationChannel.php create mode 100644 app/Notifications/DonationExpired.php create mode 100644 app/Notifications/NewWelcome.php create mode 100644 app/Notifications/PasskeyReset.php create mode 100644 app/Notifications/PasswordUpdate.php create mode 100644 app/Notifications/PersonalFreeleechCreated.php create mode 100644 app/Notifications/PersonalFreeleechDeleted.php create mode 100644 app/Notifications/ResurrectionCompleted.php create mode 100644 app/Notifications/RsskeyReset.php create mode 100644 app/Notifications/TorrentDeleted.php create mode 100644 app/Notifications/TorrentsDeleted.php create mode 100644 app/Notifications/WarningCreated.php create mode 100644 app/Notifications/WarningDeactivated.php create mode 100644 app/Notifications/WarningTorrentDeleted.php create mode 100644 app/Notifications/WarningsDeactivated.php create mode 100644 app/Notifications/WarningsDeleted.php diff --git a/app/Console/Commands/AutoRemoveExpiredDonors.php b/app/Console/Commands/AutoRemoveExpiredDonors.php index 0908856f2..85a34d63c 100644 --- a/app/Console/Commands/AutoRemoveExpiredDonors.php +++ b/app/Console/Commands/AutoRemoveExpiredDonors.php @@ -17,10 +17,12 @@ declare(strict_types=1); namespace App\Console\Commands; use App\Models\User; +use App\Notifications\DonationExpired; use App\Services\Unit3dAnnounce; use Exception; use Illuminate\Console\Command; use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Notification; use Throwable; class AutoRemoveExpiredDonors extends Command @@ -53,16 +55,12 @@ class AutoRemoveExpiredDonors extends Command $query->where('ends_at', '>', Carbon::now()); })->get(); + Notification::send($expiredDonors, new DonationExpired()); + foreach ($expiredDonors as $user) { $user->is_donor = false; $user->save(); - User::sendSystemNotificationTo( - userId: $user->id, - subject: 'Your Donor Status Has Expired', - message: 'Your donor status has expired. Feel free to donate again to regain your donor status. Thank you for your support!', - ); - cache()->forget('user:'.$user->passkey); Unit3dAnnounce::addUser($user); } diff --git a/app/Console/Commands/AutoRemovePersonalFreeleech.php b/app/Console/Commands/AutoRemovePersonalFreeleech.php index 53dba1ef5..115011c90 100644 --- a/app/Console/Commands/AutoRemovePersonalFreeleech.php +++ b/app/Console/Commands/AutoRemovePersonalFreeleech.php @@ -18,10 +18,12 @@ namespace App\Console\Commands; use App\Models\PersonalFreeleech; use App\Models\User; +use App\Notifications\PersonalFreeleechDeleted; use App\Services\Unit3dAnnounce; use Exception; use Illuminate\Console\Command; use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Notification; use Throwable; class AutoRemovePersonalFreeleech extends Command @@ -51,12 +53,7 @@ class AutoRemovePersonalFreeleech extends Command $personalFreeleech = PersonalFreeleech::where('created_at', '<', $current->copy()->subDays(1))->get(); foreach ($personalFreeleech as $pfl) { - // Send Private Message - User::sendSystemNotificationTo( - userId: $pfl->user_id, - subject: 'Personal 24 Hour Freeleech Expired', - message: 'Your [b]Personal 24 Hour Freeleech[/b] has expired! Feel free to reenable it in the BON Store!', - ); + Notification::send(new User(['id' => $pfl->user_id]), new PersonalFreeleechDeleted()); // Delete The Record From DB $pfl->delete(); diff --git a/app/Console/Commands/AutoRewardResurrection.php b/app/Console/Commands/AutoRewardResurrection.php index 0fd065edc..0263f2a4a 100644 --- a/app/Console/Commands/AutoRewardResurrection.php +++ b/app/Console/Commands/AutoRewardResurrection.php @@ -17,6 +17,7 @@ declare(strict_types=1); namespace App\Console\Commands; use App\Models\Resurrection; +use App\Notifications\ResurrectionCompleted; use App\Repositories\ChatRepository; use App\Services\Unit3dAnnounce; use Exception; @@ -96,10 +97,7 @@ class AutoRewardResurrection extends Command Unit3dAnnounce::addTorrent($resurrection->torrent); // Send Private Message - $resurrection->user->sendSystemNotification( - subject: 'Successful Graveyard Resurrection', - message: \sprintf('You have successfully resurrected [url=%s/torrents/', $appurl).$resurrection->torrent->id.']'.$resurrection->torrent->name.'[/url] ! Thank you for bringing a torrent back from the dead! Enjoy the freeleech tokens!', - ); + $resurrection->user->notify(new ResurrectionCompleted($resurrection->torrent)); } }); diff --git a/app/Http/Controllers/TorrentController.php b/app/Http/Controllers/TorrentController.php index 82042124f..76feed268 100644 --- a/app/Http/Controllers/TorrentController.php +++ b/app/Http/Controllers/TorrentController.php @@ -37,6 +37,7 @@ use App\Models\TorrentFile; use App\Models\Tv; use App\Models\Type; use App\Models\User; +use App\Notifications\TorrentDeleted; use App\Repositories\ChatRepository; use App\Services\Tmdb\TMDBScraper; use App\Services\Unit3dAnnounce; @@ -46,6 +47,7 @@ use Intervention\Image\Facades\Image; use MarcReichel\IGDBLaravel\Models\Game; use MarcReichel\IGDBLaravel\Models\PlatformLogo; use Exception; +use Illuminate\Support\Facades\Notification; use ReflectionException; use JsonException; @@ -298,13 +300,10 @@ class TorrentController extends Controller abort_unless($user->group->is_modo || ($user->id === $torrent->user_id && Carbon::now()->lt($torrent->created_at->addDay())), 403); - foreach (History::where('torrent_id', '=', $torrent->id)->pluck('user_id') as $user_id) { - User::sendSystemNotificationTo( - userId: $user_id, - subject: 'Torrent Deleted! - '.$torrent->name, - message: '[b]Attention:[/b] Torrent '.$torrent->name." has been removed from our site. Our system shows that you were either the uploader, a seeder or a leecher on said torrent. We just wanted to let you know you can safely remove it from your client.\n\n[b]Removal Reason:[/b] ".$request->message, - ); - } + Notification::send( + User::query()->whereHas('history', fn ($query) => $query->where('torrent_id', '=', $torrent->id))->get(), + new TorrentDeleted($torrent, $request->message), + ); // Reset Requests $torrent->requests()->update([ diff --git a/app/Http/Controllers/User/ApikeyController.php b/app/Http/Controllers/User/ApikeyController.php index eaf248156..08da42151 100644 --- a/app/Http/Controllers/User/ApikeyController.php +++ b/app/Http/Controllers/User/ApikeyController.php @@ -18,6 +18,7 @@ namespace App\Http\Controllers\User; use App\Http\Controllers\Controller; use App\Models\User; +use App\Notifications\ApikeyReset; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; @@ -45,10 +46,7 @@ class ApikeyController extends Controller $user->apikeys()->create(['content' => $user->api_token]); if ($changedByStaff) { - $user->sendSystemNotification( - subject: 'ATTENTION - Your API key has been reset', - message: "Your API key has been reset by staff. You will need to update your API key in all your scripts to continue using the API.\n\nFor more information, please create a helpdesk ticket.", - ); + $user->notify(new ApikeyReset()); } }); diff --git a/app/Http/Controllers/User/PasskeyController.php b/app/Http/Controllers/User/PasskeyController.php index cc5cf090b..e2e0cb272 100644 --- a/app/Http/Controllers/User/PasskeyController.php +++ b/app/Http/Controllers/User/PasskeyController.php @@ -18,6 +18,7 @@ namespace App\Http\Controllers\User; use App\Http\Controllers\Controller; use App\Models\User; +use App\Notifications\PasskeyReset; use App\Services\Unit3dAnnounce; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; @@ -62,10 +63,7 @@ class PasskeyController extends Controller $user->passkeys()->create(['content' => $user->passkey]); if ($changedByStaff) { - $user->sendSystemNotification( - subject: 'ATTENTION - Your passkey has been reset', - message: "Your passkey has been reset by staff. You will need to update your passkey in all your torrent clients to continue seeding.\n\nFor more information, please create a helpdesk ticket.", - ); + $user->notify(new PasskeyReset()); } }); diff --git a/app/Http/Controllers/User/PasswordController.php b/app/Http/Controllers/User/PasswordController.php index 507371257..b5827f063 100644 --- a/app/Http/Controllers/User/PasswordController.php +++ b/app/Http/Controllers/User/PasswordController.php @@ -18,6 +18,7 @@ namespace App\Http\Controllers\User; use App\Http\Controllers\Controller; use App\Models\User; +use App\Notifications\PasswordUpdate; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; @@ -57,10 +58,7 @@ class PasswordController extends Controller $user->passwordResetHistories()->create(); if ($changedByStaff) { - $user->sendSystemNotification( - subject: 'ATTENTION - Your password has been changed', - message: "Your password has been changed by staff. You will need to update your password manager with the new password.\n\nFor more information, please create a helpdesk ticket.", - ); + $user->notify(new PasswordUpdate()); } }); diff --git a/app/Http/Controllers/User/RsskeyController.php b/app/Http/Controllers/User/RsskeyController.php index 69b9cb946..303e56b94 100644 --- a/app/Http/Controllers/User/RsskeyController.php +++ b/app/Http/Controllers/User/RsskeyController.php @@ -18,6 +18,7 @@ namespace App\Http\Controllers\User; use App\Http\Controllers\Controller; use App\Models\User; +use App\Notifications\RsskeyReset; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; @@ -44,10 +45,7 @@ class RsskeyController extends Controller $user->rsskeys()->create(['content' => $user->rsskey]); if ($changedByStaff) { - $user->sendSystemNotification( - subject: 'ATTENTION - Your RSS key has been reset', - message: "Your RSS key has been reset by staff. You will need to update your RSS key in your torrent client to continue receiving new torrents.\n\nFor more information, please create a helpdesk ticket.", - ); + $user->notify(new RsskeyReset()); } }); diff --git a/app/Http/Controllers/User/TransactionController.php b/app/Http/Controllers/User/TransactionController.php index 76bd1cf17..dce62bf6a 100644 --- a/app/Http/Controllers/User/TransactionController.php +++ b/app/Http/Controllers/User/TransactionController.php @@ -22,9 +22,9 @@ use App\Models\BonExchange; use App\Models\BonTransactions; use App\Models\PersonalFreeleech; use App\Models\User; +use App\Notifications\PersonalFreeleechCreated; use App\Services\Unit3dAnnounce; use Illuminate\Http\Request; -use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; /** @@ -97,10 +97,7 @@ class TransactionController extends Controller Unit3dAnnounce::addPersonalFreeleech($user->id); - $user->sendSystemNotification( - subject: trans('bon.pm-subject'), - message: \sprintf(trans('bon.pm-message'), Carbon::now()->addDays(1)->toDayDateTimeString()).config('app.timezone').'[/b]!', - ); + $user->notify(new PersonalFreeleechCreated()); break; case $bonExchange->invite: diff --git a/app/Http/Controllers/User/WarningController.php b/app/Http/Controllers/User/WarningController.php index 7c5d0208b..b3e487da9 100644 --- a/app/Http/Controllers/User/WarningController.php +++ b/app/Http/Controllers/User/WarningController.php @@ -19,6 +19,9 @@ namespace App\Http\Controllers\User; use App\Http\Controllers\Controller; use App\Models\User; use App\Models\Warning; +use App\Notifications\WarningCreated; +use App\Notifications\WarningTorrentDeleted; +use App\Notifications\WarningsDeleted; use Illuminate\Http\Request; use Exception; use Illuminate\Support\Carbon; @@ -44,10 +47,7 @@ class WarningController extends Controller 'active' => true, ]); - $user->sendSystemNotification( - subject: 'Received warning', - message: 'You have received a [b]warning[/b]. Reason: '.$request->string('message'), - ); + $user->notify(new WarningCreated($request->string('message')->toString())); return to_route('users.show', ['user' => $user]) ->with('success', 'Warning issued successfully!'); @@ -65,10 +65,7 @@ class WarningController extends Controller $staff = $request->user(); - $user->sendSystemNotification( - subject: 'Hit and Run Warning Deleted', - message: $staff->username.' has decided to delete your warning for torrent '.$warning->torrent.' You lucked out!', - ); + $user->notify(new WarningTorrentDeleted($staff, $warning)); $warning->update([ 'deleted_by' => $staff->id, @@ -95,10 +92,7 @@ class WarningController extends Controller $user->warnings()->delete(); - $user->sendSystemNotification( - subject: 'All Hit and Run Warnings Deleted', - message: $staff->username.' has decided to delete all of your warnings. You lucked out!', - ); + $user->notify(new WarningsDeleted($staff)); return to_route('users.show', ['user' => $user]) ->with('success', 'All Warnings Were Successfully Deleted'); diff --git a/app/Http/Livewire/SimilarTorrent.php b/app/Http/Livewire/SimilarTorrent.php index 6d20aff7a..713a1be38 100644 --- a/app/Http/Livewire/SimilarTorrent.php +++ b/app/Http/Livewire/SimilarTorrent.php @@ -27,10 +27,11 @@ use App\Models\Torrent; use App\Models\TorrentRequest; use App\Models\Tv; use App\Models\Type; -use App\Models\User; +use App\Notifications\TorrentsDeleted; use App\Services\Unit3dAnnounce; use App\Traits\CastLivewireProperties; use App\Traits\LivewireSort; +use Illuminate\Support\Facades\Notification; use Livewire\Attributes\Computed; use Livewire\Attributes\Url; use Livewire\Component; @@ -420,7 +421,6 @@ class SimilarTorrent extends Component } $torrents = Torrent::whereKey($this->checked)->get(); - $names = []; $users = []; $title = match (true) { $this->category->movie_meta => ($movie = Movie::find($this->tmdbId))->title.' ('.$movie->release_date->format('Y').')', @@ -430,8 +430,6 @@ class SimilarTorrent extends Component }; foreach ($torrents as $torrent) { - $names[] = $torrent->name; - foreach (History::where('torrent_id', '=', $torrent->id)->get() as $pm) { if (!\in_array($pm->user_id, $users)) { $users[] = $pm->user_id; @@ -471,18 +469,7 @@ class SimilarTorrent extends Component $torrent->delete(); } - foreach ($users as $user) { - User::sendSystemNotificationTo( - userId: $user, - subject: 'Bulk Torrents Deleted - '.$title.'! ', - message: '[b]Attention: [/b] The following torrents have been removed from our site. - [list] - [*]'.implode(' [*]', $names).' - [/list] - Our system shows that you were either the uploader, a seeder or a leecher on said torrent. We just wanted to let you know you can safely remove it from your client. - [b]Removal Reason: [/b] '.$this->reason, - ); - } + Notification::send($users, new TorrentsDeleted($torrents, $title, $this->reason)); $this->checked = []; $this->selectPage = false; diff --git a/app/Http/Livewire/UserWarnings.php b/app/Http/Livewire/UserWarnings.php index 18066f931..12e2cca83 100644 --- a/app/Http/Livewire/UserWarnings.php +++ b/app/Http/Livewire/UserWarnings.php @@ -18,6 +18,11 @@ namespace App\Http\Livewire; use App\Models\User; use App\Models\Warning; +use App\Notifications\WarningCreated; +use App\Notifications\WarningDeactivated; +use App\Notifications\WarningsDeactivated; +use App\Notifications\WarningsDeleted; +use App\Notifications\WarningTorrentDeleted; use App\Traits\LivewireSort; use Illuminate\Support\Carbon; use Livewire\Attributes\Computed; @@ -118,10 +123,7 @@ class UserWarnings extends Component 'active' => true, ]); - $this->user->sendSystemNotification( - subject: 'Received warning', - message: 'You have received a [b]warning[/b]. Reason: '.$this->message, - ); + $this->user->notify(new WarningCreated($this->message)); $this->message = ''; @@ -142,10 +144,7 @@ class UserWarnings extends Component 'active' => false, ]); - $this->user->sendSystemNotification( - subject: 'Hit and Run Warning Deleted', - message: $staff->username.' has decided to deactivate your warning for torrent '.$warning->torrent.' You lucked out!', - ); + $this->user->notify(new WarningDeactivated($staff, $warning)); $this->dispatch('success', type: 'success', message: 'Warning Was Successfully Deactivated'); } @@ -182,10 +181,7 @@ class UserWarnings extends Component 'active' => false, ]); - $this->user->sendSystemNotification( - subject: 'All Hit and Run Warnings Deleted', - message: $staff->username.' has decided to deactivate all of your warnings. You lucked out!', - ); + $this->user->notify(new WarningsDeactivated($staff)); $this->dispatch('success', type: 'success', message: 'All Warnings Were Successfully Deactivated'); } @@ -207,10 +203,7 @@ class UserWarnings extends Component $warning->delete(); - $this->user->sendSystemNotification( - subject: 'Hit and Run Warning Deleted', - message: $staff->username.' has decided to delete your warning for torrent '.$warning->torrent.' You lucked out!', - ); + $this->user->notify(new WarningTorrentDeleted($staff, $warning)); $this->dispatch('success', type: 'success', message: 'Warning Was Successfully Deleted'); } @@ -232,10 +225,7 @@ class UserWarnings extends Component $this->user->warnings()->delete(); - $this->user->sendSystemNotification( - subject: 'All Hit and Run Warnings Deleted', - message: $staff->username.' has decided to delete all of your warnings. You lucked out!', - ); + $this->user->notify(new WarningsDeleted($staff)); $this->dispatch('success', type: 'success', message: 'All Warnings Were Successfully Deleted'); } diff --git a/app/Interfaces/SystemNotificationInterface.php b/app/Interfaces/SystemNotificationInterface.php new file mode 100644 index 000000000..bd2467792 --- /dev/null +++ b/app/Interfaces/SystemNotificationInterface.php @@ -0,0 +1,27 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Interfaces; + +use App\Models\User; + +interface SystemNotificationInterface +{ + /** + * @return array{subject: string, message: string} + */ + public function toSystemNotification(User $notifiable): array; +} diff --git a/app/Listeners/RegisteredListener.php b/app/Listeners/RegisteredListener.php index a05b331d3..c8c8f0ac2 100644 --- a/app/Listeners/RegisteredListener.php +++ b/app/Listeners/RegisteredListener.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace App\Listeners; use App\Models\User; +use App\Notifications\NewWelcome; use App\Repositories\ChatRepository; use Illuminate\Auth\Events\Registered; use Illuminate\Support\Arr; @@ -23,10 +24,7 @@ readonly class RegisteredListener $this->chatRepository->systemMessage($this->getWelcomeMessage($user)); // Send Welcome PM - $user->sendSystemNotification( - subject: config('welcomepm.subject'), - message: config('welcomepm.message'), - ); + $user->notify(new NewWelcome()); } private function getWelcomeMessage(User $user): string diff --git a/app/Models/User.php b/app/Models/User.php index 293b0e8dc..9b04ac00f 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -976,32 +976,6 @@ class User extends Authenticatable implements MustVerifyEmail return $this->hasMany(Donation::class); } - public function sendSystemNotification(string $subject, string $message): void - { - $conversation = Conversation::create(['subject' => $subject]); - - $conversation->users()->sync([User::SYSTEM_USER_ID => ['read' => true], $this->id]); - - PrivateMessage::create([ - 'conversation_id' => $conversation->id, - 'sender_id' => self::SYSTEM_USER_ID, - 'message' => $message - ]); - } - - public static function sendSystemNotificationTo(int $userId, string $subject, string $message): void - { - $conversation = Conversation::create(['subject' => $subject]); - - $conversation->users()->sync([User::SYSTEM_USER_ID => ['read' => true], $userId]); - - PrivateMessage::create([ - 'conversation_id' => $conversation->id, - 'sender_id' => self::SYSTEM_USER_ID, - 'message' => $message - ]); - } - /** * Has many conversations. * diff --git a/app/Notifications/ApikeyReset.php b/app/Notifications/ApikeyReset.php new file mode 100644 index 000000000..5053a8463 --- /dev/null +++ b/app/Notifications/ApikeyReset.php @@ -0,0 +1,52 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class ApikeyReset extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'Your API key has been reset by staff', + 'message' => "You will need to update your API key in all your scripts to continue using the API.\n\nFor more information, please create a helpdesk ticket.", + ]; + } +} diff --git a/app/Notifications/Channels/SystemNotificationChannel.php b/app/Notifications/Channels/SystemNotificationChannel.php new file mode 100644 index 000000000..8ea545597 --- /dev/null +++ b/app/Notifications/Channels/SystemNotificationChannel.php @@ -0,0 +1,43 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications\Channels; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\Conversation; +use App\Models\PrivateMessage; +use App\Models\User; + +class SystemNotificationChannel +{ + /** + * Send the given notification. + */ + public function send(User $notifiable, SystemNotificationInterface $notification): void + { + $data = $notification->toSystemNotification($notifiable); + + $conversation = Conversation::create(['subject' => $data['subject']]); + + $conversation->users()->sync([User::SYSTEM_USER_ID => ['read' => true], $notifiable->id]); + + PrivateMessage::create([ + 'conversation_id' => $conversation->id, + 'sender_id' => User::SYSTEM_USER_ID, + 'message' => $data['message'], + ]); + } +} diff --git a/app/Notifications/DonationExpired.php b/app/Notifications/DonationExpired.php new file mode 100644 index 000000000..b1932fcac --- /dev/null +++ b/app/Notifications/DonationExpired.php @@ -0,0 +1,52 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class DonationExpired extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'status' => 'Your Donor Status Has Expired', + 'message' => 'Your donor status has expired. Feel free to donate again to regain your donor status. Thank you for your support!' + ]; + } +} diff --git a/app/Notifications/NewWelcome.php b/app/Notifications/NewWelcome.php new file mode 100644 index 000000000..3e56f94f9 --- /dev/null +++ b/app/Notifications/NewWelcome.php @@ -0,0 +1,52 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class NewWelcome extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => config('welcomepm.subject'), + 'message' => config('welcomepm.message'), + ]; + } +} diff --git a/app/Notifications/PasskeyReset.php b/app/Notifications/PasskeyReset.php new file mode 100644 index 000000000..7d73374ce --- /dev/null +++ b/app/Notifications/PasskeyReset.php @@ -0,0 +1,52 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class PasskeyReset extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'ATTENTION - Your passkey has been reset', + 'message' => "Your passkey has been reset by staff. You will need to update your passkey in all your torrent clients to continue seeding.\n\nFor more information, please create a helpdesk ticket.", + ]; + } +} diff --git a/app/Notifications/PasswordUpdate.php b/app/Notifications/PasswordUpdate.php new file mode 100644 index 000000000..775095b97 --- /dev/null +++ b/app/Notifications/PasswordUpdate.php @@ -0,0 +1,52 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class PasswordUpdate extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'ATTENTION - Your password has been changed', + 'message' => "Your password has been changed by staff. You will need to update your password manager with the new password.\n\nFor more information, please create a helpdesk ticket.", + ]; + } +} diff --git a/app/Notifications/PersonalFreeleechCreated.php b/app/Notifications/PersonalFreeleechCreated.php new file mode 100644 index 000000000..73ae88070 --- /dev/null +++ b/app/Notifications/PersonalFreeleechCreated.php @@ -0,0 +1,52 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class PersonalFreeleechCreated extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => __('bon.pm-subject'), + 'message' => \sprintf(__('bon.pm-message'), now()->addDays(1)->toDayDateTimeString()).config('app.timezone').'[/b]!', + ]; + } +} diff --git a/app/Notifications/PersonalFreeleechDeleted.php b/app/Notifications/PersonalFreeleechDeleted.php new file mode 100644 index 000000000..0dd5ed264 --- /dev/null +++ b/app/Notifications/PersonalFreeleechDeleted.php @@ -0,0 +1,52 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class PersonalFreeleechDeleted extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'Personal 24 Hour Freeleech Expired', + 'message' => 'Your [b]Personal 24 Hour Freeleech[/b] has expired! Feel free to reenable it in the BON Store!', + ]; + } +} diff --git a/app/Notifications/ResurrectionCompleted.php b/app/Notifications/ResurrectionCompleted.php new file mode 100644 index 000000000..5744e3020 --- /dev/null +++ b/app/Notifications/ResurrectionCompleted.php @@ -0,0 +1,59 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\Torrent; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class ResurrectionCompleted extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + public function __construct(public Torrent $torrent) + { + } + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + $appurl = config('app.url'); + + return [ + 'subject' => 'Successful Graveyard Resurrection', + 'message' => "You have successfully resurrected [url={$appurl}/torrents/{$this->torrent->id}]{$this->torrent->name}[/url]! Thank you for bringing a torrent back from the dead! Enjoy the freeleech tokens!", + ]; + } +} diff --git a/app/Notifications/RsskeyReset.php b/app/Notifications/RsskeyReset.php new file mode 100644 index 000000000..da5007c62 --- /dev/null +++ b/app/Notifications/RsskeyReset.php @@ -0,0 +1,52 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class RsskeyReset extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'ATTENTION - Your RSS key has been reset', + 'message' => "Your RSS key has been reset by staff. You will need to update your RSS key in your torrent client to continue receiving new torrents.\n\nFor more information, please create a helpdesk ticket.", + ]; + } +} diff --git a/app/Notifications/TorrentDeleted.php b/app/Notifications/TorrentDeleted.php new file mode 100644 index 000000000..5ae9bf199 --- /dev/null +++ b/app/Notifications/TorrentDeleted.php @@ -0,0 +1,63 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\Torrent; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class TorrentDeleted extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + public function __construct(public Torrent $torrent, public string $reason) + { + } + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => "Torrent Deleted! - {$this->torrent->name}", + 'message' => <<torrent->name} has been removed from our site. + + Our system shows that you were either the uploader, a seeder or a leecher on said torrent. We just wanted to let you know you can safely remove it from your client. + + [b]Removal Reason:[/b] {$this->reason} + BBCODE + ]; + } +} diff --git a/app/Notifications/TorrentsDeleted.php b/app/Notifications/TorrentsDeleted.php new file mode 100644 index 000000000..5b827ab24 --- /dev/null +++ b/app/Notifications/TorrentsDeleted.php @@ -0,0 +1,71 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\Torrent; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Database\Eloquent\Collection; +use Illuminate\Notifications\Notification; + +class TorrentsDeleted extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + /** + * @param Collection $torrents + */ + public function __construct(public Collection $torrents, public string $title, public string $reason) + { + } + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'Bulk Torrents Deleted - '.$this->title.'! ', + 'message' => <<torrents->pluck('names')->map(fn ($name) => "[*]{$name}\n")} + [/list] + + Our system shows that you were either the uploader, a seeder or a leecher on said torrent. We just wanted to let you know you can safely remove it from your client. + + [b]Removal Reason:[/b] {$this->reason} + BBCODE + ]; + } +} diff --git a/app/Notifications/WarningCreated.php b/app/Notifications/WarningCreated.php new file mode 100644 index 000000000..62d0fa962 --- /dev/null +++ b/app/Notifications/WarningCreated.php @@ -0,0 +1,56 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class WarningCreated extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + public function __construct(public string $message) + { + } + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'Received warning', + 'message' => "You have received a [b]warning[/b]. Reason: {$this->message}", + ]; + } +} diff --git a/app/Notifications/WarningDeactivated.php b/app/Notifications/WarningDeactivated.php new file mode 100644 index 000000000..b9d674aef --- /dev/null +++ b/app/Notifications/WarningDeactivated.php @@ -0,0 +1,57 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Models\Warning; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class WarningDeactivated extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + public function __construct(public User $staff, public Warning $warning) + { + } + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'Hit and Run Warning Deactivated', + 'message' => "{$this->staff->username} has decided to deactivate your warning for torrent {$this->warning->torrent}. You lucked out!", + ]; + } +} diff --git a/app/Notifications/WarningTorrentDeleted.php b/app/Notifications/WarningTorrentDeleted.php new file mode 100644 index 000000000..d7d6b0d33 --- /dev/null +++ b/app/Notifications/WarningTorrentDeleted.php @@ -0,0 +1,57 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Models\Warning; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class WarningTorrentDeleted extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + public function __construct(public User $staff, public Warning $warning) + { + } + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'Hit and Run Warning Deleted', + 'message' => "{$this->staff->username} has decided to delete your warning for torrent {$this->warning->torrent}. You lucked out!", + ]; + } +} diff --git a/app/Notifications/WarningsDeactivated.php b/app/Notifications/WarningsDeactivated.php new file mode 100644 index 000000000..e309dd6ec --- /dev/null +++ b/app/Notifications/WarningsDeactivated.php @@ -0,0 +1,56 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class WarningsDeactivated extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + public function __construct(public User $staff) + { + } + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'All Hit and Run Warnings Deactivated', + 'message' => "{$this->staff->username} has decided to deactivate all of your warnings. You lucked out!", + ]; + } +} diff --git a/app/Notifications/WarningsDeleted.php b/app/Notifications/WarningsDeleted.php new file mode 100644 index 000000000..a87e016d2 --- /dev/null +++ b/app/Notifications/WarningsDeleted.php @@ -0,0 +1,56 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Notifications; + +use App\Interfaces\SystemNotificationInterface; +use App\Models\User; +use App\Notifications\Channels\SystemNotificationChannel; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Notifications\Notification; + +class WarningsDeleted extends Notification implements ShouldQueue, SystemNotificationInterface +{ + use Queueable; + + public function __construct(public User $staff) + { + } + + /** + * Get the notification's delivery channels. + * + * @return class-string + */ + public function via(object $notifiable): string + { + return SystemNotificationChannel::class; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toSystemNotification(User $notifiable): array + { + return [ + 'subject' => 'All Hit and Run Warnings Deleted', + 'message' => "{$this->staff->username} has decided to delete all of your warnings. You lucked out!", + ]; + } +}