Login Block
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Ich frage jetzt mal Tante Chat ...
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
ChatGPT hat es in 7 Sekunden erkannt - warte ...
Bei mir habe ich es schon online
Bei mir habe ich es schon online
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Hier der neue Code für den HTML-Block der Passwort-Änderung. Das Passwort wird am Auge erst sichtbar, wenn es tatsächlich neu eingetragen wurde.
Der wichtigste Unterschied ist diese Änderung.
Es war so:
Jetzt ist es im Code oben so (ersetze aber bitte den gesamten HTML-Code mit dem oben:
Code: Alles auswählen
<section data-bs-version="5.1" class="vn-changepass" group="Content" plugins="vn-login" data-endpoint="assets/vn-login/login.php" data-login-url="{{loginUrl}}" style="
--vl-bg: {{bgColor}};
--vl-card: {{cardColor}};
--vl-accent: {{accentColor}};
--vl-text: {{textColor}};
--vl-sub: {{subtextColor}};
--vl-input-bg: {{inputBgColor}};
--vl-border: {{borderColor}};
--vl-pt: {{paddingTop}}rem;
--vl-pb: {{paddingBottom}}rem;
--vl-radius: {{cardRadius}}px;
">
<mbr-parameters>
<header>URLs</header>
<input type="text" title="Login-Seite (URL)" name="loginUrl" value="Login-Members.html">
<header>Size</header>
<input type="checkbox" title="Full Width" name="fullWidth">
<input type="range" inline title="Top" name="paddingTop" min="0" max="12" step="1" value="4">
<input type="range" inline title="Bottom" name="paddingBottom" min="0" max="12" step="1" value="2">
<header>Farben</header>
<input type="color" title="Hintergrund" value="#000000" name="bgColor" selected>
<input type="color" title="Karte" value="#1a1a1a" name="cardColor" selected>
<input type="color" title="Akzent" value="#1d9e75" name="accentColor" selected>
<input type="color" title="Text" value="#ffffff" name="textColor" selected>
<input type="color" title="Subtext" value="#888888" name="subtextColor" selected>
<input type="color" title="Input Hintergrund" value="#111111" name="inputBgColor" selected>
<input type="color" title="Rahmen" value="#2a2a2a" name="borderColor" selected>
<header>Design</header>
<input type="range" inline title="Eckenrundung (px)" name="cardRadius" min="0" max="24" step="2" value="16">
</mbr-parameters>
<div mbr-class="{'container': !fullWidth, 'container-fluid': fullWidth}">
<div class="vl-wrap">
<div class="vl-header">
<div class="vl-logo">🔑</div>
<h2 class="vl-title mbr-fonts-style" mbr-text data-app-selector=".vl-title" mbr-theme-style="display-2">Passwort ändern</h2>
<p class="vl-subtitle mbr-fonts-style" mbr-text data-app-selector=".vl-subtitle" mbr-theme-style="display-7">Gib dein aktuelles und neues Passwort ein.</p>
</div>
<div class="vl-form" autocomplete="off">
<!--
Verstecktes Username-Feld nur für interne Anzeige/Zuordnung.
Wichtig: kein autocomplete="username", damit Browser hier nicht automatisch Passwortdaten koppelt.
-->
<input type="text" id="vcp-username" name="vcp-user-display" autocomplete="off" style="position:absolute;left:-9999px;top:-9999px;width:1px;height:1px;opacity:0;" tabindex="-1" readonly>
<div class="vcp-user-info" id="vcp-user-info" style="display:none;">
<span class="vcp-user-label">Eingeloggt als:</span>
<span class="vcp-user-name" id="vcp-user-name">–</span>
</div>
<div class="vl-field">
<label class="vl-label" for="vcp-old">Aktuelles Passwort</label>
<div class="vl-pw-wrap">
<input type="password" id="vcp-old" class="vl-input" placeholder="••••••••" autocomplete="off" readonly>
<button type="button" class="vl-pw-toggle" onclick="vcpToggle('vcp-old')">👁</button>
</div>
</div>
<div class="vl-field">
<label class="vl-label" for="vcp-new">Neues Passwort</label>
<div class="vl-pw-wrap">
<input type="password" id="vcp-new" class="vl-input" placeholder="min. 6 Zeichen" autocomplete="new-password">
<button type="button" class="vl-pw-toggle" onclick="vcpToggle('vcp-new')">👁</button>
</div>
</div>
<div class="vl-field">
<label class="vl-label" for="vcp-new2">Neues Passwort bestätigen</label>
<input type="password" id="vcp-new2" class="vl-input" placeholder="Passwort wiederholen" autocomplete="new-password">
</div>
<div class="vl-error" id="vcp-error" style="display:none"></div>
<div class="vcp-success" id="vcp-success" style="display:none"></div>
<button type="button" class="vl-btn" id="vcp-btn" onclick="vcpSave()">
<span id="vcp-btn-text">Passwort speichern</span>
</button>
</div>
</div>
</div>
<script>
(function () {
var sec = document.querySelector('section.vn-changepass');
if (!sec) return;
var endpoint = (sec.dataset.endpoint || 'assets/vn-login/login.php').trim();
/*
* Merker: Beim aktuellen Passwort darf das Auge nur dann anzeigen,
* wenn der Benutzer wirklich selbst etwas eingetippt hat.
* Browser-Autofill soll nicht sichtbar gemacht werden.
*/
var oldPasswordTouched = false;
function clearOldPasswordField() {
var old = document.getElementById('vcp-old');
if (!old) return;
old.value = '';
old.type = 'password';
oldPasswordTouched = false;
}
window.vcpToggle = function(id) {
var el = document.getElementById(id);
if (!el) return;
/*
* Sonderregel für "Aktuelles Passwort":
* Wenn der Browser heimlich etwas eingefüllt hat, aber der Benutzer
* noch nicht selbst getippt hat, wird nichts sichtbar gemacht.
*/
if (id === 'vcp-old' && !oldPasswordTouched) {
el.type = 'password';
el.value = '';
return;
}
if (!el.value) {
el.type = 'password';
return;
}
el.type = el.type === 'password' ? 'text' : 'password';
};
function showError(msg) {
var e = document.getElementById('vcp-error');
var s = document.getElementById('vcp-success');
if (s) s.style.display = 'none';
if (e) {
e.textContent = msg;
e.style.display = 'block';
}
}
function showSuccess(msg) {
var e = document.getElementById('vcp-error');
var s = document.getElementById('vcp-success');
if (e) e.style.display = 'none';
if (s) {
s.textContent = msg;
s.style.display = 'block';
}
['vcp-old', 'vcp-new', 'vcp-new2'].forEach(function(id) {
var el = document.getElementById(id);
if (el) {
el.value = '';
el.type = 'password';
}
});
oldPasswordTouched = false;
}
function setLoading(on) {
var btn = document.getElementById('vcp-btn');
var txt = document.getElementById('vcp-btn-text');
if (btn) btn.disabled = on;
if (txt) txt.textContent = on ? '⟳ Bitte warten…' : 'Passwort speichern';
}
/*
* Aktuelles Passwortfeld zunächst readonly halten.
* Das reduziert Browser-Autofill deutlich.
* Beim echten Fokus durch den Benutzer wird readonly entfernt.
*/
var oldPwInput = document.getElementById('vcp-old');
if (oldPwInput) {
oldPwInput.value = '';
oldPwInput.type = 'password';
oldPwInput.setAttribute('readonly', 'readonly');
oldPwInput.addEventListener('focus', function() {
oldPwInput.removeAttribute('readonly');
/*
* Falls der Browser genau beim Fokus doch etwas einfüllt,
* wird das Feld sofort wieder geleert.
*/
if (!oldPasswordTouched) {
window.setTimeout(function() {
if (!oldPasswordTouched) {
oldPwInput.value = '';
oldPwInput.type = 'password';
}
}, 50);
}
});
oldPwInput.addEventListener('input', function() {
oldPasswordTouched = true;
});
oldPwInput.addEventListener('blur', function() {
if (!oldPwInput.value) {
oldPasswordTouched = false;
oldPwInput.type = 'password';
oldPwInput.setAttribute('readonly', 'readonly');
}
});
}
/*
* Browser-Autofill nach dem Laden mehrfach neutralisieren.
* Manche Browser füllen erst verzögert ein.
*/
clearOldPasswordField();
window.setTimeout(clearOldPasswordField, 100);
window.setTimeout(clearOldPasswordField, 500);
window.setTimeout(clearOldPasswordField, 1200);
// Login-Status prüfen und Benutzer anzeigen
fetch(endpoint + '?action=check')
.then(function(r) {
return r.json();
})
.then(function(d) {
var uInput = document.getElementById('vcp-username');
var uInfo = document.getElementById('vcp-user-info');
var uName = document.getElementById('vcp-user-name');
if (d.user) {
if (uInput) uInput.value = d.user;
if (uName) uName.textContent = d.user;
if (uInfo) uInfo.style.display = 'flex';
}
/*
* Nach dem Setzen des Usernamens nochmals leeren,
* weil manche Browser dann erst Autofill auslösen.
*/
clearOldPasswordField();
window.setTimeout(clearOldPasswordField, 100);
window.setTimeout(clearOldPasswordField, 500);
// Nicht eingeloggt → weiterleiten
if (!d.loggedIn) {
var loginUrl = (sec && sec.dataset.loginUrl) ? sec.dataset.loginUrl : 'login.html';
if (loginUrl.indexOf('{{') === -1) {
window.location.href = loginUrl;
}
}
})
.catch(function() {
clearOldPasswordField();
});
window.vcpSave = function() {
var oldEl = document.getElementById('vcp-old');
var newEl = document.getElementById('vcp-new');
var new2El = document.getElementById('vcp-new2');
var old = oldEl ? (oldEl.value || '') : '';
var nw = newEl ? (newEl.value || '') : '';
var nw2 = new2El ? (new2El.value || '') : '';
if (!old || !nw || !nw2) {
showError('Bitte alle Felder ausfüllen.');
return;
}
if (nw.length < 6) {
showError('Neues Passwort mind. 6 Zeichen.');
return;
}
if (nw !== nw2) {
showError('Passwörter stimmen nicht überein.');
return;
}
setLoading(true);
var fd = new FormData();
fd.append('action', 'changepass');
fd.append('oldpassword', old);
fd.append('newpassword', nw);
fetch(endpoint, {
method: 'POST',
body: fd
})
.then(function(r) {
return r.json();
})
.then(function(d) {
setLoading(false);
if (d.success) {
showSuccess('✓ ' + (d.message || 'Passwort erfolgreich geändert!'));
} else {
showError(d.message || 'Fehler beim Ändern.');
}
})
.catch(function() {
setLoading(false);
showError('Verbindungsfehler.');
});
};
['vcp-old', 'vcp-new', 'vcp-new2'].forEach(function(id) {
var el = document.getElementById(id);
if (el) {
el.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
vcpSave();
}
});
}
});
})();
</script>
</section>
Der wichtigste Unterschied ist diese Änderung.
Es war so:
Code: Alles auswählen
<input type="password" id="vcp-old" class="vl-input" placeholder="••••••••" autocomplete="current-password">Code: Alles auswählen
<input type="password" id="vcp-old" class="vl-input" placeholder="••••••••" autocomplete="off" readonly>- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Dann schiebe das bitte nochmals alles neu in den Download-Ordner, damit ich das morgen erneut einbauen und nochmals angucken kann, ob dann hier auch alles passt.
Re: Login Block
Tommy jetzt werd ich nicht mehr,
hab das claude gegeben also deinen code soll die mir schnell einbauen. hier ihre Antwort:

