mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-01-11 23:13:21 -05:00
Added remember for 30 days 2nd factor option.
This commit is contained in:
parent
517b582d80
commit
f33a22fefc
@ -778,7 +778,7 @@ function performAmtAgentPresenceAssert() {
|
|||||||
// Called after the agent is asserted
|
// Called after the agent is asserted
|
||||||
function performAmtAgentPresenceAssertRetry(stack, name, response, status, watchdog) {
|
function performAmtAgentPresenceAssertRetry(stack, name, response, status, watchdog) {
|
||||||
if (status == 200) {
|
if (status == 200) {
|
||||||
debug(1, 'Succesful assert, sequence = ' + watchdog.Seq);
|
debug(1, 'Successful assert, sequence = ' + watchdog.Seq);
|
||||||
watchdog.Retry = 0;
|
watchdog.Retry = 0;
|
||||||
tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval);
|
tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval);
|
||||||
} else {
|
} else {
|
||||||
|
2
agents/meshcmd.min.js
vendored
2
agents/meshcmd.min.js
vendored
@ -778,7 +778,7 @@ function performAmtAgentPresenceAssert() {
|
|||||||
// Called after the agent is asserted
|
// Called after the agent is asserted
|
||||||
function performAmtAgentPresenceAssertRetry(stack, name, response, status, watchdog) {
|
function performAmtAgentPresenceAssertRetry(stack, name, response, status, watchdog) {
|
||||||
if (status == 200) {
|
if (status == 200) {
|
||||||
debug(1, 'Succesful assert, sequence = ' + watchdog.Seq);
|
debug(1, 'Successful assert, sequence = ' + watchdog.Seq);
|
||||||
watchdog.Retry = 0;
|
watchdog.Retry = 0;
|
||||||
tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval);
|
tempWatchdogTimer = setTimeout(performAmtAgentPresenceAssert, watchdog.Interval);
|
||||||
} else {
|
} else {
|
||||||
|
@ -326,7 +326,7 @@ module.exports.CreateRedirInterceptor = function (args) {
|
|||||||
obj.amt.digestQOP = obj.amt.acc.substring(12 + realmlen + noncelen, 12 + realmlen + noncelen + qoplen);
|
obj.amt.digestQOP = obj.amt.acc.substring(12 + realmlen + noncelen, 12 + realmlen + noncelen + qoplen);
|
||||||
}
|
}
|
||||||
else if (authType != obj.AuthenticationType.QUERY && authstatus == obj.AuthenticationStatus.SUCCESS) {
|
else if (authType != obj.AuthenticationType.QUERY && authstatus == obj.AuthenticationStatus.SUCCESS) {
|
||||||
// Intel AMT relayed that authentication was succesful, go to direct relay mode in both directions.
|
// Intel AMT relayed that authentication was successful, go to direct relay mode in both directions.
|
||||||
obj.ws.direct = true;
|
obj.ws.direct = true;
|
||||||
obj.amt.direct = true;
|
obj.amt.direct = true;
|
||||||
}
|
}
|
||||||
|
@ -864,7 +864,7 @@
|
|||||||
if (message.keys && message.keys.length > 0) {
|
if (message.keys && message.keys.length > 0) {
|
||||||
for (var i in message.keys) {
|
for (var i in message.keys) {
|
||||||
var key = message.keys[i], type = (key.type == 2)?'OTP':'WebAuthn';
|
var key = message.keys[i], type = (key.type == 2)?'OTP':'WebAuthn';
|
||||||
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;
|
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;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
x += start + '<tr style=text-align:center><td>' + "No Keys Configured" + end;
|
x += start + '<tr style=text-align:center><td>' + "No Keys Configured" + end;
|
||||||
|
@ -1888,7 +1888,7 @@
|
|||||||
if (message.keys && message.keys.length > 0) {
|
if (message.keys && message.keys.length > 0) {
|
||||||
for (var i in message.keys) {
|
for (var i in message.keys) {
|
||||||
var key = message.keys[i], type = (key.type == 2)?'OTP':'WebAuthn';
|
var key = message.keys[i], type = (key.type == 2)?'OTP':'WebAuthn';
|
||||||
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;
|
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;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
x += start + '<tr style=text-align:center><td>' + "No Keys Configured" + end;
|
x += start + '<tr style=text-align:center><td>' + "No Keys Configured" + end;
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -156,9 +156,15 @@
|
|||||||
<input id=hwtokenInput type=text name=hwtoken style="display:none" />
|
<input id=hwtokenInput type=text name=hwtoken style="display:none" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" style="align-content:center">
|
||||||
|
<label><input id=tokenInputRemember name=remembertoken type=checkbox />Remember this device for 30 days.</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<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><input style="display:none;float:right" id=securityKeyButton type=button value="Use Security Key" onclick="useSecurityKey()" /></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -265,6 +271,7 @@
|
|||||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||||
|
var publicKeyCredentialRequestOptions = null;
|
||||||
var currentpanel = 0;
|
var currentpanel = 0;
|
||||||
|
|
||||||
// Display the right server message
|
// Display the right server message
|
||||||
@ -322,41 +329,15 @@
|
|||||||
|
|
||||||
if (loginMode == '4') {
|
if (loginMode == '4') {
|
||||||
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')) {
|
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||||
hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer;
|
|
||||||
|
|
||||||
var publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
|
||||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
|
||||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
|
||||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// New WebAuthn hardware keys
|
|
||||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
|
||||||
function (rawAssertion) {
|
|
||||||
var assertion = {
|
|
||||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
|
||||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
|
||||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
|
||||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
|
||||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
|
||||||
};
|
|
||||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
|
||||||
QE('tokenOkButton', true);
|
|
||||||
Q('tokenOkButton').click();
|
|
||||||
},
|
|
||||||
function (error) { console.log('credentials-get error', error); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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')) {
|
||||||
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; }
|
||||||
|
|
||||||
var publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||||
@ -382,6 +363,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use a hardware security key
|
||||||
|
function useSecurityKey() {
|
||||||
|
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; }
|
||||||
|
|
||||||
|
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||||
|
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||||
|
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||||
|
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// New WebAuthn hardware keys
|
||||||
|
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||||
|
function (rawAssertion) {
|
||||||
|
var assertion = {
|
||||||
|
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||||
|
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||||
|
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||||
|
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||||
|
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||||
|
};
|
||||||
|
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||||
|
QE('tokenOkButton', true);
|
||||||
|
Q('tokenOkButton').click();
|
||||||
|
},
|
||||||
|
function (error) { console.log('credentials-get error', error); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showPassHint() {
|
function showPassHint() {
|
||||||
if (passRequirements.hint === true) { messagebox("Password Hint", passhint); }
|
if (passRequirements.hint === true) { messagebox("Password Hint", passhint); }
|
||||||
|
@ -147,13 +147,19 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td align=right width=100>Login token:</td>
|
<td align=right width=100>Login token:</td>
|
||||||
<td>
|
<td>
|
||||||
<input id=tokenInput type=text name=token maxlength=50 onchange=checkToken(event) onpaste=resetCheckToken(event) onkeyup=checkToken(event) onkeydown=checkToken(event) />
|
<input id=tokenInput type=text name=token maxlength=50 onchange=checkToken(event) onpaste=resetCheckToken(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>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" style="align-content:center">
|
||||||
|
<label><input id=tokenInputRemember name=remembertoken type=checkbox />Remember this device for 30 days.</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<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><input style="display:none;float:right" id=securityKeyButton type=button value="Use Security Key" onclick="useSecurityKey()" /></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -331,39 +337,13 @@
|
|||||||
|
|
||||||
if (loginMode == '4') {
|
if (loginMode == '4') {
|
||||||
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')) {
|
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||||
hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer;
|
|
||||||
|
|
||||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
|
||||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
|
||||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
|
||||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// New WebAuthn hardware keys
|
|
||||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
|
||||||
function (rawAssertion) {
|
|
||||||
var assertion = {
|
|
||||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
|
||||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
|
||||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
|
||||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
|
||||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
|
||||||
};
|
|
||||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
|
||||||
QE('tokenOkButton', true);
|
|
||||||
Q('tokenOkButton').click();
|
|
||||||
},
|
|
||||||
function (error) { console.log('credentials-get error', error); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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')) {
|
||||||
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; }
|
||||||
|
|
||||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||||
@ -395,6 +375,37 @@
|
|||||||
userInterfaceSelectMenu();
|
userInterfaceSelectMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use a hardware security key
|
||||||
|
function useSecurityKey() {
|
||||||
|
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; }
|
||||||
|
|
||||||
|
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||||
|
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||||
|
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||||
|
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// New WebAuthn hardware keys
|
||||||
|
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||||
|
function (rawAssertion) {
|
||||||
|
var assertion = {
|
||||||
|
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||||
|
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||||
|
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||||
|
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||||
|
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||||
|
};
|
||||||
|
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||||
|
QE('tokenOkButton', true);
|
||||||
|
Q('tokenOkButton').click();
|
||||||
|
},
|
||||||
|
function (error) { console.log('credentials-get error', error); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showPassHint(e) {
|
function showPassHint(e) {
|
||||||
messagebox("Password Hint", passhint);
|
messagebox("Password Hint", passhint);
|
||||||
haltEvent(e);
|
haltEvent(e);
|
||||||
|
@ -864,7 +864,7 @@
|
|||||||
if (message.keys && message.keys.length > 0) {
|
if (message.keys && message.keys.length > 0) {
|
||||||
for (var i in message.keys) {
|
for (var i in message.keys) {
|
||||||
var key = message.keys[i], type = (key.type == 2)?'OTP':'WebAuthn';
|
var key = message.keys[i], type = (key.type == 2)?'OTP':'WebAuthn';
|
||||||
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="' + "Retirer" + '" onclick=account_removehkey(" + key.i + ")></input>' + end;
|
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="' + "Retirer" + '" onclick=account_removehkey(' + key.i + ')></input>' + end;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
x += start + '<tr style=text-align:center><td>' + "No Keys Configured" + end;
|
x += start + '<tr style=text-align:center><td>' + "No Keys Configured" + end;
|
||||||
|
@ -1886,7 +1886,7 @@
|
|||||||
if (message.keys && message.keys.length > 0) {
|
if (message.keys && message.keys.length > 0) {
|
||||||
for (var i in message.keys) {
|
for (var i in message.keys) {
|
||||||
var key = message.keys[i], type = (key.type == 2)?'OTP':'WebAuthn';
|
var key = message.keys[i], type = (key.type == 2)?'OTP':'WebAuthn';
|
||||||
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="' + "Retirer" + '" onclick=account_removehkey(" + key.i + ")></input>' + end;
|
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="' + "Retirer" + '" onclick=account_removehkey(' + key.i + ')></input>' + end;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
x += start + '<tr style=text-align:center><td>' + "No Keys Configured" + end;
|
x += start + '<tr style=text-align:center><td>' + "No Keys Configured" + end;
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -154,9 +154,15 @@
|
|||||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" style="align-content:center">
|
||||||
|
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">Remember this device for 30 days.</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<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"><input style="display:none;float:right" id="securityKeyButton" type="button" value="Use Security Key" onclick="useSecurityKey()"></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
@ -263,6 +269,7 @@
|
|||||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||||
|
var publicKeyCredentialRequestOptions = null;
|
||||||
var currentpanel = 0;
|
var currentpanel = 0;
|
||||||
|
|
||||||
// Display the right server message
|
// Display the right server message
|
||||||
@ -320,41 +327,15 @@
|
|||||||
|
|
||||||
if (loginMode == '4') {
|
if (loginMode == '4') {
|
||||||
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')) {
|
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||||
hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer;
|
|
||||||
|
|
||||||
var publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
|
||||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
|
||||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
|
||||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// New WebAuthn hardware keys
|
|
||||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
|
||||||
function (rawAssertion) {
|
|
||||||
var assertion = {
|
|
||||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
|
||||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
|
||||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
|
||||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
|
||||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
|
||||||
};
|
|
||||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
|
||||||
QE('tokenOkButton', true);
|
|
||||||
Q('tokenOkButton').click();
|
|
||||||
},
|
|
||||||
function (error) { console.log('credentials-get error', error); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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')) {
|
||||||
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; }
|
||||||
|
|
||||||
var publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||||
@ -380,6 +361,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use a hardware security key
|
||||||
|
function useSecurityKey() {
|
||||||
|
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; }
|
||||||
|
|
||||||
|
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||||
|
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||||
|
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||||
|
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// New WebAuthn hardware keys
|
||||||
|
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||||
|
function (rawAssertion) {
|
||||||
|
var assertion = {
|
||||||
|
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||||
|
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||||
|
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||||
|
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||||
|
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||||
|
};
|
||||||
|
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||||
|
QE('tokenOkButton', true);
|
||||||
|
Q('tokenOkButton').click();
|
||||||
|
},
|
||||||
|
function (error) { console.log('credentials-get error', error); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showPassHint() {
|
function showPassHint() {
|
||||||
if (passRequirements.hint === true) { messagebox("Password Hint", passhint); }
|
if (passRequirements.hint === true) { messagebox("Password Hint", passhint); }
|
||||||
|
@ -145,13 +145,19 @@
|
|||||||
<tbody><tr>
|
<tbody><tr>
|
||||||
<td align="right" width="100">Login token:</td>
|
<td align="right" width="100">Login token:</td>
|
||||||
<td>
|
<td>
|
||||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onpaste="resetCheckToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)">
|
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onpaste="resetCheckToken(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>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" style="align-content:center">
|
||||||
|
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">Remember this device for 30 days.</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<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"><input style="display:none;float:right" id="securityKeyButton" type="button" value="Use Security Key" onclick="useSecurityKey()"></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
@ -329,39 +335,13 @@
|
|||||||
|
|
||||||
if (loginMode == '4') {
|
if (loginMode == '4') {
|
||||||
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')) {
|
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||||
hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer;
|
|
||||||
|
|
||||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
|
||||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
|
||||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
|
||||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// New WebAuthn hardware keys
|
|
||||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
|
||||||
function (rawAssertion) {
|
|
||||||
var assertion = {
|
|
||||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
|
||||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
|
||||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
|
||||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
|
||||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
|
||||||
};
|
|
||||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
|
||||||
QE('tokenOkButton', true);
|
|
||||||
Q('tokenOkButton').click();
|
|
||||||
},
|
|
||||||
function (error) { console.log('credentials-get error', error); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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')) {
|
||||||
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; }
|
||||||
|
|
||||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||||
@ -393,6 +373,37 @@
|
|||||||
userInterfaceSelectMenu();
|
userInterfaceSelectMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use a hardware security key
|
||||||
|
function useSecurityKey() {
|
||||||
|
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; }
|
||||||
|
|
||||||
|
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||||
|
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||||
|
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||||
|
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// New WebAuthn hardware keys
|
||||||
|
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||||
|
function (rawAssertion) {
|
||||||
|
var assertion = {
|
||||||
|
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||||
|
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||||
|
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||||
|
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||||
|
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||||
|
};
|
||||||
|
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||||
|
QE('tokenOkButton', true);
|
||||||
|
Q('tokenOkButton').click();
|
||||||
|
},
|
||||||
|
function (error) { console.log('credentials-get error', error); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showPassHint(e) {
|
function showPassHint(e) {
|
||||||
messagebox("Password Hint", passhint);
|
messagebox("Password Hint", passhint);
|
||||||
haltEvent(e);
|
haltEvent(e);
|
||||||
|
30
webserver.js
30
webserver.js
@ -516,6 +516,18 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
if ((req != null) && (req.ip != null) && (domain.passwordrequirements != null) && (domain.passwordrequirements.skip2factor != null)) {
|
if ((req != null) && (req.ip != null) && (domain.passwordrequirements != null) && (domain.passwordrequirements.skip2factor != null)) {
|
||||||
for (var i in domain.passwordrequirements.skip2factor) { if (require('ipcheck').match(req.ip, domain.passwordrequirements.skip2factor[i]) === true) return false; }
|
for (var i in domain.passwordrequirements.skip2factor) { if (require('ipcheck').match(req.ip, domain.passwordrequirements.skip2factor[i]) === true) return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if a 2nd factor cookie is present
|
||||||
|
if (typeof req.headers.cookie == 'string') {
|
||||||
|
const cookies = req.headers.cookie.split('; ');
|
||||||
|
for (var i in cookies) {
|
||||||
|
if (cookies[i].startsWith('twofactor=')) {
|
||||||
|
var twoFactorCookie = obj.parent.decodeCookie(decodeURIComponent(cookies[i].substring(10)), obj.parent.loginCookieEncryptionKey, (30 * 24 * 60)); // 30 day timeout
|
||||||
|
if ((twoFactorCookie != null) && ((twoFactorCookie.ip == null) || (twoFactorCookie.ip === cleanRemoteAddr(req.ip))) && (twoFactorCookie.userid == user._id)) { return false; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if a 2nd factor is present
|
// Check if a 2nd factor is present
|
||||||
return ((parent.config.settings.no2factorauth !== true) && ((user.otpsecret != null) || ((user.otphkeys != null) && (user.otphkeys.length > 0))));
|
return ((parent.config.settings.no2factorauth !== true) && ((user.otpsecret != null) || ((user.otphkeys != null) && (user.otphkeys.length > 0))));
|
||||||
}
|
}
|
||||||
@ -686,16 +698,22 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
||||||
}, randomWaitTime);
|
}, randomWaitTime);
|
||||||
} else {
|
} else {
|
||||||
// Login succesful
|
// Check if we need to remember this device
|
||||||
parent.debug('web', 'handleLoginRequest: succesful 2FA login');
|
if (req.body.remembertoken === 'on') {
|
||||||
|
const twoFactorCookie = obj.parent.encodeCookie({ userid: user._id /*, ip: cleanRemoteAddr(req.ip)*/ }, obj.parent.loginCookieEncryptionKey);
|
||||||
|
res.cookie('twofactor', twoFactorCookie, { maxAge: (30 * 24 * 60 * 60 * 1000), httpOnly: true, sameSite: 'strict', secure: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Login successful
|
||||||
|
parent.debug('web', 'handleLoginRequest: successful 2FA login');
|
||||||
completeLoginRequest(req, res, domain, user, userid, xusername, xpassword, direct);
|
completeLoginRequest(req, res, domain, user, userid, xusername, xpassword, direct);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Login succesful
|
// Login successful
|
||||||
parent.debug('web', 'handleLoginRequest: succesful login');
|
parent.debug('web', 'handleLoginRequest: successful login');
|
||||||
completeLoginRequest(req, res, domain, user, userid, xusername, xpassword, direct);
|
completeLoginRequest(req, res, domain, user, userid, xusername, xpassword, direct);
|
||||||
} else {
|
} else {
|
||||||
// Login failed, wait a random delay
|
// Login failed, wait a random delay
|
||||||
@ -959,7 +977,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||||
obj.parent.DispatchEvent(['*', 'server-users', user._id], obj, event);
|
obj.parent.DispatchEvent(['*', 'server-users', user._id], obj, event);
|
||||||
|
|
||||||
// Login succesful
|
// Login successful
|
||||||
parent.debug('web', 'handleResetPasswordRequest: success');
|
parent.debug('web', 'handleResetPasswordRequest: success');
|
||||||
req.session.userid = userid;
|
req.session.userid = userid;
|
||||||
req.session.domainid = domain.id;
|
req.session.domainid = domain.id;
|
||||||
@ -2570,7 +2588,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
var amtpassword = ((mesh.amt.password == '') ? getRandomAmtPassword() : mesh.amt.password);
|
var amtpassword = ((mesh.amt.password == '') ? getRandomAmtPassword() : mesh.amt.password);
|
||||||
if (checkAmtPassword(amtpassword) == false) { ws.send(JSON.stringify({ errorText: 'Invalid Intel AMT password' })); ws.close(); return; } // Invalid Intel AMT password, this should never happen.
|
if (checkAmtPassword(amtpassword) == false) { ws.send(JSON.stringify({ errorText: 'Invalid Intel AMT password' })); ws.close(); return; } // Invalid Intel AMT password, this should never happen.
|
||||||
|
|
||||||
// Save some state, if activation is succesful, we need this to add the device
|
// Save some state, if activation is successful, we need this to add the device
|
||||||
ws.xxstate = { uuid: cmd.uuid, realm: cmd.realm, tag: cmd.tag, name: cmd.name, hostname: cmd.hostname, pass: amtpassword, flags: activationMode, ver: cmd.ver, sku: cmd.sku }; // Flags: 2 = CCM, 4 = ACM
|
ws.xxstate = { uuid: cmd.uuid, realm: cmd.realm, tag: cmd.tag, name: cmd.name, hostname: cmd.hostname, pass: amtpassword, flags: activationMode, ver: cmd.ver, sku: cmd.sku }; // Flags: 2 = CCM, 4 = ACM
|
||||||
|
|
||||||
if (activationMode == 4) {
|
if (activationMode == 4) {
|
||||||
|
Loading…
Reference in New Issue
Block a user