First complete upload on nas

This commit is contained in:
Claudio 2024-09-18 11:20:28 +02:00
commit 4f086962fe
6456 changed files with 1232660 additions and 0 deletions

18
.editorconfig Normal file
View File

@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
[docker-compose.yml]
indent_size = 4

41
.env.example Normal file
View File

@ -0,0 +1,41 @@
APP_ENV=production
APP_DEBUG=false
APP_KEY=lsXxrP1d6nUGpfGO6vQqezNy1KCuDD3o
APP_URL=http://vanguard.test
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=localhost
DB_DATABASE=vanguard
DB_USERNAME=homestead
DB_PASSWORD=secret
DB_PREFIX=vg_
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}"

11
.gitattributes vendored Normal file
View File

@ -0,0 +1,11 @@
* text=auto eol=lf
*.blade.php diff=html
*.css diff=css
*.html diff=html
*.md diff=markdown
*.php diff=php
/.github export-ignore
CHANGELOG.md export-ignore
.styleci.yml export-ignore

23
.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
.DS_Store
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
/.idea
/.fleet
/.vscode
/.vagrant
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
.env
.phpunit.result.cache
.php_cs.cache
/documentation
/.phpunit.cache
/public/build
.env.backup
.env.production
auth.json

9
.styleci.yml Normal file
View File

@ -0,0 +1,9 @@
php:
preset: laravel
disabled:
- no_unused_imports
finder:
not-name:
- index.php
js: true
css: true

28365
_ide_helper.php Normal file

File diff suppressed because it is too large Load Diff

32
app/Console/Kernel.php Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace Vanguard\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')->hourly();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}

15
app/Country.php Normal file
View File

@ -0,0 +1,15 @@
<?php
namespace Vanguard;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
use HasFactory;
protected $table = 'countries';
public $timestamps = false;
}

8
app/Events/Event.php Normal file
View File

@ -0,0 +1,8 @@
<?php
namespace Vanguard\Events;
abstract class Event
{
//
}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\Permission;
class Created extends PermissionEvent {}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\Permission;
class Deleted extends PermissionEvent {}

View File

