From 6441882a1433d6b2227f9645f9c10ecfcd4ed3ed Mon Sep 17 00:00:00 2001 From: Pim Date: Fri, 6 Oct 2023 15:27:25 +0200 Subject: [PATCH 01/29] fix secure.valet.conf format for nginx >= 1.25.1 --- cli/stubs/secure.valet.conf | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cli/stubs/secure.valet.conf b/cli/stubs/secure.valet.conf index a7cd23104..934f5fe78 100644 --- a/cli/stubs/secure.valet.conf +++ b/cli/stubs/secure.valet.conf @@ -6,13 +6,12 @@ server { } server { - listen 127.0.0.1:443 ssl http2; - #listen VALET_LOOPBACK:443 ssl http2; # valet loopback + listen 127.0.0.1:443 ssl; + #listen VALET_LOOPBACK:443 ssl; # valet loopback server_name VALET_SITE www.VALET_SITE *.VALET_SITE; root /; charset utf-8; client_max_body_size 512M; - http2_push_preload on; location /VALET_STATIC_PREFIX/ { internal; From 80d8890995d572c0670ecddd19a67e93fc8aa719 Mon Sep 17 00:00:00 2001 From: Pim Date: Fri, 6 Oct 2023 15:36:51 +0200 Subject: [PATCH 02/29] added http2 directive --- cli/stubs/secure.valet.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/stubs/secure.valet.conf b/cli/stubs/secure.valet.conf index 934f5fe78..c44db331c 100644 --- a/cli/stubs/secure.valet.conf +++ b/cli/stubs/secure.valet.conf @@ -12,6 +12,7 @@ server { root /; charset utf-8; client_max_body_size 512M; + http2 on; location /VALET_STATIC_PREFIX/ { internal; From 984d7f33b1d495cae9eb0889bd720cb03cc61d14 Mon Sep 17 00:00:00 2001 From: Pim Date: Fri, 6 Oct 2023 16:05:25 +0200 Subject: [PATCH 03/29] fix http2 --- cli/stubs/secure.proxy.valet.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/stubs/secure.proxy.valet.conf b/cli/stubs/secure.proxy.valet.conf index d1a69d176..68f28f118 100644 --- a/cli/stubs/secure.proxy.valet.conf +++ b/cli/stubs/secure.proxy.valet.conf @@ -8,13 +8,13 @@ server { } server { - listen 127.0.0.1:443 ssl http2; - #listen VALET_LOOPBACK:443 ssl http2; # valet loopback + listen 127.0.0.1:443 ssl; + #listen VALET_LOOPBACK:443 ssl; # valet loopback server_name VALET_SITE www.VALET_SITE *.VALET_SITE; root /; charset utf-8; client_max_body_size 128M; - http2_push_preload on; + http2 on; location /VALET_STATIC_PREFIX/ { internal; From c66dfee102e72508379d6512870ac80c04b1911b Mon Sep 17 00:00:00 2001 From: PimPlaatsman Date: Mon, 9 Oct 2023 14:03:38 +0200 Subject: [PATCH 04/29] add legacy files --- cli/stubs/secure.proxy.valet-legacy.conf | 57 +++++++++++++++ cli/stubs/secure.valet-legacy.conf | 93 ++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 cli/stubs/secure.proxy.valet-legacy.conf create mode 100644 cli/stubs/secure.valet-legacy.conf diff --git a/cli/stubs/secure.proxy.valet-legacy.conf b/cli/stubs/secure.proxy.valet-legacy.conf new file mode 100644 index 000000000..d1a69d176 --- /dev/null +++ b/cli/stubs/secure.proxy.valet-legacy.conf @@ -0,0 +1,57 @@ +# valet stub: secure.proxy.valet.conf + +server { + listen 127.0.0.1:80; + #listen VALET_LOOPBACK:80; # valet loopback + server_name VALET_SITE www.VALET_SITE *.VALET_SITE; + return 301 https://$host$request_uri; +} + +server { + listen 127.0.0.1:443 ssl http2; + #listen VALET_LOOPBACK:443 ssl http2; # valet loopback + server_name VALET_SITE www.VALET_SITE *.VALET_SITE; + root /; + charset utf-8; + client_max_body_size 128M; + http2_push_preload on; + + location /VALET_STATIC_PREFIX/ { + internal; + alias /; + try_files $uri $uri/; + } + + ssl_certificate "VALET_CERT"; + ssl_certificate_key "VALET_KEY"; + + access_log off; + error_log "VALET_HOME_PATH/Log/VALET_SITE-error.log"; + + error_page 404 "VALET_SERVER_PATH"; + + location / { + proxy_pass VALET_PROXY_HOST; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Client-Verify SUCCESS; + proxy_set_header X-Client-DN $ssl_client_s_dn; + proxy_set_header X-SSL-Subject $ssl_client_s_dn; + proxy_set_header X-SSL-Issuer $ssl_client_i_dn; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + proxy_read_timeout 1800; + proxy_connect_timeout 1800; + chunked_transfer_encoding on; + proxy_redirect off; + proxy_buffering off; + } + + location ~ /\.ht { + deny all; + } +} diff --git a/cli/stubs/secure.valet-legacy.conf b/cli/stubs/secure.valet-legacy.conf new file mode 100644 index 000000000..a7cd23104 --- /dev/null +++ b/cli/stubs/secure.valet-legacy.conf @@ -0,0 +1,93 @@ +server { + listen 127.0.0.1:80; + #listen VALET_LOOPBACK:80; # valet loopback + server_name VALET_SITE www.VALET_SITE *.VALET_SITE; + return 301 https://$host$request_uri; +} + +server { + listen 127.0.0.1:443 ssl http2; + #listen VALET_LOOPBACK:443 ssl http2; # valet loopback + server_name VALET_SITE www.VALET_SITE *.VALET_SITE; + root /; + charset utf-8; + client_max_body_size 512M; + http2_push_preload on; + + location /VALET_STATIC_PREFIX/ { + internal; + alias /; + try_files $uri $uri/; + } + + ssl_certificate "VALET_CERT"; + ssl_certificate_key "VALET_KEY"; + + location / { + rewrite ^ "VALET_SERVER_PATH" last; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + access_log off; + error_log "VALET_HOME_PATH/Log/nginx-error.log"; + + error_page 404 "VALET_SERVER_PATH"; + + location ~ [^/]\.php(/|$) { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass "unix:VALET_HOME_PATH/valet.sock"; + fastcgi_index "VALET_SERVER_PATH"; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME "VALET_SERVER_PATH"; + fastcgi_param PATH_INFO $fastcgi_path_info; + } + + location ~ /\.ht { + deny all; + } +} + +server { + listen 127.0.0.1:60; + #listen VALET_LOOPBACK:60; # valet loopback + server_name VALET_SITE www.VALET_SITE *.VALET_SITE; + root /; + charset utf-8; + client_max_body_size 128M; + + add_header X-Robots-Tag 'noindex, nofollow, nosnippet, noarchive'; + + location /VALET_STATIC_PREFIX/ { + internal; + alias /; + try_files $uri $uri/; + } + + location / { + rewrite ^ "VALET_SERVER_PATH" last; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + access_log off; + error_log "VALET_HOME_PATH/Log/nginx-error.log"; + + error_page 404 "VALET_SERVER_PATH"; + + location ~ [^/]\.php(/|$) { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass "unix:VALET_HOME_PATH/valet.sock"; + fastcgi_index "VALET_SERVER_PATH"; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME "VALET_SERVER_PATH"; + fastcgi_param PATH_INFO $fastcgi_path_info; + } + + location ~ /\.ht { + deny all; + } +} + From bd3fe5bfcc9ac96105e3b6fd10bf6a656739a769 Mon Sep 17 00:00:00 2001 From: PimPlaatsman Date: Mon, 9 Oct 2023 14:11:03 +0200 Subject: [PATCH 05/29] load legacy config if nginx > 1.25.1 --- cli/Valet/Site.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index 122610e48..04bda23c3 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -631,8 +631,11 @@ public function buildCertificateConf(string $path, string $url): void public function buildSecureNginxServer(string $url, string $siteConf = null): string { if ($siteConf === null) { + $nginxVersion = ltrim(exec('nginx -v'), 'nginx version: nginx/'); + $configFile = version_compare($nginxVersion, '1.25.1', ">=") ? 'secure.valet.conf' : 'secure.valet-legacy.conf'; + $siteConf = $this->replaceOldLoopbackWithNew( - $this->files->getStub('secure.valet.conf'), + $this->files->getStub($configFile), 'VALET_LOOPBACK', $this->valetLoopback() ); @@ -774,8 +777,11 @@ public function proxyCreate(string $url, string $host, bool $secure = false): vo $proxyUrl .= '.'.$tld; } + $nginxVersion = ltrim(exec('nginx -v'), 'nginx version: nginx/'); + $configFile = version_compare($nginxVersion, '1.25.1', ">=") ? 'secure.proxy.valet.conf' : 'secure.proxy.valet-legacy.conf'; + $siteConf = $this->replaceOldLoopbackWithNew( - $this->files->getStub($secure ? 'secure.proxy.valet.conf' : 'proxy.valet.conf'), + $this->files->getStub($secure ? $configFile : 'proxy.valet.conf'), 'VALET_LOOPBACK', $this->valetLoopback() ); From 6b07e425be2a61cbb8b00088a39a8c62751d2b92 Mon Sep 17 00:00:00 2001 From: Chris Brown Date: Mon, 9 Oct 2023 13:58:03 -0400 Subject: [PATCH 06/29] Bandage for 502 errors using Gettext/PostgreSQL/MongoDB Many have reported that these changes "do" help the problem. And yet many others have reported that they make no difference. Closes #1433 This PR is merely a bandage for a broader problem that exists in the PHP build for MacOS. See the issue referenced above for discussion and links to Homebrew and PHP repository discussions. The problem is not in Homebrew, but in the PHP build published by the PHP core. Chime in on the PHP discussion if you want to stir up more active participation for a proper fix, telling them that you're a Mac user encountering the fork segfaults (they won't care whether you're using Valet, but they will recognize if you mention Homebrew). --- cli/stubs/etc-phpfpm-valet.conf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cli/stubs/etc-phpfpm-valet.conf b/cli/stubs/etc-phpfpm-valet.conf index 67618bbc2..b4d82d32f 100644 --- a/cli/stubs/etc-phpfpm-valet.conf +++ b/cli/stubs/etc-phpfpm-valet.conf @@ -24,3 +24,9 @@ pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 +;; these are an attempt to mitigate 502 errors caused by segfaults in upstream processes caused by krb5 v1.21 added in June 2023 to php's core build. Ref Issue #1433 +; for gettext +env['LC_ALL'] = C +; for postgres +env['PGGSSENCMODE'] = disable + From b2ce8ad875926ea3659c7104e01040e7005d2a6a Mon Sep 17 00:00:00 2001 From: Pim Date: Tue, 10 Oct 2023 10:38:18 +0200 Subject: [PATCH 07/29] use str_replace --- cli/Valet/Site.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index 04bda23c3..920772b3f 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -631,7 +631,7 @@ public function buildCertificateConf(string $path, string $url): void public function buildSecureNginxServer(string $url, string $siteConf = null): string { if ($siteConf === null) { - $nginxVersion = ltrim(exec('nginx -v'), 'nginx version: nginx/'); + $nginxVersion = str_replace('nginx version: nginx/', '', exec('nginx -v')); $configFile = version_compare($nginxVersion, '1.25.1', ">=") ? 'secure.valet.conf' : 'secure.valet-legacy.conf'; $siteConf = $this->replaceOldLoopbackWithNew( @@ -777,7 +777,7 @@ public function proxyCreate(string $url, string $host, bool $secure = false): vo $proxyUrl .= '.'.$tld; } - $nginxVersion = ltrim(exec('nginx -v'), 'nginx version: nginx/'); + $nginxVersion = str_replace('nginx version: nginx/', '', exec('nginx -v')); $configFile = version_compare($nginxVersion, '1.25.1', ">=") ? 'secure.proxy.valet.conf' : 'secure.proxy.valet-legacy.conf'; $siteConf = $this->replaceOldLoopbackWithNew( From 344fd515da5ea13cf3779bc71aa0a5441bacfff1 Mon Sep 17 00:00:00 2001 From: driesvints Date: Tue, 10 Oct 2023 15:43:03 +0000 Subject: [PATCH 08/29] Update CHANGELOG --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b466adcf..3f309fb4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Release Notes -## [Unreleased](https://github.com/laravel/valet/compare/v4.4.1...master) +## [Unreleased](https://github.com/laravel/valet/compare/v4.5.0...master) + +## [v4.5.0](https://github.com/laravel/valet/compare/v4.4.1...v4.5.0) - 2023-10-10 + +- Add support for proxying multiple domains at once by [@RobertBoes](https://github.com/RobertBoes) in https://github.com/laravel/valet/pull/1437 ## [v4.4.1](https://github.com/laravel/valet/compare/v4.4.0...v4.4.1) - 2023-10-03 From 2db0770f2c2f08227bc77ce59234ae792c422275 Mon Sep 17 00:00:00 2001 From: Pim Date: Fri, 13 Oct 2023 13:16:21 +0200 Subject: [PATCH 09/29] Update Site.php version to string --- cli/Valet/Site.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index 920772b3f..96b41dbbb 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -631,7 +631,7 @@ public function buildCertificateConf(string $path, string $url): void public function buildSecureNginxServer(string $url, string $siteConf = null): string { if ($siteConf === null) { - $nginxVersion = str_replace('nginx version: nginx/', '', exec('nginx -v')); + $nginxVersion = str_replace('nginx version: nginx/', '', exec('nginx -v 2>&1')); $configFile = version_compare($nginxVersion, '1.25.1', ">=") ? 'secure.valet.conf' : 'secure.valet-legacy.conf'; $siteConf = $this->replaceOldLoopbackWithNew( @@ -777,7 +777,7 @@ public function proxyCreate(string $url, string $host, bool $secure = false): vo $proxyUrl .= '.'.$tld; } - $nginxVersion = str_replace('nginx version: nginx/', '', exec('nginx -v')); + $nginxVersion = str_replace('nginx version: nginx/', '', exec('nginx -v 2>&1')); $configFile = version_compare($nginxVersion, '1.25.1', ">=") ? 'secure.proxy.valet.conf' : 'secure.proxy.valet-legacy.conf'; $siteConf = $this->replaceOldLoopbackWithNew( From c4fb099eeab3bc557844634e1a91a8b55f413d9e Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Tue, 17 Oct 2023 14:37:27 +0100 Subject: [PATCH 10/29] Uses `actions/checkout@v4` --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 47540d84e..454e7ed34 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 From e829a1cf312403fbe5b3994b7311bf5287ef8e8a Mon Sep 17 00:00:00 2001 From: Afjalur Rahman Rana Date: Tue, 5 Dec 2023 10:31:09 +0000 Subject: [PATCH 11/29] give https tunnel support for valet fetch-share-url --- cli/Valet/Ngrok.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cli/Valet/Ngrok.php b/cli/Valet/Ngrok.php index 222806677..b845def13 100644 --- a/cli/Valet/Ngrok.php +++ b/cli/Valet/Ngrok.php @@ -51,15 +51,14 @@ public function currentTunnelUrl(string $domain = null): string } /** - * Find the HTTP tunnel URL from the list of tunnels. + * Find the HTTP/HTTPS tunnel URL from the list of tunnels. */ public function findHttpTunnelUrl(array $tunnels, string $domain): ?string { // If there are active tunnels on the Ngrok instance we will spin through them and // find the one responding on HTTP. Each tunnel has an HTTP and a HTTPS address - // but for local dev purposes we just desire the plain HTTP URL endpoint. foreach ($tunnels as $tunnel) { - if ($tunnel->proto === 'http' && strpos($tunnel->config->addr, strtolower($domain))) { + if (($tunnel->proto === 'http' || $tunnel->proto === 'https') && strpos($tunnel->config->addr, strtolower($domain))) { return $tunnel->public_url; } } From ec7046f3a7fb3e866deba6ecebd626c993b8e4f4 Mon Sep 17 00:00:00 2001 From: Afjalur Rahman Rana Date: Tue, 5 Dec 2023 11:23:24 +0000 Subject: [PATCH 12/29] test case updated --- cli/Valet/Ngrok.php | 2 +- tests/NgrokTest.php | 17 ++++++----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/cli/Valet/Ngrok.php b/cli/Valet/Ngrok.php index b845def13..23fd43950 100644 --- a/cli/Valet/Ngrok.php +++ b/cli/Valet/Ngrok.php @@ -58,7 +58,7 @@ public function findHttpTunnelUrl(array $tunnels, string $domain): ?string // If there are active tunnels on the Ngrok instance we will spin through them and // find the one responding on HTTP. Each tunnel has an HTTP and a HTTPS address foreach ($tunnels as $tunnel) { - if (($tunnel->proto === 'http' || $tunnel->proto === 'https') && strpos($tunnel->config->addr, strtolower($domain))) { + if (($tunnel->proto === 'http' || $tunnel->proto === 'https') && stripos($tunnel->config->addr, $domain)) { return $tunnel->public_url; } } diff --git a/tests/NgrokTest.php b/tests/NgrokTest.php index 7f37da617..d320bcde8 100644 --- a/tests/NgrokTest.php +++ b/tests/NgrokTest.php @@ -31,26 +31,21 @@ public function test_it_matches_correct_share_tunnel() 'config' => (object) [ 'addr' => 'http://mysite.test:80', ], - 'public_url' => 'http://bad-proto.ngrok.io/', + 'public_url' => 'https://right-one.ngrok.io/', ], (object) [ 'proto' => 'http', 'config' => (object) [ - 'addr' => 'http://nottherightone.test:80', + 'addr' => 'http://mynewsite.test:80', ], - 'public_url' => 'http://bad-site.ngrok.io/', - ], - (object) [ - 'proto' => 'http', - 'config' => (object) [ - 'addr' => 'http://mysite.test:80', - ], - 'public_url' => 'http://right-one.ngrok.io/', + 'public_url' => 'http://new-right-one.ngrok.io/', ], ]; $ngrok = resolve(Ngrok::class); - $this->assertEquals('http://right-one.ngrok.io/', $ngrok->findHttpTunnelUrl($tunnels, 'mysite')); + $this->assertEquals('https://right-one.ngrok.io/', $ngrok->findHttpTunnelUrl($tunnels, 'mysite')); + $this->assertEquals('http://new-right-one.ngrok.io/', $ngrok->findHttpTunnelUrl($tunnels, 'mynewsite')); + } public function test_it_checks_against_lowercased_domain() From cd099f650f3b01f0e0e173e7a9d8992ecf0aff1f Mon Sep 17 00:00:00 2001 From: Afjalur Rahman Rana Date: Tue, 5 Dec 2023 11:41:25 +0000 Subject: [PATCH 13/29] if http and https both exist, priotize http --- cli/Valet/Ngrok.php | 18 +++++++++++++++--- tests/NgrokTest.php | 25 +++++++++++++++++++------ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/cli/Valet/Ngrok.php b/cli/Valet/Ngrok.php index 23fd43950..e5cb986ae 100644 --- a/cli/Valet/Ngrok.php +++ b/cli/Valet/Ngrok.php @@ -55,17 +55,29 @@ public function currentTunnelUrl(string $domain = null): string */ public function findHttpTunnelUrl(array $tunnels, string $domain): ?string { + $httpTunnel = null; + $httpsTunnel = null; + // If there are active tunnels on the Ngrok instance we will spin through them and // find the one responding on HTTP. Each tunnel has an HTTP and a HTTPS address + // if no HTTP tunnel is found we will return the HTTPS tunnel as a fallback. + + // Iterate through tunnels to find both HTTP and HTTPS tunnels foreach ($tunnels as $tunnel) { - if (($tunnel->proto === 'http' || $tunnel->proto === 'https') && stripos($tunnel->config->addr, $domain)) { - return $tunnel->public_url; + if (stripos($tunnel->config->addr, $domain)) { + if ($tunnel->proto === 'http') { + $httpTunnel = $tunnel->public_url; + } elseif ($tunnel->proto === 'https') { + $httpsTunnel = $tunnel->public_url; + } } } - return null; + // Return HTTP tunnel if available, otherwise return HTTPS tunnel + return $httpTunnel ?? $httpsTunnel; } + /** * Set the Ngrok auth token. */ diff --git a/tests/NgrokTest.php b/tests/NgrokTest.php index d320bcde8..c3b2329e1 100644 --- a/tests/NgrokTest.php +++ b/tests/NgrokTest.php @@ -31,21 +31,34 @@ public function test_it_matches_correct_share_tunnel() 'config' => (object) [ 'addr' => 'http://mysite.test:80', ], - 'public_url' => 'https://right-one.ngrok.io/', + 'public_url' => 'http://bad-proto.ngrok.io/', ], (object) [ 'proto' => 'http', 'config' => (object) [ - 'addr' => 'http://mynewsite.test:80', + 'addr' => 'http://nottherightone.test:80', ], - 'public_url' => 'http://new-right-one.ngrok.io/', + 'public_url' => 'http://bad-site.ngrok.io/', + ], + (object) [ + 'proto' => 'http', + 'config' => (object) [ + 'addr' => 'http://mysite.test:80', + ], + 'public_url' => 'http://right-one.ngrok.io/', + ], + (object) [ + 'proto' => 'https', + 'config' => (object) [ + 'addr' => 'http://mysecuresite.test:80', + ], + 'public_url' => 'http://secure-right-one.ngrok.io/', ], ]; $ngrok = resolve(Ngrok::class); - $this->assertEquals('https://right-one.ngrok.io/', $ngrok->findHttpTunnelUrl($tunnels, 'mysite')); - $this->assertEquals('http://new-right-one.ngrok.io/', $ngrok->findHttpTunnelUrl($tunnels, 'mynewsite')); - + $this->assertEquals('http://right-one.ngrok.io/', $ngrok->findHttpTunnelUrl($tunnels, 'mysite')); + $this->assertEquals('http://secure-right-one.ngrok.io/', $ngrok->findHttpTunnelUrl($tunnels, 'mysecuresite')); } public function test_it_checks_against_lowercased_domain() From eec8d5f0fce9a27cb272d7ec444bc6b78bd792dc Mon Sep 17 00:00:00 2001 From: Austin Drummond Date: Tue, 19 Dec 2023 23:23:02 -0500 Subject: [PATCH 14/29] added the ability to renew certs and view their expiration dates --- cli/Valet/Site.php | 17 +++++++++++++--- cli/app.php | 48 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index 122610e48..b0ba65b6d 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -2,6 +2,7 @@ namespace Valet; +use DateTime; use DomainException; use Illuminate\Support\Collection; use PhpFpm; @@ -423,15 +424,25 @@ public function replaceOldLoopbackWithNew(string $siteConf, string $old, string } /** - * Get all of the URLs that are currently secured. + * Get all of the URLs with expiration dates that are currently secured. */ public function secured(): array { return collect($this->files->scandir($this->certificatesPath())) ->filter(function ($file) { - return ends_with($file, ['.key', '.csr', '.crt', '.conf']); + return ends_with($file, ['.crt']); })->map(function ($file) { - return str_replace(['.key', '.csr', '.crt', '.conf'], '', $file); + + $host = str_replace(['.crt'], '', $file); + + $filePath = $this->certificatesPath() . '/' . $file; + + $expiration = $this->cli->run("openssl x509 -enddate -noout -in $filePath"); + + return [ + 'host' => $host, + 'exp' => new DateTime(str_replace('notAfter=', '', $expiration)), + ]; })->unique()->values()->all(); } diff --git a/cli/app.php b/cli/app.php index 61eeef510..9d92ba222 100644 --- a/cli/app.php +++ b/cli/app.php @@ -278,13 +278,51 @@ function (ConsoleCommandEvent $event) { /** * Display all of the currently secured sites. */ - $app->command('secured', function (OutputInterface $output) { - $sites = collect(Site::secured())->map(function ($url) { - return ['Site' => $url]; + $app->command('secured [--expiring] [--days=]', function (OutputInterface $output, $expiring = null, $days = 60) { + $now = (new Datetime())->add(new DateInterval('P' . $days . 'D')); + $sites = collect(Site::secured()) + ->when($expiring, fn ($collection) => $collection->filter(fn ($row) => $row['exp'] < $now)) + ->map(function ($row) { + return [ + 'Site' => $row['host'], + 'Valid Until' => $row['exp']->format('Y-m-d H:i:s T'), + ]; + }) + ->when($expiring, fn ($collection) => $collection->sortBy('Valid Until')); + + return table(['Site', 'Valid Until'], $sites->all()); + })->descriptions('Display all of the currently secured sites', [ + '--expiring' => 'Limits the results to only sites expiring within the next 60 days.', + '--days' => 'To be used with --expiring. Limits the results to only sites expiring within the next X days. Default is set to 60.', + ]); + + /** + * Renews expired or expiring (within 60 days) domains with a trusted TLS certificate. + */ + $app->command('renew [--expireIn=] [--days=]', function (OutputInterface $output, $expireIn = 368, $days = 60) { + $now = (new DateTime())->add(new DateInterval('P' . $days . 'D')); + // Update anything expiring in the next 60 days + $sites = collect(Site::secured()) + ->filter(fn ($row) => $row['exp'] < $now) + ->values(); + if ($sites->isEmpty()) { + info('No sites need renewing.'); + exit; + } + $sites->each(function ($row) use ($expireIn) { + $url = Site::domain($row['host']); + + Site::unsecure($url); + Site::secure($url, null, $expireIn); + + info('The [' . $url . '] site has been secured with a fresh TLS certificate.'); }); - table(['Site'], $sites->all()); - })->descriptions('Display all of the currently secured sites'); + Nginx::restart(); + })->descriptions('Renews expired or expiring (within 60 days) domains with a trusted TLS certificate.', [ + '--expireIn' => 'The amount of days the self signed certificate is valid for. Default is set to "368"', + '--days' => 'Renews sites expiring within the next X days. Default is set to 60.', + ]); /** * Create an Nginx proxy config for the specified domain. From 86c40dd40c336a4903a187de904da8694d43b794 Mon Sep 17 00:00:00 2001 From: Austin Drummond Date: Wed, 20 Dec 2023 00:07:57 -0500 Subject: [PATCH 15/29] restored original secured command --- cli/Valet/Site.php | 30 ++++++++++++++++++++---------- cli/app.php | 4 ++-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index b0ba65b6d..56e51211c 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -424,26 +424,36 @@ public function replaceOldLoopbackWithNew(string $siteConf, string $old, string } /** - * Get all of the URLs with expiration dates that are currently secured. + * Get all of the URLs that are currently secured. */ public function secured(): array { return collect($this->files->scandir($this->certificatesPath())) ->filter(function ($file) { - return ends_with($file, ['.crt']); + return ends_with($file, ['.key', '.csr', '.crt', '.conf']); })->map(function ($file) { + return str_replace(['.key', '.csr', '.crt', '.conf'], '', $file); + })->unique()->values()->all(); + } + + /** + * Get all of the URLs with expiration dates that are currently secured. + */ + public function securedWithDates(): array + { + return collect($this->secured())->map(function ($site) { - $host = str_replace(['.crt'], '', $file); + $filePath = $this->certificatesPath() . '/' . $site . '.crt'; - $filePath = $this->certificatesPath() . '/' . $file; + $expiration = $this->cli->run("openssl x509 -enddate -noout -in $filePath"); - $expiration = $this->cli->run("openssl x509 -enddate -noout -in $filePath"); + $expiration = str_replace('notAfter=', '', $expiration); - return [ - 'host' => $host, - 'exp' => new DateTime(str_replace('notAfter=', '', $expiration)), - ]; - })->unique()->values()->all(); + return [ + 'site' => $site, + 'exp' => new DateTime($expiration), + ]; + })->unique()->values()->all(); } public function isSecured(string $site): bool diff --git a/cli/app.php b/cli/app.php index 9d92ba222..5246cceed 100644 --- a/cli/app.php +++ b/cli/app.php @@ -280,7 +280,7 @@ function (ConsoleCommandEvent $event) { */ $app->command('secured [--expiring] [--days=]', function (OutputInterface $output, $expiring = null, $days = 60) { $now = (new Datetime())->add(new DateInterval('P' . $days . 'D')); - $sites = collect(Site::secured()) + $sites = collect(Site::securedWithDates()) ->when($expiring, fn ($collection) => $collection->filter(fn ($row) => $row['exp'] < $now)) ->map(function ($row) { return [ @@ -302,7 +302,7 @@ function (ConsoleCommandEvent $event) { $app->command('renew [--expireIn=] [--days=]', function (OutputInterface $output, $expireIn = 368, $days = 60) { $now = (new DateTime())->add(new DateInterval('P' . $days . 'D')); // Update anything expiring in the next 60 days - $sites = collect(Site::secured()) + $sites = collect(Site::securedWithDates()) ->filter(fn ($row) => $row['exp'] < $now) ->values(); if ($sites->isEmpty()) { From 7dfc7395026593a0c09a2d82fbcacc8fda196b8f Mon Sep 17 00:00:00 2001 From: Austin Drummond Date: Wed, 20 Dec 2023 00:08:05 -0500 Subject: [PATCH 16/29] update secured command test --- cli/app.php | 4 ++-- tests/CliTest.php | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cli/app.php b/cli/app.php index 5246cceed..521c57506 100644 --- a/cli/app.php +++ b/cli/app.php @@ -284,7 +284,7 @@ function (ConsoleCommandEvent $event) { ->when($expiring, fn ($collection) => $collection->filter(fn ($row) => $row['exp'] < $now)) ->map(function ($row) { return [ - 'Site' => $row['host'], + 'Site' => $row['site'], 'Valid Until' => $row['exp']->format('Y-m-d H:i:s T'), ]; }) @@ -310,7 +310,7 @@ function (ConsoleCommandEvent $event) { exit; } $sites->each(function ($row) use ($expireIn) { - $url = Site::domain($row['host']); + $url = Site::domain($row['site']); Site::unsecure($url); Site::secure($url, null, $expireIn); diff --git a/tests/CliTest.php b/tests/CliTest.php index 59ece0715..6203dc0fe 100644 --- a/tests/CliTest.php +++ b/tests/CliTest.php @@ -436,7 +436,12 @@ public function test_secured_command() [$app, $tester] = $this->appAndTester(); $site = Mockery::mock(RealSite::class); - $site->shouldReceive('secured')->andReturn(['tighten.test']); + $site->shouldReceive('securedWithDates')->andReturn([ + [ + 'site' => 'tighten.test', + 'exp' => new DateTime('Aug 2 13:16:40 2024 GMT') + ] + ]); swap(RealSite::class, $site); $tester->run(['command' => 'secured']); From dc24a8ddc06c77525f2833f03b429a3acd787c19 Mon Sep 17 00:00:00 2001 From: Austin Drummond Date: Wed, 20 Dec 2023 00:18:16 -0500 Subject: [PATCH 17/29] remove unnessary unsecure --- cli/app.php | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/app.php b/cli/app.php index 521c57506..8b53e0389 100644 --- a/cli/app.php +++ b/cli/app.php @@ -312,7 +312,6 @@ function (ConsoleCommandEvent $event) { $sites->each(function ($row) use ($expireIn) { $url = Site::domain($row['site']); - Site::unsecure($url); Site::secure($url, null, $expireIn); info('The [' . $url . '] site has been secured with a fresh TLS certificate.'); From dce796ac010104b335603b69be07bdcc47ce0acb Mon Sep 17 00:00:00 2001 From: Austin Drummond Date: Wed, 20 Dec 2023 00:18:24 -0500 Subject: [PATCH 18/29] added renew test --- tests/CliTest.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/CliTest.php b/tests/CliTest.php index 6203dc0fe..828504da9 100644 --- a/tests/CliTest.php +++ b/tests/CliTest.php @@ -450,6 +450,31 @@ public function test_secured_command() $this->assertStringContainsString('tighten.test', $tester->getDisplay()); } + public function test_renew_command() + { + [$app, $tester] = $this->appAndTester(); + + $site = Mockery::mock(RealSite::class); + $site->shouldReceive('securedWithDates')->andReturn([ + [ + 'site' => 'tighten.test', + 'exp' => new DateTime('Aug 2 13:16:40 2023 GMT') + ] + ]); + $site->shouldReceive('domain')->with('tighten.test')->andReturn('tighten.test'); + $site->shouldReceive('secure')->with('tighten.test', null, 368)->once(); + swap(RealSite::class, $site); + + $nginx = Mockery::mock(Nginx::class); + $nginx->shouldReceive('restart')->once(); + swap(Nginx::class, $nginx); + + $tester->run(['command' => 'renew']); + $tester->assertCommandIsSuccessful(); + + $this->assertStringContainsString('tighten.test', $tester->getDisplay()); + } + public function test_proxy_command() { [$app, $tester] = $this->appAndTester(); From cd198cb0c9425bce0bdb7734ae4959ba906bda2d Mon Sep 17 00:00:00 2001 From: Austin Drummond Date: Wed, 20 Dec 2023 00:35:19 -0500 Subject: [PATCH 19/29] moved renew command to site --- cli/Valet/Site.php | 24 ++++++++++++++++++++++++ cli/app.php | 18 +----------------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index 56e51211c..79dd5649a 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -3,6 +3,7 @@ namespace Valet; use DateTime; +use DateInterval; use DomainException; use Illuminate\Support\Collection; use PhpFpm; @@ -501,6 +502,29 @@ public function secure(string $url, string $siteConf = null, int $certificateExp $this->files->putAsUser($this->nginxPath($url), $siteConf); } + /** + * Renews expired or expiring (within 60 days) domains with a trusted TLS certificate. + */ + public function renew($expireIn = 368, $days = 60): void + { + $now = (new DateTime())->add(new DateInterval('P' . $days . 'D')); + // Update anything expiring in the next 60 days + $sites = collect(Site::securedWithDates()) + ->filter(fn ($row) => $row['exp'] < $now) + ->values(); + if ($sites->isEmpty()) { + info('No sites need renewing.'); + exit; + } + $sites->each(function ($row) use ($expireIn) { + $url = Site::domain($row['site']); + + $this->secure($url, null, $expireIn); + + info('The [' . $url . '] site has been secured with a fresh TLS certificate.'); + }); + } + /** * If CA and root certificates are nonexistent, create them and trust the root cert. * diff --git a/cli/app.php b/cli/app.php index 8b53e0389..ba3b3605e 100644 --- a/cli/app.php +++ b/cli/app.php @@ -300,23 +300,7 @@ function (ConsoleCommandEvent $event) { * Renews expired or expiring (within 60 days) domains with a trusted TLS certificate. */ $app->command('renew [--expireIn=] [--days=]', function (OutputInterface $output, $expireIn = 368, $days = 60) { - $now = (new DateTime())->add(new DateInterval('P' . $days . 'D')); - // Update anything expiring in the next 60 days - $sites = collect(Site::securedWithDates()) - ->filter(fn ($row) => $row['exp'] < $now) - ->values(); - if ($sites->isEmpty()) { - info('No sites need renewing.'); - exit; - } - $sites->each(function ($row) use ($expireIn) { - $url = Site::domain($row['site']); - - Site::secure($url, null, $expireIn); - - info('The [' . $url . '] site has been secured with a fresh TLS certificate.'); - }); - + Site::renew($expireIn, $days); Nginx::restart(); })->descriptions('Renews expired or expiring (within 60 days) domains with a trusted TLS certificate.', [ '--expireIn' => 'The amount of days the self signed certificate is valid for. Default is set to "368"', From a3a483e45c717a5227f101010fb3503bd748b7aa Mon Sep 17 00:00:00 2001 From: Austin Drummond Date: Wed, 20 Dec 2023 00:39:12 -0500 Subject: [PATCH 20/29] remove date logic on renewal --- cli/Valet/Site.php | 18 ++++-------------- cli/app.php | 9 ++++----- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index 79dd5649a..ca25f8293 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -3,7 +3,6 @@ namespace Valet; use DateTime; -use DateInterval; use DomainException; use Illuminate\Support\Collection; use PhpFpm; @@ -503,21 +502,12 @@ public function secure(string $url, string $siteConf = null, int $certificateExp } /** - * Renews expired or expiring (within 60 days) domains with a trusted TLS certificate. + * Renews all domains with a trusted TLS certificate. */ - public function renew($expireIn = 368, $days = 60): void + public function renew($expireIn): void { - $now = (new DateTime())->add(new DateInterval('P' . $days . 'D')); - // Update anything expiring in the next 60 days - $sites = collect(Site::securedWithDates()) - ->filter(fn ($row) => $row['exp'] < $now) - ->values(); - if ($sites->isEmpty()) { - info('No sites need renewing.'); - exit; - } - $sites->each(function ($row) use ($expireIn) { - $url = Site::domain($row['site']); + collect($this->securedWithDates())->each(function ($row) use ($expireIn) { + $url = $this->domain($row['site']); $this->secure($url, null, $expireIn); diff --git a/cli/app.php b/cli/app.php index ba3b3605e..930883e2c 100644 --- a/cli/app.php +++ b/cli/app.php @@ -297,14 +297,13 @@ function (ConsoleCommandEvent $event) { ]); /** - * Renews expired or expiring (within 60 days) domains with a trusted TLS certificate. + * Renews all domains with a trusted TLS certificate. */ - $app->command('renew [--expireIn=] [--days=]', function (OutputInterface $output, $expireIn = 368, $days = 60) { - Site::renew($expireIn, $days); + $app->command('renew [--expireIn=]', function (OutputInterface $output, $expireIn = 368) { + Site::renew($expireIn); Nginx::restart(); - })->descriptions('Renews expired or expiring (within 60 days) domains with a trusted TLS certificate.', [ + })->descriptions('Renews all domains with a trusted TLS certificate.', [ '--expireIn' => 'The amount of days the self signed certificate is valid for. Default is set to "368"', - '--days' => 'Renews sites expiring within the next X days. Default is set to 60.', ]); /** From 39ee79dfad68e1dce7b8481f0a86ebe7c7f55ac3 Mon Sep 17 00:00:00 2001 From: Austin Drummond Date: Wed, 20 Dec 2023 00:39:21 -0500 Subject: [PATCH 21/29] added renew to to install command --- cli/app.php | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/app.php b/cli/app.php index 930883e2c..74d102a2b 100644 --- a/cli/app.php +++ b/cli/app.php @@ -61,6 +61,7 @@ function (ConsoleCommandEvent $event) { output(); DnsMasq::install(Configuration::read()['tld']); output(); + Site::renew(); Nginx::restart(); output(); Valet::symlinkToUsersBin(); From 42f4f3999498e929ab4727f1461d14858882b8bc Mon Sep 17 00:00:00 2001 From: Austin Drummond Date: Wed, 20 Dec 2023 00:45:51 -0500 Subject: [PATCH 22/29] update tests to match renew command This makes me a little sad, as it doesn't really test/document the behavior of the renew command. --- tests/CliTest.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/CliTest.php b/tests/CliTest.php index 828504da9..a963f36b5 100644 --- a/tests/CliTest.php +++ b/tests/CliTest.php @@ -455,14 +455,7 @@ public function test_renew_command() [$app, $tester] = $this->appAndTester(); $site = Mockery::mock(RealSite::class); - $site->shouldReceive('securedWithDates')->andReturn([ - [ - 'site' => 'tighten.test', - 'exp' => new DateTime('Aug 2 13:16:40 2023 GMT') - ] - ]); - $site->shouldReceive('domain')->with('tighten.test')->andReturn('tighten.test'); - $site->shouldReceive('secure')->with('tighten.test', null, 368)->once(); + $site->shouldReceive('renew')->andReturn(); swap(RealSite::class, $site); $nginx = Mockery::mock(Nginx::class); @@ -471,8 +464,6 @@ public function test_renew_command() $tester->run(['command' => 'renew']); $tester->assertCommandIsSuccessful(); - - $this->assertStringContainsString('tighten.test', $tester->getDisplay()); } public function test_proxy_command() From e75f238b22ee18ef7771b919ede9a5d5d5488c26 Mon Sep 17 00:00:00 2001 From: mattstauffer Date: Thu, 21 Dec 2023 03:25:35 +0000 Subject: [PATCH 23/29] Fix code styling --- cli/Valet/Brew.php | 2 +- cli/Valet/CommandLine.php | 6 +++--- cli/Valet/Expose.php | 2 +- cli/Valet/Filesystem.php | 10 +++++----- cli/Valet/Ngrok.php | 2 +- cli/Valet/PhpFpm.php | 8 ++++---- cli/Valet/Site.php | 24 ++++++++++++------------ cli/includes/helpers.php | 2 +- find-usable-php.php | 2 +- tests/PhpFpmTest.php | 2 +- tests/SiteTest.php | 4 ++-- 11 files changed, 32 insertions(+), 32 deletions(-) diff --git a/cli/Valet/Brew.php b/cli/Valet/Brew.php index 121a13935..33d597bc8 100644 --- a/cli/Valet/Brew.php +++ b/cli/Valet/Brew.php @@ -292,7 +292,7 @@ function ($version) use ($resolvedPhpVersion) { * * @param string|null $phpVersion For example, "php@8.1" */ - public function getPhpExecutablePath(string $phpVersion = null): string + public function getPhpExecutablePath(?string $phpVersion = null): string { if (! $phpVersion) { return BREW_PREFIX.'/bin/php'; diff --git a/cli/Valet/CommandLine.php b/cli/Valet/CommandLine.php index 186d093bf..3d1841834 100644 --- a/cli/Valet/CommandLine.php +++ b/cli/Valet/CommandLine.php @@ -33,7 +33,7 @@ public function passthru(string $command): void /** * Run the given command as the non-root user. */ - public function run(string $command, callable $onError = null): string + public function run(string $command, ?callable $onError = null): string { return $this->runCommand($command, $onError); } @@ -41,7 +41,7 @@ public function run(string $command, callable $onError = null): string /** * Run the given command. */ - public function runAsUser(string $command, callable $onError = null): string + public function runAsUser(string $command, ?callable $onError = null): string { return $this->runCommand('sudo -u "'.user().'" '.$command, $onError); } @@ -49,7 +49,7 @@ public function runAsUser(string $command, callable $onError = null): string /** * Run the given command. */ - public function runCommand(string $command, callable $onError = null): string + public function runCommand(string $command, ?callable $onError = null): string { $onError = $onError ?: function () { }; diff --git a/cli/Valet/Expose.php b/cli/Valet/Expose.php index 7f9651c48..abb1428c0 100644 --- a/cli/Valet/Expose.php +++ b/cli/Valet/Expose.php @@ -11,7 +11,7 @@ public function __construct(public Composer $composer, public CommandLine $cli) { } - public function currentTunnelUrl(string $domain = null): ?string + public function currentTunnelUrl(?string $domain = null): ?string { $endpoint = 'http://127.0.0.1:4040/api/tunnels'; diff --git a/cli/Valet/Filesystem.php b/cli/Valet/Filesystem.php index eaeb1232c..3b16d7f94 100644 --- a/cli/Valet/Filesystem.php +++ b/cli/Valet/Filesystem.php @@ -19,7 +19,7 @@ public function isDir(string $path): bool /** * Create a directory. */ - public function mkdir(string $path, string $owner = null, int $mode = 0755): void + public function mkdir(string $path, ?string $owner = null, int $mode = 0755): void { mkdir($path, $mode, true); @@ -31,7 +31,7 @@ public function mkdir(string $path, string $owner = null, int $mode = 0755): voi /** * Ensure that the given directory exists. */ - public function ensureDirExists(string $path, string $owner = null, int $mode = 0755): void + public function ensureDirExists(string $path, ?string $owner = null, int $mode = 0755): void { if (! $this->isDir($path)) { $this->mkdir($path, $owner, $mode); @@ -49,7 +49,7 @@ public function mkdirAsUser(string $path, int $mode = 0755): void /** * Touch the given path. */ - public function touch(string $path, string $owner = null): string + public function touch(string $path, ?string $owner = null): string { touch($path); @@ -87,7 +87,7 @@ public function get(string $path): string /** * Write to the given file. */ - public function put(string $path, string $contents, string $owner = null): void + public function put(string $path, string $contents, ?string $owner = null): void { file_put_contents($path, $contents); @@ -107,7 +107,7 @@ public function putAsUser(string $path, ?string $contents): void /** * Append the contents to the given file. */ - public function append(string $path, string $contents, string $owner = null): void + public function append(string $path, string $contents, ?string $owner = null): void { file_put_contents($path, $contents, FILE_APPEND); diff --git a/cli/Valet/Ngrok.php b/cli/Valet/Ngrok.php index 222806677..c7c0d11d4 100644 --- a/cli/Valet/Ngrok.php +++ b/cli/Valet/Ngrok.php @@ -20,7 +20,7 @@ public function __construct(public CommandLine $cli, public Brew $brew) /** * Get the current tunnel URL from the Ngrok API. */ - public function currentTunnelUrl(string $domain = null): string + public function currentTunnelUrl(?string $domain = null): string { // wait a second for ngrok to start before attempting to find available tunnels sleep(1); diff --git a/cli/Valet/PhpFpm.php b/cli/Valet/PhpFpm.php index 75c92d896..9c5e86c92 100644 --- a/cli/Valet/PhpFpm.php +++ b/cli/Valet/PhpFpm.php @@ -102,7 +102,7 @@ public function createConfigurationFiles(string $phpVersion): void /** * Restart the PHP FPM process (if one specified) or processes (if none specified). */ - public function restart(string $phpVersion = null): void + public function restart(?string $phpVersion = null): void { $this->brew->restartService($phpVersion ?: $this->utilizedPhpVersions()); } @@ -122,7 +122,7 @@ public function stop(): void /** * Get the path to the FPM configuration file for the current PHP version. */ - public function fpmConfigPath(string $phpVersion = null): string + public function fpmConfigPath(?string $phpVersion = null): string { if (! $phpVersion) { $phpVersion = $this->brew->linkedPhp(); @@ -152,7 +152,7 @@ public function stopRunning(): void /** * Stop a given PHP version, if that specific version isn't being used globally or by any sites. */ - public function stopIfUnused(string $phpVersion = null): void + public function stopIfUnused(?string $phpVersion = null): void { if (! $phpVersion) { return; @@ -305,7 +305,7 @@ public function validateRequestedVersion(string $version): string /** * Get FPM sock file name for a given PHP version. */ - public static function fpmSockName(string $phpVersion = null): string + public static function fpmSockName(?string $phpVersion = null): string { $versionInteger = preg_replace('~[^\d]~', '', $phpVersion); diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index 122610e48..3299ecb56 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -188,7 +188,7 @@ public function getSiteUrl(string $directory): string /** * Identify whether a site is for a proxy by reading the host name from its config file. */ - public function getProxyHostForSite(string $site, string $configContents = null): ?string + public function getProxyHostForSite(string $site, ?string $configContents = null): ?string { $siteConf = $configContents ?: $this->getSiteConfigFileContents($site); @@ -207,7 +207,7 @@ public function getProxyHostForSite(string $site, string $configContents = null) /** * Get the contents of the configuration for the given site. */ - public function getSiteConfigFileContents(string $site, string $suffix = null): ?string + public function getSiteConfigFileContents(string $site, ?string $suffix = null): ?string { $config = $this->config->read(); $suffix = $suffix ?: '.'.$config['tld']; @@ -219,7 +219,7 @@ public function getSiteConfigFileContents(string $site, string $suffix = null): /** * Get all certificates from config folder. */ - public function getCertificates(string $path = null): Collection + public function getCertificates(?string $path = null): Collection { $path = $path ?: $this->certificatesPath(); @@ -283,7 +283,7 @@ public function getSites(string $path, Collection $certs): Collection /** * Unlink the given symbolic link. */ - public function unlink(string $name = null): string + public function unlink(?string $name = null): string { $name = $this->getSiteLinkName($name); @@ -452,7 +452,7 @@ public function isSecured(string $site): bool * * @see https://github.com/cabforum/servercert/blob/main/docs/BR.md */ - public function secure(string $url, string $siteConf = null, int $certificateExpireInDays = 396, int $caExpireInYears = 20): void + public function secure(string $url, ?string $siteConf = null, int $certificateExpireInDays = 396, int $caExpireInYears = 20): void { // Extract in order to later preserve custom PHP version config when securing $phpVersion = $this->customPhpVersion($url); @@ -628,7 +628,7 @@ public function buildCertificateConf(string $path, string $url): void /** * Build the TLS secured Nginx server for the given URL. */ - public function buildSecureNginxServer(string $url, string $siteConf = null): string + public function buildSecureNginxServer(string $url, ?string $siteConf = null): string { if ($siteConf === null) { $siteConf = $this->replaceOldLoopbackWithNew( @@ -943,7 +943,7 @@ public function plistPath(): string /** * Get the path to Nginx site configuration files. */ - public function nginxPath(string $additionalPath = null): string + public function nginxPath(?string $additionalPath = null): string { return $this->valetHomePath().'/Nginx'.($additionalPath ? '/'.$additionalPath : ''); } @@ -951,7 +951,7 @@ public function nginxPath(string $additionalPath = null): string /** * Get the path to the linked Valet sites. */ - public function sitesPath(string $link = null): string + public function sitesPath(?string $link = null): string { return $this->valetHomePath().'/Sites'.($link ? '/'.$link : ''); } @@ -959,7 +959,7 @@ public function sitesPath(string $link = null): string /** * Get the path to the Valet CA certificates. */ - public function caPath(string $caFile = null): string + public function caPath(?string $caFile = null): string { return $this->valetHomePath().'/CA'.($caFile ? '/'.$caFile : ''); } @@ -967,7 +967,7 @@ public function caPath(string $caFile = null): string /** * Get the path to the Valet TLS certificates. */ - public function certificatesPath(string $url = null, string $extension = null): string + public function certificatesPath(?string $url = null, ?string $extension = null): string { $url = $url ? '/'.$url : ''; $extension = $extension ? '.'.$extension : ''; @@ -1051,7 +1051,7 @@ public function replaceSockFile(string $siteConf, string $phpVersion): string /** * Get configuration items defined in .valetrc for a site. */ - public function valetRc(string $siteName, string $cwd = null): array + public function valetRc(string $siteName, ?string $cwd = null): array { if ($cwd) { $path = $cwd.'/.valetrc'; @@ -1077,7 +1077,7 @@ public function valetRc(string $siteName, string $cwd = null): array /** * Get PHP version from .valetrc or .valetphprc for a site. */ - public function phpRcVersion(string $siteName, string $cwd = null): ?string + public function phpRcVersion(string $siteName, ?string $cwd = null): ?string { if ($cwd) { $oldPath = $cwd.'/.valetphprc'; diff --git a/cli/includes/helpers.php b/cli/includes/helpers.php index 475594f05..f9d0ce89e 100644 --- a/cli/includes/helpers.php +++ b/cli/includes/helpers.php @@ -32,7 +32,7 @@ /** * Set or get a global console writer. */ -function writer(OutputInterface $writer = null): OutputInterface|\NullWriter|null +function writer(?OutputInterface $writer = null): OutputInterface|\NullWriter|null { $container = Container::getInstance(); diff --git a/find-usable-php.php b/find-usable-php.php index 9ff3869d9..7af434ae9 100644 --- a/find-usable-php.php +++ b/find-usable-php.php @@ -52,7 +52,7 @@ * @param string|null $phpFormulaName For example, "php@8.1" * @return string */ -function getPhpExecutablePath(string $phpFormulaName = null) +function getPhpExecutablePath(?string $phpFormulaName = null) { $brewPrefix = exec('printf $(brew --prefix)'); diff --git a/tests/PhpFpmTest.php b/tests/PhpFpmTest.php index 9d4e50335..232b45c77 100644 --- a/tests/PhpFpmTest.php +++ b/tests/PhpFpmTest.php @@ -449,7 +449,7 @@ public function test_isolate_will_throw_if_site_is_not_parked_or_linked() class StubForUpdatingFpmConfigFiles extends PhpFpm { - public function fpmConfigPath(string $phpVersion = null): string + public function fpmConfigPath(?string $phpVersion = null): string { return __DIR__.'/output/fpm.conf'; } diff --git a/tests/SiteTest.php b/tests/SiteTest.php index d941b258c..d6201678a 100644 --- a/tests/SiteTest.php +++ b/tests/SiteTest.php @@ -1161,7 +1161,7 @@ public function test_it_can_read_php_rc_version() class CommandLineFake extends CommandLine { - public function runCommand(string $command, callable $onError = null): string + public function runCommand(string $command, ?callable $onError = null): string { // noop // @@ -1284,7 +1284,7 @@ public function assertCertificateExistsWithCounterValue($urlWithTld, $counter) class StubForRemovingLinks extends Site { - public function sitesPath(string $additionalPath = null): string + public function sitesPath(?string $additionalPath = null): string { return __DIR__.'/output'.($additionalPath ? '/'.$additionalPath : ''); } From 3f2b62954c0cf96e5ee079396704ff243ab85551 Mon Sep 17 00:00:00 2001 From: mattstauffer Date: Thu, 21 Dec 2023 03:29:15 +0000 Subject: [PATCH 24/29] Fix code styling --- cli/Valet/Site.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index 61eac44f7..023d08e53 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -632,7 +632,7 @@ public function buildSecureNginxServer(string $url, ?string $siteConf = null): s { if ($siteConf === null) { $nginxVersion = str_replace('nginx version: nginx/', '', exec('nginx -v 2>&1')); - $configFile = version_compare($nginxVersion, '1.25.1', ">=") ? 'secure.valet.conf' : 'secure.valet-legacy.conf'; + $configFile = version_compare($nginxVersion, '1.25.1', '>=') ? 'secure.valet.conf' : 'secure.valet-legacy.conf'; $siteConf = $this->replaceOldLoopbackWithNew( $this->files->getStub($configFile), @@ -778,7 +778,7 @@ public function proxyCreate(string $url, string $host, bool $secure = false): vo } $nginxVersion = str_replace('nginx version: nginx/', '', exec('nginx -v 2>&1')); - $configFile = version_compare($nginxVersion, '1.25.1', ">=") ? 'secure.proxy.valet.conf' : 'secure.proxy.valet-legacy.conf'; + $configFile = version_compare($nginxVersion, '1.25.1', '>=') ? 'secure.proxy.valet.conf' : 'secure.proxy.valet-legacy.conf'; $siteConf = $this->replaceOldLoopbackWithNew( $this->files->getStub($secure ? $configFile : 'proxy.valet.conf'), From 34b4f0309260a538dedcb9f9eab220e637e3ad35 Mon Sep 17 00:00:00 2001 From: mattstauffer Date: Thu, 21 Dec 2023 03:39:28 +0000 Subject: [PATCH 25/29] Fix code styling --- cli/Valet/Ngrok.php | 1 - tests/NgrokTest.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cli/Valet/Ngrok.php b/cli/Valet/Ngrok.php index 734c0c963..0b3cfe7b7 100644 --- a/cli/Valet/Ngrok.php +++ b/cli/Valet/Ngrok.php @@ -77,7 +77,6 @@ public function findHttpTunnelUrl(array $tunnels, string $domain): ?string return $httpTunnel ?? $httpsTunnel; } - /** * Set the Ngrok auth token. */ diff --git a/tests/NgrokTest.php b/tests/NgrokTest.php index c3b2329e1..4191db664 100644 --- a/tests/NgrokTest.php +++ b/tests/NgrokTest.php @@ -47,7 +47,7 @@ public function test_it_matches_correct_share_tunnel() ], 'public_url' => 'http://right-one.ngrok.io/', ], - (object) [ + (object) [ 'proto' => 'https', 'config' => (object) [ 'addr' => 'http://mysecuresite.test:80', From b1b84fe1636e0876777f3ac46ae8565acfc008c9 Mon Sep 17 00:00:00 2001 From: Matt Stauffer Date: Wed, 20 Dec 2023 22:40:28 -0500 Subject: [PATCH 26/29] Minor formatting tweaks to #1460 --- cli/Valet/Ngrok.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cli/Valet/Ngrok.php b/cli/Valet/Ngrok.php index 734c0c963..245ce5a5b 100644 --- a/cli/Valet/Ngrok.php +++ b/cli/Valet/Ngrok.php @@ -73,11 +73,10 @@ public function findHttpTunnelUrl(array $tunnels, string $domain): ?string } } - // Return HTTP tunnel if available, otherwise return HTTPS tunnel + // Return HTTP tunnel if available; HTTPS tunnel if not; null if neither return $httpTunnel ?? $httpsTunnel; } - /** * Set the Ngrok auth token. */ From 9d3d2ee785d4254c8c37fe1b69eeca124c839abe Mon Sep 17 00:00:00 2001 From: mattstauffer Date: Thu, 21 Dec 2023 03:45:03 +0000 Subject: [PATCH 27/29] Fix code styling --- cli/Valet/Site.php | 4 ++-- cli/app.php | 2 +- tests/CliTest.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index 6435e5da4..baab10ad6 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -443,7 +443,7 @@ public function securedWithDates(): array { return collect($this->secured())->map(function ($site) { - $filePath = $this->certificatesPath() . '/' . $site . '.crt'; + $filePath = $this->certificatesPath().'/'.$site.'.crt'; $expiration = $this->cli->run("openssl x509 -enddate -noout -in $filePath"); @@ -511,7 +511,7 @@ public function renew($expireIn): void $this->secure($url, null, $expireIn); - info('The [' . $url . '] site has been secured with a fresh TLS certificate.'); + info('The ['.$url.'] site has been secured with a fresh TLS certificate.'); }); } diff --git a/cli/app.php b/cli/app.php index 74d102a2b..b872af4b5 100644 --- a/cli/app.php +++ b/cli/app.php @@ -280,7 +280,7 @@ function (ConsoleCommandEvent $event) { * Display all of the currently secured sites. */ $app->command('secured [--expiring] [--days=]', function (OutputInterface $output, $expiring = null, $days = 60) { - $now = (new Datetime())->add(new DateInterval('P' . $days . 'D')); + $now = (new Datetime())->add(new DateInterval('P'.$days.'D')); $sites = collect(Site::securedWithDates()) ->when($expiring, fn ($collection) => $collection->filter(fn ($row) => $row['exp'] < $now)) ->map(function ($row) { diff --git a/tests/CliTest.php b/tests/CliTest.php index a963f36b5..c73637c22 100644 --- a/tests/CliTest.php +++ b/tests/CliTest.php @@ -439,8 +439,8 @@ public function test_secured_command() $site->shouldReceive('securedWithDates')->andReturn([ [ 'site' => 'tighten.test', - 'exp' => new DateTime('Aug 2 13:16:40 2024 GMT') - ] + 'exp' => new DateTime('Aug 2 13:16:40 2024 GMT'), + ], ]); swap(RealSite::class, $site); From 59b19a20aa7a5ba8224eebfbda36b05a4ab56812 Mon Sep 17 00:00:00 2001 From: Matt Stauffer Date: Wed, 20 Dec 2023 22:46:05 -0500 Subject: [PATCH 28/29] Clean up syntax from #1461 --- cli/Valet/Site.php | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/Valet/Site.php b/cli/Valet/Site.php index baab10ad6..29814bbed 100644 --- a/cli/Valet/Site.php +++ b/cli/Valet/Site.php @@ -442,7 +442,6 @@ public function secured(): array public function securedWithDates(): array { return collect($this->secured())->map(function ($site) { - $filePath = $this->certificatesPath().'/'.$site.'.crt'; $expiration = $this->cli->run("openssl x509 -enddate -noout -in $filePath"); From b076ad6a49dd4cc7953ef4a3d165ac6b9c313a89 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Wed, 27 Dec 2023 15:47:29 +0100 Subject: [PATCH 29/29] Update app.php --- cli/app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/app.php b/cli/app.php index b872af4b5..08ffd4434 100644 --- a/cli/app.php +++ b/cli/app.php @@ -33,7 +33,7 @@ */ Container::setInstance(new Container); -$version = '4.5.0'; +$version = '4.6.0'; $app = new Application('Laravel Valet', $version);