feat(site): add alias domain hooks and validate alias domain names - #502
Merged
mrrobot47 merged 7 commits intoSep 25, 2026
Merged
Conversation
Fire site_alias_domains_updated with the site URL and the added and removed alias domains once the alias change has been applied, so packages that keep per-domain config (e.g. auth-command's htpasswd and whitelist files) can sync it.
`--add-alias-domains='b.com,'` stored an empty alias domain, and blank entries also reached the alias domain hooks, where they turned into file names. The existing, added and deleted lists are now trimmed and blank entries dropped before any processing, an update with nothing left to add or delete is refused, and the hook gets re-indexed arrays.
`site_alias_domains_updated` fires only after the new VIRTUAL_HOST has been rendered and the containers are up, so per-domain proxy config added from it (like auth-command's htpasswd and ACL files) arrives after the new alias domains are already served. `site_alias_domains_before_update` ($site_url, $domains_to_add) now fires once the input is validated and before docker-compose.yml is dumped. `site_alias_domains_update_failed` ($site_url, $domains_to_add) fires when the update is aborted after that point: when a before-update callback or dumping the compose file throws, or when the Let's Encrypt renewal fails and the revert has restored the old containers. The site then still has its old alias domains in the database. The flag is set before the before-update hook runs, so a callback that throws still gets the failure hook.
site-command no longer removes `htpasswd/<site>` or the site's auth and whitelist rows in delete_site(). auth-command's `site_cleanup` hook, which runs just before, removes them along with the `_wildcard.<site>`, alias and `_acl` files, so the copy here was a duplicate. Requires auth-command with the site_cleanup hook autoloaded (EasyEngine/auth-command#57). The two must ship in the same core release, or site delete leaves the site's auth files and rows behind.
`ee site create --type=html --alias-domains='a.com,,b.com,'` stored empty alias domains, which ended up in VIRTUAL_HOST and the nginx server_name. The trim-and-drop-blanks split used on update is now `split_alias_domains()` in the site utils and is also used on create. A flag passed without a value no longer becomes the alias domain `1`.
Alias domains were stored as given, so names like `../evil`, `a..b`, `a.com.` or `default` reached VIRTUAL_HOST and the per-domain proxy files, where `default` and `default_admin_tools` map onto the global auth and ACL files. `validate_alias_domains()` now allows only a hostname or `*.hostname` whose dot-separated labels use letters, digits, `-` and `_` (not starting or ending with `-`), and rejects `default` and `default_admin_tools` in any case. `ee site update --add-alias-domains` and `ee site create --type=html --alias-domains` exit with an error listing the invalid names before changing anything. Alias domains being deleted aren't checked, so existing invalid ones can still be removed.
This was referenced Sep 24, 2026
Merged
An alias like `_wildcard.example.com` passed validation, but it shares its proxy file names with the `*.example.com` files of site example.com, so auth-command could delete or overwrite them. Labels can no longer start with `_` (hostnames like `my_blog.example.com` still work). The rule is now also exposed per name as `is_valid_alias_domain()`, and the global proxy file names as `is_reserved_proxy_file_name()`, so auth-command can use the same rule.
mrrobot47
marked this pull request as ready for review
September 25, 2026 05:13
mrrobot47
added a commit
to mrrobot47/site-command
that referenced
this pull request
Sep 25, 2026
…gine#502) AUTH-1 is fixed on develop, so the underscore alias scenario is a regular regression check. "Delete an alias domain" now waits for the remaining alias to answer 200 before checking the deleted one: the recreated nginx container drops all of the site's domains from the proxy until docker-gen catches up, and on develop the command returns inside that gap.
This was referenced Sep 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds hooks around alias domain updates so packages that keep per-domain config (auth-command's htpasswd and ACL files) can protect new alias domains before the proxy serves them and clean up after removal. Alias domain names are now validated and blank entries dropped, since they end up in
VIRTUAL_HOSTand in per-domain proxy file names. Site delete leaves auth cleanup to auth-command'ssite_cleanuphook.Changes
site_alias_domains_updated($site_url, $domains_to_add, $domains_to_delete) once an alias domain change has been applied.site_alias_domains_before_update($site_url, $domains_to_add) after the input is validated and beforedocker-compose.ymlis dumped, andsite_alias_domains_update_failed($site_url, $domains_to_add) when the update is aborted after that point (a callback or the compose dump throws, or the Let's Encrypt renewal fails and the old containers are restored).EE\Site\Utils\split_alias_domains().EE\Site\Utils\validate_alias_domains(): only a hostname or*.hostnamewith labels of letters, digits,-and_is accepted (a label can't start with-or_, so_wildcard.Xcan't collide with another site's wildcard files, or end with-), anddefault/default_admin_tools(the global auth file names) are rejected in any case. The same rule is exposed per name asis_valid_alias_domain(), and the reserved names asis_reserved_proxy_file_name(), for auth-command.ee site update --add-alias-domainsandee site create --type=html --alias-domainsexit with an error listing the invalid names before changing anything. Alias domains being deleted aren't checked, so existing invalid ones can still be removed.delete_site()no longer removeshtpasswd/<site>or the site's auth and whitelist rows; auth-command'ssite_cleanuphook removes them along with the_wildcard.<site>, alias and_aclfiles.Release / merge order
These PRs ship together in one core release:
easyengine/nginx-proxytemplate (needs a new dockerfiles tag)Order:
easyengine/nginx-proxyimage is on Docker Hub.dev-developof every package) and tag each package.easyengine/nginx-proxyinimg-versions.jsontogether.Why they are coupled:
_wildcard.Xfile to sibling sites too (e.g.shop.example.compicks up_wildcard.example.com).site_alias_domains_before_update,site_alias_domains_updatedandsite_alias_domains_update_failedhooks, which only the new site-command fires.site_cleanuphook (autoloaded since feat(auth): support http auth and ip whitelist on wildcard subdomains and alias domains auth-command#57) does it.split_alias_domains()andvalidate_alias_domains(), and auth-command its newis_valid_alias_domain()andis_reserved_proxy_file_name(); with an older site-command, they fail with a fatal "undefined function" error._wildcard.Xfiles that were also relied on to protectXitself:Xnow needs its ownhtpasswd/X(andvhost.d/X_acl) file.Testing
*.aliases, multiple users, global auth, IP whitelists, alias add/remove, site delete, self-signed SSL and Let's Encrypt.