diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index a814bc8f4445..1b2f985a9458 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -2,15 +2,15 @@ namespace App\Http\Controllers; +use App\Http\Requests\Client\EditClientRequest; use App\Models\Client; use Illuminate\Http\Request; -use Illuminate\Support\Facades\DB; -use Illuminate\Support\Facades\Log; use Yajra\DataTables\Facades\DataTables; use Yajra\DataTables\Html\Builder; class ClientController extends Controller { + /** * Display a listing of the resource. * @@ -116,9 +116,11 @@ class ClientController extends Controller * @param int $id * @return \Illuminate\Http\Response */ - public function edit($id) + public function edit(EditClientRequest $request) { - // + $client = $request->entity(Client::class, request('client')); + + dd($client); } /** diff --git a/app/Http/Controllers/Traits/VerifiesUserEmail.php b/app/Http/Controllers/Traits/VerifiesUserEmail.php index 1070ed15111d..95aaa0f4d02d 100644 --- a/app/Http/Controllers/Traits/VerifiesUserEmail.php +++ b/app/Http/Controllers/Traits/VerifiesUserEmail.php @@ -3,10 +3,12 @@ namespace App\Http\Controllers\Traits; use App\Models\User; +use App\Utils\Traits\UserSessionAttributes; use Illuminate\Support\Facades\Auth; trait VerifiesUserEmail { + use UserSessionAttributes; public function confirm($code) { @@ -18,6 +20,8 @@ trait VerifiesUserEmail $user->confirmation_code = null; $user->save(); + $this->setCurrentCompanyId($user->companies()->first()->account->default_company_id); + Auth::loginUsingId($user->id, true); return redirect()->route('dashboard.index')->with('message', trans('texts.security_confirmation')); diff --git a/app/Http/Requests/Client/EditClientRequest.php b/app/Http/Requests/Client/EditClientRequest.php index f80d9f4d7a8c..c55ad83cf918 100644 --- a/app/Http/Requests/Client/EditClientRequest.php +++ b/app/Http/Requests/Client/EditClientRequest.php @@ -3,27 +3,19 @@ namespace App\Http\Requests\Client; use App\Http\Requests\Request; -use App\Utils\Traits\MakesHash; -class CreateAccountRequest extends Request +class EditClientRequest extends Request { - use MakesHash; /** * Determine if the user is authorized to make this request. * * @return bool */ - public function entity() - { - parent::entity(Client::class, $this->decodePrimaryKey(request())) - } - - - public function authorize() { - return ! auth()->user(); //todo permissions + return true; + // return ! auth()->user(); //todo permissions } diff --git a/app/Http/Requests/Request.php b/app/Http/Requests/Request.php index d3c3a1c11282..35f984c625a5 100644 --- a/app/Http/Requests/Request.php +++ b/app/Http/Requests/Request.php @@ -2,11 +2,17 @@ namespace App\Http\Requests; +use App\Utils\Traits\MakesHash; use Illuminate\Foundation\Http\FormRequest; -use Illuminate\Support\Facades\Auth; class Request extends FormRequest { + use MakesHash; + + public function entity($class, $encoded_primary_key) + { + return $class::findOrFail($this->decodePrimaryKey($encoded_primary_key)); + } /** * Determine if the user is authorized to make this request. @@ -25,7 +31,7 @@ class Request extends FormRequest */ public function rules() { - + return []; } } diff --git a/app/Jobs/Account/CreateAccount.php b/app/Jobs/Account/CreateAccount.php index 9be23697e795..dc70351ce702 100644 --- a/app/Jobs/Account/CreateAccount.php +++ b/app/Jobs/Account/CreateAccount.php @@ -5,6 +5,7 @@ namespace App\Jobs\Account; use App\Events\Account\AccountCreated; use App\Jobs\User\CreateUser; use App\Jobs\Company\CreateCompany; +use App\Utils\Traits\UserSessionAttributes; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Http\Request; use App\Models\Account; @@ -14,6 +15,7 @@ class CreateAccount { use Dispatchable; + use UserSessionAttributes; protected $request; @@ -35,15 +37,40 @@ class CreateAccount */ public function handle() { - + /* + * Create account + */ $account = Account::create($this->request->toArray()); + /* + * Create company + */ $company = CreateCompany::dispatchNow($this->request, $account); + /* + * Set default company + */ + $account->default_company_id = $company->id; + $account->save(); + + /* + * Create user + */ $user = CreateUser::dispatchNow($this->request, $account, $company); + /* + * Set current company + */ + $this->setCurrentCompanyId($user->companies()->first()->account->default_company_id); + + /* + * Login user + */ Auth::loginUsingId($user->id, true); + /* + * Fire related events + */ event(new AccountCreated($user)); return $user; diff --git a/app/Jobs/Company/CreateCompany.php b/app/Jobs/Company/CreateCompany.php index c9084d72c49e..442b2f19cbe9 100644 --- a/app/Jobs/Company/CreateCompany.php +++ b/app/Jobs/Company/CreateCompany.php @@ -41,6 +41,7 @@ class CreateCompany $company->name = $this->request->first_name . ' ' . $this->request->last_name; $company->account_id = $this->account->id; $company->company_key = $this->createHash(); + $company->db = config('database.default'); $company->ip = $this->request->ip(); $company->save(); diff --git a/app/Jobs/User/CreateUser.php b/app/Jobs/User/CreateUser.php index d9fbb58680f5..8b8336950e56 100644 --- a/app/Jobs/User/CreateUser.php +++ b/app/Jobs/User/CreateUser.php @@ -55,18 +55,7 @@ class CreateUser 'is_owner' => 1, 'is_admin' => 1, ]); -/* - CompanyUser::create([ - 'user_id' => $user->id, - 'account_id' => $this->account->id, - 'company_id' => $this->company->id, - 'is_admin' => true, - 'is_owner' => true, - 'permissions' => '', - ]); - -*/ event(new UserCreated($user)); return $user; diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 7fca324c8156..e8ca4305e123 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -22,6 +22,8 @@ class AuthServiceProvider extends ServiceProvider * * @return void */ + +/* public function boot() { $this->registerPolicies(); @@ -30,6 +32,18 @@ class AuthServiceProvider extends ServiceProvider return new MultiDatabaseUserProvider($this->app['hash'], $config['model']); }); + Auth::provider('contacts', function ($app, array $config) { + return new MultiDatabaseUserProvider($this->app['hash'], $config['model']); + + }); + } +*/ + public function register() + { + Auth::provider('users', function ($app, array $config) { + return new MultiDatabaseUserProvider($this->app['hash'], $config['model']); + }); + Auth::provider('contacts', function ($app, array $config) { return new MultiDatabaseUserProvider($this->app['hash'], $config['model']); diff --git a/app/Providers/TelescopeServiceProvider.php b/app/Providers/TelescopeServiceProvider.php new file mode 100644 index 000000000000..205c18da3b1d --- /dev/null +++ b/app/Providers/TelescopeServiceProvider.php @@ -0,0 +1,49 @@ +app->isLocal()) { + return true; + } + + return $entry->isReportableException() || + $entry->isFailedJob() || + $entry->isScheduledTask() || + $entry->hasMonitoredTag(); + }); + } + + /** + * Register the Telescope gate. + * + * This gate determines who can access Telescope in non-local environments. + * + * @return void + */ + protected function gate() + { + + Gate::define('viewTelescope', function ($user) { + return in_array($user->email, [ + // + ]); + }); + } +} diff --git a/composer.json b/composer.json index b7fd4ddb79e4..320ad671e1ff 100644 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ "laracasts/presenter": "^0.2.1", "laravel/framework": "5.7.*", "laravel/socialite": "^3.1", + "laravel/telescope": "^0.1.6", "laravel/tinker": "^1.0", "nwidart/laravel-modules": "^4.0", "predis/predis": "^1.1", diff --git a/composer.lock b/composer.lock index d02c6e810774..ba60a0af03a2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "753b0ff8fa34e1e5a54d950d3d780d30", + "content-hash": "a67265303c8a08e7564c887c1e040664", "packages": [ { "name": "asgrim/ofxparser", @@ -1065,6 +1065,69 @@ ], "time": "2018-10-18T03:39:04+00:00" }, + { + "name": "laravel/telescope", + "version": "v0.1.6", + "source": { + "type": "git", + "url": "https://github.com/laravel/telescope.git", + "reference": "e3dbda59367969222603a2a20f0ee3aabe7bcdce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/telescope/zipball/e3dbda59367969222603a2a20f0ee3aabe7bcdce", + "reference": "e3dbda59367969222603a2a20f0ee3aabe7bcdce", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "~5.7.7", + "moontoast/math": "^1.1", + "php": "^7.1.3", + "symfony/var-dumper": "^4.1" + }, + "require-dev": { + "nunomaduro/larastan": "^0.3.7", + "orchestra/testbench": "~3.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Telescope\\TelescopeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Telescope\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mohamed Said", + "email": "mohamed@laravel.com" + } + ], + "description": "An elegant debug assistant for the Laravel framework.", + "keywords": [ + "debugging", + "laravel", + "monitoring" + ], + "time": "2018-11-02T10:45:19+00:00" + }, { "name": "laravel/tinker", "version": "v1.0.8", @@ -1646,6 +1709,55 @@ ], "time": "2017-06-19T01:22:40+00:00" }, + { + "name": "moontoast/math", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/ramsey/moontoast-math.git", + "reference": "c2792a25df5cad4ff3d760dd37078fc5b6fccc79" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/moontoast-math/zipball/c2792a25df5cad4ff3d760dd37078fc5b6fccc79", + "reference": "c2792a25df5cad4ff3d760dd37078fc5b6fccc79", + "shasum": "" + }, + "require": { + "ext-bcmath": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "^0.9.0", + "phpunit/phpunit": "^4.7|>=5.0 <5.4", + "satooshi/php-coveralls": "^0.6.1", + "squizlabs/php_codesniffer": "^2.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Moontoast\\Math\\": "src/Moontoast/Math/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A mathematics library, providing functionality for large numbers", + "homepage": "https://github.com/ramsey/moontoast-math", + "keywords": [ + "bcmath", + "math" + ], + "time": "2017-02-16T16:54:46+00:00" + }, { "name": "nesbot/carbon", "version": "1.34.0", diff --git a/config/app.php b/config/app.php index 13eddf957dd3..9f434ea72300 100644 --- a/config/app.php +++ b/config/app.php @@ -178,6 +178,7 @@ return [ App\Providers\AuthServiceProvider::class, // App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, + App\Providers\TelescopeServiceProvider::class, App\Providers\RouteServiceProvider::class, ], diff --git a/config/database.php b/config/database.php index 9790da24c21e..45ed9c5a37fa 100644 --- a/config/database.php +++ b/config/database.php @@ -13,7 +13,7 @@ return [ | */ - 'default' => env('DB_CONNECTION', 'mysql'), + 'default' => env('DB_CONNECTION', 'db-ninja-01'), /* |-------------------------------------------------------------------------- diff --git a/config/datatables-buttons.php b/config/datatables-buttons.php new file mode 100644 index 000000000000..2bf42278951f --- /dev/null +++ b/config/datatables-buttons.php @@ -0,0 +1,70 @@ + [ + /* + * Base namespace/directory to create the new file. + * This is appended on default Laravel namespace. + * Usage: php artisan datatables:make User + * Output: App\DataTables\UserDataTable + * With Model: App\User (default model) + * Export filename: users_timestamp + */ + 'base' => 'DataTables', + + /* + * Base namespace/directory where your model's are located. + * This is appended on default Laravel namespace. + * Usage: php artisan datatables:make Post --model + * Output: App\DataTables\PostDataTable + * With Model: App\Post + * Export filename: posts_timestamp + */ + 'model' => '', + ], + + /* + * Set Custom stub folder + */ + //'stub' => '/resources/custom_stub', + + /* + * PDF generator to be used when converting the table to pdf. + * Available generators: excel, snappy + * Snappy package: barryvdh/laravel-snappy + * Excel package: maatwebsite/excel + */ + 'pdf_generator' => 'snappy', + + /* + * Snappy PDF options. + */ + 'snappy' => [ + 'options' => [ + 'no-outline' => true, + 'margin-left' => '0', + 'margin-right' => '0', + 'margin-top' => '10mm', + 'margin-bottom' => '10mm', + ], + 'orientation' => 'landscape', + ], + + /* + * Default html builder parameters. + */ + 'parameters' => [ + 'dom' => 'Bfrtip', + 'order' => [[0, 'desc']], + 'buttons' => [ + 'create', + 'export', + 'print', + 'reset', + 'reload', + ], + ], +]; diff --git a/config/datatables-fractal.php b/config/datatables-fractal.php new file mode 100644 index 000000000000..25f547a8341a --- /dev/null +++ b/config/datatables-fractal.php @@ -0,0 +1,13 @@ + 'include', + + /* + * Default fractal serializer. + */ + 'serializer' => League\Fractal\Serializer\DataArraySerializer::class, +]; diff --git a/config/datatables.php b/config/datatables.php new file mode 100644 index 000000000000..c0bce1fa4c4d --- /dev/null +++ b/config/datatables.php @@ -0,0 +1,116 @@ + [ + /* + * Smart search will enclose search keyword with wildcard string "%keyword%". + * SQL: column LIKE "%keyword%" + */ + 'smart' => true, + + /* + * Multi-term search will explode search keyword using spaces resulting into multiple term search. + */ + 'multi_term' => true, + + /* + * Case insensitive will search the keyword in lower case format. + * SQL: LOWER(column) LIKE LOWER(keyword) + */ + 'case_insensitive' => true, + + /* + * Wild card will add "%" in between every characters of the keyword. + * SQL: column LIKE "%k%e%y%w%o%r%d%" + */ + 'use_wildcards' => false, + ], + + /* + * DataTables internal index id response column name. + */ + 'index_column' => 'DT_Row_Index', + + /* + * List of available builders for DataTables. + * This is where you can register your custom dataTables builder. + */ + 'engines' => [ + 'eloquent' => \Yajra\DataTables\EloquentDataTable::class, + 'query' => \Yajra\DataTables\QueryDataTable::class, + 'collection' => \Yajra\DataTables\CollectionDataTable::class, + 'resource' => \Yajra\DataTables\ApiResourceDataTable::class, + ], + + /* + * DataTables accepted builder to engine mapping. + * This is where you can override which engine a builder should use + * Note, only change this if you know what you are doing! + */ + 'builders' => [ + //Illuminate\Database\Eloquent\Relations\Relation::class => 'eloquent', + //Illuminate\Database\Eloquent\Builder::class => 'eloquent', + //Illuminate\Database\Query\Builder::class => 'query', + //Illuminate\Support\Collection::class => 'collection', + ], + + /* + * Nulls last sql pattern for Posgresql & Oracle. + * For MySQL, use '-%s %s' + */ + 'nulls_last_sql' => '%s %s NULLS LAST', + + /* + * User friendly message to be displayed on user if error occurs. + * Possible values: + * null - The exception message will be used on error response. + * 'throw' - Throws a \Yajra\DataTables\Exceptions\Exception. Use your custom error handler if needed. + * 'custom message' - Any friendly message to be displayed to the user. You can also use translation key. + */ + 'error' => env('DATATABLES_ERROR', null), + + /* + * Default columns definition of dataTable utility functions. + */ + 'columns' => [ + /* + * List of columns hidden/removed on json response. + */ + 'excess' => ['rn', 'row_num'], + + /* + * List of columns to be escaped. If set to *, all columns are escape. + * Note: You can set the value to empty array to disable XSS protection. + */ + 'escape' => '*', + + /* + * List of columns that are allowed to display html content. + * Note: Adding columns to list will make us available to XSS attacks. + */ + 'raw' => ['action'], + + /* + * List of columns are are forbidden from being searched/sorted. + */ + 'blacklist' => ['password', 'remember_token'], + + /* + * List of columns that are only allowed fo search/sort. + * If set to *, all columns are allowed. + */ + 'whitelist' => '*', + ], + + /* + * JsonResponse header and options config. + */ + 'json' => [ + 'header' => [], + 'options' => 0, + ], + +]; diff --git a/config/telescope.php b/config/telescope.php new file mode 100644 index 000000000000..717491fffd84 --- /dev/null +++ b/config/telescope.php @@ -0,0 +1,82 @@ + 'telescope', + + /* + |-------------------------------------------------------------------------- + | Telescope Storage Driver + |-------------------------------------------------------------------------- + | + | This configuration options determines the storage driver that will + | be used to store Telescope's data. In addition, you may set any + | custom options as needed by the particular driver you choose. + | + */ + + 'driver' => env('TELESCOPE_DRIVER', 'database'), + + 'storage' => [ + 'database' => [ + 'connection' => env('DB_CONNECTION', 'mysql'), + ], + ], + + /* + |-------------------------------------------------------------------------- + | Telescope Route Middleware + |-------------------------------------------------------------------------- + | + | These middleware will be assigned to every Telescope route, giving you + | the chance to add your own middleware to this list or change any of + | the existing middleware. Or, you can simply stick with this list. + | + */ + + 'middleware' => [ + 'web', + Authorize::class, + ], + + /* + |-------------------------------------------------------------------------- + | Telescope Watchers + |-------------------------------------------------------------------------- + | + | The following array lists the "watchers" that will be registered with + | Telescope. The watchers gather the application's profile data when + | a request or task is executed. Feel free to customize this list. + | + */ + + 'watchers' => [ + Watchers\CacheWatcher::class => env('TELESCOPE_CACHE_WATCHER', true), + Watchers\CommandWatcher::class => env('TELESCOPE_COMMAND_WATCHER', true), + Watchers\DumpWatcher::class => env('TELESCOPE_DUMP_WATCHER', true), + Watchers\EventWatcher::class => env('TELESCOPE_EVENT_WATCHER', true), + Watchers\ExceptionWatcher::class => env('TELESCOPE_EXCEPTION_WATCHER', true), + Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true), + Watchers\LogWatcher::class => env('TELESCOPE_LOG_WATCHER', true), + Watchers\MailWatcher::class => env('TELESCOPE_MAIL_WATCHER', true), + Watchers\ModelWatcher::class => env('TELESCOPE_MODEL_WATCHER', true), + Watchers\NotificationWatcher::class => env('TELESCOPE_NOTIFICATION_WATCHER', true), + + Watchers\QueryWatcher::class => [ + 'enabled' => env('TELESCOPE_QUERY_WATCHER', true), + 'slow' => 100, + ], + + Watchers\RedisWatcher::class => env('TELESCOPE_REDIS_WATCHER', true), + + Watchers\RequestWatcher::class => [ + 'enabled' => env('TELESCOPE_REQUEST_WATCHER', true), + 'size_limit' => env('TELESCOPE_REQUEST_SIZE_LIMIT', 64), + ], + + Watchers\ScheduleWatcher::class => env('TELESCOPE_SCHEDULE_WATCHER', true), + ], +]; diff --git a/database/seeds/RandomDataSeeder.php b/database/seeds/RandomDataSeeder.php index bd52997106b6..a693b09124a0 100644 --- a/database/seeds/RandomDataSeeder.php +++ b/database/seeds/RandomDataSeeder.php @@ -62,7 +62,7 @@ class RandomDataSeeder extends Seeder ]); - factory(\App\Models\Client::class, 500)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){ + factory(\App\Models\Client::class, 50)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){ factory(\App\Models\ClientContact::class,1)->create([ 'user_id' => $user->id, @@ -71,7 +71,7 @@ class RandomDataSeeder extends Seeder 'is_primary' => 1 ]); - factory(\App\Models\ClientContact::class,100)->create([ + factory(\App\Models\ClientContact::class,10)->create([ 'user_id' => $user->id, 'client_id' => $c->id, 'company_id' => $company->id @@ -82,7 +82,7 @@ class RandomDataSeeder extends Seeder 'is_primary' => 1 ]); - factory(\App\Models\ClientLocation::class,100)->create([ + factory(\App\Models\ClientLocation::class,10)->create([ 'client_id' => $c->id, ]);