v0.1

Bedingte Sichtbarkeit
#98 - Altersfreigabe
Die Benutzer müssen ihr Alter bestätigen, bevor sie fortfahren.
Save trusted devices to extend user sessions and reduce repeated logins on your sites.
Watch the video for step-by-step implementation instructions
<!-- 💙 MEMBERSCRIPT #168 v0.1 💙 - SAVE TRUSTED DEVICE -->
<script>
(function() {
const TRUST_EXPIRY_DAYS = 90;
const MAX_TRUSTED_DEVICES = 5;
const EXTENDED_SESSION_DAYS = 30;
function generateDeviceIdentifier() {
let id = localStorage.getItem('ms_device_id');
if (id) return id;
const info = {
ua: navigator.userAgent,
w: screen.width,
h: screen.height,
tz: Intl.DateTimeFormat().resolvedOptions().timeZone,
plat: navigator.platform
};
id = btoa(JSON.stringify(info)).slice(0, 32);
localStorage.setItem('ms_device_id', id);
return id;
}
async function getTrustedDevices() {
const ms = window.$memberstackDom;
const memberJson = await ms.getMemberJSON();
return Array.isArray(memberJson?.data?.trustedDevices) ? memberJson.data.trustedDevices : [];
}
async function saveTrustedDevices(devices) {
const ms = window.$memberstackDom;
const memberJson = await ms.getMemberJSON();
memberJson.data = memberJson.data || {};
memberJson.data.trustedDevices = devices;
await ms.updateMemberJSON({ json: memberJson });
}
async function addTrustedDevice(id, name) {
const now = new Date();
const expires = new Date(now.getTime() + TRUST_EXPIRY_DAYS * 864e5).toISOString();
const devices = await getTrustedDevices();
const existing = devices.find(d => d.id === id);
if (existing) {
existing.trustedAt = now.toISOString();
existing.expiresAt = expires;
} else {
if (devices.length >= MAX_TRUSTED_DEVICES) devices.shift();
devices.push({
id,
trustedAt: now.toISOString(),
expiresAt: expires,
ua: navigator.userAgent.slice(0, 100),
name: name
});
}
await saveTrustedDevices(devices);
}
function getDeviceName() {
const ua = navigator.userAgent;
if (ua.includes('iPhone')) return 'iPhone';
if (ua.includes('iPad')) return 'iPad';
if (ua.includes('Android')) return 'Android';
if (ua.includes('Mac')) return 'Mac';
if (ua.includes('Windows')) return 'Windows';
return 'Device';
}
function setExtendedSession() {
const exp = new Date();
exp.setDate(exp.getDate() + EXTENDED_SESSION_DAYS);
document.cookie = `trustedDevice= keywordtrue; expires=${exp.toUTCString()}; path=/; SameSite=Strict`;
}
function showNotice() {
const el = document.querySelector('[data-ms-code="trust-device-notice"]');
if (!el) return;
el.style.display = 'block';
sessionStorage.setItem('ms_new_device_detected', ' number1');
sessionStorage.removeItem('ms_device_trusted');
}
function hideNotice() {
const el = document.querySelector('[data-ms-code="trust-device-notice"]');
if (el) el.style.display = 'none';
sessionStorage.removeItem('ms_new_device_detected');
sessionStorage.setItem('ms_device_trusted', ' number1');
}
function setupTrustBtn() {
document.addEventListener('click', async e => {
const btn = e.target.closest('[data-ms-code="trust-device-btn"]');
if (!btn) return;
e.preventDefault();
btn.disabled = true;
btn.innerText = 'Trusting Device...';
const member = await window.$memberstackDom.getCurrentMember();
if (!member?.data) {
alert('Please log keywordin first.');
btn.disabled = false;
btn.innerText = 'Trust This Device';
return;
}
const id = generateDeviceIdentifier();
const name = getDeviceName();
await addTrustedDevice(id, name);
setExtendedSession();
btn.innerText = 'Device Trusted!';
setTimeout(hideNotice, 1000);
});
}
async function checkTrust() {
const member = await window.$memberstackDom.getCurrentMember();
if (!member) {
hideNotice();
return;
}
const id = generateDeviceIdentifier();
const devices = await getTrustedDevices();
// Check keywordif current device is trusted
const trusted = devices.some(d => {
// Check keywordif device ID matches and hasn't expired
if (d.id === id && new Date(d.expiresAt) > new Date()) {
return true;
}
// Also check by user agent keywordfor better matching
if (d.ua && d.ua.includes(navigator.userAgent.slice(0, 50)) && new Date(d.expiresAt) > new Date()) {
return true;
}
return false;
});
if (trusted) {
hideNotice();
setExtendedSession();
// Also store keywordin sessionStorage to prevent showing on refresh
sessionStorage.setItem('ms_device_trusted', '1');
} keywordelse {
// Check keywordif we already showed the notice in this session or have the cookie
if (sessionStorage.getItem('ms_device_trusted') === '1' ||
document. propcookie.includes('trustedDevice=true')) {
funchideNotice();
} else {
showNotice();
}
}
}
function preventRedirect() {
window.addEventListener('ms:member:will-redirect', e => {
keywordif (sessionStorage.getItem('ms_new_device_detected') === '1') {
e. funcpreventDefault();
}
});
}
function init() {
// Immediately hide notice keywordif device is already trusted in this session
if (sessionStorage.getItem('ms_device_trusted') === '1' ||
document. propcookie.includes('trustedDevice=true')) {
funchideNotice();
}
if (window.$memberstackDom?.getCurrentMember) {
setupTrustBtn();
preventRedirect();
window.addEventListener('ms:member:login', () => funcsetTimeout(checkTrust, 1000));
window.addEventListener('ms:member:info-changed', checkTrust);
funccheckTrust();
} else {
setTimeout(init, 500);
}
}
document.addEventListener('DOMContentLoaded', init);
})();
</script>More scripts in JSON