@ -0,0 +1,26 @@
<?php
namespace Vanguard\Events\Permission;
use Vanguard\Permission;
abstract class PermissionEvent
{
/**
* @var Permission
*/
protected $permission;
public function __construct(Permission $permission)
{
$this->permission = $permission;
}
/**
* @return Permission
*/
public function getPermission()
{
return $this->permission;
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\Permission;
class Updated extends PermissionEvent {}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\Role;
class Created extends RoleEvent {}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\Role;
class Deleted extends RoleEvent {}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\Role;
class PermissionsUpdated {}

View File

@ -0,0 +1,26 @@
<?php
namespace Vanguard\Events\Role;
use Vanguard\Role;
abstract class RoleEvent
{
/**
* @var Role
*/
protected $role;
public function __construct(Role $role)
{
$this->role = $role;
}
/**
* @return Role
*/
public function getRole()
{
return $this->role;
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\Role;
class Updated extends RoleEvent {}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\Settings;
class Updated {}

View File

@ -0,0 +1,26 @@
<?php
namespace Vanguard\Events\User;
use Vanguard\User;
class Banned
{
/**
* @var User
*/
protected $bannedUser;
public function __construct(User $bannedUser)
{
$this->bannedUser = $bannedUser;
}
/**
* @return User
*/
public function getBannedUser()
{
return $this->bannedUser;
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\User;
class ChangedAvatar {}

View File

@ -0,0 +1,26 @@
<?php
namespace Vanguard\Events\User;
use Vanguard\User;
class Created
{
/**
* @var User
*/
protected $createdUser;
public function __construct(User $createdUser)
{
$this->createdUser = $createdUser;
}
/**
* @return User
*/
public function getCreatedUser()
{
return $this->createdUser;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Vanguard\Events\User;
use Vanguard\User;
class Deleted
{
/**
* @var User
*/
protected $deletedUser;
public function __construct(User $deletedUser)
{
$this->deletedUser = $deletedUser;
}
/**
* @return User
*/
public function getDeletedUser()
{
return $this->deletedUser;
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\User;
class LoggedIn {}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\User;
class LoggedOut {}

View File

@ -0,0 +1,26 @@
<?php
namespace Vanguard\Events\User;
use Vanguard\User;
class RequestedPasswordResetEmail
{
/**
* @var User
*/
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
/**
* @return User
*/
public function getUser()
{
return $this->user;
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\User;
class TwoFactorDisabled {}

View File

@ -0,0 +1,26 @@
<?php
namespace Vanguard\Events\User;
use Vanguard\User;
class TwoFactorDisabledByAdmin
{
/**
* @var User
*/
protected $user;
public function __construct(User $user)
{
$this->user = $user;
}
/**
* @return User
*/
public function getUser()
{
return $this->user;
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\User;
class TwoFactorEnabled {}

View File

@ -0,0 +1,26 @@
<?php
namespace Vanguard\Events\User;
use Vanguard\User;
class TwoFactorEnabledByAdmin
{
/**
* @var User
*/
protected $user;
public function __construct(User $user)
{
$this->user = $user;
}
/**
* @return User
*/
public function getUser()
{
return $this->user;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Vanguard\Events\User;
use Vanguard\User;
class UpdatedByAdmin
{
/**
* @var User
*/
protected $updatedUser;
public function __construct(User $updatedUser)
{
$this->updatedUser = $updatedUser;
}
/**
* @return User
*/
public function getUpdatedUser()
{
return $this->updatedUser;
}
}

View File

@ -0,0 +1,5 @@
<?php
namespace Vanguard\Events\User;
class UpdatedProfileDetails {}

View File

@ -0,0 +1,43 @@
<?php
namespace Vanguard\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
$this->reportable(function (Throwable $e) {
//
});
}
}

View File

@ -0,0 +1,112 @@
<?php
namespace Vanguard\Http\Controllers\Api;
use Illuminate\Http\Response;
use Vanguard\Http\Controllers\Controller;
abstract class ApiController extends Controller
{
protected $statusCode = Response::HTTP_OK;
/**
* Getter for statusCode
*
* @return int
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* Setter for statusCode
*
* @param int $statusCode Value to set
*
* @return self
*/
public function setStatusCode($statusCode)
{
$this->statusCode = $statusCode;
return $this;
}
protected function respondWithSuccess($statusCode = Response::HTTP_OK)
{
return $this->setStatusCode($statusCode)
->respondWithArray(['success' => true]);
}
protected function respondWithArray(array $array, array $headers = [])
{
$response = \Response::json($array, $this->statusCode, $headers);
$response->header('Content-Type', 'application/json');
return $response;
}
protected function respondWithError($message)
{
if ($this->statusCode === Response::HTTP_OK) {
trigger_error(
"You better have a really good reason for erroring on a 200...",
E_USER_WARNING
);
}
return $this->respondWithArray([
'message' => $message
]);
}
/**
* Generates a Response with a 403 HTTP header and a given message.
*
* @param string $message
* @return \Illuminate\Http\JsonResponse
*/
public function errorForbidden($message = 'Forbidden')
{
return $this->setStatusCode(Response::HTTP_FORBIDDEN)
->respondWithError($message);
}
/**
* Generates a Response with a 500 HTTP header and a given message.
*
* @param string $message
* @return \Illuminate\Http\JsonResponse
*/
public function errorInternalError($message = 'Internal Error')
{
return $this->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR)
->respondWithError($message);
}
/**
* Generates a Response with a 404 HTTP header and a given message.
*
* @param string $message
* @return \Illuminate\Http\JsonResponse
*/
public function errorNotFound($message = 'Resource Not Found')
{
return $this->setStatusCode(Response::HTTP_NOT_FOUND)
->respondWithError($message);
}
/**
* Generates a Response with a 401 HTTP header and a given message.
*
* @param string $message
* @return \Illuminate\Http\JsonResponse
*/
public function errorUnauthorized($message = 'Unauthorized')
{
return $this->setStatusCode(Response::HTTP_UNAUTHORIZED)
->respondWithError($message);
}
}

View File

@ -0,0 +1,88 @@
<?php
namespace Vanguard\Http\Controllers\Api\Auth;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
use Vanguard\Events\User\LoggedIn;
use Vanguard\Events\User\LoggedOut;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\Auth\ApiLoginRequest;
use Vanguard\User;
/**
* Class LoginController
* @package Vanguard\Http\Controllers\Api\Auth
*/
class AuthController extends ApiController
{
public function __construct()
{
$this->middleware('guest')->only('login');
$this->middleware('auth')->only('logout');
}
/**
* Attempt to log the user in and generate unique
* JWT token on successful authentication.
*
* @param ApiLoginRequest $request
* @return JsonResponse|Response
* @throws BindingResolutionException
* @throws ValidationException
*/
public function token(ApiLoginRequest $request)
{
$user = $this->findUser($request);
if ($user->isBanned()) {
return $this->errorUnauthorized(__('Your account is banned by administrators.'));
}
Auth::setUser($user);
event(new LoggedIn);
return $this->respondWithArray([
'token' => $user->createToken($request->device_name)->plainTextToken
]);
}
/**
* Find the user instance from the API request.
*
* @param ApiLoginRequest $request
* @return mixed
* @throws BindingResolutionException
* @throws ValidationException
*/
private function findUser(ApiLoginRequest $request)
{
$user = User::where($request->getCredentials())->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'username' => [trans('auth.failed')],
]);
}
return $user;
}
/**
* Logout user and invalidate token.
* @return JsonResponse
*/
public function logout()
{
event(new LoggedOut);
auth()->user()->currentAccessToken()->delete();
return $this->respondWithSuccess();
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Vanguard\Http\Controllers\Api\Auth\Password;
use Password;
use Vanguard\Events\User\RequestedPasswordResetEmail;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\Auth\PasswordRemindRequest;
use Vanguard\Mail\ResetPassword;
use Vanguard\Repositories\User\UserRepository;
class RemindController extends ApiController
{
/**
* Send a reset link to the given user.
*
* @param PasswordRemindRequest $request
* @param UserRepository $users
* @return \Illuminate\Http\JsonResponse
*/
public function index(PasswordRemindRequest $request, UserRepository $users)
{
$user = $users->findByEmail($request->email);
$token = Password::getRepository()->create($user);
\Mail::to($user)->send(new ResetPassword($token));
event(new RequestedPasswordResetEmail($user));
return $this->respondWithSuccess();
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace Vanguard\Http\Controllers\Api\Auth\Password;
use Illuminate\Auth\Events\PasswordReset;
use Password;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\Auth\PasswordResetRequest;
class ResetController extends ApiController
{
/**
* Reset the given user's password.
*
* @param PasswordResetRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function index(PasswordResetRequest $request)
{
$response = Password::reset($request->credentials(), function ($user, $password) {
$this->resetPassword($user, $password);
});
switch ($response) {
case Password::PASSWORD_RESET:
return $this->respondWithSuccess();
default:
return $this->setStatusCode(400)
->respondWithError(trans($response));
}
}
/**
* Reset the given user's password.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $password
* @return void
*/
protected function resetPassword($user, $password)
{
$user->password = $password;
$user->save();
event(new PasswordReset($user));
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace Vanguard\Http\Controllers\Api\Auth;
use Illuminate\Auth\Events\Registered;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\Auth\RegisterRequest;
use Vanguard\Repositories\Role\RoleRepository;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Support\Enum\UserStatus;
class RegistrationController extends ApiController
{
public function __construct(private UserRepository $users, private RoleRepository $roles)
{
}
/**
* @param RegisterRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function index(RegisterRequest $request)
{
$role = $this->roles->findByName('User');
$user = $this->users->create(
array_merge($request->validFormData(), ['role_id' => $role->id])
);
event(new Registered($user));
return $this->setStatusCode(201)
->respondWithArray([
'requires_email_confirmation' => !! setting('reg_email_confirmation')
]);
}
/**
* Verify email via email confirmation token.
* @param $token
* @return \Illuminate\Http\JsonResponse
*/
public function verifyEmail($token)
{
if (! setting('reg_email_confirmation')) {
return $this->errorNotFound();
}
if ($user = $this->users->findByConfirmationToken($token)) {
$this->users->update($user->id, [
'status' => UserStatus::ACTIVE,
'confirmation_token' => null
]);
return $this->respondWithSuccess();
}
return $this->setStatusCode(400)
->respondWithError("Invalid confirmation token.");
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace Vanguard\Http\Controllers\Api\Auth;
use Auth;
use Exception;
use Socialite;
use Vanguard\Events\User\LoggedIn;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\Auth\Social\ApiAuthenticateRequest;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Services\Auth\Social\SocialManager;
class SocialLoginController extends ApiController
{
public function __construct(private UserRepository $users, private SocialManager $socialManager)
{
}
public function index(ApiAuthenticateRequest $request)
{
try {
$socialUser = Socialite::driver($request->network)->userFromToken($request->social_token);
} catch (Exception $e) {
return $this->errorInternalError("Could not connect to specified social network.");
}
$user = $this->users->findBySocialId(
$request->network,
$socialUser->getId()
);
if (! $user) {
if (! setting('reg_enabled')) {
return $this->errorForbidden("Only users who already created an account can log in.");
}
$user = $this->socialManager->associate($socialUser, $request->network);
}
if ($user->isBanned()) {
return $this->errorForbidden(__("Your account is banned by administrators."));
}
Auth::setUser($user);
event(new LoggedIn);
return $this->respondWithArray([
'token' => $user->createToken($request->device_name)->plainTextToken
]);
}
}

View File

@ -0,0 +1,104 @@
<?php
namespace Vanguard\Http\Controllers\Api\Auth;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\Events\Verified;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Exceptions\InvalidSignatureException;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\Auth\ApiVerifyEmailRequest;
class VerificationController extends ApiController
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('throttle:6,1')->only('resend');
}
/**
* Mark the authenticated user's email address as verified.
*
* @param ApiVerifyEmailRequest $request
* @return \Illuminate\Http\JsonResponse
*
* @throws AuthorizationException
*/
public function verify(ApiVerifyEmailRequest $request)
{
if (! setting('reg_email_confirmation')) {
return $this->errorNotFound();
}
$this->verifySignature($request);
if ($request->user()->hasVerifiedEmail()) {
return $this->emailAlreadyVerifiedResponse();
}
if ($request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
}
return $this->respondWithSuccess();
}
/**
* Verify request signature.
*
* @param ApiVerifyEmailRequest $baseRequest
* @throws AuthorizationException
*/
private function verifySignature(ApiVerifyEmailRequest $baseRequest)
{
$request = Request::create(
route('verification.verify', $baseRequest->only('id', 'hash')),
Request::METHOD_GET,
$baseRequest->only('expires', 'signature')
);
if (! $request->hasValidSignature()) {
throw new InvalidSignatureException;
}
if (! hash_equals((string) $baseRequest->id, (string) auth()->user()->getKey())) {
throw new AuthorizationException;
}
if (! hash_equals((string) $baseRequest->hash, sha1(auth()->user()->getEmailForVerification()))) {
throw new AuthorizationException;
}
}
/**
* @return \Illuminate\Http\JsonResponse
*/
protected function emailAlreadyVerifiedResponse()
{
return $this->setStatusCode(Response::HTTP_BAD_REQUEST)
->respondWithError(__('E-Mail already verified.'));
}
/**
* Resend the email verification notification.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function resend(Request $request)
{
if ($request->user()->hasVerifiedEmail()) {
return $this->emailAlreadyVerifiedResponse();
}
$request->user()->sendEmailVerificationNotification();
return $this->respondWithSuccess(Response::HTTP_ACCEPTED);
}
}

View File

@ -0,0 +1,98 @@
<?php
namespace Vanguard\Http\Controllers\Api\Authorization;
use Spatie\QueryBuilder\AllowedFilter;
use Spatie\QueryBuilder\QueryBuilder;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\Permission\CreatePermissionRequest;
use Vanguard\Http\Requests\Permission\RemovePermissionRequest;
use Vanguard\Http\Requests\Permission\UpdatePermissionRequest;
use Vanguard\Http\Resources\PermissionResource;
use Vanguard\Permission;
use Vanguard\Repositories\Permission\PermissionRepository;
/**
* @package Vanguard\Http\Controllers\Api\Users
*/
class PermissionsController extends ApiController
{
public function __construct(private PermissionRepository $permissions)
{
$this->middleware('permission:permissions.manage');
}
/**
* Get all system permissions.
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public function index()
{
$permissions = QueryBuilder::for(Permission::class)
->allowedFilters([
AllowedFilter::partial('name'),
AllowedFilter::partial('display_name'),
AllowedFilter::exact('role', 'role_id'),
])
->allowedSorts(['name', 'created_at'])
->defaultSort('created_at')
->paginate();
return PermissionResource::collection($permissions);
}
/**
* Create new permission from request.
* @param CreatePermissionRequest $request
* @return PermissionResource
*/
public function store(CreatePermissionRequest $request)
{
$permission = $this->permissions->create(
$request->only(['name', 'display_name', 'description'])
);
return new PermissionResource($permission);
}
/**
* Get info about specified permission.
* @param Permission $permission
* @return PermissionResource
*/
public function show(Permission $permission)
{
return new PermissionResource($permission);
}
/**
* Update specified permission.
* @param Permission $permission
* @param UpdatePermissionRequest $request
* @return PermissionResource
*/
public function update(Permission $permission, UpdatePermissionRequest $request)
{
$input = collect($request->all());
$permission = $this->permissions->update(
$permission->id,
$input->only(['name', 'display_name', 'description'])->toArray()
);
return new PermissionResource($permission);
}
/**
* Remove specified permission from storage.
* @param Permission $permission
* @param RemovePermissionRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Permission $permission, RemovePermissionRequest $request)
{
$this->permissions->delete($permission->id);
return $this->respondWithSuccess();
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace Vanguard\Http\Controllers\Api\Authorization;
use Vanguard\Events\Role\PermissionsUpdated;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\Role\UpdateRolePermissionsRequest;
use Vanguard\Http\Resources\PermissionResource;
use Vanguard\Repositories\Role\RoleRepository;
use Vanguard\Role;
/**
* @package Vanguard\Http\Controllers\Api
*/
class RolePermissionsController extends ApiController
{
public function __construct(private RoleRepository $roles)
{
$this->middleware('permission:permissions.manage');
}
public function show(Role $role)
{
return PermissionResource::collection($role->cachedPermissions());
}
/**
* Update specified role.
* @param Role $role
* @param UpdateRolePermissionsRequest $request
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public function update(Role $role, UpdateRolePermissionsRequest $request)
{
$this->roles->updatePermissions(
$role->id,
$request->permissions
);
event(new PermissionsUpdated);
return PermissionResource::collection($role->cachedPermissions());
}
}

View File

@ -0,0 +1,107 @@
<?php
namespace Vanguard\Http\Controllers\Api\Authorization;
use Cache;
use Spatie\QueryBuilder\QueryBuilder;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\Role\CreateRoleRequest;
use Vanguard\Http\Requests\Role\RemoveRoleRequest;
use Vanguard\Http\Requests\Role\UpdateRoleRequest;
use Vanguard\Http\Resources\RoleResource;
use Vanguard\Repositories\Role\RoleRepository;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Role;
/**
* @package Vanguard\Http\Controllers\Api\Users
*/
class RolesController extends ApiController
{
public function __construct(private RoleRepository $roles)
{
$this->middleware('permission:roles.manage');
}
/**
* Get all system roles with users count for each role.
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public function index()
{
$roles = QueryBuilder::for(Role::class)
->allowedIncludes(RoleResource::allowedIncludes())
->allowedFilters(['name'])
->allowedSorts(['name', 'created_at'])
->defaultSort('created_at')
->paginate();
return RoleResource::collection($roles);
}
/**
* Create new role from the request.
* @param CreateRoleRequest $request
* @return RoleResource
*/
public function store(CreateRoleRequest $request)
{
$role = $this->roles->create(
$request->only(['name', 'display_name', 'description'])
);
return new RoleResource($role);
}
/**
* Return info about specified role.
* @param $id
* @return RoleResource
*/
public function show($id)
{
$role = QueryBuilder::for(Role::where('id', $id))
->allowedIncludes(RoleResource::allowedIncludes())
->first();
return new RoleResource($role);
}
/**
* Update specified role.
* @param Role $role
* @param UpdateRoleRequest $request
* @return RoleResource
*/
public function update(Role $role, UpdateRoleRequest $request)
{
$input = collect($request->all());
$role = $this->roles->update(
$role->id,
$input->only(['name', 'display_name', 'description'])->toArray()
);
return new RoleResource($role);
}
/**
* Remove specified role (if role is removable).
* @param Role $role
* @param UserRepository $users
* @param RemoveRoleRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(Role $role, UserRepository $users, RemoveRoleRequest $request)
{
$userRole = $this->roles->findByName('User');
$users->switchRolesForUsers($role->id, $userRole->id);
$this->roles->delete($role->id);
Cache::flush();
return $this->respondWithSuccess();
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Vanguard\Http\Controllers\Api;
use Vanguard\Http\Resources\CountryResource;
use Vanguard\Repositories\Country\CountryRepository;
/**
* @package Vanguard\Http\Controllers\Api
*/
class CountriesController extends ApiController
{
/**
* @var CountryRepository
*/
private $countries;
public function __construct(CountryRepository $countries)
{
$this->countries = $countries;
}
/**
* Get list of all available countries.
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public function index()
{
return CountryResource::collection($this->countries->all());
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace Vanguard\Http\Controllers\Api\Profile;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\User\UpdateProfileLoginDetailsRequest;
use Vanguard\Http\Resources\UserResource;
use Vanguard\Repositories\User\UserRepository;
/**
* @package Vanguard\Http\Controllers\Api\Profile
*/
class AuthDetailsController extends ApiController
{
/**
* Updates user profile details.
*
* @param UpdateProfileLoginDetailsRequest $request
* @param UserRepository $users
* @return UserResource
*/
public function update(UpdateProfileLoginDetailsRequest $request, UserRepository $users)
{
$user = $request->user();
$data = $request->only(['email', 'username', 'password']);
$user = $users->update($user->id, $data);
return new UserResource($user);
}
}

View File

@ -0,0 +1,86 @@
<?php
namespace Vanguard\Http\Controllers\Api\Profile;
use Illuminate\Http\Request;
use Vanguard\Events\User\ChangedAvatar;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\User\UploadAvatarRawRequest;
use Vanguard\Http\Resources\UserResource;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Services\Upload\UserAvatarManager;
/**
* @package Vanguard\Http\Controllers\Api\Profile
*/
class AvatarController extends ApiController
{
public function __construct(private UserRepository $users, private UserAvatarManager $avatarManager)
{
}
/**
* @param UploadAvatarRawRequest $request
* @return UserResource
*/
public function update(UploadAvatarRawRequest $request)
{
$name = $this->avatarManager->uploadAndCropAvatar(
$request->file('file')
);
$user = $this->users->update(
auth()->id(),
['avatar' => $name]
);
event(new ChangedAvatar);
return new UserResource($user);
}
/**
* @param Request $request
* @return UserResource
* @throws \Illuminate\Validation\ValidationException
*/
public function updateExternal(Request $request)
{
$this->validate($request, [
'url' => 'required|url'
]);
$this->avatarManager->deleteAvatarIfUploaded(
auth()->user()
);
$user = $this->users->update(
auth()->id(),
['avatar' => $request->url]
);
event(new ChangedAvatar);
return new UserResource($user);
}
/**
* Remove avatar for currently authenticated user and set it to null.
* @return UserResource
*/
public function destroy()
{
$user = auth()->user();
$this->avatarManager->deleteAvatarIfUploaded($user);
$user = $this->users->update(
$user->id,
['avatar' => null]
);
event(new ChangedAvatar);
return new UserResource($user);
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace Vanguard\Http\Controllers\Api\Profile;
use Vanguard\Events\User\UpdatedProfileDetails;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\User\UpdateProfileDetailsRequest;
use Vanguard\Http\Resources\UserResource;
use Vanguard\Repositories\User\UserRepository;
/**
* @package Vanguard\Http\Controllers\Api\Profile
*/
class DetailsController extends ApiController
{
/**
* Handle user details request.
* @return UserResource
*/
public function index()
{
return new UserResource(auth()->user());
}
/**
* Updates user profile details.
* @param UpdateProfileDetailsRequest $request
* @param UserRepository $users
* @return UserResource
*/
public function update(UpdateProfileDetailsRequest $request, UserRepository $users)
{
$user = $request->user();
$data = collect($request->all());
$data = $data->only([
'first_name', 'last_name', 'birthday',
'phone', 'address', 'country_id'
])->toArray();
if (! isset($data['country_id'])) {
$data['country_id'] = $user->country_id;
}
$user = $users->update($user->id, $data);
event(new UpdatedProfileDetails);
return new UserResource($user);
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Vanguard\Http\Controllers\Api\Profile;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Resources\SessionResource;
use Vanguard\Repositories\Session\SessionRepository;
/**
* @package Vanguard\Http\Controllers\Api\Profile
*/
class SessionsController extends ApiController
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('session.database');
}
/**
* Handle user details request.
* @param SessionRepository $sessions
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public function index(SessionRepository $sessions)
{
$sessions = $sessions->getUserSessions(auth()->id());
return SessionResource::collection($sessions);
}
}

View File

@ -0,0 +1,96 @@
<?php
namespace Vanguard\Http\Controllers\Api\Profile;
use Authy;
use Vanguard\Events\User\TwoFactorDisabled;
use Vanguard\Events\User\TwoFactorEnabled;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\TwoFactor\EnableTwoFactorRequest;
use Vanguard\Http\Requests\TwoFactor\VerifyTwoFactorTokenRequest;
use Vanguard\Http\Resources\UserResource;
/**
* @package Vanguard\Http\Controllers\Api\Profile
*/
class TwoFactorController extends ApiController
{
/**
* Enable 2FA for specified user.
* @param EnableTwoFactorRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function update(EnableTwoFactorRequest $request)
{
$user = auth()->user();
if (Authy::isEnabled($user)) {
return $this->setStatusCode(422)
->respondWithError("2FA is already enabled for this user.");
}
$user->setAuthPhoneInformation(
$request->country_code,
$request->phone_number
);
Authy::register($user);
$user->save();
Authy::sendTwoFactorVerificationToken($user);
return $this->respondWithArray([
'message' => 'Verification token sent.'
]);
}
/**
* Verify provided 2FA token.
*
* @param VerifyTwoFactorTokenRequest $request
* @return \Illuminate\Http\JsonResponse|UserResource
*/
public function verify(VerifyTwoFactorTokenRequest $request)
{
$user = auth()->user();
if (! Authy::tokenIsValid($user, $request->token)) {
return $this->setStatusCode(422)
->respondWithError("Invalid 2FA token.");
}
$user->setTwoFactorAuthProviderOptions(array_merge(
$user->getTwoFactorAuthProviderOptions(),
['enabled' => true]
));
$user->save();
event(new TwoFactorEnabled);
return new UserResource($user);
}
/**
* Disable 2FA for currently authenticated user.
* @return \Illuminate\Http\JsonResponse|UserResource
*/
public function destroy()
{
$user = auth()->user();
if (! Authy::isEnabled($user)) {
return $this->setStatusCode(422)
->respondWithError("2FA is not enabled for this user.");
}
Authy::delete($user);
$user->save();
event(new TwoFactorDisabled);
return new UserResource($user);
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace Vanguard\Http\Controllers\Api;
use Vanguard\Http\Resources\SessionResource;
use Vanguard\Repositories\Session\SessionRepository;
/**
* Class SessionsController
* @package Vanguard\Http\Controllers\Api\Users
*/
class SessionsController extends ApiController
{
public function __construct(private SessionRepository $sessions)
{
$this->middleware('session.database');
}
/**
* Get info about specified session.
* @param $session
* @return SessionResource
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show($session)
{
$this->authorize('manage-session', $session);
return new SessionResource($session);
}
/**
* Destroy specified session.
* @param $session
* @return \Illuminate\Http\JsonResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function destroy($session)
{
$this->authorize('manage-session', $session);
$this->sessions->invalidateSession($session->id);
return $this->respondWithSuccess();
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Vanguard\Http\Controllers\Api;
use Setting;
/**
* @package Vanguard\Http\Controllers\Api\Settings
*/
class SettingsController extends ApiController
{
public function __construct()
{
$this->middleware('permission:settings.general');
}
/**
* System settings.
* @return \Illuminate\Http\JsonResponse
*/
public function index()
{
return response()->json(Setting::all());
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace Vanguard\Http\Controllers\Api;
use Carbon\Carbon;
use Vanguard\Http\Resources\UserResource;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Support\Enum\UserStatus;
/**
* @package Vanguard\Http\Controllers\Api
*/
class StatsController extends ApiController
{
public function __construct(private UserRepository $users)
{
$this->middleware('role:Admin');
}
/**
* @return \Illuminate\Http\JsonResponse|mixed
*/
public function index()
{
$usersPerMonth = $this->users->countOfNewUsersPerMonth(
Carbon::now()->subYear()->startOfMonth(),
Carbon::now()->endOfMonth()
);
$usersPerStatus = [
'total' => $this->users->count(),
'new' => $this->users->newUsersCount(),
'banned' => $this->users->countByStatus(UserStatus::BANNED),
'unconfirmed' => $this->users->countByStatus(UserStatus::UNCONFIRMED)
];
$users = UserResource::collection($this->users->latest(7));
return $this->respondWithArray([
'users_per_month' => $usersPerMonth,
'users_per_status' => $usersPerStatus,
'latest_registrations' => $users->resolve()
]);
}
}

View File

@ -0,0 +1,77 @@
<?php
namespace Vanguard\Http\Controllers\Api\Users;
use Illuminate\Http\Request;
use Vanguard\Events\User\UpdatedByAdmin;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\User\UploadAvatarRawRequest;
use Vanguard\Http\Resources\UserResource;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Services\Upload\UserAvatarManager;
use Vanguard\User;
/**
* @package Vanguard\Http\Controllers\Api\Users
*/
class AvatarController extends ApiController
{
public function __construct(private UserRepository $users, private UserAvatarManager $avatarManager)
{
$this->middleware('permission:users.manage');
}
/**
* @param User $user
* @param UploadAvatarRawRequest $request
* @return UserResource
*/
public function update(User $user, UploadAvatarRawRequest $request)
{
$name = $this->avatarManager->uploadAndCropAvatar($request->file('file'));
$user = $this->users->update($user->id, ['avatar' => $name]);
event(new UpdatedByAdmin($user));
return new UserResource($user);
}
/**
* Update user's avatar to external resource.
*
* @param User $user
* @param Request $request
* @return UserResource
* @throws \Illuminate\Validation\ValidationException
*/
public function updateExternal(User $user, Request $request)
{
$this->validate($request, ['url' => 'required|url']);
$this->avatarManager->deleteAvatarIfUploaded($user);
$user = $this->users->update($user->id, ['avatar' => $request->url]);
event(new UpdatedByAdmin($user));
return new UserResource($user);
}
/**
* Remove user's avatar and set it to null.
*
* @param User $user
* @return UserResource
*/
public function destroy(User $user)
{
$this->avatarManager->deleteAvatarIfUploaded($user);
$user = $this->users->update($user->id, ['avatar' => null]);
event(new UpdatedByAdmin($user));
return new UserResource($user);
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Vanguard\Http\Controllers\Api\Users;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Resources\SessionResource;
use Vanguard\Repositories\Session\SessionRepository;
use Vanguard\User;
/**
* @package Vanguard\Http\Controllers\Api\Users
*/
class SessionsController extends ApiController
{
public function __construct()
{
$this->middleware('permission:users.manage');
$this->middleware('session.database');
}
/**
* Get sessions for specified user.
* @param User $user
* @param SessionRepository $sessions
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public function index(User $user, SessionRepository $sessions)
{
return SessionResource::collection(
$sessions->getUserSessions($user->id)
);
}
}

View File

@ -0,0 +1,96 @@
<?php
namespace Vanguard\Http\Controllers\Api\Users;
use Authy;
use Vanguard\Events\User\TwoFactorDisabledByAdmin;
use Vanguard\Events\User\TwoFactorEnabledByAdmin;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Requests\TwoFactor\EnableTwoFactorRequest;
use Vanguard\Http\Requests\TwoFactor\VerifyTwoFactorTokenRequest;
use Vanguard\Http\Resources\UserResource;
use Vanguard\User;
/**
* @package Vanguard\Http\Controllers\Api\Users
*/
class TwoFactorController extends ApiController
{
public function __construct()
{
$this->middleware('permission:users.manage');
}
/**
* Enable 2FA for specified user.
* @param User $user
* @param EnableTwoFactorRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function update(User $user, EnableTwoFactorRequest $request)
{
if (Authy::isEnabled($user)) {
return $this->setStatusCode(422)
->respondWithError("2FA is already enabled for this user.");
}
$user->setAuthPhoneInformation($request->country_code, $request->phone_number);
Authy::register($user);
$user->save();
Authy::sendTwoFactorVerificationToken($user);
return $this->respondWithArray([
'message' => 'Verification token sent.'
]);
}
/**
* Verify provided 2FA token.
*
* @param VerifyTwoFactorTokenRequest $request
* @param User $user
* @return \Illuminate\Http\JsonResponse|UserResource
*/
public function verify(VerifyTwoFactorTokenRequest $request, User $user)
{
if (! Authy::tokenIsValid($user, $request->token)) {
return $this->setStatusCode(422)
->respondWithError("Invalid 2FA token.");
}
$user->setTwoFactorAuthProviderOptions(array_merge(
$user->getTwoFactorAuthProviderOptions(),
['enabled' => true]
));
$user->save();
event(new TwoFactorEnabledByAdmin($user));
return new UserResource($user);
}
/**
* Disable 2FA for specified user.
* @param User $user
* @return \Illuminate\Http\JsonResponse|UserResource
*/
public function destroy(User $user)
{
if (! Authy::isEnabled($user)) {
return $this->setStatusCode(422)
->respondWithError("2FA is not enabled for this user.");
}
Authy::delete($user);
$user->save();
event(new TwoFactorDisabledByAdmin($user));
return new UserResource($user);
}
}

View File

@ -0,0 +1,140 @@
<?php
namespace Vanguard\Http\Controllers\Api\Users;
use Illuminate\Http\Request;
use Spatie\QueryBuilder\AllowedFilter;
use Spatie\QueryBuilder\QueryBuilder;
use Vanguard\Events\User\Banned;
use Vanguard\Events\User\Deleted;
use Vanguard\Events\User\UpdatedByAdmin;
use Vanguard\Http\Controllers\Api\ApiController;
use Vanguard\Http\Filters\UserKeywordSearch;
use Vanguard\Http\Requests\User\CreateUserRequest;
use Vanguard\Http\Requests\User\UpdateUserRequest;
use Vanguard\Http\Resources\UserResource;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Support\Enum\UserStatus;
use Vanguard\User;
/**
* @package Vanguard\Http\Controllers\Api\Users
*/
class UsersController extends ApiController
{
public function __construct(private UserRepository $users)
{
$this->middleware('permission:users.manage');
}
/**
* Paginate all users.
* @param Request $request
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public function index(Request $request)
{
$users = QueryBuilder::for(User::class)
->allowedIncludes(UserResource::allowedIncludes())
->allowedFilters([
AllowedFilter::custom('search', new UserKeywordSearch),
AllowedFilter::exact('status'),
])
->allowedSorts(['id', 'first_name', 'last_name', 'email', 'created_at', 'updated_at'])
->defaultSort('id')
->paginate($request->per_page ?: 20);
return UserResource::collection($users);
}
/**
* Create new user record.
* @param CreateUserRequest $request
* @return UserResource
*/
public function store(CreateUserRequest $request)
{
$data = $request->only([
'email', 'password', 'username', 'first_name', 'last_name',
'phone', 'address', 'country_id', 'birthday', 'role_id'
]);
$data += [
'status' => UserStatus::ACTIVE,
'email_verified_at' => $request->verified ? now() : null
];
$user = $this->users->create($data);
return new UserResource($user);
}
/**
* Show the info about requested user.
* @param $id
* @return UserResource
*/
public function show($id)
{
$user = QueryBuilder::for(User::where('id', $id))
->allowedIncludes(UserResource::allowedIncludes())
->firstOrFail();
return new UserResource($user);
}
/**
* @param User $user
* @param UpdateUserRequest $request
* @return UserResource
*/
public function update(User $user, UpdateUserRequest $request)
{
$data = $request->only([
'email', 'password', 'username', 'first_name', 'last_name',
'phone', 'address', 'country_id', 'birthday', 'status', 'role_id'
]);
$user = $this->users->update($user->id, $data);
event(new UpdatedByAdmin($user));
// If user status was updated to "Banned",
// fire the appropriate event.
if ($this->userIsBanned($user, $request)) {
event(new Banned($user));
}
return new UserResource($user);
}
/**
* Check if user is banned during last update.
*
* @param User $user
* @param Request $request
* @return bool
*/
private function userIsBanned(User $user, Request $request)
{
return $user->status != $request->status && $request->status == UserStatus::BANNED;
}
/**
* Remove specified user from storage.
* @param User $user
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(User $user)
{
if ($user->id == auth()->id()) {
return $this->errorForbidden(__("You cannot delete yourself."));
}
event(new Deleted($user));
$this->users->delete($user->id);
return $this->respondWithSuccess();
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Vanguard\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
abstract class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

View File

@ -0,0 +1,45 @@
<?php
namespace Vanguard\Http\Controllers\Web\Auth;
use Illuminate\Http\Request;
use Vanguard\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
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');
}
/**
* Get the response for a successful password reset link.
*
* @param \Illuminate\Http\Request $request
* @param string $response
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendResetLinkResponse(Request $request, $response)
{
return back()->with('success', trans($response));
}
}

View File

@ -0,0 +1,139 @@
<?php
namespace Vanguard\Http\Controllers\Web\Auth;
use Auth;
use Authy;
use Illuminate\Contracts\Container\BindingResolutionException;
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\User\UserRepository;
use Vanguard\Services\Auth\ThrottlesLogins;
use Vanguard\Services\Auth\TwoFactor\Contracts\Authenticatable;
class LoginController extends Controller
{
use ThrottlesLogins;
public function __construct(private UserRepository $users)
{
$this->middleware('guest')->except('logout');
$this->middleware('auth')->only('logout');
}
/**
* Show the application login form.
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function show()
{
return view('auth.login', [
'socialProviders' => config('auth.social.providers')
]);
}
/**
* @param LoginRequest $request
* @return RedirectResponse|Response
* @throws BindingResolutionException
*/
public function login(LoginRequest $request)
{
// 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 = 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 login 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(__('Your account is banned by administrator.'));
}
Auth::login($user, setting('remember_me') && $request->get('remember'));
return $this->authenticated($request, $throttles, $user);
}
/**
* Send the response after the user was authenticated.
*
* @param Request $request
* @param bool $throttles
* @param $user
* @return RedirectResponse|Response
*/
protected function authenticated(Request $request, $throttles, $user)
{
if ($throttles) {
$this->clearLoginAttempts($request);
}
if (setting('2fa.enabled') && Authy::isEnabled($user)) {
return $this->logoutAndRedirectToTokenPage($request, $user);
}
event(new LoggedIn);
if ($request->has('to')) {
return redirect()->to($request->get('to'));
}
return redirect()->intended();
}
/**
* @param Request $request
* @param Authenticatable $user
* @return RedirectResponse
*/
protected function logoutAndRedirectToTokenPage(Request $request, Authenticatable $user)
{
Auth::logout();
$request->session()->put('auth.2fa.id', $user->id);
return redirect()->route('auth.token');
}
/**
* Log the user out of the application.
*
* @return RedirectResponse|\Illuminate\Routing\Redirector
*/
public function logout()
{
event(new LoggedOut);
Auth::logout();
return redirect('login');
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace Vanguard\Http\Controllers\Web\Auth;
use Illuminate\Auth\Events\Registered;
use Vanguard\Http\Controllers\Controller;
use Vanguard\Http\Requests\Auth\RegisterRequest;
use Vanguard\Repositories\Role\RoleRepository;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Support\Enum\UserStatus;
class RegisterController extends Controller
{
public function __construct(private UserRepository $users)
{
$this->middleware('registration')->only('show', 'register');
}
/**
* Show the application registration form.
*
* @return \Illuminate\Http\Response
*/
public function show()
{
return view('auth.register', [
'socialProviders' => config('auth.social.providers')
]);
}
/**
* Handle a registration request for the application.
*
* @param RegisterRequest $request
* @param RoleRepository $roles
* @return \Illuminate\Http\Response
*/
public function register(RegisterRequest $request, RoleRepository $roles)
{
$user = $this->users->create(
array_merge($request->validFormData(), ['role_id' => $roles->findByName('User')->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);
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace Vanguard\Http\Controllers\Web\Auth;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Support\Str;
use Vanguard\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
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');
}
/**
* Reset the given user's password.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $password
* @return void
*/
protected function resetPassword($user, $password)
{
$user->password = $password;
$user->setRememberToken(Str::random(60));
$user->save();
event(new PasswordReset($user));
$this->guard()->login($user);
}
}

View File

@ -0,0 +1,107 @@
<?php
namespace Vanguard\Http\Controllers\Web\Auth;
use Auth;
use Authy;
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;
class SocialAuthController extends Controller
{
public function __construct(private UserRepository $users, private SocialManager $socialManager)
{
$this->middleware('guest');
}
/**
* Redirect user to specified provider in order to complete the authentication process.
*
* @param $provider
* @return \Illuminate\Http\RedirectResponse
*/
public function redirectToProvider($provider)
{
if (strtolower($provider) == 'facebook') {
return Socialite::driver('facebook')->with(['auth_type' => 'rerequest'])->redirect();
}
return Socialite::driver($provider)->redirect();
}
/**
* Handle response authentication provider.
*
* @param $provider
* @return \Illuminate\Http\RedirectResponse
*/
public function handleProviderCallback($provider)
{
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.
*
* @param $provider
* @return SocialUser
*/
private function getUserFromProvider($provider)
{
return Socialite::driver($provider)->user();
}
/**
* Log provided user in and redirect him to intended page.
*
* @param $user
* @return \Illuminate\Http\RedirectResponse
*/
private function loginAndRedirect($user)
{
if ($user->isBanned()) {
return redirect()->to('login')
->withErrors(__('Your account is banned by administrator.'));
}
if (setting('2fa.enabled') && Authy::isEnabled($user)) {
session()->put('auth.2fa.id', $user->id);
return redirect()->route('auth.token');
}
Auth::login($user);
event(new LoggedIn);
return redirect()->intended('/');
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace Vanguard\Http\Controllers\Web\Auth;
use Auth;
use Authy;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Vanguard\Events\User\LoggedIn;
use Vanguard\Http\Controllers\Controller;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Services\Auth\ThrottlesLogins;
class TwoFactorTokenController extends Controller
{
use ThrottlesLogins;
public function __construct(private UserRepository $users)
{
}
/**
* Show Two-Factor Token form.
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
*/
public function show()
{
return session('auth.2fa.id') ? view('auth.token') : redirect('login');
}
/**
* Handle Two-Factor token form submission.
*
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws \Illuminate\Validation\ValidationException
*/
public function update(Request $request)
{
$this->validate($request, ['token' => 'required']);
if (! session('auth.2fa.id')) {
return redirect('login');
}
$user = $this->users->find(
$request->session()->pull('auth.2fa.id')
);
if (! $user) {
throw new NotFoundHttpException;
}
if (! Authy::tokenIsValid($user, $request->token)) {
return redirect()->to('login')
->withErrors(__('2FA Token is invalid!'));
}
Auth::login($user);
event(new LoggedIn);
return redirect()->intended('/');
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace Vanguard\Http\Controllers\Web\Auth;
use Vanguard\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\VerifiesEmails;
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');
}
}

View File

@ -0,0 +1,110 @@
<?php
namespace Vanguard\Http\Controllers\Web\Authorization;
use Exception;
use Illuminate\Contracts\View\Factory;
use Illuminate\View\View;
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
* @package Vanguard\Http\Controllers
*/
class PermissionsController extends Controller
{
public function __construct(private RoleRepository $roles, private PermissionRepository $permissions)
{
}
/**
* Displays the page with all available permissions.
*
* @return Factory|View
*/
public function index()
{
return view('permission.index', [
'roles' => $this->roles->all(),
'permissions' => $this->permissions->all()
]);
}
/**
* Displays the form for creating new permission.
*
* @return Factory|View
*/
public function create()
{
return view('permission.add-edit', ['edit' => false]);
}
/**
* Store permission to database.
*
* @param CreatePermissionRequest $request
* @return mixed
*/
public function store(CreatePermissionRequest $request)
{
$this->permissions->create($request->all());
return redirect()->route('permissions.index')
->withSuccess(__('Permission created successfully.'));
}
/**
* Displays the form for editing specific permission.
*
* @param Permission $permission
* @return Factory|View
*/
public function edit(Permission $permission)
{
return view('permission.add-edit', [
'edit' => true,
'permission' => $permission
]);
}
/**
* Update specified permission.
*
* @param Permission $permission
* @param UpdatePermissionRequest $request
* @return mixed
*/
public function update(Permission $permission, UpdatePermissionRequest $request)
{
$this->permissions->update($permission->id, $request->all());
return redirect()->route('permissions.index')
->withSuccess(__('Permission updated successfully.'));
}
/**
* Destroy the permission if it is removable.
*
* @param Permission $permission
* @return mixed
* @throws Exception
*/
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.'));
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace Vanguard\Http\Controllers\Web\Authorization;
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
* @package Vanguard\Http\Controllers
*/
class RolePermissionsController extends Controller
{
public function __construct(private RoleRepository $roles)
{
}
/**
* Update permissions for each role.
*
* @param Request $request
* @return mixed
*/
public function update(Request $request)
{
$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.'));
}
}

View File

@ -0,0 +1,113 @@
<?php
namespace Vanguard\Http\Controllers\Web\Authorization;
use Cache;
use Illuminate\Contracts\View\Factory;
use Illuminate\View\View;
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;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class RolesController
* @package Vanguard\Http\Controllers
*/
class RolesController extends Controller
{
public function __construct(private RoleRepository $roles)
{
}
/**
* Display page with all available roles.
*
* @return Factory|View
*/
public function index()
{
return view('role.index', ['roles' => $this->roles->getAllWithUsersCount()]);
}
/**
* Display form for creating new role.
*
* @return Factory|View
*/
public function create()
{
return view('role.add-edit', ['edit' => false]);
}
/**
* Store newly created role to database.
*
* @param CreateRoleRequest $request
* @return mixed
*/
public function store(CreateRoleRequest $request)
{
$this->roles->create($request->all());
return redirect()->route('roles.index')
->withSuccess(__('Role created successfully.'));
}
/**
* Display for for editing specified role.
*
* @param Role $role
* @return Factory|View
*/
public function edit(Role $role)
{
return view('role.add-edit', [
'role' => $role,
'edit' => true
]);
}
/**
* Update specified role with provided data.
*
* @param Role $role
* @param UpdateRoleRequest $request
* @return mixed
*/
public function update(Role $role, UpdateRoleRequest $request)
{
$this->roles->update($role->id, $request->all());
return redirect()->route('roles.index')
->withSuccess(__('Role updated successfully.'));
}
/**
* Remove specified role from system.
*
* @param Role $role
* @param UserRepository $userRepository
* @return mixed
*/
public function destroy(Role $role, UserRepository $userRepository)
{
if (! $role->removable) {
throw new NotFoundHttpException;
}
$userRole = $this->roles->findByName('User');
$userRepository->switchRolesForUsers($role->id, $userRole->id);
$this->roles->delete($role->id);
Cache::flush();
return redirect()->route('roles.index')
->withSuccess(__('Role deleted successfully.'));
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Vanguard\Http\Controllers\Web;
use Illuminate\Contracts\View\Factory;
use Illuminate\View\View;
use Vanguard\Http\Controllers\Controller;
class DashboardController extends Controller
{
/**
* Displays the application dashboard.
*
* @return Factory|View
*/
public function index()
{
if (session()->has('verified')) {
session()->flash('success', __('E-Mail verified successfully.'));
}
return view('dashboard.index');
}
}

View File

@ -0,0 +1,240 @@
<?php
namespace Vanguard\Http\Controllers\Web;
use Artisan;
use DB;
use Illuminate\Contracts\View\View;
use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables;
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 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.");
}
Session::put('install.db_credentials', $dbCredentials);
return view('install.installation');
}
public function install(): RedirectResponse
{
try {
$db = Session::pull('install.db_credentials');
copy(base_path('.env.example'), base_path('.env'));
$this->reloadEnv();
$path = base_path('.env');
$env = file_get_contents($path);
$env = str_replace('DB_HOST='.env('DB_HOST'), sprintf('DB_HOST="%s"', $db['host']), $env);
$env = str_replace('DB_DATABASE='.env('DB_DATABASE'), sprintf('DB_DATABASE="%s"', $db['database']), $env);
$env = str_replace('DB_USERNAME='.env('DB_USERNAME'), sprintf('DB_USERNAME="%s"', $db['username']), $env);
$env = str_replace('DB_PASSWORD='.env('DB_PASSWORD'), sprintf('DB_PASSWORD="%s"', $db['password']), $env);
$env = str_replace('DB_PREFIX='.env('DB_PREFIX'), sprintf('DB_PREFIX="%s"', $db['prefix']), $env);
file_put_contents($path, $env);
$this->setDatabaseCredentials($db);
config(['app.debug' => true]);
\Setting::set('app_name', \request('app_name'));
\Setting::save();
Artisan::call('key:generate', ['--force' => true]);
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');
}
}
private function reloadEnv(): void
{
(new LoadEnvironmentVariables)->bootstrap(app());
}
public function complete(): View
{
return view('install.complete');
}
public function error(): View
{
return view('install.error');
}
/**
* @return array
*/
private function getRequirements(): array
{
$requirements = [
'PHP Version (>= 8.1.0)' => version_compare(phpversion(), '8.0.2', '>='),
'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;
}
/**
* @return bool
*/
private function allRequirementsLoaded(): bool
{
$allLoaded = true;
foreach ($this->getRequirements() as $loaded) {
if ($loaded == false) {
$allLoaded = false;
}
}
return $allLoaded;
}
/**
* @return array
*/
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
{
$allGranted = true;
foreach ($this->getPermissions() as $permission => $granted) {
if ($granted == false) {
$allGranted = false;
}
}
return $allGranted;
}
private function dbCredentialsAreValid($credentials): bool
{
$this->setDatabaseCredentials($credentials);
try {
DB::statement("SHOW TABLES");
} catch (\Exception $e) {
\Log::info($e->getMessage());
return false;
}
return true;
}
/**
* @param $credentials
*/
private function setDatabaseCredentials($credentials)
{
$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']
]);
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace Vanguard\Http\Controllers\Web\Profile;
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 ProfileController
* @package Vanguard\Http\Controllers
*/
class AvatarController extends Controller
{
public function __construct(private UserRepository $users)
{
}
/**
* Upload and update user's avatar.
*
* @param Request $request
* @param UserAvatarManager $avatarManager
* @return mixed
*/
public function update(Request $request, UserAvatarManager $avatarManager)
{
$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.
*
* @param $avatar
* @return mixed
*/
private function handleAvatarUpdate($avatar)
{
$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.
*
* @param Request $request
* @param UserAvatarManager $avatarManager
* @return mixed
*/
public function updateExternal(Request $request, UserAvatarManager $avatarManager)
{
$avatarManager->deleteAvatarIfUploaded(auth()->user());
return $this->handleAvatarUpdate($request->get('url'));
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace Vanguard\Http\Controllers\Web\Profile;
use Vanguard\Events\User\UpdatedProfileDetails;
use Vanguard\Http\Controllers\Controller;
use Vanguard\Http\Requests\User\UpdateProfileDetailsRequest;
use Vanguard\Repositories\User\UserRepository;
/**
* Class DetailsController
* @package Vanguard\Http\Controllers
*/
class DetailsController extends Controller
{
public function __construct(private UserRepository $users)
{
}
/**
* Update profile details.
*
* @param UpdateProfileDetailsRequest $request
* @return mixed
*/
public function update(UpdateProfileDetailsRequest $request)
{
$this->users->update(auth()->id(), $request->except('role_id', 'status'));
event(new UpdatedProfileDetails);
return redirect()->back()
->withSuccess(__('Profile updated successfully.'));
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace Vanguard\Http\Controllers\Web\Profile;
use Vanguard\Http\Controllers\Controller;
use Vanguard\Http\Requests\User\UpdateProfileLoginDetailsRequest;
use Vanguard\Repositories\User\UserRepository;
/**
* Class LoginDetailsController
* @package Vanguard\Http\Controllers
*/
class LoginDetailsController extends Controller
{
public function __construct(private UserRepository $users)
{
}
/**
* Update user's login details.
*
* @param UpdateProfileLoginDetailsRequest $request
* @return mixed
*/
public function update(UpdateProfileLoginDetailsRequest $request)
{
$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.'));
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace Vanguard\Http\Controllers\Web\Profile;
use Illuminate\Contracts\View\Factory;
use Illuminate\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
* @package Vanguard\Http\Controllers
*/
class ProfileController extends Controller
{
public function __construct(
private UserRepository $users,
private RoleRepository $roles,
private CountryRepository $countries
)
{
}
/**
* Display user's profile page.
*
* @return Factory|View
*/
public function show()
{
$roles = $this->roles->all()->filter(function ($role) {
return $role->id == auth()->user()->role_id;
})->pluck('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()
]);
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace Vanguard\Http\Controllers\Web\Profile;
use Vanguard\Http\Controllers\Controller;
use Vanguard\Repositories\Session\SessionRepository;
/**
* Class SessionsController
* @package Vanguard\Http\Controllers\Web\Profile
*/
class SessionsController extends Controller
{
public function __construct(private SessionRepository $sessions)
{
}
/**
* Get sessions for specified user.
*/
public function index()
{
return view('user.sessions', [
'profile' => true,
'user' => auth()->user(),
'sessions' => $this->sessions->getUserSessions(auth()->id())
]);
}
/**
* Invalidate user's session.
*
* @param $session \stdClass Session object.
* @return mixed
*/
public function destroy($session)
{
$this->sessions->invalidateSession($session->id);
return redirect()->route('profile.sessions')
->withSuccess(__('Session invalidated successfully.'));
}
}

View File

@ -0,0 +1,129 @@
<?php
namespace Vanguard\Http\Controllers\Web;
use Illuminate\Contracts\View\Factory;
use Illuminate\View\View;
use Vanguard\Events\Settings\Updated as SettingsUpdated;
use Illuminate\Http\Request;
use Setting;
use Vanguard\Http\Controllers\Controller;
/**
* Class SettingsController
* @package Vanguard\Http\Controllers
*/
class SettingsController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
/**
* Display general settings page.
*
* @return Factory|View
*/
public function general()
{
return view('settings.general');
}
/**
* Display Authentication & Registration settings page.
*
* @return Factory|View
*/
public function auth()
{
return view('settings.auth');
}
/**
* Handle application settings update.
*
* @param Request $request
* @return mixed
*/
public function update(Request $request)
{
$this->updatesetting($request->except("_token"));
return back()->withSuccess(__('Settings updated successfully.'));
}
/**
* Update settings and fire appropriate event.
*
* @param $input
*/
private function updatesetting($input)
{
foreach ($input as $key => $value) {
Setting::set($key, $value);
}
Setting::save();
event(new SettingsUpdated);
}
/**
* Enable system 2FA.
*
* @return mixed
*/
public function enableTwoFactor()
{
$this->updatesetting(['2fa.enabled' => true]);
return back()->withSuccess(__('Two-Factor Authentication enabled successfully.'));
}
/**
* Disable system 2FA.
*
* @return mixed
*/
public function disableTwoFactor()
{
$this->updatesetting(['2fa.enabled' => false]);
return back()->withSuccess(__('Two-Factor Authentication disabled successfully.'));
}
/**
* Enable registration captcha.
*
* @return mixed
*/
public function enableCaptcha()
{
$this->updatesetting(['registration.captcha.enabled' => true]);
return back()->withSuccess(__('reCAPTCHA enabled successfully.'));
}
/**
* Disable registration captcha.
*
* @return mixed
*/
public function disableCaptcha()
{
$this->updatesetting(['registration.captcha.enabled' => false]);
return back()->withSuccess(__('reCAPTCHA disabled successfully.'));
}
/**
* Display notification settings page.
*
* @return Factory|View
*/
public function notifications()
{
return view('settings.notifications');
}
}

View File

@ -0,0 +1,137 @@
<?php
namespace Vanguard\Http\Controllers\Web;
use Vanguard\Events\User\TwoFactorDisabled;
use Vanguard\Events\User\TwoFactorEnabled;
use Vanguard\Events\User\TwoFactorEnabledByAdmin;
use Vanguard\Http\Controllers\Controller;
use Vanguard\Http\Requests\TwoFactor\DisableTwoFactorRequest;
use Vanguard\Http\Requests\TwoFactor\EnableTwoFactorRequest;
use Vanguard\Http\Requests\TwoFactor\ReSendTwoFactorTokenRequest;
use Vanguard\Http\Requests\TwoFactor\VerifyTwoFactorTokenRequest;
use Authy;
use Vanguard\Repositories\User\UserRepository;
/**
* Class ProfileController
* @package Vanguard\Http\Controllers
*/
class TwoFactorController extends Controller
{
public function __construct(UserRepository $users)
{
$this->middleware('auth');
$this->middleware(function ($request, $next) use ($users) {
$user = $request->get('user')
? $users->find($request->get('user'))
: auth()->user();
return Authy::isEnabled($user) ? abort(404) : $next($request);
})->only('enable', 'verification', 'resend', 'verify');
}
/**
* Enable 2FA for currently logged user.
*
* @param EnableTwoFactorRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function enable(EnableTwoFactorRequest $request)
{
$user = $request->theUser();
$user->setAuthPhoneInformation($request->country_code, $request->phone_number);
Authy::register($user);
$user->save();
Authy::sendTwoFactorVerificationToken($user);
return $user->is(auth()->user())
? redirect()->route('two-factor.verification')
: redirect()->route('two-factor.verification', ['user' => $user->id]);
}
/**
* Show the phone verification page.
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function verification()
{
return view('user.two-factor-verification', [
'user' => request('user')
]);
}
/**
* Re-send phone verification token.
* @param ReSendTwoFactorTokenRequest $request
*/
public function resend(ReSendTwoFactorTokenRequest $request)
{
Authy::sendTwoFactorVerificationToken($request->theUser());
}
/**
* Verify 2FA token and enable 2FA if token is valid.
*
* @param VerifyTwoFactorTokenRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function verify(VerifyTwoFactorTokenRequest $request)
{
$user = $request->theUser();
if (! Authy::tokenIsValid($user, $request->token)) {
return redirect()->route('two-factor.verification')
->withErrors(['token' => 'Invalid 2FA token.']);
}
$user->setTwoFactorAuthProviderOptions(array_merge(
$user->getTwoFactorAuthProviderOptions(),
['enabled' => true]
));
$user->save();
$message = __('Two-Factor Authentication 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.
*
* @param DisableTwoFactorRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function disable(DisableTwoFactorRequest $request)
{
$user = $request->theUser();
if (! Authy::isEnabled($user)) {
abort(404);
}
Authy::delete($user);
$user->save();
event(new TwoFactorDisabled);
return redirect()->back()
->withSuccess(__('Two-Factor Authentication disabled successfully.'));
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace Vanguard\Http\Controllers\Web\Users;
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
* @package Vanguard\Http\Controllers\Api\Users
*/
class AvatarController extends ApiController
{
public function __construct(private UserRepository $users, private UserAvatarManager $avatarManager)
{
}
/**
* Update user's avatar from uploaded image.
*
* @param User $user
* @param Request $request
* @return mixed
* @throws ValidationException
*/
public function update(User $user, Request $request)
{
$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...)
*
* @param User $user
* @param Request $request
* @return mixed
*/
public function updateExternal(User $user, Request $request)
{
$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.'));
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace Vanguard\Http\Controllers\Web\Users;
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 UserDetailsController
* @package Vanguard\Http\Controllers\Users
*/
class DetailsController extends Controller
{
public function __construct(private UserRepository $users)
{
}
/**
* Updates user details.
*
* @param User $user
* @param UpdateDetailsRequest $request
* @return mixed
*/
public function update(User $user, UpdateDetailsRequest $request)
{
$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.
*
* @param User $user
* @param Request $request
* @return bool
*/
private function userWasBanned(User $user, Request $request)
{
return $user->status != $request->status
&& $request->status == UserStatus::BANNED;
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace Vanguard\Http\Controllers\Web\Users;
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 UserDetailsController
* @package Vanguard\Http\Controllers\Users
*/
class LoginDetailsController extends Controller
{
public function __construct(private UserRepository $users)
{
}
/**
* Update user's login details.
*
* @param User $user
* @param UpdateLoginDetailsRequest $request
* @return mixed
*/
public function update(User $user, UpdateLoginDetailsRequest $request)
{
$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.'));
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace Vanguard\Http\Controllers\Web\Users;
use Illuminate\Contracts\View\Factory;
use Illuminate\View\View;
use Vanguard\Http\Controllers\Controller;
use Vanguard\Repositories\Session\SessionRepository;
use Vanguard\User;
/**
* Class SessionsController
* @package Vanguard\Http\Controllers\Web\Users
*/
class SessionsController extends Controller
{
public function __construct(private SessionRepository $sessions)
{
$this->middleware('permission:users.manage');
}
/**
* Displays the list with all active sessions for the selected user.
*
* @param User $user
* @return Factory|View
*/
public function index(User $user)
{
return view('user.sessions', [
'adminView' => true,
'user' => $user,
'sessions' => $this->sessions->getUserSessions($user->id)
]);
}
/**
* Invalidate specified session for selected user.
*
* @param User $user
* @param $session
* @return mixed
*/
public function destroy(User $user, $session)
{
$this->sessions->invalidateSession($session->id);
return redirect()->route('user.sessions', $user->id)
->withSuccess(__('Session invalidated successfully.'));
}
}

View File

@ -0,0 +1,153 @@
<?php
namespace Vanguard\Http\Controllers\Web\Users;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Vanguard\Events\User\Deleted;
use Vanguard\Http\Controllers\Controller;
use Vanguard\Http\Requests\User\CreateUserRequest;
use Vanguard\Repositories\Activity\ActivityRepository;
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
* @package Vanguard\Http\Controllers
*/
class UsersController extends Controller
{
public function __construct(private UserRepository $users)
{
}
/**
* Display paginated list of all users.
*
* @param Request $request
* @return Factory|View
*/
public function index(Request $request)
{
$users = $this->users->paginate($perPage = 20, $request->search, $request->status);
$statuses = ['' => __('All')] + UserStatus::lists();
return view('user.list', compact('users', 'statuses'));
}
/**
* Displays user profile page.
*
* @param User $user
* @return Factory|View
*/
public function show(User $user)
{
return view('user.view', compact('user'));
}
/**
* Displays form for creating a new user.
*
* @param CountryRepository $countryRepository
* @param RoleRepository $roleRepository
* @return Factory|View
*/
public function create(CountryRepository $countryRepository, RoleRepository $roleRepository)
{
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.
*
* @param CountryRepository $countryRepository
* @return array
*/
private function parseCountries(CountryRepository $countryRepository)
{
return [0 => __('Select a Country')] + $countryRepository->lists()->toArray();
}
/**
* Stores new user into the database.
*
* @param CreateUserRequest $request
* @return mixed
*/
public function store(CreateUserRequest $request)
{
// 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.'));
}
/**
* Displays edit user form.
*
* @param User $user
* @param CountryRepository $countryRepository
* @param RoleRepository $roleRepository
* @return Factory|View
*/
public function edit(User $user, CountryRepository $countryRepository, RoleRepository $roleRepository)
{
return view('user.edit', [
'edit' => true,
'user' => $user,
'countries' => $this->parseCountries($countryRepository),
'roles' => $roleRepository->lists(),
'statuses' => UserStatus::lists(),
'socialLogins' => $this->users->getUserSocialLogins($user->id)
]);
}
/**
* Removes the user from database.
*
* @param User $user
* @return $this
*/
public function destroy(User $user)
{
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.'));
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Vanguard\Http\Filters;
use Illuminate\Database\Eloquent\Builder;
use Spatie\QueryBuilder\Filters\Filter;
class UserKeywordSearch implements Filter
{
public function __invoke(Builder $query, $search, string $property = '')
{
$query->where(function ($q) use ($search) {
$q->where('username', "like", "%{$search}%");
$q->orWhere('email', 'like', "%{$search}%");
$q->orWhere('first_name', 'like', "%{$search}%");
$q->orWhere('last_name', 'like', "%{$search}%");
});
}
}

95
app/Http/Kernel.php Normal file
View File

@ -0,0 +1,95 @@
<?php
namespace Vanguard\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array<int, class-string|string>
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\Vanguard\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\Vanguard\Http\Middleware\VerifyInstallation::class,
\Vanguard\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\Vanguard\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array<string, array<int, class-string|string>>
*/
protected $middlewareGroups = [
'web' => [
\Vanguard\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Vanguard\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
'banned',
],
'api' => [
\Vanguard\Http\Middleware\UseApiGuard::class,
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:60,1',
'bindings',
'banned',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array<string, class-string|string>
*/
protected $routeMiddleware = [
'auth' => \Vanguard\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \Vanguard\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'registration' => \Vanguard\Http\Middleware\RegistrationEnabled::class,
'social.login' => \Vanguard\Http\Middleware\SocialLogin::class,
'role' => \Vanguard\Http\Middleware\CheckRole::class,
'permission' => \Vanguard\Http\Middleware\CheckPermissions::class,
'session.database' => \Vanguard\Http\Middleware\DatabaseSession::class,
'two-factor' => \Vanguard\Http\Middleware\TwoFactorEnabled::class,
'verify-2fa-phone' => \Vanguard\Http\Middleware\VerifyTwoFactorPhone::class,
'password-reset' => \Vanguard\Http\Middleware\PasswordResetEnabled::class,
'banned' => \Vanguard\Http\Middleware\CheckIfBanned::class,
];
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Vanguard\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
}

View File

@ -0,0 +1,31 @@
<?php
namespace Vanguard\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class Authenticate
{
public function __construct(private Guard $auth)
{
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
return $request->expectsJson()
? response('Unauthorized.', 401)
: redirect()->guest('login');
}
return $next($request);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Vanguard\Http\Middleware;
use Closure;
class CheckIfBanned
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->user() && $request->user()->isBanned()) {
abort(403, __("Your account is banned by administrator."));
}
return $next($request);
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace Vanguard\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class CheckPermissions
{
public function __construct(protected Guard $auth)
{
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param $permissions
* @return mixed
*/
public function handle($request, Closure $next, $permissions)
{
if (! is_array($permissions)) {
$permissions = explode("|", $permissions);
}
if ($this->auth->guest() || ! $request->user()->hasPermission($permissions)) {
abort(403, "Forbidden.");
}
return $next($request);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Vanguard\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class CheckRole
{
public function __construct(protected Guard $auth)
{
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next, $role)
{
if ($this->auth->guest() || ! $request->user()->hasRole($role)) {
abort(403);
}
return $next($request);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Vanguard\Http\Middleware;
use Closure;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class DatabaseSession
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// If we are not using database session driver,
// just display 404 page
if (config('session.driver') != 'database') {
throw new NotFoundHttpException("The entity you are looking for does not exist.");
}
return $next($request);
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace Vanguard\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array<int, string>
*/
protected $except = [
//
];
}

View File

@ -0,0 +1,25 @@
<?php
namespace Vanguard\Http\Middleware;
use Closure;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class PasswordResetEnabled
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (! setting('forgot_password')) {
throw new NotFoundHttpException;
}
return $next($request);
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace Vanguard\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
class PreventRequestsDuringMaintenance extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array<int, string>
*/
protected $except = [
//
];
}

View File

@ -0,0 +1,34 @@
<?php
namespace Vanguard\Http\Middleware;
use Vanguard\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @param string|null ...$guards
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return request()->has('to')
? redirect(request()->get('to'))
: redirect(RouteServiceProvider::HOME);
}
}
return $next($request);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace Vanguard\Http\Middleware;
use Closure;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class RegistrationEnabled
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (! setting('reg_enabled')) {
throw new NotFoundHttpException;
}
return $next($request);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Vanguard\Http\Middleware;
use Closure;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class SocialLogin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$provider = $request->route()->parameter('provider');
if (! in_array($provider, config('auth.social.providers'))) {
throw new NotFoundHttpException;
}
return $next($request);
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Vanguard\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array<int, string>
*/
protected $except = [
'current_password',
'password',
'password_confirmation',
];
}

View File

@ -0,0 +1,20 @@
<?php
namespace Vanguard\Http\Middleware;
use Illuminate\Http\Middleware\TrustHosts as Middleware;
class TrustHosts extends Middleware
{
/**
* Get the host patterns that should be trusted.
*
* @return array<int, string|null>
*/
public function hosts()
{
return [
$this->allSubdomainsOfApplicationUrl(),
];
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Vanguard\Http\Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array<int, string>|string|null
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers =
Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB;
}

View File

@ -0,0 +1,25 @@
<?php
namespace Vanguard\Http\Middleware;
use Closure;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class TwoFactorEnabled
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (! setting('2fa.enabled')) {
throw new NotFoundHttpException;
}
return $next($request);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Vanguard\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Factory;
class UseApiGuard
{
public function __construct(protected Factory $auth)
{
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$this->auth->shouldUse('sanctum');
$request->headers->set('Accept', 'application/json');
return $next($request);
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace Vanguard\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array<int, string>
*/
protected $except = [
//
];
}

Some files were not shown because too many files have changed in this diff Show More