Updated clickonce, password hint is configurable.
This commit is contained in:
parent
65e6c1925c
commit
54fb8040ec
20
meshuser.js
20
meshuser.js
|
@ -789,7 +789,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
// Check if this is an existing user
|
// Check if this is an existing user
|
||||||
var newuser = { type: 'user', _id: newuserid, name: newusername, creation: Math.floor(Date.now() / 1000), domain: domain.id };
|
var newuser = { type: 'user', _id: newuserid, name: newusername, creation: Math.floor(Date.now() / 1000), domain: domain.id };
|
||||||
if (command.email != null) { newuser.email = command.email; } // Email
|
if (command.email != null) { newuser.email = command.email; } // Email
|
||||||
|
if (command.resetNextLogin === true) { newuser.passchange = -1; } else { newuser.passchange = Math.floor(Date.now() / 1000); }
|
||||||
obj.parent.users[newuserid] = newuser;
|
obj.parent.users[newuserid] = newuser;
|
||||||
|
|
||||||
// Create a user, generate a salt and hash the password
|
// Create a user, generate a salt and hash the password
|
||||||
require('./pass').hash(command.pass, function (err, salt, hash) {
|
require('./pass').hash(command.pass, function (err, salt, hash) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
@ -830,7 +832,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
// Change our own password
|
// Change our own password
|
||||||
if (obj.common.validateString(command.oldpass, 1, 256) == false) break;
|
if (obj.common.validateString(command.oldpass, 1, 256) == false) break;
|
||||||
if (obj.common.validateString(command.newpass, 1, 256) == false) break;
|
if (obj.common.validateString(command.newpass, 1, 256) == false) break;
|
||||||
if (obj.common.validateString(command.hint, 0, 256) == false) break;
|
if ((command.hint != null) && (obj.common.validateString(command.hint, 0, 256) == false)) break;
|
||||||
if (obj.common.checkPasswordRequirements(command.newpass, domain.passwordrequirements) == false) break; // Password does not meet requirements
|
if (obj.common.checkPasswordRequirements(command.newpass, domain.passwordrequirements) == false) break; // Password does not meet requirements
|
||||||
|
|
||||||
// Start by checking the old password
|
// Start by checking the old password
|
||||||
|
@ -843,11 +845,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
displayNotificationMessage('Error, password not changed.');
|
displayNotificationMessage('Error, password not changed.');
|
||||||
} else {
|
} else {
|
||||||
// Change the password
|
// Change the password
|
||||||
|
if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true) && (command.hint != null)) {
|
||||||
var hint = command.hint;
|
var hint = command.hint;
|
||||||
if (hint.length > 250) hint = hint.substring(0, 250);
|
if (hint.length > 250) { hint = hint.substring(0, 250); }
|
||||||
|
user.passhint = hint;
|
||||||
|
}
|
||||||
user.salt = salt;
|
user.salt = salt;
|
||||||
user.hash = hash;
|
user.hash = hash;
|
||||||
user.passhint = hint;
|
|
||||||
user.passchange = Math.floor(Date.now() / 1000);
|
user.passchange = Math.floor(Date.now() / 1000);
|
||||||
delete user.passtype;
|
delete user.passtype;
|
||||||
obj.db.SetUser(user);
|
obj.db.SetUser(user);
|
||||||
|
@ -870,7 +874,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
if (user.siteadmin != 0xFFFFFFFF) break;
|
if (user.siteadmin != 0xFFFFFFFF) break;
|
||||||
if (obj.common.validateString(command.user, 1, 256) == false) break;
|
if (obj.common.validateString(command.user, 1, 256) == false) break;
|
||||||
if (obj.common.validateString(command.pass, 1, 256) == false) break;
|
if (obj.common.validateString(command.pass, 1, 256) == false) break;
|
||||||
if (obj.common.validateString(command.hint, 0, 256) == false) break;
|
if ((command.hint != null) && (obj.common.validateString(command.hint, 0, 256) == false)) break;
|
||||||
if (typeof command.removeMultiFactor != 'boolean') break;
|
if (typeof command.removeMultiFactor != 'boolean') break;
|
||||||
if (obj.common.checkPasswordRequirements(command.pass, domain.passwordrequirements) == false) break; // Password does not meet requirements
|
if (obj.common.checkPasswordRequirements(command.pass, domain.passwordrequirements) == false) break; // Password does not meet requirements
|
||||||
|
|
||||||
|
@ -881,8 +885,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
if (!err) {
|
if (!err) {
|
||||||
chguser.salt = salt;
|
chguser.salt = salt;
|
||||||
chguser.hash = hash;
|
chguser.hash = hash;
|
||||||
chguser.passhint = command.hint;
|
if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true) && (command.hint != null)) {
|
||||||
if (command.resetNextLogin == true) { chguser.passchange = -1; } else { chguser.passchange = Math.floor(Date.now() / 1000); }
|
var hint = command.hint;
|
||||||
|
if (hint.length > 250) { hint = hint.substring(0, 250); }
|
||||||
|
chguser.passhint = hint;
|
||||||
|
}
|
||||||
|
if (command.resetNextLogin === true) { chguser.passchange = -1; } else { chguser.passchange = Math.floor(Date.now() / 1000); }
|
||||||
delete chguser.passtype; // Remove the password type if one was present.
|
delete chguser.passtype; // Remove the password type if one was present.
|
||||||
if (command.removeMultiFactor == true) {
|
if (command.removeMultiFactor == true) {
|
||||||
if (chguser.otpsecret) { delete chguser.otpsecret; }
|
if (chguser.otpsecret) { delete chguser.otpsecret; }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "meshcentral",
|
"name": "meshcentral",
|
||||||
"version": "0.2.9-h",
|
"version": "0.2.9-i",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Remote Management",
|
"Remote Management",
|
||||||
"Intel AMT",
|
"Intel AMT",
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
|
|
||||||
<assemblyIdentity name="MeshMiniRouter.application" version="2.0.0.22" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" />
|
|
||||||
<description asmv2:publisher="Meshcentral.com" asmv2:product="MeshCentral Mini-Router" asmv2:supportUrl="https://meshcentral.com/" xmlns="urn:schemas-microsoft-com:asm.v1" />
|
|
||||||
<deployment install="false" mapFileExtensions="true" trustURLParameters="true" />
|
|
||||||
<compatibleFrameworks xmlns="urn:schemas-microsoft-com:clickonce.v2">
|
|
||||||
<framework targetVersion="4.5" profile="Full" supportedRuntime="4.0.30319" />
|
|
||||||
</compatibleFrameworks>
|
|
||||||
<dependency>
|
|
||||||
<dependentAssembly dependencyType="install" codebase="Application Files\MeshMiniRouter_2_0_0_22\MeshMiniRouter.exe.manifest" size="4712">
|
|
||||||
<assemblyIdentity name="MeshMiniRouter.exe" version="2.0.0.22" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" type="win32" />
|
|
||||||
<hash>
|
|
||||||
<dsig:Transforms>
|
|
||||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
|
||||||
</dsig:Transforms>
|
|
||||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
|
||||||
<dsig:DigestValue>WOFMexmFiT1cRB5ZPY6zmeQ7x/Cbx//7QyPjwnjKGnA=</dsig:DigestValue>
|
|
||||||
</hash>
|
|
||||||
</dependentAssembly>
|
|
||||||
</dependency>
|
|
||||||
</asmv1:assembly>
|
|
|
@ -1,82 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
|
|
||||||
<asmv1:assemblyIdentity name="MeshMiniRouter.exe" version="2.0.0.22" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" type="win32" />
|
|
||||||
<description asmv2:iconFile="MeshMiniRouter.ico" xmlns="urn:schemas-microsoft-com:asm.v1" />
|
|
||||||
<application />
|
|
||||||
<entryPoint>
|
|
||||||
<assemblyIdentity name="MeshMiniRouter" version="1.0.6919.31937" language="neutral" processorArchitecture="msil" />
|
|
||||||
<commandLine file="MeshMiniRouter.exe" parameters="" />
|
|
||||||
</entryPoint>
|
|
||||||
<trustInfo>
|
|
||||||
<security>
|
|
||||||
<applicationRequestMinimum>
|
|
||||||
<PermissionSet version="1" class="System.Security.NamedPermissionSet" Name="Internet" Description="Default rights given to Internet applications" Unrestricted="true" ID="Custom" SameSite="site" />
|
|
||||||
<defaultAssemblyRequest permissionSetReference="Custom" />
|
|
||||||
</applicationRequestMinimum>
|
|
||||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<!-- UAC Manifest Options
|
|
||||||
If you want to change the Windows User Account Control level replace the
|
|
||||||
requestedExecutionLevel node with one of the following.
|
|
||||||
|
|
||||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
|
||||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
|
||||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
|
||||||
|
|
||||||
Specifying requestedExecutionLevel node will disable file and registry virtualization.
|
|
||||||
If you want to utilize File and Registry Virtualization for backward
|
|
||||||
compatibility then delete the requestedExecutionLevel node.
|
|
||||||
-->
|
|
||||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
|
||||||
</requestedPrivileges>
|
|
||||||
</security>
|
|
||||||
</trustInfo>
|
|
||||||
<dependency>
|
|
||||||
<dependentOS>
|
|
||||||
<osVersionInfo>
|
|
||||||
<os majorVersion="5" minorVersion="1" buildNumber="2600" servicePackMajor="0" />
|
|
||||||
</osVersionInfo>
|
|
||||||
</dependentOS>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
|
|
||||||
<assemblyIdentity name="Microsoft.Windows.CommonLanguageRuntime" version="4.0.30319.0" />
|
|
||||||
</dependentAssembly>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="MeshMiniRouter.exe" size="186880">
|
|
||||||
<assemblyIdentity name="MeshMiniRouter" version="1.0.6919.31937" language="neutral" processorArchitecture="msil" />
|
|
||||||
<hash>
|
|
||||||
<dsig:Transforms>
|
|
||||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
|
||||||
</dsig:Transforms>
|
|
||||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
|
||||||
<dsig:DigestValue>e/EE2UyAOSDkWCqJcDJPIiu7cOLRXJszqGGnayICf5I=</dsig:DigestValue>
|
|
||||||
</hash>
|
|
||||||
</dependentAssembly>
|
|
||||||
</dependency>
|
|
||||||
<file name="MeshMiniRouter.exe.config" size="2397">
|
|
||||||
<hash>
|
|
||||||
<dsig:Transforms>
|
|
||||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
|
||||||
</dsig:Transforms>
|
|
||||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
|
||||||
<dsig:DigestValue>UylUFD4/o0KBti+5/eodTDgq4BkUJD0J0aUXNd3yHbY=</dsig:DigestValue>
|
|
||||||
</hash>
|
|
||||||
</file>
|
|
||||||
<file name="MeshMiniRouter.ico" size="1078">
|
|
||||||
<hash>
|
|
||||||
<dsig:Transforms>
|
|
||||||
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
|
|
||||||
</dsig:Transforms>
|
|
||||||
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" />
|
|
||||||
<dsig:DigestValue>mkjbDQuo7YXa8wZxdKEu/ECXrORwwtpRgNj8NBKbzHo=</dsig:DigestValue>
|
|
||||||
</hash>
|
|
||||||
</file>
|
|
||||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
|
||||||
<application>
|
|
||||||
<!-- A list of all Windows versions that this application is designed to work with. Windows will automatically select the most compatible environment.-->
|
|
||||||
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
|
|
||||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
|
|
||||||
</application>
|
|
||||||
</compatibility>
|
|
||||||
</asmv1:assembly>
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
File diff suppressed because one or more lines are too long
|
@ -59,7 +59,7 @@ FONT.key {font-weight: bold; color: darkgreen}
|
||||||
<TR><TD ALIGN="LEFT"><TABLE CELLPADDING="2" CELLSPACING="0" BORDER="0" WIDTH="540"><TR><TD WIDTH="496">
|
<TR><TD ALIGN="LEFT"><TABLE CELLPADDING="2" CELLSPACING="0" BORDER="0" WIDTH="540"><TR><TD WIDTH="496">
|
||||||
|
|
||||||
<!-- Begin AppInfo -->
|
<!-- Begin AppInfo -->
|
||||||
<TABLE><TR><TD COLSPAN="3"> </TD></TR><TR><TD><B>Name:</B></TD><TD WIDTH="5"><SPACER TYPE="block" WIDTH="10" /></TD><TD>MeshCentral Mini-Router</TD></TR><TR><TD COLSPAN="3"> </TD></TR><TR><TD><B>Version:</B></TD><TD WIDTH="5"><SPACER TYPE="block" WIDTH="10" /></TD><TD>2.0.0.22</TD></TR><TR><TD COLSPAN="3"> </TD></TR><TR><TD><B>Publisher:</B></TD><TD WIDTH="5"><SPACER TYPE="block" WIDTH="10" /></TD><TD>Meshcentral.com</TD></TR><tr><td colspan="3"> </td></tr></TABLE>
|
<TABLE><TR><TD COLSPAN="3"> </TD></TR><TR><TD><B>Name:</B></TD><TD WIDTH="5"><SPACER TYPE="block" WIDTH="10" /></TD><TD>MeshCentral Mini-Router</TD></TR><TR><TD COLSPAN="3"> </TD></TR><TR><TD><B>Version:</B></TD><TD WIDTH="5"><SPACER TYPE="block" WIDTH="10" /></TD><TD>2.0.0.25</TD></TR><TR><TD COLSPAN="3"> </TD></TR><TR><TD><B>Publisher:</B></TD><TD WIDTH="5"><SPACER TYPE="block" WIDTH="10" /></TD><TD>Meshcentral.com</TD></TR><tr><td colspan="3"> </td></tr></TABLE>
|
||||||
<!-- End AppInfo -->
|
<!-- End AppInfo -->
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1152,7 +1152,7 @@
|
||||||
var x = "<form action='" + domainUrl + "changepassword' method=post><table style=margin-left:10px><tr>";
|
var x = "<form action='" + domainUrl + "changepassword' method=post><table style=margin-left:10px><tr>";
|
||||||
x += "<td align=right>Password:</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b><span id=dxPassWarn></span></b></td>";
|
x += "<td align=right>Password:</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b><span id=dxPassWarn></span></b></td>";
|
||||||
x += "</tr><tr><td align=right>Password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td>";
|
x += "</tr><tr><td align=right>Password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td>";
|
||||||
x += "</tr><tr><td align=right>Hint:</td><td><input id=apasswordhint name=apasswordhint maxlength=250 type=text autocomplete=off /></td>";
|
if (features & 0x00010000) { x += "</tr><tr><td align=right>Hint:</td><td><input id=apasswordhint name=apasswordhint maxlength=250 type=text autocomplete=off /></td>"; }
|
||||||
x += '</tr></table><div style=padding:10px;margin-bottom:4px>';
|
x += '</tr></table><div style=padding:10px;margin-bottom:4px>';
|
||||||
x += '<input id=account_dlgCancelButton type=button value=Cancel style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>';
|
x += '<input id=account_dlgCancelButton type=button value=Cancel style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>';
|
||||||
x += '<input id=account_dlgOkButton type=submit value=OK style="float:right;width:80px" onclick=dialogclose(1)>';
|
x += '<input id=account_dlgOkButton type=submit value=OK style="float:right;width:80px" onclick=dialogclose(1)>';
|
||||||
|
|
|
@ -5593,9 +5593,13 @@
|
||||||
x += "<tr><td align=right>Old password:</td><td><input id=apassword0 type=password name=apassword0 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b></b></td></tr>";
|
x += "<tr><td align=right>Old password:</td><td><input id=apassword0 type=password name=apassword0 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b></b></td></tr>";
|
||||||
x += "<tr><td align=right>New password:</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b><span id=dxPassWarn></span></b></td></tr>";
|
x += "<tr><td align=right>New password:</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b><span id=dxPassWarn></span></b></td></tr>";
|
||||||
x += "<tr><td align=right>New password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td></tr>";
|
x += "<tr><td align=right>New password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td></tr>";
|
||||||
x += "<tr><td align=right>Password hint:</td><td><input id=apasswordhint name=apasswordhint maxlength=250 type=text autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td></tr>";
|
if (features & 0x00010000) { x += "<tr><td align=right>Password hint:</td><td><input id=apasswordhint name=apasswordhint maxlength=250 type=text autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td></tr>"; }
|
||||||
x += '</table>'
|
x += '</table>'
|
||||||
if (passRequirements) { var r = []; for (var i in passRequirements) { r.push(i + ':' + passRequirements[i]); } x += '<br /><span style=font-size:x-small>Requirements: ' + r.join(', ') + '.</span>'; }
|
if (passRequirements) {
|
||||||
|
var r = [], rc = 0;
|
||||||
|
for (var i in passRequirements) { if ((i != 'reset') && (i != 'hint')) { r.push(i + ':' + passRequirements[i]); rc++; } }
|
||||||
|
if (rc > 0) { x += '<br /><span style=font-size:x-small>Requirements: ' + r.join(', ') + '.</span>'; }
|
||||||
|
}
|
||||||
x += '<br />';
|
x += '<br />';
|
||||||
//x += '<br /><div style=padding:10px;margin-bottom:4px>';
|
//x += '<br /><div style=padding:10px;margin-bottom:4px>';
|
||||||
//x += '<input id=account_dlgCancelButton type=button value=Cancel style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>';
|
//x += '<input id=account_dlgCancelButton type=button value=Cancel style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>';
|
||||||
|
@ -5608,7 +5612,9 @@
|
||||||
|
|
||||||
function account_showChangePasswordEx() {
|
function account_showChangePasswordEx() {
|
||||||
if (Q('apassword1').value == Q('apassword2').value) {
|
if (Q('apassword1').value == Q('apassword2').value) {
|
||||||
meshserver.send({ action: 'changepassword', oldpass: Q('apassword0').value, newpass: Q('apassword1').value, hint: Q('apasswordhint').value });
|
var r = { action: 'changepassword', oldpass: Q('apassword0').value, newpass: Q('apassword1').value };
|
||||||
|
if (features & 0x00010000) { r.hint = Q('apasswordhint').value; }
|
||||||
|
meshserver.send(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6487,7 +6493,14 @@
|
||||||
x += addHtmlValue('Email', '<input id=p4email style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />');
|
x += addHtmlValue('Email', '<input id=p4email style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />');
|
||||||
x += addHtmlValue('Password', '<input id=p4pass1 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />');
|
x += addHtmlValue('Password', '<input id=p4pass1 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />');
|
||||||
x += addHtmlValue('Password', '<input id=p4pass2 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />');
|
x += addHtmlValue('Password', '<input id=p4pass2 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate() onkeyup=showCreateNewAccountDialogValidate() />');
|
||||||
if (passRequirements) { var r = []; for (var i in passRequirements) { r.push(i + ':' + passRequirements[i]); } x += '<div style=font-size:x-small;padding:6px>Requirements: ' + r.join(', ') + '.</div>'; }
|
x += '<div><input id=p4resetNextLogin type=checkbox />Force password reset on next login.</div>';
|
||||||
|
|
||||||
|
if (passRequirements) {
|
||||||
|
var r = [], rc = 0;
|
||||||
|
for (var i in passRequirements) { if ((i != 'reset') && (i != 'hint')) { r.push(i + ':' + passRequirements[i]); rc++; } }
|
||||||
|
if (rc > 0) { x += '<div style=font-size:x-small;padding:6px>Requirements: ' + r.join(', ') + '.</div>'; }
|
||||||
|
}
|
||||||
|
|
||||||
setDialogMode(2, "Create Account", 3, showCreateNewAccountDialogEx, x);
|
setDialogMode(2, "Create Account", 3, showCreateNewAccountDialogEx, x);
|
||||||
showCreateNewAccountDialogValidate();
|
showCreateNewAccountDialogValidate();
|
||||||
Q('p4name').focus();
|
Q('p4name').focus();
|
||||||
|
@ -6501,7 +6514,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function showCreateNewAccountDialogEx() {
|
function showCreateNewAccountDialogEx() {
|
||||||
meshserver.send({ action: 'adduser', username: Q('p4name').value, email: Q('p4email').value, pass: Q('p4pass1').value });
|
meshserver.send({ action: 'adduser', username: Q('p4name').value, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked });
|
||||||
}
|
}
|
||||||
|
|
||||||
function showUserAdminDialog(e, userid) {
|
function showUserAdminDialog(e, userid) {
|
||||||
|
@ -6689,8 +6702,14 @@
|
||||||
var x = '';
|
var x = '';
|
||||||
x += addHtmlValue('Password', '<input id=p4pass1 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=showCreateNewAccountDialogValidate(1)></input>');
|
x += addHtmlValue('Password', '<input id=p4pass1 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=showCreateNewAccountDialogValidate(1)></input>');
|
||||||
x += addHtmlValue('Password', '<input id=p4pass2 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=showCreateNewAccountDialogValidate(1)></input>');
|
x += addHtmlValue('Password', '<input id=p4pass2 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=showCreateNewAccountDialogValidate(1)></input>');
|
||||||
x += addHtmlValue('Password hint', '<input id=p4hint type=text style=width:230px maxlength=256></input>');
|
if (features & 0x00010000) { x += addHtmlValue('Password hint', '<input id=p4hint type=text style=width:230px maxlength=256></input>'); }
|
||||||
if (passRequirements) { var r = []; for (var i in passRequirements) { r.push(i + ':' + passRequirements[i]); } x += '<div style=font-size:x-small;padding:6px>Requirements: ' + r.join(', ') + '.</div>'; }
|
|
||||||
|
if (passRequirements) {
|
||||||
|
var r = [], rc = 0;
|
||||||
|
for (var i in passRequirements) { if ((i != 'reset') && (i != 'hint')) { r.push(i + ':' + passRequirements[i]); rc++; } }
|
||||||
|
if (rc > 0) { x += '<div style=font-size:x-small;padding:6px>Requirements: ' + r.join(', ') + '.</div>'; }
|
||||||
|
}
|
||||||
|
|
||||||
x += '<div><input id=p4resetNextLogin type=checkbox />Force password reset on next login.</div>';
|
x += '<div><input id=p4resetNextLogin type=checkbox />Force password reset on next login.</div>';
|
||||||
if (multiFactor == 1) { x += '<div><input id=p4twoFactorRemove type=checkbox />Remove all 2nd factor authentication.</div>'; }
|
if (multiFactor == 1) { x += '<div><input id=p4twoFactorRemove type=checkbox />Remove all 2nd factor authentication.</div>'; }
|
||||||
setDialogMode(2, "Change Password for " + EscapeHtml(currentUser.name), 3, p30showUserChangePassDialogEx, x, multiFactor);
|
setDialogMode(2, "Change Password for " + EscapeHtml(currentUser.name), 3, p30showUserChangePassDialogEx, x, multiFactor);
|
||||||
|
@ -6701,7 +6720,11 @@
|
||||||
function p30showUserChangePassDialogEx(b, tag) {
|
function p30showUserChangePassDialogEx(b, tag) {
|
||||||
var removeMultiFactor = false;
|
var removeMultiFactor = false;
|
||||||
if ((tag == 1) && (Q('p4twoFactorRemove').checked == true)) { removeMultiFactor = true; }
|
if ((tag == 1) && (Q('p4twoFactorRemove').checked == true)) { removeMultiFactor = true; }
|
||||||
if (Q('p4pass1').value == Q('p4pass2').value) { meshserver.send({ action: 'changeuserpass', user: currentUser.name, pass: Q('p4pass1').value, hint: Q('p4hint').value, removeMultiFactor: removeMultiFactor, resetNextLogin: Q('p4resetNextLogin').checked }); }
|
if (Q('p4pass1').value == Q('p4pass2').value) {
|
||||||
|
var r = { action: 'changeuserpass', user: currentUser.name, pass: Q('p4pass1').value, removeMultiFactor: removeMultiFactor, resetNextLogin: Q('p4resetNextLogin').checked };
|
||||||
|
if (features & 0x00010000) { r.hint = Q('p4hint').value; }
|
||||||
|
meshserver.send(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function p30showDeleteUserDialog() {
|
function p30showDeleteUserDialog() {
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -100,7 +100,7 @@
|
||||||
<td align=right>Password:</td>
|
<td align=right>Password:</td>
|
||||||
<td><input id=apassword2 type=password name=password2 autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(4) onkeyup=validateCreate(4,event) /></td>
|
<td><input id=apassword2 type=password name=password2 autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(4) onkeyup=validateCreate(4,event) /></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr id="createPanelHint" style="display:none">
|
||||||
<td align=right>Pass Hint:</td>
|
<td align=right>Pass Hint:</td>
|
||||||
<td><input id=apasswordhint type=text name=apasswordhint autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(5) onkeyup=validateCreate(5,event) /></td>
|
<td><input id=apasswordhint type=text name=apasswordhint autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(5) onkeyup=validateCreate(5,event) /></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -151,7 +151,7 @@
|
||||||
<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) onkeyup=checkToken(event) onkeydown=checkToken(event) />
|
<input id=tokenInput type=text name=token maxlength=50 onchange=checkToken(event) onkeyup=checkToken(event) onkeydown=checkToken(event) onfocus=checkTokenTimer(1) onblur=checkTokenTimer(0) />
|
||||||
<input id=hwtokenInput type=text name=hwtoken style="display:none" />
|
<input id=hwtokenInput type=text name=hwtoken style="display:none" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -203,7 +203,7 @@
|
||||||
<td id="rnuPass2" align=right>Password:</td>
|
<td id="rnuPass2" align=right>Password:</td>
|
||||||
<td><input id=rapassword2 type=password name=rpassword2 autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validatePassReset(4,event) onkeyup=validatePassReset(4,event) /></td>
|
<td><input id=rapassword2 type=password name=rpassword2 autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validatePassReset(4,event) onkeyup=validatePassReset(4,event) /></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr id="resetpasswordpanelHint" style="display:none">
|
||||||
<td id="rnuHint" align=right>Password Hint:</td>
|
<td id="rnuHint" align=right>Password Hint:</td>
|
||||||
<td><input id=rapasswordhint type=text name=rpasswordhint autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validatePassReset(5,event) onkeyup=validatePassReset(5,event) /></td>
|
<td><input id=rapasswordhint type=text name=rpasswordhint autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validatePassReset(5,event) onkeyup=validatePassReset(5,event) /></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -258,8 +258,10 @@
|
||||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||||
var features = parseInt('{{{features}}}');
|
var features = parseInt('{{{features}}}');
|
||||||
var passRequirements = "{{{passRequirements}}}";
|
var passRequirements = "{{{passRequirements}}}";
|
||||||
if (passRequirements != "") { passRequirements = JSON.parse(decodeURIComponent(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 hardwareKeyChallenge = '{{{hkey}}}';
|
var hardwareKeyChallenge = '{{{hkey}}}';
|
||||||
|
var currentpanel = 0;
|
||||||
|
|
||||||
function startup() {
|
function startup() {
|
||||||
if ((features & 32) == 0) {
|
if ((features & 32) == 0) {
|
||||||
|
@ -269,13 +271,16 @@
|
||||||
if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
|
if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QV('createPanelHint', passRequirements.hint === true);
|
||||||
|
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||||
|
|
||||||
window.onresize = center;
|
window.onresize = center;
|
||||||
center();
|
center();
|
||||||
validateLogin();
|
validateLogin();
|
||||||
validateCreate();
|
validateCreate();
|
||||||
if ('{{loginmode}}' != '') { go(parseInt('{{loginmode}}')); } else { go(1); }
|
if ('{{loginmode}}' != '') { go(parseInt('{{loginmode}}')); } else { go(1); }
|
||||||
QV('newAccountDiv', ('{{{newAccount}}}' != '0') && ('{{{newAccount}}}' != 'false')); // If new accounts are not allowed, don't display the new account link.
|
QV('newAccountDiv', ('{{{newAccount}}}' != '0') && ('{{{newAccount}}}' != 'false')); // If new accounts are not allowed, don't display the new account link.
|
||||||
if ((passhint != null) && (passhint.length > 0)) { QV("showPassHintLink", true); }
|
if ((passRequirements.hint === true) && (passhint != null) && (passhint.length > 0)) { QV("showPassHintLink", true); }
|
||||||
QV("newAccountPass", (newAccountPass == 1));
|
QV("newAccountPass", (newAccountPass == 1));
|
||||||
QV("resetAccountDiv", (emailCheck == true));
|
QV("resetAccountDiv", (emailCheck == true));
|
||||||
QV("hrAccountDiv", (emailCheck == true) || (newAccountPass == 1));
|
QV("hrAccountDiv", (emailCheck == true) || (newAccountPass == 1));
|
||||||
|
@ -284,7 +289,7 @@
|
||||||
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) && u2fSupported()) {
|
if ((hardwareKeyChallenge != null) && u2fSupported()) {
|
||||||
window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
|
window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
|
||||||
if (authResponse.signatureData) {
|
if ((currentpanel == 4) && authResponse.signatureData) {
|
||||||
Q('hwtokenInput').value = JSON.stringify(authResponse);
|
Q('hwtokenInput').value = JSON.stringify(authResponse);
|
||||||
QE('tokenOkButton', true);
|
QE('tokenOkButton', true);
|
||||||
Q('tokenOkButton').click();
|
Q('tokenOkButton').click();
|
||||||
|
@ -297,7 +302,7 @@
|
||||||
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) && u2fSupported()) {
|
if ((hardwareKeyChallenge != null) && u2fSupported()) {
|
||||||
window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
|
window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
|
||||||
if (authResponse.signatureData) {
|
if ((currentpanel == 5) && authResponse.signatureData) {
|
||||||
Q('resetHwtokenInput').value = JSON.stringify(authResponse);
|
Q('resetHwtokenInput').value = JSON.stringify(authResponse);
|
||||||
QE('resetTokenOkButton', true);
|
QE('resetTokenOkButton', true);
|
||||||
Q('resetTokenOkButton').click();
|
Q('resetTokenOkButton').click();
|
||||||
|
@ -308,7 +313,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPassHint() {
|
function showPassHint() {
|
||||||
messagebox("Password Hint", passhint);
|
if (passRequirements.hint === true) { messagebox("Password Hint", passhint); }
|
||||||
}
|
}
|
||||||
|
|
||||||
function xgo(x) {
|
function xgo(x) {
|
||||||
|
@ -322,6 +327,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function go(x) {
|
function go(x) {
|
||||||
|
currentpanel = x;
|
||||||
setDialogMode(0);
|
setDialogMode(0);
|
||||||
QV("showPassHintLink", false);
|
QV("showPassHintLink", false);
|
||||||
QV('loginpanel', x == 1);
|
QV('loginpanel', x == 1);
|
||||||
|
@ -354,7 +360,7 @@
|
||||||
QH('passWarning', '');
|
QH('passWarning', '');
|
||||||
QV('passwordPolicyCallout', false);
|
QV('passwordPolicyCallout', false);
|
||||||
} else {
|
} else {
|
||||||
if (passRequirements == null || passRequirements == '') {
|
if (!passRequirementsEx) {
|
||||||
// No password requirements, display password strength
|
// No password requirements, display password strength
|
||||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>Strong Password</b><span>'); }
|
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>Strong Password</b><span>'); }
|
||||||
|
@ -402,7 +408,7 @@
|
||||||
QH('rpassWarning', '');
|
QH('rpassWarning', '');
|
||||||
QV('rpasswordPolicyCallout', false);
|
QV('rpasswordPolicyCallout', false);
|
||||||
} else {
|
} else {
|
||||||
if (passRequirements == null || passRequirements == '') {
|
if (!passRequirementsEx) {
|
||||||
// No password requirements, display password strength
|
// No password requirements, display password strength
|
||||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>Strong Password</b><span>'); }
|
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>Strong Password</b><span>'); }
|
||||||
|
@ -491,16 +497,20 @@
|
||||||
return counts;
|
return counts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var xcheckTokenTimer = null;
|
||||||
|
function checkTokenTimer(enter) {
|
||||||
|
if ((enter == 0) && (xcheckTokenTimer != null)) { clearInterval(xcheckTokenTimer); xcheckTokenTimer = null; }
|
||||||
|
if ((enter == 1) && (xcheckTokenTimer == null)) { xcheckTokenTimer = setInterval(checkToken, 200); }
|
||||||
|
}
|
||||||
|
|
||||||
function checkToken() {
|
function checkToken() {
|
||||||
var t1 = Q('tokenInput').value;
|
var t1 = Q('tokenInput').value, t2 = t1.split(' ').join('');
|
||||||
var t2 = t1.split(' ').join('');
|
|
||||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetCheckToken() {
|
function resetCheckToken() {
|
||||||
var t1 = Q('resetTokenInput').value;
|
var t1 = Q('resetTokenInput').value, t2 = t1.split(' ').join('');
|
||||||
var t2 = t1.split(' ').join('');
|
|
||||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@
|
||||||
<td id="nuPass2" align=right>Password:</td>
|
<td id="nuPass2" align=right>Password:</td>
|
||||||
<td><input id=apassword2 type=password name=password2 autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(4,event) onkeyup=validateCreate(4,event) /></td>
|
<td><input id=apassword2 type=password name=password2 autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(4,event) onkeyup=validateCreate(4,event) /></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr id="createPanelHint" style="display:none">
|
||||||
<td id="nuHint" align=right>Password Hint:</td>
|
<td id="nuHint" align=right>Password Hint:</td>
|
||||||
<td><input id=apasswordhint type=text name=apasswordhint autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(5,event) onkeyup=validateCreate(5,event) /></td>
|
<td><input id=apasswordhint type=text name=apasswordhint autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(5,event) onkeyup=validateCreate(5,event) /></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -273,7 +273,7 @@
|
||||||
<td id="rnuPass2" align=right>Password:</td>
|
<td id="rnuPass2" align=right>Password:</td>
|
||||||
<td><input id=rapassword2 type=password name=rpassword2 autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validatePassReset(4,event) onkeyup=validatePassReset(4,event) /></td>
|
<td><input id=rapassword2 type=password name=rpassword2 autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validatePassReset(4,event) onkeyup=validatePassReset(4,event) /></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr id="resetpasswordpanelHint" style="display:none">
|
||||||
<td id="rnuHint" align=right>Password Hint:</td>
|
<td id="rnuHint" align=right>Password Hint:</td>
|
||||||
<td><input id=rapasswordhint type=text name=rpasswordhint autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validatePassReset(5,event) onkeyup=validatePassReset(5,event) /></td>
|
<td><input id=rapasswordhint type=text name=rpasswordhint autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validatePassReset(5,event) onkeyup=validatePassReset(5,event) /></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -333,12 +333,14 @@
|
||||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||||
var passRequirements = "{{{passRequirements}}}";
|
var passRequirements = "{{{passRequirements}}}";
|
||||||
var hardwareKeyChallenge = '{{{hkey}}}';
|
var hardwareKeyChallenge = '{{{hkey}}}';
|
||||||
if (passRequirements != "") { passRequirements = JSON.parse(decodeURIComponent(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 features = parseInt('{{{features}}}');
|
var features = parseInt('{{{features}}}');
|
||||||
var webPageFullScreen = getstore('webPageFullScreen', true);
|
var webPageFullScreen = getstore('webPageFullScreen', true);
|
||||||
if (webPageFullScreen == 'false') { webPageFullScreen = false; }
|
if (webPageFullScreen == 'false') { webPageFullScreen = false; }
|
||||||
if (webPageFullScreen == 'true') { webPageFullScreen = true; }
|
if (webPageFullScreen == 'true') { webPageFullScreen = true; }
|
||||||
var welcomeText = decodeURIComponent("{{{welcometext}}}");
|
var welcomeText = decodeURIComponent("{{{welcometext}}}");
|
||||||
|
var currentpanel = 0;
|
||||||
toggleFullScreen();
|
toggleFullScreen();
|
||||||
|
|
||||||
function startup() {
|
function startup() {
|
||||||
|
@ -349,6 +351,9 @@
|
||||||
if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
|
if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QV('createPanelHint', passRequirements.hint === true);
|
||||||
|
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||||
|
|
||||||
// Display the welcome text
|
// Display the welcome text
|
||||||
if (welcomeText) { QH('welcomeText', welcomeText); }
|
if (welcomeText) { QH('welcomeText', welcomeText); }
|
||||||
QV('welcomeText', true);
|
QV('welcomeText', true);
|
||||||
|
@ -369,7 +374,7 @@
|
||||||
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) && u2fSupported()) {
|
if ((hardwareKeyChallenge != null) && u2fSupported()) {
|
||||||
window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
|
window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
|
||||||
if (authResponse.signatureData) {
|
if ((currentpanel == 4) && authResponse.signatureData) {
|
||||||
Q('hwtokenInput').value = JSON.stringify(authResponse);
|
Q('hwtokenInput').value = JSON.stringify(authResponse);
|
||||||
QE('tokenOkButton', true);
|
QE('tokenOkButton', true);
|
||||||
Q('tokenOkButton').click();
|
Q('tokenOkButton').click();
|
||||||
|
@ -382,7 +387,7 @@
|
||||||
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) && u2fSupported()) {
|
if ((hardwareKeyChallenge != null) && u2fSupported()) {
|
||||||
window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
|
window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
|
||||||
if (authResponse.signatureData) {
|
if ((currentpanel == 5) && authResponse.signatureData) {
|
||||||
Q('resetHwtokenInput').value = JSON.stringify(authResponse);
|
Q('resetHwtokenInput').value = JSON.stringify(authResponse);
|
||||||
QE('resetTokenOkButton', true);
|
QE('resetTokenOkButton', true);
|
||||||
Q('resetTokenOkButton').click();
|
Q('resetTokenOkButton').click();
|
||||||
|
@ -407,6 +412,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function go(x) {
|
function go(x) {
|
||||||
|
currentpanel = x;
|
||||||
setDialogMode(0);
|
setDialogMode(0);
|
||||||
QV("showPassHintLink", false);
|
QV("showPassHintLink", false);
|
||||||
QV('loginpanel', x == 1);
|
QV('loginpanel', x == 1);
|
||||||
|
@ -451,7 +457,7 @@
|
||||||
QH('passWarning', '');
|
QH('passWarning', '');
|
||||||
QV('passwordPolicyCallout', false);
|
QV('passwordPolicyCallout', false);
|
||||||
} else {
|
} else {
|
||||||
if (passRequirements == null || passRequirements == '') {
|
if (!passRequirementsEx) {
|
||||||
// No password requirements, display password strength
|
// No password requirements, display password strength
|
||||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>Strong Password</b><span>'); }
|
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>Strong Password</b><span>'); }
|
||||||
|
@ -499,7 +505,7 @@
|
||||||
QH('rpassWarning', '');
|
QH('rpassWarning', '');
|
||||||
QV('rpasswordPolicyCallout', false);
|
QV('rpasswordPolicyCallout', false);
|
||||||
} else {
|
} else {
|
||||||
if (passRequirements == null || passRequirements == '') {
|
if (!passRequirementsEx) {
|
||||||
// No password requirements, display password strength
|
// No password requirements, display password strength
|
||||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>Strong Password</b><span>'); }
|
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>Strong Password</b><span>'); }
|
||||||
|
|
49
webserver.js
49
webserver.js
|
@ -578,9 +578,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
req.session.loginmode = '2';
|
req.session.loginmode = '2';
|
||||||
req.session.error = '<b style=color:#8C001A>Username already exists.</b>';
|
req.session.error = '<b style=color:#8C001A>Username already exists.</b>';
|
||||||
} else {
|
} else {
|
||||||
var hint = req.body.apasswordhint;
|
var user = { type: 'user', _id: 'user/' + domain.id + '/' + req.body.username.toLowerCase(), name: req.body.username, email: req.body.email, creation: Math.floor(Date.now() / 1000), login: Math.floor(Date.now() / 1000), domain: domain.id };
|
||||||
if (hint.length > 250) hint = hint.substring(0, 250);
|
if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true) && (req.body.apasswordhint)) { var hint = req.body.apasswordhint; if (hint.length > 250) { hint = hint.substring(0, 250); } user.passhint = hint; }
|
||||||
var user = { type: 'user', _id: 'user/' + domain.id + '/' + req.body.username.toLowerCase(), name: req.body.username, email: req.body.email, creation: Math.floor(Date.now() / 1000), login: Math.floor(Date.now() / 1000), domain: domain.id, passhint: hint };
|
|
||||||
var usercount = 0;
|
var usercount = 0;
|
||||||
for (var i in obj.users) { if (obj.users[i].domain == domain.id) { usercount++; } }
|
for (var i in obj.users) { if (obj.users[i].domain == domain.id) { usercount++; } }
|
||||||
if (usercount == 0) { user.siteadmin = 0xFFFFFFFF; if (domain.newaccounts === 2) { domain.newaccounts = 0; } } // If this is the first user, give the account site admin.
|
if (usercount == 0) { user.siteadmin = 0xFFFFFFFF; if (domain.newaccounts === 2) { domain.newaccounts = 0; } } // If this is the first user, give the account site admin.
|
||||||
|
@ -655,7 +654,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
user.salt = salt;
|
user.salt = salt;
|
||||||
user.hash = hash;
|
user.hash = hash;
|
||||||
user.passhint = req.body.rpasswordhint;
|
if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true)) { var hint = req.body.rpasswordhint; if (hint.length > 250) { hint = hint.substring(0, 250); } user.passhint = hint; } else { delete user.passhint; }
|
||||||
user.passchange = Math.floor(Date.now() / 1000);
|
user.passchange = Math.floor(Date.now() / 1000);
|
||||||
delete user.passtype;
|
delete user.passtype;
|
||||||
obj.db.SetUser(user);
|
obj.db.SetUser(user);
|
||||||
|
@ -812,7 +811,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
userinfo.hash = hash;
|
userinfo.hash = hash;
|
||||||
delete userinfo.passtype;
|
delete userinfo.passtype;
|
||||||
userinfo.passchange = Math.floor(Date.now() / 1000);
|
userinfo.passchange = Math.floor(Date.now() / 1000);
|
||||||
userinfo.passhint = null;
|
delete userinfo.passhint;
|
||||||
//delete userinfo.otpsecret; // Currently a email password reset will turn off 2-step login.
|
//delete userinfo.otpsecret; // Currently a email password reset will turn off 2-step login.
|
||||||
obj.db.SetUser(userinfo);
|
obj.db.SetUser(userinfo);
|
||||||
|
|
||||||
|
@ -925,11 +924,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
// Update the password
|
// Update the password
|
||||||
require('./pass').hash(req.body.apassword1, function (err, salt, hash) {
|
require('./pass').hash(req.body.apassword1, function (err, salt, hash) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
var hint = req.body.apasswordhint;
|
|
||||||
if (hint.length > 250) hint = hint.substring(0, 250);
|
|
||||||
user.salt = salt;
|
user.salt = salt;
|
||||||
user.hash = hash;
|
user.hash = hash;
|
||||||
user.passhint = req.body.apasswordhint;
|
if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true) && (req.body.apasswordhint)) { var hint = req.body.apasswordhint; if (hint.length > 250) hint = hint.substring(0, 250); user.passhint = hint; } else { delete user.passhint; }
|
||||||
user.passchange = Math.floor(Date.now() / 1000);
|
user.passchange = Math.floor(Date.now() / 1000);
|
||||||
delete user.passtype;
|
delete user.passtype;
|
||||||
obj.db.SetUser(user);
|
obj.db.SetUser(user);
|
||||||
|
@ -1070,22 +1067,23 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
|
|
||||||
// Give the web page a list of supported server features
|
// Give the web page a list of supported server features
|
||||||
features = 0;
|
features = 0;
|
||||||
if (obj.args.wanonly == true) { features += 0x0001; } // WAN-only mode
|
if (obj.args.wanonly == true) { features += 0x00000001; } // WAN-only mode
|
||||||
if (obj.args.lanonly == true) { features += 0x0002; } // LAN-only mode
|
if (obj.args.lanonly == true) { features += 0x00000002; } // LAN-only mode
|
||||||
if (obj.args.nousers == true) { features += 0x0004; } // Single user mode
|
if (obj.args.nousers == true) { features += 0x00000004; } // Single user mode
|
||||||
if (domain.userQuota == -1) { features += 0x0008; } // No server files mode
|
if (domain.userQuota == -1) { features += 0x00000008; } // No server files mode
|
||||||
if (obj.args.mpstlsoffload) { features += 0x0010; } // No mutual-auth CIRA
|
if (obj.args.mpstlsoffload) { features += 0x00000010; } // No mutual-auth CIRA
|
||||||
if ((parent.config != null) && (parent.config.settings != null) && (parent.config.settings.allowframing == true)) { features += 0x0020; } // Allow site within iframe
|
if ((parent.config != null) && (parent.config.settings != null) && (parent.config.settings.allowframing == true)) { features += 0x00000020; } // Allow site within iframe
|
||||||
if ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName != 'un-configured') && (obj.args.lanonly != true)) { features += 0x0040; } // Email invites
|
if ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName != 'un-configured') && (obj.args.lanonly != true)) { features += 0x00000040; } // Email invites
|
||||||
if (obj.args.webrtc == true) { features += 0x0080; } // Enable WebRTC (Default false for now)
|
if (obj.args.webrtc == true) { features += 0x00000080; } // Enable WebRTC (Default false for now)
|
||||||
if (obj.args.clickonce !== false) { features += 0x0100; } // Enable ClickOnce (Default true)
|
if (obj.args.clickonce !== false) { features += 0x00000100; } // Enable ClickOnce (Default true)
|
||||||
if (obj.args.allowhighqualitydesktop == true) { features += 0x0200; } // Enable AllowHighQualityDesktop (Default false)
|
if (obj.args.allowhighqualitydesktop == true) { features += 0x00000200; } // Enable AllowHighQualityDesktop (Default false)
|
||||||
if (obj.args.lanonly == true || obj.args.mpsport == 0) { features += 0x0400; } // No CIRA
|
if (obj.args.lanonly == true || obj.args.mpsport == 0) { features += 0x00000400; } // No CIRA
|
||||||
if ((obj.parent.serverSelfWriteAllowed == true) && (user != null) && (user.siteadmin == 0xFFFFFFFF)) { features += 0x0800; } // Server can self-write (Allows self-update)
|
if ((obj.parent.serverSelfWriteAllowed == true) && (user != null) && (user.siteadmin == 0xFFFFFFFF)) { features += 0x00000800; } // Server can self-write (Allows self-update)
|
||||||
if ((domain.auth != 'sspi') && (obj.parent.certificates.CommonName != 'un-configured') && (obj.args.nousers !== true)) { features += 0x1000; } // 2-step login supported
|
if ((domain.auth != 'sspi') && (obj.parent.certificates.CommonName != 'un-configured') && (obj.args.nousers !== true)) { features += 0x00001000; } // 2-step login supported
|
||||||
if (domain.agentnoproxy === true) { features += 0x2000; } // Indicates that agents should be installed without using a HTTP proxy
|
if (domain.agentnoproxy === true) { features += 0x00002000; } // Indicates that agents should be installed without using a HTTP proxy
|
||||||
if (domain.yubikey && domain.yubikey.id && domain.yubikey.secret) { features += 0x4000; } // Indicates Yubikey support
|
if (domain.yubikey && domain.yubikey.id && domain.yubikey.secret) { features += 0x00004000; } // Indicates Yubikey support
|
||||||
if (domain.geolocation == true) { features += 0x8000; } // Enable geo-location features
|
if (domain.geolocation == true) { features += 0x00008000; } // Enable geo-location features
|
||||||
|
if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true)) { features += 0x00010000; } // Enable password hints
|
||||||
|
|
||||||
// Create a authentication cookie
|
// Create a authentication cookie
|
||||||
const authCookie = obj.parent.encodeCookie({ userid: user._id, domainid: domain.id }, obj.parent.loginCookieEncryptionKey);
|
const authCookie = obj.parent.encodeCookie({ userid: user._id, domainid: domain.id }, obj.parent.loginCookieEncryptionKey);
|
||||||
|
@ -1151,7 +1149,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
if (req.session != null) {
|
if (req.session != null) {
|
||||||
err = req.session.error;
|
err = req.session.error;
|
||||||
msg = req.session.success;
|
msg = req.session.success;
|
||||||
passhint = req.session.passhint;
|
if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true)) { passhint = EscapeHtml(req.session.passhint); }
|
||||||
delete req.session.error;
|
delete req.session.error;
|
||||||
delete req.session.success;
|
delete req.session.success;
|
||||||
delete req.session.passhint;
|
delete req.session.passhint;
|
||||||
|
@ -1159,7 +1157,6 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
var message = '';
|
var message = '';
|
||||||
if (err != null) message = '<p class="msg error">' + err + '</p>';
|
if (err != null) message = '<p class="msg error">' + err + '</p>';
|
||||||
if (msg != null) message = '<p class="msg success">' + msg + '</p>';
|
if (msg != null) message = '<p class="msg success">' + msg + '</p>';
|
||||||
if (passhint != null) passhint = EscapeHtml(passhint);
|
|
||||||
var emailcheck = ((obj.parent.mailserver != null) && (domain.auth != 'sspi'));
|
var emailcheck = ((obj.parent.mailserver != null) && (domain.auth != 'sspi'));
|
||||||
|
|
||||||
if (obj.args.minify && !req.query.nominify) {
|
if (obj.args.minify && !req.query.nominify) {
|
||||||
|
|
Loading…
Reference in New Issue