Many small fixes.

This commit is contained in:
Ylian Saint-Hilaire 2020-01-12 13:50:06 -08:00
parent 3b5657650b
commit cc67941c98
9 changed files with 57 additions and 54 deletions

View File

@ -2256,7 +2256,7 @@ function mainStart() {
var modules = ['ws', 'cbor', 'nedb', 'https', 'yauzl', 'xmldom', 'ipcheck', 'express', 'archiver', 'multiparty', 'node-forge', 'express-ws', 'compression', 'body-parser', 'connect-redis', 'cookie-session', 'express-handlebars']; var modules = ['ws', 'cbor', 'nedb', 'https', 'yauzl', 'xmldom', 'ipcheck', 'express', 'archiver', 'multiparty', 'node-forge', 'express-ws', 'compression', 'body-parser', 'connect-redis', 'cookie-session', 'express-handlebars'];
if (require('os').platform() == 'win32') { modules.push('node-windows'); if (sspi == true) { modules.push('node-sspi'); } } // Add Windows modules if (require('os').platform() == 'win32') { modules.push('node-windows'); if (sspi == true) { modules.push('node-sspi'); } } // Add Windows modules
if (ldap == true) { modules.push('ldapauth-fork'); } if (ldap == true) { modules.push('ldapauth-fork'); }
if (config.letsencrypt != null) { if ((nodeVersion < 10) || (require('crypto').generateKeyPair == null)) { addServerWarning("Let's Encrypt support requires Node v10.12 or higher.", !args.launch); } else { modules.push('greenlock'); } } // Add Greenlock Module if (config.letsencrypt != null) { if ((nodeVersion < 10) || (require('crypto').generateKeyPair == null)) { addServerWarning("Let's Encrypt support requires Node v10.12 or higher.", !args.launch); } else { modules.push('greenlock@3.1.5'); } } // Add Greenlock Module
if (config.settings.mqtt != null) { modules.push('aedes'); } // Add MQTT Modules if (config.settings.mqtt != null) { modules.push('aedes'); } // Add MQTT Modules
if (config.settings.mongodb != null) { modules.push('mongodb'); } // Add MongoDB, official driver. if (config.settings.mongodb != null) { modules.push('mongodb'); } // Add MongoDB, official driver.
if (config.settings.vault != null) { modules.push('node-vault'); } // Add official HashiCorp's Vault module. if (config.settings.vault != null) { modules.push('node-vault'); } // Add official HashiCorp's Vault module.

View File

@ -1452,8 +1452,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if ((common.validateInt(command.quota, 0) || command.quota == null) && (command.quota != chguser.quota)) { chguser.quota = command.quota; if (chguser.quota == null) { delete chguser.quota; } change = 1; } if ((common.validateInt(command.quota, 0) || command.quota == null) && (command.quota != chguser.quota)) { chguser.quota = command.quota; if (chguser.quota == null) { delete chguser.quota; } change = 1; }
// Site admins can change any server rights, user managers can only change AccountLock, NoMeshCmd and NoNewGroups // Site admins can change any server rights, user managers can only change AccountLock, NoMeshCmd and NoNewGroups
var chgusersiteadmin = chguser.siteadmin ? chguser.siteadmin : 0; if (chguser._id !== user._id) { // We can't change our own siteadmin permissions.
if (((user.siteadmin == 0xFFFFFFFF) || ((user.siteadmin & 2) && (((chgusersiteadmin ^ command.siteadmin) & 0xFFFFFF1F) == 0))) && common.validateInt(command.siteadmin) && (chguser.siteadmin != command.siteadmin)) { chguser.siteadmin = command.siteadmin; change = 1; } var chgusersiteadmin = chguser.siteadmin ? chguser.siteadmin : 0;
if (((user.siteadmin == 0xFFFFFFFF) || ((user.siteadmin & 2) && (((chgusersiteadmin ^ command.siteadmin) & 0xFFFFFF1F) == 0))) && common.validateInt(command.siteadmin) && (chguser.siteadmin != command.siteadmin)) { chguser.siteadmin = command.siteadmin; change = 1; }
}
// Went sending a notification about a group change, we need to send to all the previous and new groups. // Went sending a notification about a group change, we need to send to all the previous and new groups.
var allTargetGroups = chguser.groups; var allTargetGroups = chguser.groups;

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.4.7-i", "version": "0.4.7-j",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

View File

@ -3390,7 +3390,7 @@
"de": "Das Ändern der Sprache erfordert eine Aktualisierung der Seite.", "de": "Das Ändern der Sprache erfordert eine Aktualisierung der Seite.",
"en": "Changing the language will require a refresh of the page.", "en": "Changing the language will require a refresh of the page.",
"ja": "言語を変更するには、ページを更新する必要があります。", "ja": "言語を変更するには、ページを更新する必要があります。",
"nl": "Als u de taal wilt wijzigen, moet de pagina worden vernieuwd.", "nl": "Als u de taal wilt wijzigen, moet de pagina worden ververst.",
"pt": "Alterar o idioma exigirá uma atualização da página.", "pt": "Alterar o idioma exigirá uma atualização da página.",
"ru": "Изменение языка потребует обновления страницы.", "ru": "Изменение языка потребует обновления страницы.",
"xloc": [ "xloc": [
@ -3778,7 +3778,7 @@
"de": "Bestätigen Sie das Kopieren von 1 Eintrag an diesen Ort?", "de": "Bestätigen Sie das Kopieren von 1 Eintrag an diesen Ort?",
"en": "Confirm copy of 1 entrie to this location?", "en": "Confirm copy of 1 entrie to this location?",
"ja": "この場所への1つのエントリのコピーを確認しますか", "ja": "この場所への1つのエントリのコピーを確認しますか",
"nl": "Bevestig kopie van 1 bestand naar deze locatie?", "nl": "Bevestig kopiëren van 1 bestand naar deze locatie?",
"pt": "Confirmar cópia de 1 entrada para este local?", "pt": "Confirmar cópia de 1 entrada para este local?",
"ru": "Подтвердить копию 1 записи в это место?", "ru": "Подтвердить копию 1 записи в это место?",
"xloc": [ "xloc": [
@ -3791,7 +3791,7 @@
"de": "Bestätigen Sie das Kopieren von {0} Einträgen an diesen Ort?", "de": "Bestätigen Sie das Kopieren von {0} Einträgen an diesen Ort?",
"en": "Confirm copy of {0} entries's to this location?", "en": "Confirm copy of {0} entries's to this location?",
"ja": "{0}エントリのコピーをこの場所に確認しますか?", "ja": "{0}エントリのコピーをこの場所に確認しますか?",
"nl": "Bevestig kopieën van {0} bestanden naar deze locatie?", "nl": "Bevestig kopiëren van {0} bestanden naar deze locatie?",
"pt": "Confirmar cópia de {0} entradas para este local?", "pt": "Confirmar cópia de {0} entradas para este local?",
"ru": "Подтвердить копию {0} записей в этом месте?", "ru": "Подтвердить копию {0} записей в этом месте?",
"xloc": [ "xloc": [
@ -4130,7 +4130,7 @@
"de": "Kopie", "de": "Kopie",
"en": "Copy", "en": "Copy",
"ja": "コピー", "ja": "コピー",
"nl": "Kopie", "nl": "Kopiëren",
"pt": "Copiar", "pt": "Copiar",
"ru": "Копировать", "ru": "Копировать",
"xloc": [ "xloc": [
@ -4743,7 +4743,7 @@
{ {
"de": "Benutzergruppe löschen", "de": "Benutzergruppe löschen",
"en": "Delete User Group", "en": "Delete User Group",
"nl": "Verdwijder de gebruikersgroep", "nl": "Verwijder de gebruikersgroep",
"xloc": [ "xloc": [
"default.handlebars->23->1277", "default.handlebars->23->1277",
"default.handlebars->23->1285" "default.handlebars->23->1285"
@ -5788,7 +5788,7 @@
{ {
"de": "Dupliziere Benutzergruppe", "de": "Dupliziere Benutzergruppe",
"en": "Duplicate User Group", "en": "Duplicate User Group",
"nl": "Duplicer Gebruikers Groep", "nl": "Dupliceer Gebruikers Groep",
"xloc": [ "xloc": [
"default.handlebars->23->1253" "default.handlebars->23->1253"
] ]
@ -13127,7 +13127,8 @@
] ]
}, },
{ {
"en": "Relay teller" "en": "Relay teller",
"nl": "Relay teller"
}, },
{ {
"cs": "Zapamatovat toto zařízení na 30 dní.", "cs": "Zapamatovat toto zařízení na 30 dní.",
@ -13541,7 +13542,7 @@
"en": "Reset devices", "en": "Reset devices",
"fr": "Réinitialiser les appareils", "fr": "Réinitialiser les appareils",
"ja": "デバイスをリセットする", "ja": "デバイスをリセットする",
"nl": "Reset apparaten", "nl": "Herstart apparaten",
"pt": "Redefinir dispositivos", "pt": "Redefinir dispositivos",
"ru": "Сбросить устройства", "ru": "Сбросить устройства",
"xloc": [ "xloc": [
@ -16011,7 +16012,7 @@
"de": "Diese Seite existiert nicht.", "de": "Diese Seite existiert nicht.",
"en": "This page does not exist", "en": "This page does not exist",
"ja": "このページは存在しません", "ja": "このページは存在しません",
"nl": "", "nl": "Deze pagina bestaat niet",
"pt": "Esta página não existe", "pt": "Esta página não existe",
"ru": "Страница не существует", "ru": "Страница не существует",
"xloc": [ "xloc": [
@ -16191,7 +16192,7 @@
"de": "Um dieses Konto zu löschen, geben Sie das Konto-Passwort in beide untenstehenden Eingabefelder ein und wählen Sie OK.", "de": "Um dieses Konto zu löschen, geben Sie das Konto-Passwort in beide untenstehenden Eingabefelder ein und wählen Sie OK.",
"en": "To delete this account, type in the account password in both boxes below and hit ok.", "en": "To delete this account, type in the account password in both boxes below and hit ok.",
"ja": "このアカウントを削除するには、下の両方のボックスにアカウントのパスワードを入力して[OK]をクリックします。", "ja": "このアカウントを削除するには、下の両方のボックスにアカウントのパスワードを入力して[OK]をクリックします。",
"nl": "Om dit account te verwijderen, typt u het accountwachtwoord in beide onderstaande vakken en drukt u op OK.", "nl": "Om dit account te verwijderen, typt u het accountwachtwoord in beide onderstaande vakken en klikt u op OK.",
"pt": "Para excluir esta conta, digite a senha da conta nas duas caixas abaixo e pressione ok.", "pt": "Para excluir esta conta, digite a senha da conta nas duas caixas abaixo e pressione ok.",
"ru": "Чтобы удалить эту учетную запись, введите пароль учетной записи в оба поля и нажмите ОК.", "ru": "Чтобы удалить эту учетную запись, введите пароль учетной записи в оба поля и нажмите ОК.",
"xloc": [ "xloc": [
@ -16215,7 +16216,7 @@
"de": "Zum Installieren, kopieren Sie den folgenden Befehl und führen Sie ihn in einem Root-Terminal aus.", "de": "Zum Installieren, kopieren Sie den folgenden Befehl und führen Sie ihn in einem Root-Terminal aus.",
"en": "To install, cut and paste the following command in a root terminal.", "en": "To install, cut and paste the following command in a root terminal.",
"ja": "インストールするには、ルートターミナルで次のコマンドをカットアンドペーストします。", "ja": "インストールするには、ルートターミナルで次のコマンドをカットアンドペーストします。",
"nl": "Om de volgende opdracht te installeren, knippen en plakken in een root-terminal.", "nl": "Om te installeren, knip en plak de volgende opdracht in de root-terminal.",
"pt": "Para instalar, recorte e cole o seguinte comando em um terminal raiz.", "pt": "Para instalar, recorte e cole o seguinte comando em um terminal raiz.",
"ru": "Для установки, вырежьте и вставьте следующую команду в root терминал.", "ru": "Для установки, вырежьте и вставьте следующую команду в root терминал.",
"xloc": [ "xloc": [
@ -16239,7 +16240,7 @@
"de": "Um einen Mesh-Agenten zu entfernen, führen Sie den folgenden Befehl aus. Root-Zugriff wird benötigt.", "de": "Um einen Mesh-Agenten zu entfernen, führen Sie den folgenden Befehl aus. Root-Zugriff wird benötigt.",
"en": "To remove a mesh agent, run the following command. Root credentials will be needed.", "en": "To remove a mesh agent, run the following command. Root credentials will be needed.",
"ja": "メッシュエージェントを削除するには、次のコマンドを実行します。ルート資格情報が必要になります。", "ja": "メッシュエージェントを削除するには、次のコマンドを実行します。ルート資格情報が必要になります。",
"nl": "Voer de volgende opdracht uit om een mesh-agent te verwijderen. Root gegevens zijn nodig.", "nl": "Voer de volgende opdracht uit om een mesh-agent te verwijderen. Root rechten zijn nodig.",
"pt": "Para remover um agente de malha, execute o seguinte comando. Serão necessárias credenciais raiz.", "pt": "Para remover um agente de malha, execute o seguinte comando. Serão necessárias credenciais raiz.",
"ru": "Для удаления mesh агента, выполните следующую команду. Root учетные данные будут необходимы.", "ru": "Для удаления mesh агента, выполните следующую команду. Root учетные данные будут необходимы.",
"xloc": [ "xloc": [
@ -18333,7 +18334,7 @@
"de": "kopieren", "de": "kopieren",
"en": "copy", "en": "copy",
"ja": "コピー", "ja": "コピー",
"nl": "kopieren", "nl": "kopiëren",
"pt": "Copiar", "pt": "Copiar",
"ru": "копировать", "ru": "копировать",
"xloc": [ "xloc": [

View File

@ -822,7 +822,7 @@
var secret = message.secret; var secret = message.secret;
if (secret.length == 52) { secret = secret.split(/(.............)/).filter(Boolean).join(' '); } if (secret.length == 52) { secret = secret.split(/(.............)/).filter(Boolean).join(' '); }
else if (secret.length == 32) { secret = secret.split(/(....)/).filter(Boolean).join(' '); secret = secret.substring(0, 20) + '<br/>' + secret.substring(20) } else if (secret.length == 32) { secret = secret.split(/(....)/).filter(Boolean).join(' '); secret = secret.substring(0, 20) + '<br/>' + secret.substring(20) }
QH('d2optinfo', format("Install <a href=\"https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2\" rel=\"noreferrer noopener\" target=_blank>Google Authenticator</a> or a compatible application, use <a href=\"{0}\" rel=\"noreferrer noopener\" target=_blank> this link</a> or enter the secret below. Then, enter the current 6 digit token to activate 2-Step login.", message.url) + '<br /><br /><div style=width:100%;text-align:center><tt id=d2optsecret secret=\"' + message.secret + '\" style=font-size:15px>' + secret + '</tt><br /><br />Token: <input type=text onkeypress=\"return (event.keyCode == 8) || (event.charCode >= 48 && event.charCode <= 57)\" onkeyup=account_addOtpCheck(event) onkeydown=account_addOtpCheck() maxlength=6 id=d2otpauthinput type=text></div>'); QH('d2optinfo', format("Install <a href=\"https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2\" rel=\"noreferrer noopener\" target=_blank>Google Authenticator</a> or a compatible application, use <a href=\"{0}\" rel=\"noreferrer noopener\" target=_blank> this link</a> or enter the secret below. Then, enter the current 6 digit token to activate 2-Step login.", message.url) + '<br /><br /><div style=width:100%;text-align:center><tt id=d2optsecret secret=\"' + message.secret + '\" style=font-size:15px>' + secret + '</tt><br /><br />Token: <input type=text autocomplete="one-time-code" inputmode="numeric" pattern="[0-9]*" onkeypress=\"return (event.keyCode == 8) || (event.charCode >= 48 && event.charCode <= 57)\" onkeyup=account_addOtpCheck(event) onkeydown=account_addOtpCheck() maxlength=6 id=d2otpauthinput type=text></div>');
QV('idx_dlgOkButton', true); QV('idx_dlgOkButton', true);
QE('idx_dlgOkButton', false); QE('idx_dlgOkButton', false);
Q('d2otpauthinput').focus(); Q('d2otpauthinput').focus();

View File

@ -2032,7 +2032,7 @@
var secret = message.secret; var secret = message.secret;
if (secret.length == 52) { secret = secret.split(/(.............)/).filter(Boolean).join(' '); } if (secret.length == 52) { secret = secret.split(/(.............)/).filter(Boolean).join(' '); }
else if (secret.length == 32) { secret = secret.split(/(....)/).filter(Boolean).join(' '); secret = secret.substring(0, 20) + '<br/>' + secret.substring(20) } else if (secret.length == 32) { secret = secret.split(/(....)/).filter(Boolean).join(' '); secret = secret.substring(0, 20) + '<br/>' + secret.substring(20) }
QH('d2optinfo', '<table style=width:380px><tr><td style=vertical-align:top>' + format("Install <a href=\"https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2\" rel=\"noreferrer noopener\" target=_blank>Google Authenticator</a> or a compatible application and scan the barcode, use <a href=\"{0}\" rel=\"noreferrer noopener\" target=_blank>this link</a> or enter the secret. Then, enter the current 6 digit token below to activate 2-Step login.", message.url) + '<br /><br />Secret<br /><tt id=d2optsecret secret=\"' + message.secret + '\" style=font-size:12px>' + secret + '</tt><br /><br /></td><td style=width:1px;vertical-align:top><a href=\"' + message.url + '\" rel=\"noreferrer noopener\" target=_blank><div id="qrcode"></div></a></td><tr><td colspan=2 style="text-align:center;border-top:1px solid black"><br />' + "Enter the token here for 2-step login:" + ' <input type=text onkeypress=\"return (event.keyCode == 8) || (event.charCode >= 48 && event.charCode <= 57)\" onkeyup=account_addOtpCheck(event) onkeydown=account_addOtpCheck() maxlength=6 id=d2otpauthinput type=text></td></table>'); QH('d2optinfo', '<table style=width:380px><tr><td style=vertical-align:top>' + format("Install <a href=\"https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2\" rel=\"noreferrer noopener\" target=_blank>Google Authenticator</a> or a compatible application and scan the barcode, use <a href=\"{0}\" rel=\"noreferrer noopener\" target=_blank>this link</a> or enter the secret. Then, enter the current 6 digit token below to activate 2-Step login.", message.url) + '<br /><br />Secret<br /><tt id=d2optsecret secret=\"' + message.secret + '\" style=font-size:12px>' + secret + '</tt><br /><br /></td><td style=width:1px;vertical-align:top><a href=\"' + message.url + '\" rel=\"noreferrer noopener\" target=_blank><div id="qrcode"></div></a></td><tr><td colspan=2 style="text-align:center;border-top:1px solid black"><br />' + "Enter the token here for 2-step login:" + ' <input type=text autocomplete="one-time-code" inputmode="numeric" pattern="[0-9]*" onkeypress=\"return (event.keyCode == 8) || (event.charCode >= 48 && event.charCode <= 57)\" onkeyup=account_addOtpCheck(event) onkeydown=account_addOtpCheck() maxlength=6 id=d2otpauthinput type=text></td></table>');
new QRCode(Q('qrcode'), { text: message.url, width: 128, height: 128, colorDark: '#000000', colorLight: '#EEE', correctLevel: QRCode.CorrectLevel.H }); new QRCode(Q('qrcode'), { text: message.url, width: 128, height: 128, colorDark: '#000000', colorLight: '#EEE', correctLevel: QRCode.CorrectLevel.H });
QV('idx_dlgOkButton', true); QV('idx_dlgOkButton', true);
QE('idx_dlgOkButton', false); QE('idx_dlgOkButton', false);
@ -9036,6 +9036,9 @@
if (xxdialogMode) return; if (xxdialogMode) return;
haltEvent(e); haltEvent(e);
userid = decodeURIComponent(userid); userid = decodeURIComponent(userid);
var user = users[userid.toLowerCase()];
if (user == null) return;
var uself = (userinfo._id == user._id);
var x = '<div><div id=d2AdminPermissions>'; var x = '<div><div id=d2AdminPermissions>';
x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_fileaccess>' + "Server Files" + '</label>, <input type=number onchange=showUserAdminDialogValidate() maxlength=10 id=ua_fileaccessquota>k max, blank for default<br><hr/>'; x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_fileaccess>' + "Server Files" + '</label>, <input type=number onchange=showUserAdminDialogValidate() maxlength=10 id=ua_fileaccessquota>k max, blank for default<br><hr/>';
x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_fulladmin>' + "Full Administrator" + '</label><br>'; x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_fulladmin>' + "Full Administrator" + '</label><br>';
@ -9048,8 +9051,7 @@
x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_nonewgroups>' + "No New Device Groups" + '</label><br>'; x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_nonewgroups>' + "No New Device Groups" + '</label><br>';
x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_nomeshcmd>' + "No Tools (MeshCmd/Router)" + '</label><br>'; x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_nomeshcmd>' + "No Tools (MeshCmd/Router)" + '</label><br>';
x += '</div>'; x += '</div>';
var user = users[userid.toLowerCase()]; setDialogMode(2, "Server Permissions", 2 + (uself?0:1), showUserAdminDialogEx, x, user);
setDialogMode(2, "Server Permissions", 3, showUserAdminDialogEx, x, user);
if (user.siteadmin && user.siteadmin != 0) { if (user.siteadmin && user.siteadmin != 0) {
Q('ua_fulladmin').checked = (user.siteadmin == 0xFFFFFFFF); Q('ua_fulladmin').checked = (user.siteadmin == 0xFFFFFFFF);
Q('ua_serverbackup').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1) != 0)); // Server Backup Q('ua_serverbackup').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1) != 0)); // Server Backup
@ -9062,18 +9064,18 @@
Q('ua_nomeshcmd').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 128) != 0)); // No Tools (MeshCMD / Router) Q('ua_nomeshcmd').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 128) != 0)); // No Tools (MeshCMD / Router)
Q('ua_manageusergroups').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 256) != 0)); // Manage User Groups Q('ua_manageusergroups').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 256) != 0)); // Manage User Groups
} }
QE('ua_fulladmin', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_fulladmin', !uself && (userinfo.siteadmin == 0xFFFFFFFF));
QE('ua_serverbackup', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_serverbackup', !uself && (userinfo.siteadmin == 0xFFFFFFFF));
QE('ua_manageusers', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_manageusers', !uself && (userinfo.siteadmin == 0xFFFFFFFF));
QE('ua_manageusergroups', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_manageusergroups', !uself && (userinfo.siteadmin == 0xFFFFFFFF));
QE('ua_serverrestore', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_serverrestore', !uself && (userinfo.siteadmin == 0xFFFFFFFF));
QE('ua_fileaccess', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_fileaccess', !uself && (userinfo.siteadmin == 0xFFFFFFFF));
QE('ua_fileaccessquota', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_fileaccessquota', !uself && (userinfo.siteadmin == 0xFFFFFFFF));
QE('ua_serverupdate', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_serverupdate', !uself && (userinfo.siteadmin == 0xFFFFFFFF));
QV('d2AdminPermissions', userinfo.siteadmin == 0xFFFFFFFF) QV('d2AdminPermissions', userinfo.siteadmin == 0xFFFFFFFF)
QE('ua_lockedaccount', (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id)); QE('ua_lockedaccount', !uself && (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id));
QE('ua_nonewgroups', (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id)); QE('ua_nonewgroups', !uself && (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id));
QE('ua_nomeshcmd', (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id)); QE('ua_nomeshcmd', !uself && (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id));
Q('ua_fileaccessquota').value = (user.quota != null)?(user.quota / 1024):''; Q('ua_fileaccessquota').value = (user.quota != null)?(user.quota / 1024):'';
showUserAdminDialogValidate(); showUserAdminDialogValidate();
return false; return false;
@ -9961,12 +9963,12 @@
window.serverStatCpu = new Chart(document.getElementById('serverCpuChart').getContext('2d'), { window.serverStatCpu = new Chart(document.getElementById('serverCpuChart').getContext('2d'), {
type: 'doughnut', type: 'doughnut',
data: { datasets: [{ data: [0, 0], backgroundColor: ['#AAAAAA', '#00AA00'] }], labels: ["Used", "Free"] }, data: { datasets: [{ data: [0, 0], backgroundColor: ['#AAAAAA', '#00AA00'] }], labels: ["Used", "Free"] },
options: { responsive: true, legend: { position: 'none', }, animation: { animateScale: true, animateRotate: true }, width: '60px' } options: { events: [], responsive: true, legend: { position: 'none', }, animation: { animateScale: true, animateRotate: true }, width: '60px' }
}); });
window.serverStatMemory = new Chart(document.getElementById('serverMemoryChart').getContext('2d'), { window.serverStatMemory = new Chart(document.getElementById('serverMemoryChart').getContext('2d'), {
type: 'doughnut', type: 'doughnut',
data: { datasets: [{ data: [0, 0], backgroundColor: ['#AAAAAA', '#00AA00'] }], labels: ["Used", "Free"] }, data: { datasets: [{ data: [0, 0], backgroundColor: ['#AAAAAA', '#00AA00'] }], labels: ["Used", "Free"] },
options: { responsive: true, legend: { position: 'none', }, animation: { animateScale: true, animateRotate: true }, width: '60px' } options: { events: [], responsive: true, legend: { position: 'none', }, animation: { animateScale: true, animateRotate: true }, width: '60px' }
}); });
} }

View File

@ -53,11 +53,11 @@
<table> <table>
<tr> <tr>
<td id=loginusername align=right width=100>Username:</td> <td id=loginusername align=right width=100>Username:</td>
<td><input id=username type=text maxlength=64 name=username onchange=validateLogin(1) onkeyup=validateLogin(1,event) /></td> <td><input id=username type=text autocomplete="username" maxlength=64 name=username onchange=validateLogin(1) onkeyup=validateLogin(1,event) /></td>
</tr> </tr>
<tr> <tr>
<td align=right>Password:</td> <td align=right>Password:</td>
<td><input id=password type=password maxlength=256 name=password autocomplete=off onchange=validateLogin(2) onkeyup=validateLogin(2,event) /></td> <td><input id=password type=password autocomplete="current-password" maxlength=256 name=password autocomplete=off onchange=validateLogin(2) onkeyup=validateLogin(2,event) /></td>
</tr> </tr>
<tr> <tr>
<td><div id=showPassHintLink style=display:none><a onclick=showPassHint() style="cursor:pointer">Show Hint</a></div></td> <td><div id=showPassHintLink style=display:none><a onclick=showPassHint() style="cursor:pointer">Show Hint</a></div></td>
@ -86,19 +86,19 @@
<table> <table>
<tr id="nuUserRow"> <tr id="nuUserRow">
<td align=right width=100>Username:</td> <td align=right width=100>Username:</td>
<td><input id=ausername type=text name=username onchange=validateCreate(1) maxlength=64 onkeydown=haltReturn(event) onkeyup=validateCreate(1,event) /></td> <td><input id=ausername type=text autocomplete="username" name=username onchange=validateCreate(1) maxlength=64 onkeydown=haltReturn(event) onkeyup=validateCreate(1,event) /></td>
</tr> </tr>
<tr> <tr>
<td align=right width=100>Email:</td> <td align=right width=100>Email:</td>
<td><input id=aemail type=text name=email onchange=validateCreate(2) maxlength=256 onkeydown=haltReturn(event) onkeyup=validateCreate(2,event) /></td> <td><input id=aemail type=text autocomplete="email" inputmode="email" name=email onchange=validateCreate(2) maxlength=256 onkeydown=haltReturn(event) onkeyup=validateCreate(2,event) /></td>
</tr> </tr>
<tr> <tr>
<td align=right>Password:</td> <td align=right>Password:</td>
<td><input id=apassword1 type=password name=password1 autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(3) onkeyup=validateCreate(3,event) /></td> <td><input id=apassword1 type=password autocomplete="current-password" name=password1 maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(3) onkeyup=validateCreate(3,event) /></td>
</tr> </tr>
<tr> <tr>
<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 autocomplete="current-password" name=password2 maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(4) onkeyup=validateCreate(4,event) /></td>
</tr> </tr>
<tr id="createPanelHint" style="display:none"> <tr id="createPanelHint" style="display:none">
<td align=right>Pass Hint:</td> <td align=right>Pass Hint:</td>
@ -130,7 +130,7 @@
<table> <table>
<tr> <tr>
<td align=right width=100>Email:</td> <td align=right width=100>Email:</td>
<td><input id=remail type=text name=email maxlength=256 onchange=validateReset() onkeyup=validateReset(event) /></td> <td><input id=remail type=text inputmode="email" autocomplete="email" name=email maxlength=256 onchange=validateReset() onkeyup=validateReset(event) /></td>
</tr> </tr>
<tr> <tr>
<td colspan=2> <td colspan=2>
@ -152,7 +152,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) onfocus=checkTokenTimer(1) onblur=checkTokenTimer(0) /> <input id=tokenInput type=text autocomplete="one-time-code" inputmode="numeric" pattern="[0-9]*" 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>
@ -172,7 +172,6 @@
<input id=tokenformargs name="urlargs" type="hidden" value="" /> <input id=tokenformargs name="urlargs" type="hidden" value="" />
</form> </form>
</div> </div>
<div id=resettokenpanel style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both"> <div id=resettokenpanel style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
<form method=post autocomplete=off> <form method=post autocomplete=off>
<input type=hidden name=action value=resetaccount /> <input type=hidden name=action value=resetaccount />
@ -195,7 +194,6 @@
<input id=resettokenformargs name="urlargs" type="hidden" value="" /> <input id=resettokenformargs name="urlargs" type="hidden" value="" />
</form> </form>
</div> </div>
<div id=resetpasswordpanel style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <div id=resetpasswordpanel style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
<form method=post> <form method=post>
<input type=hidden name=action value=resetpassword /> <input type=hidden name=action value=resetpassword />

View File

@ -51,11 +51,11 @@
<table> <table>
<tr> <tr>
<td id=loginusername align=right width=100>Username:</td> <td id=loginusername align=right width=100>Username:</td>
<td><input id=username type=text maxlength=64 name=username onchange=validateLogin(1) onkeyup=validateLogin(1,event) /></td> <td><input id=username autocomplete="username" type=text maxlength=64 name=username onchange=validateLogin(1) onkeyup=validateLogin(1,event) /></td>
</tr> </tr>
<tr> <tr>
<td align=right>Password:</td> <td align=right>Password:</td>
<td><input id=password type=password maxlength=256 name=password autocomplete=off onchange=validateLogin(2) onkeyup=validateLogin(2,event) /></td> <td><input id=password autocomplete="current-password" type=password maxlength=256 name=password onchange=validateLogin(2) onkeyup=validateLogin(2,event) /></td>
</tr> </tr>
<tr> <tr>
<td><div id=showPassHintLink style=display:none><a onclick="return showPassHint(event);" href="#" style="cursor:pointer">Show Hint</a></div></td> <td><div id=showPassHintLink style=display:none><a onclick="return showPassHint(event);" href="#" style="cursor:pointer">Show Hint</a></div></td>
@ -83,19 +83,19 @@
<table> <table>
<tr id="nuUserRow"> <tr id="nuUserRow">
<td id="nuUser" align=right width=100>Username:</td> <td id="nuUser" align=right width=100>Username:</td>
<td><input id=ausername type=text name=username onchange=validateCreate(1) maxlength=64 onkeydown=haltReturn(event) onkeyup=validateCreate(1,event) /></td> <td><input id=ausername type=text autocomplete="username" name=username onchange=validateCreate(1) maxlength=64 onkeydown=haltReturn(event) onkeyup=validateCreate(1,event) /></td>
</tr> </tr>
<tr> <tr>
<td id="nuEmail" align=right width=100>Email:</td> <td id="nuEmail" align=right width=100>Email:</td>
<td><input id=aemail type=text name=email onchange=validateCreate(2) maxlength=256 onkeydown=haltReturn(event) onkeyup=validateCreate(2,event) /></td> <td><input id=aemail type=text autocomplete="email" inputmode="email" name=email onchange=validateCreate(2) maxlength=256 onkeydown=haltReturn(event) onkeyup=validateCreate(2,event) /></td>
</tr> </tr>
<tr> <tr>
<td id="nuPass1" align=right>Password:</td> <td id="nuPass1" align=right>Password:</td>
<td><input id=apassword1 type=password name=password1 autocomplete=off maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(3,event) onkeyup=validateCreate(3,event) /></td> <td><input id=apassword1 type=password name=password1 autocomplete="new-password" maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(3,event) onkeyup=validateCreate(3,event) /></td>
</tr> </tr>
<tr> <tr>
<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="new-password" maxlength=256 onkeydown=haltReturn(event) onchange=validateCreate(4,event) onkeyup=validateCreate(4,event) /></td>
</tr> </tr>
<tr id="createPanelHint" style="display:none"> <tr id="createPanelHint" style="display:none">
<td id="nuHint" align=right>Password Hint:</td> <td id="nuHint" align=right>Password Hint:</td>
@ -126,7 +126,7 @@
<table> <table>
<tr> <tr>
<td align=right width=100>Email:</td> <td align=right width=100>Email:</td>
<td><input id=remail type=text name=email maxlength=256 onchange=validateReset() onkeyup=validateReset(event) /></td> <td><input id=remail type=text inputmode="email" name=email maxlength=256 onchange=validateReset() onkeyup=validateReset(event) /></td>
</tr> </tr>
<tr> <tr>
<td colspan=2> <td colspan=2>
@ -148,7 +148,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) onpaste=resetCheckToken(event) onkeyup=checkToken(event) onkeydown=checkToken(event) /><br /> <input id=tokenInput autocomplete="one-time-code" inputmode="numeric" pattern="[0-9]*" 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>

View File

@ -1546,7 +1546,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true)) { features += 0x00000040; } // Email invites if ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true)) { features += 0x00000040; } // Email invites
if (obj.args.webrtc == true) { features += 0x00000080; } // 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 += 0x00000100; } // Enable ClickOnce (Default true) if (obj.args.clickonce !== false) { features += 0x00000100; } // Enable ClickOnce (Default true)
if (obj.args.allowhighqualitydesktop == true) { features += 0x00000200; } // Enable AllowHighQualityDesktop (Default false) if (obj.args.allowhighqualitydesktop !== false) { features += 0x00000200; } // Enable AllowHighQualityDesktop (Default true)
if (obj.args.lanonly == true || obj.args.mpsport == 0) { features += 0x00000400; } // 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 += 0x00000800; } // 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 ((parent.config.settings.no2factorauth !== true) && (domain.auth != 'sspi') && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.nousers !== true)) { features += 0x00001000; } // 2-step login supported if ((parent.config.settings.no2factorauth !== true) && (domain.auth != 'sspi') && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.nousers !== true)) { features += 0x00001000; } // 2-step login supported
@ -3410,7 +3410,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
'Referrer-Policy': 'no-referrer', 'Referrer-Policy': 'no-referrer',
'X-XSS-Protection': '1; mode=block', 'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff', 'X-Content-Type-Options': 'nosniff',
'Content-Security-Policy': "default-src 'none'; script-src 'self' 'unsafe-inline'; connect-src 'self'" + geourl + selfurl + "; img-src 'self'" + geourl + " data:; style-src 'self' 'unsafe-inline'; frame-src 'self'; media-src 'self'; base-url: 'none'; form-action 'self'" 'Content-Security-Policy': "default-src 'none'; script-src 'self' 'unsafe-inline'; connect-src 'self'" + geourl + selfurl + "; img-src 'self'" + geourl + " data:; style-src 'self' 'unsafe-inline'; frame-src 'self'; media-src 'self'; form-action 'self'"
}; };
if ((parent.config.settings.allowframing !== true) && (typeof parent.config.settings.allowframing !== 'string')) { headers['X-Frame-Options'] = 'sameorigin'; } if ((parent.config.settings.allowframing !== true) && (typeof parent.config.settings.allowframing !== 'string')) { headers['X-Frame-Options'] = 'sameorigin'; }
res.set(headers); res.set(headers);