hab das claude gegeben also deinen code soll die mir schnell einbauen. hier ihre Antwort:
Jetzt DUDas ist Tommys verbesserte Version mit dem super Autofill-Schutz! Ich ersetze das komplette Template:
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Ich habe da nur das autocomplete geändert (ausgeschaltet) - teste es auf meiner Seite - das geht so bestens.
Das ist doch nur ein neuer HTML-Code vom Block, den Du schell tauschen kannst. Passe auf, dass die KI jetzt nicht wieder andere Stellen zerschießt!
Sorry - mir fällt da noch eine Kleinigkeit auf, die man vielleicht präziser in der Anleitung beschreiben sollte, siehe auch meine Änderungen im Code:
Das ist doch nur ein neuer HTML-Code vom Block, den Du schell tauschen kannst. Passe auf, dass die KI jetzt nicht wieder andere Stellen zerschießt!
Sorry - mir fällt da noch eine Kleinigkeit auf, die man vielleicht präziser in der Anleitung beschreiben sollte, siehe auch meine Änderungen im Code:
Anleitung zum VN-Login hat geschrieben:
PHP-Session-Schutz eintragen
Seiteneigenschaften → „Vor <DOCTYPE>" → diesen Code einfügen. Bitte weder vor noch nach dem Code Leerzeichen lassen, da dies den Browser in den "Quirks-Modus" schalten kann und es dann keinen validen DOCTYPE gibt:
Code: Alles auswählen
<?php session_start(); if (empty($_SESSION['vn_login_user'])) { header('Location: login.html'); // ← Pfad und Name deiner Login-Seite! exit; } ?>
Re: Login Block
Ist nun im Download Tommy
https://www.niederastroth.de/00login/vn ... itung.html
Anleitung auch ergänzt
https://www.niederastroth.de/00login/vn ... itung.html
Anleitung auch ergänzt
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Computer ist aus.
Ich mache das morgen am späten Vormittag. Falls Dir noch was einfällt, nur zu
Ich mache das morgen am späten Vormittag. Falls Dir noch was einfällt, nur zu
Re: Login Block
Tommys verbesserte Version ist drin! Die wichtigsten Verbesserungen:
readonly Trick – Feld startet readonly, wird erst beim echten Fokus des Users editierbar
clearOldPasswordField() – wird 4x aufgerufen (0ms, 100ms, 500ms, 1200ms) damit auch verzögertes Browser-Autofill erwischt wird
Auge-Button – zeigt nur wenn der User wirklich selbst getippt hat (oldPasswordTouched)
autocomplete="off" statt current-password am alten Passwort-Feld
Nach dem check()-Call nochmals leeren falls Browser dann erst befüllt
Danke Tommy für den schlauen Code!
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Ich werde noch als "Ki-Flüsterer" in die Geschichte eingehen
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Moin,
also alles jetzt prima - eine schöne und sichere Anwendung um beliebig viele Seiten eines Projektes zu schützen. Die integrierte Benutzerverwaltung macht diese Anwendung modern und praktisch
Das Häkchen nach der Passwort-Änderung ist immer noch doppelt, das doppelte Häkchen entsteht hier:
Die login.php liefert bereits diese Meldung zurück! Das muss also im JavaScript der Block-HTML raus. Hier nochmals die gesamte korrigierte und getestete HTML. Das solltest Du vielleicht noch ändern, ohne das ich das dann erneut teste, bei mir ist es bereits korrigiert eingebaut.
Meine Beispielseite:
https://www.mobirise-tutorials.com/VN-B ... mbers.html
Am besten den Code unten zur Korrektur einbauen.
Bitte löscht vor dem Import eines Updates dieser oder einer anderen PHP-Anwendung von Volker Niederastroth (VN) alle Komponenten innerhalb der Software, einschließlich der Blöcke, sowie auf dem Rechner das zugehörige Erweiterungsverzeichnis und auf dem Server das Verzeichnis /assets/vn-login/, damit eine fehlerfreie Neuinstallation möglich ist.
Bitte veröffentlicht in diesem Fall einmalig alles und deaktiviert dazu die Option „Nur Änderungen veröffentlichen“.
also alles jetzt prima - eine schöne und sichere Anwendung um beliebig viele Seiten eines Projektes zu schützen. Die integrierte Benutzerverwaltung macht diese Anwendung modern und praktisch
Das Häkchen nach der Passwort-Änderung ist immer noch doppelt, das doppelte Häkchen entsteht hier:
Code: Alles auswählen
showSuccess('✓ ' + (d.message || 'Passwort erfolgreich geändert!'));Meine Beispielseite:
Am besten den Code unten zur Korrektur einbauen.
Code: Alles auswählen
<section data-bs-version="5.1" class="vn-changepass" group="Content" plugins="vn-login" data-endpoint="assets/vn-login/login.php" data-login-url="{{loginUrl}}" style="
--vl-bg: {{bgColor}};
--vl-card: {{cardColor}};
--vl-accent: {{accentColor}};
--vl-text: {{textColor}};
--vl-sub: {{subtextColor}};
--vl-input-bg: {{inputBgColor}};
--vl-border: {{borderColor}};
--vl-pt: {{paddingTop}}rem;
--vl-pb: {{paddingBottom}}rem;
--vl-radius: {{cardRadius}}px;
">
<mbr-parameters>
<header>URLs</header>
<input type="text" title="Login-Seite (URL)" name="loginUrl" value="Login-Members.html">
<header>Size</header>
<input type="checkbox" title="Full Width" name="fullWidth">
<input type="range" inline title="Top" name="paddingTop" min="0" max="12" step="1" value="4">
<input type="range" inline title="Bottom" name="paddingBottom" min="0" max="12" step="1" value="4">
<header>Farben</header>
<input type="color" title="Hintergrund" value="#000000" name="bgColor" selected>
<input type="color" title="Karte" value="#1a1a1a" name="cardColor" selected>
<input type="color" title="Akzent" value="#1d9e75" name="accentColor" selected>
<input type="color" title="Text" value="#ffffff" name="textColor" selected>
<input type="color" title="Subtext" value="#888888" name="subtextColor" selected>
<input type="color" title="Input Hintergrund" value="#111111" name="inputBgColor" selected>
<input type="color" title="Rahmen" value="#2a2a2a" name="borderColor" selected>
<header>Design</header>
<input type="range" inline title="Eckenrundung (px)" name="cardRadius" min="0" max="24" step="2" value="16">
</mbr-parameters>
<div mbr-class="{'container': !fullWidth, 'container-fluid': fullWidth}">
<div class="vl-wrap">
<div class="vl-header">
<div class="vl-logo">🔑</div>
<h2 class="vl-title mbr-fonts-style" mbr-text data-app-selector=".vl-title" mbr-theme-style="display-2">Passwort ändern</h2>
<p class="vl-subtitle mbr-fonts-style" mbr-text data-app-selector=".vl-subtitle" mbr-theme-style="display-7">Gib dein aktuelles und neues Passwort ein.</p>
</div>
<div class="vl-form" autocomplete="off">
<input type="text" id="vcp-username" name="vcp-user-display" autocomplete="off" style="position:absolute;left:-9999px;top:-9999px;width:1px;height:1px;opacity:0;" tabindex="-1" readonly>
<div class="vcp-user-info" id="vcp-user-info" style="display:none;">
<span class="vcp-user-label">Eingeloggt als:</span>
<span class="vcp-user-name" id="vcp-user-name">–</span>
</div>
<div class="vl-field">
<label class="vl-label" for="vcp-old">Aktuelles Passwort</label>
<div class="vl-pw-wrap">
<input type="password" id="vcp-old" class="vl-input" placeholder="••••••••" autocomplete="off" readonly>
<button type="button" class="vl-pw-toggle" onclick="vcpToggle('vcp-old')">👁</button>
</div>
</div>
<div class="vl-field">
<label class="vl-label" for="vcp-new">Neues Passwort</label>
<div class="vl-pw-wrap">
<input type="password" id="vcp-new" class="vl-input" placeholder="min. 6 Zeichen" autocomplete="new-password">
<button type="button" class="vl-pw-toggle" onclick="vcpToggle('vcp-new')">👁</button>
</div>
</div>
<div class="vl-field">
<label class="vl-label" for="vcp-new2">Neues Passwort bestätigen</label>
<input type="password" id="vcp-new2" class="vl-input" placeholder="Passwort wiederholen" autocomplete="new-password">
</div>
<div class="vl-error" id="vcp-error" style="display:none"></div>
<div class="vcp-success" id="vcp-success" style="display:none"></div>
<button type="button" class="vl-btn" id="vcp-btn" onclick="vcpSave()">
<span id="vcp-btn-text">Passwort speichern</span>
</button>
</div>
</div>
</div>
<script>
(function () {
var sec = document.querySelector('section.vn-changepass');
if (!sec) return;
var endpoint = (sec.dataset.endpoint || 'assets/vn-login/login.php').trim();
var oldPasswordTouched = false;
function clearOldPasswordField() {
var old = document.getElementById('vcp-old');
if (!old) return;
old.value = '';
old.type = 'password';
oldPasswordTouched = false;
}
window.vcpToggle = function(id) {
var el = document.getElementById(id);
if (!el) return;
if (id === 'vcp-old' && !oldPasswordTouched) {
el.type = 'password';
el.value = '';
return;
}
if (!el.value) { el.type = 'password'; return; }
el.type = el.type === 'password' ? 'text' : 'password';
};
function showError(msg) {
var e = document.getElementById('vcp-error');
var s = document.getElementById('vcp-success');
if (s) s.style.display = 'none';
if (e) { e.textContent = msg; e.style.display = 'block'; }
}
function showSuccess(msg) {
var e = document.getElementById('vcp-error');
var s = document.getElementById('vcp-success');
if (e) e.style.display = 'none';
if (s) { s.textContent = msg; s.style.display = 'block'; }
['vcp-old','vcp-new','vcp-new2'].forEach(function(id) {
var el = document.getElementById(id);
if (el) { el.value = ''; el.type = 'password'; }
});
oldPasswordTouched = false;
}
function setLoading(on) {
var btn = document.getElementById('vcp-btn');
var txt = document.getElementById('vcp-btn-text');
if (btn) btn.disabled = on;
if (txt) txt.textContent = on ? '⟳ Bitte warten…' : 'Passwort speichern';
}
var oldPwInput = document.getElementById('vcp-old');
if (oldPwInput) {
oldPwInput.value = '';
oldPwInput.type = 'password';
oldPwInput.setAttribute('readonly', 'readonly');
oldPwInput.addEventListener('focus', function() {
oldPwInput.removeAttribute('readonly');
if (!oldPasswordTouched) {
window.setTimeout(function() {
if (!oldPasswordTouched) {
oldPwInput.value = '';
oldPwInput.type = 'password';
}
}, 50);
}
});
oldPwInput.addEventListener('input', function() { oldPasswordTouched = true; });
oldPwInput.addEventListener('blur', function() {
if (!oldPwInput.value) {
oldPasswordTouched = false;
oldPwInput.type = 'password';
oldPwInput.setAttribute('readonly', 'readonly');
}
});
}
clearOldPasswordField();
window.setTimeout(clearOldPasswordField, 100);
window.setTimeout(clearOldPasswordField, 500);
window.setTimeout(clearOldPasswordField, 1200);
fetch(endpoint + '?action=check')
.then(function(r) { return r.json(); })
.then(function(d) {
var uInput = document.getElementById('vcp-username');
var uInfo = document.getElementById('vcp-user-info');
var uName = document.getElementById('vcp-user-name');
if (d.user) {
if (uInput) uInput.value = d.user;
if (uName) uName.textContent = d.user;
if (uInfo) uInfo.style.display = 'flex';
}
clearOldPasswordField();
window.setTimeout(clearOldPasswordField, 100);
window.setTimeout(clearOldPasswordField, 500);
if (!d.loggedIn) {
var loginUrl = (sec && sec.dataset.loginUrl) ? sec.dataset.loginUrl : 'login.html';
if (loginUrl.indexOf('{{') === -1) window.location.href = loginUrl;
}
})
.catch(function() { clearOldPasswordField(); });
window.vcpSave = function() {
var oldEl = document.getElementById('vcp-old');
var newEl = document.getElementById('vcp-new');
var new2El = document.getElementById('vcp-new2');
var old = oldEl ? (oldEl.value || '') : '';
var nw = newEl ? (newEl.value || '') : '';
var nw2 = new2El ? (new2El.value || '') : '';
if (!old || !nw || !nw2) { showError('Bitte alle Felder ausfüllen.'); return; }
if (nw.length < 6) { showError('Neues Passwort mind. 6 Zeichen.'); return; }
if (nw !== nw2) { showError('Passwörter stimmen nicht überein.'); return; }
setLoading(true);
var fd = new FormData();
fd.append('action', 'changepass');
fd.append('oldpassword', old);
fd.append('newpassword', nw);
fetch(endpoint, { method: 'POST', body: fd })
.then(function(r) { return r.json(); })
.then(function(d) {
setLoading(false);
if (d.success) showSuccess(d.message || '✓ Passwort erfolgreich geändert!');
else showError(d.message || 'Fehler beim Ändern.');
})
.catch(function() { setLoading(false); showError('Verbindungsfehler.'); });
};
['vcp-old','vcp-new','vcp-new2'].forEach(function(id) {
var el = document.getElementById(id);
if (el) el.addEventListener('keypress', function(e) { if (e.key === 'Enter') vcpSave(); });
});
})();
</script>
</section>
Bitte löscht vor dem Import eines Updates dieser oder einer anderen PHP-Anwendung von Volker Niederastroth (VN) alle Komponenten innerhalb der Software, einschließlich der Blöcke, sowie auf dem Rechner das zugehörige Erweiterungsverzeichnis und auf dem Server das Verzeichnis /assets/vn-login/, damit eine fehlerfreie Neuinstallation möglich ist.
Bitte veröffentlicht in diesem Fall einmalig alles und deaktiviert dazu die Option „Nur Änderungen veröffentlichen“.
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Moin,
wozu hast Du da eigentlich noch das E-Mail Feld in der JSON vom "VN Login"?
Ich habe bei mir jetzt die Änderung zwar noch stehen aber unterbunden. Ich kann diese nur durch ein "true" wieder aktivieren. Nur falls Du das auch brauchen kannst.
wozu hast Du da eigentlich noch das E-Mail Feld in der JSON vom "VN Login"?
Code: Alles auswählen
"Tester": {
"password": "$2y$12$m23iNa77jupzuyK\/.xAZMeW0s712VkO3X\/g\/13XJO1SFgWi4Yn0LS",
"email": "",
"status": "active",
"created": "2026-07-06 05:49:47"
}Re: Login Block
Es war ursprünglich als Vorbereitung für ein „Passwort vergessen" Feature gedach ist halt noch drin 
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Moin Volker,
willst Du die Passwort-Änderung nicht auf Deiner Demo-Seite auch lieber sperren?
Schließlich kann bei Dir jeder das Benutzerpasswort ändern, ohne dass Du es bemerkst. Dann kann kein interessierter Besucher mehr nachsehen — vielleicht wochen- oder monatelang, bis Du es zufällig entdeckst. Wahrscheinlich würdest Du es aber nie merken
Wahrscheinlich würde es dir dann auch niemand mitteilen, sondern denken: „Das funktioniert nicht.“
Zum scharf schalten einfach den Demo-Mode in Zeile 95 auf "false" setzen:
Hier das gesamte angepassste Script zur Passwort-Änderung mit oder ohne Demo-Mode:
willst Du die Passwort-Änderung nicht auf Deiner Demo-Seite auch lieber sperren?
Schließlich kann bei Dir jeder das Benutzerpasswort ändern, ohne dass Du es bemerkst. Dann kann kein interessierter Besucher mehr nachsehen — vielleicht wochen- oder monatelang, bis Du es zufällig entdeckst. Wahrscheinlich würdest Du es aber nie merken
Wahrscheinlich würde es dir dann auch niemand mitteilen, sondern denken: „Das funktioniert nicht.“
Zum scharf schalten einfach den Demo-Mode in Zeile 95 auf "false" setzen:
Code: Alles auswählen
var DEMO_MODE = true;Code: Alles auswählen
<section data-bs-version="5.1" class="vn-changepass" group="Content" plugins="vn-login" data-endpoint="assets/vn-login/login.php" data-login-url="{{loginUrl}}" style="
--vl-bg: {{bgColor}};
--vl-card: {{cardColor}};
--vl-accent: {{accentColor}};
--vl-text: {{textColor}};
--vl-sub: {{subtextColor}};
--vl-input-bg: {{inputBgColor}};
--vl-border: {{borderColor}};
--vl-pt: {{paddingTop}}rem;
--vl-pb: {{paddingBottom}}rem;
--vl-radius: {{cardRadius}}px;
">
<mbr-parameters>
<header>URLs</header>
<input type="text" title="Login-Seite (URL)" name="loginUrl" value="Login-Members.html">
<header>Size</header>
<input type="checkbox" title="Full Width" name="fullWidth">
<input type="range" inline title="Top" name="paddingTop" min="0" max="12" step="1" value="4">
<input type="range" inline title="Bottom" name="paddingBottom" min="0" max="12" step="1" value="4">
<header>Farben</header>
<input type="color" title="Hintergrund" value="#000000" name="bgColor" selected>
<input type="color" title="Karte" value="#232323" name="cardColor" selected>
<input type="color" title="Akzent" value="#e43f3f" name="accentColor" selected>
<input type="color" title="Text" value="#ffffff" name="textColor" selected>
<input type="color" title="Subtext" value="#888888" name="subtextColor" selected>
<input type="color" title="Input Hintergrund" value="#2b2a2a" name="inputBgColor" selected>
<input type="color" title="Rahmen" value="#2a2a2a" name="borderColor" selected>
<header>Design</header>
<input type="range" inline title="Eckenrundung (px)" name="cardRadius" min="0" max="24" step="2" value="16">
</mbr-parameters>
<div mbr-class="{'container': !fullWidth, 'container-fluid': fullWidth}">
<div class="vl-wrap">
<div class="vl-header">
<div class="vl-logo">🔑</div>
<h2 class="vl-title mbr-fonts-style" mbr-text data-app-selector=".vl-title" mbr-theme-style="display-2">Passwort ändern</h2>
<p class="vl-subtitle mbr-fonts-style" mbr-text data-app-selector=".vl-subtitle" mbr-theme-style="display-7">Gib dein aktuelles und neues Passwort ein.</p>
</div>
<div class="vl-form" autocomplete="off">
<input type="text" id="vcp-username" name="vcp-user-display" autocomplete="off" style="position:absolute;left:-9999px;top:-9999px;width:1px;height:1px;opacity:0;" tabindex="-1" readonly>
<div class="vcp-user-info" id="vcp-user-info" style="display:none;">
<span class="vcp-user-label">Eingeloggt als:</span>
<span class="vcp-user-name" id="vcp-user-name">–</span>
</div>
<div class="vl-field">
<label class="vl-label" for="vcp-old">Aktuelles Passwort</label>
<div class="vl-pw-wrap">
<input type="password" id="vcp-old" class="vl-input" placeholder="••••••••" autocomplete="off" readonly>
<button type="button" class="vl-pw-toggle" onclick="vcpToggle('vcp-old')">👁</button>
</div>
</div>
<div class="vl-field">
<label class="vl-label" for="vcp-new">Neues Passwort</label>
<div class="vl-pw-wrap">
<input type="password" id="vcp-new" class="vl-input" placeholder="min. 6 Zeichen" autocomplete="new-password">
<button type="button" class="vl-pw-toggle" onclick="vcpToggle('vcp-new')">👁</button>
</div>
</div>
<div class="vl-field">
<label class="vl-label" for="vcp-new2">Neues Passwort bestätigen</label>
<input type="password" id="vcp-new2" class="vl-input" placeholder="Passwort wiederholen" autocomplete="new-password">
</div>
<!-- Demo-Hinweis: wird nur bei DEMO_MODE = true per JavaScript sichtbar geschaltet -->
<div class="vl-error" id="vcp-error" style="display:none;color:#ff3333;font-weight:bold;"></div>
<div class="vcp-success" id="vcp-success" style="display:none"></div>
<button type="button" class="vl-btn" id="vcp-btn" onclick="vcpSave()">
<span id="vcp-btn-text">Passwort speichern</span>
</button>
</div>
</div>
</div>
<script>
(function () {
var sec = document.querySelector('section.vn-changepass');
if (!sec) return;
var endpoint = (sec.dataset.endpoint || 'assets/vn-login/login.php').trim();
/*
* DEMO-MODUS:
* true = Passwortänderung ist gesperrt
* false = ursprüngliche Passwortänderung wieder aktiv
*/
var DEMO_MODE = true;
var oldPasswordTouched = false;
function clearOldPasswordField() {
var old = document.getElementById('vcp-old');
if (!old) return;
old.value = '';
old.type = 'password';
oldPasswordTouched = false;
}
window.vcpToggle = function(id) {
var el = document.getElementById(id);
if (!el) return;
if (id === 'vcp-old' && !oldPasswordTouched) {
el.type = 'password';
el.value = '';
return;
}
if (!el.value) { el.type = 'password'; return; }
el.type = el.type === 'password' ? 'text' : 'password';
};
function showError(msg) {
var e = document.getElementById('vcp-error');
var s = document.getElementById('vcp-success');
if (s) s.style.display = 'none';
if (e) {
e.textContent = msg;
e.style.display = 'block';
e.style.color = '#ff3333';
e.style.fontWeight = 'bold';
}
}
function hideError() {
var e = document.getElementById('vcp-error');
if (e) {
e.textContent = '';
e.style.display = 'none';
}
}
function showSuccess(msg) {
var e = document.getElementById('vcp-error');
var s = document.getElementById('vcp-success');
if (e) e.style.display = 'none';
if (s) { s.textContent = msg; s.style.display = 'block'; }
['vcp-old','vcp-new','vcp-new2'].forEach(function(id) {
var el = document.getElementById(id);
if (el) { el.value = ''; el.type = 'password'; }
});
oldPasswordTouched = false;
}
function setLoading(on) {
var btn = document.getElementById('vcp-btn');
var txt = document.getElementById('vcp-btn-text');
if (btn) btn.disabled = on;
if (txt) txt.textContent = on ? '⟳ Bitte warten…' : 'Passwort speichern';
}
/*
* Demo-Hinweis nur dann sofort anzeigen,
* wenn der Demo-Modus tatsächlich aktiv ist.
*/
if (DEMO_MODE) {
showError('Änderung in Demo nicht möglich');
} else {
hideError();
}
var oldPwInput = document.getElementById('vcp-old');
if (oldPwInput) {
oldPwInput.value = '';
oldPwInput.type = 'password';
oldPwInput.setAttribute('readonly', 'readonly');
oldPwInput.addEventListener('focus', function() {
oldPwInput.removeAttribute('readonly');
if (!oldPasswordTouched) {
window.setTimeout(function() {
if (!oldPasswordTouched) {
oldPwInput.value = '';
oldPwInput.type = 'password';
}
}, 50);
}
});
oldPwInput.addEventListener('input', function() { oldPasswordTouched = true; });
oldPwInput.addEventListener('blur', function() {
if (!oldPwInput.value) {
oldPasswordTouched = false;
oldPwInput.type = 'password';
oldPwInput.setAttribute('readonly', 'readonly');
}
});
}
clearOldPasswordField();
window.setTimeout(clearOldPasswordField, 100);
window.setTimeout(clearOldPasswordField, 500);
window.setTimeout(clearOldPasswordField, 1200);
fetch(endpoint + '?action=check')
.then(function(r) { return r.json(); })
.then(function(d) {
var uInput = document.getElementById('vcp-username');
var uInfo = document.getElementById('vcp-user-info');
var uName = document.getElementById('vcp-user-name');
if (d.user) {
if (uInput) uInput.value = d.user;
if (uName) uName.textContent = d.user;
if (uInfo) uInfo.style.display = 'flex';
}
clearOldPasswordField();
window.setTimeout(clearOldPasswordField, 100);
window.setTimeout(clearOldPasswordField, 500);
if (!d.loggedIn) {
var loginUrl = (sec && sec.dataset.loginUrl) ? sec.dataset.loginUrl : 'login.html';
if (loginUrl.indexOf('{{') === -1) window.location.href = loginUrl;
}
})
.catch(function() { clearOldPasswordField(); });
window.vcpSave = function() {
/*
* DEMO-SPERRE:
* In dieser Demo wird keine Anfrage an login.php?action=changepass gesendet.
* Dadurch kann der öffentliche Tester-Account nicht verändert werden.
*/
if (DEMO_MODE) {
showError('Änderung in Demo nicht möglich');
return;
}
/*
* URSPRÜNGLICHE VERSION:
* Zum Scharfschalten oben DEMO_MODE auf false setzen.
*/
var oldEl = document.getElementById('vcp-old');
var newEl = document.getElementById('vcp-new');
var new2El = document.getElementById('vcp-new2');
var old = oldEl ? (oldEl.value || '') : '';
var nw = newEl ? (newEl.value || '') : '';
var nw2 = new2El ? (new2El.value || '') : '';
if (!old || !nw || !nw2) { showError('Bitte alle Felder ausfüllen.'); return; }
if (nw.length < 6) { showError('Neues Passwort mind. 6 Zeichen.'); return; }
if (nw !== nw2) { showError('Passwörter stimmen nicht überein.'); return; }
setLoading(true);
var fd = new FormData();
fd.append('action', 'changepass');
fd.append('oldpassword', old);
fd.append('newpassword', nw);
fetch(endpoint, { method: 'POST', body: fd })
.then(function(r) { return r.json(); })
.then(function(d) {
setLoading(false);
if (d.success) showSuccess(d.message || '✓ Passwort erfolgreich geändert!');
else showError(d.message || 'Fehler beim Ändern.');
})
.catch(function() { setLoading(false); showError('Verbindungsfehler.'); });
};
['vcp-old','vcp-new','vcp-new2'].forEach(function(id) {
var el = document.getElementById(id);
if (el) el.addEventListener('keypress', function(e) { if (e.key === 'Enter') vcpSave(); });
});
})();
</script>
</section>
Re: Login Block
Moin Tommy,
Demo Mode ist eine nette Idee
Aber ich gucke da schon täglich rein, solange das da online ist
Ich überarbeite gerade meine Seite, die wird kleiner und übersichtlicher - da fliegen ganz viele Seiten raus jetzt.
Also ich lass das mal so stehen, wenn einer meint mein Login würde nicht funktionieren dann soll er das von mir aus denken
Will eh keiner haben wegen der Kosten
Ich hab es gebaut - klappt - fertig
Baue gerade noch andere nette Dinge - ob ich die veröffentliche weiß ich noch gar nicht.
Demo Mode ist eine nette Idee
Aber ich gucke da schon täglich rein, solange das da online ist
Ich überarbeite gerade meine Seite, die wird kleiner und übersichtlicher - da fliegen ganz viele Seiten raus jetzt.
Also ich lass das mal so stehen, wenn einer meint mein Login würde nicht funktionieren dann soll er das von mir aus denken
Baue gerade noch andere nette Dinge - ob ich die veröffentliche weiß ich noch gar nicht.
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Na ja - bei mir habe ich das jetzt so eingebaut (denn ich vergesse das spätestens wenn ich mich mit etwas Neuem beschäftige) und auch die CSS für das "Auge" und die Platzhaltertexte geändert. Die sind an meinem Laptop nämlich nicht zu sehen - ich weiß Deiner ist anders kalibriert.
Die Anwendung würde sicherlich von vielen Menschen genutzt werden – vorausgesetzt, man findet sie bei dir und du würdest etwas Werbung dafür machen. Allein das Forum reicht kaum aus; es hilft zwar, darf aber nicht die einzige Werbemaßnahme sein.
Ein weiteres Problem ist, dass du die Suchmaschinenoptimierung vernachlässigst: Es fehlen viele Einträge und es gibt kaum Texte, sodass die Website bei Google nur schwer auffindbar sein wird.
Na zumindest kommt meine alte Seite, die ganz ähnlich aufgebaut ist und auch einen Link zu der neuen Seite hat bei Google ganz oben beim Suchbegriff:
"Mobirise Mitglieder Bereich"
Die Anwendung würde sicherlich von vielen Menschen genutzt werden – vorausgesetzt, man findet sie bei dir und du würdest etwas Werbung dafür machen. Allein das Forum reicht kaum aus; es hilft zwar, darf aber nicht die einzige Werbemaßnahme sein.
Ein weiteres Problem ist, dass du die Suchmaschinenoptimierung vernachlässigst: Es fehlen viele Einträge und es gibt kaum Texte, sodass die Website bei Google nur schwer auffindbar sein wird.
Na zumindest kommt meine alte Seite, die ganz ähnlich aufgebaut ist und auch einen Link zu der neuen Seite hat bei Google ganz oben beim Suchbegriff:
"Mobirise Mitglieder Bereich"
Re: Login Block
Tommy
Ich will nix bewerben oder verkaufen.
Das sind doch alles Erweiterungen speziell hier für Foren Mitglieder - die im Hersteller Forum verpassen ja jetzt meine neuen Blöcke
Mir ist das doch wuppe ob Google die findet oder sonst wer. Ich bau die, weil ich es kann
Hab jetzt meinen Live Chat in einen Block gepackt - cool. Admin panel einfach per Link aufrufen. Wird nicht veröffentlicht. Ich wollte das hin bekommen - hab ich.
Jetzt bau ich ( nur für Frank) die Galerie noch um, das Effekte für die Bilder und HG Farbe einstellbar ist.
Ich will nix bewerben oder verkaufen.
Das sind doch alles Erweiterungen speziell hier für Foren Mitglieder - die im Hersteller Forum verpassen ja jetzt meine neuen Blöcke
Mir ist das doch wuppe ob Google die findet oder sonst wer. Ich bau die, weil ich es kann
Hab jetzt meinen Live Chat in einen Block gepackt - cool. Admin panel einfach per Link aufrufen. Wird nicht veröffentlicht. Ich wollte das hin bekommen - hab ich.
Jetzt bau ich ( nur für Frank) die Galerie noch um, das Effekte für die Bilder und HG Farbe einstellbar ist.
- Tommy Herrmann
- Site Admin

- Beiträge: 9127
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Login Block
Also ich interessiere mich sehr für deine Blöcke, obwohl ich wahrscheinlich der Einzige bin, der sie wirklich nicht braucht, da ich das nur als Hobby betreibe 
Glaub bloß nicht, dass hier niemand aus dem anderen Forum mitliest — alle schauen zu, besonders diejenigen, die über mich schimpfen.
Immerhin habe ich über zwei Millionen eindeutige Besucher im Jahr; auch wenn die meisten davon Bots sind, bleiben trotzdem viele echte Besucher übrig, darunter zahlreiche aus dem Herstellerforum. Rate mal, warum unser Forum bei fast allen Google-Suchen noch vor dem Herstellerforum gelistet wird.
Da können dann auch schon mal nur in einem Monat (wie im Mai) über 500.000 Besucher dabei sein und die wollen alle Deine Anwendungen
Auch ganz interessant wo die Besucher herkommen - nur dieser laufende Monat - jedenfalls nicht vom Herstellerforum - das finde ich auch in den vielen anderen Statistiken fast nicht - weil die da behaupten ich würde da nur User abgreifen - zumal ich eigentlich fast nie einen Link zu meinem Forum dort poste - lächerlich ist das:
Hier kann man auch gut sehen wie wichtig die Handys sind - die Betriebssysteme der letzten 4 Wochen:
Ich benutze das Hersteller-Forum als Marketing-Werkzeug
wie zum Beispiel dieses nette Mitglied hier schreibt:
https://forums.mobirise.com/discussion/ ... ent_126169
Dabei habe ich nur Volker verteidigt, der dort in Deutsch geschrieben hatte und bemerkt, dass man in meinem Forum in jeder Sprache schreiben darf.
Glaub bloß nicht, dass hier niemand aus dem anderen Forum mitliest — alle schauen zu, besonders diejenigen, die über mich schimpfen.
Immerhin habe ich über zwei Millionen eindeutige Besucher im Jahr; auch wenn die meisten davon Bots sind, bleiben trotzdem viele echte Besucher übrig, darunter zahlreiche aus dem Herstellerforum. Rate mal, warum unser Forum bei fast allen Google-Suchen noch vor dem Herstellerforum gelistet wird.
Da können dann auch schon mal nur in einem Monat (wie im Mai) über 500.000 Besucher dabei sein und die wollen alle Deine Anwendungen
Auch ganz interessant wo die Besucher herkommen - nur dieser laufende Monat - jedenfalls nicht vom Herstellerforum - das finde ich auch in den vielen anderen Statistiken fast nicht - weil die da behaupten ich würde da nur User abgreifen - zumal ich eigentlich fast nie einen Link zu meinem Forum dort poste - lächerlich ist das:
Hier kann man auch gut sehen wie wichtig die Handys sind - die Betriebssysteme der letzten 4 Wochen:
Ich benutze das Hersteller-Forum als Marketing-Werkzeug
https://forums.mobirise.com/discussion/ ... ent_126169
Dabei habe ich nur Volker verteidigt, der dort in Deutsch geschrieben hatte und bemerkt, dass man in meinem Forum in jeder Sprache schreiben darf.
1. Juli 2026 Strettonbull an Tommy Herrmann
Also, this isn't about your forum, it's about this one. I'm not interested in your forum at all and it's obvious you are using this forum as a marketing tool to promote your own forum.
>>> auf Deutsch:
Außerdem geht es hier nicht um dein Forum, sondern um dieses hier. Dein Forum interessiert mich überhaupt nicht, und es ist offensichtlich, dass du dieses Forum als Marketinginstrument nutzt, um für dein eigenes Forum zu werben.
Re: Login Block
Tommy !!!!
Du sollt dich doch nicht aufregen
Alles total gechillt
Du sollt dich doch nicht aufregen
Alles total gechillt
Wer ist online?
Mitglieder in diesem Forum: Amazon [Bot] und 5 Gäste
