split RMS login email into callsign and domain select
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -59,14 +59,21 @@
|
||||
<section class="view auth-view" id="authView">
|
||||
<article class="card login-card stagger" id="authCard">
|
||||
<h2>Anmeldung</h2>
|
||||
<p class="muted">Anmeldung per ARCG E-Mail-Adresse wird automatisch freigeschalten. Andere Mailadressen brauchen eine manuelle Freischaltung. Du bekommst einen Login- oder Bestaetigungslink.</p>
|
||||
<p class="muted">Bitte Rufzeichen und Club-Domain eingeben. Du bekommst einen Login- oder Bestaetigungslink.</p>
|
||||
<p id="maintenanceBanner" class="message" hidden></p>
|
||||
|
||||
<form id="authForm" class="stack">
|
||||
<label class="field">
|
||||
<span>E-Mail</span>
|
||||
<input id="email" type="email" autocomplete="email" required />
|
||||
</label>
|
||||
<div class="actions" style="align-items: end; gap: 0.6rem; flex-wrap: wrap;">
|
||||
<label class="field" style="flex: 2 1 220px; min-width: 180px; margin: 0;">
|
||||
<span>Rufzeichen</span>
|
||||
<input id="callsignInput" type="text" autocomplete="username" placeholder="oe6abc" required />
|
||||
</label>
|
||||
<span class="muted" aria-hidden="true" style="padding-bottom: 0.5rem;">@</span>
|
||||
<label class="field" style="flex: 1 1 180px; min-width: 160px; margin: 0;">
|
||||
<span>Domain</span>
|
||||
<select id="emailDomainSelect"></select>
|
||||
</label>
|
||||
</div>
|
||||
<label class="field">
|
||||
<span>Bestaetigungsart</span>
|
||||
<select id="authMethodSelect"></select>
|
||||
|
||||
Reference in New Issue
Block a user