split RMS login email into callsign and domain select

This commit is contained in:
2026-04-02 22:42:49 +02:00
parent bc2f972769
commit 8c031a939c
2 changed files with 89 additions and 10 deletions

View File

@@ -81,7 +81,8 @@ const state = {
const els = {
authForm: document.getElementById("authForm"),
email: document.getElementById("email"),
callsignInput: document.getElementById("callsignInput"),
emailDomainSelect: document.getElementById("emailDomainSelect"),
loginBtn: document.getElementById("loginBtn"),
authMethodSelect: document.getElementById("authMethodSelect"),
otpWrap: document.getElementById("otpWrap"),
@@ -910,7 +911,7 @@ async function refreshFrontendOnResume() {
async function requestAccess() {
clearMessages("auth");
const email = els.email.value.trim();
const email = composeLoginEmail();
if (!isLoginEmailAllowed(email)) {
renderMessage(els.authMessage, `Nur Club-Mailadressen (${formatAllowedDomainsHint()}) sind zum Anmelden moeglich.`, true);
return;
@@ -950,11 +951,12 @@ async function requestAccess() {
async function verifyOtpCode() {
clearMessages("auth");
const email = composeLoginEmail();
try {
const result = await api("/v1/auth/verify-email", {
method: "POST",
body: {
email: els.email.value.trim(),
email,
code: els.otpCode.value.trim()
},
authRequired: false
@@ -997,6 +999,41 @@ function isLoginEmailAllowed(email) {
return getAllowedLoginDomains().includes(domain);
}
function composeLoginEmail() {
const callsign = String(els.callsignInput && els.callsignInput.value ? els.callsignInput.value : "")
.trim()
.toLowerCase();
const selectedDomain = String(
els.emailDomainSelect && els.emailDomainSelect.value
? els.emailDomainSelect.value
: getAllowedLoginDomains()[0] || ""
)
.trim()
.toLowerCase();
if (!callsign || !selectedDomain) {
return "";
}
if (callsign.includes("@")) {
return callsign;
}
return `${callsign}@${selectedDomain}`;
}
function splitEmailParts(email) {
const normalized = String(email || "").trim().toLowerCase();
const atIndex = normalized.lastIndexOf("@");
if (atIndex < 0) {
return {
callsign: normalized,
domain: ""
};
}
return {
callsign: normalized.slice(0, atIndex),
domain: normalized.slice(atIndex + 1)
};
}
function getAllowedLoginDomains() {
const list = state && state.system && Array.isArray(state.system.allowedLoginDomains)
? state.system.allowedLoginDomains
@@ -1008,12 +1045,32 @@ function formatAllowedDomainsHint() {
return getAllowedLoginDomains().map((domain) => `@${domain}`).join(" oder ");
}
function renderLoginDomainSelect() {
if (!els.emailDomainSelect) {
return;
}
const domains = getAllowedLoginDomains();
const previous = String(els.emailDomainSelect.value || "").toLowerCase();
els.emailDomainSelect.innerHTML = "";
for (const domain of domains) {
const option = document.createElement("option");
option.value = domain;
option.textContent = domain;
els.emailDomainSelect.appendChild(option);
}
if (previous && domains.includes(previous)) {
els.emailDomainSelect.value = previous;
} else if (domains.length > 0) {
els.emailDomainSelect.value = domains[0];
}
}
async function handleEmailTokenFromUrl() {
const url = new URL(window.location.href);
if (url.searchParams.get("requestApproval") === "1") {
const email = (url.searchParams.get("email") || "").trim();
if (email) {
els.email.value = email;
setLoginEmail(email);
try {
const result = await api("/v1/auth/request-approval", {
method: "POST",
@@ -1066,6 +1123,19 @@ async function handleEmailTokenFromUrl() {
}
}
function setLoginEmail(email) {
const parts = splitEmailParts(email);
if (els.callsignInput) {
els.callsignInput.value = parts.callsign || "";
}
if (els.emailDomainSelect) {
renderLoginDomainSelect();
if (parts.domain && getAllowedLoginDomains().includes(parts.domain)) {
els.emailDomainSelect.value = parts.domain;
}
}
}
async function refreshPublicSystemStatus() {
try {
const result = await api("/v1/public/system", { authRequired: false });
@@ -1085,6 +1155,7 @@ async function refreshPublicSystemStatus() {
allowedLoginDomains: DEFAULT_ALLOWED_LOGIN_DOMAINS.slice()
};
}
renderLoginDomainSelect();
renderMaintenanceBanner();
renderBranding();
}
@@ -4225,7 +4296,8 @@ function updateUserUi() {
setDisabled(els.logoutBtn, !loggedIn);
setDisabled(els.settingsLogoutTopBtn, !loggedIn);
setDisabled(els.userMenuButton, !loggedIn);
setDisabled(els.email, loggedIn);
setDisabled(els.callsignInput, loggedIn);
setDisabled(els.emailDomainSelect, loggedIn);
if (els.userMenuButton) {
els.userMenuButton.textContent = "☰";
els.userMenuButton.setAttribute("aria-label", loggedIn ? `Menue (${state.user.email})` : "Menue");