feat(main): several improvements, home page updates
This commit is contained in:
parent
1236970bef
commit
92a3972371
@ -13,6 +13,8 @@ GUIDELINES_URL="#"
|
|||||||
PRIVACY_URL="#"
|
PRIVACY_URL="#"
|
||||||
TERMS_URL="#"
|
TERMS_URL="#"
|
||||||
SOURCE_REPO="#"
|
SOURCE_REPO="#"
|
||||||
|
SUPPORT_EMAIL=
|
||||||
|
SUPPORT_URL=
|
||||||
|
|
||||||
# The auth banner is a relative path
|
# The auth banner is a relative path
|
||||||
|
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2020 Miguel Nogueira
|
|
||||||
*
|
|
||||||
* This file is part of Raspberry Staff Manager.
|
|
||||||
*
|
|
||||||
* Raspberry Staff Manager is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Raspberry Staff Manager is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Ban;
|
|
||||||
use App\Events\UserBannedEvent;
|
|
||||||
use App\Http\Requests\BanUserRequest;
|
|
||||||
use App\Services\AccountSuspensionService;
|
|
||||||
use App\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
|
|
||||||
class BanController extends Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
protected $suspensionService;
|
|
||||||
|
|
||||||
public function __construct(AccountSuspensionService $suspensionService)
|
|
||||||
{
|
|
||||||
// Inject the service via DI
|
|
||||||
$this->suspensionService = $suspensionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function insert(BanUserRequest $request, User $user)
|
|
||||||
{
|
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', __('This feature is disabled'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->authorize('create', [Ban::class, $user]);
|
|
||||||
|
|
||||||
|
|
||||||
if (!$this->suspensionService->isSuspended($user)) {
|
|
||||||
|
|
||||||
$this->suspensionService->suspend($request->reason, $request->duration, $user, $request->suspensionType);
|
|
||||||
$request->session()->flash('success', __('Account suspended.'));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
$request->session()->flash('error', __('Account already suspended!'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete(Request $request, User $user)
|
|
||||||
{
|
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', __('This feature is disabled'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->authorize('delete', $user->bans);
|
|
||||||
|
|
||||||
if ($this->suspensionService->isSuspended($user)) {
|
|
||||||
|
|
||||||
$this->suspensionService->unsuspend($user);
|
|
||||||
$request->session()->flash('success', __('Account unsuspended successfully!'));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$request->session()->flash('error', __('This account isn\'t suspended!'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
@ -26,6 +26,7 @@ use App\Exceptions\ProfileCreationFailedException;
|
|||||||
use App\Exceptions\ProfileNotFoundException;
|
use App\Exceptions\ProfileNotFoundException;
|
||||||
use App\Facades\IP;
|
use App\Facades\IP;
|
||||||
use App\Http\Requests\ProfileSave;
|
use App\Http\Requests\ProfileSave;
|
||||||
|
use App\Services\AccountSuspensionService;
|
||||||
use App\Services\ProfileService;
|
use App\Services\ProfileService;
|
||||||
use App\User;
|
use App\User;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
@ -35,7 +36,7 @@ use Spatie\Permission\Models\Role;
|
|||||||
|
|
||||||
class ProfileController extends Controller
|
class ProfileController extends Controller
|
||||||
{
|
{
|
||||||
private $profileService;
|
private ProfileService $profileService;
|
||||||
|
|
||||||
public function __construct(ProfileService $profileService) {
|
public function __construct(ProfileService $profileService) {
|
||||||
$this->profileService = $profileService;
|
$this->profileService = $profileService;
|
||||||
@ -63,7 +64,7 @@ class ProfileController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function showSingleProfile(User $user)
|
public function showSingleProfile(AccountSuspensionService $accountSuspensionService, User $user)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (is_null($user->profile)) {
|
if (is_null($user->profile)) {
|
||||||
@ -77,21 +78,10 @@ class ProfileController extends Controller
|
|||||||
$socialMediaProfiles = json_decode($user->profile->socialLinks, true);
|
$socialMediaProfiles = json_decode($user->profile->socialLinks, true);
|
||||||
$createdDate = Carbon::parse($user->created_at);
|
$createdDate = Carbon::parse($user->created_at);
|
||||||
|
|
||||||
$systemRoles = Role::all()->pluck('name')->all();
|
|
||||||
$userRoles = $user->roles->pluck('name')->all();
|
|
||||||
|
|
||||||
$roleList = [];
|
|
||||||
|
|
||||||
foreach ($systemRoles as $role) {
|
|
||||||
if (in_array($role, $userRoles)) {
|
|
||||||
$roleList[$role] = true;
|
|
||||||
} else {
|
|
||||||
$roleList[$role] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$suspensionInfo = null;
|
$suspensionInfo = null;
|
||||||
if ($user->isBanned())
|
if ($accountSuspensionService->isSuspended($user))
|
||||||
{
|
{
|
||||||
$suspensionInfo = [
|
$suspensionInfo = [
|
||||||
|
|
||||||
|
@ -22,7 +22,9 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Ban;
|
use App\Ban;
|
||||||
|
use App\Facades\IP;
|
||||||
use App\Http\Requests\Add2FASecretRequest;
|
use App\Http\Requests\Add2FASecretRequest;
|
||||||
|
use App\Http\Requests\BanUserRequest;
|
||||||
use App\Http\Requests\ChangeEmailRequest;
|
use App\Http\Requests\ChangeEmailRequest;
|
||||||
use App\Http\Requests\ChangePasswordRequest;
|
use App\Http\Requests\ChangePasswordRequest;
|
||||||
use App\Http\Requests\DeleteUserRequest;
|
use App\Http\Requests\DeleteUserRequest;
|
||||||
@ -32,6 +34,7 @@ use App\Http\Requests\SearchPlayerRequest;
|
|||||||
use App\Http\Requests\UpdateUserRequest;
|
use App\Http\Requests\UpdateUserRequest;
|
||||||
use App\Notifications\ChangedPassword;
|
use App\Notifications\ChangedPassword;
|
||||||
use App\Notifications\EmailChanged;
|
use App\Notifications\EmailChanged;
|
||||||
|
use App\Services\AccountSuspensionService;
|
||||||
use App\Traits\DisablesFeatures;
|
use App\Traits\DisablesFeatures;
|
||||||
use App\Traits\HandlesAccountDeletion;
|
use App\Traits\HandlesAccountDeletion;
|
||||||
use App\Traits\ReceivesAccountTokens;
|
use App\Traits\ReceivesAccountTokens;
|
||||||
@ -45,8 +48,15 @@ use Spatie\Permission\Models\Role;
|
|||||||
|
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
use HandlesAccountDeletion;
|
use HandlesAccountDeletion, DisablesFeatures;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows list of users
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
public function showUsers()
|
public function showUsers()
|
||||||
{
|
{
|
||||||
$this->authorize('viewPlayers', User::class);
|
$this->authorize('viewPlayers', User::class);
|
||||||
@ -59,6 +69,15 @@ class UserController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for a player with the given search query.
|
||||||
|
*
|
||||||
|
* @deprecated Until Algolia implementation
|
||||||
|
* @param SearchPlayerRequest $request
|
||||||
|
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
public function showPlayersLike(SearchPlayerRequest $request)
|
public function showPlayersLike(SearchPlayerRequest $request)
|
||||||
{
|
{
|
||||||
$this->authorize('viewPlayers', User::class);
|
$this->authorize('viewPlayers', User::class);
|
||||||
@ -85,6 +104,16 @@ class UserController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the user account's settings page
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
|
||||||
|
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
|
||||||
|
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
|
||||||
|
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
|
||||||
|
*/
|
||||||
public function showAccount(Request $request)
|
public function showAccount(Request $request)
|
||||||
{
|
{
|
||||||
$QRCode = null;
|
$QRCode = null;
|
||||||
@ -109,6 +138,49 @@ class UserController extends Controller
|
|||||||
->with('twofaQRCode', $QRCode);
|
->with('twofaQRCode', $QRCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show account management screen
|
||||||
|
*
|
||||||
|
* @param AccountSuspensionService $suspensionService
|
||||||
|
* @param Request $request
|
||||||
|
* @param User $user
|
||||||
|
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
|
public function showAcocuntManagement(AccountSuspensionService $suspensionService, Request $request, User $user)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->authorize('adminEdit', $user);
|
||||||
|
|
||||||
|
$systemRoles = Role::all()->pluck('name')->all();
|
||||||
|
$userRoles = $user->roles->pluck('name')->all();
|
||||||
|
|
||||||
|
$roleList = [];
|
||||||
|
|
||||||
|
foreach ($systemRoles as $role) {
|
||||||
|
if (in_array($role, $userRoles)) {
|
||||||
|
$roleList[$role] = true;
|
||||||
|
} else {
|
||||||
|
$roleList[$role] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('dashboard.user.manage')
|
||||||
|
->with([
|
||||||
|
'user' => $user,
|
||||||
|
'roles' => $roleList,
|
||||||
|
'ipInfo' => IP::lookup($request->ip())
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log out other sessions for the current user
|
||||||
|
*
|
||||||
|
* @param FlushSessionsRequest $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
* @throws \Illuminate\Auth\AuthenticationException
|
||||||
|
*/
|
||||||
public function flushSessions(FlushSessionsRequest $request)
|
public function flushSessions(FlushSessionsRequest $request)
|
||||||
{
|
{
|
||||||
// TODO: Move all log calls to a listener, which binds to an event fired by each significant event, such as this one
|
// TODO: Move all log calls to a listener, which binds to an event fired by each significant event, such as this one
|
||||||
@ -127,6 +199,14 @@ class UserController extends Controller
|
|||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the current user's password
|
||||||
|
*
|
||||||
|
* @param ChangePasswordRequest $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse|void
|
||||||
|
*/
|
||||||
public function changePassword(ChangePasswordRequest $request)
|
public function changePassword(ChangePasswordRequest $request)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
if (config('demo.is_enabled')) {
|
||||||
@ -155,13 +235,17 @@ class UserController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the current user's email address
|
||||||
|
*
|
||||||
|
* @param ChangeEmailRequest $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
public function changeEmail(ChangeEmailRequest $request)
|
public function changeEmail(ChangeEmailRequest $request)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
$this->disable();
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', __('This feature is disabled'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = User::find(Auth::user()->id);
|
$user = User::find(Auth::user()->id);
|
||||||
|
|
||||||
@ -184,13 +268,18 @@ class UserController extends Controller
|
|||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the given user's account
|
||||||
|
*
|
||||||
|
* @param DeleteUserRequest $request
|
||||||
|
* @param User $user
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
public function delete(DeleteUserRequest $request, User $user)
|
public function delete(DeleteUserRequest $request, User $user)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
$this->disable();
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', _('This feature is disabled'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->authorize('delete', $user);
|
$this->authorize('delete', $user);
|
||||||
|
|
||||||
@ -204,14 +293,19 @@ class UserController extends Controller
|
|||||||
return redirect()->route('registeredPlayerList');
|
return redirect()->route('registeredPlayerList');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a given user's details
|
||||||
|
*
|
||||||
|
* @param UpdateUserRequest $request
|
||||||
|
* @param User $user
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
public function update(UpdateUserRequest $request, User $user)
|
public function update(UpdateUserRequest $request, User $user)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', __('This feature is disabled'));
|
|
||||||
}
|
|
||||||
$this->authorize('adminEdit', $user);
|
$this->authorize('adminEdit', $user);
|
||||||
|
$this->disable();
|
||||||
|
|
||||||
// Mass update would not be possible here without extra code, making route model binding useless
|
// Mass update would not be possible here without extra code, making route model binding useless
|
||||||
$user->email = $request->email;
|
$user->email = $request->email;
|
||||||
@ -243,6 +337,16 @@ class UserController extends Controller
|
|||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate and add a 2FA secret for the current user
|
||||||
|
*
|
||||||
|
* @param Add2FASecretRequest $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
|
||||||
|
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
|
||||||
|
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
|
||||||
|
*/
|
||||||
public function add2FASecret(Add2FASecretRequest $request)
|
public function add2FASecret(Add2FASecretRequest $request)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
if (config('demo.is_enabled')) {
|
||||||
@ -285,6 +389,13 @@ class UserController extends Controller
|
|||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the current user's two factor secret key
|
||||||
|
*
|
||||||
|
* @param Remove2FASecretRequest $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
public function remove2FASecret(Remove2FASecretRequest $request)
|
public function remove2FASecret(Remove2FASecretRequest $request)
|
||||||
{
|
{
|
||||||
Log::warning('SECURITY: Disabling two factor authentication (user initiated)', [
|
Log::warning('SECURITY: Disabling two factor authentication (user initiated)', [
|
||||||
@ -300,6 +411,15 @@ class UserController extends Controller
|
|||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demote the given user's privileges
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param User $user
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
public function terminate(Request $request, User $user)
|
public function terminate(Request $request, User $user)
|
||||||
{
|
{
|
||||||
$this->authorize('terminate', User::class);
|
$this->authorize('terminate', User::class);
|
||||||
@ -330,4 +450,58 @@ class UserController extends Controller
|
|||||||
//TODO: Dispatch event
|
//TODO: Dispatch event
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suspend the given user
|
||||||
|
*
|
||||||
|
* @param AccountSuspensionService $suspensionService
|
||||||
|
* @param BanUserRequest $request
|
||||||
|
* @param User $user
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
|
public function suspend(AccountSuspensionService $suspensionService, BanUserRequest $request, User $user)
|
||||||
|
{
|
||||||
|
$this->authorize('create', [Ban::class, $user]);
|
||||||
|
$this->disable();
|
||||||
|
|
||||||
|
if (!$suspensionService->isSuspended($user)) {
|
||||||
|
|
||||||
|
$suspensionService->suspend($request->reason, $request->duration, $user, $request->suspensionType);
|
||||||
|
$request->session()->flash('success', __('Account suspended.'));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$request->session()->flash('error', __('Account already suspended!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsuspend the given user
|
||||||
|
*
|
||||||
|
* @param AccountSuspensionService $suspensionService
|
||||||
|
* @param Request $request
|
||||||
|
* @param User $user
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
|
public function unsuspend(AccountSuspensionService $suspensionService, Request $request, User $user)
|
||||||
|
{
|
||||||
|
$this->authorize('delete', $user->bans);
|
||||||
|
$this->disable();
|
||||||
|
|
||||||
|
if ($suspensionService->isSuspended($user)) {
|
||||||
|
|
||||||
|
$suspensionService->unsuspend($user);
|
||||||
|
$request->session()->flash('success', __('Account unsuspended successfully!'));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$request->session()->flash('error', __('This account isn\'t suspended!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
30
app/Listeners/NewUser.php
Executable file
30
app/Listeners/NewUser.php
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Listeners;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
|
||||||
|
class NewUser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the event listener.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the event.
|
||||||
|
*
|
||||||
|
* @param object $event
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle($event)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
@ -120,6 +120,17 @@ class AccountSuspensionService
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the reason for the user's suspension.
|
||||||
|
*
|
||||||
|
* @param User $user The user account to check
|
||||||
|
* @return string|bool Reason for the suspension, false if not suspended
|
||||||
|
*/
|
||||||
|
public function getSuspensionReason(User $user): string|bool {
|
||||||
|
return ($this->isSuspended($user)) ? $user->bans->reason : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether an account is locked
|
* Checks whether an account is locked
|
||||||
*
|
*
|
||||||
|
25
app/Traits/DisablesFeatures.php
Executable file
25
app/Traits/DisablesFeatures.php
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Traits;
|
||||||
|
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
|
||||||
|
trait DisablesFeatures
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if demo mode is active. If so, it stops any more logic from running.
|
||||||
|
*
|
||||||
|
* @return RedirectResponse|null
|
||||||
|
*/
|
||||||
|
protected function disable(): RedirectResponse|null
|
||||||
|
{
|
||||||
|
if (config('demo.is_enabled')) {
|
||||||
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->with('error', __('This feature is disabled'));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -71,6 +71,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||||||
public function votes()
|
public function votes()
|
||||||
{
|
{
|
||||||
return $this->hasMany('App\Vote', 'userID', 'id');
|
return $this->hasMany('App\Vote', 'userID', 'id');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function profile()
|
public function profile()
|
||||||
|
@ -110,6 +110,8 @@ return [
|
|||||||
| RBRecruiter will display these URLs at appropriate locations and force users to accept them,
|
| RBRecruiter will display these URLs at appropriate locations and force users to accept them,
|
||||||
| if legally necessary, such as in the registration & application form pages.
|
| if legally necessary, such as in the registration & application form pages.
|
||||||
|
|
|
|
||||||
|
| Additionally, you can also specify a support email and URL where your users/customers can send inquiries if necessary.
|
||||||
|
|
|
||||||
| You can leave these URLs empty if your website hasn't entered production yet, but we recommend
|
| You can leave these URLs empty if your website hasn't entered production yet, but we recommend
|
||||||
| you draft these documents as soon as possible.
|
| you draft these documents as soon as possible.
|
||||||
|
|
|
|
||||||
@ -118,6 +120,8 @@ return [
|
|||||||
'terms_url' => env('TERMS_URL', '#'),
|
'terms_url' => env('TERMS_URL', '#'),
|
||||||
'privacy_url' => env('PRIVACY_URL', '#'),
|
'privacy_url' => env('PRIVACY_URL', '#'),
|
||||||
'guidelines_url' => env('GUIDELINES_URL', '#'),
|
'guidelines_url' => env('GUIDELINES_URL', '#'),
|
||||||
|
'support_url' => env('SUPPORT_URL', 'https://support.example.com'),
|
||||||
|
'support_email' => env('SUPPORT_EMAIL', 'support@example.com'),
|
||||||
'source_repo' => env('SOURCE_REPO', 'https://code.webvokestudio.pt/miguel456/rbrecruiter'),
|
'source_repo' => env('SOURCE_REPO', 'https://code.webvokestudio.pt/miguel456/rbrecruiter'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
23
database/factories/ProfileFactory.php
Executable file
23
database/factories/ProfileFactory.php
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Profile>
|
||||||
|
*/
|
||||||
|
class ProfileFactory extends Factory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Define the model's default state.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function definition()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -1,47 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2020 Miguel Nogueira
|
|
||||||
*
|
|
||||||
* This file is part of Raspberry Staff Manager.
|
|
||||||
*
|
|
||||||
* Raspberry Staff Manager is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Raspberry Staff Manager is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\User;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
use Faker\Generator as Faker;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|--------------------------------------------------------------------------
|
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\User>
|
||||||
| Model Factories
|
*/
|
||||||
|--------------------------------------------------------------------------
|
class UserFactory extends Factory
|
||||||
|
|
{
|
||||||
| This directory should contain each of the model factory definitions for
|
/**
|
||||||
| your application. Factories provide a convenient way to generate new
|
* Define the model's default state.
|
||||||
| model instances for testing / seeding your application's database.
|
*
|
||||||
|
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
|
public function definition()
|
||||||
$factory->define(User::class, function (Faker $faker) {
|
{
|
||||||
return [
|
return [
|
||||||
'name' => $faker->name,
|
//
|
||||||
'email' => $faker->unique()->safeEmail,
|
];
|
||||||
'email_verified_at' => now(),
|
}
|
||||||
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
|
}
|
||||||
'remember_token' => Str::random(10),
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
@ -103,7 +103,8 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>{{$user->created_at}}</td>
|
<td>{{$user->created_at}}</td>
|
||||||
<td>
|
<td>
|
||||||
<button type="button" class="btn btn-sm btn-success" onclick="window.location.href='{{route('showSingleProfile', ['user' => $user->id])}}'"><i class="fa fa-eye"></i></button>
|
<button type="button" class="btn btn-sm btn-success" onclick="window.location.href='{{route('showSingleProfile', ['user' => $user->id])}}'"><i class="fa fa-eye"></i> {{ __('View') }}</button>
|
||||||
|
<a class="ml-2 btn btn-sm btn-warning" href="{{ route('manageUser', ['user' => $user->id]) }}"><i class="fas fa-wrench"></i> {{ __('Manage') }}</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
211
resources/views/dashboard/user/manage.blade.php
Executable file
211
resources/views/dashboard/user/manage.blade.php
Executable file
@ -0,0 +1,211 @@
|
|||||||
|
@extends('adminlte::page')
|
||||||
|
|
||||||
|
@section('title', config('app.name') . ' | ' . __('Account Management'))
|
||||||
|
|
||||||
|
@section('content_header')
|
||||||
|
|
||||||
|
<h4>{{ __('Users / Accounts / :username / Manage', ['username' => $user->name]) }}</h4>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('js')
|
||||||
|
<script src="/js/app.js"></script>
|
||||||
|
<x-global-errors></x-global-errors>
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<x-modal id="banAccountModal" modal-label="banAccount" modal-title="{{__('Please confirm')}}" include-close-button="true">
|
||||||
|
|
||||||
|
<p>{{__("Please confirm that you want to suspend this account. You'll need to add a reason and expiration date to confirm this.")}}</p>
|
||||||
|
|
||||||
|
<form id="banAccountForm" name="banAccount" method="POST" action="{{route('banUser', ['user' => $user->id])}}">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
@if($demoActive)
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<p class="font-weight-bold"><i class="fas fa-exclamation-triangle"></i> {{ __('This feature is disabled') }}</p>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
<label for="reason">{{__('Public note')}}</label>
|
||||||
|
<input type="text" name="reason" id="reason" class="form-control" placeholder="{{__('e.g. Spamming')}}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
<label for="duration">{{ __('Duration') }}</label>
|
||||||
|
<input type="text" name="duration" id="duration" class="form-control" placeholder="{{ __('in days') }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="mt-2">
|
||||||
|
<input type="hidden" name="suspensionType" value="off">
|
||||||
|
|
||||||
|
<label for="suspensionType">{{ __('Suspension type') }}</label><br>
|
||||||
|
<input type="checkbox" id="suspensionType" name="suspensionType" checked data-toggle="toggle" data-on="Temporary" data-off="Permanent" data-onstyle="success" data-offstyle="danger" data-width="130" data-height="40">
|
||||||
|
<p class="text-muted text-sm"><i class="fas fa-info-circle"></i> {{ __('Temporary suspensions will be automatically lifted. The suspension note is visible to all users. Suspended users will not be able to login or register.') }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<x-slot name="modalFooter">
|
||||||
|
<button id="banAccountButton" type="button" class="btn btn-danger" {{ ($demoActive) ? 'disabled' : '' }} ><i class="fa fa-gavel"></i> {{__('Confirm')}}</button>
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
|
</x-modal>
|
||||||
|
|
||||||
|
@if (!Auth::user()->is($user) && $user->isStaffMember())
|
||||||
|
<x-modal id="terminateUser" modal-label="terminateUser" modal-title="{{__('Please Confirm')}}" include-close-button="true">
|
||||||
|
|
||||||
|
@if($demoActive)
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<p class="font-weight-bold"><i class="fas fa-exclamation-triangle"></i> {{ __('This feature is disabled') }}</p>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<p><i class="fa fa-exclamation-triangle"></i> <b>{{__('You are about to terminate a recruited staff member')}}</b></p>
|
||||||
|
<p>
|
||||||
|
{{__('Terminating a staff member will remove their privileges on the application management site and connected integrations configured for the vacancy they applied for.')}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>{{__('THIS PROCESS IS IRREVERSIBLE AND IMMEDIATE')}}</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<x-slot name="modalFooter">
|
||||||
|
|
||||||
|
<form method="POST" action="{{route('terminateStaffMember', ['user' => $user->id])}}" id="terminateUserForm">
|
||||||
|
@csrf
|
||||||
|
@method('PATCH')
|
||||||
|
<button type="submit" class="btn btn-warning" {{ ($demoActive) ? 'disabled' : '' }}><i class="fas fa-exclamation-circle"></i> {{__('Confirm')}}</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
|
</x-modal>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<x-modal id="deleteAccount" modal-label="deleteAccount" modal-title="{{__('Confirm')}}" include-close-button="true">
|
||||||
|
|
||||||
|
@if($demoActive)
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<p class="font-weight-bold"><i class="fas fa-exclamation-triangle"></i> {{ __('This feature is disabled') }}</p>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<p><i class="fa fa-exclamation-triangle"></i><b> {{__('WARNING: This is a potentially destructive action!')}}</b></p>
|
||||||
|
|
||||||
|
<p>{{__("Deleting a user's account is an irreversible process. Historic and current applications, votes, and profile content, as well as any personally identifiable information will be immediately erased.")}}</p>
|
||||||
|
|
||||||
|
<form id="deleteAccountForm" method="POST" action={{route('deleteUser', ['user' => $user->id])}}>
|
||||||
|
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
|
||||||
|
<label for="promptConfirm">{{__('Type to confirm: ')}} "DELETE ACCOUNT"</label>
|
||||||
|
<input type="text" name="confirmPrompt" class="form-control" placeholder="{{__('Please type the above text')}}">
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<x-slot name="modalFooter">
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-danger" {{ ($demoActive) ? 'disabled' : '' }} onclick="document.getElementById('deleteAccountForm').submit()"><i class="fa fa-trash"></i> {{strtoupper(__('Confirm'))}}</button>
|
||||||
|
|
||||||
|
</x-slot>
|
||||||
|
</x-modal>
|
||||||
|
|
||||||
|
|
||||||
|
<x-modal id="editUser" modal-label="editUser" modal-title="{{__('Edit account')}}" include-close-button="true">
|
||||||
|
|
||||||
|
@if($demoActive)
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<p class="font-weight-bold"><i class="fas fa-exclamation-triangle"></i> {{ __('This feature is disabled') }}</p>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<form id="updateUserForm" method="post" action="{{ route('updateUser', ['user' => $user->id]) }}">
|
||||||
|
@csrf
|
||||||
|
@method('PATCH')
|
||||||
|
|
||||||
|
<label for="email">{{__('Email')}}</label>
|
||||||
|
<input {{ ($demoActive) ? 'disabled' : '' }} id="email" type="text" name="email" class="form-control" required value="{{ $user->email }}" />
|
||||||
|
|
||||||
|
<label for="name">{{__('Name')}}</label>
|
||||||
|
<input {{ ($demoActive) ? 'disabled' : '' }} id="name" type="text" name="name" class="form-control" required value="{{ $user->name }}" />
|
||||||
|
|
||||||
|
<label for="uuid">{{ __('Mojang UUID (deprecated)') }}</label>
|
||||||
|
<input {{ ($demoActive) ? 'disabled' : '' }} id="uuid" type="text" name="uuid" class="form-control" required value="{{ $user->uuid ?? "disabled" }}" />
|
||||||
|
<p class="text-muted text-sm">
|
||||||
|
<i class="fas fa-exclamation-triangle"></i> {{__('If the setting "Require Valid Game License" is activated, editing this field may have unintended consequences. Proceed with caution.')}}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="form-group mt-3">
|
||||||
|
|
||||||
|
<label>{{__('Roles')}}</label>
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
@foreach($roles as $roleName => $status)
|
||||||
|
<tr>
|
||||||
|
<th><input {{ ($demoActive) ? 'disabled' : '' }} type="checkbox" name="roles[]" value="{{ $roleName }}" {{ ($status) ? 'checked' : '' }}></th>
|
||||||
|
<td class="col-md-2">{{ ucfirst($roleName) }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<x-slot name="modalFooter">
|
||||||
|
|
||||||
|
<button type="button" {{ ($demoActive) ? 'disabled' : '' }} class="btn btn-warning" onclick="$('#updateUserForm').submit()"><i class="fa fa-exclamation-cicle"></i> {{__('Save changes')}}</button>
|
||||||
|
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
|
</x-modal>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
|
||||||
|
<div class="card-header">
|
||||||
|
<h3>{{ __('Account data') }}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
|
||||||
|
@section('footer')
|
||||||
|
@include('breadcrumbs.dashboard.footer')
|
||||||
|
@stop
|
@ -34,256 +34,6 @@
|
|||||||
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if (Auth::user()->hasRole('admin'))
|
|
||||||
|
|
||||||
<x-modal id="banAccountModal" modal-label="banAccount" modal-title="{{__('Please confirm')}}" include-close-button="true">
|
|
||||||
|
|
||||||
<p>{{__("Please confirm that you want to suspend this account. You'll need to add a reason and expiration date to confirm this.")}}</p>
|
|
||||||
|
|
||||||
<form id="banAccountForm" name="banAccount" method="POST" action="{{route('banUser', ['user' => $profile->user->id])}}">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
@if($demoActive)
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<p class="font-weight-bold"><i class="fas fa-exclamation-triangle"></i> {{ __('This feature is disabled') }}</p>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label for="reason">{{__('Public note')}}</label>
|
|
||||||
<input type="text" name="reason" id="reason" class="form-control" placeholder="{{__('e.g. Spamming')}}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label for="duration">{{ __('Duration') }}</label>
|
|
||||||
<input type="text" name="duration" id="duration" class="form-control" placeholder="{{ __('in days') }}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="mt-2">
|
|
||||||
<input type="hidden" name="suspensionType" value="off">
|
|
||||||
|
|
||||||
<label for="suspensionType">{{ __('Suspension type') }}</label><br>
|
|
||||||
<input type="checkbox" id="suspensionType" name="suspensionType" checked data-toggle="toggle" data-on="Temporary" data-off="Permanent" data-onstyle="success" data-offstyle="danger" data-width="130" data-height="40">
|
|
||||||
<p class="text-muted text-sm"><i class="fas fa-info-circle"></i> {{ __('Temporary suspensions will be automatically lifted. The suspension note is visible to all users. Suspended users will not be able to login or register.') }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<x-slot name="modalFooter">
|
|
||||||
<button id="banAccountButton" type="button" class="btn btn-danger" {{ ($demoActive) ? 'disabled' : '' }} ><i class="fa fa-gavel"></i> {{__('Confirm')}}</button>
|
|
||||||
</x-slot>
|
|
||||||
|
|
||||||
</x-modal>
|
|
||||||
|
|
||||||
@if (!Auth::user()->is($profile->user) && $profile->user->isStaffMember())
|
|
||||||
<x-modal id="terminateUser" modal-label="terminateUser" modal-title="{{__('Please Confirm')}}" include-close-button="true">
|
|
||||||
|
|
||||||
@if($demoActive)
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<p class="font-weight-bold"><i class="fas fa-exclamation-triangle"></i> {{ __('This feature is disabled') }}</p>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<p><i class="fa fa-exclamation-triangle"></i> <b>{{__('You are about to terminate a recruited staff member')}}</b></p>
|
|
||||||
<p>
|
|
||||||
{{__('Terminating a staff member will remove their privileges on the application management site and connected integrations configured for the vacancy they applied for.')}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<b>{{__('THIS PROCESS IS IRREVERSIBLE AND IMMEDIATE')}}</b>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<x-slot name="modalFooter">
|
|
||||||
|
|
||||||
<form method="POST" action="{{route('terminateStaffMember', ['user' => $profile->user->id])}}" id="terminateUserForm">
|
|
||||||
@csrf
|
|
||||||
@method('PATCH')
|
|
||||||
<button type="submit" class="btn btn-warning" {{ ($demoActive) ? 'disabled' : '' }}><i class="fas fa-exclamation-circle"></i> {{__('Confirm')}}</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</x-slot>
|
|
||||||
|
|
||||||
</x-modal>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<x-modal id="deleteAccount" modal-label="deleteAccount" modal-title="{{__('Confirm')}}" include-close-button="true">
|
|
||||||
|
|
||||||
@if($demoActive)
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<p class="font-weight-bold"><i class="fas fa-exclamation-triangle"></i> {{ __('This feature is disabled') }}</p>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<p><i class="fa fa-exclamation-triangle"></i><b> {{__('WARNING: This is a potentially destructive action!')}}</b></p>
|
|
||||||
|
|
||||||
<p>{{__("Deleting a user's account is an irreversible process. Historic and current applications, votes, and profile content, as well as any personally identifiable information will be immediately erased.")}}</p>
|
|
||||||
|
|
||||||
<form id="deleteAccountForm" method="POST" action={{route('deleteUser', ['user' => $profile->user->id])}}>
|
|
||||||
|
|
||||||
@csrf
|
|
||||||
@method('DELETE')
|
|
||||||
|
|
||||||
<label for="promptConfirm">{{__('Type to confirm: ')}} "DELETE ACCOUNT"</label>
|
|
||||||
<input type="text" name="confirmPrompt" class="form-control" placeholder="{{__('Please type the above text')}}">
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<x-slot name="modalFooter">
|
|
||||||
|
|
||||||
<button type="button" class="btn btn-danger" {{ ($demoActive) ? 'disabled' : '' }} onclick="document.getElementById('deleteAccountForm').submit()"><i class="fa fa-trash"></i> {{strtoupper(__('Confirm'))}}</button>
|
|
||||||
|
|
||||||
</x-slot>
|
|
||||||
</x-modal>
|
|
||||||
|
|
||||||
<x-modal id="ipInfo" modal-label="ipInfo" modal-title="{{__('IP Address Information')}}" include-close-button="true">
|
|
||||||
|
|
||||||
<h4 class="text-center">{{__('Search results')}}</h4>
|
|
||||||
|
|
||||||
@if (!isset($ipInfo->message))
|
|
||||||
|
|
||||||
<table class="table table-borderless">
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('Origin country')}}</th>
|
|
||||||
<td>{{$ipInfo->country_name ?? 'N/A'}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('State/Province')}}</th>
|
|
||||||
<td>{{$ipInfo->state_prov ?? 'None'}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('District (if any)')}}</th>
|
|
||||||
<td>{{$ipInfo->district ?? 'N/A'}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('City')}}</th>
|
|
||||||
<td>{{$ipInfo->city ?? 'N/A'}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('Postal code')}}</th>
|
|
||||||
<td>{{$ipInfo->zipcode ?? 'N/A'}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('Geographical coordinates')}}</th>
|
|
||||||
<td>{{$ipInfo->latitude ?? 0}}, {{$ipInfo->longitude ?? 0}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('European?')}}</th>
|
|
||||||
<td>{{($ipInfo->is_eu) ? __('Yes') : __('No')}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('ISP')}}</th>
|
|
||||||
<td>{{$ipInfo->isp ?? 'N/A'}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('Organization')}}</th>
|
|
||||||
<td>{{$ipInfo->organization ?? 'N/A'}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('Connection type (e.g. datacenter, home)')}}</th>
|
|
||||||
<td>{{$ipInfo->connection_type ?? 'N/A'}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>{{__('Timezone')}}</th>
|
|
||||||
<td>{{$ipInfo->time_zone->name ?? __('N/A')}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
@else
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
|
|
||||||
<i class="fas fa-exclamation-circle"></i> <b>{{__("This query didn't return any results.")}}</b>
|
|
||||||
<p>
|
|
||||||
{{$ipInfo->message}}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<x-slot name="modalFooter"></x-slot>
|
|
||||||
</x-modal>
|
|
||||||
|
|
||||||
<x-modal id="editUser" modal-label="editUser" modal-title="{{__('Edit account')}}" include-close-button="true">
|
|
||||||
|
|
||||||
@if($demoActive)
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<p class="font-weight-bold"><i class="fas fa-exclamation-triangle"></i> {{ __('This feature is disabled') }}</p>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<form id="updateUserForm" method="post" action="{{ route('updateUser', ['user' => $profile->user->id]) }}">
|
|
||||||
@csrf
|
|
||||||
@method('PATCH')
|
|
||||||
|
|
||||||
<label for="email">{{__('Email')}}</label>
|
|
||||||
<input {{ ($demoActive) ? 'disabled' : '' }} id="email" type="text" name="email" class="form-control" required value="{{ $profile->user->email }}" />
|
|
||||||
|
|
||||||
<label for="name">{{__('Name')}}</label>
|
|
||||||
<input {{ ($demoActive) ? 'disabled' : '' }} id="name" type="text" name="name" class="form-control" required value="{{ $profile->user->name }}" />
|
|
||||||
|
|
||||||
<label for="uuid">{{ __('Mojang UUID (deprecated)') }}</label>
|
|
||||||
<input {{ ($demoActive) ? 'disabled' : '' }} id="uuid" type="text" name="uuid" class="form-control" required value="{{ $profile->user->uuid ?? "disabled" }}" />
|
|
||||||
<p class="text-muted text-sm">
|
|
||||||
<i class="fas fa-exclamation-triangle"></i> {{__('If the setting "Require Valid Game License" is activated, editing this field may have unintended consequences. Proceed with caution.')}}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="form-group mt-3">
|
|
||||||
|
|
||||||
<label>{{__('Roles')}}</label>
|
|
||||||
<table class="table table-borderless">
|
|
||||||
<tbody>
|
|
||||||
|
|
||||||
@foreach($roles as $roleName => $status)
|
|
||||||
<tr>
|
|
||||||
<th><input {{ ($demoActive) ? 'disabled' : '' }} type="checkbox" name="roles[]" value="{{ $roleName }}" {{ ($status) ? 'checked' : '' }}></th>
|
|
||||||
<td class="col-md-2">{{ ucfirst($roleName) }}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<x-slot name="modalFooter">
|
|
||||||
|
|
||||||
<button type="button" {{ ($demoActive) ? 'disabled' : '' }} class="btn btn-warning" onclick="$('#updateUserForm').submit()"><i class="fa fa-exclamation-cicle"></i> {{__('Save changes')}}</button>
|
|
||||||
|
|
||||||
</x-slot>
|
|
||||||
|
|
||||||
</x-modal>
|
|
||||||
|
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@ -316,14 +66,9 @@
|
|||||||
|
|
||||||
<p class="text-muted">{{$profile->profileShortBio}}</p>
|
<p class="text-muted">{{$profile->profileShortBio}}</p>
|
||||||
<p class="text-muted">{{__('Member since :date', ['date' => $since])}}</p>
|
<p class="text-muted">{{__('Member since :date', ['date' => $since])}}</p>
|
||||||
@if (Auth::user()->hasRole('admin'))
|
|
||||||
<button type="button" class="btn btn-sm btn-info" onclick="$('#ipInfo').modal('show')">{{__('Lookup :ipAddress', ['ipAddress' => ($shouldCollect) ? $profile->user->originalIP : '0.0.0.0'])}}</button>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($profile->user->is(Auth::user()))
|
@if ($profile->user->is(Auth::user()))
|
||||||
<button type="button" class="btn btn-sm btn-warning" onclick="window.location.href='{{route('showProfileSettings')}}'"><i class="fas fa-pencil-alt"></i></button>
|
<button type="button" class="btn btn-sm btn-warning" onclick="window.location.href='{{route('showProfileSettings')}}'"><i class="fas fa-pencil-alt"></i></button>
|
||||||
@elseif (Auth::user()->hasRole('admin') && $profile->user->isStaffMember())
|
|
||||||
<button type="button" class="btn btn-sm btn-danger" onclick="$('#terminateUser').modal('show')">{{__('Terminate Staff Member')}}</button>
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -342,46 +87,6 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (Auth::user()->hasRole('admin'))
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h5 class="card-header">
|
|
||||||
<a class="collapsed d-block" data-toggle="collapse" href="#collapse-collapsed" aria-expanded="true" aria-controls="collapse-collapsed" id="heading-collapsed">
|
|
||||||
<i class="fa fa-chevron-down pull-right"></i>
|
|
||||||
{{__('Account management (admin)')}}
|
|
||||||
</a>
|
|
||||||
</h5>
|
|
||||||
<div id="collapse-collapsed" class="collapse" aria-labelledby="heading-collapsed">
|
|
||||||
<div class="card-body">
|
|
||||||
|
|
||||||
<div class="management-btn text-center">
|
|
||||||
|
|
||||||
@if (!$profile->user->isBanned())
|
|
||||||
<button class="btn btn-danger mb-2" id="banAccountTrigger"><i class="fa fa-ban"></i> {{__('Suspend')}}</button><br>
|
|
||||||
@else
|
|
||||||
<form method="post" action="{{route('unbanUser', ['user' => $profile->user->id])}}">
|
|
||||||
|
|
||||||
@method('DELETE')
|
|
||||||
@csrf
|
|
||||||
<button type="submit" class="btn btn-warning mb-2"><i class="fa fa-check"></i> {{__('Lift Suspension')}}</button>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
@endif
|
|
||||||
<button class="btn btn-danger mb-2" onclick="$('#deleteAccount').modal('show')"><i class="fas fa-trash-alt"></i> {{__('Delete Account')}}</button><br>
|
|
||||||
|
|
||||||
<button class="btn btn-warning mb-2" onclick="$('#editUser').modal('show')"><i class="fas fa-pencil-alt"></i> {{__('Edit Account')}}</button><br>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div><!-- .col -->
|
|
||||||
@endif
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row buttonBar">
|
<div class="row buttonBar">
|
||||||
|
@ -56,36 +56,6 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-8">
|
|
||||||
|
|
||||||
<div class="jumbotron">
|
|
||||||
|
|
||||||
<h1 class="display-4">Junte-se ao nosso Discord!</h1>
|
|
||||||
<p class="lead">O Discord é o coração da nossa comunidade — onde toda a diversão acontece.</p>
|
|
||||||
<hr class="my-4">
|
|
||||||
<p>Venha conhecer a nossa comunidade de perto aderindo ao nosso servidor Discord. Conheça novos amigos, jogos, vários minigames divertidos e fale com a nossa equipe amigável! Todo mundo é bem-vindo.</p>
|
|
||||||
<p>Registre-se também no nosso portal online, que lhe permite gerir suas candidaturas à nossa equipe, ligar a sua conta Discord (e receber vantagens no servidor!), ver o diretório de usuários, fazer doação e muito mais!</p>
|
|
||||||
<p class="lead">
|
|
||||||
<a class="btn btn-primary btn-lg" href="https://discord.gg/tbxKEEeBpf" role="button">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-discord" viewBox="0 0 16 16">
|
|
||||||
<path d="M6.552 6.712c-.456 0-.816.4-.816.888s.368.888.816.888c.456 0 .816-.4.816-.888.008-.488-.36-.888-.816-.888zm2.92 0c-.456 0-.816.4-.816.888s.368.888.816.888c.456 0 .816-.4.816-.888s-.36-.888-.816-.888z"/>
|
|
||||||
<path d="M13.36 0H2.64C1.736 0 1 .736 1 1.648v10.816c0 .912.736 1.648 1.64 1.648h9.072l-.424-1.48 1.024.952.968.896L15 16V1.648C15 .736 14.264 0 13.36 0zm-3.088 10.448s-.288-.344-.528-.648c1.048-.296 1.448-.952 1.448-.952-.328.216-.64.368-.92.472-.4.168-.784.28-1.16.344a5.604 5.604 0 0 1-2.072-.008 6.716 6.716 0 0 1-1.176-.344 4.688 4.688 0 0 1-.584-.272c-.024-.016-.048-.024-.072-.04-.016-.008-.024-.016-.032-.024-.144-.08-.224-.136-.224-.136s.384.64 1.4.944c-.24.304-.536.664-.536.664-1.768-.056-2.44-1.216-2.44-1.216 0-2.576 1.152-4.664 1.152-4.664 1.152-.864 2.248-.84 2.248-.84l.08.096c-1.44.416-2.104 1.048-2.104 1.048s.176-.096.472-.232c.856-.376 1.536-.48 1.816-.504.048-.008.088-.016.136-.016a6.521 6.521 0 0 1 4.024.752s-.632-.6-1.992-1.016l.112-.128s1.096-.024 2.248.84c0 0 1.152 2.088 1.152 4.664 0 0-.68 1.16-2.448 1.216z"/>
|
|
||||||
</svg> Aderir ao Discord</a>
|
|
||||||
<a class="btn btn-primary btn-lg" href="{{route('register')}}" role="button"><i class="fas fa-plus"></i> Aderir ao portal</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col text-center">
|
|
||||||
<iframe src="https://discord.com/widget?id=866521211550433301&theme=dark" width="350px" height="95%" allowtransparency="true" frameborder="0" sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"></iframe>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row mt-5">
|
<div class="row mt-5">
|
||||||
|
|
||||||
@ -183,118 +153,13 @@
|
|||||||
|
|
||||||
<div class="col text-center">
|
<div class="col text-center">
|
||||||
|
|
||||||
<h3>Convencido?</h3>
|
<h3>{{ __('A gestão da :appName responde a todas candidaturas dentro de 48 horas.', ['appName' => config('app.name')]) }}</h3>
|
||||||
|
<p>{!! __('Se você tiver algum dúvida sobre a sua conta de recrutamento, candidatura, ou qualquer outra questão, visite o nosso <a href=":supportURL" target="_blank">site de atendimento</a>, ou <a href="mailto::supportEmail">envie-nos um email</a>.', ['supportURL' => config('app.support_url'), 'supportEmail' => config('app.support_email')]) !!}</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col text-center">
|
|
||||||
<p>
|
|
||||||
Esperamos você! Junte-se hoje e desfrute de uma nova experiência.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row text-center mt-5 mb-4">
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
<h3>{{__('Any questions? Leave a message!')}}</h3>
|
|
||||||
<p class="text-muted">{{__('*This is not an application form. Any applications sent here will be ignored. Additionally, please keep messages on topic (about this site only). For anything else, please use other contact options available.')}}</p>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row text-center">
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<form method="POST" action="{{route('sendSubmission')}}" id="contactForm">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<!-- Tamper warning: Your captcha will fail if you modify this value programmatically/manually. -->
|
|
||||||
<input type="hidden" name="captcha" id="captcha">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="md-form">
|
|
||||||
|
|
||||||
<input type="text" name="name" class="form-control" id="firstName">
|
|
||||||
<label for="firstName">{{__('Name')}}</label>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
|
|
||||||
<div class="md-form">
|
|
||||||
|
|
||||||
<input type="email" name="email" class="form-control" id="email">
|
|
||||||
<label for="email">{{__('Email')}}</label>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-md-12">
|
|
||||||
|
|
||||||
<div class="md-form">
|
|
||||||
|
|
||||||
<input type="text" name="subject" id="subject" class="form-control">
|
|
||||||
<label for="subject">{{__('Subject')}}</label>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-12">
|
|
||||||
|
|
||||||
<div class="md-form">
|
|
||||||
|
|
||||||
<textarea rows="3" name="msg" id="message" class="md-textarea form-control" placeholder="{{ __('Your message') }}"></textarea>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row text-center">
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function gcallback(response)
|
|
||||||
{
|
|
||||||
document.getElementById('captcha').value = response
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- align: deprecated cheap hack, but quick -->
|
|
||||||
<div align="center" class="g-recaptcha pb-3" data-callback="gcallback" data-sitekey="{{config('recaptcha.keys.sitekey')}}"></div>
|
|
||||||
|
|
||||||
<button type="button" class="btn btn-info" onclick="document.getElementById('contactForm').submit()">{{__('Send')}}</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -291,18 +291,22 @@ Route::group(['prefix' => LaravelLocalization::setLocale(), 'middleware' => ['lo
|
|||||||
Route::patch('settings/game/update', [OptionsController::class, 'saveGameIntegration'])
|
Route::patch('settings/game/update', [OptionsController::class, 'saveGameIntegration'])
|
||||||
->name('saveGameIntegration');
|
->name('saveGameIntegration');
|
||||||
|
|
||||||
Route::post('players/ban/{user}', [BanController::class, 'insert'])
|
|
||||||
|
Route::post('accounts/suspend/{user}', [UserController::class, 'suspend'])
|
||||||
->name('banUser');
|
->name('banUser');
|
||||||
|
|
||||||
Route::delete('players/unban/{user}', [BanController::class, 'delete'])
|
Route::delete('accounts/unsuspend/{user}', [UserController::class, 'unsuspend'])
|
||||||
->name('unbanUser');
|
->name('unbanUser');
|
||||||
|
|
||||||
Route::delete('players/delete/{user}', [UserController::class, 'delete'])
|
Route::delete('accounts/delete/{user}', [UserController::class, 'delete'])
|
||||||
->name('deleteUser');
|
->name('deleteUser');
|
||||||
|
|
||||||
Route::patch('players/update/{user}', [UserController::class, 'update'])
|
Route::patch('accounts/update/{user}', [UserController::class, 'update'])
|
||||||
->name('updateUser');
|
->name('updateUser');
|
||||||
|
|
||||||
|
Route::get('accounts/manage/{user}', [UserController::class, 'showAcocuntManagement'])
|
||||||
|
->name('manageUser');
|
||||||
|
|
||||||
Route::get('positions', [VacancyController::class, 'index'])
|
Route::get('positions', [VacancyController::class, 'index'])
|
||||||
->name('showPositions');
|
->name('showPositions');
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user