From 5c5c91cf8eb6a04d12c870b6f0323d6ca133565c Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 16 Jul 2021 10:47:32 +0100 Subject: [PATCH 01/12] Update flame to 1.1 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 51e9575939..88eeaee530 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ }, "require": { "php": ">=7.3", - "tastyigniter/flame": "~1.0", + "tastyigniter/flame": "~1.1", "laravel/framework": "~6.0" }, "require-dev": { From ff05b43f327b809cfadb4b948ede5554e13f4bda Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 16 Jul 2021 10:49:06 +0100 Subject: [PATCH 02/12] Add schedule types lang strings --- app/admin/formwidgets/ScheduleEditor.php | 2 +- app/admin/formwidgets/scheduleeditor/schedules.blade.php | 2 +- app/admin/language/en/lang.php | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/admin/formwidgets/ScheduleEditor.php b/app/admin/formwidgets/ScheduleEditor.php index f0546eecba..8e288341ec 100644 --- a/app/admin/formwidgets/ScheduleEditor.php +++ b/app/admin/formwidgets/ScheduleEditor.php @@ -72,7 +72,7 @@ public function onLoadRecord() $scheduleCode = post('recordId'); $scheduleItem = $this->getSchedule($scheduleCode); - $formTitle = sprintf(lang($this->formTitle), $scheduleCode); + $formTitle = sprintf(lang($this->formTitle), lang('admin::lang.text_'.$scheduleCode)); return $this->makePartial('recordeditor/form', [ 'formRecordId' => $scheduleCode, diff --git a/app/admin/formwidgets/scheduleeditor/schedules.blade.php b/app/admin/formwidgets/scheduleeditor/schedules.blade.php index 1dd56e0985..befb524089 100644 --- a/app/admin/formwidgets/scheduleeditor/schedules.blade.php +++ b/app/admin/formwidgets/scheduleeditor/schedules.blade.php @@ -10,7 +10,7 @@ class="card bg-light shadow-sm mb-2" >
-
{{ ucfirst(strtolower($schedule->name.' '.lang('admin::lang.locations.text_schedule'))) }}
+
{{ lang('admin::lang.text_'.$schedule->name).' '.lang('admin::lang.locations.text_schedule') }}

{{ lang('admin::lang.locations.text_'.$schedule->type) }}

diff --git a/app/admin/language/en/lang.php b/app/admin/language/en/lang.php index 9678428935..927ed99da9 100644 --- a/app/admin/language/en/lang.php +++ b/app/admin/language/en/lang.php @@ -49,6 +49,9 @@ 'text_help' => 'Click for Help', 'text_no_title' => 'No Title', 'text_allow' => 'Allow', + 'text_opening' => 'Opening', + 'text_delivery' => 'Delivery', + 'text_collection' => 'Pick-up', 'label_code' => 'Code', 'label_name' => 'Name', @@ -498,8 +501,6 @@ 'label_schedule_hours' => 'Hours', 'label_schedule_open' => 'Start Time', 'label_schedule_close' => 'End Time', - 'label_delivery_type' => 'Delivery Hours', - 'label_collection_type' => 'Pick-up Hours', 'label_area_shape' => 'Area Shape', 'label_area_circle' => 'Area Circle', 'label_area_vertices' => 'Area Vertices', From a48e1ddcfee2f7d41d7e66bb0c87c4d3b35f65eb Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 16 Jul 2021 10:51:22 +0100 Subject: [PATCH 03/12] New admin.workingSchedule.created event --- app/admin/traits/HasWorkingHours.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/admin/traits/HasWorkingHours.php b/app/admin/traits/HasWorkingHours.php index 793e18a6e5..9e16de3495 100644 --- a/app/admin/traits/HasWorkingHours.php +++ b/app/admin/traits/HasWorkingHours.php @@ -7,6 +7,7 @@ use Exception; use Igniter\Flame\Location\WorkingSchedule; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Event; use InvalidArgumentException; trait HasWorkingHours @@ -122,6 +123,8 @@ public function newWorkingSchedule($type, $days = null) $schedule->setType($type); + Event::fire('admin.workingSchedule.created', [$this, $schedule]); + return $schedule; } From 923c6e9f6cb18052eea653ceaf233ab2d6fd5e1e Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 16 Jul 2021 10:52:45 +0100 Subject: [PATCH 04/12] Minor fix --- app/admin/widgets/Lists.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/admin/widgets/Lists.php b/app/admin/widgets/Lists.php index 86bc335406..ee90eb257d 100644 --- a/app/admin/widgets/Lists.php +++ b/app/admin/widgets/Lists.php @@ -864,7 +864,7 @@ protected function evalTimetenseTypeValue($record, $column, $value) */ protected function evalCurrencyTypeValue($record, $column, $value) { - return currency_format($value); + return currency_format((float)$value); } /** From b86e113e27793a0d1ae485f6117447d7283aacfc Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 23 Jul 2021 14:55:04 +0100 Subject: [PATCH 05/12] Add cross-site scripting protection to controllers instead --- app/admin/classes/AdminController.php | 6 ++ app/admin/language/en/lang.php | 1 + app/admin/routes.php | 3 +- app/main/classes/MainController.php | 5 ++ app/main/routes.php | 3 +- app/system/traits/VerifiesCsrfToken.php | 83 +++++++++++++++++++++++++ config/system.php | 12 ++++ 7 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 app/system/traits/VerifiesCsrfToken.php diff --git a/app/admin/classes/AdminController.php b/app/admin/classes/AdminController.php index cb054ab47e..9a56332543 100644 --- a/app/admin/classes/AdminController.php +++ b/app/admin/classes/AdminController.php @@ -28,6 +28,7 @@ use System\Classes\ErrorHandler; use System\Traits\AssetMaker; use System\Traits\ConfigMaker; +use System\Traits\VerifiesCsrfToken; use System\Traits\ViewMaker; class AdminController extends BaseController @@ -38,6 +39,7 @@ class AdminController extends BaseController use WidgetMaker; use ValidatesForm; use HasAuthentication; + use VerifiesCsrfToken; /** * @var object Object used for storing a fatal error. @@ -136,6 +138,10 @@ public function remap($action, $params) $this->action = $action; $this->params = $params; + if (!$this->verifyCsrfToken()) { + return Response::make(lang('admin::lang.alert_invalid_csrf_token'), 403); + } + // Determine if this request is a public action or authentication is required $requireAuthentication = !(in_array($action, $this->publicActions) OR !$this->requireAuthentication); diff --git a/app/admin/language/en/lang.php b/app/admin/language/en/lang.php index 927ed99da9..3b1cb5d5a2 100644 --- a/app/admin/language/en/lang.php +++ b/app/admin/language/en/lang.php @@ -98,6 +98,7 @@ 'alert_warning_locationable_delete' => 'Warning: You do not have the right permission to delete record(s) attached to multiple locations, please contact the system administrator.', 'alert_form_error_message' => 'Sorry but form validation has failed, please check for errors.', 'alert_error_set_default' => '"%s" is disabled and cannot be set as default.', + 'alert_invalid_csrf_token' => 'Invalid security token, please reload the page and try again.', 'text_settings_title' => 'Settings', 'text_message_title' => 'Your messages', 'text_activity_title' => 'Recent activities', diff --git a/app/admin/routes.php b/app/admin/routes.php index fbe4eaae02..bf3a3fa84b 100644 --- a/app/admin/routes.php +++ b/app/admin/routes.php @@ -15,8 +15,7 @@ // Other pages Route::any('{slug}', 'System\Classes\Controller@runAdmin') - ->where('slug', '(.*)?') - ->middleware(\Igniter\Flame\Foundation\Http\Middleware\VerifyCsrfToken::class); + ->where('slug', '(.*)?'); }); // Admin entry point diff --git a/app/main/classes/MainController.php b/app/main/classes/MainController.php index ef0a9dd4c7..4617029441 100644 --- a/app/main/classes/MainController.php +++ b/app/main/classes/MainController.php @@ -34,6 +34,7 @@ use System\Models\Request_logs_model; use System\Template\Extension\BladeExtension as SystemBladeExtension; use System\Traits\AssetMaker; +use System\Traits\VerifiesCsrfToken; use URL; use View; @@ -44,6 +45,7 @@ class MainController extends BaseController { use AssetMaker; use EventEmitter; + use VerifiesCsrfToken; /** * @var \Main\Classes\Theme The main theme processed by the controller. @@ -354,6 +356,9 @@ protected function processHandlers() if (!$handler = $this->getHandler()) return FALSE; + if (!$this->verifyCsrfToken()) + return FALSE; + try { $this->validateHandler($handler); diff --git a/app/main/routes.php b/app/main/routes.php index 2ee8e77bca..d6c243d368 100644 --- a/app/main/routes.php +++ b/app/main/routes.php @@ -14,7 +14,6 @@ Route::any(config('system.assetsCombinerUri', '_assets').'/{asset}', 'System\Classes\Controller@combineAssets'); Route::any('{slug}', 'System\Classes\Controller@run') - ->where('slug', '(.*)?') - ->middleware(\Igniter\Flame\Foundation\Http\Middleware\VerifyCsrfToken::class); + ->where('slug', '(.*)?'); }); }); diff --git a/app/system/traits/VerifiesCsrfToken.php b/app/system/traits/VerifiesCsrfToken.php new file mode 100644 index 0000000000..bb5b79eb7f --- /dev/null +++ b/app/system/traits/VerifiesCsrfToken.php @@ -0,0 +1,83 @@ +addMinutes((int)$config['lifetime'])->getTimestamp(), + $config['path'], + $config['domain'], + $config['secure'], + FALSE, + FALSE, + $config['same_site'] ?? null + ); + } + + protected function verifyCsrfToken() + { + if (!config('system.enableCsrfProtection', TRUE) OR !$this->enableCsrfProtection) + return TRUE; + + if (in_array(Request::method(), ['HEAD', 'GET', 'OPTIONS'])) + return TRUE; + + if (!strlen($token = $this->getCsrfTokenFromRequest())) + return FALSE; + + return is_string(Request::session()->token()) + AND is_string($token) + AND hash_equals(Request::session()->token(), $token); + } + + /** + * Get the CSRF token from the request. + * + * @return string + */ + protected function getCsrfTokenFromRequest() + { + $token = Request::input('_token') ?: Request::header('X-CSRF-TOKEN'); + + if (!$token && $header = Request::header('X-XSRF-TOKEN')) { + try { + $token = Crypt::decrypt($header, static::serialized()); + } + catch (DecryptException $e) { + $token = ''; + } + } + + return $token; + } + + /** + * Determine if the cookie contents should be serialized. + * + * @return bool + */ + public static function serialized() + { + return EncryptCookies::serialized('XSRF-TOKEN'); + } +} diff --git a/config/system.php b/config/system.php index 1416dd2e47..1232d6724f 100644 --- a/config/system.php +++ b/config/system.php @@ -217,4 +217,16 @@ 'filePermissions' => '777', 'folderPermissions' => '777', + + /* + |-------------------------------------------------------------------------- + | Cross Site Request Forgery (CSRF) Protection + |-------------------------------------------------------------------------- + | + | If the CSRF protection is enabled, all "postback" requests are checked + | for a valid security token. + | + */ + + 'enableCsrfProtection' => TRUE, ]; From f61ae681da91317a29d77e6760d492943f8d4cc4 Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 23 Jul 2021 14:56:40 +0100 Subject: [PATCH 06/12] Set default queue connection to sync --- config/queue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/queue.php b/config/queue.php index 27aafd0371..e2ef5c13ea 100644 --- a/config/queue.php +++ b/config/queue.php @@ -15,7 +15,7 @@ | */ - 'default' => env('QUEUE_CONNECTION', 'database'), + 'default' => env('QUEUE_CONNECTION', 'sync'), /* |-------------------------------------------------------------------------- From 7050b4340b997871101337c03af7a95fda44a00b Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 23 Jul 2021 14:57:37 +0100 Subject: [PATCH 07/12] Add nginx config file --- .nginx.conf | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .nginx.conf diff --git a/.nginx.conf b/.nginx.conf new file mode 100644 index 0000000000..140bda6556 --- /dev/null +++ b/.nginx.conf @@ -0,0 +1,33 @@ +## Pass requests that don't refer directly to files in the filesystem to index.php +location / { try_files $uri $uri/ /index.php?$query_string; } + +## Pass the PHP scripts to FastCGI server +location ~ ^/index.php { +## Write your FPM configuration here + +} + +## Whitelist +location ~ ^/favicon\.ico { try_files $uri /index.php; } +location ~ ^/sitemap\.xml { try_files $uri /index.php; } + +## Block all .dotfiles except well-known +location ~ /\.(?!well-known).* { deny all; } + +### Let nginx return 404 if static file does not exists +location ~ ^/assets/media { try_files $uri 404; } +location ~ ^/storage/temp/public { try_files $uri 404; } + +location ~ ^/app/.*/assets { try_files $uri 404; } +location ~ ^/app/.*/actions/.*/assets { try_files $uri 404; } +location ~ ^/app/.*/dashboardwidgets/.*/assets { try_files $uri 404; } +location ~ ^/app/.*/formwidgets/.*/assets { try_files $uri 404; } +location ~ ^/app/.*/widgets/.*/assets { try_files $uri 404; } + +location ~ ^/extensions/.*/.*/assets { try_files $uri 404; } +location ~ ^/extensions/.*/.*/actions/.*/assets { try_files $uri 404; } +location ~ ^/extensions/.*/.*/dashboardwidgets/.*/assets { try_files $uri 404; } +location ~ ^/extensions/.*/.*/formwidgets/.*/assets { try_files $uri 404; } +location ~ ^/extensions/.*/.*/widgets/.*/assets { try_files $uri 404; } + +location ~ ^/themes/.*/assets { try_files $uri 404; } From dd90e71c3b3b4758497ba7ca0f150d421cc8f703 Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 23 Jul 2021 14:58:12 +0100 Subject: [PATCH 08/12] Add authorization header rewrite rules --- example.htaccess | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/example.htaccess b/example.htaccess index 36b3dc236f..12a1b116a9 100644 --- a/example.htaccess +++ b/example.htaccess @@ -17,6 +17,10 @@ ## # RewriteBase / + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + ## Redirect index.php from url to prevent duplicate urls ## RewriteCond %{THE_REQUEST} /index\.php [NC] From 27506e79f9d6e216a0e3527611e6030e9cf4ac35 Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 23 Jul 2021 17:48:19 +0100 Subject: [PATCH 09/12] Minor fix --- app/admin/classes/ToolbarButton.php | 2 +- ...07_20_010000_add_columns_default_value.php | 25 +++++++++++++++++++ app/admin/models/Orders_model.php | 5 ++-- app/admin/models/Reservations_model.php | 7 +++--- app/main/classes/MainController.php | 3 +-- 5 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 app/admin/database/migrations/2021_07_20_010000_add_columns_default_value.php diff --git a/app/admin/classes/ToolbarButton.php b/app/admin/classes/ToolbarButton.php index 7981ab423a..c5b87b24ff 100644 --- a/app/admin/classes/ToolbarButton.php +++ b/app/admin/classes/ToolbarButton.php @@ -93,7 +93,7 @@ public function getAttributes($htmlBuild = TRUE) } if ($this->disabled) - $result['disabled'] = 'disabled'; + $attributes['disabled'] = 'disabled'; return $htmlBuild ? Html::attributes($attributes) : $attributes; } diff --git a/app/admin/database/migrations/2021_07_20_010000_add_columns_default_value.php b/app/admin/database/migrations/2021_07_20_010000_add_columns_default_value.php new file mode 100644 index 0000000000..ea5ad05638 --- /dev/null +++ b/app/admin/database/migrations/2021_07_20_010000_add_columns_default_value.php @@ -0,0 +1,25 @@ +text('options')->change()->nullable(); + }); + + Schema::table('menu_item_options', function (Blueprint $table) { + $table->boolean('required')->change()->default(0); + }); + } + + public function down() + { + } +} diff --git a/app/admin/models/Orders_model.php b/app/admin/models/Orders_model.php index a09165b058..fa0d8cbcb2 100644 --- a/app/admin/models/Orders_model.php +++ b/app/admin/models/Orders_model.php @@ -202,9 +202,8 @@ public function getOrderDatetimeAttribute($value) AND !isset($this->attributes['order_time']) ) return null; - return Carbon::createFromTimeString( - "{$this->attributes['order_date']} {$this->attributes['order_time']}" - ); + return make_carbon($this->attributes['order_date']) + ->setTimeFromTimeString($this->attributes['order_time']); } public function getFormattedAddressAttribute($value) diff --git a/app/admin/models/Reservations_model.php b/app/admin/models/Reservations_model.php index 40c360e514..92c4a43d3d 100644 --- a/app/admin/models/Reservations_model.php +++ b/app/admin/models/Reservations_model.php @@ -78,7 +78,7 @@ class Reservations_model extends Model protected $purgeable = ['tables']; - public $appends = ['customer_name', 'duration', 'table_name']; + public $appends = ['customer_name', 'duration', 'table_name', 'reservation_datetime', 'reservation_end_datetime']; public static $allowedSortingColumns = [ 'reservation_id asc', 'reservation_id desc', @@ -222,9 +222,8 @@ public function getReservationDatetimeAttribute($value) AND !isset($this->attributes['reserve_time']) ) return null; - return Carbon::createFromTimeString( - "{$this->attributes['reserve_date']} {$this->attributes['reserve_time']}" - ); + return make_carbon($this->attributes['reserve_date']) + ->setTimeFromTimeString($this->attributes['reserve_time']); } public function getReservationEndDatetimeAttribute($value) diff --git a/app/main/classes/MainController.php b/app/main/classes/MainController.php index 4617029441..ece1511d46 100644 --- a/app/main/classes/MainController.php +++ b/app/main/classes/MainController.php @@ -276,9 +276,8 @@ public function runPage($page) // Render the layout $this->loader->setSource($this->layout); $template = $this->template->load($this->layout->getFilePath()); - $result = $template->render($this->vars); - return $result; + return $template->render($this->vars); } /** From c5b3eb78e0239a73ef0134103c576abf435e788b Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Sat, 24 Jul 2021 00:31:18 +0100 Subject: [PATCH 10/12] Env support (#804) * Start .env support * Add location_mode var * Missed app_key * update config env * code refactor * wip * Bootstrap app after rewriting env file * Config folder backup not necessary during update * Add mailer env * Copy example.env rather than move This prevents issues with example.env being missing when installation fails * wip * revert wip * refactor Co-authored-by: Sam Poyigi Co-authored-by: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> --- .../console/commands/IgniterInstall.php | 84 ++++++++++++++----- config/app.php | 23 ++++- config/broadcasting.php | 5 ++ config/cache.php | 8 ++ config/database.php | 81 ++++++++++-------- config/filesystems.php | 8 +- config/mail.php | 15 +++- config/queue.php | 13 +-- config/services.php | 12 ++- config/session.php | 4 +- config/system.php | 2 +- config/view.php | 9 +- example.env | 42 ++++++++++ 13 files changed, 224 insertions(+), 82 deletions(-) create mode 100644 example.env diff --git a/app/system/console/commands/IgniterInstall.php b/app/system/console/commands/IgniterInstall.php index c1dd1c0d69..17fa08daf2 100644 --- a/app/system/console/commands/IgniterInstall.php +++ b/app/system/console/commands/IgniterInstall.php @@ -2,14 +2,23 @@ namespace System\Console\Commands; +use Admin\Models\Customer_groups_model; +use Admin\Models\Locations_model; +use Admin\Models\Staff_groups_model; +use Admin\Models\Staff_roles_model; +use Admin\Models\Staffs_model; +use Admin\Models\Users_model; use App; +use Carbon\Carbon; use Config; use DB; +use Igniter\Flame\Foundation\Http\Kernel; use Igniter\Flame\Support\ConfigRewrite; use Illuminate\Console\Command; use Symfony\Component\Console\Input\InputOption; use System\Classes\UpdateManager; use System\Database\Seeds\DatabaseSeeder; +use System\Models\Languages_model; /** * Console command to install TastyIgniter. @@ -32,7 +41,7 @@ class IgniterInstall extends Command /** * @var \Igniter\Flame\Support\ConfigRewrite */ - protected $configWriter; + protected $configRewrite; /** * Create a new command instance. @@ -60,7 +69,10 @@ public function handle() $this->line('Enter a new value, or press ENTER for the default'); - $this->rewriteConfigFiles(); + $this->moveExampleFile('env', null, 'backup'); + $this->copyExampleFile('env', 'example', null); + + $this->rewriteEnvFile(); $this->setSeederProperties(); @@ -73,6 +85,8 @@ public function handle() $this->moveExampleFile('htaccess', null, 'backup'); $this->moveExampleFile('htaccess', 'example', null); + $this->deleteExampleFile('env'); + $this->alert('INSTALLATION COMPLETE'); } @@ -86,14 +100,10 @@ protected function getOptions() ]; } - protected function rewriteConfigFiles() + protected function rewriteEnvFile() { - $this->writeDatabaseConfig(); - $this->writeToConfig('app', ['key' => $this->generateEncryptionKey()]); - } + $this->replaceInEnv('APP_KEY=', 'APP_KEY='.$this->generateEncryptionKey()); - protected function writeDatabaseConfig() - { $config = []; $name = Config::get('database.default'); $config['host'] = $this->ask('MySQL Host', Config::get("database.connections.{$name}.host")); @@ -103,10 +113,10 @@ protected function writeDatabaseConfig() $config['password'] = $this->ask('MySQL Password', Config::get("database.connections.{$name}.password") ?: FALSE) ?: ''; $config['prefix'] = $this->ask('MySQL Table Prefix', Config::get("database.connections.{$name}.prefix") ?: FALSE) ?: ''; - $this->writeToConfig('database', ['default' => $name]); + $this->replaceInEnv('DB_CONNECTION=mysql', 'DB_CONNECTION='.$name); - foreach ($config as $config => $value) { - $this->writeToConfig('database', ['connections.'.$name.'.'.$config => $value]); + foreach ($config as $key => $value) { + $this->replaceInEnv('DB_'.strtoupper($key).'=', 'DB_'.strtoupper($key).'='.$value); } } @@ -114,6 +124,8 @@ protected function migrateDatabase() { $this->line('Migrating application and extensions...'); + resolve(Kernel::class)->bootstrap(); + DB::purge(); $manager = UpdateManager::instance()->setLogsOutput($this->output); @@ -126,10 +138,10 @@ protected function migrateDatabase() protected function setSeederProperties() { $siteName = $this->ask('Site Name', DatabaseSeeder::$siteName); - $this->writeToConfig('app', ['name' => $siteName]); + $this->replaceInEnv('APP_NAME=', 'APP_NAME='.$siteName); $siteUrl = $this->ask('Site URL', Config::get('app.url')); - $this->writeToConfig('app', ['url' => $siteUrl]); + $this->replaceInEnv('APP_URL=', 'APP_URL='.$siteUrl); DatabaseSeeder::$seedDemo = $this->confirm('Install demo data?', DatabaseSeeder::$seedDemo); @@ -144,22 +156,22 @@ protected function createSuperUser() $username = $this->ask('Admin Username', 'admin'); $password = $this->ask('Admin Password', '123456'); - $staff = \Admin\Models\Staffs_model::firstOrNew(['staff_email' => DatabaseSeeder::$siteEmail]); + $staff = Staffs_model::firstOrNew(['staff_email' => DatabaseSeeder::$siteEmail]); $staff->staff_name = DatabaseSeeder::$staffName; - $staff->staff_role_id = \Admin\Models\Staff_roles_model::first()->staff_role_id; - $staff->language_id = \System\Models\Languages_model::first()->language_id; + $staff->staff_role_id = Staff_roles_model::first()->staff_role_id; + $staff->language_id = Languages_model::first()->language_id; $staff->staff_status = TRUE; $staff->save(); - $staff->groups()->attach(\Admin\Models\Staff_groups_model::first()->staff_group_id); - $staff->locations()->attach(\Admin\Models\Locations_model::first()->location_id); + $staff->groups()->attach(Staff_groups_model::first()->staff_group_id); + $staff->locations()->attach(Locations_model::first()->location_id); - $user = \Admin\Models\Users_model::firstOrNew(['username' => $username]); + $user = Users_model::firstOrNew(['username' => $username]); $user->staff_id = $staff->staff_id; $user->password = $password; $user->super_user = TRUE; $user->is_activated = TRUE; - $user->date_activated = \Carbon\Carbon::now(); + $user->date_activated = Carbon::now(); $user->save(); $this->line('Admin user '.$username.' created!'); @@ -171,7 +183,7 @@ protected function addSystemValues() params()->set([ 'ti_setup' => 'installed', - 'default_location_id' => \Admin\Models\Locations_model::first()->location_id, + 'default_location_id' => Locations_model::first()->location_id, ]); params()->save(); @@ -181,7 +193,7 @@ protected function addSystemValues() setting()->set('site_email', DatabaseSeeder::$siteEmail); setting()->set('sender_name', DatabaseSeeder::$siteName); setting()->set('sender_email', DatabaseSeeder::$siteEmail); - setting()->set('customer_group_id', \Admin\Models\Customer_groups_model::first()->customer_group_id); + setting()->set('customer_group_id', Customer_groups_model::first()->customer_group_id); setting()->save(); // These parameters are no longer in use @@ -221,4 +233,32 @@ protected function moveExampleFile($name, $old, $new) rename(base_path().'/'.$old.'.'.$name, base_path().'/'.$new.'.'.$name); } } + + protected function copyExampleFile($name, $old, $new) + { + // /$old.$name => /$new.$name + if (file_exists(base_path().'/'.$old.'.'.$name)) { + if (file_exists(base_path().'/'.$new.'.'.$name)) + unlink(base_path().'/'.$new.'.'.$name); + + copy(base_path().'/'.$old.'.'.$name, base_path().'/'.$new.'.'.$name); + } + } + + protected function deleteExampleFile($name) + { + if (file_exists(base_path().'/example.'.$name)) { + unlink(base_path().'/example.'.$name); + } + } + + protected function replaceInEnv(string $search, string $replace) + { + $file = base_path().'/.env'; + + file_put_contents( + $file, + str_replace($search, $replace, file_get_contents($file)) + ); + } } diff --git a/config/app.php b/config/app.php index d2fdbdbffb..f923564a89 100755 --- a/config/app.php +++ b/config/app.php @@ -13,7 +13,7 @@ | */ - 'name' => 'TastyIgniter', + 'name' => env('APP_NAME', 'TastyIgniter'), /* |-------------------------------------------------------------------------- @@ -39,7 +39,7 @@ | */ - 'debug' => FALSE, + 'debug' => (bool)env('APP_DEBUG', FALSE), /* |-------------------------------------------------------------------------- @@ -52,7 +52,9 @@ | */ - 'url' => 'http://localhost/', + 'url' => env('APP_URL', 'http://localhost/'), + + 'asset_url' => env('ASSET_URL', null), /* |-------------------------------------------------------------------------- @@ -93,6 +95,19 @@ 'fallback_locale' => 'en', + /* + |-------------------------------------------------------------------------- + | Faker Locale + |-------------------------------------------------------------------------- + | + | This locale will be used by the Faker PHP library when generating fake + | data for your database seeds. For example, this will be used to get + | localized telephone numbers, street address information and more. + | + */ + + 'faker_locale' => 'en_US', + /* |-------------------------------------------------------------------------- | Encryption Key @@ -104,7 +119,7 @@ | */ - 'key' => 'CHANGE!!!!!!!!!!!!!!!!!!!!!!!!!', + 'key' => env('APP_KEY', 'CHANGE!!!!!!!!!!!!!!!!!!!!!!!!!'), 'cipher' => 'AES-256-CBC', diff --git a/config/broadcasting.php b/config/broadcasting.php index 5eecd2b266..0026b18c95 100644 --- a/config/broadcasting.php +++ b/config/broadcasting.php @@ -40,6 +40,11 @@ ], ], + 'ably' => [ + 'driver' => 'ably', + 'key' => env('ABLY_KEY'), + ], + 'redis' => [ 'driver' => 'redis', 'connection' => 'default', diff --git a/config/cache.php b/config/cache.php index f2bdc97e9e..fd126d52d0 100644 --- a/config/cache.php +++ b/config/cache.php @@ -73,6 +73,14 @@ 'connection' => 'default', ], + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], ], /* diff --git a/config/database.php b/config/database.php index 1c829269d4..0c070eae84 100644 --- a/config/database.php +++ b/config/database.php @@ -13,7 +13,7 @@ | */ - 'default' => 'mysql', + 'default' => env('DB_CONNECTION', 'mysql'), /* |-------------------------------------------------------------------------- @@ -35,49 +35,58 @@ 'sqlite' => [ 'driver' => 'sqlite', - 'database' => 'storage/database.sqlite', + 'url' => env('DATABASE_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', TRUE), ], 'mysql' => [ 'driver' => 'mysql', - 'host' => '127.0.0.1', - 'port' => 3306, - 'database' => 'database', - 'username' => 'username', - 'password' => 'password', - 'unix_socket' => '', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', - 'prefix' => 'ti_', - 'strict' => FALSE, + 'prefix' => env('DB_PREFIX', 'ti_'), + 'prefix_indexes' => TRUE, + 'strict' => TRUE, 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], ], 'pgsql' => [ 'driver' => 'pgsql', - 'host' => '127.0.0.1', - 'port' => 5432, - 'database' => 'database', - 'username' => 'username', - 'password' => 'password', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', + 'prefix_indexes' => TRUE, 'schema' => 'public', 'sslmode' => 'prefer', ], 'sqlsrv' => [ 'driver' => 'sqlsrv', - 'host' => 'localhost', - 'port' => 1433, - 'database' => 'database', - 'username' => 'username', - 'password' => 'password', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', - 'odbc' => TRUE, - 'odbc_datasource_name' => 'your-odbc-dsn', + 'prefix_indexes' => TRUE, ], ], @@ -101,32 +110,36 @@ |-------------------------------------------------------------------------- | | Redis is an open source, fast, and advanced key-value store that also - | provides a richer set of commands than a typical key-value systems + | provides a richer body of commands than a typical key-value system | such as APC or Memcached. Laravel makes it easy to dig right in. | */ 'redis' => [ - 'client' => 'phpredis', + 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ - 'cluster' => 'redis', - 'prefix' => 'tastyigniter_database_', + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', str_slug(env('APP_NAME', 'tastyigniter'), '_').'_database_'), ], 'default' => [ - 'host' => '127.0.0.1', - 'password' => null, - 'port' => 6379, - 'database' => 0, + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'password' => env('REDIS_PASSWORD', null), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_DB', '0'), ], 'cache' => [ - 'host' => '127.0.0.1', - 'password' => null, - 'port' => 6379, - 'database' => 1, + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'password' => env('REDIS_PASSWORD', null), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_CACHE_DB', '1'), ], + ], + ]; diff --git a/config/filesystems.php b/config/filesystems.php index 1768936300..209e5bbe14 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -62,10 +62,12 @@ 's3' => [ 'driver' => 's3', - 'key' => env('AWS_KEY'), - 'secret' => env('AWS_SECRET'), - 'region' => env('AWS_REGION'), + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + 'endpoint' => env('AWS_ENDPOINT'), ], ], diff --git a/config/mail.php b/config/mail.php index 5d94cf851f..8b632d577a 100644 --- a/config/mail.php +++ b/config/mail.php @@ -15,7 +15,7 @@ | */ - 'driver' => env('MAIL_DRIVER', 'smtp'), + 'driver' => env('MAIL_MAILER', 'smtp'), /* |-------------------------------------------------------------------------- @@ -119,4 +119,17 @@ ], ], + /* + |-------------------------------------------------------------------------- + | Log Channel + |-------------------------------------------------------------------------- + | + | If you are using the "log" driver, you may specify the logging channel + | if you prefer to keep mail messages separate from other log entries + | for simpler reading. Otherwise, the default channel will be used. + | + */ + + 'log_channel' => env('MAIL_LOG_CHANNEL'), + ]; diff --git a/config/queue.php b/config/queue.php index e2ef5c13ea..adcf2c8fff 100644 --- a/config/queue.php +++ b/config/queue.php @@ -50,17 +50,18 @@ 'sqs' => [ 'driver' => 'sqs', - 'key' => 'your-public-key', - 'secret' => 'your-secret-key', - 'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id', - 'queue' => 'your-queue-name', - 'region' => 'us-east-1', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'your-queue-name'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), ], 'redis' => [ 'driver' => 'redis', 'connection' => 'default', - 'queue' => 'default', + 'queue' => env('REDIS_QUEUE', 'default'), 'retry_after' => 90, 'block_for' => null, ], diff --git a/config/services.php b/config/services.php index 827d9fe79b..90f73d281e 100644 --- a/config/services.php +++ b/config/services.php @@ -17,6 +17,11 @@ 'mailgun' => [ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'), + 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), + ], + + 'postmark' => [ + 'token' => env('POSTMARK_TOKEN'), ], 'ses' => [ @@ -24,11 +29,4 @@ 'secret' => env('SES_SECRET'), 'region' => env('SES_REGION', 'us-east-1'), ], - - //'stripe' => [ - //'model' => App\User::class, - //'key' => env('STRIPE_KEY'), - //'secret' => env('STRIPE_SECRET'), - //], - ]; diff --git a/config/session.php b/config/session.php index c23001a219..f3c17876f3 100644 --- a/config/session.php +++ b/config/session.php @@ -70,7 +70,7 @@ | */ - 'connection' => null, + 'connection' => env('SESSION_CONNECTION', null), /* |-------------------------------------------------------------------------- @@ -96,7 +96,7 @@ | */ - 'store' => null, + 'store' => env('SESSION_STORE', null), /* |-------------------------------------------------------------------------- diff --git a/config/system.php b/config/system.php index 1232d6724f..ae9f4b95b0 100644 --- a/config/system.php +++ b/config/system.php @@ -13,7 +13,7 @@ | */ - 'locationMode' => 'multiple', + 'locationMode' => env('IGNITER_LOCATION_MODE', 'multiple'), /* |-------------------------------------------------------------------------- diff --git a/config/view.php b/config/view.php index 1e729d21b1..dea194c471 100644 --- a/config/view.php +++ b/config/view.php @@ -14,7 +14,9 @@ */ 'paths' => [ - base_path('views'), + base_path('app/admin/views'), + base_path('app/main/views'), + base_path('app/system/views'), ], /* @@ -28,6 +30,9 @@ | */ - 'compiled' => realpath(storage_path('framework/views')), + 'compiled' => env( + 'VIEW_COMPILED_PATH', + realpath(storage_path('framework/views')) + ), ]; diff --git a/example.env b/example.env new file mode 100644 index 0000000000..09126b8f5a --- /dev/null +++ b/example.env @@ -0,0 +1,42 @@ +# APP CONFIG (DO NOT REMOVE!) +APP_NAME= +APP_ENV=production +APP_KEY= +APP_DEBUG=false +APP_URL= + +IGNITER_LOCATION_MODE=multiple + +LOG_CHANNEL=stack + +# DATABASE CONFIG (DO NOT REMOVE!) +DB_CONNECTION=mysql +DB_HOST= +DB_PORT= +DB_DATABASE= +DB_USERNAME= +DB_PASSWORD= +DB_PREFIX= + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=log +MAIL_HOST=null +MAIL_PORT=null +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS=noreply@tastyigniter.tld +MAIL_FROM_NAME="${APP_NAME}" + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= From c276442a4c8ee1405705cb33c83cad49251fb2e0 Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Sat, 24 Jul 2021 12:51:12 +0100 Subject: [PATCH 11/12] Rewrite env file variables using preg_replace --- .../console/commands/IgniterInstall.php | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/app/system/console/commands/IgniterInstall.php b/app/system/console/commands/IgniterInstall.php index 17fa08daf2..9e77c2dabb 100644 --- a/app/system/console/commands/IgniterInstall.php +++ b/app/system/console/commands/IgniterInstall.php @@ -43,6 +43,8 @@ class IgniterInstall extends Command */ protected $configRewrite; + protected $dbConfig = []; + /** * Create a new command instance. */ @@ -69,13 +71,10 @@ public function handle() $this->line('Enter a new value, or press ENTER for the default'); - $this->moveExampleFile('env', null, 'backup'); - $this->copyExampleFile('env', 'example', null); + $this->setSeederProperties(); $this->rewriteEnvFile(); - $this->setSeederProperties(); - $this->migrateDatabase(); $this->createSuperUser(); @@ -102,20 +101,20 @@ protected function getOptions() protected function rewriteEnvFile() { - $this->replaceInEnv('APP_KEY=', 'APP_KEY='.$this->generateEncryptionKey()); + if (file_exists(base_path().'/example.env')) { + $this->moveExampleFile('env', null, 'backup'); + $this->moveExampleFile('env', 'example', null); + } - $config = []; - $name = Config::get('database.default'); - $config['host'] = $this->ask('MySQL Host', Config::get("database.connections.{$name}.host")); - $config['port'] = $this->ask('MySQL Port', Config::get("database.connections.{$name}.port") ?: FALSE) ?: ''; - $config['database'] = $this->ask('Database Name', Config::get("database.connections.{$name}.database")); - $config['username'] = $this->ask('MySQL Login', Config::get("database.connections.{$name}.username")); - $config['password'] = $this->ask('MySQL Password', Config::get("database.connections.{$name}.password") ?: FALSE) ?: ''; - $config['prefix'] = $this->ask('MySQL Table Prefix', Config::get("database.connections.{$name}.prefix") ?: FALSE) ?: ''; + if (!file_exists(base_path().'/.env')) + return; - $this->replaceInEnv('DB_CONNECTION=mysql', 'DB_CONNECTION='.$name); + $this->replaceInEnv('APP_KEY=', 'APP_KEY='.$this->generateEncryptionKey()); - foreach ($config as $key => $value) { + $this->replaceInEnv('APP_NAME=', 'APP_NAME='.DatabaseSeeder::$siteName); + $this->replaceInEnv('APP_URL=', 'APP_URL='.DatabaseSeeder::$siteUrl); + + foreach ($this->dbConfig as $key => $value) { $this->replaceInEnv('DB_'.strtoupper($key).'=', 'DB_'.strtoupper($key).'='.$value); } } @@ -137,16 +136,19 @@ protected function migrateDatabase() protected function setSeederProperties() { - $siteName = $this->ask('Site Name', DatabaseSeeder::$siteName); - $this->replaceInEnv('APP_NAME=', 'APP_NAME='.$siteName); + $name = Config::get('database.default'); + $this->dbConfig['host'] = $this->ask('MySQL Host', Config::get("database.connections.$name.host")); + $this->dbConfig['port'] = $this->ask('MySQL Port', Config::get("database.connections.$name.port") ?: FALSE) ?: ''; + $this->dbConfig['database'] = $this->ask('MySQL Database', Config::get("database.connections.$name.database")); + $this->dbConfig['username'] = $this->ask('MySQL Username', Config::get("database.connections.$name.username")); + $this->dbConfig['password'] = $this->ask('MySQL Password', Config::get("database.connections.$name.password") ?: FALSE) ?: ''; + $this->dbConfig['prefix'] = $this->ask('MySQL Table Prefix', Config::get("database.connections.$name.prefix") ?: FALSE) ?: ''; - $siteUrl = $this->ask('Site URL', Config::get('app.url')); - $this->replaceInEnv('APP_URL=', 'APP_URL='.$siteUrl); + DatabaseSeeder::$siteName = $this->ask('Site Name', DatabaseSeeder::$siteName); + DatabaseSeeder::$siteUrl = $this->ask('Site URL', Config::get('app.url')); DatabaseSeeder::$seedDemo = $this->confirm('Install demo data?', DatabaseSeeder::$seedDemo); - DatabaseSeeder::$siteName = $siteName; - DatabaseSeeder::$siteUrl = $siteUrl; DatabaseSeeder::$siteEmail = $this->ask('Admin Email', DatabaseSeeder::$siteEmail); DatabaseSeeder::$staffName = $this->ask('Admin Name', DatabaseSeeder::$staffName); } @@ -258,7 +260,7 @@ protected function replaceInEnv(string $search, string $replace) file_put_contents( $file, - str_replace($search, $replace, file_get_contents($file)) + preg_replace('/^'.$search.'(.*)$/m', $replace, file_get_contents($file)) ); } } From 8baf83b42e7756aaf903aaf2a38815f668239d47 Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Wed, 28 Jul 2021 11:39:57 +0100 Subject: [PATCH 12/12] Fix core upgrade path --- app/system/classes/UpdateManager.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/system/classes/UpdateManager.php b/app/system/classes/UpdateManager.php index 9a102f2aef..3f71071b23 100644 --- a/app/system/classes/UpdateManager.php +++ b/app/system/classes/UpdateManager.php @@ -513,6 +513,9 @@ public function extractFile($fileCode, $extractTo = null) if ($extractTo) $extractTo .= '/'.str_replace('.', '/', $fileCode); + if (is_null($extractTo)) + $extractTo = base_path(); + if (!file_exists($extractTo)) mkdir($extractTo, 0777, TRUE);