diff --git a/src/open/ServerConsentView.js b/src/open/ServerConsentView.js index cb87d7d..a44be81 100644 --- a/src/open/ServerConsentView.js +++ b/src/open/ServerConsentView.js @@ -75,7 +75,6 @@ class ServerOptions extends TemplateView { className: "line", placeholder: "Other", name: "otherServer", - pattern: "((?:[0-9a-zA-Z][0-9a-zA-Z-]{1,61}\\.)*)(xn--[a-z0-9]+|[a-z]+)", onClick: evt => this._onClickOther(evt), }) ]))); @@ -98,9 +97,13 @@ class ServerOptions extends TemplateView { let {name, value} = evt.target; if (name === "selectedServer") { this._onChangeServerRadio(evt.target); - } else if (name === "otherServer") { - this.value.selectServer(value); + const textField = evt.target; + if(!this.value.selectOtherServer(value)) { + textField.setCustomValidity("Please enter a valid domain name"); + } else { + textField.setCustomValidity(""); + } } } @@ -112,6 +115,7 @@ class ServerOptions extends TemplateView { value = otherServer.value; } else { otherServer.required = false; + otherServer.setCustomValidity(""); } this.value.selectServer(value); } diff --git a/src/open/ServerConsentViewModel.js b/src/open/ServerConsentViewModel.js index d11b1fc..d7a117a 100644 --- a/src/open/ServerConsentViewModel.js +++ b/src/open/ServerConsentViewModel.js @@ -39,6 +39,22 @@ export class ServerConsentViewModel extends ViewModel { this.emitChange(); } + selectOtherServer(domainOrUrl) { + let urlStr = domainOrUrl; + if (!urlStr.startsWith("http://") && !urlStr.startsWith("https://")) { + urlStr = `https://${domainOrUrl}`; + } + try { + const domain = new URL(urlStr).hostname; + if (/((?:[0-9a-zA-Z][0-9a-zA-Z-]{1,61}\.)+)(xn--[a-z0-9]+|[a-z]+)/.test(domain) || domain === "localhost") { + this.selectServer(urlStr); + return true; + } + } catch (err) {} + this.selectServer(null); + return false; + } + continueWithSelection() { // keep previously consented servers const homeservers = this.preferences.homeservers || [];