diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index 7457d3b..c71a820 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -87,6 +87,7 @@ C42CFB1A27DFE8BD00862737 /* NginxConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */; }; C42F26732805B4B400938AC7 /* DomainListable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42F26722805B4B400938AC7 /* DomainListable.swift */; }; C42F26742805B4B400938AC7 /* DomainListable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42F26722805B4B400938AC7 /* DomainListable.swift */; }; + C42F26762805FEE200938AC7 /* nginx-secure-proxy.test in Resources */ = {isa = PBXBuildFile; fileRef = C42F26752805FEE200938AC7 /* nginx-secure-proxy.test */; }; C43603A0275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = C436039F275E67610028EFC6 /* AppDelegate+Notifications.swift */; }; C43603A1275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = C436039F275E67610028EFC6 /* AppDelegate+Notifications.swift */; }; C43A8A1A25D9CD1000591B77 /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43A8A1925D9CD1000591B77 /* Utility.swift */; }; @@ -312,6 +313,7 @@ C42CFB1727DFDFDC00862737 /* nginx-site-isolated.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-site-isolated.test"; sourceTree = ""; }; C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NginxConfigurationTest.swift; sourceTree = ""; }; C42F26722805B4B400938AC7 /* DomainListable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListable.swift; sourceTree = ""; }; + C42F26752805FEE200938AC7 /* nginx-secure-proxy.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-secure-proxy.test"; sourceTree = ""; }; C436039F275E67610028EFC6 /* AppDelegate+Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Notifications.swift"; sourceTree = ""; }; C43A8A1925D9CD1000591B77 /* Utility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utility.swift; sourceTree = ""; }; C43A8A1F25D9D1D700591B77 /* brew-formula.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "brew-formula.json"; sourceTree = ""; }; @@ -630,6 +632,7 @@ C459B4BE27F6093A00E9B4B4 /* nginx */ = { isa = PBXGroup; children = ( + C42F26752805FEE200938AC7 /* nginx-secure-proxy.test */, C459B4BC27F6093700E9B4B4 /* nginx-proxy.test */, C42CFB1527DFDE7900862737 /* nginx-site.test */, C42CFB1727DFDFDC00862737 /* nginx-site-isolated.test */, @@ -1058,6 +1061,7 @@ C43A8A2025D9D1D700591B77 /* brew-formula.json in Resources */, C4AF9F72275445FF00D44ED0 /* valet-config.json in Resources */, C44C1992276E44CB0072762D /* ProgressWindow.storyboard in Resources */, + C42F26762805FEE200938AC7 /* nginx-secure-proxy.test in Resources */, C4F30B08278E195800755FCE /* brew-services.json in Resources */, C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */, C459B4BD27F6093700E9B4B4 /* nginx-proxy.test in Resources */, diff --git a/assets/affinity/icons.afdesign b/assets/affinity/icons.afdesign index 8811fa5..7081043 100644 Binary files a/assets/affinity/icons.afdesign and b/assets/affinity/icons.afdesign differ diff --git a/phpmon-tests/Parsers/NginxConfigurationTest.swift b/phpmon-tests/Parsers/NginxConfigurationTest.swift index 521a216..7e2a819 100644 --- a/phpmon-tests/Parsers/NginxConfigurationTest.swift +++ b/phpmon-tests/Parsers/NginxConfigurationTest.swift @@ -22,6 +22,10 @@ class NginxConfigurationTest: XCTestCase { return Bundle(for: Self.self).url(forResource: "nginx-proxy", withExtension: "test")! } + static var secureProxyUrl: URL { + return Bundle(for: Self.self).url(forResource: "nginx-secure-proxy", withExtension: "test")! + } + func testCanDetermineSiteNameAndTld() throws { XCTAssertEqual( "nginx-site", @@ -54,4 +58,10 @@ class NginxConfigurationTest: XCTestCase { XCTAssertEqual(nil, normal.proxy) } + func testCanDetermineSecuredProxy() throws { + let proxied = NginxConfiguration(filePath: NginxConfigurationTest.secureProxyUrl.path) + XCTAssertTrue(proxied.contents.contains("# valet stub: secure.proxy.valet.conf")) + XCTAssertEqual("http://127.0.0.1:90", proxied.proxy) + } + } diff --git a/phpmon-tests/Test Files/nginx/nginx-secure-proxy.test b/phpmon-tests/Test Files/nginx/nginx-secure-proxy.test new file mode 100644 index 0000000..a9ef7ac --- /dev/null +++ b/phpmon-tests/Test Files/nginx/nginx-secure-proxy.test @@ -0,0 +1,57 @@ +# valet stub: secure.proxy.valet.conf + +server { + listen 127.0.0.1:80; + #listen 127.0.0.1:80; # valet loopback + server_name my-proxy.test www.my-proxy.test *.my-proxy.test; + return 301 https://$host$request_uri; +} + +server { + listen 127.0.0.1:443 ssl http2; + #listen 127.0.0.1:443 ssl http2; # valet loopback + server_name my-proxy.test www.my-proxy.test *.my-proxy.test; + root /; + charset utf-8; + client_max_body_size 128M; + http2_push_preload on; + + location /41c270e4-5535-4daa-b23e-c269744c2f45/ { + internal; + alias /; + try_files $uri $uri/; + } + + ssl_certificate "/Users/nicoverbruggen/.config/valet/Certificates/my-proxy.test.crt"; + ssl_certificate_key "/Users/nicoverbruggen/.config/valet/Certificates/my-proxy.test.key"; + + access_log off; + error_log "/Users/nicoverbruggen/.config/valet/Log/my-proxy.test-error.log"; + + error_page 404 "/Users/nicoverbruggen/.composer/vendor/laravel/valet/server.php"; + + location / { + proxy_pass http://127.0.0.1:90; + 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/phpmon/Domain/DomainList/AddSiteVC.swift b/phpmon/Domain/DomainList/AddSiteVC.swift index ce4112d..dabc774 100644 --- a/phpmon/Domain/DomainList/AddSiteVC.swift +++ b/phpmon/Domain/DomainList/AddSiteVC.swift @@ -45,6 +45,10 @@ class AddSiteVC: NSViewController, NSTextFieldDelegate { // MARK: - Outlet Interactions + @IBAction func pressedCreateProxy(_ sender: Any) { + // valet proxy (domain) http://127.0.0.1:90 (--secure) + } + @IBAction func pressedCreateLink(_ sender: Any) { let path = self.pathControl.url!.path let name = self.linkName.stringValue diff --git a/phpmon/Domain/DomainList/Cells/DomainListTLSCell.swift b/phpmon/Domain/DomainList/Cells/DomainListTLSCell.swift index e2a5ee2..da7d831 100644 --- a/phpmon/Domain/DomainList/Cells/DomainListTLSCell.swift +++ b/phpmon/Domain/DomainList/Cells/DomainListTLSCell.swift @@ -22,7 +22,7 @@ class DomainListTLSCell: NSTableCellView, DomainListCellProtocol } func populateCell(with proxy: ValetProxy) { - imageViewLock.contentTintColor = proxy.target.contains("https") + imageViewLock.contentTintColor = proxy.secured ? NSColor(named: "IconColorGreen") : NSColor(named: "IconColorRed") } diff --git a/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift b/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift index 89ce064..60d311d 100644 --- a/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift +++ b/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift @@ -13,11 +13,13 @@ class ValetProxy: DomainListable var domain: String var tld: String var target: String + var secured: Bool = false init(_ configuration: NginxConfiguration) { self.domain = configuration.domain self.tld = configuration.tld self.target = configuration.proxy! + self.secured = Filesystem.fileExists("~/.config/valet/Certificates/\(self.domain).\(self.tld).key") } // MARK: - DomainListable Protocol @@ -27,7 +29,7 @@ class ValetProxy: DomainListable } func getListableSecured() -> Bool { - return false + return self.secured } func getListableAbsolutePath() -> String {