From 6cf671cb23f3b78fafa73dc021e84b9d7b29ceff Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 10 Apr 2022 05:50:44 -0600 Subject: [PATCH] Add web installer --- app/Http/Controllers/InstallController.php | 214 +++++++++++++++++++++ public/js/installer.js | Bin 0 -> 66532 bytes public/js/installer.js.LICENSE.txt | 1 + public/mix-manifest.json | Bin 3235 -> 3315 bytes resources/views/installer/index.blade.php | 79 ++++++++ routes/web.php | 8 + 6 files changed, 302 insertions(+) create mode 100644 app/Http/Controllers/InstallController.php create mode 100644 public/js/installer.js create mode 100644 public/js/installer.js.LICENSE.txt create mode 100644 resources/views/installer/index.blade.php diff --git a/app/Http/Controllers/InstallController.php b/app/Http/Controllers/InstallController.php new file mode 100644 index 000000000..0204f16f0 --- /dev/null +++ b/app/Http/Controllers/InstallController.php @@ -0,0 +1,214 @@ + PHP_VERSION, + 'supported' => (bool) version_compare(PHP_VERSION, 7.4), + 'min_version' => '7.4', + 'memory_limit' => [ + 'recommended' => '256M', + 'actual' => ini_get('memory_limit'), + ], + 'upload_max_filesize' => [ + 'recommended' => '15M', + 'actual' => ini_get('upload_max_filesize') + ], + 'post_max_size' => [ + 'recommended' => '15M', + 'actual' => ini_get('post_max_size') + ] + ]; + + $reqs['php']['extensions'] = collect($phpExtensions) + ->map(function($ext) { + return [ 'name' => $ext, 'loaded' => extension_loaded($ext) ]; + }); + + $reqs['permissions'] = collect($dirs) + ->map(function($path) { + return [ + 'name' => $path, + 'writable' => is_writable(base_path($path)), + 'mode' => substr(sprintf('%o', fileperms(base_path($path))), -4), + 'path' => base_path($path) + ]; + }); + return $reqs; + } + + public function store(Request $request) + { + abort_if(file_exists(base_path('.env')), 404, 'The .env configuration file already exists.'); + return $this->checkPermissions($request); + return response()->json($request->all(), 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); + } + + protected function checkPermissions($request) + { + abort_if(file_exists(base_path('.env')), 404); + + if( file_exists(base_path('.env'))) { + return response('Found existing .env file, aborting installation', 400); + } + + if( !is_writable(base_path('storage/')) ) { + return response('Permission Problem(s), cannot write to bootstrap or storage directories', 400); + } + return $this->checkDatabase($request); + } + + protected function checkDatabase($request) + { + abort_if(file_exists(base_path('.env')), 404); + + $driver = $request->input('db_driver', 'mysql'); + $name = $request->input('db_name', 'pixelfed'); + $host = $request->input('db_host', 'localhost'); + $username = $request->input('db_username'); + $password = $request->input('db_password'); + $dsn = "{$driver}:dbname={$name};host={$host}"; + $dbh = new \PDO($dsn, $username, $password); + + try { + $dbh->query('SELECT count(*) from INFORMATION_SCHEMA.TABLES'); + } catch (\PDOException $e) { + return response($e, 400); + } + + $this->createConfiguration($request); + } + + protected function createConfiguration($request) + { + abort_if(file_exists(base_path('.env')), 404); + $source = base_path('.env.example'); + $target = base_path('.env'); + @copy($source, $target); + + $this->updateConfig('APP_URL=http://localhost', 'APP_URL=https://'.$request->input('domain')); + $this->updateConfig('APP_NAME="Pixelfed Prod"', 'APP_NAME="'.$request->input('name').'"'); + $this->updateConfig('APP_DOMAIN="localhost"', 'APP_DOMAIN="'.$request->input('domain').'"'); + $this->updateConfig('ADMIN_DOMAIN="localhost"', 'ADMIN_DOMAIN="'.$request->input('domain').'"'); + $this->updateConfig('SESSION_DOMAIN="localhost"', 'SESSION_DOMAIN="'.$request->input('domain').'"'); + + $this->updateConfig('DB_CONNECTION=mysql', 'DB_CONNECTION='.$request->input('db_driver')); + $this->updateConfig('DB_HOST=127.0.0.1', 'DB_HOST='.$request->input('db_host')); + $this->updateConfig('DB_PORT=3306', 'DB_PORT='.$request->input('db_port')); + $this->updateConfig('DB_DATABASE=pixelfed', 'DB_DATABASE='.$request->input('db_name')); + $this->updateConfig('DB_USERNAME=pixelfed', 'DB_USERNAME='.$request->input('db_username')); + $this->updateConfig('DB_PASSWORD=pixelfed', 'DB_PASSWORD='.$request->input('db_password')); + + $this->updateConfig('CACHE_DRIVER=redis', 'CACHE_DRIVER='.$request->input('cache_driver')); + $this->updateConfig('QUEUE_DRIVER=redis', 'QUEUE_DRIVER='.$request->input('queue_driver')); + $this->updateConfig('REDIS_SCHEME=tcp', 'REDIS_SCHEME='.$request->input('redis_scheme')); + $this->updateConfig('REDIS_HOST=127.0.0.1', 'REDIS_HOST='.$request->input('redis_host')); + $this->updateConfig('REDIS_PORT=6379', 'REDIS_PORT='.$request->input('redis_port')); + $this->updateConfig('REDIS_PASSWORD=null', 'REDIS_PASSWORD='.$request->input('redis_password')); + + $this->updateConfig('ACTIVITY_PUB=false', 'ACTIVITY_PUB=' .($request->input('features.activitypub') ? 'true' : 'false')); + $this->updateConfig('AP_INBOX=false', 'AP_INBOX=' .($request->input('features.activitypub') ? 'true' : 'false')); + $this->updateConfig('AP_REMOTE_FOLLOW=false', 'AP_REMOTE_FOLLOW=' .($request->input('features.activitypub') ? 'true' : 'false')); + $this->updateConfig('OPEN_REGISTRATION=true', 'OPEN_REGISTRATION=' .($request->input('features.open_registration') ? 'true' : 'false')); + + $this->updateConfig('ENFORCE_EMAIL_VERIFICATION=true', 'ENFORCE_EMAIL_VERIFICATION=' .($request->input('mail_address_verify') ? 'true' : 'false')); + $this->updateConfig('PF_OPTIMIZE_IMAGES=true', 'PF_OPTIMIZE_IMAGES=' .($request->input('optimize_media') ? 'true' : 'false')); + $this->updateConfig('MAX_PHOTO_SIZE=15000', 'MAX_PHOTO_SIZE=' .($request->input('max_upload_size') * 1000)); + $this->updateConfig('MEDIA_TYPES=image/jpeg,image/png,image/gif', 'MEDIA_TYPES=' .implode(',', $request->input('mime_types'))); + $this->updateConfig('OAUTH_ENABLED=true', 'OAUTH_ENABLED=true'); + + if($request->input('optimize_media') == true) { + $this->updateConfig('IMAGE_QUALITY=80', 'IMAGE_QUALITY=' .$request->input('image_quality')); + } + + sleep(1); + Artisan::call('config:cache'); + sleep(1); + Artisan::call('key:generate --force'); + sleep(1); + Artisan::call('migrate --force'); + sleep(1); + Artisan::call('config:cache'); + + if($request->has('features.activitypub') && $request->input('features.activitypub') == true) { + Artisan::call('instance:actor'); + } + + if($request->filled(['admin_username', 'admin_password', 'admin_email'])) { + $user = new User; + $user->username = $request->input('admin_username', 'admin'); + $user->name = $request->input('admin_username', 'admin'); + $user->email = $request->input('admin_email'); + $user->password = bcrypt($request->input('admin_password')); + $user->is_admin = true; + $user->email_verified_at = now(); + $user->save(); + } + } + + protected function updateConfig($key, $value) + { + $f = file_get_contents(base_path('.env')); + if(strpos($f, $key) !== false) { + $u = str_replace($key, $value, $f); + } else { + $u = $f; + $u .= $value . PHP_EOL; + } + sleep(1); + file_put_contents(base_path('.env'), $u); + } + + public function precheckDatabase(Request $request) + { + $driver = $request->input('db_driver', 'mysql'); + $name = $request->input('db_name', 'pixelfed'); + $host = $request->input('db_host', 'localhost'); + $username = $request->input('db_username'); + $password = $request->input('db_password'); + $dsn = "{$driver}:dbname={$name};host={$host}"; + $dbh = new \PDO($dsn, $username, $password); + + try { + $dbh->query('SELECT count(*) from INFORMATION_SCHEMA.TABLES'); + } catch (\PDOException $e) { + return response($e, 400); + } + } +} diff --git a/public/js/installer.js b/public/js/installer.js new file mode 100644 index 0000000000000000000000000000000000000000..2ad4f308480228cf1d4befffb0719c2c608f6fd2 GIT binary patch literal 66532 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 KEF{b*b^jkRIN!kl literal 0 HcmV?d00001 diff --git a/public/js/installer.js.LICENSE.txt b/public/js/installer.js.LICENSE.txt new file mode 100644 index 000000000..ba8e2aeda --- /dev/null +++ b/public/js/installer.js.LICENSE.txt @@ -0,0 +1 @@ +/*! @source http://purl.eligrey.com/github/canvas-toBlob.js/blob/master/canvas-toBlob.js */ diff --git a/public/mix-manifest.json b/public/mix-manifest.json index f532b30887d57bf30a13c4f3f5ae6a8c4e87cb91..f31c59478e7f6af2679ae583b9dbafdba2b7d516 100644 GIT binary patch delta 81 zcmZ21`B`# + + + + + + + Pixelfed Installer + + + + + +
+ +
+
+
+

+ + + +

+ + + +

+ Help + v{{config('pixelfed.version')}} +

+
+
+
+
+ + + + + diff --git a/routes/web.php b/routes/web.php index d9436a21e..7445b747c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -529,6 +529,14 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('{username}', 'ProfileController@permalinkRedirect'); }); + Route::group(['prefix' => 'installer'], function() { + Route::get('api/requirements', 'InstallController@getRequirements')->withoutMiddleware(['web']); + Route::post('precheck/database', 'InstallController@precheckDatabase')->withoutMiddleware(['web']); + Route::post('store', 'InstallController@store')->withoutMiddleware(['web']); + Route::get('/', 'InstallController@index')->withoutMiddleware(['web']); + Route::get('/{q}', 'InstallController@index')->withoutMiddleware(['web'])->where('q', '.*'); + }); + Route::get('stories/{username}', 'ProfileController@stories'); Route::get('p/{id}', 'StatusController@shortcodeRedirect'); Route::get('c/{collection}', 'CollectionController@show');