mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-01-14 16:24:59 -05:00
Fixed account password reset when used with 2FA accounts.
This commit is contained in:
parent
09ad47b412
commit
ca22ac0d3b
6
db.js
6
db.js
@ -1012,8 +1012,8 @@ module.exports.CreateDB = function (parent, func) {
|
|||||||
};
|
};
|
||||||
obj.GetAllType = function (type, func) { obj.file.find({ type: type }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetAllType = function (type, func) { obj.file.find({ type: type }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetAllIdsOfType = function (ids, domain, type, func) { obj.file.find({ type: type, domain: domain, _id: { $in: ids } }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetAllIdsOfType = function (ids, domain, type, func) { obj.file.find({ type: type, domain: domain, _id: { $in: ids } }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }).project({ type: 0 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetUserWithVerifiedEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email, emailVerified: true }).project({ type: 0 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetUserWithVerifiedEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email, emailVerified: true }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.Remove = function (id, func) { obj.file.deleteOne({ _id: id }, func); };
|
obj.Remove = function (id, func) { obj.file.deleteOne({ _id: id }, func); };
|
||||||
obj.RemoveAll = function (func) { obj.file.deleteMany({}, { multi: true }, func); };
|
obj.RemoveAll = function (func) { obj.file.deleteMany({}, { multi: true }, func); };
|
||||||
obj.RemoveAllOfType = function (type, func) { obj.file.deleteMany({ type: type }, { multi: true }, func); };
|
obj.RemoveAllOfType = function (type, func) { obj.file.deleteMany({ type: type }, { multi: true }, func); };
|
||||||
@ -1166,7 +1166,7 @@ module.exports.CreateDB = function (parent, func) {
|
|||||||
obj.GetAllType = function (type, func) { obj.file.find({ type: type }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetAllType = function (type, func) { obj.file.find({ type: type }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetAllIdsOfType = function (ids, domain, type, func) { obj.file.find({ type: type, domain: domain, _id: { $in: ids } }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetAllIdsOfType = function (ids, domain, type, func) { obj.file.find({ type: type, domain: domain, _id: { $in: ids } }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }, { type: 0 }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }, { type: 0 }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetUserWithVerifiedEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email, emailVerified: true }, { type: 0 }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetUserWithVerifiedEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email, emailVerified: true }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.Remove = function (id, func) { obj.file.remove({ _id: id }, func); };
|
obj.Remove = function (id, func) { obj.file.remove({ _id: id }, func); };
|
||||||
obj.RemoveAll = function (func) { obj.file.remove({}, { multi: true }, func); };
|
obj.RemoveAll = function (func) { obj.file.remove({}, { multi: true }, func); };
|
||||||
obj.RemoveAllOfType = function (type, func) { obj.file.remove({ type: type }, { multi: true }, func); };
|
obj.RemoveAllOfType = function (type, func) { obj.file.remove({ type: type }, { multi: true }, func); };
|
||||||
|
@ -13546,11 +13546,13 @@
|
|||||||
"login-mobile.handlebars->5->42",
|
"login-mobile.handlebars->5->42",
|
||||||
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->4->1->3",
|
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->4->1->3",
|
||||||
"login.handlebars->5->43",
|
"login.handlebars->5->43",
|
||||||
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->resettokenpanel->1->5->1->2->1->3",
|
||||||
"login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->4->1->3",
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->4->1->3",
|
||||||
"login2.handlebars->7->22",
|
"login2.handlebars->7->22",
|
||||||
"login2.handlebars->7->44",
|
"login2.handlebars->7->44",
|
||||||
"login2.handlebars->centralTable->1->0->logincell->resetpanel->1->7->1->0->1",
|
"login2.handlebars->centralTable->1->0->logincell->resetpanel->1->7->1->0->1",
|
||||||
"login2.handlebars->centralTable->1->0->logincell->resetpanel->1->7->1->0->1",
|
"login2.handlebars->centralTable->1->0->logincell->resetpanel->1->7->1->0->1",
|
||||||
|
"login2.handlebars->centralTable->1->0->logincell->resettokenpanel->1->5->1->2farow2->1->3",
|
||||||
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->2farow->1->3"
|
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->2farow->1->3"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -21235,6 +21237,7 @@
|
|||||||
"login.handlebars->container->column_l->centralTable->1->0->logincell->loginpanel->1->5->1",
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->loginpanel->1->5->1",
|
||||||
"login.handlebars->container->column_l->centralTable->1->0->logincell->loginpanel->1->7->1->4->3",
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->loginpanel->1->7->1->4->3",
|
||||||
"login2.handlebars->centralTable->1->0->logincell->loginpanel->1->5->1->6->1",
|
"login2.handlebars->centralTable->1->0->logincell->loginpanel->1->5->1->6->1",
|
||||||
|
"login2.handlebars->centralTable->1->0->logincell->resettokenpanel->1->5->1->2->1->1",
|
||||||
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->2->1->1"
|
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->2->1->1"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -21300,8 +21303,7 @@
|
|||||||
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->resettokenpanel->1->5->1->2->1->1",
|
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->resettokenpanel->1->5->1->2->1->1",
|
||||||
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->4->1->1",
|
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->4->1->1",
|
||||||
"login.handlebars->container->column_l->centralTable->1->0->logincell->resettokenpanel->1->5->1->2->1->1",
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->resettokenpanel->1->5->1->2->1->1",
|
||||||
"login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->4->1->1",
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->4->1->1"
|
||||||
"login2.handlebars->centralTable->1->0->logincell->resettokenpanel->1->5->1->2->1->1"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -21388,8 +21390,7 @@
|
|||||||
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->resettokenpanel->1->5->1->0->1",
|
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->resettokenpanel->1->5->1->0->1",
|
||||||
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->0->1",
|
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->0->1",
|
||||||
"login.handlebars->container->column_l->centralTable->1->0->logincell->resettokenpanel->1->5->1->0->1",
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->resettokenpanel->1->5->1->0->1",
|
||||||
"login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->0->1",
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->0->1"
|
||||||
"login2.handlebars->centralTable->1->0->logincell->resettokenpanel->1->5->1->0->1"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -30335,7 +30336,9 @@
|
|||||||
"default.handlebars->27->1905",
|
"default.handlebars->27->1905",
|
||||||
"default.handlebars->27->1910",
|
"default.handlebars->27->1910",
|
||||||
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->4->1->3",
|
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->4->1->3",
|
||||||
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->resettokenpanel->1->5->1->2->1->3",
|
||||||
"login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->4->1->3",
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->4->1->3",
|
||||||
|
"login2.handlebars->centralTable->1->0->logincell->resettokenpanel->1->5->1->2farow2->1->3",
|
||||||
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->2farow->1->3"
|
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->2farow->1->3"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -36193,6 +36196,8 @@
|
|||||||
"zh-chs": "代币",
|
"zh-chs": "代币",
|
||||||
"zh-cht": "代幣",
|
"zh-cht": "代幣",
|
||||||
"xloc": [
|
"xloc": [
|
||||||
|
"login2.handlebars->centralTable->1->0->logincell->resettokenpanel->1->5->1->0->1",
|
||||||
|
"login2.handlebars->centralTable->1->0->logincell->resettokenpanel->1->5->1->0->1",
|
||||||
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->0->1",
|
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->0->1",
|
||||||
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->0->1"
|
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->0->1"
|
||||||
]
|
]
|
||||||
@ -37429,7 +37434,9 @@
|
|||||||
"zh-cht": "使用安全密鑰",
|
"zh-cht": "使用安全密鑰",
|
||||||
"xloc": [
|
"xloc": [
|
||||||
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->4->1->3",
|
"login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->4->1->3",
|
||||||
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->resettokenpanel->1->5->1->2->1->3",
|
||||||
"login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->4->1->3",
|
"login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->4->1->3",
|
||||||
|
"login2.handlebars->centralTable->1->0->logincell->resettokenpanel->1->5->1->2farow2->1->3",
|
||||||
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->2farow->1->3"
|
"login2.handlebars->centralTable->1->0->logincell->tokenpanel->1->7->1->2farow->1->3"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -161,7 +161,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td align=right width=100>Login token:</td>
|
<td align=right width=100>Login token:</td>
|
||||||
<td>
|
<td>
|
||||||
<input id=tokenInput autocomplete="one-time-code" inputmode="numeric" type=text name=token maxlength=50 onchange=checkToken(event) onpaste=resetCheckToken(event) onkeyup=checkToken(event) onkeydown=checkToken(event) /><br />
|
<input id=tokenInput autocomplete="one-time-code" inputmode="numeric" type=text name=token maxlength=50 onchange=checkToken(event) onpaste=checkToken(event) onkeyup=checkToken(event) onkeydown=checkToken(event) /><br />
|
||||||
<input id=hwtokenInput type=text name=hwtoken style="display:none" />
|
<input id=hwtokenInput type=text name=hwtoken style="display:none" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -174,9 +174,9 @@
|
|||||||
<td colspan=2>
|
<td colspan=2>
|
||||||
<div style=float:right><input id=tokenOkButton type=submit value="Login" disabled="disabled" /></div>
|
<div style=float:right><input id=tokenOkButton type=submit value="Login" disabled="disabled" /></div>
|
||||||
<div style=float:right>
|
<div style=float:right>
|
||||||
<input style="display:none;float:right" id=securityKeyButton type=button value="Use Security Key" onclick="useSecurityKey()" />
|
<input style="display:none;float:right" id=securityKeyButton type=button value="Use Security Key" onclick="useSecurityKey(1)" />
|
||||||
<input style="display:none;float:right" id=emailKeyButton type=button value="Email" onclick="useEmailToken()" />
|
<input style="display:none;float:right" id=emailKeyButton type=button value="Email" onclick="useEmailToken(1)" />
|
||||||
<input style="display:none;float:right" id=smsKeyButton type=button value="SMS" onclick="useSMSToken()" />
|
<input style="display:none;float:right" id=smsKeyButton type=button value="SMS" onclick="useSMSToken(1)" />
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -200,6 +200,11 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td colspan=2>
|
<td colspan=2>
|
||||||
<div style=float:right><input id=resetTokenOkButton type=submit value="Login" disabled="disabled" /></div>
|
<div style=float:right><input id=resetTokenOkButton type=submit value="Login" disabled="disabled" /></div>
|
||||||
|
<div style=float:right>
|
||||||
|
<input style="display:none;float:right" id=securityKeyButton2 type=button value="Use Security Key" onclick="useSecurityKey(2)" />
|
||||||
|
<input style="display:none;float:right" id=emailKeyButton2 type=button value="Email" onclick="useEmailToken(2)" />
|
||||||
|
<input style="display:none;float:right" id=smsKeyButton2 type=button value="SMS" onclick="useSMSToken(2)" />
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -422,6 +427,14 @@
|
|||||||
QV('smsKeyButton', otpsms && (messageid != 2) && (messageid != 4));
|
QV('smsKeyButton', otpsms && (messageid != 2) && (messageid != 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loginMode == '5') {
|
||||||
|
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||||
|
QV('securityKeyButton2', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||||
|
QV('emailKeyButton2', otpemail && (messageid != 2) && (messageid != 4));
|
||||||
|
QV('smsKeyButton2', otpsms && (messageid != 2) && (messageid != 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (loginMode == '5') {
|
if (loginMode == '5') {
|
||||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||||
@ -452,13 +465,14 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Setup the user interface in the right mode
|
// Setup the user interface in the right mode
|
||||||
userInterfaceSelectMenu();
|
userInterfaceSelectMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a hardware security key
|
// Use a hardware security key
|
||||||
function useSecurityKey() {
|
function useSecurityKey(panelAction) {
|
||||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||||
|
|
||||||
@ -479,35 +493,53 @@
|
|||||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||||
};
|
};
|
||||||
|
if (panelAction == 1) {
|
||||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||||
QE('tokenOkButton', true);
|
QE('tokenOkButton', true);
|
||||||
Q('tokenOkButton').click();
|
Q('tokenOkButton').click();
|
||||||
|
} else if (panelAction == 2) {
|
||||||
|
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||||
|
QE('resetTokenOkButton', true);
|
||||||
|
Q('resetTokenOkButton').click();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
function (error) { console.log('credentials-get error', error); }
|
function (error) { console.log('credentials-get error', error); }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function useEmailToken() {
|
function useEmailToken(panelAction) {
|
||||||
if (otpemail != true) return;
|
if (otpemail != true) return;
|
||||||
setDialogMode(1, "Secure Login", 3, useEmailKeyEx, "Send token to registered email address?");
|
setDialogMode(1, "Secure Login", 3, useEmailKeyEx, "Send token to registered email address?", panelAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
function useEmailKeyEx() {
|
function useEmailKeyEx(b, panelAction) {
|
||||||
|
if (panelAction == 1) {
|
||||||
Q('hwtokenInput').value = '**email**';
|
Q('hwtokenInput').value = '**email**';
|
||||||
QE('tokenOkButton', true);
|
QE('tokenOkButton', true);
|
||||||
Q('tokenOkButton').click();
|
Q('tokenOkButton').click();
|
||||||
|
} else if (panelAction == 2) {
|
||||||
|
Q('resetHwtokenInput').value = '**email**';
|
||||||
|
QE('resetTokenOkButton', true);
|
||||||
|
Q('resetTokenOkButton').click();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function useSMSToken() {
|
function useSMSToken(panelAction) {
|
||||||
if (otpsms != true) return;
|
if (otpsms != true) return;
|
||||||
setDialogMode(1, "Secure Login", 3, useSMSTokenEx, "Send token to registered phone number?");
|
setDialogMode(1, "Secure Login", 3, useSMSTokenEx, "Send token to registered phone number?", panelAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
function useSMSTokenEx() {
|
function useSMSTokenEx(b, panelAction) {
|
||||||
|
if (panelAction == 1) {
|
||||||
Q('hwtokenInput').value = '**sms**';
|
Q('hwtokenInput').value = '**sms**';
|
||||||
QE('tokenOkButton', true);
|
QE('tokenOkButton', true);
|
||||||
Q('tokenOkButton').click();
|
Q('tokenOkButton').click();
|
||||||
|
} else if (panelAction == 2) {
|
||||||
|
Q('resetHwtokenInput').value = '**sms**';
|
||||||
|
QE('resetTokenOkButton', true);
|
||||||
|
Q('resetTokenOkButton').click();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPassHint(e) {
|
function showPassHint(e) {
|
||||||
|
@ -180,9 +180,9 @@
|
|||||||
<td>
|
<td>
|
||||||
<hr />
|
<hr />
|
||||||
<div>
|
<div>
|
||||||
<img id=securityKeyButton src="images/login/2fa-key-48.png" title="Use Security Key" loading="lazy" width="48" height="48" style="display:none;margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer;background-color:#FFF" onclick="useSecurityKey()" />
|
<img id=securityKeyButton src="images/login/2fa-key-48.png" title="Use Security Key" loading="lazy" width="48" height="48" style="display:none;margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer;background-color:#FFF" onclick="useSecurityKey(1)" />
|
||||||
<img id=smsKeyButton src="images/login/2fa-sms-48.png" title="SMS" loading="lazy" width="48" height="48" style="display:none;margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer;background-color:#FFF" onclick="useSMSToken()" />
|
<img id=smsKeyButton src="images/login/2fa-sms-48.png" title="SMS" loading="lazy" width="48" height="48" style="display:none;margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer;background-color:#FFF" onclick="useSMSToken(1)" />
|
||||||
<img id=emailKeyButton src="images/login/2fa-mail-48.png" title="Email" loading="lazy" width="48" height="48" style="display:none;margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer;background-color:#FFF" onclick="useEmailToken()" />
|
<img id=emailKeyButton src="images/login/2fa-mail-48.png" title="Email" loading="lazy" width="48" height="48" style="display:none;margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer;background-color:#FFF" onclick="useEmailToken(1)" />
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -195,17 +195,28 @@
|
|||||||
<form method=post>
|
<form method=post>
|
||||||
<input type=hidden name=action value=resetaccount />
|
<input type=hidden name=action value=resetaccount />
|
||||||
<div id=message5></div>
|
<div id=message5></div>
|
||||||
<table>
|
<table style="width:100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td align=right width=100>Login token:</td>
|
|
||||||
<td>
|
<td>
|
||||||
<input id=resetTokenInput type=text name=token maxlength=50 onchange=resetCheckToken(event) onkeyup=resetCheckToken(event) onkeydown=resetCheckToken(event) />
|
<input id=resetTokenInput autocomplete="one-time-code" title="Token" style="box-sizing:border-box;width:280px;border:0;border-radius:4px;padding:8px;background-color:#FFF8CC" placeholder="Token" type=text maxlength=50 name=token onchange=resetCheckToken(event) onpaste=resetCheckToken(event) onkeyup=resetCheckToken(event) onkeydown=resetCheckToken(event) /><br />
|
||||||
<input id=resetHwtokenInput type=text name=hwtoken style="display:none" />
|
<input id=resetHwtokenInput type=text name=hwtoken style="display:none" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<input id=resetTokenOkButton style="box-sizing:border-box;width:280px;border:0;border-radius:4px;padding:6px" type=submit value="Log In" disabled="disabled" />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="2farow2">
|
||||||
<td colspan=2>
|
<td colspan=2>
|
||||||
<div style=float:right><input id=resetTokenOkButton type=submit value="Login" disabled="disabled" /></div>
|
<hr />
|
||||||
|
<div>
|
||||||
|
<img id=securityKeyButton2 src="images/login/2fa-key-48.png" title="Use Security Key" loading="lazy" width="48" height="48" style="display:none;margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer;background-color:#FFF" onclick="useSecurityKey(2)" />
|
||||||
|
<img id=smsKeyButton2 src="images/login/2fa-sms-48.png" title="SMS" loading="lazy" width="48" height="48" style="display:none;margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer;background-color:#FFF" onclick="useSMSToken(2)" />
|
||||||
|
<img id=emailKeyButton2 src="images/login/2fa-mail-48.png" title="Email" loading="lazy" width="48" height="48" style="display:none;margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer;background-color:#FFF" onclick="useEmailToken(2)" />
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -427,6 +438,18 @@
|
|||||||
QV('2farow', twofakey || emailkey || smskey);
|
QV('2farow', twofakey || emailkey || smskey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loginMode == '5') {
|
||||||
|
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||||
|
var twofakey = (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn');
|
||||||
|
var emailkey = otpemail && (messageid != 2) && (messageid != 4);
|
||||||
|
var smskey = otpsms && (messageid != 2) && (messageid != 4);
|
||||||
|
QV('securityKeyButton2', twofakey);
|
||||||
|
QV('emailKeyButton2', emailkey);
|
||||||
|
QV('smsKeyButton2', smskey);
|
||||||
|
QV('2farow2', twofakey || emailkey || smskey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (loginMode == '5') {
|
if (loginMode == '5') {
|
||||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||||
@ -457,10 +480,11 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a hardware security key
|
// Use a hardware security key
|
||||||
function useSecurityKey() {
|
function useSecurityKey(panelAction) {
|
||||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||||
|
|
||||||
@ -481,35 +505,53 @@
|
|||||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||||
};
|
};
|
||||||
|
if (panelAction == 1) {
|
||||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||||
QE('tokenOkButton', true);
|
QE('tokenOkButton', true);
|
||||||
Q('tokenOkButton').click();
|
Q('tokenOkButton').click();
|
||||||
|
} else if (panelAction == 2) {
|
||||||
|
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||||
|
QE('resetTokenOkButton', true);
|
||||||
|
Q('resetTokenOkButton').click();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
function (error) { console.log('credentials-get error', error); }
|
function (error) { console.log('credentials-get error', error); }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function useEmailToken() {
|
function useEmailToken(panelAction) {
|
||||||
if (otpemail != true) return;
|
if (otpemail != true) return;
|
||||||
setDialogMode(1, "Secure Login", 3, useEmailKeyEx, "Send token to registered email address?");
|
setDialogMode(1, "Secure Login", 3, useEmailKeyEx, "Send token to registered email address?");
|
||||||
}
|
}
|
||||||
|
|
||||||
function useEmailKeyEx() {
|
function useEmailKeyEx(b, panelAction) {
|
||||||
|
if (panelAction == 1) {
|
||||||
Q('hwtokenInput').value = '**email**';
|
Q('hwtokenInput').value = '**email**';
|
||||||
QE('tokenOkButton', true);
|
QE('tokenOkButton', true);
|
||||||
Q('tokenOkButton').click();
|
Q('tokenOkButton').click();
|
||||||
|
} else if (panelAction == 2) {
|
||||||
|
Q('resetHwtokenInput').value = '**email**';
|
||||||
|
QE('resetTokenOkButton', true);
|
||||||
|
Q('resetTokenOkButton').click();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function useSMSToken() {
|
function useSMSToken(panelAction) {
|
||||||
if (otpsms != true) return;
|
if (otpsms != true) return;
|
||||||
setDialogMode(1, "Secure Login", 3, useSMSTokenEx, "Send token to registered phone number?");
|
setDialogMode(1, "Secure Login", 3, useSMSTokenEx, "Send token to registered phone number?");
|
||||||
}
|
}
|
||||||
|
|
||||||
function useSMSTokenEx() {
|
function useSMSTokenEx(b, panelAction) {
|
||||||
|
if (panelAction == 1) {
|
||||||
Q('hwtokenInput').value = '**sms**';
|
Q('hwtokenInput').value = '**sms**';
|
||||||
QE('tokenOkButton', true);
|
QE('tokenOkButton', true);
|
||||||
Q('tokenOkButton').click();
|
Q('tokenOkButton').click();
|
||||||
|
} else if (panelAction == 2) {
|
||||||
|
Q('resetHwtokenInput').value = '**sms**';
|
||||||
|
QE('resetTokenOkButton', true);
|
||||||
|
Q('resetTokenOkButton').click();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPassHint(e) {
|
function showPassHint(e) {
|
||||||
|
@ -2438,7 +2438,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
if (hardwareKeyChallenge) { hwstate = obj.parent.encodeCookie({ u: req.session.tokenusername, p: req.session.tokenpassword, c: req.session.u2fchallenge }, obj.parent.loginCookieEncryptionKey) }
|
if (hardwareKeyChallenge) { hwstate = obj.parent.encodeCookie({ u: req.session.tokenusername, p: req.session.tokenpassword, c: req.session.u2fchallenge }, obj.parent.loginCookieEncryptionKey) }
|
||||||
|
|
||||||
// Check if we can use OTP tokens with email
|
// Check if we can use OTP tokens with email
|
||||||
var otpemail = (parent.mailserver != null) && (req.session != null) && (req.session.tokenemail == true);
|
var otpemail = (parent.mailserver != null) && (req.session != null) && ((req.session.tokenemail == true) || (typeof req.session.tokenemail == 'string'));
|
||||||
if ((typeof domain.passwordrequirements == 'object') && (domain.passwordrequirements.email2factor == false)) { otpemail = false; }
|
if ((typeof domain.passwordrequirements == 'object') && (domain.passwordrequirements.email2factor == false)) { otpemail = false; }
|
||||||
var otpsms = (parent.smsserver != null) && (req.session != null) && (req.session.tokensms == true);
|
var otpsms = (parent.smsserver != null) && (req.session != null) && (req.session.tokensms == true);
|
||||||
if ((typeof domain.passwordrequirements == 'object') && (domain.passwordrequirements.sms2factor == false)) { otpsms = false; }
|
if ((typeof domain.passwordrequirements == 'object') && (domain.passwordrequirements.sms2factor == false)) { otpsms = false; }
|
||||||
|
Loading…
Reference in New Issue
Block a user