v0.27.0 — user-configurable app subdomains
Users can now customize the subdomain for each app during deployment instead of using a fixed value. The deploy page shows an editable text input with the default pre-filled and the base domain as a suffix. New "subdomain" deploy field type with DNS-safe format validation, reserved name blocklist, and uniqueness check across deployed stacks. Locked after deploy — changing requires Remove + Redeploy. Backward compatible: InjectMissingFields() auto-fills SUBDOMAIN from .felhom.yml defaults for existing deployed apps on next sync/restart. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -270,7 +270,22 @@
|
||||
{{if .LockedAfterDeploy}}<span class="locked-hint">telepítés után nem módosítható</span>{{end}}
|
||||
</label>
|
||||
|
||||
{{if eq .Type "select"}}
|
||||
{{if eq .Type "subdomain"}}
|
||||
<div class="subdomain-input-group">
|
||||
<input type="text" id="field-{{.EnvVar}}" name="{{.EnvVar}}"
|
||||
class="form-control subdomain-input"
|
||||
value="{{if and $.AlreadyDeployed $.DeployedFieldValues}}{{index $.DeployedFieldValues .EnvVar}}{{else}}{{.Default}}{{end}}"
|
||||
placeholder="aldomain"
|
||||
pattern="[a-z0-9]([a-z0-9-]*[a-z0-9])?"
|
||||
required
|
||||
{{if $.AlreadyDeployed}}disabled{{end}}
|
||||
oninput="this.value=this.value.toLowerCase().replace(/[^a-z0-9-]/g,'')">
|
||||
<span class="subdomain-suffix">.{{$.Domain}}</span>
|
||||
</div>
|
||||
{{if not $.AlreadyDeployed}}
|
||||
<span class="form-hint">Az aldomain telepítés után nem módosítható. Megváltoztatáshoz az alkalmazás eltávolítása és újratelepítése szükséges (minden adat törlődik).</span>
|
||||
{{end}}
|
||||
{{else if eq .Type "select"}}
|
||||
<select id="field-{{.EnvVar}}" name="{{.EnvVar}}" class="form-control"
|
||||
{{if $.AlreadyDeployed}}disabled{{end}}>
|
||||
{{range .Options}}
|
||||
@@ -510,6 +525,17 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
||||
}
|
||||
}
|
||||
|
||||
// Client-side validation: check subdomain format
|
||||
const subdomainField = e.target.querySelector('.subdomain-input');
|
||||
if (subdomainField && !subdomainField.disabled) {
|
||||
const sd = subdomainField.value.trim().toLowerCase();
|
||||
if (!sd || !/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(sd)) {
|
||||
alert('Az aldomain csak kisbetűket, számokat és kötőjelet tartalmazhat, és nem kezdődhet/végződhet kötőjellel.');
|
||||
subdomainField.focus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Client-side validation: check all required fields
|
||||
const requiredFields = e.target.querySelectorAll('input[required], select[required]');
|
||||
for (const rf of requiredFields) {
|
||||
|
||||
Reference in New Issue
Block a user