TRF Certest first commit
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Auth;
|
||||
|
||||
use Illuminate\Contracts\Auth\PasswordBroker;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset emails and
|
||||
| includes a trait which assists in sending these notifications from
|
||||
| your application to your users. Feel free to explore this trait.
|
||||
|
|
||||
*/
|
||||
|
||||
use SendsPasswordResetEmails;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function sendResetLinkResponse(Request $request, $response): RedirectResponse
|
||||
{
|
||||
return back()->with('success', trans($response));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function sendResetLinkFailedResponse(Request $request, $response): RedirectResponse
|
||||
{
|
||||
$messages = ['email' => trans($response)];
|
||||
$httpResponse = back()->withInput($request->only('email'));
|
||||
|
||||
return $response === PasswordBroker::INVALID_USER
|
||||
? $httpResponse->withSuccess($messages)
|
||||
: $httpResponse->withErrors($messages);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Auth;
|
||||
|
||||
use Auth;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as BaseAuthenticatable;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Vanguard\Events\User\LoggedIn;
|
||||
use Vanguard\Events\User\LoggedOut;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\Auth\LoginRequest;
|
||||
use Vanguard\Repositories\Session\SessionRepository;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\Services\Auth\ThrottlesLogins;
|
||||
use Vanguard\User;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
use ThrottlesLogins;
|
||||
|
||||
public function __construct(private readonly UserRepository $users)
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
$this->middleware('auth')->only('logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application login form.
|
||||
*/
|
||||
public function show(): View
|
||||
{
|
||||
return view('auth.login', [
|
||||
'socialProviders' => config('auth.social.providers'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function login(LoginRequest $request, SessionRepository $sessions): Response|RedirectResponse
|
||||
{
|
||||
// In case that request throttling is enabled, we have to check if user can perform this request.
|
||||
// We'll key this by the username and the IP address of the client making these requests into this application.
|
||||
$throttles = (bool) setting('throttle_enabled');
|
||||
|
||||
//Redirect URL that can be passed as hidden field.
|
||||
$to = $request->has('to') ? '?to='.$request->get('to') : '';
|
||||
|
||||
if ($throttles && $this->hasTooManyLoginAttempts($request)) {
|
||||
return $this->sendLockoutResponse($request);
|
||||
}
|
||||
|
||||
$credentials = $request->getCredentials();
|
||||
|
||||
if (! Auth::validate($credentials)) {
|
||||
// If the login attempt was unsuccessful we will increment the number of attempts
|
||||
// to log in and redirect the user back to the login form. Of course, when this
|
||||
// user surpasses their maximum number of attempts they will get locked out.
|
||||
if ($throttles) {
|
||||
$this->incrementLoginAttempts($request);
|
||||
}
|
||||
|
||||
return redirect()->to('login'.$to)
|
||||
->withErrors(trans('auth.failed'));
|
||||
}
|
||||
|
||||
$user = Auth::getProvider()->retrieveByCredentials($credentials);
|
||||
|
||||
if ($user->isBanned()) {
|
||||
return redirect()->to('login'.$to)
|
||||
->withErrors(trans('auth.banned'));
|
||||
}
|
||||
|
||||
$maxSessions = setting('max_active_sessions');
|
||||
if ($maxSessions && $sessions->getActiveSessionsCount($user->id) >= $maxSessions) {
|
||||
return redirect()->to('login'.$to)
|
||||
->withErrors(trans('auth.max_sessions_reached'));
|
||||
}
|
||||
|
||||
Auth::login($user, setting('remember_me') && $request->get('remember'));
|
||||
|
||||
return $this->authenticated($request, $throttles, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the response after the user was authenticated.
|
||||
*/
|
||||
protected function authenticated(
|
||||
Request $request,
|
||||
bool $throttles,
|
||||
BaseAuthenticatable $user,
|
||||
): Response|RedirectResponse {
|
||||
if ($throttles) {
|
||||
$this->clearLoginAttempts($request);
|
||||
}
|
||||
|
||||
$redirectPage = $request->get('to');
|
||||
|
||||
if (setting('2fa.enabled') && $user->twoFactorEnabled()) {
|
||||
return $this->logoutAndRedirectToTokenPage($request, $user, $redirectPage);
|
||||
}
|
||||
|
||||
event(new LoggedIn);
|
||||
|
||||
if ($redirectPage) {
|
||||
return redirect()->to($redirectPage);
|
||||
}
|
||||
|
||||
// Reindirizza in base al ruolo
|
||||
if ($user->hasRole('Admin')) {
|
||||
return redirect()->to('userarea/admin.php');
|
||||
} elseif ($user->hasRole('User')) {
|
||||
return redirect()->to('userarea/index.php');
|
||||
}
|
||||
|
||||
// Se il ruolo non è specificato, reindirizza alla home predefinita
|
||||
return redirect()->intended('/');
|
||||
|
||||
}
|
||||
|
||||
protected function logoutAndRedirectToTokenPage(Request $request, $user, ?string $redirectPage): RedirectResponse
|
||||
{
|
||||
Auth::logout();
|
||||
|
||||
$request->session()->put('auth.2fa.id', $user->id);
|
||||
|
||||
if ($redirectPage) {
|
||||
$request->session()->put('auth.redirect_to', $redirectPage);
|
||||
}
|
||||
|
||||
return redirect()->route('auth.token');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the user out of the application.
|
||||
*/
|
||||
public function logout(): RedirectResponse
|
||||
{
|
||||
event(new LoggedOut);
|
||||
|
||||
Auth::logout();
|
||||
|
||||
return redirect('login');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Auth;
|
||||
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\Auth\RegisterRequest;
|
||||
use Vanguard\Repositories\Role\RoleRepository;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\Role;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
public function __construct(private readonly UserRepository $users)
|
||||
{
|
||||
$this->middleware('registration')->only('show', 'register');
|
||||
}
|
||||
|
||||
public function show(): View
|
||||
{
|
||||
return view('auth.register', [
|
||||
'socialProviders' => config('auth.social.providers'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function register(RegisterRequest $request, RoleRepository $roles): RedirectResponse
|
||||
{
|
||||
$user = $this->users->create(
|
||||
array_merge(
|
||||
$request->validFormData(),
|
||||
['role_id' => $roles->findByName(Role::DEFAULT_USER_ROLE)->id],
|
||||
)
|
||||
);
|
||||
|
||||
event(new Registered($user));
|
||||
|
||||
$message = setting('reg_email_confirmation')
|
||||
? __('Your account is created successfully! Please confirm your email.')
|
||||
: __('Your account is created successfully!');
|
||||
|
||||
\Auth::login($user);
|
||||
|
||||
return redirect('/')->with('success', $message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Auth;
|
||||
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Contracts\Auth\CanResetPassword;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Support\Str;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users after resetting their password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function resetPassword(CanResetPassword $user, string $password)
|
||||
{
|
||||
$user->password = $password;
|
||||
|
||||
$user->setRememberToken(Str::random(60));
|
||||
|
||||
$user->save();
|
||||
|
||||
event(new PasswordReset($user));
|
||||
|
||||
$this->guard()->login($user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Auth;
|
||||
|
||||
use Auth;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Laravel\Socialite\Contracts\User as SocialUser;
|
||||
use Socialite;
|
||||
use Vanguard\Events\User\LoggedIn;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\Services\Auth\Social\SocialManager;
|
||||
use Vanguard\User;
|
||||
|
||||
class SocialAuthController extends Controller
|
||||
{
|
||||
public function __construct(private readonly UserRepository $users, private readonly SocialManager $socialManager)
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect user to specified provider in order to complete the authentication process.
|
||||
*/
|
||||
public function redirectToProvider(string $provider): RedirectResponse
|
||||
{
|
||||
if (strtolower($provider) == 'facebook') {
|
||||
return Socialite::driver('facebook')->with(['auth_type' => 'rerequest'])->redirect();
|
||||
}
|
||||
|
||||
return Socialite::driver($provider)->redirect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle response authentication provider.
|
||||
*/
|
||||
public function handleProviderCallback(string $provider): RedirectResponse
|
||||
{
|
||||
if (request()->get('error')) {
|
||||
return redirect('login')
|
||||
->withErrors(__('Something went wrong during the authentication process. Please try again.'));
|
||||
}
|
||||
|
||||
$socialUser = $this->getUserFromProvider($provider);
|
||||
|
||||
$user = $this->users->findBySocialId($provider, $socialUser->getId());
|
||||
|
||||
if (! $user) {
|
||||
if (! setting('reg_enabled')) {
|
||||
return redirect('login')
|
||||
->withErrors(__('Only users who already created an account can log in.'));
|
||||
}
|
||||
|
||||
if (! $socialUser->getEmail()) {
|
||||
return redirect('login')
|
||||
->withErrors(__('You have to provide your email address.'));
|
||||
}
|
||||
|
||||
$user = $this->socialManager->associate($socialUser, $provider);
|
||||
|
||||
event(new \Illuminate\Auth\Events\Registered($user));
|
||||
}
|
||||
|
||||
return $this->loginAndRedirect($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user from authentication provider.
|
||||
*/
|
||||
private function getUserFromProvider(string $provider): SocialUser
|
||||
{
|
||||
return Socialite::driver($provider)->user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log provided user in and redirect him to intended page.
|
||||
*/
|
||||
private function loginAndRedirect(User $user): RedirectResponse
|
||||
{
|
||||
if ($user->isBanned()) {
|
||||
return redirect()->to('login')
|
||||
->withErrors(__('Your account is banned by administrator.'));
|
||||
}
|
||||
|
||||
if (setting('2fa.enabled') && $user->twoFactorEnabled()) {
|
||||
session()->put('auth.2fa.id', $user->id);
|
||||
|
||||
return redirect()->route('auth.token');
|
||||
}
|
||||
|
||||
Auth::login($user);
|
||||
|
||||
event(new LoggedIn);
|
||||
|
||||
return redirect()->intended('/');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Auth;
|
||||
|
||||
use Auth;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Vanguard\Events\User\LoggedIn;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\TwoFactor\TwoFactorLoginRequest;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\Services\Auth\ThrottlesLogins;
|
||||
|
||||
class TwoFactorTokenController extends Controller
|
||||
{
|
||||
use ThrottlesLogins;
|
||||
|
||||
public function __construct(private readonly UserRepository $users)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Two-Factor Token form.
|
||||
*/
|
||||
public function show(): View|RedirectResponse
|
||||
{
|
||||
return session('auth.2fa.id') ? view('auth.token') : redirect('login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Two-Factor token form submission.
|
||||
*/
|
||||
public function update(TwoFactorLoginRequest $request): RedirectResponse
|
||||
{
|
||||
$this->validate($request, ['code' => 'required']);
|
||||
|
||||
if (! session('auth.2fa.id')) {
|
||||
return redirect('login');
|
||||
}
|
||||
|
||||
$user = $this->users->find(
|
||||
$request->session()->pull('auth.2fa.id')
|
||||
);
|
||||
|
||||
if (!$user) {
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
$customRedirect = $request->session()->pull('auth.redirect_to') ?: '';
|
||||
|
||||
if (!$request->hasValidCode($user)) {
|
||||
return redirect()->to('login' . ($customRedirect ? "?to={$customRedirect}" : ''))
|
||||
->withErrors(trans('auth.2fa.invalid_token'));
|
||||
}
|
||||
|
||||
Auth::login($user);
|
||||
|
||||
event(new LoggedIn);
|
||||
|
||||
return redirect()->intended($customRedirect ?: '/');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Auth;
|
||||
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email Verification Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling email verification for any
|
||||
| user that recently registered with the application. Emails may also
|
||||
| be re-sent if the user didn't receive the original email message.
|
||||
|
|
||||
*/
|
||||
|
||||
use VerifiesEmails;
|
||||
|
||||
/**
|
||||
* Where to redirect users after verification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Authorization;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\Permission\CreatePermissionRequest;
|
||||
use Vanguard\Http\Requests\Permission\UpdatePermissionRequest;
|
||||
use Vanguard\Permission;
|
||||
use Vanguard\Repositories\Permission\PermissionRepository;
|
||||
use Vanguard\Repositories\Role\RoleRepository;
|
||||
|
||||
class PermissionsController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly RoleRepository $roles,
|
||||
private readonly PermissionRepository $permissions
|
||||
) {
|
||||
}
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
return view('permission.index', [
|
||||
'roles' => $this->roles->all(),
|
||||
'permissions' => $this->permissions->all(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
return view('permission.add-edit', ['edit' => false]);
|
||||
}
|
||||
|
||||
public function store(CreatePermissionRequest $request): RedirectResponse
|
||||
{
|
||||
$this->permissions->create($request->all());
|
||||
|
||||
return redirect()->route('permissions.index')
|
||||
->withSuccess(__('Permission created successfully.'));
|
||||
}
|
||||
|
||||
public function edit(Permission $permission): View
|
||||
{
|
||||
return view('permission.add-edit', [
|
||||
'edit' => true,
|
||||
'permission' => $permission,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(Permission $permission, UpdatePermissionRequest $request): RedirectResponse
|
||||
{
|
||||
$this->permissions->update($permission->id, $request->all());
|
||||
|
||||
return redirect()->route('permissions.index')
|
||||
->withSuccess(__('Permission updated successfully.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
public function destroy(Permission $permission)
|
||||
{
|
||||
if (! $permission->removable) {
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
$this->permissions->delete($permission->id);
|
||||
|
||||
return redirect()->route('permissions.index')
|
||||
->withSuccess(__('Permission deleted successfully.'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Authorization;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Vanguard\Events\Role\PermissionsUpdated;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Repositories\Role\RoleRepository;
|
||||
|
||||
class RolePermissionsController extends Controller
|
||||
{
|
||||
public function __construct(private readonly RoleRepository $roles)
|
||||
{
|
||||
}
|
||||
|
||||
public function update(Request $request): RedirectResponse
|
||||
{
|
||||
$roles = $request->get('roles');
|
||||
|
||||
$allRoles = $this->roles->lists('id');
|
||||
|
||||
foreach ($allRoles as $roleId) {
|
||||
$permissions = Arr::get($roles, $roleId, []);
|
||||
$this->roles->updatePermissions($roleId, $permissions);
|
||||
}
|
||||
|
||||
event(new PermissionsUpdated);
|
||||
|
||||
return redirect()->route('permissions.index')
|
||||
->withSuccess(__('Permissions saved successfully.'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Authorization;
|
||||
|
||||
use Cache;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\View\View;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\Role\CreateRoleRequest;
|
||||
use Vanguard\Http\Requests\Role\UpdateRoleRequest;
|
||||
use Vanguard\Repositories\Role\RoleRepository;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\Role;
|
||||
|
||||
class RolesController extends Controller
|
||||
{
|
||||
public function __construct(private readonly RoleRepository $roles)
|
||||
{
|
||||
}
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
return view('role.index', ['roles' => $this->roles->getAllWithUsersCount()]);
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
return view('role.add-edit', ['edit' => false]);
|
||||
}
|
||||
|
||||
public function store(CreateRoleRequest $request): RedirectResponse
|
||||
{
|
||||
$this->roles->create($request->all());
|
||||
|
||||
return redirect()->route('roles.index')
|
||||
->withSuccess(__('Role created successfully.'));
|
||||
}
|
||||
|
||||
public function edit(Role $role): View
|
||||
{
|
||||
return view('role.add-edit', [
|
||||
'role' => $role,
|
||||
'edit' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(Role $role, UpdateRoleRequest $request): RedirectResponse
|
||||
{
|
||||
$this->roles->update($role->id, $request->all());
|
||||
|
||||
return redirect()->route('roles.index')
|
||||
->withSuccess(__('Role updated successfully.'));
|
||||
}
|
||||
|
||||
public function destroy(Role $role, UserRepository $userRepository): RedirectResponse
|
||||
{
|
||||
if (! $role->removable) {
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
$userRole = $this->roles->findByName(Role::DEFAULT_USER_ROLE);
|
||||
|
||||
$userRepository->switchRolesForUsers($role->id, $userRole->id);
|
||||
|
||||
$this->roles->delete($role->id);
|
||||
|
||||
Cache::flush();
|
||||
|
||||
return redirect()->route('roles.index')
|
||||
->withSuccess(__('Role deleted successfully.'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function index(): View
|
||||
{
|
||||
if (session()->has('verified')) {
|
||||
session()->flash('success', __('E-Mail verified successfully.'));
|
||||
}
|
||||
|
||||
return view('dashboard.index');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web;
|
||||
|
||||
use Artisan;
|
||||
use DB;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Encryption\Encrypter;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Session;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
|
||||
class InstallController extends Controller
|
||||
{
|
||||
public const TMP_APP_KEY = 'lsXxrP1d6nUGpfGO6vQ1ezNy1KCuDD3o';
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
return view('install.start');
|
||||
}
|
||||
|
||||
public function requirements(): View
|
||||
{
|
||||
$requirements = $this->getRequirements();
|
||||
$allLoaded = $this->allRequirementsLoaded();
|
||||
|
||||
return view('install.requirements', compact('requirements', 'allLoaded'));
|
||||
}
|
||||
|
||||
public function permissions(): View|RedirectResponse
|
||||
{
|
||||
if (! $this->allRequirementsLoaded()) {
|
||||
return redirect()->route('install.requirements');
|
||||
}
|
||||
|
||||
$folders = $this->getPermissions();
|
||||
$allGranted = $this->allPermissionsGranted();
|
||||
|
||||
return view('install.permissions', compact('folders', 'allGranted'));
|
||||
}
|
||||
|
||||
public function databaseInfo(): View|RedirectResponse
|
||||
{
|
||||
if (! $this->allRequirementsLoaded()) {
|
||||
return redirect()->route('install.requirements');
|
||||
}
|
||||
|
||||
if (! $this->allPermissionsGranted()) {
|
||||
return redirect()->route('install.permissions');
|
||||
}
|
||||
|
||||
return view('install.database');
|
||||
}
|
||||
|
||||
public function installation(Request $request): View|RedirectResponse
|
||||
{
|
||||
if (! $this->allRequirementsLoaded()) {
|
||||
return redirect()->route('install.requirements');
|
||||
}
|
||||
|
||||
if (! $this->allPermissionsGranted()) {
|
||||
return redirect()->route('install.permissions');
|
||||
}
|
||||
|
||||
$dbCredentials = $request->only('host', 'username', 'password', 'database', 'prefix');
|
||||
|
||||
if (! $this->dbCredentialsAreValid($dbCredentials)) {
|
||||
return redirect()->route('install.database')
|
||||
->withInput(Arr::except($dbCredentials, 'password'))
|
||||
->withErrors('Connection to your database cannot be established.
|
||||
Please provide correct database credentials.');
|
||||
}
|
||||
|
||||
if (! $this->foreignKeysAreEnabled()) {
|
||||
return redirect()->route('install.database')
|
||||
->withInput(Arr::except($dbCredentials, 'password'))
|
||||
->withErrors('Database connection established but foreign keys are not enabled.
|
||||
Please enable foreign key support to proceed.');
|
||||
}
|
||||
|
||||
Session::put('install.db_credentials', $dbCredentials);
|
||||
|
||||
return view('install.installation');
|
||||
}
|
||||
|
||||
public function install(): RedirectResponse
|
||||
{
|
||||
try {
|
||||
$db = Session::pull('install.db_credentials');
|
||||
$appKey = $this->generateRandomKey();
|
||||
|
||||
$content = <<<PHP
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_KEY={$appKey}
|
||||
APP_URL=http://vanguard.test
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST="{$db['host']}"
|
||||
DB_DATABASE="{$db['database']}"
|
||||
DB_USERNAME="{$db['username']}"
|
||||
DB_PASSWORD="{$db['password']}"
|
||||
DB_PREFIX="{$db['prefix']}"
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=mail
|
||||
MAIL_FROM_NAME=Vanguard
|
||||
MAIL_FROM_ADDRESS=vanguard@test.dev
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
MIX_PUSHER_APP_KEY="\${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="\${PUSHER_APP_CLUSTER}"
|
||||
PHP;
|
||||
|
||||
file_put_contents(base_path('.env'), $content);
|
||||
|
||||
$this->setDatabaseCredentials($db);
|
||||
config(['app.debug' => true]);
|
||||
|
||||
\Setting::set('app_name', \request('app_name'));
|
||||
\Setting::save();
|
||||
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
Artisan::call('db:seed', ['--force' => true]);
|
||||
Artisan::call('db:seed', [
|
||||
'--force' => true,
|
||||
'--quiet' => true,
|
||||
'--class' => '\\Vanguard\\Announcements\\Database\\Seeders\\AnnouncementsDatabaseSeeder',
|
||||
]);
|
||||
|
||||
return redirect()->route('install.complete');
|
||||
} catch (\Exception $e) {
|
||||
@unlink(base_path('.env'));
|
||||
\Log::error($e->getMessage());
|
||||
\Log::error($e->getTraceAsString());
|
||||
|
||||
return redirect()->route('install.error');
|
||||
}
|
||||
}
|
||||
|
||||
public function complete(): View
|
||||
{
|
||||
return view('install.complete');
|
||||
}
|
||||
|
||||
public function error(): View
|
||||
{
|
||||
return view('install.error');
|
||||
}
|
||||
|
||||
private function getRequirements(): array
|
||||
{
|
||||
$requirements = [
|
||||
'PHP Version (>= 8.2.0)' => version_compare(phpversion(), '8.2.0', '>='),
|
||||
'BCMath Extension' => extension_loaded('bcmath'),
|
||||
'OpenSSL Extension' => extension_loaded('openssl'),
|
||||
'PDO Extension' => extension_loaded('PDO'),
|
||||
'PDO MySQL Extension' => extension_loaded('pdo_mysql'),
|
||||
'Mbstring Extension' => extension_loaded('mbstring'),
|
||||
'Tokenizer Extension' => extension_loaded('tokenizer'),
|
||||
'XML Extension' => extension_loaded('xml'),
|
||||
'Ctype PHP Extension' => extension_loaded('ctype'),
|
||||
'JSON PHP Extension' => extension_loaded('json'),
|
||||
'GD Extension' => extension_loaded('gd'),
|
||||
'Fileinfo Extension' => extension_loaded('fileinfo'),
|
||||
];
|
||||
|
||||
if (extension_loaded('xdebug')) {
|
||||
$requirements['Xdebug Max Nesting Level (>= 500)'] = (int) ini_get('xdebug.max_nesting_level') >= 500;
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
private function allRequirementsLoaded(): bool
|
||||
{
|
||||
foreach ($this->getRequirements() as $loaded) {
|
||||
if (! $loaded) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getPermissions(): array
|
||||
{
|
||||
return [
|
||||
'public/upload/users' => is_writable(public_path('upload/users')),
|
||||
'storage/app' => is_writable(storage_path('app')),
|
||||
'storage/framework/cache' => is_writable(storage_path('framework/cache')),
|
||||
'storage/framework/sessions' => is_writable(storage_path('framework/sessions')),
|
||||
'storage/framework/views' => is_writable(storage_path('framework/views')),
|
||||
'storage/logs' => is_writable(storage_path('logs')),
|
||||
'bootstrap/cache' => is_writable(base_path('bootstrap/cache')),
|
||||
'Base Directory' => is_writable(base_path('')),
|
||||
];
|
||||
}
|
||||
|
||||
private function allPermissionsGranted(): bool
|
||||
{
|
||||
foreach ($this->getPermissions() as $permission => $granted) {
|
||||
if (! $granted) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function dbCredentialsAreValid($credentials): bool
|
||||
{
|
||||
$this->setDatabaseCredentials($credentials);
|
||||
|
||||
try {
|
||||
DB::statement('SHOW FULL TABLES');
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function foreignKeysAreEnabled(): bool
|
||||
{
|
||||
try {
|
||||
$result = DB::select('SELECT @@foreign_key_checks;');
|
||||
|
||||
return data_get($result, '0.@@foreign_key_checks') === 1;
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function setDatabaseCredentials($credentials): void
|
||||
{
|
||||
$default = config('database.default');
|
||||
|
||||
config([
|
||||
"database.connections.{$default}.host" => $credentials['host'],
|
||||
"database.connections.{$default}.database" => $credentials['database'],
|
||||
"database.connections.{$default}.username" => $credentials['username'],
|
||||
"database.connections.{$default}.password" => $credentials['password'],
|
||||
"database.connections.{$default}.prefix" => $credentials['prefix'],
|
||||
]);
|
||||
}
|
||||
|
||||
protected function generateRandomKey(): string
|
||||
{
|
||||
return 'base64:'.base64_encode(Encrypter::generateKey(config('app.cipher')));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Profile;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Vanguard\Events\User\ChangedAvatar;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\Services\Upload\UserAvatarManager;
|
||||
|
||||
class AvatarController extends Controller
|
||||
{
|
||||
public function __construct(private readonly UserRepository $users)
|
||||
{
|
||||
}
|
||||
|
||||
public function update(Request $request, UserAvatarManager $avatarManager): RedirectResponse
|
||||
{
|
||||
$request->validate(['avatar' => 'image']);
|
||||
|
||||
$name = $avatarManager->uploadAndCropAvatar(
|
||||
$request->file('avatar'),
|
||||
$request->get('points')
|
||||
);
|
||||
|
||||
if ($name) {
|
||||
return $this->handleAvatarUpdate($name);
|
||||
}
|
||||
|
||||
return redirect()->route('profile')
|
||||
->withErrors(__('Avatar image cannot be updated. Please try again.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update avatar for currently logged-in user and fire appropriate event.
|
||||
*/
|
||||
private function handleAvatarUpdate(string|null $avatar): RedirectResponse
|
||||
{
|
||||
$this->users->update(auth()->id(), ['avatar' => $avatar]);
|
||||
|
||||
event(new ChangedAvatar);
|
||||
|
||||
return redirect()->route('profile')
|
||||
->withSuccess(__('Avatar changed successfully.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user's avatar from external location/url.
|
||||
*/
|
||||
public function updateExternal(Request $request, UserAvatarManager $avatarManager): RedirectResponse
|
||||
{
|
||||
$avatarManager->deleteAvatarIfUploaded(auth()->user());
|
||||
|
||||
return $this->handleAvatarUpdate($request->get('url'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Profile;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Vanguard\Events\User\UpdatedProfileDetails;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\User\UpdateProfileDetailsRequest;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
|
||||
class DetailsController extends Controller
|
||||
{
|
||||
public function __construct(private readonly UserRepository $users)
|
||||
{
|
||||
}
|
||||
|
||||
public function update(UpdateProfileDetailsRequest $request): RedirectResponse
|
||||
{
|
||||
$this->users->update(auth()->id(), $request->except('role_id', 'status'));
|
||||
|
||||
event(new UpdatedProfileDetails);
|
||||
|
||||
return redirect()->back()
|
||||
->withSuccess(__('Profile updated successfully.'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Profile;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\User\UpdateProfileLoginDetailsRequest;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
|
||||
class LoginDetailsController extends Controller
|
||||
{
|
||||
public function __construct(private readonly UserRepository $users)
|
||||
{
|
||||
}
|
||||
|
||||
public function update(UpdateProfileLoginDetailsRequest $request): RedirectResponse
|
||||
{
|
||||
$data = $request->except('role', 'status');
|
||||
|
||||
// If password is not provided, then we will
|
||||
// just remove it from $data array and do not change it
|
||||
if (! data_get($data, 'password')) {
|
||||
unset($data['password']);
|
||||
unset($data['password_confirmation']);
|
||||
}
|
||||
|
||||
$this->users->update(auth()->id(), $data);
|
||||
|
||||
return redirect()->route('profile')
|
||||
->withSuccess(__('Login details updated successfully.'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Profile;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Repositories\Country\CountryRepository;
|
||||
use Vanguard\Repositories\Role\RoleRepository;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\Support\Enum\UserStatus;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly UserRepository $users,
|
||||
private readonly RoleRepository $roles,
|
||||
private readonly CountryRepository $countries
|
||||
) {
|
||||
}
|
||||
|
||||
public function show(): View
|
||||
{
|
||||
$roles = $this->roles->all()->filter(function ($role) {
|
||||
return $role->id == auth()->user()->role_id;
|
||||
})->pluck('display_name', 'id');
|
||||
|
||||
return view('user.profile', [
|
||||
'user' => auth()->user(),
|
||||
'edit' => true,
|
||||
'roles' => $roles,
|
||||
'countries' => [0 => __('Select a Country')] + $this->countries->lists()->toArray(),
|
||||
'socialLogins' => $this->users->getUserSocialLogins(auth()->id()),
|
||||
'statuses' => UserStatus::lists(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Profile;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Repositories\Session\SessionRepository;
|
||||
|
||||
class SessionsController extends Controller
|
||||
{
|
||||
public function __construct(private readonly SessionRepository $sessions)
|
||||
{
|
||||
}
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
return view('user.sessions', [
|
||||
'profile' => true,
|
||||
'user' => auth()->user(),
|
||||
'sessions' => $this->sessions->getUserSessions(auth()->id()),
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy($session): RedirectResponse
|
||||
{
|
||||
$this->sessions->invalidateSession($session->id);
|
||||
|
||||
return redirect()->route('profile.sessions')
|
||||
->withSuccess(__('Session invalidated successfully.'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Setting;
|
||||
use Vanguard\Events\Settings\Updated as SettingsUpdated;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display general settings page.
|
||||
*/
|
||||
public function general(): View
|
||||
{
|
||||
return view('settings.general');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Authentication & Registration settings page.
|
||||
*/
|
||||
public function auth(): View
|
||||
{
|
||||
return view('settings.auth');
|
||||
}
|
||||
|
||||
public function update(Request $request): RedirectResponse
|
||||
{
|
||||
$this->updateSetting($request->except('_token'));
|
||||
|
||||
return back()->withSuccess(__('Settings updated successfully.'));
|
||||
}
|
||||
|
||||
private function updateSetting(array $input): void
|
||||
{
|
||||
foreach ($input as $key => $value) {
|
||||
Setting::set($key, $value);
|
||||
}
|
||||
|
||||
Setting::save();
|
||||
|
||||
event(new SettingsUpdated);
|
||||
}
|
||||
|
||||
public function enableTwoFactor(): RedirectResponse
|
||||
{
|
||||
$this->updateSetting(['2fa.enabled' => true]);
|
||||
|
||||
return back()->withSuccess(__('Two-Factor Authentication enabled successfully.'));
|
||||
}
|
||||
|
||||
public function disableTwoFactor(): RedirectResponse
|
||||
{
|
||||
$this->updateSetting(['2fa.enabled' => false]);
|
||||
|
||||
return back()->withSuccess(__('Two-Factor Authentication disabled successfully.'));
|
||||
}
|
||||
|
||||
public function enableCaptcha(): RedirectResponse
|
||||
{
|
||||
$this->updateSetting(['registration.captcha.enabled' => true]);
|
||||
|
||||
return back()->withSuccess(__('reCAPTCHA enabled successfully.'));
|
||||
}
|
||||
|
||||
public function disableCaptcha(): RedirectResponse
|
||||
{
|
||||
$this->updateSetting(['registration.captcha.enabled' => false]);
|
||||
|
||||
return back()->withSuccess(__('reCAPTCHA disabled successfully.'));
|
||||
}
|
||||
|
||||
public function notifications(): View
|
||||
{
|
||||
return view('settings.notifications');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Laravel\Fortify\Actions\ConfirmTwoFactorAuthentication;
|
||||
use Laravel\Fortify\Actions\EnableTwoFactorAuthentication;
|
||||
use Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider;
|
||||
use Vanguard\Events\User\TwoFactorEnabled;
|
||||
use Vanguard\Events\User\TwoFactorEnabledByAdmin;
|
||||
use Vanguard\Events\User\TwoFactorDisabled;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\TwoFactor\DisableTwoFactorRequest;
|
||||
use Vanguard\Http\Requests\TwoFactor\EnableTwoFactorRequest;
|
||||
use Vanguard\Http\Requests\TwoFactor\VerifyTwoFactorTokenRequest;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
|
||||
class TwoFactorController extends Controller
|
||||
{
|
||||
public function __construct(protected UserRepository $users, protected TwoFactorAuthenticationProvider $twoFactorProvider)
|
||||
{
|
||||
$this->middleware('auth');
|
||||
|
||||
$this->middleware(function ($request, $next) use ($users) {
|
||||
$user = $request->get('user')
|
||||
? $users->find($request->get('user'))
|
||||
: auth()->user();
|
||||
|
||||
return $user->twoFactorEnabled() ? abort(404) : $next($request);
|
||||
})->only('enable', 'verification', 'resend', 'verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable 2FA for currently logged user.
|
||||
*/
|
||||
public function enable(EnableTwoFactorRequest $request, EnableTwoFactorAuthentication $enable)
|
||||
{
|
||||
$user = $request->theUser();
|
||||
|
||||
$enable($user, $request->boolean('force', false));
|
||||
|
||||
session()->flash('tab', '2fa');
|
||||
|
||||
return redirect()->back()
|
||||
->withSuccess(trans('auth.2fa.enabled_successfully'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the phone verification page.
|
||||
*/
|
||||
public function verification(): View
|
||||
{
|
||||
return view('user.two-factor-verification', [
|
||||
'user' => request('user'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify 2FA token and enable 2FA if token is valid.
|
||||
*/
|
||||
public function verify(VerifyTwoFactorTokenRequest $request, ConfirmTwoFactorAuthentication $confirm): RedirectResponse
|
||||
{
|
||||
$user = $request->theUser();
|
||||
|
||||
try {
|
||||
$confirm($user, $request->input('code'));
|
||||
} catch (ValidationException $e) {
|
||||
session()->flash('tab', '2fa');
|
||||
|
||||
return redirect()->back()
|
||||
->withErrors(trans('auth.2fa.invalid_token'));
|
||||
}
|
||||
|
||||
$message = trans('auth.2fa.enabled_successfully');
|
||||
|
||||
if ($user->is(auth()->user())) {
|
||||
event(new TwoFactorEnabled);
|
||||
|
||||
return redirect()->route('profile')->withSuccess($message);
|
||||
}
|
||||
|
||||
event(new TwoFactorEnabledByAdmin($user));
|
||||
|
||||
return redirect()->route('users.edit', $user)->withSuccess($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable 2FA for currently logged user.
|
||||
*/
|
||||
public function disable(DisableTwoFactorRequest $request): RedirectResponse
|
||||
{
|
||||
$user = $request->theUser();
|
||||
|
||||
if (!$user->twoFactorEnabled()) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$user->forceFill([
|
||||
'two_factor_secret' => null,
|
||||
'two_factor_recovery_codes' => null,
|
||||
'two_factor_confirmed_at' => null,
|
||||
])->save();
|
||||
|
||||
event(new TwoFactorDisabled);
|
||||
|
||||
return redirect()->back()
|
||||
->withSuccess(trans('auth.2fa.disabled_successfully'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Users;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Vanguard\Events\User\UpdatedByAdmin;
|
||||
use Vanguard\Http\Controllers\Api\ApiController;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\Services\Upload\UserAvatarManager;
|
||||
use Vanguard\User;
|
||||
|
||||
class AvatarController extends ApiController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly UserRepository $users,
|
||||
private readonly UserAvatarManager $avatarManager
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(User $user, Request $request): RedirectResponse
|
||||
{
|
||||
$this->validate($request, ['avatar' => 'image']);
|
||||
|
||||
$name = $this->avatarManager->uploadAndCropAvatar(
|
||||
$request->file('avatar'),
|
||||
$request->get('points')
|
||||
);
|
||||
|
||||
if ($name) {
|
||||
$this->users->update($user->id, ['avatar' => $name]);
|
||||
|
||||
event(new UpdatedByAdmin($user));
|
||||
|
||||
return redirect()->route('users.edit', $user)
|
||||
->withSuccess(__('Avatar changed successfully.'));
|
||||
}
|
||||
|
||||
return redirect()->route('users.edit', $user)
|
||||
->withErrors(__('Avatar image cannot be updated. Please try again.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user's avatar from some external source (Gravatar, Facebook, Twitter...)
|
||||
*/
|
||||
public function updateExternal(User $user, Request $request): RedirectResponse
|
||||
{
|
||||
$this->avatarManager->deleteAvatarIfUploaded($user);
|
||||
|
||||
$this->users->update($user->id, ['avatar' => $request->get('url')]);
|
||||
|
||||
event(new UpdatedByAdmin($user));
|
||||
|
||||
return redirect()->route('users.edit', $user)
|
||||
->withSuccess(__('Avatar changed successfully.'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Users;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Vanguard\Events\User\Banned;
|
||||
use Vanguard\Events\User\UpdatedByAdmin;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\User\UpdateDetailsRequest;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\Support\Enum\UserStatus;
|
||||
use Vanguard\User;
|
||||
|
||||
class DetailsController extends Controller
|
||||
{
|
||||
public function __construct(private readonly UserRepository $users)
|
||||
{
|
||||
}
|
||||
|
||||
public function update(User $user, UpdateDetailsRequest $request): RedirectResponse
|
||||
{
|
||||
$data = $request->all();
|
||||
|
||||
if (! data_get($data, 'country_id')) {
|
||||
$data['country_id'] = null;
|
||||
}
|
||||
|
||||
$this->users->update($user->id, $data);
|
||||
$this->users->setRole($user->id, $request->role_id);
|
||||
|
||||
event(new UpdatedByAdmin($user));
|
||||
|
||||
// If user status was updated to "Banned",
|
||||
// fire the appropriate event.
|
||||
if ($this->userWasBanned($user, $request)) {
|
||||
event(new Banned($user));
|
||||
}
|
||||
|
||||
return redirect()->back()
|
||||
->withSuccess(__('User updated successfully.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is banned during last update.
|
||||
*/
|
||||
private function userWasBanned(User $user, Request $request): bool
|
||||
{
|
||||
return $user->status != $request->status
|
||||
&& $request->status == UserStatus::BANNED->value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Users;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Vanguard\Events\User\UpdatedByAdmin;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\User\UpdateLoginDetailsRequest;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\User;
|
||||
|
||||
class LoginDetailsController extends Controller
|
||||
{
|
||||
public function __construct(private readonly UserRepository $users)
|
||||
{
|
||||
}
|
||||
|
||||
public function update(User $user, UpdateLoginDetailsRequest $request): RedirectResponse
|
||||
{
|
||||
$data = $request->all();
|
||||
|
||||
if (! $data['password']) {
|
||||
unset($data['password']);
|
||||
unset($data['password_confirmation']);
|
||||
}
|
||||
|
||||
$this->users->update($user->id, $data);
|
||||
|
||||
event(new UpdatedByAdmin($user));
|
||||
|
||||
return redirect()->route('users.edit', $user->id)
|
||||
->withSuccess(__('Login details updated successfully.'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Users;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Repositories\Session\SessionRepository;
|
||||
use Vanguard\User;
|
||||
|
||||
class SessionsController extends Controller
|
||||
{
|
||||
public function __construct(private readonly SessionRepository $sessions)
|
||||
{
|
||||
$this->middleware('permission:users.manage');
|
||||
}
|
||||
|
||||
public function index(User $user): View
|
||||
{
|
||||
return view('user.sessions', [
|
||||
'adminView' => true,
|
||||
'user' => $user,
|
||||
'sessions' => $this->sessions->getUserSessions($user->id),
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy(User $user, $session): RedirectResponse
|
||||
{
|
||||
$this->sessions->invalidateSession($session->id);
|
||||
|
||||
return redirect()->route('user.sessions', $user->id)
|
||||
->withSuccess(__('Session invalidated successfully.'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Vanguard\Http\Controllers\Web\Users;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Vanguard\Events\User\Deleted;
|
||||
use Vanguard\Http\Controllers\Controller;
|
||||
use Vanguard\Http\Requests\User\CreateUserRequest;
|
||||
use Vanguard\Repositories\Country\CountryRepository;
|
||||
use Vanguard\Repositories\Role\RoleRepository;
|
||||
use Vanguard\Repositories\User\UserRepository;
|
||||
use Vanguard\Support\Enum\UserStatus;
|
||||
use Vanguard\User;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
public function __construct(private readonly UserRepository $users)
|
||||
{
|
||||
}
|
||||
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$users = $this->users->paginate($perPage = 20, $request->search, $request->status);
|
||||
|
||||
$statuses = ['' => __('All')] + UserStatus::lists();
|
||||
|
||||
return view('user.list', compact('users', 'statuses'));
|
||||
}
|
||||
|
||||
public function show(User $user): View
|
||||
{
|
||||
return view('user.view', compact('user'));
|
||||
}
|
||||
|
||||
public function create(CountryRepository $countryRepository, RoleRepository $roleRepository): View
|
||||
{
|
||||
return view('user.add', [
|
||||
'countries' => $this->parseCountries($countryRepository),
|
||||
'roles' => $roleRepository->lists(),
|
||||
'statuses' => UserStatus::lists(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse countries into an array that also has a blank
|
||||
* item as first element, which will allow users to
|
||||
* leave the country field unpopulated.
|
||||
*/
|
||||
private function parseCountries(CountryRepository $countryRepository): array
|
||||
{
|
||||
return [0 => __('Select a Country')] + $countryRepository->lists()->toArray();
|
||||
}
|
||||
|
||||
public function store(CreateUserRequest $request): RedirectResponse
|
||||
{
|
||||
// When user is created by administrator, we will set his
|
||||
// status to Active by default.
|
||||
$data = $request->all() + [
|
||||
'status' => UserStatus::ACTIVE,
|
||||
'email_verified_at' => now(),
|
||||
];
|
||||
|
||||
if (! data_get($data, 'country_id')) {
|
||||
$data['country_id'] = null;
|
||||
}
|
||||
|
||||
// Username should be updated only if it is provided.
|
||||
if (! data_get($data, 'username')) {
|
||||
$data['username'] = null;
|
||||
}
|
||||
|
||||
$this->users->create($data);
|
||||
|
||||
return redirect()->route('users.index')
|
||||
->withSuccess(__('User created successfully.'));
|
||||
}
|
||||
|
||||
public function edit(User $user, CountryRepository $countryRepository, RoleRepository $roleRepository): View
|
||||
{
|
||||
return view('user.edit', [
|
||||
'edit' => true,
|
||||
'user' => $user,
|
||||
'countries' => $this->parseCountries($countryRepository),
|
||||
'roles' => $roleRepository->lists(),
|
||||
'statuses' => UserStatus::lists(),
|
||||
'socialLogins' => $this->users->getUserSocialLogins($user->id),
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy(User $user): RedirectResponse
|
||||
{
|
||||
if ($user->is(auth()->user())) {
|
||||
return redirect()->route('users.index')
|
||||
->withErrors(__('You cannot delete yourself.'));
|
||||
}
|
||||
|
||||
$this->users->delete($user->id);
|
||||
|
||||
event(new Deleted($user));
|
||||
|
||||
return redirect()->route('users.index')
|
||||
->withSuccess(__('User deleted successfully.'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user