mirror of
https://github.com/Bubka/2FAuth.git
synced 2024-12-25 00:19:47 +01:00
Fix multiple issues detected by static analysis
This commit is contained in:
parent
46ef26e9dc
commit
2123250a5e
@ -19,14 +19,13 @@ public function index()
|
|||||||
{
|
{
|
||||||
$settings = Settings::all();
|
$settings = Settings::all();
|
||||||
$settingsResources = collect();
|
$settingsResources = collect();
|
||||||
$settings->each(function ($item, $key) use ($settingsResources) {
|
$settings->each(function (mixed $item, string $key) use ($settingsResources) {
|
||||||
$settingsResources->push([
|
$settingsResources->push([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $item
|
'value' => $item
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// return SettingResource::collection($tata);
|
|
||||||
return response()->json($settingsResources->all(), 200);
|
return response()->json($settingsResources->all(), 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property mixed $id
|
||||||
|
* @property string $name
|
||||||
|
* @property int|null $twofaccounts_count
|
||||||
|
*/
|
||||||
class GroupResource extends JsonResource
|
class GroupResource extends JsonResource
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
namespace App\Api\v1\Resources;
|
namespace App\Api\v1\Resources;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property mixed $id
|
||||||
|
* @property mixed $group_id
|
||||||
|
*/
|
||||||
class TwoFAccountReadResource extends TwoFAccountStoreResource
|
class TwoFAccountReadResource extends TwoFAccountStoreResource
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -4,6 +4,17 @@
|
|||||||
|
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property mixed $otp_type
|
||||||
|
* @property string $account
|
||||||
|
* @property string $service
|
||||||
|
* @property string $icon
|
||||||
|
* @property string $secret
|
||||||
|
* @property int $digits
|
||||||
|
* @property string $algorithm
|
||||||
|
* @property int|null $period
|
||||||
|
* @property int|null $counter
|
||||||
|
*/
|
||||||
class TwoFAccountStoreResource extends JsonResource
|
class TwoFAccountStoreResource extends JsonResource
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property mixed $id
|
||||||
|
* @property string $name
|
||||||
|
* @property string $email
|
||||||
|
*/
|
||||||
class UserResource extends JsonResource
|
class UserResource extends JsonResource
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +35,7 @@ public function __construct()
|
|||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function handle() : int
|
public function handle() : int
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@ trait ResetTrait
|
|||||||
/**
|
/**
|
||||||
* Reset icons
|
* Reset icons
|
||||||
*/
|
*/
|
||||||
protected function resetIcons()
|
protected function resetIcons() : void
|
||||||
{
|
{
|
||||||
$this->deleteIcons();
|
$this->deleteIcons();
|
||||||
$this->generateIcons();
|
$this->generateIcons();
|
||||||
@ -20,7 +20,7 @@ protected function resetIcons()
|
|||||||
/**
|
/**
|
||||||
* Delete all icons
|
* Delete all icons
|
||||||
*/
|
*/
|
||||||
protected function deleteIcons()
|
protected function deleteIcons() : void
|
||||||
{
|
{
|
||||||
$filesForDelete = \Illuminate\Support\Facades\File::glob('public/icons/*.png');
|
$filesForDelete = \Illuminate\Support\Facades\File::glob('public/icons/*.png');
|
||||||
Storage::delete($filesForDelete);
|
Storage::delete($filesForDelete);
|
||||||
@ -31,7 +31,7 @@ protected function deleteIcons()
|
|||||||
/**
|
/**
|
||||||
* Generate icons for seeded accounts
|
* Generate icons for seeded accounts
|
||||||
*/
|
*/
|
||||||
protected function generateIcons()
|
protected function generateIcons() : void
|
||||||
{
|
{
|
||||||
IconGenerator::generateIcon('amazon', IconGenerator::AMAZON);
|
IconGenerator::generateIcon('amazon', IconGenerator::AMAZON);
|
||||||
IconGenerator::generateIcon('apple', IconGenerator::APPLE);
|
IconGenerator::generateIcon('apple', IconGenerator::APPLE);
|
||||||
@ -49,7 +49,7 @@ protected function generateIcons()
|
|||||||
/**
|
/**
|
||||||
* Reset DB
|
* Reset DB
|
||||||
*/
|
*/
|
||||||
protected function resetDB(string $seeder)
|
protected function resetDB(string $seeder) : void
|
||||||
{
|
{
|
||||||
$this->flushDB();
|
$this->flushDB();
|
||||||
$this->seedDB($seeder);
|
$this->seedDB($seeder);
|
||||||
@ -58,7 +58,7 @@ protected function resetDB(string $seeder)
|
|||||||
/**
|
/**
|
||||||
* Delete all DB tables
|
* Delete all DB tables
|
||||||
*/
|
*/
|
||||||
protected function flushDB()
|
protected function flushDB() : void
|
||||||
{
|
{
|
||||||
// Reset the db
|
// Reset the db
|
||||||
DB::table('users')->delete();
|
DB::table('users')->delete();
|
||||||
@ -78,7 +78,7 @@ protected function flushDB()
|
|||||||
/**
|
/**
|
||||||
* Seed the DB
|
* Seed the DB
|
||||||
*/
|
*/
|
||||||
protected function seedDB(string $seeder)
|
protected function seedDB(string $seeder) : void
|
||||||
{
|
{
|
||||||
$this->callSilent('db:seed', [
|
$this->callSilent('db:seed', [
|
||||||
'--class' => $seeder
|
'--class' => $seeder
|
||||||
|
@ -29,7 +29,7 @@ public function update(UserUpdateRequest $request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!config('2fauth.config.isDemoApp') ) {
|
if (!config('2fauth.config.isDemoApp') ) {
|
||||||
tap($user)->update([
|
$user->update([
|
||||||
'name' => $validated['name'],
|
'name' => $validated['name'],
|
||||||
'email' => $validated['email'],
|
'email' => $validated['email'],
|
||||||
]);
|
]);
|
||||||
|
@ -54,7 +54,7 @@ public function rename(WebauthnRenameRequest $request, string $credential)
|
|||||||
$validated = $request->validated();
|
$validated = $request->validated();
|
||||||
|
|
||||||
$webAuthnCredential = WebAuthnCredential::where('id', $credential)->firstOrFail();
|
$webAuthnCredential = WebAuthnCredential::where('id', $credential)->firstOrFail();
|
||||||
$webAuthnCredential->name = $validated['name'];
|
$webAuthnCredential->name = $validated['name']; // @phpstan-ignore-line
|
||||||
$webAuthnCredential->save();
|
$webAuthnCredential->save();
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
@ -32,7 +32,8 @@ protected function authenticate($request, array $guards)
|
|||||||
|
|
||||||
foreach ($guards as $guard) {
|
foreach ($guards as $guard) {
|
||||||
if ($this->auth->guard($guard)->check()) {
|
if ($this->auth->guard($guard)->check()) {
|
||||||
return $this->auth->shouldUse($guard);
|
$this->auth->shouldUse($guard);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,10 @@ class KickOutInactiveUser
|
|||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @param \Closure $next
|
* @param \Closure $next
|
||||||
|
* @param string $guards
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function handle($request, Closure $next, ...$quards)
|
public function handle($request, Closure $next, ...$guards)
|
||||||
{
|
{
|
||||||
// We do not track activity of:
|
// We do not track activity of:
|
||||||
// - Guest
|
// - Guest
|
||||||
|
@ -13,7 +13,7 @@ class LogUserLastSeen
|
|||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @param \Closure $next
|
* @param \Closure $next
|
||||||
* @param string|null $guards
|
* @param string $guards
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function handle($request, Closure $next, ...$guards)
|
public function handle($request, Closure $next, ...$guards)
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property int $twofaccounts_count
|
||||||
|
*/
|
||||||
class Group extends Model
|
class Group extends Model
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -50,8 +50,6 @@ class TwoFAccount extends Model implements Sortable
|
|||||||
const DEFAULT_ALGORITHM = self::SHA1;
|
const DEFAULT_ALGORITHM = self::SHA1;
|
||||||
|
|
||||||
private const IMAGELINK_STORAGE_PATH = 'imagesLink/';
|
private const IMAGELINK_STORAGE_PATH = 'imagesLink/';
|
||||||
private const ICON_STORAGE_PATH = 'public/icons/';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of OTP types supported by 2FAuth
|
* List of OTP types supported by 2FAuth
|
||||||
@ -152,24 +150,6 @@ protected static function boot()
|
|||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Fill the model with an array of attributes.
|
|
||||||
*
|
|
||||||
* @param array $attributes
|
|
||||||
* @return $this
|
|
||||||
*
|
|
||||||
* @throws \Illuminate\Database\Eloquent\MassAssignmentException
|
|
||||||
*/
|
|
||||||
// public function fill(array $attributes)
|
|
||||||
// {
|
|
||||||
// parent::fill($attributes);
|
|
||||||
|
|
||||||
// if ($this->otp_type == self::TOTP && !$this->period) $this->period = self::DEFAULT_PERIOD;
|
|
||||||
// if ($this->otp_type == self::HOTP && !$this->counter) $this->counter = self::DEFAULT_COUNTER;
|
|
||||||
|
|
||||||
// return $this;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings for @spatie/eloquent-sortable package
|
* Settings for @spatie/eloquent-sortable package
|
||||||
@ -307,7 +287,7 @@ public function setPeriodAttribute($value)
|
|||||||
*/
|
*/
|
||||||
public function setCounterAttribute($value)
|
public function setCounterAttribute($value)
|
||||||
{
|
{
|
||||||
$this->attributes['counter'] = is_null($value) && $this->otp_type === self::HOTP ? self::DEFAULT_COUNTER : $value;
|
$this->attributes['counter'] = blank($value) && $this->otp_type === self::HOTP ? self::DEFAULT_COUNTER : $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -316,6 +296,8 @@ public function setCounterAttribute($value)
|
|||||||
*
|
*
|
||||||
* @throws InvalidSecretException The secret is not a valid base32 encoded string
|
* @throws InvalidSecretException The secret is not a valid base32 encoded string
|
||||||
* @throws UndecipherableException The secret cannot be deciphered
|
* @throws UndecipherableException The secret cannot be deciphered
|
||||||
|
* @throws UnsupportedOtpTypeException The defined OTP type is not supported
|
||||||
|
* @throws InvalidOtpParameterException One OTP parameter is invalid
|
||||||
* @return TotpDto|HotpDto
|
* @return TotpDto|HotpDto
|
||||||
*/
|
*/
|
||||||
public function getOTP()
|
public function getOTP()
|
||||||
@ -332,7 +314,15 @@ public function getOTP()
|
|||||||
$this->initGenerator();
|
$this->initGenerator();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( $this->otp_type === self::TOTP || $this->otp_type === self::STEAM_TOTP ) {
|
if ( $this->otp_type === self::HOTP ) {
|
||||||
|
|
||||||
|
$OtpDto = new HotpDto();
|
||||||
|
$OtpDto->otp_type = $this->otp_type;
|
||||||
|
$counter = $this->generator->getParameter('counter');
|
||||||
|
$OtpDto->password = $this->generator->at($counter);
|
||||||
|
$OtpDto->counter = $this->counter = $counter + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
$OtpDto = new TotpDto();
|
$OtpDto = new TotpDto();
|
||||||
$OtpDto->otp_type = $this->otp_type;
|
$OtpDto->otp_type = $this->otp_type;
|
||||||
@ -342,15 +332,6 @@ public function getOTP()
|
|||||||
: SteamTotp::getAuthCode(base64_encode(Base32::decodeUpper($this->secret)));
|
: SteamTotp::getAuthCode(base64_encode(Base32::decodeUpper($this->secret)));
|
||||||
$OtpDto->period = $this->period;
|
$OtpDto->period = $this->period;
|
||||||
}
|
}
|
||||||
else if ( $this->otp_type === self::HOTP ) {
|
|
||||||
|
|
||||||
$OtpDto = new HotpDto();
|
|
||||||
$OtpDto->otp_type = $this->otp_type;
|
|
||||||
$counter = $this->generator->getCounter();
|
|
||||||
$OtpDto->password = $this->generator->at($counter);
|
|
||||||
$OtpDto->counter = $this->counter = $counter + 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Log::info(sprintf('New OTP generated for TwoFAccount (%s)', $this->id ? 'id:'.$this->id: 'preview'));
|
Log::info(sprintf('New OTP generated for TwoFAccount (%s)', $this->id ? 'id:'.$this->id: 'preview'));
|
||||||
|
|
||||||
@ -475,12 +456,15 @@ private function enforceAsSteam() : void
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the OTP type of the instanciated OTP generator
|
* Returns the OTP type of the instanciated OTP generator
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function getGeneratorOtpType()
|
private function getGeneratorOtpType()
|
||||||
{
|
{
|
||||||
return Arr::get($this->generatorClassMap, get_class($this->generator));
|
return Arr::get($this->generatorClassMap, get_class($this->generator));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an otpauth URI built with model attribute values
|
* Returns an otpauth URI built with model attribute values
|
||||||
*/
|
*/
|
||||||
@ -494,6 +478,8 @@ public function getURI() : string
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Instanciates the OTP generator with model attribute values
|
* Instanciates the OTP generator with model attribute values
|
||||||
|
* @throws UnsupportedOtpTypeException The defined OTP type is not supported
|
||||||
|
* @throws InvalidOtpParameterException One OTP parameter is invalid
|
||||||
*/
|
*/
|
||||||
private function initGenerator() : void
|
private function initGenerator() : void
|
||||||
{
|
{
|
||||||
@ -604,7 +590,7 @@ private function getDefaultIcon()
|
|||||||
/**
|
/**
|
||||||
* Returns an acceptable value
|
* Returns an acceptable value
|
||||||
*/
|
*/
|
||||||
private function decryptOrReturn($value)
|
private function decryptOrReturn(mixed $value) : mixed
|
||||||
{
|
{
|
||||||
// Decipher when needed
|
// Decipher when needed
|
||||||
if ( Settings::get('useEncryption') && $value )
|
if ( Settings::get('useEncryption') && $value )
|
||||||
@ -625,7 +611,7 @@ private function decryptOrReturn($value)
|
|||||||
/**
|
/**
|
||||||
* Encrypt a value
|
* Encrypt a value
|
||||||
*/
|
*/
|
||||||
private function encryptOrReturn($value)
|
private function encryptOrReturn(mixed $value) : mixed
|
||||||
{
|
{
|
||||||
// should be replaced by laravel 8 attribute encryption casting
|
// should be replaced by laravel 8 attribute encryption casting
|
||||||
return Settings::get('useEncryption') ? Crypt::encryptString($value) : $value;
|
return Settings::get('useEncryption') ? Crypt::encryptString($value) : $value;
|
||||||
|
@ -15,7 +15,6 @@ class AuthServiceProvider extends ServiceProvider
|
|||||||
/**
|
/**
|
||||||
* The policy mappings for the application.
|
* The policy mappings for the application.
|
||||||
*
|
*
|
||||||
* @var array
|
|
||||||
*/
|
*/
|
||||||
// protected $policies = [
|
// protected $policies = [
|
||||||
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
|
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
|
||||||
|
@ -41,7 +41,7 @@ public function boot()
|
|||||||
$this->routes(function () {
|
$this->routes(function () {
|
||||||
Route::prefix('api/v1')
|
Route::prefix('api/v1')
|
||||||
->middleware('api.v1')
|
->middleware('api.v1')
|
||||||
->namespace($this->getApiNamespace(1))
|
->namespace($this->getApiNamespace('1'))
|
||||||
->group(base_path('routes/api/v1.php'));
|
->group(base_path('routes/api/v1.php'));
|
||||||
|
|
||||||
// Route::prefix('api/v2')
|
// Route::prefix('api/v2')
|
||||||
|
@ -15,12 +15,12 @@ class LogoService
|
|||||||
protected $tfas;
|
protected $tfas;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var
|
* @var string
|
||||||
*/
|
*/
|
||||||
const TFA_JSON = 'tfa.json';
|
const TFA_JSON = 'tfa.json';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var
|
* @var string
|
||||||
*/
|
*/
|
||||||
const TFA_URL = 'https://2fa.directory/api/v3/tfa.json';
|
const TFA_URL = 'https://2fa.directory/api/v3/tfa.json';
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ protected function fetchLogo(string $logoFile) : void
|
|||||||
/**
|
/**
|
||||||
* Prepare and make some replacement to optimize logo fetching
|
* Prepare and make some replacement to optimize logo fetching
|
||||||
*
|
*
|
||||||
* @param string $str
|
* @param string $domain
|
||||||
* @return string Optimized domain name
|
* @return string Optimized domain name
|
||||||
*/
|
*/
|
||||||
protected function cleanDomain(string $domain) : string
|
protected function cleanDomain(string $domain) : string
|
||||||
|
@ -36,7 +36,7 @@ public function __construct()
|
|||||||
/**
|
/**
|
||||||
* Get a setting
|
* Get a setting
|
||||||
*
|
*
|
||||||
* @param string|array $setting A single setting name or an associative array of name:value settings
|
* @param string $setting A single setting name
|
||||||
* @return mixed string|int|boolean|null
|
* @return mixed string|int|boolean|null
|
||||||
*/
|
*/
|
||||||
public function get($setting)
|
public function get($setting)
|
||||||
@ -135,7 +135,7 @@ private function build()
|
|||||||
/**
|
/**
|
||||||
* Replaces boolean by a patterned string as appstrack/laravel-options package does not support var type
|
* Replaces boolean by a patterned string as appstrack/laravel-options package does not support var type
|
||||||
*
|
*
|
||||||
* @param mixed $settings
|
* @param mixed $value
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function replaceBoolean(mixed $value)
|
private function replaceBoolean(mixed $value)
|
||||||
@ -147,7 +147,7 @@ private function replaceBoolean(mixed $value)
|
|||||||
/**
|
/**
|
||||||
* Replaces patterned string that represent booleans with real booleans
|
* Replaces patterned string that represent booleans with real booleans
|
||||||
*
|
*
|
||||||
* @param mixed $settings
|
* @param mixed $value
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function restoreType(mixed $value)
|
private function restoreType(mixed $value)
|
||||||
|
@ -82,6 +82,8 @@ public static function convertMigrationFromGA($migrationUri) : Collection
|
|||||||
throw new InvalidGoogleAuthMigration();
|
throw new InvalidGoogleAuthMigration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$twofaccounts = array();
|
||||||
|
|
||||||
foreach ($otpParameters->getIterator() as $key => $otp_parameters) {
|
foreach ($otpParameters->getIterator() as $key => $otp_parameters) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -123,9 +125,11 @@ public static function convertMigrationFromGA($migrationUri) : Collection
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Explode a comma separated list of IDs to an array of IDs
|
||||||
*
|
*
|
||||||
|
* @param int|array|string $ids
|
||||||
*/
|
*/
|
||||||
private static function commaSeparatedToArray($ids)
|
private static function commaSeparatedToArray($ids) : mixed
|
||||||
{
|
{
|
||||||
if(is_string($ids))
|
if(is_string($ids))
|
||||||
{
|
{
|
||||||
@ -142,10 +146,10 @@ private static function commaSeparatedToArray($ids)
|
|||||||
/**
|
/**
|
||||||
* Return the given collection with items marked as Duplicates (using id=-1) if a similar record exists in database
|
* Return the given collection with items marked as Duplicates (using id=-1) if a similar record exists in database
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Support\Collection
|
* @param \Illuminate\Support\Collection $twofaccounts
|
||||||
* @return \Illuminate\Support\Collection
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
private static function markAsDuplicate($twofaccounts) : Collection
|
private static function markAsDuplicate(Collection $twofaccounts) : Collection
|
||||||
{
|
{
|
||||||
$storage = TwoFAccount::all();
|
$storage = TwoFAccount::all();
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Illuminate\Foundation\Inspiring;
|
use Illuminate\Foundation\Inspiring;
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user