From f6b19b2e3d8836fe1a73f9858a79891195839421 Mon Sep 17 00:00:00 2001 From: Pete Bishop Date: Fri, 28 Feb 2025 17:10:35 +0000 Subject: [PATCH 1/4] Trait-ify installing the CACert --- src/Commands/BuildCommand.php | 8 +++---- src/Commands/DevelopCommand.php | 8 ++++++- src/Traits/CopiesCertificateAuthority.php | 29 +++++++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 src/Traits/CopiesCertificateAuthority.php diff --git a/src/Commands/BuildCommand.php b/src/Commands/BuildCommand.php index a631d018..2f479269 100644 --- a/src/Commands/BuildCommand.php +++ b/src/Commands/BuildCommand.php @@ -7,6 +7,7 @@ use Illuminate\Support\Str; use Native\Electron\Facades\Updater; use Native\Electron\Traits\CleansEnvFile; +use Native\Electron\Traits\CopiesCertificateAuthority; use Native\Electron\Traits\CopiesToBuildDirectory; use Native\Electron\Traits\HasPreAndPostProcessing; use Native\Electron\Traits\InstallsAppIcon; @@ -22,6 +23,7 @@ class BuildCommand extends Command { use CleansEnvFile; + use CopiesCertificateAuthority; use CopiesToBuildDirectory; use HasPreAndPostProcessing; use InstallsAppIcon; @@ -81,11 +83,7 @@ public function handle(): void $this->copyToBuildDirectory(); $this->newLine(); - intro('Copying latest CA Certificate...'); - copy( - Path::join($this->sourcePath(), 'vendor', 'nativephp', 'php-bin', 'cacert.pem'), - Path::join($this->sourcePath(), 'vendor', 'nativephp', 'electron', 'resources', 'js', 'resources', 'cacert.pem') - ); + $this->copyCertificateAuthorityCertificate(); $this->newLine(); intro('Cleaning .env file...'); diff --git a/src/Commands/DevelopCommand.php b/src/Commands/DevelopCommand.php index 4a0abc14..f855cfa6 100644 --- a/src/Commands/DevelopCommand.php +++ b/src/Commands/DevelopCommand.php @@ -3,6 +3,7 @@ namespace Native\Electron\Commands; use Illuminate\Console\Command; +use Native\Electron\Traits\CopiesCertificateAuthority; use Native\Electron\Traits\Developer; use Native\Electron\Traits\Installer; use Native\Electron\Traits\InstallsAppIcon; @@ -12,7 +13,10 @@ class DevelopCommand extends Command { - use Developer, Installer, InstallsAppIcon; + use CopiesCertificateAuthority; + use Developer; + use Installer; + use InstallsAppIcon; protected $signature = 'native:serve {--no-queue} {--D|no-dependencies} {--installer=npm}'; @@ -40,6 +44,8 @@ public function handle(): void $this->installIcon(); + $this->copyCertificateAuthorityCertificate(); + $this->runDeveloper( installer: $this->option('installer'), skip_queue: $this->option('no-queue'), diff --git a/src/Traits/CopiesCertificateAuthority.php b/src/Traits/CopiesCertificateAuthority.php new file mode 100644 index 00000000..6d3b2904 --- /dev/null +++ b/src/Traits/CopiesCertificateAuthority.php @@ -0,0 +1,29 @@ +sourcePath(), 'vendor', 'nativephp', 'php-bin', 'cacert.pem'), + Path::join($this->sourcePath(), 'vendor', 'nativephp', 'electron', 'resources', 'js', 'resources', 'cacert.pem') + ); + + if (!$copied) { + // It returned false, but doesn't give a reason why. + throw new \Exception('copy() failed for an unknown reason.'); + } + } catch (\Throwable $e) { + error('Failed to copy CA Certificate: '.$e->getMessage()); + } + } +} From da6b5c3fb407790c858b8cc4b8d79c260e650877 Mon Sep 17 00:00:00 2001 From: Pete Bishop Date: Fri, 28 Feb 2025 17:53:34 +0000 Subject: [PATCH 2/4] Test for new trait --- src/Traits/CopiesCertificateAuthority.php | 22 +++++++- .../Traits/CopiesCertificateAuthorityTest.php | 55 +++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Traits/CopiesCertificateAuthorityTest.php diff --git a/src/Traits/CopiesCertificateAuthority.php b/src/Traits/CopiesCertificateAuthority.php index 6d3b2904..1ee29f43 100644 --- a/src/Traits/CopiesCertificateAuthority.php +++ b/src/Traits/CopiesCertificateAuthority.php @@ -5,6 +5,7 @@ use Symfony\Component\Filesystem\Path; use function Laravel\Prompts\error; use function Laravel\Prompts\intro; +use function Laravel\Prompts\warning; trait CopiesCertificateAuthority { @@ -13,9 +14,26 @@ protected function copyCertificateAuthorityCertificate(): void try { intro('Copying latest CA Certificate...'); + $phpBinaryDirectory = base_path('vendor/nativephp/php-bin/'); + + // Check if the class this trait is used in also uses LocatesPhpBinary + if (method_exists($this, 'phpBinaryPath')) { + // Get binary directory but up one level + $phpBinaryDirectory = dirname(base_path($this->phpBinaryPath())); + } + + $certificateFileName = 'cacert.pem'; + $certFilePath = Path::join($phpBinaryDirectory, $certificateFileName); + + if (!file_exists($certFilePath)) { + warning('CA Certificate not found at ' . $certFilePath . '. Skipping copy.'); + + return; + } + $copied = copy( - Path::join($this->sourcePath(), 'vendor', 'nativephp', 'php-bin', 'cacert.pem'), - Path::join($this->sourcePath(), 'vendor', 'nativephp', 'electron', 'resources', 'js', 'resources', 'cacert.pem') + $certFilePath, + Path::join(base_path('vendor/nativephp/electron/resources/js/resources'), $certificateFileName) ); if (!$copied) { diff --git a/tests/Unit/Traits/CopiesCertificateAuthorityTest.php b/tests/Unit/Traits/CopiesCertificateAuthorityTest.php new file mode 100644 index 00000000..60eaa629 --- /dev/null +++ b/tests/Unit/Traits/CopiesCertificateAuthorityTest.php @@ -0,0 +1,55 @@ +setBasePath(realpath(__DIR__.'/../../../')); + + /// Make directory temporarily + mkdir(base_path('vendor/nativephp/electron/resources/js/resources'), 0777, true); + + // Test + expect(file_exists(base_path('vendor/nativephp/electron/resources/js/resources/cacert.pem')))->toBeFalse(); + + $mock->run(); + + expect(file_exists(base_path('vendor/nativephp/electron/resources/js/resources/cacert.pem')))->toBeTrue(); + + // Cleanup + // Delete the vendor/nativephp/electron directory, recursively including directories and then files + $files = new RecursiveIteratorIterator( + new RecursiveCallbackFilterIterator( + new RecursiveDirectoryIterator(base_path('vendor/nativephp/electron'), RecursiveDirectoryIterator::SKIP_DOTS), + fn ($current, $key, $iterator) => $current->isDir() || $current->isFile() + ), + RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach ($files as $file) { + if ($file->isDir()) { + rmdir($file->getRealPath()); + } else { + unlink($file->getRealPath()); + } + } + + rmdir(base_path('vendor/nativephp/electron')); + +})->with([ + // Empty class with the CopiesCertificateAuthority trait + new class + { + use CopiesCertificateAuthority; + + public function run() + { + $this->copyCertificateAuthorityCertificate(); + } + }, +]); From af3eebf4efa7f401307050ed335d2bf4abbe73e3 Mon Sep 17 00:00:00 2001 From: Pete Bishop Date: Fri, 28 Feb 2025 17:58:14 +0000 Subject: [PATCH 3/4] Remove certPath from unnecessary and unused locations --- resources/js/php.js | 11 ----------- src/Commands/BuildCommand.php | 1 - src/Traits/ExecuteCommand.php | 2 -- 3 files changed, 14 deletions(-) diff --git a/resources/js/php.js b/resources/js/php.js index f91f48f7..39c53350 100644 --- a/resources/js/php.js +++ b/resources/js/php.js @@ -8,7 +8,6 @@ import unzip from "yauzl"; const isBuilding = Boolean(process.env.NATIVEPHP_BUILDING); const phpBinaryPath = process.env.NATIVEPHP_PHP_BINARY_PATH; const phpVersion = process.env.NATIVEPHP_PHP_BINARY_VERSION; -const certificatePath = process.env.NATIVEPHP_CERTIFICATE_FILE_PATH; // Differentiates for Serving and Building const isArm64 = isBuilding ? process.argv.includes('--arm64') : process.arch.includes('arm64'); @@ -98,13 +97,3 @@ if (platform.phpBinary) { console.error('Error copying PHP binary', e); } } - -if (certificatePath) { - try { - let certDest = join(import.meta.dirname, 'resources', 'cacert.pem'); - copySync(certificatePath, certDest); - console.log('Copied certificate file from ' + certificatePath + ' to ' + certDest); - } catch (e) { - console.error('Error copying certificate file', e); - } -} diff --git a/src/Commands/BuildCommand.php b/src/Commands/BuildCommand.php index 2f479269..8125c262 100644 --- a/src/Commands/BuildCommand.php +++ b/src/Commands/BuildCommand.php @@ -119,7 +119,6 @@ protected function getEnvironmentVariables(): array 'NATIVEPHP_BUILDING' => true, 'NATIVEPHP_PHP_BINARY_VERSION' => PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION, 'NATIVEPHP_PHP_BINARY_PATH' => $this->sourcePath($this->phpBinaryPath()), - 'NATIVEPHP_CERTIFICATE_FILE_PATH' => $this->sourcePath($this->binaryPackageDirectory().'cacert.pem'), 'NATIVEPHP_APP_NAME' => config('app.name'), 'NATIVEPHP_APP_ID' => config('nativephp.app_id'), 'NATIVEPHP_APP_VERSION' => config('nativephp.version'), diff --git a/src/Traits/ExecuteCommand.php b/src/Traits/ExecuteCommand.php index 26e98c06..a25b3bfb 100644 --- a/src/Traits/ExecuteCommand.php +++ b/src/Traits/ExecuteCommand.php @@ -20,13 +20,11 @@ protected function executeCommand( 'install' => [ 'NATIVEPHP_PHP_BINARY_VERSION' => PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION, 'NATIVEPHP_PHP_BINARY_PATH' => base_path($this->phpBinaryPath()), - 'NATIVEPHP_CERTIFICATE_FILE_PATH' => base_path($this->binaryPackageDirectory().'cacert.pem'), ], 'serve' => [ 'APP_PATH' => base_path(), 'NATIVEPHP_PHP_BINARY_VERSION' => PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION, 'NATIVEPHP_PHP_BINARY_PATH' => base_path($this->phpBinaryPath()), - 'NATIVEPHP_CERTIFICATE_FILE_PATH' => base_path($this->binaryPackageDirectory().'cacert.pem'), 'NATIVE_PHP_SKIP_QUEUE' => $skip_queue, 'NATIVEPHP_BUILDING' => false, ], From 83ba36d509d7c4f28b0bdedfa75b683b9d1a1dce Mon Sep 17 00:00:00 2001 From: PeteBishwhip <9081809+PeteBishwhip@users.noreply.github.com> Date: Fri, 28 Feb 2025 17:59:43 +0000 Subject: [PATCH 4/4] Fix styling --- src/Commands/BuildCommand.php | 1 - src/Traits/CopiesCertificateAuthority.php | 7 ++++--- tests/Unit/Traits/CopiesCertificateAuthorityTest.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Commands/BuildCommand.php b/src/Commands/BuildCommand.php index 8125c262..20d6fd62 100644 --- a/src/Commands/BuildCommand.php +++ b/src/Commands/BuildCommand.php @@ -15,7 +15,6 @@ use Native\Electron\Traits\OsAndArch; use Native\Electron\Traits\PrunesVendorDirectory; use Native\Electron\Traits\SetsAppName; -use Symfony\Component\Filesystem\Path; use Symfony\Component\Process\Process as SymfonyProcess; use function Laravel\Prompts\intro; diff --git a/src/Traits/CopiesCertificateAuthority.php b/src/Traits/CopiesCertificateAuthority.php index 1ee29f43..b8ed6486 100644 --- a/src/Traits/CopiesCertificateAuthority.php +++ b/src/Traits/CopiesCertificateAuthority.php @@ -3,6 +3,7 @@ namespace Native\Electron\Traits; use Symfony\Component\Filesystem\Path; + use function Laravel\Prompts\error; use function Laravel\Prompts\intro; use function Laravel\Prompts\warning; @@ -25,8 +26,8 @@ protected function copyCertificateAuthorityCertificate(): void $certificateFileName = 'cacert.pem'; $certFilePath = Path::join($phpBinaryDirectory, $certificateFileName); - if (!file_exists($certFilePath)) { - warning('CA Certificate not found at ' . $certFilePath . '. Skipping copy.'); + if (! file_exists($certFilePath)) { + warning('CA Certificate not found at '.$certFilePath.'. Skipping copy.'); return; } @@ -36,7 +37,7 @@ protected function copyCertificateAuthorityCertificate(): void Path::join(base_path('vendor/nativephp/electron/resources/js/resources'), $certificateFileName) ); - if (!$copied) { + if (! $copied) { // It returned false, but doesn't give a reason why. throw new \Exception('copy() failed for an unknown reason.'); } diff --git a/tests/Unit/Traits/CopiesCertificateAuthorityTest.php b/tests/Unit/Traits/CopiesCertificateAuthorityTest.php index 60eaa629..495211f7 100644 --- a/tests/Unit/Traits/CopiesCertificateAuthorityTest.php +++ b/tests/Unit/Traits/CopiesCertificateAuthorityTest.php @@ -11,7 +11,7 @@ // Set up app()->setBasePath(realpath(__DIR__.'/../../../')); - /// Make directory temporarily + // / Make directory temporarily mkdir(base_path('vendor/nativephp/electron/resources/js/resources'), 0777, true); // Test