2021-06-05 09:26:32 +00:00
|
|
|
<?php
|
2021-06-06 18:22:40 +00:00
|
|
|
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
|
2023-04-25 07:22:30 +00:00
|
|
|
use App\Classes\Pterodactyl;
|
2021-09-09 19:06:08 +00:00
|
|
|
use App\Events\UserUpdateCreditsEvent;
|
2021-06-06 18:22:40 +00:00
|
|
|
use App\Http\Controllers\Controller;
|
|
|
|
use App\Models\DiscordUser;
|
|
|
|
use App\Models\User;
|
2022-06-07 14:19:14 +00:00
|
|
|
use App\Notifications\ReferralNotification;
|
2023-01-29 22:12:34 +00:00
|
|
|
use App\Traits\Referral;
|
2022-06-07 14:19:14 +00:00
|
|
|
use Carbon\Carbon;
|
2021-06-06 18:22:40 +00:00
|
|
|
use Illuminate\Contracts\Foundation\Application;
|
2021-10-11 21:46:06 +00:00
|
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
2021-06-06 18:22:40 +00:00
|
|
|
use Illuminate\Contracts\Routing\ResponseFactory;
|
2021-10-11 21:46:06 +00:00
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
use Illuminate\Database\Eloquent\Collection;
|
2021-10-13 20:34:05 +00:00
|
|
|
use Illuminate\Database\Eloquent\Model;
|
2021-06-06 18:22:40 +00:00
|
|
|
use Illuminate\Http\Request;
|
|
|
|
use Illuminate\Http\Response;
|
2021-10-12 19:36:13 +00:00
|
|
|
use Illuminate\Support\Facades\App;
|
2022-06-07 14:19:14 +00:00
|
|
|
use Illuminate\Support\Facades\DB;
|
2021-10-12 19:36:13 +00:00
|
|
|
use Illuminate\Support\Facades\Hash;
|
|
|
|
use Illuminate\Support\Str;
|
2021-06-06 18:22:40 +00:00
|
|
|
use Illuminate\Validation\Rule;
|
2021-07-28 08:47:10 +00:00
|
|
|
use Illuminate\Validation\ValidationException;
|
2021-10-11 21:46:06 +00:00
|
|
|
use Spatie\QueryBuilder\QueryBuilder;
|
2021-06-06 18:22:40 +00:00
|
|
|
|
|
|
|
class UserController extends Controller
|
|
|
|
{
|
2023-01-29 22:12:34 +00:00
|
|
|
use Referral;
|
|
|
|
|
2021-10-12 19:36:13 +00:00
|
|
|
const ALLOWED_INCLUDES = ['servers', 'notifications', 'payments', 'vouchers', 'discordUser'];
|
2023-01-05 17:01:42 +00:00
|
|
|
|
2021-10-12 19:36:13 +00:00
|
|
|
const ALLOWED_FILTERS = ['name', 'server_limit', 'email', 'pterodactyl_id', 'role', 'suspended'];
|
|
|
|
|
2021-06-06 18:22:40 +00:00
|
|
|
/**
|
|
|
|
* Display a listing of the resource.
|
|
|
|
*
|
2023-01-05 17:01:42 +00:00
|
|
|
* @param Request $request
|
2021-10-11 21:46:06 +00:00
|
|
|
* @return LengthAwarePaginator
|
2021-06-06 18:22:40 +00:00
|
|
|
*/
|
|
|
|
public function index(Request $request)
|
|
|
|
{
|
2021-10-11 21:46:06 +00:00
|
|
|
$query = QueryBuilder::for(User::class)
|
|
|
|
->allowedIncludes(self::ALLOWED_INCLUDES)
|
|
|
|
->allowedFilters(self::ALLOWED_FILTERS);
|
|
|
|
|
|
|
|
return $query->paginate($request->input('per_page') ?? 50);
|
2021-06-06 18:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Display the specified resource.
|
|
|
|
*
|
2023-01-05 17:01:42 +00:00
|
|
|
* @param int $id
|
2021-10-13 20:34:05 +00:00
|
|
|
* @return User|Builder|Collection|Model
|
2021-06-06 18:22:40 +00:00
|
|
|
*/
|
|
|
|
public function show(int $id)
|
|
|
|
{
|
|
|
|
$discordUser = DiscordUser::find($id);
|
2021-10-12 19:36:13 +00:00
|
|
|
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
|
2021-10-11 21:46:06 +00:00
|
|
|
|
|
|
|
$query = QueryBuilder::for($user)
|
|
|
|
->with('discordUser')
|
|
|
|
->allowedIncludes(self::ALLOWED_INCLUDES)
|
2021-10-12 19:36:13 +00:00
|
|
|
->where('users.id', '=', $id)
|
|
|
|
->orWhereHas('discordUser', function (Builder $builder) use ($id) {
|
|
|
|
$builder->where('id', '=', $id);
|
2021-10-11 21:46:06 +00:00
|
|
|
});
|
|
|
|
|
2021-10-13 20:34:05 +00:00
|
|
|
return $query->firstOrFail();
|
2021-06-06 18:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the specified resource in storage.
|
|
|
|
*
|
2023-01-05 17:01:42 +00:00
|
|
|
* @param Request $request
|
|
|
|
* @param int $id
|
2021-06-06 18:22:40 +00:00
|
|
|
* @return User
|
|
|
|
*/
|
|
|
|
public function update(Request $request, int $id)
|
|
|
|
{
|
|
|
|
$discordUser = DiscordUser::find($id);
|
|
|
|
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
|
|
|
|
|
|
|
|
$request->validate([
|
2023-01-05 17:01:42 +00:00
|
|
|
'name' => 'sometimes|string|min:4|max:30',
|
|
|
|
'email' => 'sometimes|string|email',
|
|
|
|
'credits' => 'sometimes|numeric|min:0|max:1000000',
|
|
|
|
'server_limit' => 'sometimes|numeric|min:0|max:1000000',
|
|
|
|
'role' => ['sometimes', Rule::in(['admin', 'moderator', 'client', 'member'])],
|
2021-06-06 18:22:40 +00:00
|
|
|
]);
|
|
|
|
|
2021-09-09 19:06:08 +00:00
|
|
|
event(new UserUpdateCreditsEvent($user));
|
|
|
|
|
2021-12-27 08:10:38 +00:00
|
|
|
//Update Users Password on Pterodactyl
|
|
|
|
//Username,Mail,First and Lastname are required aswell
|
2023-04-25 07:22:30 +00:00
|
|
|
$response = Pterodactyl::client()->patch('/application/users/' . $user->pterodactyl_id, [
|
2023-01-05 17:01:42 +00:00
|
|
|
'username' => $request->name,
|
|
|
|
'first_name' => $request->name,
|
|
|
|
'last_name' => $request->name,
|
|
|
|
'email' => $request->email,
|
2021-12-27 08:10:38 +00:00
|
|
|
|
|
|
|
]);
|
|
|
|
if ($response->failed()) {
|
|
|
|
throw ValidationException::withMessages([
|
|
|
|
'pterodactyl_error_message' => $response->toException()->getMessage(),
|
2023-01-05 17:01:42 +00:00
|
|
|
'pterodactyl_error_status' => $response->toException()->getCode(),
|
2021-12-27 08:10:38 +00:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
$user->update($request->all());
|
2021-09-09 19:06:08 +00:00
|
|
|
|
2021-06-06 18:22:40 +00:00
|
|
|
return $user;
|
|
|
|
}
|
|
|
|
|
2021-07-23 19:41:49 +00:00
|
|
|
/**
|
2021-07-27 12:20:31 +00:00
|
|
|
* increments the users credits or/and server_limit
|
2021-08-02 14:33:34 +00:00
|
|
|
*
|
2023-01-05 17:01:42 +00:00
|
|
|
* @param Request $request
|
|
|
|
* @param int $id
|
2021-07-23 19:41:49 +00:00
|
|
|
* @return User
|
2023-01-05 17:01:42 +00:00
|
|
|
*
|
2021-08-02 14:33:34 +00:00
|
|
|
* @throws ValidationException
|
2021-07-23 19:41:49 +00:00
|
|
|
*/
|
2021-07-27 08:15:10 +00:00
|
|
|
public function increment(Request $request, int $id)
|
2021-07-23 19:41:49 +00:00
|
|
|
{
|
|
|
|
$discordUser = DiscordUser::find($id);
|
|
|
|
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
|
|
|
|
|
|
|
|
$request->validate([
|
2023-01-05 17:01:42 +00:00
|
|
|
'credits' => 'sometimes|numeric|min:0|max:1000000',
|
|
|
|
'server_limit' => 'sometimes|numeric|min:0|max:1000000',
|
2021-07-25 18:19:59 +00:00
|
|
|
]);
|
2021-08-02 14:33:34 +00:00
|
|
|
|
2021-10-11 21:46:06 +00:00
|
|
|
if ($request->credits) {
|
2023-01-05 17:01:42 +00:00
|
|
|
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",
|
|
|
|
]);
|
|
|
|
}
|
2021-09-09 19:06:08 +00:00
|
|
|
event(new UserUpdateCreditsEvent($user));
|
2021-07-27 08:15:10 +00:00
|
|
|
$user->increment('credits', $request->credits);
|
2021-10-11 21:46:06 +00:00
|
|
|
}
|
2021-07-27 08:15:10 +00:00
|
|
|
|
2021-10-11 21:46:06 +00:00
|
|
|
if ($request->server_limit) {
|
2023-01-05 17:01:42 +00:00
|
|
|
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.',
|
|
|
|
]);
|
|
|
|
}
|
2021-10-11 21:46:06 +00:00
|
|
|
$user->increment('server_limit', $request->server_limit);
|
2021-07-27 08:15:10 +00:00
|
|
|
}
|
2021-07-23 19:41:49 +00:00
|
|
|
|
|
|
|
return $user;
|
|
|
|
}
|
|
|
|
|
2021-07-27 12:20:31 +00:00
|
|
|
/**
|
|
|
|
* decrements the users credits or/and server_limit
|
2021-08-02 14:33:34 +00:00
|
|
|
*
|
2023-01-05 17:01:42 +00:00
|
|
|
* @param Request $request
|
|
|
|
* @param int $id
|
2021-07-27 12:20:31 +00:00
|
|
|
* @return User
|
2023-01-05 17:01:42 +00:00
|
|
|
*
|
2021-08-02 14:33:34 +00:00
|
|
|
* @throws ValidationException
|
2021-07-27 12:20:31 +00:00
|
|
|
*/
|
|
|
|
public function decrement(Request $request, int $id)
|
|
|
|
{
|
|
|
|
$discordUser = DiscordUser::find($id);
|
|
|
|
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
|
|
|
|
|
|
|
|
$request->validate([
|
2023-01-05 17:01:42 +00:00
|
|
|
'credits' => 'sometimes|numeric|min:0|max:1000000',
|
|
|
|
'server_limit' => 'sometimes|numeric|min:0|max:1000000',
|
2021-07-27 12:20:31 +00:00
|
|
|
]);
|
2021-08-02 14:33:34 +00:00
|
|
|
|
2021-10-11 21:46:06 +00:00
|
|
|
if ($request->credits) {
|
2023-01-05 17:01:42 +00:00
|
|
|
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",
|
|
|
|
]);
|
|
|
|
}
|
2021-07-27 12:20:31 +00:00
|
|
|
$user->decrement('credits', $request->credits);
|
2021-10-11 21:46:06 +00:00
|
|
|
}
|
2021-07-27 12:20:31 +00:00
|
|
|
|
2021-10-11 21:46:06 +00:00
|
|
|
if ($request->server_limit) {
|
2023-01-05 17:01:42 +00:00
|
|
|
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.',
|
|
|
|
]);
|
|
|
|
}
|
2021-10-11 21:46:06 +00:00
|
|
|
$user->decrement('server_limit', $request->server_limit);
|
2021-07-27 12:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $user;
|
|
|
|
}
|
|
|
|
|
2022-01-03 21:14:45 +00:00
|
|
|
/**
|
|
|
|
* Suspends the user
|
|
|
|
*
|
2023-01-05 17:01:42 +00:00
|
|
|
* @param Request $request
|
|
|
|
* @param int $id
|
2022-01-03 21:14:45 +00:00
|
|
|
* @return bool
|
2023-01-05 17:01:42 +00:00
|
|
|
*
|
2022-01-03 21:14:45 +00:00
|
|
|
* @throws ValidationException
|
|
|
|
*/
|
2023-04-25 07:22:30 +00:00
|
|
|
public function suspend(Request $request, int $id)
|
2022-01-03 21:14:45 +00:00
|
|
|
{
|
|
|
|
$discordUser = DiscordUser::find($id);
|
|
|
|
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
|
|
|
|
|
|
|
|
if ($user->isSuspended()) {
|
2022-01-25 21:52:19 +00:00
|
|
|
throw ValidationException::withMessages([
|
|
|
|
'error' => 'The user is already suspended',
|
|
|
|
]);
|
2022-01-03 21:14:45 +00:00
|
|
|
}
|
|
|
|
$user->suspend();
|
|
|
|
|
|
|
|
return $user;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-01-05 17:08:41 +00:00
|
|
|
* Unsuspend the user
|
2022-01-03 21:14:45 +00:00
|
|
|
*
|
2023-01-05 17:01:42 +00:00
|
|
|
* @param Request $request
|
|
|
|
* @param int $id
|
2022-01-03 21:14:45 +00:00
|
|
|
* @return bool
|
2023-01-05 17:01:42 +00:00
|
|
|
*
|
2022-01-03 21:14:45 +00:00
|
|
|
* @throws ValidationException
|
|
|
|
*/
|
2023-04-25 07:22:30 +00:00
|
|
|
public function unsuspend(Request $request, int $id)
|
2022-01-03 21:14:45 +00:00
|
|
|
{
|
|
|
|
$discordUser = DiscordUser::find($id);
|
|
|
|
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
|
|
|
|
|
2023-01-29 22:12:34 +00:00
|
|
|
if (!$user->isSuspended()) {
|
2022-01-03 21:14:45 +00:00
|
|
|
throw ValidationException::withMessages([
|
2023-01-05 17:01:42 +00:00
|
|
|
'error' => 'You cannot unsuspend an User who is not suspended.',
|
2022-01-03 21:14:45 +00:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
$user->unSuspend();
|
|
|
|
|
|
|
|
return $user;
|
|
|
|
}
|
2023-01-05 17:01:42 +00:00
|
|
|
|
2021-10-12 19:36:13 +00:00
|
|
|
/**
|
2021-10-12 19:37:11 +00:00
|
|
|
* @throws ValidationException
|
2021-10-12 19:36:13 +00:00
|
|
|
*/
|
2023-04-25 07:22:30 +00:00
|
|
|
public function store(Request $request)
|
2021-10-12 19:36:13 +00:00
|
|
|
{
|
|
|
|
$request->validate([
|
|
|
|
'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
|
|
|
|
'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
|
|
|
|
'password' => ['required', 'string', 'min:8', 'max:191'],
|
|
|
|
]);
|
2023-01-05 17:01:42 +00:00
|
|
|
|
2022-11-04 17:15:16 +00:00
|
|
|
// Prevent the creation of new users via API if this is enabled.
|
2023-04-25 07:22:30 +00:00
|
|
|
if (!config('SETTINGS::SYSTEM:CREATION_OF_NEW_USERS', 'true')) {
|
2022-11-04 17:15:16 +00:00
|
|
|
throw ValidationException::withMessages([
|
2023-01-05 17:01:42 +00:00
|
|
|
'error' => 'The creation of new users has been blocked by the system administrator.',
|
2022-11-04 17:15:16 +00:00
|
|
|
]);
|
2023-01-05 17:01:42 +00:00
|
|
|
}
|
2021-10-12 19:36:13 +00:00
|
|
|
|
|
|
|
$user = User::create([
|
|
|
|
'name' => $request->input('name'),
|
|
|
|
'email' => $request->input('email'),
|
2023-04-25 07:22:30 +00:00
|
|
|
'credits' => config('SETTINGS::USER:INITIAL_CREDITS', 150),
|
|
|
|
'server_limit' => config('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
|
2021-10-12 19:36:13 +00:00
|
|
|
'password' => Hash::make($request->input('password')),
|
2022-06-07 14:19:14 +00:00
|
|
|
'referral_code' => $this->createReferralCode(),
|
2021-10-12 19:36:13 +00:00
|
|
|
]);
|
|
|
|
|
2023-04-25 07:22:30 +00:00
|
|
|
$response = Pterodactyl::client()->post('/application/users', [
|
2023-01-05 17:01:42 +00:00
|
|
|
'external_id' => App::environment('local') ? Str::random(16) : (string) $user->id,
|
|
|
|
'username' => $user->name,
|
|
|
|
'email' => $user->email,
|
|
|
|
'first_name' => $user->name,
|
|
|
|
'last_name' => $user->name,
|
|
|
|
'password' => $request->input('password'),
|
|
|
|
'root_admin' => false,
|
|
|
|
'language' => 'en',
|
2021-10-12 19:36:13 +00:00
|
|
|
]);
|
|
|
|
|
|
|
|
if ($response->failed()) {
|
|
|
|
$user->delete();
|
|
|
|
throw ValidationException::withMessages([
|
|
|
|
'pterodactyl_error_message' => $response->toException()->getMessage(),
|
2023-01-05 17:01:42 +00:00
|
|
|
'pterodactyl_error_status' => $response->toException()->getCode(),
|
2021-10-12 19:36:13 +00:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
$user->update([
|
2023-01-05 17:01:42 +00:00
|
|
|
'pterodactyl_id' => $response->json()['attributes']['id'],
|
2021-10-12 19:36:13 +00:00
|
|
|
]);
|
2022-06-07 14:19:14 +00:00
|
|
|
//INCREMENT REFERRAL-USER CREDITS
|
2023-01-29 22:12:34 +00:00
|
|
|
if (!empty($request->input('referral_code'))) {
|
2023-01-05 17:01:42 +00:00
|
|
|
$ref_code = $request->input('referral_code');
|
2022-06-07 14:19:14 +00:00
|
|
|
$new_user = $user->id;
|
2023-01-05 17:01:42 +00:00
|
|
|
if ($ref_user = User::query()->where('referral_code', '=', $ref_code)->first()) {
|
2023-04-25 07:22:30 +00:00
|
|
|
if (config('SETTINGS::REFERRAL:MODE') == 'register' || config('SETTINGS::REFERRAL:MODE') == 'both') {
|
|
|
|
$ref_user->increment('credits', config('SETTINGS::REFERRAL::REWARD'));
|
2022-06-07 14:19:14 +00:00
|
|
|
$ref_user->notify(new ReferralNotification($ref_user->id, $new_user));
|
|
|
|
}
|
|
|
|
//INSERT INTO USER_REFERRALS TABLE
|
|
|
|
DB::table('user_referrals')->insert([
|
|
|
|
'referral_id' => $ref_user->id,
|
|
|
|
'registered_user_id' => $user->id,
|
2023-01-05 17:01:42 +00:00
|
|
|
'created_at' => Carbon::now(),
|
|
|
|
'updated_at' => Carbon::now(),
|
2022-06-07 14:19:14 +00:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
2021-12-26 21:48:43 +00:00
|
|
|
$user->sendEmailVerificationNotification();
|
|
|
|
|
2021-10-12 19:36:13 +00:00
|
|
|
return $user;
|
|
|
|
}
|
|
|
|
|
2021-06-06 18:22:40 +00:00
|
|
|
/**
|
|
|
|
* Remove the specified resource from storage.
|
|
|
|
*
|
2023-01-05 17:01:42 +00:00
|
|
|
* @param int $id
|
2021-08-02 14:33:34 +00:00
|
|
|
* @return Application|Response|ResponseFactory
|
2021-06-06 18:22:40 +00:00
|
|
|
*/
|
|
|
|
public function destroy(int $id)
|
|
|
|
{
|
|
|
|
$discordUser = DiscordUser::find($id);
|
|
|
|
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
|
|
|
|
|
|
|
|
$user->delete();
|
2023-01-05 17:01:42 +00:00
|
|
|
|
2021-06-06 18:22:40 +00:00
|
|
|
return response($user, 200);
|
|
|
|
}
|
|
|
|
}
|