fix 2fa modal issues in modern ui #6925
Signed-off-by: si458 <simonsmith5521@gmail.com>
si458 committed
Mar 26, 2025 at 14:54 UTC
fee02a17ff0b5cde2c683ce7f94d474e799a67dc
2 files changed
+18
-18
views/default.handlebars
-1
@@ -12920,7 +12920,6 @@
12920
if (serverinfo.discordUrl) { x += '<div id=d2discordurl style=display:none><br /><a href=' + serverinfo.discordUrl + ' target="_discord">' + "Join this Discord server to receive notifications." + '</a></div>'; }
12921
x += '<div id=d2callmebotinfo style=display:none><br /><a href=https://www.callmebot.com/blog/free-api-signal-send-messages/ target="_callmebot">' + "Signal" + '</a>, <a href=https://www.callmebot.com/blog/free-api-whatsapp-messages/ target="_callmebot">' + "Whatsapp" + '</a>, <a href=https://www.callmebot.com/blog/free-api-facebook-messenger/ target="_callmebot">' + "Facebook" + '</a>, <a href=https://www.callmebot.com/blog/telegram-text-messages/ target="_callmebot">' + "Telegram" + '</a></div>';
12922
x += '<div id=d2pushoverinfo style=display:none><br /><a href=https://pushover.net/ target="_pushover">' + "Information at Pushover.net" + '</a></div>';
12923
- console.log(serverinfo.userMsgNftyUrl);
12923
x += '<div id=d2ntfyinfo style=display:none><br /><a href="' + (serverinfo.userMsgNftyUrl ? serverinfo.userMsgNftyUrl : 'https://ntfy.sh/') + '" target="_ntfy">' + "Free service at ntfy.sh" + '</a></div>';
12924
x += '<div id=d2slackinfo style=display:none><br /><a href=https://api.slack.com/messaging/webhooks target="_slack">' + "Slack Webhook Setup" + '</a></div>';
12925
setDialogMode(2, "Messaging Notifications", 3, account_manageMessagingAdd, x, 'verifyMessaging');
views/default3.handlebars
+18
-17
@@ -3506,7 +3506,7 @@
3506
var secret = message.secret;
3507
if (secret.length == 52) { secret = secret.split(/(.............)/).filter(Boolean).join(' '); }
3508
else if (secret.length == 32) { secret = secret.split(/(....)/).filter(Boolean).join(' '); secret = secret.substring(0, 20) + '<br/>' + secret.substring(20) }
3509
- QH('d2optinfo', '<table style=width:380px><tr><td style=vertical-align:top>' + format("Install" + ' <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" rel="noreferrer noopener" target=_blank>' + "Google Authenticator" + '</a> ' + "or a compatible application and scan the barcode, use <a href=\"{0}\" rel=\"noreferrer noopener\" target=_blank>this link</a> or enter the secret. Then, enter the current 6 digit token below to activate 2-Step login.", message.url) + '<br /><br />' + 'Secret <img src=images/link4.png height=10 width=10 title="' + "Copy Secret to clipboard" + '" style=cursor:pointer onclick=d2CopySecretToClip()>' + '<br /><tt id=d2optsecret secret="' + message.secret + '" style=font-size:12px>' + secret + '</tt><br /><br /></td><td style=width:1px;vertical-align:top><a href="' + message.url + '" rel="noreferrer noopener" target=_blank><div id="qrcode"></div></a></td><tr><td colspan=2 style="text-align:center;border-top:1px solid black"><br />' + "Enter the token here for 2-step login:" + ' <input type=text autocomplete="one-time-code" inputmode="numeric" pattern="[0-9]*" onkeypress="return (event.keyCode == 8) || (event.charCode >= 48 && event.charCode <= 57)" onkeyup=account_addOtpCheck(event) onkeydown=account_addOtpCheck() maxlength=6 id=d2otpauthinput type=text></td></table>');
3509
+ QH('d2optinfo', '<table><tr><td style=vertical-align:top>' + format("Install" + ' <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" rel="noreferrer noopener" target=_blank>' + "Google Authenticator" + '</a> ' + "or a compatible application and scan the barcode, use <a href=\"{0}\" rel=\"noreferrer noopener\" target=_blank>this link</a> or enter the secret. Then, enter the current 6 digit token below to activate 2-Step login.", message.url) + '<br /><br />' + 'Secret <img src=images/link4.png height=10 width=10 title="' + "Copy Secret to clipboard" + '" style=cursor:pointer onclick=d2CopySecretToClip()>' + '<br /><tt id=d2optsecret secret="' + message.secret + '" style=font-size:12px>' + secret + '</tt><br /><br /></td><td style=width:1px;vertical-align:top><a href="' + message.url + '" rel="noreferrer noopener" target=_blank><div id="qrcode"></div></a></td><tr><td colspan=2 style="text-align:center;border-top:1px solid black"><br />' + "Enter the token here for 2-step login:" + ' <input type=text autocomplete="one-time-code" inputmode="numeric" pattern="[0-9]*" onkeypress="return (event.keyCode == 8) || (event.charCode >= 48 && event.charCode <= 57)" onkeyup=account_addOtpCheck(event) onkeydown=account_addOtpCheck() maxlength=6 id=d2otpauthinput type=text></td></table>');
3510
new QRCode(Q('qrcode'), { text: message.url, width: 128, height: 128, colorDark: '#000000', colorLight: '#EEE', correctLevel: QRCode.CorrectLevel.H });
3511
QV('idx_dlgOkButton', true);
3512
QE('idx_dlgOkButton', false);
@@ -3528,7 +3528,7 @@
3528
break;
3529
}
3530
case 'otpauth-getpasswords': {
3531
- if (xxdialogMode) return;
3531
+ if (xxdialogMode == 2 && (xxdialogTag != 'otpauth-manage')) return;
3532
var x = "One time tokens can be used as secondary authentication. Generate a set, print them and keep them in a safe place.";
3533
x += '<div style="border-radius:6px;border: 2px dashed #888;width:100%;margin-top:8px"><div style="padding:8px;font-family:Arial, Helvetica, sans-serif;font-size:20px;font-weight:bold"><table class=selecttext style=width:100%;text-align:center>';
3534
if (message.passwords) {
@@ -3549,13 +3549,15 @@
3549
x += '<tr><td>' + "No Active Tokens";
3550
}
3551
x += '</table></div></div><br />';
3552
- x += '<div>';
3553
- x += '<input type=button value="' + "Generate New Tokens" + '" onclick="account_manageOtp(1);"></input>';
3552
+ x += '<div class="btn-group">';
3553
+ x += '<button type=button class="btn btn-warning" onclick="account_manageOtp(1);">' + "Generate New Tokens" + '</input>';
3554
if (message.passwords != null) {
3555
- x += '<input type=button value="' + "Clear Tokens" + '" onclick="account_manageOtp(2);"></input>';
3556
- x += ' <img src=images/link4.png height=10 width=10 title="' + "Copy valid codes to clipboard" + '" style=cursor:pointer onclick=copyTextToClip2("' + encodeURIComponentEx(clipb) + '")>';
3555
+ x += '<button type=button class="btn btn-danger" onclick="account_manageOtp(2);">' + "Clear Tokens" + '</button></div>';
3556
+ x += ' <i class="fa-regular fa-clipboard" title="' + "Copy valid codes to clipboard" + '" style="cursor:pointer" onclick=copyTextToClip2("' + encodeURIComponentEx(clipb) + '")></i>';
3557
+ } else {
3558
+ x += '</div>'
3559
}
3558
- x += '</div><br />';
3560
+ xxdialogTag = 'otpauth-manage';
3561
setModalContent('xxAddAgent', "Manage Backup Codes", x);
3562
showModal('xxAddAgentModal', 'idx_dlgOkButton');
3563
break;
@@ -3569,7 +3571,7 @@
3571
if (message.keys && message.keys.length > 0) {
3572
for (var i in message.keys) {
3573
var key = message.keys[i], type = (key.type == 2) ? 'OTP' : 'WebAuthn';
3572
- x += start + '<tr style=margin:5px><td style=width:30px><img width=24 height=18 src="images/hardware-key-' + type + '-24.png" style=margin-top:4px><td style=width:250px>' + key.name + '<td><input type=button value="' + "Remove" + '" onclick=account_removehkey(' + key.i + ')></input>' + end;
3574
+ x += start + '<tr style=margin:5px><td style=width:30px><img width=24 height=18 src="images/hardware-key-' + type + '-24.png" style=margin-top:4px><td style=width:250px>' + key.name + '<td style=text-align:right><button type=button class="btn btn-danger" onclick=account_removehkey(' + key.i + ')>' + "Remove" + '</button>' + end;
3575
}
3576
} else {
3577
x += start + '<tr style=text-align:center><td>' + "No Keys Configured" + end;
@@ -3578,12 +3580,13 @@
3580
x += '<div>';
3581
var hkeycount = (typeof userinfo.otphkeys == 'number') ? userinfo.otphkeys : 0;
3582
if ((typeof serverinfo.maxfidokeys != 'number') || (serverinfo.maxfidokeys > hkeycount)) { // Check if we we reached maximum hardware keys
3581
- if ((features & 0x00020000) != 0) { x += '<input id=d2addkey3 type=button value="' + "Add Key" + '" onclick="account_addhkey(3);"></input>'; }
3582
- if ((features & 0x00004000) != 0) { x += '<input id=d2addkey2 type=button value="' + "Add YubiKey® OTP" + '" onclick="account_addhkey(2);"></input>'; }
3583
+ if ((features & 0x00020000) != 0) { x += '<button class="btn btn-primary" id=d2addkey3 type=button onclick="account_addhkey(3);">' + "Add Key" + '</input>'; }
3584
+ if ((features & 0x00004000) != 0) { x += '<button class="btn btn-primary" id=d2addkey2 type=button onclick="account_addhkey(2);">' + "Add YubiKey® OTP" +'</input>'; }
3585
} else {
3586
x += "Maximum keys reached.";
3587
}
3588
x += '</div><br />';
3589
+ xxdialogTag = 'otpauth-hardware-manage';
3590
setModalContent('xxAddAgent', "Manage Security Keys", x);
3591
showModal('xxAddAgentModal', 'idx_dlgOkButton');
3592
if (u2fSupported() == false) { QE('d2addkey1', false); }
@@ -3619,7 +3622,6 @@
3622
navigator.credentials.create({ publicKey: publicKey }).then(function (newCredentialInfo) {
3623
// Public key credential
3624
meshserver.send({ action: 'webauthn-endregister', response: { rawId: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.rawId))), response: { attestationObject: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.response.attestationObject))), clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.response.clientDataJSON))) }, type: newCredentialInfo.type } });
3622
- setDialogMode(0);
3625
}, function (error) {
3626
// Error
3627
console.log("ERROR: " + error);
@@ -13764,12 +13766,11 @@
13766
if (serverinfo.discordUrl) { x += '<div id=d2discordurl style=display:none><br /><a href=' + serverinfo.discordUrl + ' target="_discord">' + "Join this Discord server to receive notifications." + '</a></div>'; }
13767
x += '<div id=d2callmebotinfo style=display:none><br /><a href=https://www.callmebot.com/blog/free-api-signal-send-messages/ target="_callmebot">' + "Signal" + '</a>, <a href=https://www.callmebot.com/blog/free-api-whatsapp-messages/ target="_callmebot">' + "Whatsapp" + '</a>, <a href=https://www.callmebot.com/blog/free-api-facebook-messenger/ target="_callmebot">' + "Facebook" + '</a>, <a href=https://www.callmebot.com/blog/telegram-text-messages/ target="_callmebot">' + "Telegram" + '</a></div>';
13768
x += '<div id=d2pushoverinfo style=display:none><br /><a href=https://pushover.net/ target="_pushover">' + "Information at Pushover.net" + '</a></div>';
13767
- console.log(serverinfo.userMsgNftyUrl);
13769
x += '<div id=d2ntfyinfo style=display:none><br /><a href="' + (serverinfo.userMsgNftyUrl ? serverinfo.userMsgNftyUrl : 'https://ntfy.sh/') + '" target="_ntfy">' + "Free service at ntfy.sh" + '</a></div>';
13770
x += '<div id=d2slackinfo style=display:none><br /><a href=https://api.slack.com/messaging/webhooks target="_slack">' + "Slack Webhook Setup" + '</a></div>';
13771
xxdialogTag = 'VerifyMessaging';
13772
setModalContent('xxAddAgent', "Messaging Notifications", x);
13772
- showModal('xxAddAgentModal', 'idx_dlgOkButton', account_manageMessagingAdd());
13773
+ showModal('xxAddAgentModal', 'idx_dlgOkButton', () => account_manageMessagingAdd());
13774
Q('d2handleinput').focus();
13775
account_manageMessagingValidate();
13776
}
@@ -13791,7 +13792,7 @@
13792
else { Q('d2handleinput')['placeholder'] = "Username"; }
13793
var ok = (Q('d2handleinput').value.length > 0); QE('idx_dlgOkButton', ok); if ((x == 1) && ok) { dialogclose(1); }
13794
}
13794
- function account_manageMessagingAdd() { if (Q('d2handleinput').value.length == 0) return; QE('d2handleinput', false); meshserver.send({ action: 'verifyMessaging', service: Q('d2serviceselect').value, handle: Q('d2handleinput').value }); }
13795
+ function account_manageMessagingAdd() { if (Q('d2handleinput').value.length == 0) return; QE('d2handleinput', false); meshserver.send({ action: 'verifyMessaging', service: Q('d2serviceselect').value, handle: Q('d2handleinput').value }); return false; }
13796
function account_manageMessagingConfirm(b, tag) { meshserver.send({ action: 'confirmMessaging', code: Q('d2phoneCodeInput').value, cookie: tag }); }
13797
function account_manageMessagingRemove() { if (Q('d2delPhone').checked) { meshserver.send({ action: 'removeMessaging' }); } }
13798
@@ -13835,7 +13836,7 @@
13836
if (xxdialogMode || (userinfo.otpsecret == 1) || ((features & 4096) == 0)) return;
13837
xxdialogTag = 'otpauth-request';
13838
setModalContent('xxAddAgent', "Authenticator App", ('<div id=d2optinfo>' + "Loading..." + '</div>'));
13838
- showModal('xxAddAgentModal', 'idx_dlgOkButton', function () { meshserver.send({ action: 'otpauth-setup', secret: Q('d2optsecret').attributes.secret.value, token: Q('d2otpauthinput').value }); });
13839
+ showModal('xxAddAgentModal', 'idx_dlgOkButton', function () { meshserver.send({ action: 'otpauth-setup', secret: Q('d2optsecret').attributes.secret.value, token: Q('d2otpauthinput').value }); return false; });
13840
meshserver.send({ action: 'otpauth-request' });
13841
}
13842
@@ -13852,8 +13853,7 @@
13853
}
13854
13855
function account_manageOtp(action) {
13855
- if ((xxdialogMode == 2) && (xxdialogTag == 'otpauth-manage')) { dialogclose(0); }
13856
- if (xxdialogMode || ((features & 4096) == 0)) return false;
13856
+ if ((features & 4096) == 0) return false;
13857
if (count2factoraAuths() > 0) { meshserver.send({ action: 'otpauth-getpasswords', subaction: action }); }
13858
return false;
13859
}
@@ -13921,6 +13921,7 @@
13921
showModal('xxAddAgentModal', 'idx_dlgOkButton');
13922
} else if (type == 3) {
13923
meshserver.send({ action: 'webauthn-startregister', name: name });
13924
+ return false;
13925
}
13926
}
13927