mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-28 22:01:33 +00:00
294 lines
12 KiB
PHP
294 lines
12 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Requests\UpdateThemeRequest;
|
|
use App\Jobs\SendAccountDeletedEmail;
|
|
use App\Models\ReleaseComment;
|
|
use App\Models\RootCategory;
|
|
use App\Models\User;
|
|
use App\Models\UserDownload;
|
|
use App\Models\UserRequest;
|
|
use App\Rules\ValidEmailDomain;
|
|
use App\Support\PermissionSyncHelper;
|
|
use Illuminate\Contracts\View\Factory;
|
|
use Illuminate\Contracts\View\View;
|
|
use Illuminate\Foundation\Application;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use PragmaRX\Google2FALaravel\Facade as Google2FA;
|
|
|
|
class ProfileController extends BasePageController
|
|
{
|
|
/**
|
|
* @throws \Throwable
|
|
*/
|
|
public function show(Request $request): mixed
|
|
{
|
|
|
|
$userID = $this->userdata->id;
|
|
$privileged = $this->userdata->hasRole('Admin') || $this->userdata->hasRole('Moderator');
|
|
$privateProfiles = config('nntmux_settings.private_profiles');
|
|
$publicView = false;
|
|
|
|
if ($privileged || ! $privateProfiles) {
|
|
$altID = ($request->has('id') && (int) $request->input('id') >= 0) ? (int) $request->input('id') : false;
|
|
$altUsername = ($request->has('name') && $request->input('name') !== '') ? $request->input('name') : false;
|
|
|
|
// If both 'id' and 'name' are specified, 'id' should take precedence.
|
|
if ($altID === false && $altUsername !== false) {
|
|
$user = User::getByUsername($altUsername);
|
|
if ($user) {
|
|
$this->userdata = $user;
|
|
$altID = $user['id'];
|
|
$userID = $altID;
|
|
}
|
|
} elseif ($altID !== false) {
|
|
$user = User::find($altID);
|
|
if ($user) {
|
|
$this->userdata = $user;
|
|
$userID = $altID;
|
|
$publicView = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($this->userdata === null) { // @phpstan-ignore identical.alwaysFalse
|
|
return $this->show404('No such user!');
|
|
}
|
|
|
|
// Check if the user selected a theme.
|
|
if (! isset($this->userdata->style) || $this->userdata->style === 'None') {
|
|
$this->userdata->style = 'Using the admin selected theme.';
|
|
}
|
|
|
|
// Get 24-hour hourly data for downloads and API requests
|
|
$downloadsHourly = UserDownload::getHourlyDownloads($userID);
|
|
$apiRequestsHourly = UserRequest::getHourlyApiRequests($userID);
|
|
|
|
// Get role limits
|
|
$userRole = $this->userdata->roles->first();
|
|
$downloadLimit = $userRole->downloadrequests ?? 0;
|
|
$apiLimit = $userRole->apirequests ?? 0;
|
|
|
|
$this->viewData = array_merge($this->viewData, [
|
|
'downloadlist' => UserDownload::getDownloadRequestsForUser($userID),
|
|
'apirequests' => UserRequest::getApiRequests($userID),
|
|
'grabstoday' => UserDownload::getDownloadRequests($userID),
|
|
'userinvitedby' => $this->userdata->invitedby ? User::find($this->userdata->invitedby) : null,
|
|
'user' => $this->userdata,
|
|
'privateprofiles' => $privateProfiles,
|
|
'publicview' => $publicView,
|
|
'privileged' => $privileged,
|
|
'isadmin' => $this->userdata->hasRole('Admin'),
|
|
'commentslist' => ReleaseComment::getCommentsForUserRange($userID),
|
|
'downloadsHourly' => $downloadsHourly,
|
|
'apiRequestsHourly' => $apiRequestsHourly,
|
|
'downloadLimit' => $downloadLimit,
|
|
'apiLimit' => $apiLimit,
|
|
'meta_title' => 'View User Profile',
|
|
'meta_keywords' => 'view,profile,user,details',
|
|
'meta_description' => 'View User Profile for '.$this->userdata->username,
|
|
]);
|
|
|
|
return view('profile.index', $this->viewData);
|
|
}
|
|
|
|
/**
|
|
* @return Factory|\Illuminate\View\View|View|RedirectResponse
|
|
*
|
|
* @throws \Exception
|
|
*/
|
|
public function edit(Request $request)
|
|
{
|
|
|
|
$action = $request->input('action') ?? 'view';
|
|
|
|
$userid = $this->userdata->id;
|
|
|
|
$errorStr = '';
|
|
$success_2fa = $request->session()->get('success');
|
|
$error_2fa = $request->session()->get('error');
|
|
|
|
// Generate 2FA QR code URL if 2FA is set up but not enabled
|
|
$google2fa_url = '';
|
|
if ($this->userdata->passwordSecurity()->exists() && ! $this->userdata->passwordSecurity->google2fa_enable) {
|
|
$google2fa_url = Google2FA::getQRCodeInline(
|
|
config('app.name'),
|
|
$this->userdata->email,
|
|
$this->userdata->passwordSecurity->google2fa_secret
|
|
);
|
|
}
|
|
|
|
switch ($action) {
|
|
case 'newapikey':
|
|
User::updateRssKey($userid);
|
|
|
|
return redirect()->to('profile');
|
|
case 'clearcookies':
|
|
return redirect()->to('profileedit');
|
|
case 'submit':
|
|
$validator = Validator::make($request->all(), [
|
|
'email' => ['nullable', 'string', 'email', 'max:255', 'unique:users,email,'.$userid, new ValidEmailDomain],
|
|
'password' => ['nullable', 'string', 'min:8', 'confirmed', 'regex:/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/'],
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
$errorStr = implode('', Arr::collapse($validator->errors()->toArray()));
|
|
} else {
|
|
User::updateUser(
|
|
$userid,
|
|
$this->userdata->username,
|
|
$request->input('email'),
|
|
$this->userdata->grabs,
|
|
$this->userdata->roles_id,
|
|
$this->userdata->notes,
|
|
$this->userdata->invites,
|
|
$request->has('movieview') ? 1 : 0,
|
|
$request->has('musicview') ? 1 : 0,
|
|
$request->has('gameview') ? 1 : 0,
|
|
$this->userdata->xxxview ? 1 : 0,
|
|
$request->has('consoleview') ? 1 : 0,
|
|
$request->has('bookview') ? 1 : 0,
|
|
'None',
|
|
);
|
|
|
|
// Update theme preference
|
|
if ($request->has('theme_preference')) {
|
|
$themeValue = $request->input('theme_preference');
|
|
if (in_array($themeValue, ['light', 'dark', 'system'], true)) {
|
|
User::where('id', $userid)->update(['theme_preference' => $themeValue]);
|
|
}
|
|
}
|
|
|
|
// Update color scheme
|
|
if ($request->has('color_scheme')) {
|
|
$schemeValue = $request->input('color_scheme');
|
|
if (in_array($schemeValue, ['blue', 'emerald', 'violet'], true)) {
|
|
User::where('id', $userid)->update(['color_scheme' => $schemeValue]);
|
|
}
|
|
}
|
|
|
|
// Update timezone preference
|
|
if ($request->has('timezone')) {
|
|
$timezoneValue = $request->input('timezone');
|
|
$validTimezones = array_merge(['UTC'], ...array_values(getAvailableTimezones()));
|
|
if (in_array($timezoneValue, $validTimezones, true)) {
|
|
User::where('id', $userid)->update(['timezone' => $timezoneValue]);
|
|
}
|
|
}
|
|
|
|
// Update excluded subcategories
|
|
$excludedCategories = $request->input('excluded_categories', []);
|
|
// Ensure all values are integers
|
|
$excludedCategories = array_map('intval', array_filter($excludedCategories, 'is_numeric'));
|
|
$this->userdata->syncExcludedCategories($excludedCategories);
|
|
|
|
Cache::forget('user_category_exclusions_'.$userid);
|
|
|
|
PermissionSyncHelper::syncUserPermissions($this->userdata, $request);
|
|
|
|
if ($request->has('password') && ! empty($request->input('password'))) {
|
|
User::updatePassword($userid, $request->input('password'));
|
|
}
|
|
|
|
if (! $this->userdata->hasRole('Admin')) {
|
|
if (! empty($request->input('email')) && $this->userdata->email !== $request->input('email')) {
|
|
$this->userdata->email = $request->input('email');
|
|
$this->userdata->resetEmailVerification();
|
|
$this->userdata->sendEmailVerificationNotification();
|
|
|
|
Auth::logout();
|
|
|
|
return redirect()->to('login')->with('info', 'You will be able to login after you verify your new email address');
|
|
}
|
|
}
|
|
|
|
return redirect()->to('profile')->with('success', 'Profile changes saved');
|
|
}
|
|
break;
|
|
|
|
case 'view':
|
|
default:
|
|
break;
|
|
}
|
|
|
|
$this->viewData = array_merge($this->viewData, [
|
|
'error' => $errorStr,
|
|
'user' => $this->userdata,
|
|
'userexccat' => User::getCategoryExclusionById($userid),
|
|
'userExcludedCategories' => $this->userdata->excludedCategories()->pluck('categories_id')->toArray(),
|
|
'success_2fa' => $success_2fa,
|
|
'error_2fa' => $error_2fa,
|
|
'google2fa_url' => $google2fa_url,
|
|
'yesno_ids' => [1, 0],
|
|
'yesno_names' => ['Yes', 'No'],
|
|
'publicview' => false,
|
|
'privileged' => $this->userdata->hasRole('Admin') || $this->userdata->hasRole('Moderator'),
|
|
'userinvitedby' => $this->userdata->invitedby ? User::find($this->userdata->invitedby) : null,
|
|
'categoriesWithSubs' => RootCategory::with(['categories' => function ($query) {
|
|
$query->where('status', 1)->orderBy('title');
|
|
}])->where('status', 1)->orderBy('title')->get(),
|
|
'meta_title' => 'Edit User Profile',
|
|
'meta_keywords' => 'edit,profile,user,details',
|
|
'meta_description' => 'Edit User Profile for '.$this->userdata->username,
|
|
]);
|
|
|
|
return view('profile.edit', $this->viewData);
|
|
}
|
|
|
|
/**
|
|
* @throws \Exception
|
|
*/
|
|
public function destroy(Request $request): Application|View|Factory|RedirectResponse|\Illuminate\Contracts\Foundation\Application
|
|
{
|
|
$userId = $request->input('id');
|
|
|
|
if ($userId !== null && (int) $userId === $this->userdata->id && ! $this->userdata->hasRole('Admin')) {
|
|
$user = User::find($userId);
|
|
if ($user === null) {
|
|
return redirect()->to('profile');
|
|
}
|
|
SendAccountDeletedEmail::dispatch($user);
|
|
Auth::logout();
|
|
$user->delete();
|
|
}
|
|
|
|
if ($this->userdata->hasRole('Admin')) {
|
|
return redirect()->to('profile');
|
|
}
|
|
|
|
return view('errors.503')->with('warning', 'Dont try to delete another user account!');
|
|
}
|
|
|
|
public function updateTheme(UpdateThemeRequest $request): JsonResponse
|
|
{
|
|
$user = Auth::user();
|
|
|
|
if (! $user) {
|
|
return response()->json(['success' => false, 'message' => 'User not authenticated'], 401);
|
|
}
|
|
|
|
if ($request->has('theme_preference')) {
|
|
$user->theme_preference = $request->input('theme_preference');
|
|
}
|
|
if ($request->has('color_scheme')) {
|
|
$user->color_scheme = $request->input('color_scheme');
|
|
}
|
|
$user->save();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'theme_preference' => $user->theme_preference,
|
|
'color_scheme' => $user->color_scheme,
|
|
]);
|
|
}
|
|
}
|