feat: allow custom subdomains in create UI (#1109)

* feat: allow custom subdomains in create UI

* test: stabilize custom subdomain browser flow

* test: fix normalized address expectation

* fix: gate custom subdomain input by setting

* fix: scope custom subdomains to random domains

* test: recreate random subdomain manually

* refactor: minimize custom subdomain changes

* refactor: reduce custom subdomain changes

* test: fix custom subdomain locator

* refactor: clarify manual subdomain validation

* test: target visible custom subdomain input

* refactor: simplify manual subdomain validation

* refactor: use subdomain mode selector

* style: stack subdomain modes vertically

* test: click visible subdomain mode labels
This commit is contained in:
Dream Hunter
2026-08-19 12:10:09 +08:00
committed by GitHub
parent 624fc9bb96
commit a3c62de42f
17 changed files with 225 additions and 66 deletions
@@ -27,7 +27,7 @@ RANDOM_SUBDOMAIN_DOMAINS = ["abc.com"]
RANDOM_SUBDOMAIN_LENGTH = 8
```
- `RANDOM_SUBDOMAIN_DOMAINS`: base domains that allow optional random second-level subdomains
- `RANDOM_SUBDOMAIN_DOMAINS`: base domains that allow random or manually entered subdomains
- `RANDOM_SUBDOMAIN_LENGTH`: random string length, range `1-63`, default `8`
The create-address APIs only generate a random subdomain when the request explicitly passes
@@ -47,6 +47,10 @@ the request body:
If you want to create an address under a specific subdomain such as `team.abc.com`, do not pass
`enableRandomSubdomain: true`; use the direct-subdomain flow below instead.
For base domains in `RANDOM_SUBDOMAIN_DOMAINS`, the web and admin pages offer **Normal Domain**,
**Use Random Subdomain**, and **Use Custom Subdomain** as single-choice modes. In custom mode,
enter only `team`; the frontend combines it as `team.abc.com`.
> [!NOTE]
> This feature only appends a random second-level subdomain when the mailbox is created.
>
@@ -77,10 +81,10 @@ If you want to create an address under a specific subdomain such as `team.abc.co
>
> Reference issue: [#1035](https://github.com/dreamhunter2333/cloudflare_temp_email/issues/1035)
## Let APIs Specify Subdomains Directly
## Let APIs Specify Other Subdomains Directly
If you do not want the system to generate a random subdomain, and instead want the caller to
explicitly create addresses like `team.abc.com`, enable:
If a base domain is not in `RANDOM_SUBDOMAIN_DOMAINS`, but API callers still need to create
addresses like `team.abc.com` directly, enable:
```toml
ENABLE_CREATE_ADDRESS_SUBDOMAIN_MATCH = true
@@ -93,7 +97,7 @@ addresses can be created through `/api/new_address` or `/admin/new_address`:
- `name@dev.team.abc.com`
> [!NOTE]
> This only relaxes the domain validation used by the create-address APIs. It does not change the
> default domain dropdown, and it does not create Cloudflare-side subdomain mail routes for you.
> This switch only relaxes create-address API domain validation. It does not change the frontend
> domain scope or create Cloudflare-side subdomain mail routes for you.
>
> If the admin panel has already saved an override once, you can switch it back to **Follow Environment Variable** to clear the override and return to env fallback behavior.
+5 -6
View File
@@ -37,7 +37,7 @@
| `DEFAULT_DOMAINS` | JSON | Default domains available to users (not logged in or users without assigned roles) | `["awsl.uk", "dreamhunter2333.xyz"]` |
| `CREATE_ADDRESS_DEFAULT_DOMAIN_FIRST` | Text/JSON | Whether to prioritize default domain when creating new addresses, if set to true, will use the first domain when no domain is specified, mainly for telegram bot scenarios | `false` |
| `ENABLE_CREATE_ADDRESS_SUBDOMAIN_MATCH` | Text/JSON | Whether to allow create-address APIs to use base-domain suffix matching. When enabled, if `example.com` is allowed, `/api/new_address` and `/admin/new_address` can also accept `foo.example.com` or `a.b.example.com` | `true` |
| `RANDOM_SUBDOMAIN_DOMAINS` | JSON | Base domains that allow optional random subdomain creation, so `name@abc.com` can become `name@<random>.abc.com` | `["abc.com"]` |
| `RANDOM_SUBDOMAIN_DOMAINS` | JSON | Base domains that allow random or manual subdomains; random mode can turn `name@abc.com` into `name@<random>.abc.com` | `["abc.com"]` |
| `RANDOM_SUBDOMAIN_LENGTH` | Number | Random subdomain length, default `8`, valid range `1-63` | `8` |
| `DOMAIN_LABELS` | JSON | For Chinese domains, you can use DOMAIN_LABELS to display Chinese names | `["中文.awsl.uk", "dreamhunter2333.xyz"]` |
| `ENABLE_AUTO_REPLY` | Text/JSON | Allow automatic email replies. Sender filter (`source_prefix`) supports three modes: empty to match all senders, prefix for `startsWith` matching, or `/regex/` syntax for regex matching (e.g. `/@example\.com$/`) | `true` |
@@ -50,8 +50,8 @@
> [!NOTE]
> When `DEFAULT_DOMAINS` is unset or configured as an empty array, it falls back to `DOMAINS`.
>
> `RANDOM_SUBDOMAIN_DOMAINS` only controls automatic random subdomain generation during mailbox
> creation. It does not create Cloudflare-side subdomain routing for you.
> `RANDOM_SUBDOMAIN_DOMAINS` defines the base-domain scope shared by the frontend random and manual
> subdomain modes. It does not create Cloudflare-side subdomain routing for you.
>
> To actually receive mail on addresses like `name@<random>.abc.com`, **you must add a wildcard
> `*` MX record under the base domain in DNS** by copying the apex's existing MX records to
@@ -65,9 +65,8 @@
> Subdomain addresses are usually best used for receiving only; for sending, prefer the main
> domain.
>
> `ENABLE_CREATE_ADDRESS_SUBDOMAIN_MATCH` is different from random subdomain generation: it lets
> API callers **directly specify** a subdomain such as `foo.example.com`, while random subdomain
> generation appends one automatically during creation.
> `ENABLE_CREATE_ADDRESS_SUBDOMAIN_MATCH` is independent from those frontend modes. It lets API
> callers **directly specify** subdomains such as `foo.example.com` under other allowed base domains.
>
> `ENABLE_CREATE_ADDRESS_SUBDOMAIN_MATCH` precedence: if the env is explicitly set to `false`, the
> feature is globally forced off; otherwise the persisted admin setting takes precedence, and the env