From bd77efe4b47835295e845b5fefd3c1e3ce760607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Duarte?= <72362116+Hiekki4@users.noreply.github.com> Date: Fri, 23 Jul 2021 00:07:01 +0100 Subject: [PATCH 01/37] Update main.blade.php --- resources/views/layouts/main.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/layouts/main.blade.php b/resources/views/layouts/main.blade.php index c9ff4bfd..b9f0a780 100644 --- a/resources/views/layouts/main.blade.php +++ b/resources/views/layouts/main.blade.php @@ -316,7 +316,7 @@ From 28ab548094c139d2c5487bcba4edf6f2ba1bf26e Mon Sep 17 00:00:00 2001 From: Hiekki <72362116+Hiekki4@users.noreply.github.com> Date: Fri, 23 Jul 2021 20:41:49 +0100 Subject: [PATCH 02/37] credits endpoint [WORK IN PROGRESS] --- app/Http/Controllers/Api/UserController.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 7c905328..aa982e19 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -63,6 +63,27 @@ class UserController extends Controller return $user; } + /** + * Give credits to a user. + * + * @param Request $request + * @param int $id + * @return User + */ + public function addCredits(Request $request, int $id) + { + $discordUser = DiscordUser::find($id); + $user = $discordUser ? $discordUser->user : User::findOrFail($id); + + $request->validate([ + "credits" => "require|numeric|min:0|max:1000000", + ]); + + $user->increment('credits', $request); + + return $user; + } + /** * Remove the specified resource from storage. * From 32f6fb51985809abcf4d8a6f13ad86a0bf289f4f Mon Sep 17 00:00:00 2001 From: Hiekki <72362116+Hiekki4@users.noreply.github.com> Date: Sun, 25 Jul 2021 17:07:03 +0100 Subject: [PATCH 03/37] AddCredits endpoint is working --- app/Http/Controllers/Api/UserController.php | 4 ++-- routes/api.php | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index aa982e19..a78b8f7f 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -76,10 +76,10 @@ class UserController extends Controller $user = $discordUser ? $discordUser->user : User::findOrFail($id); $request->validate([ - "credits" => "require|numeric|min:0|max:1000000", + "credits" => "required|numeric|min:0|max:1000000", ]); - $user->increment('credits', $request); + $user->increment('credits', $request->credits); return $user; } diff --git a/routes/api.php b/routes/api.php index 5ffa4d9d..8afc6587 100644 --- a/routes/api.php +++ b/routes/api.php @@ -17,6 +17,7 @@ use Illuminate\Support\Facades\Route; */ Route::middleware('api.token')->group(function () { + Route::patch('/users/{server}/addcredits', [UserController::class, 'addCredits']); Route::resource('users', UserController::class)->except(['store', 'create']); Route::patch('/servers/{server}/suspend', [ServerController::class, 'suspend']); From 87f57af51007ddb074af1a3c8b1328c3b08c715a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Duarte?= <72362116+Hiekki4@users.noreply.github.com> Date: Sun, 25 Jul 2021 19:04:44 +0100 Subject: [PATCH 04/37] Update api.php --- routes/api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/api.php b/routes/api.php index 8afc6587..3f475be8 100644 --- a/routes/api.php +++ b/routes/api.php @@ -17,7 +17,7 @@ use Illuminate\Support\Facades\Route; */ Route::middleware('api.token')->group(function () { - Route::patch('/users/{server}/addcredits', [UserController::class, 'addCredits']); + Route::patch('/users/{user}/addcredits', [UserController::class, 'addCredits']); Route::resource('users', UserController::class)->except(['store', 'create']); Route::patch('/servers/{server}/suspend', [ServerController::class, 'suspend']); From dbf389e71751538bb71495be145f146eacc8cf2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Duarte?= <72362116+Hiekki4@users.noreply.github.com> Date: Sun, 25 Jul 2021 19:19:59 +0100 Subject: [PATCH 05/37] Update UserController.php --- app/Http/Controllers/Api/UserController.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index a78b8f7f..dac3d412 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -78,7 +78,11 @@ class UserController extends Controller $request->validate([ "credits" => "required|numeric|min:0|max:1000000", ]); - + + if ($request->user()->credits + $request->credits >= 99999999) throw ValidationException::withMessages([ + 'code' => "You can't add this amount of credits because you would exceed the credit limit" + ]); + $user->increment('credits', $request->credits); return $user; From 57edcd0b571b3e89c24a54e4a60073e266d78712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Duarte?= <72362116+Hiekki4@users.noreply.github.com> Date: Sun, 25 Jul 2021 19:20:43 +0100 Subject: [PATCH 06/37] Update UserController.php --- app/Http/Controllers/Api/UserController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index dac3d412..aed2c10c 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -80,7 +80,7 @@ class UserController extends Controller ]); if ($request->user()->credits + $request->credits >= 99999999) throw ValidationException::withMessages([ - 'code' => "You can't add this amount of credits because you would exceed the credit limit" + 'credits' => "You can't add this amount of credits because you would exceed the credit limit" ]); $user->increment('credits', $request->credits); From f331049ec03c35e0e6534bfdde6861d0507cb083 Mon Sep 17 00:00:00 2001 From: Hiekki <72362116+Hiekki4@users.noreply.github.com> Date: Sun, 25 Jul 2021 23:38:12 +0100 Subject: [PATCH 07/37] AVMG --- app/Http/Controllers/Api/UserController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index aed2c10c..55c2c595 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -78,8 +78,8 @@ class UserController extends Controller $request->validate([ "credits" => "required|numeric|min:0|max:1000000", ]); - - if ($request->user()->credits + $request->credits >= 99999999) throw ValidationException::withMessages([ + + if ($user->credits + $request->credits >= 99999999) throw ValidationException::withMessages([ 'credits' => "You can't add this amount of credits because you would exceed the credit limit" ]); From 07e4537e01189a5a9fc2e2f3ae92aa6927295a1e Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Mon, 26 Jul 2021 01:05:26 +0200 Subject: [PATCH 08/37] add trustedproxy config --- bootstrap/cache/.gitignore | 0 config/trustedproxy.php | 54 +++++++++++++++++++++++++ storage/app/.gitignore | 0 storage/app/public/.gitignore | 0 storage/framework/.gitignore | 0 storage/framework/cache/.gitignore | 0 storage/framework/cache/data/.gitignore | 0 storage/framework/sessions/.gitignore | 0 storage/framework/testing/.gitignore | 0 storage/framework/views/.gitignore | 0 storage/logs/.gitignore | 0 11 files changed, 54 insertions(+) mode change 100644 => 100755 bootstrap/cache/.gitignore create mode 100755 config/trustedproxy.php mode change 100644 => 100755 storage/app/.gitignore mode change 100644 => 100755 storage/app/public/.gitignore mode change 100644 => 100755 storage/framework/.gitignore mode change 100644 => 100755 storage/framework/cache/.gitignore mode change 100644 => 100755 storage/framework/cache/data/.gitignore mode change 100644 => 100755 storage/framework/sessions/.gitignore mode change 100644 => 100755 storage/framework/testing/.gitignore mode change 100644 => 100755 storage/framework/views/.gitignore mode change 100644 => 100755 storage/logs/.gitignore diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore old mode 100644 new mode 100755 diff --git a/config/trustedproxy.php b/config/trustedproxy.php new file mode 100755 index 00000000..8cfd785e --- /dev/null +++ b/config/trustedproxy.php @@ -0,0 +1,54 @@ +getClientIp() + * always gets the originating client IP, no matter + * how many proxies that client's request has + * subsequently passed through. + */ + 'proxies' => in_array(env('TRUSTED_PROXIES', []), ['*', '**']) ? + env('TRUSTED_PROXIES') : explode(',', env('TRUSTED_PROXIES', null)), + + /* + * Or, to trust all proxies that connect + * directly to your server, uncomment this: + */ + // 'proxies' => '*', + + /* + * Or, to trust ALL proxies, including those that + * are in a chain of forwarding, uncomment this: + */ + // 'proxies' => '**', + + /* + * Default Header Names + * + * Change these if the proxy does + * not send the default header names. + * + * Note that headers such as X-Forwarded-For + * are transformed to HTTP_X_FORWARDED_FOR format. + * + * The following are Symfony defaults, found in + * \Symfony\Component\HttpFoundation\Request::$trustedHeaders + */ + 'headers' => \Illuminate\Http\Request::HEADER_X_FORWARDED_ALL, +]; \ No newline at end of file diff --git a/storage/app/.gitignore b/storage/app/.gitignore old mode 100644 new mode 100755 diff --git a/storage/app/public/.gitignore b/storage/app/public/.gitignore old mode 100644 new mode 100755 diff --git a/storage/framework/.gitignore b/storage/framework/.gitignore old mode 100644 new mode 100755 diff --git a/storage/framework/cache/.gitignore b/storage/framework/cache/.gitignore old mode 100644 new mode 100755 diff --git a/storage/framework/cache/data/.gitignore b/storage/framework/cache/data/.gitignore old mode 100644 new mode 100755 diff --git a/storage/framework/sessions/.gitignore b/storage/framework/sessions/.gitignore old mode 100644 new mode 100755 diff --git a/storage/framework/testing/.gitignore b/storage/framework/testing/.gitignore old mode 100644 new mode 100755 diff --git a/storage/framework/views/.gitignore b/storage/framework/views/.gitignore old mode 100644 new mode 100755 diff --git a/storage/logs/.gitignore b/storage/logs/.gitignore old mode 100644 new mode 100755 From bdc1981c3604a815b4296dfb5151a98d57068362 Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Mon, 26 Jul 2021 04:24:55 +0200 Subject: [PATCH 09/37] Add DynamicNotification and notification api endpoints --- .../Api/NotificationController.php | 139 ++++++++++++++++++ app/Notifications/DynamicNotification.php | 57 +++++++ routes/api.php | 16 +- 3 files changed, 207 insertions(+), 5 deletions(-) create mode 100644 app/Http/Controllers/Api/NotificationController.php create mode 100644 app/Notifications/DynamicNotification.php diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php new file mode 100644 index 00000000..2b0005fe --- /dev/null +++ b/app/Http/Controllers/Api/NotificationController.php @@ -0,0 +1,139 @@ +user : User::findOrFail($userId); + + return $user->notifications()->paginate($request->query("per_page", 50)); + } + + /** + * Displays a specific notification + * + * @param int $userId + * @param int $notificationId + * @return JsonResponse + */ + public function view(int $userId, $notificationId) + { + $discordUser = DiscordUser::find($userId); + $user = $discordUser ? $discordUser->user : User::findOrFail($userId); + + $notification = $user->notifications()->where("id", $notificationId)->get()->first(); + + if (!$notification) { + return response()->json(["message" => "Notification not found."], 404); + } + + return $notification; + } + /** + * Shows all unread notifications of an user. + * @param Request $request + * @param int $userId + * @return Response + */ + public function indexUnread(Request $request, int $userId) + { + $discordUser = DiscordUser::find($userId); + $user = $discordUser ? $discordUser->user : User::findOrFail($userId); + + return $user->unreadNotifications()->paginate($request->query("per_page", 50)); + } + + /** + * Send a notification to an user. + * + * @param Request $request + * @param int $userId + * @return JsonResponse + */ + public function send(Request $request, int $userId) + { + $discordUser = DiscordUser::find($userId); + $user = $discordUser ? $discordUser->user : User::findOrFail($userId); + + $body = $request->validate([ + "title" => "required:string|min:0", + "content" => "required:string|min:0" + ]); + + $user->notify( + new DynamicNotification($body["title"], $body["content"]) + ); + + return response()->json(["message" => "Notification successfully sent."]); + } + + /** + * Delete all notifications from an user + * + * @param int $userId + * @return JsonResponse + */ + public function delete(int $userId) + { + $discordUser = DiscordUser::find($userId); + $user = $discordUser ? $discordUser->user : User::findOrFail($userId); + + $count = $user->notifications()->delete(); + + return response()->json(["message" => "All notifications have been successfully deleted.", "count" => $count]); + } + + /** + * Delete all read notifications from an user + * + * @param int $userId + * @return JsonResponse + */ + public function deleteRead(int $userId) + { + $discordUser = DiscordUser::find($userId); + $user = $discordUser ? $discordUser->user : User::findOrFail($userId); + + $count = $user->notifications()->whereNotNull("read_at")->delete(); + + return response()->json(["message" => "All read notifications have been successfully deleted.", "count" => $count]); + } + + /** + * Deletes a specific notification + * + * @param int $userId + * @param int $notificationId + * @return JsonResponse + */ + public function deleteOne(int $userId, $notificationid) + { + $discordUser = DiscordUser::find($userId); + $user = $discordUser ? $discordUser->user : User::findOrFail($userId); + + $notification = $user->notifications()->where("id", $notificationid)->get()->first(); + + if (!$notification) { + return response()->json(["message" => "Notification not found."], 404); + } + + $notification->delete(); + return response()->json($notification); + } +} diff --git a/app/Notifications/DynamicNotification.php b/app/Notifications/DynamicNotification.php new file mode 100644 index 00000000..0075de13 --- /dev/null +++ b/app/Notifications/DynamicNotification.php @@ -0,0 +1,57 @@ +title = $title; + $this->content = $content; + } + + /** + * Get the notification's delivery channels. + * + * @param mixed $notifiable + * @return array + */ + public function via() + { + return ['database']; + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * @return array + */ + public function toArray() + { + return [ + 'title' => $this->title, + 'content' => $this->content, + ]; + } +} diff --git a/routes/api.php b/routes/api.php index 5ffa4d9d..88865810 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,5 +1,6 @@ group(function () { Route::patch('/servers/{server}/unsuspend', [ServerController::class, 'unSuspend']); Route::resource('servers', ServerController::class)->except(['store', 'create', 'edit', 'update']); -// Route::get('/vouchers/{voucher}/users' , [VoucherController::class , 'users']); - Route::resource('vouchers', VoucherController::class)->except('create' , 'edit'); + // Route::get('/vouchers/{voucher}/users' , [VoucherController::class , 'users']); + Route::resource('vouchers', VoucherController::class)->except('create', 'edit'); + + Route::get('/notifications/{user}', [NotificationController::class, 'index']); + Route::get('/notifications/{user}/unread', [NotificationController::class, 'indexUnread']); + Route::get('/notifications/{user}/{notification}', [NotificationController::class, 'view']); + Route::post('/notifications/{user}', [NotificationController::class, 'send']); + Route::delete('/notifications/{user}', [NotificationController::class, 'delete']); + Route::delete('/notifications/{user}/read', [NotificationController::class, 'deleteRead']); + Route::delete('/notifications/{user}/{notification}', [NotificationController::class, 'deleteOne']); }); - - - From 696ce64df3bd334bc8db9d1df28eea7aed668b69 Mon Sep 17 00:00:00 2001 From: Hiekki <72362116+Hiekki4@users.noreply.github.com> Date: Tue, 27 Jul 2021 09:15:10 +0100 Subject: [PATCH 10/37] [WIP] increment --- app/Http/Controllers/Api/UserController.php | 22 +++++++++++++-------- routes/api.php | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 55c2c595..6946f7e3 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -64,26 +64,32 @@ class UserController extends Controller } /** - * Give credits to a user. + * * * @param Request $request * @param int $id * @return User */ - public function addCredits(Request $request, int $id) + public function increment(Request $request, int $id) { $discordUser = DiscordUser::find($id); $user = $discordUser ? $discordUser->user : User::findOrFail($id); $request->validate([ - "credits" => "required|numeric|min:0|max:1000000", - ]); - - if ($user->credits + $request->credits >= 99999999) throw ValidationException::withMessages([ - 'credits' => "You can't add this amount of credits because you would exceed the credit limit" + "credits" => "sometimes|numeric|min:0|max:1000000", + "server_limit" => "sometimes|numeric|min:0|max:1000000", ]); - $user->increment('credits', $request->credits); + if($request->credits){ + if ($user->credits + $request->credits >= 99999999) throw ValidationException::withMessages([ + 'credits' => "You can't add this amount of credits because you would exceed the credit limit" + ]); + $user->increment('credits', $request->credits); + } + + if($request->server_limit){ + $user->increment('server_limit', $request->server_limit); + } return $user; } diff --git a/routes/api.php b/routes/api.php index 3f475be8..7a1f8dae 100644 --- a/routes/api.php +++ b/routes/api.php @@ -17,7 +17,7 @@ use Illuminate\Support\Facades\Route; */ Route::middleware('api.token')->group(function () { - Route::patch('/users/{user}/addcredits', [UserController::class, 'addCredits']); + Route::patch('/users/{user}/increment', [UserController::class, 'increment']); Route::resource('users', UserController::class)->except(['store', 'create']); Route::patch('/servers/{server}/suspend', [ServerController::class, 'suspend']); From b12007aea318a9ff831fa0a25b75bed9b12b5bac Mon Sep 17 00:00:00 2001 From: Hiekki <72362116+Hiekki4@users.noreply.github.com> Date: Tue, 27 Jul 2021 13:20:31 +0100 Subject: [PATCH 11/37] decrement and increment endpoints --- app/Http/Controllers/Api/UserController.php | 39 ++++++++++++++++++++- routes/api.php | 1 + 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 6946f7e3..702be6c3 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -64,8 +64,8 @@ class UserController extends Controller } /** + * increments the users credits or/and server_limit * - * * @param Request $request * @param int $id * @return User @@ -88,12 +88,49 @@ class UserController extends Controller } if($request->server_limit){ + if ($user->server_limit + $request->server_limit >= 2147483647) throw ValidationException::withMessages([ + 'server_limit' => "You cannot add this amount of servers because it would exceed the server limit." + ]); $user->increment('server_limit', $request->server_limit); } return $user; } + /** + * decrements the users credits or/and server_limit + * + * @param Request $request + * @param int $id + * @return User + */ + public function decrement(Request $request, int $id) + { + $discordUser = DiscordUser::find($id); + $user = $discordUser ? $discordUser->user : User::findOrFail($id); + + $request->validate([ + "credits" => "sometimes|numeric|min:0|max:1000000", + "server_limit" => "sometimes|numeric|min:0|max:1000000", + ]); + + if($request->credits){ + if ($user->credits - $request->credits >= 99999999) throw ValidationException::withMessages([ + 'credits' => "You cannot remove this amount of credits because you would exceed the minimum credit" + ]); + $user->decrement('credits', $request->credits); + } + + if($request->server_limit){ + if ($user->server_limit - $request->server_limit >= 2147483647) throw ValidationException::withMessages([ + 'server_limit' => "You cannot remove this amount of servers because it would exceed the minimum server." + ]); + $user->decrement('server_limit', $request->server_limit); + } + + return $user; + } + /** * Remove the specified resource from storage. * diff --git a/routes/api.php b/routes/api.php index 7a1f8dae..3c5f1fb9 100644 --- a/routes/api.php +++ b/routes/api.php @@ -18,6 +18,7 @@ use Illuminate\Support\Facades\Route; Route::middleware('api.token')->group(function () { Route::patch('/users/{user}/increment', [UserController::class, 'increment']); + Route::patch('/users/{user}/decrement', [UserController::class, 'decrement']); Route::resource('users', UserController::class)->except(['store', 'create']); Route::patch('/servers/{server}/suspend', [ServerController::class, 'suspend']); From a5d030e71002de437a7815039ae10cd034a5933e Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Wed, 28 Jul 2021 10:05:01 +0200 Subject: [PATCH 12/37] improved the make user command to give better feedback --- app/Classes/Pterodactyl.php | 6 ++-- app/Console/Commands/MakeUserCommand.php | 29 ++++++++++++++----- app/Http/Controllers/Admin/UserController.php | 3 +- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/app/Classes/Pterodactyl.php b/app/Classes/Pterodactyl.php index a48b569f..22bce864 100644 --- a/app/Classes/Pterodactyl.php +++ b/app/Classes/Pterodactyl.php @@ -11,6 +11,7 @@ use Exception; use Illuminate\Http\Client\PendingRequest; use Illuminate\Http\Client\Response; use Illuminate\Support\Facades\Http; +use Illuminate\Validation\Validator; class Pterodactyl { @@ -34,9 +35,8 @@ class Pterodactyl */ public function getUser(int $pterodactylId){ $response = self::client()->get("/application/users/{$pterodactylId}"); - if ($response->failed()) { - return []; - } + + if ($response->failed()) return $response->json(); return $response->json()['attributes']; } diff --git a/app/Console/Commands/MakeUserCommand.php b/app/Console/Commands/MakeUserCommand.php index ef3b1372..4d4a7ed5 100644 --- a/app/Console/Commands/MakeUserCommand.php +++ b/app/Console/Commands/MakeUserCommand.php @@ -6,6 +6,8 @@ use App\Classes\Pterodactyl; use App\Models\User; use Illuminate\Console\Command; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Facades\Validator; +use Illuminate\Validation\ValidationException; class MakeUserCommand extends Command { @@ -46,24 +48,35 @@ class MakeUserCommand extends Command $ptero_id = $this->option('ptero_id') ?? $this->ask('Please specify your Pterodactyl ID.'); $password = $this->option('password') ?? $this->ask('Please specify your password.'); - if (strlen($password) < 8) { - $this->alert('Your password need to be at least 8 characters long'); + // Validate user input + $validator = Validator::make([ + 'ptero_id' => $ptero_id, + 'password' => $password, + ], [ + 'ptero_id' => 'required|numeric|integer|min:1|max:2147483647', + 'password' => 'required|string|min:8|max:60', + ]); + + if ($validator->fails()) { + $this->error($validator->errors()->first()); return 0; } //TODO: Do something with response (check for status code and give hints based upon that) $response = $this->pterodactyl->getUser($ptero_id); - if ($response === []) { - $this->alert('It seems that your Pterodactyl ID is not correct. Rerun the command and input an correct ID'); + if (isset($response['errors'])) { + if (isset($response['errors'][0]['code'])) $this->error("code: {$response['errors'][0]['code']}"); + if (isset($response['errors'][0]['status'])) $this->error("status: {$response['errors'][0]['status']}"); + if (isset($response['errors'][0]['detail'])) $this->error("detail: {$response['errors'][0]['detail']}"); return 0; } $user = User::create([ - 'name' => $response['first_name'], - 'email' => $response['email'], - 'role' => 'admin', - 'password' => Hash::make($password), + 'name' => $response['first_name'], + 'email' => $response['email'], + 'role' => 'admin', + 'password' => Hash::make($password), 'pterodactyl_id' => $response['id'] ]); diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 496c1bf3..132dc154 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -83,13 +83,12 @@ class UserController extends Controller "role" => Rule::in(['admin', 'mod', 'client', 'member']), ]); - if (empty($this->pterodactyl->getUser($request->input('pterodactyl_id')))) { + if (isset($this->pterodactyl->getUser($request->input('pterodactyl_id'))['errors'])) { throw ValidationException::withMessages([ 'pterodactyl_id' => ["User does not exists on pterodactyl's panel"] ]); } - if (!is_null($request->input('new_password'))) { $request->validate([ 'new_password' => 'required|string|min:8', From adba5b1fdbb22137189a09e47c77f322ff3884db Mon Sep 17 00:00:00 2001 From: Hiekki <72362116+Hiekki4@users.noreply.github.com> Date: Wed, 28 Jul 2021 09:47:10 +0100 Subject: [PATCH 13/37] Validation for negative values --- app/Http/Controllers/Api/UserController.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 702be6c3..d9fb64fe 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -10,6 +10,7 @@ use Illuminate\Contracts\Routing\ResponseFactory; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Validation\Rule; +use Illuminate\Validation\ValidationException; class UserController extends Controller { @@ -116,7 +117,10 @@ class UserController extends Controller if($request->credits){ if ($user->credits - $request->credits >= 99999999) throw ValidationException::withMessages([ - 'credits' => "You cannot remove this amount of credits because you would exceed the minimum credit" + 'credits' => "You cannot remove this amount of credits because you would exceed the minimum credit limit" + ]); + elseif($user->credits - $request->credits < 0) throw ValidationException::withMessages([ + 'credits' => "You can't remove this amount of credits because you would exceed the minimum credit limit" ]); $user->decrement('credits', $request->credits); } @@ -125,6 +129,9 @@ class UserController extends Controller if ($user->server_limit - $request->server_limit >= 2147483647) throw ValidationException::withMessages([ 'server_limit' => "You cannot remove this amount of servers because it would exceed the minimum server." ]); + elseif($user->server_limit - $request->server_limit < 0) throw ValidationException::withMessages([ + 'server_limit' => "You cannot remove this amount of servers because it would exceed the minimum server." + ]); $user->decrement('server_limit', $request->server_limit); } From 916fbad8af84f4c49fed636baf047b05e90da880 Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Wed, 28 Jul 2021 16:56:02 +0200 Subject: [PATCH 14/37] Clean up some code --- .../Api/NotificationController.php | 34 ++----------------- .../Controllers/Api/VoucherController.php | 5 +-- routes/api.php | 2 -- 3 files changed, 6 insertions(+), 35 deletions(-) diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php index 2b0005fe..84e89547 100644 --- a/app/Http/Controllers/Api/NotificationController.php +++ b/app/Http/Controllers/Api/NotificationController.php @@ -12,7 +12,7 @@ use Illuminate\Http\Request; class NotificationController extends Controller { /** - * Displays all notifications of an user. + * Display all notifications of an user. * @param Request $request * @param int $userId * @return Response @@ -26,7 +26,7 @@ class NotificationController extends Controller } /** - * Displays a specific notification + * Display a specific notification * * @param int $userId * @param int $notificationId @@ -45,19 +45,6 @@ class NotificationController extends Controller return $notification; } - /** - * Shows all unread notifications of an user. - * @param Request $request - * @param int $userId - * @return Response - */ - public function indexUnread(Request $request, int $userId) - { - $discordUser = DiscordUser::find($userId); - $user = $discordUser ? $discordUser->user : User::findOrFail($userId); - - return $user->unreadNotifications()->paginate($request->query("per_page", 50)); - } /** * Send a notification to an user. @@ -99,24 +86,9 @@ class NotificationController extends Controller return response()->json(["message" => "All notifications have been successfully deleted.", "count" => $count]); } - /** - * Delete all read notifications from an user - * - * @param int $userId - * @return JsonResponse - */ - public function deleteRead(int $userId) - { - $discordUser = DiscordUser::find($userId); - $user = $discordUser ? $discordUser->user : User::findOrFail($userId); - - $count = $user->notifications()->whereNotNull("read_at")->delete(); - - return response()->json(["message" => "All read notifications have been successfully deleted.", "count" => $count]); - } /** - * Deletes a specific notification + * Delete a specific notification * * @param int $userId * @param int $notificationId diff --git a/app/Http/Controllers/Api/VoucherController.php b/app/Http/Controllers/Api/VoucherController.php index 9b70277f..99d9507a 100644 --- a/app/Http/Controllers/Api/VoucherController.php +++ b/app/Http/Controllers/Api/VoucherController.php @@ -116,7 +116,8 @@ class VoucherController extends Controller * @param Voucher $voucher * @return LengthAwarePaginator */ - public function users(Request $request, Voucher $voucher){ + public function users(Request $request, Voucher $voucher) + { $request->validate([ 'include' => [ 'nullable', @@ -125,7 +126,7 @@ class VoucherController extends Controller ] ]); - if($request->input('include') == 'discorduser'){ + if ($request->input('include') == 'discorduser') { return $voucher->users()->with('discordUser')->paginate($request->query('per_page') ?? 50); } diff --git a/routes/api.php b/routes/api.php index 88865810..d83ba203 100644 --- a/routes/api.php +++ b/routes/api.php @@ -28,10 +28,8 @@ Route::middleware('api.token')->group(function () { Route::resource('vouchers', VoucherController::class)->except('create', 'edit'); Route::get('/notifications/{user}', [NotificationController::class, 'index']); - Route::get('/notifications/{user}/unread', [NotificationController::class, 'indexUnread']); Route::get('/notifications/{user}/{notification}', [NotificationController::class, 'view']); Route::post('/notifications/{user}', [NotificationController::class, 'send']); Route::delete('/notifications/{user}', [NotificationController::class, 'delete']); - Route::delete('/notifications/{user}/read', [NotificationController::class, 'deleteRead']); Route::delete('/notifications/{user}/{notification}', [NotificationController::class, 'deleteOne']); }); From f0a31fd4e267a999f3ea478473cd5c8e193fdfd6 Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Wed, 28 Jul 2021 18:22:12 +0200 Subject: [PATCH 15/37] Add support to add time for voucher expires_at --- .../Controllers/Admin/VoucherController.php | 11 +- .../Controllers/Api/VoucherController.php | 9 +- app/Providers/AppServiceProvider.php | 23 ++ .../views/admin/vouchers/create.blade.php | 289 +++++++++-------- resources/views/admin/vouchers/edit.blade.php | 292 +++++++++--------- 5 files changed, 310 insertions(+), 314 deletions(-) diff --git a/app/Http/Controllers/Admin/VoucherController.php b/app/Http/Controllers/Admin/VoucherController.php index e1a71580..b0955d3a 100644 --- a/app/Http/Controllers/Admin/VoucherController.php +++ b/app/Http/Controllers/Admin/VoucherController.php @@ -48,7 +48,7 @@ class VoucherController extends Controller 'code' => 'required|string|alpha_dash|max:36|min:4', 'uses' => 'required|numeric|max:2147483647|min:1', 'credits' => 'required|numeric|between:0,99999999', - 'expires_at' => ['nullable','date_format:d-m-Y','after:today',"before:10 years"], + 'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years', ]); Voucher::create($request->except('_token')); @@ -75,7 +75,7 @@ class VoucherController extends Controller */ public function edit(Voucher $voucher) { - return view('admin.vouchers.edit' , [ + return view('admin.vouchers.edit', [ 'voucher' => $voucher ]); } @@ -94,7 +94,7 @@ class VoucherController extends Controller 'code' => 'required|string|alpha_dash|max:36|min:4', 'uses' => 'required|numeric|max:2147483647|min:1', 'credits' => 'required|numeric|between:0,99999999', - 'expires_at' => ['nullable','date_format:d-m-Y','after:today',"before:10 years"], + 'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years', ]); $voucher->update($request->except('_token')); @@ -127,7 +127,7 @@ class VoucherController extends Controller ]); #get voucher by code - $voucher = Voucher::where('code' , '=' , $request->input('code'))->firstOrFail(); + $voucher = Voucher::where('code', '=', $request->input('code'))->firstOrFail(); #extra validations if ($voucher->getStatus() == 'USES_LIMIT_REACHED') throw ValidationException::withMessages([ @@ -138,7 +138,7 @@ class VoucherController extends Controller 'code' => 'This voucher has expired' ]); - if (!$request->user()->vouchers()->where('id' , '=' , $voucher->id)->get()->isEmpty()) throw ValidationException::withMessages([ + if (!$request->user()->vouchers()->where('id', '=', $voucher->id)->get()->isEmpty()) throw ValidationException::withMessages([ 'code' => 'You already redeemed this voucher code' ]); @@ -191,5 +191,4 @@ class VoucherController extends Controller ->rawColumns(['actions', 'code', 'status']) ->make(); } - } diff --git a/app/Http/Controllers/Api/VoucherController.php b/app/Http/Controllers/Api/VoucherController.php index 9b70277f..9b9e06e8 100644 --- a/app/Http/Controllers/Api/VoucherController.php +++ b/app/Http/Controllers/Api/VoucherController.php @@ -44,7 +44,7 @@ class VoucherController extends Controller 'code' => 'required|string|alpha_dash|max:36|min:4', 'uses' => 'required|numeric|max:2147483647|min:1', 'credits' => 'required|numeric|between:0,99999999', - 'expires_at' => 'nullable|date_format:d-m-Y|after:today|before:10 years' + 'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years' ]); return Voucher::create($request->all()); @@ -88,7 +88,7 @@ class VoucherController extends Controller 'code' => 'required|string|alpha_dash|max:36|min:4', 'uses' => 'required|numeric|max:2147483647|min:1', 'credits' => 'required|numeric|between:0,99999999', - 'expires_at' => 'nullable|date_format:d-m-Y|after:today|before:10 years' + 'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years' ]); $voucher->update($request->all()); @@ -116,7 +116,8 @@ class VoucherController extends Controller * @param Voucher $voucher * @return LengthAwarePaginator */ - public function users(Request $request, Voucher $voucher){ + public function users(Request $request, Voucher $voucher) + { $request->validate([ 'include' => [ 'nullable', @@ -125,7 +126,7 @@ class VoucherController extends Controller ] ]); - if($request->input('include') == 'discorduser'){ + if ($request->input('include') == 'discorduser') { return $voucher->users()->with('discordUser')->paginate($request->query('per_page') ?? 50); } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index c220bc7f..84f68299 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -4,6 +4,7 @@ namespace App\Providers; use Illuminate\Pagination\Paginator; use Illuminate\Support\Facades\Schema; +use Illuminate\Support\Facades\Validator; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -27,5 +28,27 @@ class AppServiceProvider extends ServiceProvider { Paginator::useBootstrap(); Schema::defaultStringLength(191); + + Validator::extend('multiple_date_format', function ($attribute, $value, $parameters, $validator) { + + $ok = true; + + $result = []; + + // iterate through all formats + foreach ($parameters as $parameter) { + + //validate with laravels standard date format validation + $result[] = $validator->validateDateFormat($attribute, $value, [$parameter]); + } + + //if none of result array is true. it sets ok to false + if (!in_array(true, $result)) { + $ok = false; + $validator->setCustomMessages(['multiple_date_format' => 'The format must be one of ' . join(",", $parameters)]); + } + + return $ok; + }); } } diff --git a/resources/views/admin/vouchers/create.blade.php b/resources/views/admin/vouchers/create.blade.php index 1aca487d..430c62b1 100644 --- a/resources/views/admin/vouchers/create.blade.php +++ b/resources/views/admin/vouchers/create.blade.php @@ -1,181 +1,170 @@ @extends('layouts.main') @section('content') - -
-
-
-
-

Vouchers

-
-
- -
+ +
+
+
+
+

Vouchers

+
+
+
-
- +
+
+ - -
-
+ +
+
-
-
-
-
-
- Voucher details -
-
-
-
- @csrf +
+
+
+
+
+ Voucher details +
+
+
+ + @csrf -
- - - @error('memo') -
- {{$message}} -
- @enderror +
+ + + @error('memo') +
+ {{$message}}
+ @enderror +
-
- - - @error('credits') -
- {{$message}} -
- @enderror +
+ + + @error('credits') +
+ {{$message}}
+ @enderror +
-
- -
- -
- -
+
+ +
+ +
+
- @error('code') -
- {{$message}} -
- @enderror
- -
- -
- -
- -
-
- @error('uses') -
- {{$message}} -
- @enderror + @error('code') +
+ {{$message}}
+ @enderror +
-
- -
- -
-
-
+
+ +
+ +
+
- @error('expires_at') -
- {{$message}} -
- @enderror
+ @error('uses') +
+ {{$message}} +
+ @enderror +
-
- +
+ +
+ +
+
+
- -
+ @error('expires_at') +
+ {{$message}} +
+ @enderror +
+ +
+ +
+
- - -
-
- + + + +
+
+ - + return result; + } + -@endsection +@endsection \ No newline at end of file diff --git a/resources/views/admin/vouchers/edit.blade.php b/resources/views/admin/vouchers/edit.blade.php index 467a30de..2f6364fd 100644 --- a/resources/views/admin/vouchers/edit.blade.php +++ b/resources/views/admin/vouchers/edit.blade.php @@ -1,186 +1,170 @@ @extends('layouts.main') @section('content') - -
-
-
-
-

Vouchers

-
-
- -
+ +
+
+
+
+

Vouchers

+
+
+
-
- +
+
+ - -
-
+ +
+
-
-
-
-
-
- Voucher details -
-
-
-
- @csrf - @method('PATCH') +
+
+
+
+
+ Voucher details +
+
+
+ + @csrf + @method('PATCH') -
- - - @error('memo') -
- {{$message}} -
- @enderror +
+ + + @error('memo') +
+ {{$message}}
+ @enderror +
-
- - - @error('credits') -
- {{$message}} -
- @enderror +
+ + + @error('credits') +
+ {{$message}}
+ @enderror +
-
- -
- -
- -
+
+ +
+ +
+
- @error('code') -
- {{$message}} -
- @enderror
- -
- -
- -
- -
-
- @error('uses') -
- {{$message}} -
- @enderror + @error('code') +
+ {{$message}}
+ @enderror +
-
- -
- -
-
-
+
+ +
+ +
+
- @error('expires_at') -
- {{$message}} +
+ @error('uses') +
+ {{$message}} +
+ @enderror +
+ +
+ +
+ +
+
- @enderror
+ @error('expires_at') +
+ {{$message}} +
+ @enderror +
-
- -
- -
+
+ +
+
-
-
- + +
+
+ - + return result; + } + -@endsection +@endsection \ No newline at end of file From 98df07269f4fb0e6df14b6380a908a146f32bf85 Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Wed, 28 Jul 2021 18:29:06 +0200 Subject: [PATCH 16/37] Add APP_TIMEZONE env variable --- .env.example | 1 + config/app.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 94676473..2c3c21aa 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,7 @@ APP_ENV=production APP_KEY= APP_DEBUG=false APP_URL=http://localhost +APP_TIMEZONE=UTC DB_CONNECTION=mysql DB_HOST=127.0.0.1 diff --git a/config/app.php b/config/app.php index d54c7e1d..11d8d417 100644 --- a/config/app.php +++ b/config/app.php @@ -67,7 +67,7 @@ return [ | */ - 'timezone' => 'UTC', + 'timezone' => env('APP_TIMEZONE', 'UTC'), /* |-------------------------------------------------------------------------- From f177ae53ce029bda81d3f56302071b3be2795782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Duarte?= <72362116+Hiekki4@users.noreply.github.com> Date: Sun, 1 Aug 2021 18:52:44 +0100 Subject: [PATCH 17/37] Update UserController.php --- app/Http/Controllers/Api/UserController.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index d9fb64fe..5a21945d 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -116,20 +116,14 @@ class UserController extends Controller ]); if($request->credits){ - if ($user->credits - $request->credits >= 99999999) throw ValidationException::withMessages([ - 'credits' => "You cannot remove this amount of credits because you would exceed the minimum credit limit" - ]); - elseif($user->credits - $request->credits < 0) throw ValidationException::withMessages([ + if($user->credits - $request->credits < 0) throw ValidationException::withMessages([ 'credits' => "You can't remove this amount of credits because you would exceed the minimum credit limit" ]); $user->decrement('credits', $request->credits); } if($request->server_limit){ - if ($user->server_limit - $request->server_limit >= 2147483647) throw ValidationException::withMessages([ - 'server_limit' => "You cannot remove this amount of servers because it would exceed the minimum server." - ]); - elseif($user->server_limit - $request->server_limit < 0) throw ValidationException::withMessages([ + if($user->server_limit - $request->server_limit < 0) throw ValidationException::withMessages([ 'server_limit' => "You cannot remove this amount of servers because it would exceed the minimum server." ]); $user->decrement('server_limit', $request->server_limit); From 27028c97112a06abb739b0e80aafd0d8a7a1ca53 Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Mon, 2 Aug 2021 16:33:34 +0200 Subject: [PATCH 18/37] cleanup --- .env.example | 1 + app/Http/Controllers/Api/UserController.php | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.env.example b/.env.example index 2c3c21aa..c9562f96 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,7 @@ APP_ENV=production APP_KEY= APP_DEBUG=false APP_URL=http://localhost +#list with timezones https://www.php.net/manual/en/timezones.php APP_TIMEZONE=UTC DB_CONNECTION=mysql diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 5a21945d..126a55b7 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -66,10 +66,11 @@ class UserController extends Controller /** * increments the users credits or/and server_limit - * + * * @param Request $request * @param int $id * @return User + * @throws ValidationException */ public function increment(Request $request, int $id) { @@ -80,7 +81,7 @@ class UserController extends Controller "credits" => "sometimes|numeric|min:0|max:1000000", "server_limit" => "sometimes|numeric|min:0|max:1000000", ]); - + if($request->credits){ if ($user->credits + $request->credits >= 99999999) throw ValidationException::withMessages([ 'credits' => "You can't add this amount of credits because you would exceed the credit limit" @@ -100,10 +101,11 @@ class UserController extends Controller /** * decrements the users credits or/and server_limit - * + * * @param Request $request * @param int $id * @return User + * @throws ValidationException */ public function decrement(Request $request, int $id) { @@ -114,7 +116,7 @@ class UserController extends Controller "credits" => "sometimes|numeric|min:0|max:1000000", "server_limit" => "sometimes|numeric|min:0|max:1000000", ]); - + if($request->credits){ if($user->credits - $request->credits < 0) throw ValidationException::withMessages([ 'credits' => "You can't remove this amount of credits because you would exceed the minimum credit limit" @@ -136,7 +138,7 @@ class UserController extends Controller * Remove the specified resource from storage. * * @param int $id - * @return Application|ResponseFactory|Response|void + * @return Application|Response|ResponseFactory */ public function destroy(int $id) { From a07749e04ba66aee00b37302b04f89d01ba9b7f6 Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Mon, 2 Aug 2021 16:47:22 +0200 Subject: [PATCH 19/37] fixed a bug: is ptero is down don't delete the server from our side if pterodactylpanel would be down and you would delete your server then it would be removed from controlpanel but not from pterodactyl, it now makes sure to delete on pterodactyl before deleting on controlpanel --- app/Http/Controllers/Admin/ServerController.php | 8 ++++++-- app/Http/Controllers/ServerController.php | 2 +- app/Models/Server.php | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Admin/ServerController.php b/app/Http/Controllers/Admin/ServerController.php index 0a1d98b6..6d333feb 100644 --- a/app/Http/Controllers/Admin/ServerController.php +++ b/app/Http/Controllers/Admin/ServerController.php @@ -90,8 +90,12 @@ class ServerController extends Controller */ public function destroy(Server $server) { - $server->delete(); - return redirect()->back()->with('success', 'server has been removed!'); + try { + $server->delete(); + return redirect()->route('admin.servers.index')->with('success', 'server removed'); + } catch (Exception $e) { + return redirect()->route('admin.servers.index')->with('error', 'An exception has occurred while trying to remove a resource "' . $e->getMessage() . '"'); + } } /** diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php index cf5db936..85922fb8 100644 --- a/app/Http/Controllers/ServerController.php +++ b/app/Http/Controllers/ServerController.php @@ -111,7 +111,7 @@ class ServerController extends Controller $server->delete(); return redirect()->route('servers.index')->with('success', 'server removed'); } catch (Exception $e) { - return redirect()->route('servers.index')->with('error', 'An exception has occurred while trying to remove a resource'); + return redirect()->route('servers.index')->with('error', 'An exception has occurred while trying to remove a resource "' . $e->getMessage() . '"'); } } diff --git a/app/Models/Server.php b/app/Models/Server.php index e48dc8a0..3527d9fb 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -70,7 +70,8 @@ class Server extends Model }); static::deleting(function (Server $server) { - Pterodactyl::client()->delete("/application/servers/{$server->pterodactyl_id}"); + $response = Pterodactyl::client()->delete("/application/servers/{$server->pterodactyl_id}"); + if ($response->failed()) throw new Exception($response['errors'][0]['code']); }); } From 07454ddd783695c7ab02ee7cefbad895851444f2 Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Mon, 2 Aug 2021 17:49:37 +0200 Subject: [PATCH 20/37] 500 | Server Error on Duplicate Voucher #133 Fixed! --- app/Http/Controllers/Admin/VoucherController.php | 4 ++-- app/Http/Controllers/Api/VoucherController.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/Admin/VoucherController.php b/app/Http/Controllers/Admin/VoucherController.php index b0955d3a..db78cdfe 100644 --- a/app/Http/Controllers/Admin/VoucherController.php +++ b/app/Http/Controllers/Admin/VoucherController.php @@ -45,7 +45,7 @@ class VoucherController extends Controller { $request->validate([ 'memo' => 'nullable|string|max:191', - 'code' => 'required|string|alpha_dash|max:36|min:4', + 'code' => 'required|string|alpha_dash|max:36|min:4|unique:vouchers', 'uses' => 'required|numeric|max:2147483647|min:1', 'credits' => 'required|numeric|between:0,99999999', 'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years', @@ -91,7 +91,7 @@ class VoucherController extends Controller { $request->validate([ 'memo' => 'nullable|string|max:191', - 'code' => 'required|string|alpha_dash|max:36|min:4', + 'code' => "required|string|alpha_dash|max:36|min:4|unique:vouchers,code,{$voucher->id}", 'uses' => 'required|numeric|max:2147483647|min:1', 'credits' => 'required|numeric|between:0,99999999', 'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years', diff --git a/app/Http/Controllers/Api/VoucherController.php b/app/Http/Controllers/Api/VoucherController.php index 9b9e06e8..f7acfdd5 100644 --- a/app/Http/Controllers/Api/VoucherController.php +++ b/app/Http/Controllers/Api/VoucherController.php @@ -41,7 +41,7 @@ class VoucherController extends Controller { $request->validate([ 'memo' => 'nullable|string|max:191', - 'code' => 'required|string|alpha_dash|max:36|min:4', + 'code' => 'required|string|alpha_dash|max:36|min:4|unique:vouchers', 'uses' => 'required|numeric|max:2147483647|min:1', 'credits' => 'required|numeric|between:0,99999999', 'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years' @@ -85,7 +85,7 @@ class VoucherController extends Controller $request->validate([ 'memo' => 'nullable|string|max:191', - 'code' => 'required|string|alpha_dash|max:36|min:4', + 'code' => "required|string|alpha_dash|max:36|min:4|unique:vouchers,code,{$voucher->id}", 'uses' => 'required|numeric|max:2147483647|min:1', 'credits' => 'required|numeric|between:0,99999999', 'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years' From cd4a01db7bbf8b3c5603dc9a87a9cf26106f1b84 Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Mon, 2 Aug 2021 17:52:26 +0200 Subject: [PATCH 21/37] make user command, made password field invis --- app/Console/Commands/MakeUserCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Commands/MakeUserCommand.php b/app/Console/Commands/MakeUserCommand.php index 4d4a7ed5..a06f0d18 100644 --- a/app/Console/Commands/MakeUserCommand.php +++ b/app/Console/Commands/MakeUserCommand.php @@ -46,7 +46,7 @@ class MakeUserCommand extends Command public function handle() { $ptero_id = $this->option('ptero_id') ?? $this->ask('Please specify your Pterodactyl ID.'); - $password = $this->option('password') ?? $this->ask('Please specify your password.'); + $password = $this->secret('password') ?? $this->ask('Please specify your password.'); // Validate user input $validator = Validator::make([ From 370c85585cd2392946f510cfd4ac059937428f73 Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Mon, 2 Aug 2021 19:25:33 +0200 Subject: [PATCH 22/37] added the option to change the credits display name --- app/Http/Controllers/ServerController.php | 2 +- app/Http/Controllers/StoreController.php | 2 +- app/Http/Kernel.php | 5 +- app/Http/Middleware/CreditsDisplayName.php | 23 +++ app/Http/Middleware/isAdmin.php | 2 +- .../seeders/Seeds/ConfigurationSeeder.php | 9 + .../views/admin/products/create.blade.php | 2 +- resources/views/admin/products/edit.blade.php | 2 +- resources/views/admin/users/edit.blade.php | 2 +- resources/views/admin/users/index.blade.php | 2 +- resources/views/admin/users/show.blade.php | 2 +- .../views/admin/vouchers/create.blade.php | 4 +- resources/views/admin/vouchers/edit.blade.php | 4 +- .../views/admin/vouchers/index.blade.php | 2 +- resources/views/home.blade.php | 4 +- resources/views/profile/index.blade.php | 2 +- resources/views/store/checkout.blade.php | 2 +- resources/views/store/index.blade.php | 4 +- resources/views/terms.blade.php | 186 ------------------ 19 files changed, 55 insertions(+), 206 deletions(-) create mode 100644 app/Http/Middleware/CreditsDisplayName.php delete mode 100644 resources/views/terms.blade.php diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php index 85922fb8..1ec74e14 100644 --- a/app/Http/Controllers/ServerController.php +++ b/app/Http/Controllers/ServerController.php @@ -88,7 +88,7 @@ class ServerController extends Controller //minimum credits if (Auth::user()->credits <= Configuration::getValueByKey('MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)) { - return redirect()->route('servers.index')->with('error', "You do not have the required amount of credits to create a new server!"); + return redirect()->route('servers.index')->with('error', "You do not have the required amount of ".CREDITS_DISPLAY_NAME." to create a new server!"); } //Required Verification for creating an server diff --git a/app/Http/Controllers/StoreController.php b/app/Http/Controllers/StoreController.php index 2aa0ed23..1b23d305 100644 --- a/app/Http/Controllers/StoreController.php +++ b/app/Http/Controllers/StoreController.php @@ -23,7 +23,7 @@ class StoreController extends Controller //Required Verification for creating an server if (Configuration::getValueByKey('FORCE_DISCORD_VERIFICATION', false) === 'true' && !Auth::user()->discordUser) { - return redirect()->route('profile.index')->with('error', "You are required to link your discord account before you can purchase credits."); + return redirect()->route('profile.index')->with('error', "You are required to link your discord account before you can purchase ".CREDITS_DISPLAY_NAME."."); } return view('store.index')->with([ diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 5e7b9418..572a8656 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -3,6 +3,7 @@ namespace App\Http; use App\Http\Middleware\ApiAuthToken; +use App\Http\Middleware\CreditsDisplayName; use App\Http\Middleware\isAdmin; use App\Http\Middleware\LastSeen; use Illuminate\Foundation\Http\Kernel as HttpKernel; @@ -40,12 +41,14 @@ class Kernel extends HttpKernel \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, - LastSeen::class + LastSeen::class, + CreditsDisplayName::class ], 'api' => [ 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, + CreditsDisplayName::class ], ]; diff --git a/app/Http/Middleware/CreditsDisplayName.php b/app/Http/Middleware/CreditsDisplayName.php new file mode 100644 index 00000000..a6962f41 --- /dev/null +++ b/app/Http/Middleware/CreditsDisplayName.php @@ -0,0 +1,23 @@ +role == 'admin') { + if (Auth::user() && Auth::user()->role == 'admin') { return $next($request); } diff --git a/database/seeders/Seeds/ConfigurationSeeder.php b/database/seeders/Seeds/ConfigurationSeeder.php index 7dc5e46b..f84bdd26 100644 --- a/database/seeders/Seeds/ConfigurationSeeder.php +++ b/database/seeders/Seeds/ConfigurationSeeder.php @@ -119,6 +119,15 @@ class ConfigurationSeeder extends Seeder 'description' => 'The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!' ]); + //credits display name + Configuration::firstOrCreate([ + 'key' => 'CREDITS_DISPLAY_NAME', + ], [ + 'value' => 'Credits', + 'type' => 'string', + 'description' => 'Set the display name of your currency :)' + ]); + } } diff --git a/resources/views/admin/products/create.blade.php b/resources/views/admin/products/create.blade.php index 2a29bbe8..96935a55 100644 --- a/resources/views/admin/products/create.blade.php +++ b/resources/views/admin/products/create.blade.php @@ -53,7 +53,7 @@
- +
- +
- + Name Role Email - Credits + {{CREDITS_DISPLAY_NAME}} Usage Servers Verified diff --git a/resources/views/admin/users/show.blade.php b/resources/views/admin/users/show.blade.php index 1e394359..f18dbd65 100644 --- a/resources/views/admin/users/show.blade.php +++ b/resources/views/admin/users/show.blade.php @@ -148,7 +148,7 @@
- +
diff --git a/resources/views/admin/vouchers/create.blade.php b/resources/views/admin/vouchers/create.blade.php index 430c62b1..6876f401 100644 --- a/resources/views/admin/vouchers/create.blade.php +++ b/resources/views/admin/vouchers/create.blade.php @@ -48,7 +48,7 @@
- + @error('credits')
@@ -167,4 +167,4 @@ -@endsection \ No newline at end of file +@endsection diff --git a/resources/views/admin/vouchers/edit.blade.php b/resources/views/admin/vouchers/edit.blade.php index 2f6364fd..7447f237 100644 --- a/resources/views/admin/vouchers/edit.blade.php +++ b/resources/views/admin/vouchers/edit.blade.php @@ -49,7 +49,7 @@
- + @error('credits')
@@ -167,4 +167,4 @@ -@endsection \ No newline at end of file +@endsection diff --git a/resources/views/admin/vouchers/index.blade.php b/resources/views/admin/vouchers/index.blade.php index bfe4cef6..3b8b604a 100644 --- a/resources/views/admin/vouchers/index.blade.php +++ b/resources/views/admin/vouchers/index.blade.php @@ -42,7 +42,7 @@ Status Code Memo - Credits + {{CREDITS_DISPLAY_NAME}} Used / Uses Expires diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index 8f47bbf2..5c13ea05 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -41,7 +41,7 @@
- Credits + {{CREDITS_DISPLAY_NAME}} {{Auth::user()->Credits()}}
@@ -58,7 +58,7 @@
- Credit usage + {{CREDITS_DISPLAY_NAME}} usage {{number_format($useage, 2, '.', '')}} per month
diff --git a/resources/views/profile/index.blade.php b/resources/views/profile/index.blade.php index c2a1ee25..88a6c0b5 100644 --- a/resources/views/profile/index.blade.php +++ b/resources/views/profile/index.blade.php @@ -198,7 +198,7 @@ extra {{$credits_reward_after_verify_discord}} - credits and increased server limit + {{CREDITS_DISPLAY_NAME}} and increased server limit

@endif
diff --git a/resources/views/store/checkout.blade.php b/resources/views/store/checkout.blade.php index 70e0282b..8355da4e 100644 --- a/resources/views/store/checkout.blade.php +++ b/resources/views/store/checkout.blade.php @@ -81,7 +81,7 @@ 1 - {{$product->quantity}} {{$product->type}} + {{$product->quantity}} {{strtolower($product->type) == 'credits' ? CREDITS_DISPLAY_NAME : $product->type}} {{$product->description}} {{$product->formatCurrency()}} diff --git a/resources/views/store/index.blade.php b/resources/views/store/index.blade.php index c022054e..8bc3f077 100644 --- a/resources/views/store/index.blade.php +++ b/resources/views/store/index.blade.php @@ -34,7 +34,7 @@
-
Credits
+
{{CREDITS_DISPLAY_NAME}}
@@ -51,7 +51,7 @@ @foreach($products as $product) - + diff --git a/resources/views/terms.blade.php b/resources/views/terms.blade.php deleted file mode 100644 index 3497416d..00000000 --- a/resources/views/terms.blade.php +++ /dev/null @@ -1,186 +0,0 @@ -@extends('layouts.app') - -@section('content') - -
-

Privacy Policy

-

Last updated: February 17, 2021

-

This Privacy Policy describes Our policies and procedures on the collection, use and disclosure of Your information when You use the Service and tells You about Your privacy rights and how the law protects You.

-

We use Your Personal data to provide and improve the Service. By using the Service, You agree to the collection and use of information in accordance with this Privacy Policy. This Privacy Policy has been created with the help of the Privacy Policy Generator.

-

Interpretation and Definitions

-

Interpretation

-

The words of which the initial letter is capitalized have meanings defined under the following conditions. The following definitions shall have the same meaning regardless of whether they appear in singular or in plural.

-

Definitions

-

For the purposes of this Privacy Policy:

-
    -
  • -

    Account means a unique account created for You to access our Service or parts of our Service.

    -
  • -
  • -

    Company (referred to as either "the Company", "We", "Us" or "Our" in this Agreement) refers to Bitsec Hosting.

    -
  • -
  • -

    Cookies are small files that are placed on Your computer, mobile device or any other device by a website, containing the details of Your browsing history on that website among its many uses.

    -
  • -
  • -

    Country refers to: Netherlands

    -
  • -
  • -

    Device means any device that can access the Service such as a computer, a cellphone or a digital tablet.

    -
  • -
  • -

    Personal Data is any information that relates to an identified or identifiable individual.

    -
  • -
  • -

    Service refers to the Website.

    -
  • -
  • -

    Service Provider means any natural or legal person who processes the data on behalf of the Company. It refers to third-party companies or individuals employed by the Company to facilitate the Service, to provide the Service on behalf of the Company, to perform services related to the Service or to assist the Company in analyzing how the Service is used.

    -
  • -
  • -

    Third-party Social Media Service refers to any website or any social network website through which a User can log in or create an account to use the Service.

    -
  • -
  • -

    Usage Data refers to data collected automatically, either generated by the use of the Service or from the Service infrastructure itself (for example, the duration of a page visit).

    -
  • -
  • -

    Website refers to Bitsec Hosting, accessible from https://bitsec.dev

    -
  • -
  • -

    You means the individual accessing or using the Service, or the company, or other legal entity on behalf of which such individual is accessing or using the Service, as applicable.

    -
  • -
-

Collecting and Using Your Personal Data

-

Types of Data Collected

-

Personal Data

-

While using Our Service, We may ask You to provide Us with certain personally identifiable information that can be used to contact or identify You. Personally identifiable information may include, but is not limited to:

-
    -
  • -

    Email address

    -
  • -
  • -

    First name and last name

    -
  • -
  • -

    Phone number

    -
  • -
  • -

    Address, State, Province, ZIP/Postal code, City

    -
  • -
  • -

    Usage Data

    -
  • -
-

Usage Data

-

Usage Data is collected automatically when using the Service.

-

Usage Data may include information such as Your Device's Internet Protocol address (e.g. IP address), browser type, browser version, the pages of our Service that You visit, the time and date of Your visit, the time spent on those pages, unique device identifiers and other diagnostic data.

-

When You access the Service by or through a mobile device, We may collect certain information automatically, including, but not limited to, the type of mobile device You use, Your mobile device unique ID, the IP address of Your mobile device, Your mobile operating system, the type of mobile Internet browser You use, unique device identifiers and other diagnostic data.

-

We may also collect information that Your browser sends whenever You visit our Service or when You access the Service by or through a mobile device.

-

Tracking Technologies and Cookies

-

We use Cookies and similar tracking technologies to track the activity on Our Service and store certain information. Tracking technologies used are beacons, tags, and scripts to collect and track information and to improve and analyze Our Service. The technologies We use may include:

-
    -
  • Cookies or Browser Cookies. A cookie is a small file placed on Your Device. You can instruct Your browser to refuse all Cookies or to indicate when a Cookie is being sent. However, if You do not accept Cookies, You may not be able to use some parts of our Service. Unless you have adjusted Your browser setting so that it will refuse Cookies, our Service may use Cookies.
  • -
  • Flash Cookies. Certain features of our Service may use local stored objects (or Flash Cookies) to collect and store information about Your preferences or Your activity on our Service. Flash Cookies are not managed by the same browser settings as those used for Browser Cookies. For more information on how You can delete Flash Cookies, please read "Where can I change the settings for disabling, or deleting local shared objects?" available at https://helpx.adobe.com/flash-player/kb/disable-local-shared-objects-flash.html#main_Where_can_I_change_the_settings_for_disabling__or_deleting_local_shared_objects_
  • -
  • Web Beacons. Certain sections of our Service and our emails may contain small electronic files known as web beacons (also referred to as clear gifs, pixel tags, and single-pixel gifs) that permit the Company, for example, to count users who have visited those pages or opened an email and for other related website statistics (for example, recording the popularity of a certain section and verifying system and server integrity).
  • -
-

Cookies can be "Persistent" or "Session" Cookies. Persistent Cookies remain on Your personal computer or mobile device when You go offline, while Session Cookies are deleted as soon as You close Your web browser. Learn more about cookies: Cookies: What Do They Do?.

-

We use both Session and Persistent Cookies for the purposes set out below:

-
    -
  • -

    Necessary / Essential Cookies

    -

    Type: Session Cookies

    -

    Administered by: Us

    -

    Purpose: These Cookies are essential to provide You with services available through the Website and to enable You to use some of its features. They help to authenticate users and prevent fraudulent use of user accounts. Without these Cookies, the services that You have asked for cannot be provided, and We only use these Cookies to provide You with those services.

    -
  • -
  • -

    Cookies Policy / Notice Acceptance Cookies

    -

    Type: Persistent Cookies

    -

    Administered by: Us

    -

    Purpose: These Cookies identify if users have accepted the use of cookies on the Website.

    -
  • -
  • -

    Functionality Cookies

    -

    Type: Persistent Cookies

    -

    Administered by: Us

    -

    Purpose: These Cookies allow us to remember choices You make when You use the Website, such as remembering your login details or language preference. The purpose of these Cookies is to provide You with a more personal experience and to avoid You having to re-enter your preferences every time You use the Website.

    -
  • -
-

For more information about the cookies we use and your choices regarding cookies, please visit our Cookies Policy or the Cookies section of our Privacy Policy.

-

Use of Your Personal Data

-

The Company may use Personal Data for the following purposes:

-
    -
  • -

    To provide and maintain our Service, including to monitor the usage of our Service.

    -
  • -
  • -

    To manage Your Account: to manage Your registration as a user of the Service. The Personal Data You provide can give You access to different functionalities of the Service that are available to You as a registered user.

    -
  • -
  • -

    For the performance of a contract: the development, compliance and undertaking of the purchase contract for the products, items or services You have purchased or of any other contract with Us through the Service.

    -
  • -
  • -

    To contact You: To contact You by email, telephone calls, SMS, or other equivalent forms of electronic communication, such as a mobile application's push notifications regarding updates or informative communications related to the functionalities, products or contracted services, including the security updates, when necessary or reasonable for their implementation.

    -
  • -
  • -

    To provide You with news, special offers and general information about other goods, services and events which we offer that are similar to those that you have already purchased or enquired about unless You have opted not to receive such information.

    -
  • -
  • -

    To manage Your requests: To attend and manage Your requests to Us.

    -
  • -
  • -

    For business transfers: We may use Your information to evaluate or conduct a merger, divestiture, restructuring, reorganization, dissolution, or other sale or transfer of some or all of Our assets, whether as a going concern or as part of bankruptcy, liquidation, or similar proceeding, in which Personal Data held by Us about our Service users is among the assets transferred.

    -
  • -
  • -

    For other purposes: We may use Your information for other purposes, such as data analysis, identifying usage trends, determining the effectiveness of our promotional campaigns and to evaluate and improve our Service, products, services, marketing and your experience.

    -
  • -
-

We may share Your personal information in the following situations:

-
    -
  • With Service Providers: We may share Your personal information with Service Providers to monitor and analyze the use of our Service, to contact You.
  • -
  • For business transfers: We may share or transfer Your personal information in connection with, or during negotiations of, any merger, sale of Company assets, financing, or acquisition of all or a portion of Our business to another company.
  • -
  • With Affiliates: We may share Your information with Our affiliates, in which case we will require those affiliates to honor this Privacy Policy. Affiliates include Our parent company and any other subsidiaries, joint venture partners or other companies that We control or that are under common control with Us.
  • -
  • With business partners: We may share Your information with Our business partners to offer You certain products, services or promotions.
  • -
  • With other users: when You share personal information or otherwise interact in the public areas with other users, such information may be viewed by all users and may be publicly distributed outside. If You interact with other users or register through a Third-Party Social Media Service, Your contacts on the Third-Party Social Media Service may see Your name, profile, pictures and description of Your activity. Similarly, other users will be able to view descriptions of Your activity, communicate with You and view Your profile.
  • -
  • With Your consent: We may disclose Your personal information for any other purpose with Your consent.
  • -
-

Retention of Your Personal Data

-

The Company will retain Your Personal Data only for as long as is necessary for the purposes set out in this Privacy Policy. We will retain and use Your Personal Data to the extent necessary to comply with our legal obligations (for example, if we are required to retain your data to comply with applicable laws), resolve disputes, and enforce our legal agreements and policies.

-

The Company will also retain Usage Data for internal analysis purposes. Usage Data is generally retained for a shorter period of time, except when this data is used to strengthen the security or to improve the functionality of Our Service, or We are legally obligated to retain this data for longer time periods.

-

Transfer of Your Personal Data

-

Your information, including Personal Data, is processed at the Company's operating offices and in any other places where the parties involved in the processing are located. It means that this information may be transferred to — and maintained on — computers located outside of Your state, province, country or other governmental jurisdiction where the data protection laws may differ than those from Your jurisdiction.

-

Your consent to this Privacy Policy followed by Your submission of such information represents Your agreement to that transfer.

-

The Company will take all steps reasonably necessary to ensure that Your data is treated securely and in accordance with this Privacy Policy and no transfer of Your Personal Data will take place to an organization or a country unless there are adequate controls in place including the security of Your data and other personal information.

-

Disclosure of Your Personal Data

-

Business Transactions

-

If the Company is involved in a merger, acquisition or asset sale, Your Personal Data may be transferred. We will provide notice before Your Personal Data is transferred and becomes subject to a different Privacy Policy.

-

Law enforcement

-

Under certain circumstances, the Company may be required to disclose Your Personal Data if required to do so by law or in response to valid requests by public authorities (e.g. a court or a government agency).

-

Other legal requirements

-

The Company may disclose Your Personal Data in the good faith belief that such action is necessary to:

-
    -
  • Comply with a legal obligation
  • -
  • Protect and defend the rights or property of the Company
  • -
  • Prevent or investigate possible wrongdoing in connection with the Service
  • -
  • Protect the personal safety of Users of the Service or the public
  • -
  • Protect against legal liability
  • -
-

Security of Your Personal Data

-

The security of Your Personal Data is important to Us, but remember that no method of transmission over the Internet, or method of electronic storage is 100% secure. While We strive to use commercially acceptable means to protect Your Personal Data, We cannot guarantee its absolute security.

-

Children's Privacy

-

Our Service does not address anyone under the age of 13. We do not knowingly collect personally identifiable information from anyone under the age of 13. If You are a parent or guardian and You are aware that Your child has provided Us with Personal Data, please contact Us. If We become aware that We have collected Personal Data from anyone under the age of 13 without verification of parental consent, We take steps to remove that information from Our servers.

-

If We need to rely on consent as a legal basis for processing Your information and Your country requires consent from a parent, We may require Your parent's consent before We collect and use that information.

-

Links to Other Websites

-

Our Service may contain links to other websites that are not operated by Us. If You click on a third party link, You will be directed to that third party's site. We strongly advise You to review the Privacy Policy of every site You visit.

-

We have no control over and assume no responsibility for the content, privacy policies or practices of any third party sites or services.

-

Changes to this Privacy Policy

-

We may update Our Privacy Policy from time to time. We will notify You of any changes by posting the new Privacy Policy on this page.

-

We will let You know via email and/or a prominent notice on Our Service, prior to the change becoming effective and update the "Last updated" date at the top of this Privacy Policy.

-

You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.

-

Contact Us

-

If you have any questions about this Privacy Policy, You can contact us:

-
    -
  • By email: bitsechosting@gmail.com
  • -
-
- -@endsection From 3f78d7dd1df33219cc96a9d30af0cbb4f07c015f Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Mon, 2 Aug 2021 19:44:14 +0200 Subject: [PATCH 23/37] small addition to the delete --- app/Models/Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/Server.php b/app/Models/Server.php index 3527d9fb..4d704cbe 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -71,7 +71,7 @@ class Server extends Model static::deleting(function (Server $server) { $response = Pterodactyl::client()->delete("/application/servers/{$server->pterodactyl_id}"); - if ($response->failed()) throw new Exception($response['errors'][0]['code']); + if ($response->failed() && !is_null($server->pterodactyl_id)) throw new Exception($response['errors'][0]['code']); }); } From e9bc2e8827c9e51bce132fc2657ec4d0ab6899f4 Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Mon, 2 Aug 2021 20:32:22 +0200 Subject: [PATCH 24/37] CREDITS_DISPLAY_NAME --- app/Http/Controllers/Admin/VoucherController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Admin/VoucherController.php b/app/Http/Controllers/Admin/VoucherController.php index db78cdfe..cf1b8600 100644 --- a/app/Http/Controllers/Admin/VoucherController.php +++ b/app/Http/Controllers/Admin/VoucherController.php @@ -143,14 +143,14 @@ class VoucherController extends Controller ]); if ($request->user()->credits + $voucher->credits >= 99999999) throw ValidationException::withMessages([ - 'code' => "You can't redeem this voucher because you would exceed the credit limit" + 'code' => "You can't redeem this voucher because you would exceed the ".CREDITS_DISPLAY_NAME." limit" ]); #redeem voucher $voucher->redeem($request->user()); return response()->json([ - 'success' => "{$voucher->credits} credits have been added to your balance!" + 'success' => "{$voucher->credits} ".CREDITS_DISPLAY_NAME." have been added to your balance!" ]); } From 2f92967a9c6c6aded094c84a67ed050862ba276c Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Tue, 3 Aug 2021 00:10:59 +0200 Subject: [PATCH 25/37] Add notifications api --- .../Api/NotificationController.php | 27 +++++-- app/Notifications/DynamicNotification.php | 36 +++++---- composer.json | 5 +- composer.lock | 73 ++++++++++++++++++- 4 files changed, 118 insertions(+), 23 deletions(-) diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php index 84e89547..8ba3570a 100644 --- a/app/Http/Controllers/Api/NotificationController.php +++ b/app/Http/Controllers/Api/NotificationController.php @@ -8,6 +8,9 @@ use App\Models\User; use App\Notifications\DynamicNotification; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Illuminate\Notifications\Messages\MailMessage; +use Illuminate\Support\HtmlString; +use Spatie\ValidationRules\Rules\Delimited; class NotificationController extends Controller { @@ -58,13 +61,27 @@ class NotificationController extends Controller $discordUser = DiscordUser::find($userId); $user = $discordUser ? $discordUser->user : User::findOrFail($userId); - $body = $request->validate([ - "title" => "required:string|min:0", - "content" => "required:string|min:0" + $via = $request->validate([ + "via" => ["required", new Delimited("in:mail,database")] ]); - + $via = explode(',', $via["via"]); + $mail = null; + $database = null; + if (in_array('database', $via)) { + $database = $request->validate([ + "title" => "required_if:database,true|string|min:1", + "content" => "required_if:database,true|string|min:1" + ]); + } + if (in_array('mail', $via)) { + $data = $request->validate([ + "subject" => "required|string|min:1", + "body" => "required|string|min:1" + ]); + $mail = (new MailMessage)->subject($data["subject"])->line(new HtmlString($data["body"])); + } $user->notify( - new DynamicNotification($body["title"], $body["content"]) + new DynamicNotification($via, $database, $mail) ); return response()->json(["message" => "Notification successfully sent."]); diff --git a/app/Notifications/DynamicNotification.php b/app/Notifications/DynamicNotification.php index 0075de13..6e24c329 100644 --- a/app/Notifications/DynamicNotification.php +++ b/app/Notifications/DynamicNotification.php @@ -10,24 +10,29 @@ class DynamicNotification extends Notification { use Queueable; /** - * @var string + * @var array */ - private $title; + private $via; /** - * @var string + * @var array */ - private $content; - + private $database; + /** + * @var MailMessage + */ + private $mail; /** * Create a new notification instance. * - * @param string $title - * @param string $content + * @param array $via + * @param array $database + * @param MailMessage $mail */ - public function __construct($title, $content) + public function __construct($via, $database, $mail) { - $this->title = $title; - $this->content = $content; + $this->via = $via; + $this->database = $database; + $this->mail = $mail; } /** @@ -38,9 +43,13 @@ class DynamicNotification extends Notification */ public function via() { - return ['database']; + return $this->via; } + public function toMail() + { + return $this->mail; + } /** * Get the array representation of the notification. * @@ -49,9 +58,6 @@ class DynamicNotification extends Notification */ public function toArray() { - return [ - 'title' => $this->title, - 'content' => $this->content, - ]; + return $this->database; } } diff --git a/composer.json b/composer.json index cc28d042..a4c8a987 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "license": "MIT", "require": { "php": "^8.0|^7.4", + "ext-intl": "*", "biscolab/laravel-recaptcha": "^5.0", "doctrine/dbal": "^3.1", "fideloper/proxy": "^4.4", @@ -22,8 +23,8 @@ "paypal/rest-api-sdk-php": "^1.14", "socialiteproviders/discord": "^4.1", "spatie/laravel-activitylog": "^3.16", - "yajra/laravel-datatables-oracle": "~9.0", - "ext-intl": "*" + "spatie/laravel-validation-rules": "^3.0", + "yajra/laravel-datatables-oracle": "~9.0" }, "require-dev": { "facade/ignition": "^2.5", diff --git a/composer.lock b/composer.lock index 48624e80..9a0f0594 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "dda32482531d11fdf6adc74fcba74715", + "content-hash": "eb7191a6b0476ec319915f6b98561af9", "packages": [ { "name": "asm89/stack-cors", @@ -3460,6 +3460,77 @@ ], "time": "2021-03-02T16:49:06+00:00" }, + { + "name": "spatie/laravel-validation-rules", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-validation-rules.git", + "reference": "43e15a70fb6148b0128d7981b0c0f3e99463b9fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-validation-rules/zipball/43e15a70fb6148b0128d7981b0c0f3e99463b9fb", + "reference": "43e15a70fb6148b0128d7981b0c0f3e99463b9fb", + "shasum": "" + }, + "require": { + "illuminate/support": "^6.0|^7.0|^8.0", + "php": "^7.3|^8.0" + }, + "require-dev": { + "laravel/legacy-factories": "^1.0.4", + "myclabs/php-enum": "^1.6", + "orchestra/testbench": "^4.5|^5.0|^6.0", + "phpunit/phpunit": "^9.3", + "spatie/enum": "^2.2|^3.0" + }, + "suggest": { + "league/iso3166": "Needed for the CountryCode rule" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\ValidationRules\\ValidationRulesServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\ValidationRules\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A set of useful Laravel validation rules", + "homepage": "https://github.com/spatie/laravel-validation-rules", + "keywords": [ + "laravel-validation-rules", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-validation-rules/issues", + "source": "https://github.com/spatie/laravel-validation-rules/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2020-11-30T15:23:31+00:00" + }, { "name": "swiftmailer/swiftmailer", "version": "v6.2.7", From aa19844d8e48575df67e6a2187bfca4b66e199c0 Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Tue, 3 Aug 2021 00:25:55 +0200 Subject: [PATCH 26/37] Remove required_if --- app/Http/Controllers/Api/NotificationController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php index 8ba3570a..68c52c90 100644 --- a/app/Http/Controllers/Api/NotificationController.php +++ b/app/Http/Controllers/Api/NotificationController.php @@ -69,8 +69,8 @@ class NotificationController extends Controller $database = null; if (in_array('database', $via)) { $database = $request->validate([ - "title" => "required_if:database,true|string|min:1", - "content" => "required_if:database,true|string|min:1" + "title" => "required|string|min:1", + "content" => "required|string|min:1" ]); } if (in_array('mail', $via)) { From 0597b4aabe7672e0db5730b9fd143a9c1fa8996f Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Tue, 3 Aug 2021 04:03:02 +0200 Subject: [PATCH 27/37] Add admin ui --- app/Http/Controllers/Admin/UserController.php | 62 ++++++- .../views/admin/users/notifications.blade.php | 161 ++++++++++++++++++ routes/web.php | 2 + 3 files changed, 220 insertions(+), 5 deletions(-) create mode 100644 resources/views/admin/users/notifications.blade.php diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 496c1bf3..74a37364 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin; use App\Classes\Pterodactyl; use App\Http\Controllers\Controller; use App\Models\User; +use App\Notifications\DynamicNotification; use Exception; use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\View\Factory; @@ -12,8 +13,10 @@ use Illuminate\Contracts\View\View; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Http\Response; +use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\HtmlString; use Illuminate\Validation\Rule; use Illuminate\Validation\ValidationException; @@ -104,7 +107,6 @@ class UserController extends Controller $user->update($request->all()); return redirect()->route('admin.users.index')->with('success', 'User updated!'); - } /** @@ -142,6 +144,55 @@ class UserController extends Controller return redirect()->route('admin.users.index'); } + /** + * Show the form for seding notifications to the specified resource. + * + * @param User $user + * @return Application|Factory|View|Response + */ + public function notifications(User $user) + { + return view('admin.users.notifications')->with([ + 'user' => $user + ]); + } + + /** + * Notify the specified resource. + * + * @param Request $request + * @param User $user + * @return RedirectResponse + * @throws Exception + */ + public function notify(Request $request, User $user) + { + $via = $request->validate([ + "via" => "required|min:1|array", + "via.*" => "required|string|in:mail,database", + ])["via"]; + + $mail = null; + $database = null; + if (in_array('database', $via)) { + $database = $request->validate([ + "title" => "required|string|min:1", + "content" => "required|string|min:1" + ]); + } + if (in_array('mail', $via)) { + $data = $request->validate([ + "subject" => "required|string|min:1", + "body" => "required|string|min:1" + ]); + $mail = (new MailMessage)->subject($data["subject"])->line(new HtmlString($data["body"])); + } + $user->notify( + new DynamicNotification($via, $database, $mail) + ); + return redirect()->route('admin.users.notifications', $user->id)->with('success', 'User notified!'); + } + /** * * @throws Exception @@ -177,6 +228,7 @@ class UserController extends Controller +
' . csrf_field() . ' ' . method_field("DELETE") . ' @@ -186,16 +238,16 @@ class UserController extends Controller }) ->editColumn('role', function (User $user) { switch ($user->role) { - case 'admin' : + case 'admin': $badgeColor = 'badge-danger'; break; - case 'mod' : + case 'mod': $badgeColor = 'badge-info'; break; - case 'client' : + case 'client': $badgeColor = 'badge-success'; break; - default : + default: $badgeColor = 'badge-secondary'; break; } diff --git a/resources/views/admin/users/notifications.blade.php b/resources/views/admin/users/notifications.blade.php new file mode 100644 index 00000000..a8f8b69d --- /dev/null +++ b/resources/views/admin/users/notifications.blade.php @@ -0,0 +1,161 @@ +@extends('layouts.main') + +@section('content') + +
+
+
+
+

Users

+
+ +
+
+
+ + + +
+
+ +
+
+
+
+ + @csrf + @method('POST') + +
+
+ + +
+ + + @error('via') +
+ {{$message}} +
+ @enderror +
+ +
+
+ + + @error('title') +
+ {{$message}} +
+ @enderror +
+
+ + + @error('content') +
+ {{$message}} +
+ @enderror +
+
+ +
+
+ + + @error('subject') +
+ {{$message}} +
+ @enderror +
+ +
+ + + @error('body') +
+ {{$message}} +
+ @enderror +
+
+
+ +
+
+
+
+
+
+ + +
+ + + + +@endsection diff --git a/routes/web.php b/routes/web.php index 00d35e70..f7978319 100644 --- a/routes/web.php +++ b/routes/web.php @@ -76,6 +76,8 @@ Route::middleware('auth')->group(function () { Route::get('users/loginas/{user}', [UserController::class, 'loginAs'])->name('users.loginas'); Route::get('users/datatable', [UserController::class, 'datatable'])->name('users.datatable'); + Route::get('users/{user}/notifications', [UserController::class, 'notifications'])->name('users.notifications'); + Route::post('users/{user}/notifications', [UserController::class, 'notify'])->name('users.notifications'); Route::resource('users', UserController::class); Route::get('servers/datatable', [AdminServerController::class, 'datatable'])->name('servers.datatable'); From bdedecbe5b6810d26cc5cf575457dc385e7223d5 Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Tue, 3 Aug 2021 16:40:39 +0200 Subject: [PATCH 28/37] Don't display database button when phpmyadmin is empty --- .env.example | 4 ++-- resources/views/servers/index.blade.php | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index c9562f96..c7016a83 100644 --- a/.env.example +++ b/.env.example @@ -33,8 +33,8 @@ DISCORD_GUILD_ID= DISCORD_ROLE_ID= #nesseary URL's -PTERODACTYL_URL=https://panel.bitsec.dev -PHPMYADMIN_URL=https://mysql.bitsec.dev +PTERODACTYL_URL=https://panel.controlpanel.gg +PHPMYADMIN_URL=https://mysql.controlpanel.gg #optional. remove to remove database button DISCORD_INVITE_URL=https://discord.gg/vrUYdxG4wZ #GOOGLE RECAPTCHA diff --git a/resources/views/servers/index.blade.php b/resources/views/servers/index.blade.php index 8097b2e0..a8dd29e3 100644 --- a/resources/views/servers/index.blade.php +++ b/resources/views/servers/index.blade.php @@ -45,7 +45,9 @@ From a19cbb1575cb1b78e483fa81b785be1d88bcc677 Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Tue, 3 Aug 2021 22:46:58 +0200 Subject: [PATCH 29/37] Merge database and mail fields --- app/Http/Controllers/Admin/UserController.php | 28 +++--- .../Api/NotificationController.php | 24 ++--- .../views/admin/users/notifications.blade.php | 93 +++++-------------- 3 files changed, 49 insertions(+), 96 deletions(-) diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 74a37364..52057914 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -167,28 +167,28 @@ class UserController extends Controller */ public function notify(Request $request, User $user) { - $via = $request->validate([ + $data = $request->validate([ "via" => "required|min:1|array", "via.*" => "required|string|in:mail,database", - ])["via"]; + "title" => "required|string|min:1", + "content" => "required|string|min:1" + ]); $mail = null; $database = null; - if (in_array('database', $via)) { - $database = $request->validate([ - "title" => "required|string|min:1", - "content" => "required|string|min:1" - ]); + if (in_array('database', $data["via"])) { + $database = [ + "title" => $data["title"], + "content" => $data["content"] + ]; } - if (in_array('mail', $via)) { - $data = $request->validate([ - "subject" => "required|string|min:1", - "body" => "required|string|min:1" - ]); - $mail = (new MailMessage)->subject($data["subject"])->line(new HtmlString($data["body"])); + if (in_array('mail', $data["via"])) { + $mail = (new MailMessage) + ->subject($data["title"]) + ->line(new HtmlString($data["content"])); } $user->notify( - new DynamicNotification($via, $database, $mail) + new DynamicNotification($data["via"], $database, $mail) ); return redirect()->route('admin.users.notifications', $user->id)->with('success', 'User notified!'); } diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php index 68c52c90..a5bf3084 100644 --- a/app/Http/Controllers/Api/NotificationController.php +++ b/app/Http/Controllers/Api/NotificationController.php @@ -61,24 +61,24 @@ class NotificationController extends Controller $discordUser = DiscordUser::find($userId); $user = $discordUser ? $discordUser->user : User::findOrFail($userId); - $via = $request->validate([ - "via" => ["required", new Delimited("in:mail,database")] + $data = $request->validate([ + "via" => ["required", new Delimited("in:mail,database")], + "title" => "required|string|min:1", + "content" => "required|string|min:1" ]); - $via = explode(',', $via["via"]); + $via = explode(',', $data["via"]); $mail = null; $database = null; if (in_array('database', $via)) { - $database = $request->validate([ - "title" => "required|string|min:1", - "content" => "required|string|min:1" - ]); + $database = [ + "title" => $data["title"], + "content" => $data["content"] + ]; } if (in_array('mail', $via)) { - $data = $request->validate([ - "subject" => "required|string|min:1", - "body" => "required|string|min:1" - ]); - $mail = (new MailMessage)->subject($data["subject"])->line(new HtmlString($data["body"])); + $mail = (new MailMessage) + ->subject($data["title"]) + ->line(new HtmlString($data["content"])); } $user->notify( new DynamicNotification($via, $database, $mail) diff --git a/resources/views/admin/users/notifications.blade.php b/resources/views/admin/users/notifications.blade.php index a8f8b69d..b3474ba2 100644 --- a/resources/views/admin/users/notifications.blade.php +++ b/resources/views/admin/users/notifications.blade.php @@ -36,13 +36,11 @@

+ type="checkbox">
+ type="checkbox"> @error('via')
@@ -51,61 +49,30 @@ @enderror
-
-
- - - @error('title') -
- {{$message}} -
- @enderror -
-
- - - @error('content') -
- {{$message}} -
- @enderror +
+ + + @error('title') +
+ {{$message}}
+ @enderror
- -
-
- - - @error('subject') -
- {{$message}} -
- @enderror -
- -
- - - @error('body') -
- {{$message}} -
- @enderror +
+ + + @error('content') +
+ {{$message}}
+ @enderror
@@ -122,20 +89,6 @@ From e97ae5572503eaa30203eb354c45cb02d370575a Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Wed, 4 Aug 2021 22:01:50 +0200 Subject: [PATCH 31/37] Send notification to multiple users --- app/Http/Controllers/Admin/UserController.php | 42 +++++++-- .../Api/NotificationController.php | 21 ++--- composer.json | 1 + composer.lock | 72 +++++++++++++- resources/views/admin/users/index.blade.php | 2 + .../views/admin/users/notifications.blade.php | 93 ++++++++++++++++++- resources/views/layouts/main.blade.php | 6 ++ routes/api.php | 2 +- routes/web.php | 5 +- 9 files changed, 216 insertions(+), 28 deletions(-) diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 52057914..502e8f89 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -6,6 +6,7 @@ use App\Classes\Pterodactyl; use App\Http\Controllers\Controller; use App\Models\User; use App\Notifications\DynamicNotification; +use Spatie\QueryBuilder\QueryBuilder; use Exception; use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\View\Factory; @@ -16,6 +17,7 @@ use Illuminate\Http\Response; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Facades\Notification; use Illuminate\Support\HtmlString; use Illuminate\Validation\Rule; use Illuminate\Validation\ValidationException; @@ -53,6 +55,28 @@ class UserController extends Controller ]); } + /** + * Get a JSON response of users. + * + * @return \Illuminate\Support\Collection|\App\models\User + */ + public function json(Request $request) + { + $users = QueryBuilder::for(User::query())->allowedFilters(['id', 'name', 'pterodactyl_id', 'email'])->paginate(25); + + if ($request->query('user_id')) { + $user = User::query()->findOrFail($request->input('user_id')); + $user->avatarUrl = $user->getAvatar(); + + return $user; + } + + return $users->map(function ($item) { + $item->avatarUrl = $item->getAvatar(); + + return $item; + }); + } /** * Show the form for editing the specified resource. * @@ -152,9 +176,7 @@ class UserController extends Controller */ public function notifications(User $user) { - return view('admin.users.notifications')->with([ - 'user' => $user - ]); + return view('admin.users.notifications'); } /** @@ -165,11 +187,14 @@ class UserController extends Controller * @return RedirectResponse * @throws Exception */ - public function notify(Request $request, User $user) + public function notify(Request $request) { $data = $request->validate([ "via" => "required|min:1|array", "via.*" => "required|string|in:mail,database", + "all" => "required_without:users|boolean", + "users" => "required_without:all|min:1|array", + "users.*" => "exists:users,id", "title" => "required|string|min:1", "content" => "required|string|min:1" ]); @@ -187,10 +212,10 @@ class UserController extends Controller ->subject($data["title"]) ->line(new HtmlString($data["content"])); } - $user->notify( - new DynamicNotification($data["via"], $database, $mail) - ); - return redirect()->route('admin.users.notifications', $user->id)->with('success', 'User notified!'); + $all = $data["all"] ?? false; + $users = $all ? User::all() : User::whereIn("id", $data["users"])->get(); + Notification::send($users, new DynamicNotification($data["via"], $database, $mail)); + return redirect()->route('admin.users.notifications')->with('success', 'Notification sent!'); } /** @@ -228,7 +253,6 @@ class UserController extends Controller - ' . csrf_field() . ' ' . method_field("DELETE") . ' diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php index a5bf3084..2371e524 100644 --- a/app/Http/Controllers/Api/NotificationController.php +++ b/app/Http/Controllers/Api/NotificationController.php @@ -9,6 +9,7 @@ use App\Notifications\DynamicNotification; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Notifications\Messages\MailMessage; +use Illuminate\Support\Facades\Notification; use Illuminate\Support\HtmlString; use Spatie\ValidationRules\Rules\Delimited; @@ -56,34 +57,32 @@ class NotificationController extends Controller * @param int $userId * @return JsonResponse */ - public function send(Request $request, int $userId) + public function send(Request $request) { - $discordUser = DiscordUser::find($userId); - $user = $discordUser ? $discordUser->user : User::findOrFail($userId); - $data = $request->validate([ "via" => ["required", new Delimited("in:mail,database")], + "all" => "required_without:users|boolean", + "users" => ["required_without:all", new Delimited("exists:users,id")], "title" => "required|string|min:1", "content" => "required|string|min:1" ]); - $via = explode(',', $data["via"]); + $via = explode(",", $data["via"]); $mail = null; $database = null; - if (in_array('database', $via)) { + if (in_array("database", $via)) { $database = [ "title" => $data["title"], "content" => $data["content"] ]; } - if (in_array('mail', $via)) { + if (in_array("mail", $via)) { $mail = (new MailMessage) ->subject($data["title"]) ->line(new HtmlString($data["content"])); } - $user->notify( - new DynamicNotification($via, $database, $mail) - ); - + $all = $data["all"] ?? false; + $users = $all ? User::all() : User::whereIn("id", explode(",", $data["users"]))->get(); + Notification::send($users, new DynamicNotification($via, $database, $mail)); return response()->json(["message" => "Notification successfully sent."]); } diff --git a/composer.json b/composer.json index a4c8a987..3edec1b4 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ "paypal/rest-api-sdk-php": "^1.14", "socialiteproviders/discord": "^4.1", "spatie/laravel-activitylog": "^3.16", + "spatie/laravel-query-builder": "^3.5", "spatie/laravel-validation-rules": "^3.0", "yajra/laravel-datatables-oracle": "~9.0" }, diff --git a/composer.lock b/composer.lock index 9a0f0594..14abe8de 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "eb7191a6b0476ec319915f6b98561af9", + "content-hash": "b3b61a46d5d4d6560d052cfda863d12c", "packages": [ { "name": "asm89/stack-cors", @@ -3460,6 +3460,76 @@ ], "time": "2021-03-02T16:49:06+00:00" }, + { + "name": "spatie/laravel-query-builder", + "version": "3.5.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-query-builder.git", + "reference": "4e5257be24139836dc092f618d7c73bcb1c00302" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-query-builder/zipball/4e5257be24139836dc092f618d7c73bcb1c00302", + "reference": "4e5257be24139836dc092f618d7c73bcb1c00302", + "shasum": "" + }, + "require": { + "illuminate/database": "^6.20.13|^7.30.4|^8.22.2", + "illuminate/http": "^6.20.13|7.30.4|^8.22.2", + "illuminate/support": "^6.20.13|7.30.4|^8.22.2", + "php": "^7.3|^8.0" + }, + "require-dev": { + "ext-json": "*", + "laravel/legacy-factories": "^1.0.4", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^4.9|^5.8|^6.3", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\QueryBuilder\\QueryBuilderServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\QueryBuilder\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alex Vanderbist", + "email": "alex@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Easily build Eloquent queries from API requests", + "homepage": "https://github.com/spatie/laravel-query-builder", + "keywords": [ + "laravel-query-builder", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-query-builder/issues", + "source": "https://github.com/spatie/laravel-query-builder" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2021-07-05T14:17:44+00:00" + }, { "name": "spatie/laravel-validation-rules", "version": "3.0.0", diff --git a/resources/views/admin/users/index.blade.php b/resources/views/admin/users/index.blade.php index b5c81c5e..364bfdba 100644 --- a/resources/views/admin/users/index.blade.php +++ b/resources/views/admin/users/index.blade.php @@ -28,6 +28,8 @@
Users
+ Notify
diff --git a/resources/views/admin/users/notifications.blade.php b/resources/views/admin/users/notifications.blade.php index ba7806c6..e4390903 100644 --- a/resources/views/admin/users/notifications.blade.php +++ b/resources/views/admin/users/notifications.blade.php @@ -1,5 +1,4 @@ @extends('layouts.main') - @section('content')
@@ -13,7 +12,7 @@ + href="{{route('admin.users.notifications')}}">Notifications
@@ -29,10 +28,31 @@
- + @csrf @method('POST') +
+
+ + +
+ +
+ @error('all') +
+ {{$message}} +
+ @enderror + @error('users') +
+ {{$message}} +
+ @enderror +
+

" + + "
" + + "
" + + "
" + + "" + + "
" + + "
" + ); + + $container.find(".select2-result-repository__username").text(data.name); + $container.find(".select2-result-repository__email").text(data.email); + + return $container; + {{-- return $('
\ + User Image \ + \ + ' + escapeHtml(data.name) +' \ + \ + ' + escapeHtml(data.email) + ' \ +
'); --}} + }, + templateSelection: function (data) { + return $('
\ + \ + User Image \ + \ + \ + ' + escapeHtml(data.name) +' \ + \ +
'); + } + }) + }) + + function toggleClass(id, className) { + document.getElementById(id).classList.toggle(className) + } + function escapeHtml(str) { + var div = document.createElement('div'); + div.appendChild(document.createTextNode(str)); + return div.innerHTML; + } diff --git a/resources/views/layouts/main.blade.php b/resources/views/layouts/main.blade.php index c9ff4bfd..9f22a2bd 100644 --- a/resources/views/layouts/main.blade.php +++ b/resources/views/layouts/main.blade.php @@ -19,6 +19,9 @@ {{-- datetimepicker --}} + {{-- select2 --}} + + @@ -344,6 +347,9 @@ + + From 212a5372792e2aabfe7e9b887dad18848ef1d3e7 Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Sun, 8 Aug 2021 15:14:01 +0200 Subject: [PATCH 34/37] Add value to all checkbox and close form tag --- resources/views/admin/users/notifications.blade.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/views/admin/users/notifications.blade.php b/resources/views/admin/users/notifications.blade.php index ac7cb522..3a12e8fb 100644 --- a/resources/views/admin/users/notifications.blade.php +++ b/resources/views/admin/users/notifications.blade.php @@ -35,7 +35,7 @@

@@ -97,6 +97,7 @@
+
From 53331392049989461e21c5bf1615eaf1bda66da4 Mon Sep 17 00:00:00 2001 From: Jovan Jovanovic Date: Tue, 10 Aug 2021 00:49:28 +0200 Subject: [PATCH 35/37] Use product limmit instead of hardcoded one --- app/Classes/Pterodactyl.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/Classes/Pterodactyl.php b/app/Classes/Pterodactyl.php index 22bce864..c1726bf8 100644 --- a/app/Classes/Pterodactyl.php +++ b/app/Classes/Pterodactyl.php @@ -33,7 +33,8 @@ class Pterodactyl * @param int $pterodactylId * @return mixed */ - public function getUser(int $pterodactylId){ + public function getUser(int $pterodactylId) + { $response = self::client()->get("/application/users/{$pterodactylId}"); if ($response->failed()) return $response->json(); @@ -50,7 +51,7 @@ class Pterodactyl $response = self::getAllocations($node); $freeAllocations = []; - if(isset($response['data'])){ + if (isset($response['data'])) { if (!empty($response['data'])) { foreach ($response['data'] as $allocation) { if (!$allocation['attributes']['assigned']) array_push($freeAllocations, $allocation); @@ -125,7 +126,7 @@ class Pterodactyl */ public static function getAllocations(Node $node) { - $per_page = Configuration::getValueByKey('ALLOCATION_LIMIT' , 200); + $per_page = Configuration::getValueByKey('ALLOCATION_LIMIT', 200); $response = self::client()->get("/application/nodes/{$node->id}/allocations?per_page={$per_page}"); if ($response->failed()) throw self::getException(); return $response->json(); @@ -167,7 +168,7 @@ class Pterodactyl "feature_limits" => [ "databases" => $server->product->databases, "backups" => $server->product->backups, - "allocations" => 1 + "allocations" => $server->product->allocations, ], "allocation" => [ "default" => $allocationId From b8c8cb74045e0e0ad4260092622cf0c7c35a9428 Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Thu, 9 Sep 2021 20:50:16 +0200 Subject: [PATCH 36/37] cleanup + auto unsuspend servers when credits update --- app/Events/UserUpdatedEvent.php | 32 +++++++++++++++++++ .../Api/NotificationController.php | 9 +++--- app/Listeners/UnsuspendServers.php | 30 +++++++++++++++++ app/Models/User.php | 5 +++ app/Providers/EventServiceProvider.php | 5 +++ config/app.php | 1 + resources/views/layouts/main.blade.php | 4 +-- 7 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 app/Events/UserUpdatedEvent.php create mode 100644 app/Listeners/UnsuspendServers.php diff --git a/app/Events/UserUpdatedEvent.php b/app/Events/UserUpdatedEvent.php new file mode 100644 index 00000000..199dada6 --- /dev/null +++ b/app/Events/UserUpdatedEvent.php @@ -0,0 +1,32 @@ +user = $user; + } +} diff --git a/app/Http/Controllers/Api/NotificationController.php b/app/Http/Controllers/Api/NotificationController.php index 2371e524..ceecbb24 100644 --- a/app/Http/Controllers/Api/NotificationController.php +++ b/app/Http/Controllers/Api/NotificationController.php @@ -31,7 +31,7 @@ class NotificationController extends Controller /** * Display a specific notification - * + * * @param int $userId * @param int $notificationId * @return JsonResponse @@ -52,9 +52,8 @@ class NotificationController extends Controller /** * Send a notification to an user. - * + * * @param Request $request - * @param int $userId * @return JsonResponse */ public function send(Request $request) @@ -88,7 +87,7 @@ class NotificationController extends Controller /** * Delete all notifications from an user - * + * * @param int $userId * @return JsonResponse */ @@ -105,7 +104,7 @@ class NotificationController extends Controller /** * Delete a specific notification - * + * * @param int $userId * @param int $notificationId * @return JsonResponse diff --git a/app/Listeners/UnsuspendServers.php b/app/Listeners/UnsuspendServers.php new file mode 100644 index 00000000..8bcecbe0 --- /dev/null +++ b/app/Listeners/UnsuspendServers.php @@ -0,0 +1,30 @@ +user->credits > Configuration::getValueByKey('MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER' , 50)){ + /** @var Server $server */ + foreach ($event->user->servers as $server){ + if ($server->isSuspended()) $server->unSuspend(); + } + } + } +} diff --git a/app/Models/User.php b/app/Models/User.php index a4f68ec4..b31d9bd2 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Classes\Pterodactyl; +use App\Events\UserUpdatedEvent; use App\Notifications\Auth\QueuedVerifyEmail; use App\Notifications\WelcomeMessage; use Illuminate\Contracts\Auth\MustVerifyEmail; @@ -111,6 +112,10 @@ class User extends Authenticatable implements MustVerifyEmail Pterodactyl::client()->delete("/application/users/{$user->pterodactyl_id}"); }); + + static::updated(function (User $user){ + event(new UserUpdatedEvent($user)); + }); } /** diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index ae9c40bc..cb150ed5 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -2,6 +2,8 @@ namespace App\Providers; +use App\Events\UserUpdatedEvent; +use App\Listeners\UnsuspendServers; use App\Listeners\Verified; use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; @@ -20,6 +22,9 @@ class EventServiceProvider extends ServiceProvider Registered::class => [ SendEmailVerificationNotification::class, ], + UserUpdatedEvent::class => [ + UnsuspendServers::class + ], SocialiteWasCalled::class => [ // ... other providers 'SocialiteProviders\\Discord\\DiscordExtendSocialite@handle', diff --git a/config/app.php b/config/app.php index 11d8d417..592e97d2 100644 --- a/config/app.php +++ b/config/app.php @@ -2,6 +2,7 @@ return [ + 'version' => '0.5', /* |-------------------------------------------------------------------------- | Application Name diff --git a/resources/views/layouts/main.blade.php b/resources/views/layouts/main.blade.php index 8af86ac3..1f01b180 100644 --- a/resources/views/layouts/main.blade.php +++ b/resources/views/layouts/main.blade.php @@ -21,7 +21,7 @@ {{-- select2 --}} - + @@ -319,7 +319,7 @@ From 5877ddbe8115e932fce277f49dd608776d053ca9 Mon Sep 17 00:00:00 2001 From: AVMG20 Date: Thu, 9 Sep 2021 21:06:08 +0200 Subject: [PATCH 37/37] update auto unsuspend servers to be server resource friendlier --- .../{UserUpdatedEvent.php => UserUpdateCreditsEvent.php} | 2 +- app/Http/Controllers/Admin/PaymentController.php | 3 +++ app/Http/Controllers/Admin/UserController.php | 2 ++ app/Http/Controllers/Admin/VoucherController.php | 3 +++ app/Http/Controllers/Api/UserController.php | 4 ++++ app/Listeners/UnsuspendServers.php | 6 +++--- app/Models/User.php | 6 +----- app/Providers/EventServiceProvider.php | 4 ++-- resources/views/models/redeem_voucher_modal.blade.php | 1 + 9 files changed, 20 insertions(+), 11 deletions(-) rename app/Events/{UserUpdatedEvent.php => UserUpdateCreditsEvent.php} (95%) diff --git a/app/Events/UserUpdatedEvent.php b/app/Events/UserUpdateCreditsEvent.php similarity index 95% rename from app/Events/UserUpdatedEvent.php rename to app/Events/UserUpdateCreditsEvent.php index 199dada6..7194bd8a 100644 --- a/app/Events/UserUpdatedEvent.php +++ b/app/Events/UserUpdateCreditsEvent.php @@ -11,7 +11,7 @@ use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; -class UserUpdatedEvent +class UserUpdateCreditsEvent { use Dispatchable, InteractsWithSockets, SerializesModels; diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php index 2f21c014..110d2c0d 100644 --- a/app/Http/Controllers/Admin/PaymentController.php +++ b/app/Http/Controllers/Admin/PaymentController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Admin; +use App\Events\UserUpdateCreditsEvent; use App\Http\Controllers\Controller; use App\Models\Configuration; use App\Models\Payment; @@ -167,6 +168,8 @@ class PaymentController extends Controller //payment notification $user->notify(new ConfirmPaymentNotification($payment)); + event(new UserUpdateCreditsEvent($user)); + //redirect back to home return redirect()->route('home')->with('success', 'Your credit balance has been increased!'); } diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index bc480aab..795ad553 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Admin; use App\Classes\Pterodactyl; +use App\Events\UserUpdateCreditsEvent; use App\Http\Controllers\Controller; use App\Models\User; use App\Notifications\DynamicNotification; @@ -130,6 +131,7 @@ class UserController extends Controller } $user->update($request->all()); + event(new UserUpdateCreditsEvent($user)); return redirect()->route('admin.users.index')->with('success', 'User updated!'); } diff --git a/app/Http/Controllers/Admin/VoucherController.php b/app/Http/Controllers/Admin/VoucherController.php index cf1b8600..1aa2c59e 100644 --- a/app/Http/Controllers/Admin/VoucherController.php +++ b/app/Http/Controllers/Admin/VoucherController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Admin; +use App\Events\UserUpdateCreditsEvent; use App\Http\Controllers\Controller; use App\Models\Voucher; use Illuminate\Contracts\Foundation\Application; @@ -149,6 +150,8 @@ class VoucherController extends Controller #redeem voucher $voucher->redeem($request->user()); + event(new UserUpdateCreditsEvent($request->user())); + return response()->json([ 'success' => "{$voucher->credits} ".CREDITS_DISPLAY_NAME." have been added to your balance!" ]); diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 126a55b7..a5f7263c 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Api; +use App\Events\UserUpdateCreditsEvent; use App\Http\Controllers\Controller; use App\Models\DiscordUser; use App\Models\User; @@ -61,6 +62,8 @@ class UserController extends Controller $user->update($request->all()); + event(new UserUpdateCreditsEvent($user)); + return $user; } @@ -86,6 +89,7 @@ class UserController extends Controller if ($user->credits + $request->credits >= 99999999) throw ValidationException::withMessages([ 'credits' => "You can't add this amount of credits because you would exceed the credit limit" ]); + event(new UserUpdateCreditsEvent($user)); $user->increment('credits', $request->credits); } diff --git a/app/Listeners/UnsuspendServers.php b/app/Listeners/UnsuspendServers.php index 8bcecbe0..51f1ad60 100644 --- a/app/Listeners/UnsuspendServers.php +++ b/app/Listeners/UnsuspendServers.php @@ -2,7 +2,7 @@ namespace App\Listeners; -use App\Events\UserUpdatedEvent; +use App\Events\UserUpdateCreditsEvent; use App\Models\Configuration; use App\Models\Server; use Exception; @@ -14,11 +14,11 @@ class UnsuspendServers implements ShouldQueue /** * Handle the event. * - * @param UserUpdatedEvent $event + * @param UserUpdateCreditsEvent $event * @return void * @throws Exception */ - public function handle(UserUpdatedEvent $event) + public function handle(UserUpdateCreditsEvent $event) { if ($event->user->credits > Configuration::getValueByKey('MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER' , 50)){ /** @var Server $server */ diff --git a/app/Models/User.php b/app/Models/User.php index b31d9bd2..6dc4efc8 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -3,7 +3,7 @@ namespace App\Models; use App\Classes\Pterodactyl; -use App\Events\UserUpdatedEvent; +use App\Events\UserUpdateCreditsEvent; use App\Notifications\Auth\QueuedVerifyEmail; use App\Notifications\WelcomeMessage; use Illuminate\Contracts\Auth\MustVerifyEmail; @@ -112,10 +112,6 @@ class User extends Authenticatable implements MustVerifyEmail Pterodactyl::client()->delete("/application/users/{$user->pterodactyl_id}"); }); - - static::updated(function (User $user){ - event(new UserUpdatedEvent($user)); - }); } /** diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index cb150ed5..d42ccae5 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -2,7 +2,7 @@ namespace App\Providers; -use App\Events\UserUpdatedEvent; +use App\Events\UserUpdateCreditsEvent; use App\Listeners\UnsuspendServers; use App\Listeners\Verified; use Illuminate\Auth\Events\Registered; @@ -22,7 +22,7 @@ class EventServiceProvider extends ServiceProvider Registered::class => [ SendEmailVerificationNotification::class, ], - UserUpdatedEvent::class => [ + UserUpdateCreditsEvent::class => [ UnsuspendServers::class ], SocialiteWasCalled::class => [ diff --git a/resources/views/models/redeem_voucher_modal.blade.php b/resources/views/models/redeem_voucher_modal.blade.php index 37a24414..84a243dd 100644 --- a/resources/views/models/redeem_voucher_modal.blade.php +++ b/resources/views/models/redeem_voucher_modal.blade.php @@ -56,6 +56,7 @@ url: form.action, dataType: 'json', data: { + "_token": "{{ csrf_token() }}", code: input.value }, success: function (response) {
{{$product->formatCurrency()}}{{$product->type}}{{strtolower($product->type) == 'credits' ? CREDITS_DISPLAY_NAME : $product->type}} {{$product->display}} Purchase