diff --git a/src/Auth_Command.php b/src/Auth_Command.php index f297aa6..6e6336e 100644 --- a/src/Auth_Command.php +++ b/src/Auth_Command.php @@ -161,7 +161,7 @@ private function create_auth( array $assoc_args, bool $global, string $site_url if ( 'default' === $site_url ) { $this->generate_global_auth_files(); } else { - $this->generate_site_auth_files( $site_url ); + $this->generate_site_auth_files( $site_url, $this->site_data ); } EE::log( 'Reloading global reverse proxy.' ); @@ -200,7 +200,7 @@ private function create_whitelist( string $site_url, string $ips ) { if ( 'default' === $site_url ) { $this->generate_global_whitelist(); } else { - $this->generate_site_whitelist( $site_url ); + $this->generate_site_whitelist( $site_url, $this->site_data ); } reload_global_nginx_proxy(); @@ -283,7 +283,10 @@ private function generate_global_auth_files() { ); foreach ( $sites as $site ) { - $this->generate_site_auth_files( $site ); + // Fetch site data to get app_sub_type and alias_domains + $site_info = \EE\Model\Site::where( 'site_url', $site ); + $site_data = ! empty( $site_info ) ? $site_info[0] : null; + $this->generate_site_auth_files( $site, $site_data ); } } } @@ -292,25 +295,77 @@ private function generate_global_auth_files() { * Generates auth files for a site * * @param string $site_url URL of site + * @param object $site_data Optional site data object containing app_sub_type and alias_domains * * @throws Exception */ - private function generate_site_auth_files( string $site_url ) { - $site_auth_file = EE_ROOT_DIR . '/services/nginx-proxy/htpasswd/' . $site_url; - $this->fs->remove( $site_auth_file ); + private function generate_site_auth_files( string $site_url, $site_data = null ) { + // Always clean up wildcard file first (handles site type changes from subdom to regular) + $wildcard_file = EE_ROOT_DIR . '/services/nginx-proxy/htpasswd/_wildcard.' . $site_url; + $this->fs->remove( $wildcard_file ); + + // Collect all domains to generate htpasswd files for + $domains = [ $site_url ]; + + // For subdomain multisites, add wildcard file + if ( $site_data && ! empty( $site_data->app_sub_type ) && 'subdom' === $site_data->app_sub_type ) { + $domains[] = '_wildcard.' . $site_url; + } + + // Add alias domains (excluding main site_url) + if ( $site_data && ! empty( $site_data->alias_domains ) ) { + $alias_list = array_map( 'trim', explode( ',', $site_data->alias_domains ) ); + foreach ( $alias_list as $alias ) { + if ( empty( $alias ) || $alias === $site_url ) { + continue; + } + // Skip *.site_url as it transforms to _wildcard.site_url (already added for subdomain multisite) + if ( ! empty( $site_data->app_sub_type ) && 'subdom' === $site_data->app_sub_type && '*.' . $site_url === $alias ) { + continue; + } + // Replace *.domain with _wildcard.domain + if ( 0 === strpos( $alias, '*.' ) ) { + $domains[] = '_wildcard.' . substr( $alias, 2 ); + } else { + $domains[] = $alias; + // For subdomain multisites, also add wildcard for non-wildcard alias domains + if ( ! empty( $site_data->app_sub_type ) && 'subdom' === $site_data->app_sub_type ) { + $domains[] = '_wildcard.' . $alias; + } + } + } + } $auths = array_merge( Auth::get_global_auths(), Auth::where( 'site_url', $site_url ) ); - foreach ( $auths as $key => $auth ) { - $flags = 'b'; + // Remove duplicates (e.g., *.example.com alias + subdomain multisite both create _wildcard.example.com) + $domains = array_unique( $domains ); + + // If no auths exist, remove all htpasswd files for this site and its domains + if ( empty( $auths ) ) { + foreach ( $domains as $domain ) { + $domain_auth_file = EE_ROOT_DIR . '/services/nginx-proxy/htpasswd/' . $domain; + $this->fs->remove( $domain_auth_file ); + } + return; + } + + // Generate htpasswd files for all collected domains + foreach ( $domains as $domain ) { + $domain_auth_file = EE_ROOT_DIR . '/services/nginx-proxy/htpasswd/' . $domain; + $this->fs->remove( $domain_auth_file ); - if ( $key === 0 ) { - $flags = 'bc'; + foreach ( $auths as $key => $auth ) { + $flags = 'b'; + + if ( $key === 0 ) { + $flags = 'bc'; + } + EE::exec( sprintf( 'docker exec %s htpasswd -%s /etc/nginx/htpasswd/%s %s %s', EE_PROXY_TYPE, $flags, $domain, $auth->username, $auth->password ) ); } - EE::exec( sprintf( 'docker exec %s htpasswd -%s /etc/nginx/htpasswd/%s %s %s', EE_PROXY_TYPE, $flags, $site_url, $auth->username, $auth->password ) ); } } @@ -333,7 +388,10 @@ private function generate_global_whitelist() { } foreach ( $sites as $site ) { - $this->generate_site_whitelist( $site ); + // Fetch site data to get app_sub_type and alias_domains + $site_info = \EE\Model\Site::where( 'site_url', $site ); + $site_data = ! empty( $site_info ) ? $site_info[0] : null; + $this->generate_site_whitelist( $site, $site_data ); } } @@ -342,12 +400,49 @@ private function generate_global_whitelist() { * Generates site whitelist files * * @param string $site_url + * @param object $site_data Optional site data object containing app_sub_type and alias_domains * * @throws Exception */ - private function generate_site_whitelist( string $site_url ) { - $site_whitelist_file = EE_ROOT_DIR . '/services/nginx-proxy/vhost.d/' . $site_url . '_acl'; - $this->fs->remove( $site_whitelist_file ); + private function generate_site_whitelist( string $site_url, $site_data = null ) { + // Always clean up wildcard file first (handles site type changes from subdom to regular) + $wildcard_file = EE_ROOT_DIR . '/services/nginx-proxy/vhost.d/_wildcard.' . $site_url . '_acl'; + $this->fs->remove( $wildcard_file ); + + // Collect all domains to generate whitelist files for + $domains = [ $site_url ]; + + // For subdomain multisites, add wildcard file + if ( $site_data && ! empty( $site_data->app_sub_type ) && 'subdom' === $site_data->app_sub_type ) { + $domains[] = '_wildcard.' . $site_url; + } + + // Add alias domains (excluding main site_url) + if ( $site_data && ! empty( $site_data->alias_domains ) ) { + $alias_list = array_map( 'trim', explode( ',', $site_data->alias_domains ) ); + foreach ( $alias_list as $alias ) { + if ( empty( $alias ) || $alias === $site_url ) { + continue; + } + // Skip *.site_url as it transforms to _wildcard.site_url (already added for subdomain multisite) + if ( ! empty( $site_data->app_sub_type ) && 'subdom' === $site_data->app_sub_type && '*.' . $site_url === $alias ) { + continue; + } + // Replace *.domain with _wildcard.domain + if ( 0 === strpos( $alias, '*.' ) ) { + $domains[] = '_wildcard.' . substr( $alias, 2 ); + } else { + $domains[] = $alias; + // For subdomain multisites, also add wildcard for non-wildcard alias domains + if ( ! empty( $site_data->app_sub_type ) && 'subdom' === $site_data->app_sub_type ) { + $domains[] = '_wildcard.' . $alias; + } + } + } + } + + // Remove duplicates + $domains = array_unique( $domains ); $whitelists = array_column( 'default' === $site_url ? Whitelist::get_global_ips() : @@ -358,7 +453,21 @@ private function generate_site_whitelist( string $site_url ) { 'ip' ); - $this->put_ips_to_file( $site_whitelist_file, $whitelists ); + // If no whitelists exist, remove all whitelist files for this site and its domains + if ( empty( $whitelists ) ) { + foreach ( $domains as $domain ) { + $domain_whitelist_file = EE_ROOT_DIR . '/services/nginx-proxy/vhost.d/' . $domain . '_acl'; + $this->fs->remove( $domain_whitelist_file ); + } + return; + } + + // Generate whitelist files for all collected domains + foreach ( $domains as $domain ) { + $domain_whitelist_file = EE_ROOT_DIR . '/services/nginx-proxy/vhost.d/' . $domain . '_acl'; + $this->fs->remove( $domain_whitelist_file ); + $this->put_ips_to_file( $domain_whitelist_file, $whitelists ); + } } /** @@ -453,7 +562,7 @@ private function update_auth( array $assoc_args, string $site_url ) { if ( 'default' === $site_url ) { $this->generate_global_auth_files(); } else { - $this->generate_site_auth_files( $site_url ); + $this->generate_site_auth_files( $site_url, $this->site_data ); } EE::log( 'Reloading global reverse proxy.' ); @@ -499,7 +608,7 @@ private function update_whitelist( string $site_url, string $ips ) { if ( 'default' === $site_url ) { $this->generate_global_whitelist(); } else { - $this->generate_site_whitelist( $site_url ); + $this->generate_site_whitelist( $site_url, $this->site_data ); } reload_global_nginx_proxy(); @@ -594,7 +703,7 @@ public function delete( $args, $assoc_args ) { if ( 'default' === $site_url ) { $this->generate_global_auth_files(); } else { - $this->generate_site_auth_files( $site_url ); + $this->generate_site_auth_files( $site_url, $this->site_data ); } if ( $user ) { @@ -646,7 +755,7 @@ public function delete( $args, $assoc_args ) { if ( 'default' === $site_url ) { $this->generate_global_whitelist(); } else { - $this->generate_site_whitelist( $site_url ); + $this->generate_site_whitelist( $site_url, $this->site_data ); } reload_global_nginx_proxy();