Added multi-language support for user notifications.

Ylian Saint-Hilaire committed Jan 4, 2021 at 01:38 UTC e86459ebf29f9754de77b91fa4ca28ff957f9238
3 files changed +398 -127
meshuser.js
+41 -39
@@ -488,7 +488,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
488 const lastLoginTime = parent.users[user._id].pastlogin;
489 if (lastLoginTime != null) {
490 db.GetFailedLoginCount(user.name, user.domain, new Date(lastLoginTime * 1000), function (count) {
491 - if (count > 0) { try { ws.send(JSON.stringify({ action: 'msg', type: 'notify', title: "Security Warning", tag: 'ServerNotify', id: Math.random(), value: "There has been " + count + " failed login attempts on this account since the last login." })); } catch (ex) { } delete user.pastlogin; }
491 + if (count > 0) { try { ws.send(JSON.stringify({ action: 'msg', type: 'notify', title: "Security Warning", tag: 'ServerNotify', id: Math.random(), value: "There has been " + count + " failed login attempts on this account since the last login.", titleid: 3, msgid: 12, args: [count] })); } catch (ex) { } delete user.pastlogin; }
492 });
493 }
494
@@ -1540,7 +1540,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1540 db.GetUserWithVerifiedEmail(domain.id, command.email, function (err, docs) {
1541 if ((docs != null) && (docs.length > 0)) {
1542 // Notify the duplicate email error
1543 - try { ws.send(JSON.stringify({ action: 'msg', type: 'notify', title: 'Account Settings', id: Math.random(), tag: 'ServerNotify', value: 'Failed to change email address, another account already using: ' + command.email + '.' })); } catch (ex) { }
1543 + try { ws.send(JSON.stringify({ action: 'msg', type: 'notify', title: 'Account Settings', id: Math.random(), tag: 'ServerNotify', value: 'Failed to change email address, another account already using: ' + command.email + '.', titleid: 4, msgid: 13, args: [command.email] })); } catch (ex) { }
1544 } else {
1545 // Update the user's email
1546 var oldemail = user.email;
@@ -1815,7 +1815,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1815 // Account count exceed, do notification
1816
1817 // Create the notification message
1818 - var notification = { action: 'msg', type: 'notify', id: Math.random(), value: "Account limit reached.", title: "Server Limit", userid: user._id, username: user.name, domain: domain.id };
1818 + var notification = { action: 'msg', type: 'notify', id: Math.random(), value: "Account limit reached.", title: "Server Limit", userid: user._id, username: user.name, domain: domain.id, titleid: 2, msgid: 10 };
1819
1820 // Get the list of sessions for this user
1821 var sessions = parent.wssessions[user._id];
@@ -1870,36 +1870,36 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1870 if (command.randomPassword === true) { command.pass = getRandomPassword(); }
1871
1872 // Add a new user account
1873 - var err = null, newusername, newuserid, newuserdomain;
1873 + var err = null, errid = 0, newusername, newuserid, newuserdomain;
1874 try {
1875 - if ((user.siteadmin & 2) == 0) { err = 'Permission denied'; }
1876 - else if (common.validateUsername(command.username, 1, 256) == false) { err = 'Invalid username'; } // Username is between 1 and 64 characters, no spaces
1877 - else if ((command.username[0] == '~') || (command.username.indexOf('/') >= 0)) { err = 'Invalid username'; } // Usernames cant' start with ~ and can't have '/'
1878 - else if (common.validateString(command.pass, 1, 256) == false) { err = 'Invalid password'; } // Password is between 1 and 256 characters
1879 - else if ((command.randomPassword !== true) && (common.checkPasswordRequirements(command.pass, domain.passwordrequirements) == false)) { err = 'Invalid password'; } // Password does not meet requirements
1880 - else if ((command.email != null) && (common.validateEmail(command.email, 1, 1024) == false)) { err = 'Invalid email'; } // Check if this is a valid email address
1881 - else if ((obj.crossDomain === true) && (command.domain != null) && ((typeof command.domain != 'string') || (parent.parent.config.domains[command.domain] == null))) { err = 'Invalid domain'; } // Check if this is a valid domain
1875 + if ((user.siteadmin & 2) == 0) { err = "Permission denied"; errid = 1; }
1876 + else if (common.validateUsername(command.username, 1, 256) == false) { err = "Invalid username"; errid = 2; } // Username is between 1 and 64 characters, no spaces
1877 + else if ((command.username[0] == '~') || (command.username.indexOf('/') >= 0)) { err = "Invalid username"; errid = 2; } // Usernames cant' start with ~ and can't have '/'
1878 + else if (common.validateString(command.pass, 1, 256) == false) { err = "Invalid password"; errid = 3; } // Password is between 1 and 256 characters
1879 + else if ((command.randomPassword !== true) && (common.checkPasswordRequirements(command.pass, domain.passwordrequirements) == false)) { err = "Invalid password"; errid = 3; } // Password does not meet requirements
1880 + else if ((command.email != null) && (common.validateEmail(command.email, 1, 1024) == false)) { err = "Invalid email"; errid = 4; } // Check if this is a valid email address
1881 + else if ((obj.crossDomain === true) && (command.domain != null) && ((typeof command.domain != 'string') || (parent.parent.config.domains[command.domain] == null))) { err = "Invalid domain"; errid = 5; } // Check if this is a valid domain
1882 else {
1883 newuserdomain = domain;
1884 if ((obj.crossDomain === true) && (command.domain != null)) { newuserdomain = parent.parent.config.domains[command.domain]; }
1885 newusername = command.username;
1886 newuserid = 'user/' + newuserdomain.id + '/' + command.username.toLowerCase();
1887 if (command.siteadmin != null) {
1888 - if ((typeof command.siteadmin != 'number') || (Number.isInteger(command.siteadmin) == false)) { err = 'Invalid site permissions'; } // Check permissions
1889 - else if ((user.siteadmin != SITERIGHT_ADMIN) && ((command.siteadmin & (SITERIGHT_ADMIN - 224)) != 0)) { err = 'Invalid site permissions'; }
1888 + if ((typeof command.siteadmin != 'number') || (Number.isInteger(command.siteadmin) == false)) { err = "Invalid site permissions"; errid = 6; } // Check permissions
1889 + else if ((user.siteadmin != SITERIGHT_ADMIN) && ((command.siteadmin & (SITERIGHT_ADMIN - 224)) != 0)) { err = "Invalid site permissions"; errid = 6; }
1890 }
1891 - if (parent.users[newuserid]) { err = 'User already exists'; } // Account already exists
1892 - else if ((newuserdomain.auth == 'sspi') || (newuserdomain.auth == 'ldap')) { err = 'Unable to add user in this mode'; }
1891 + if (parent.users[newuserid]) { err = "User already exists"; errid = 7; } // Account already exists
1892 + else if ((newuserdomain.auth == 'sspi') || (newuserdomain.auth == 'ldap')) { err = "Unable to add user in this mode"; errid = 8; }
1893 }
1894 - } catch (ex) { err = 'Validation exception'; }
1894 + } catch (ex) { err = "Validation exception"; errid = 9; }
1895
1896 // Handle any errors
1897 if (err != null) {
1898 if (command.responseid != null) {
1899 - try { ws.send(JSON.stringify({ action: 'adduser', responseid: command.responseid, result: err })); } catch (ex) { }
1899 + try { ws.send(JSON.stringify({ action: 'adduser', responseid: command.responseid, result: err, msgid: errid })); } catch (ex) { }
1900 } else {
1901 // Send error back, user not found.
1902 - displayNotificationMessage(err, 'New Account', 'ServerNotify');
1902 + displayNotificationMessage(err, "New Account", 'ServerNotify', null, 1, errid);
1903 }
1904 break;
1905 }
@@ -1913,7 +1913,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1913 try { ws.send(JSON.stringify({ action: 'adduser', responseid: command.responseid, result: 'maxUsersExceed' })); } catch (ex) { }
1914 } else {
1915 // Create the notification message
1916 - var notification = { action: 'msg', type: 'notify', id: Math.random(), value: "Account limit reached.", title: "Server Limit", userid: user._id, username: user.name, domain: newuserdomain.id };
1916 + var notification = { action: 'msg', type: 'notify', id: Math.random(), value: "Account limit reached.", title: "Server Limit", userid: user._id, username: user.name, domain: newuserdomain.id, titleid: 2, msgid: 10 };
1917
1918 // Get the list of sessions for this user
1919 var sessions = parent.wssessions[user._id];
@@ -2420,7 +2420,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2420
2421 if (unknownUsers.length > 0) {
2422 // Send error back, user not found.
2423 - displayNotificationMessage('User' + ((unknownUsers.length > 1) ? 's' : '') + ' ' + EscapeHtml(unknownUsers.join(', ')) + ' not found.', 'Device Group', 'ServerNotify');
2423 + displayNotificationMessage('User' + ((unknownUsers.length > 1) ? 's' : '') + ' ' + EscapeHtml(unknownUsers.join(', ')) + ' not found.', "Device Group", 'ServerNotify', 5, (unknownUsers.length > 1) ? 16 : 15, [EscapeHtml(unknownUsers.join(', '))]);
2424 }
2425 }
2426
@@ -2553,16 +2553,16 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2553 parent.checkOldUserPasswords(domain, user, command.newpass, function (result) {
2554 if (result == 1) {
2555 // Send user notification of error
2556 - displayNotificationMessage('Error, unable to change to previously used password.', 'Account Settings', 'ServerNotify');
2556 + displayNotificationMessage("Error, unable to change to previously used password.", "Account Settings", 'ServerNotify', 4, 17);
2557 } else if (result == 2) {
2558 // Send user notification of error
2559 - displayNotificationMessage('Error, unable to change to commonly used password.', 'Account Settings', 'ServerNotify');
2559 + displayNotificationMessage("Error, unable to change to commonly used password.", "Account Settings", 'ServerNotify', 4, 18);
2560 } else {
2561 // Update the password
2562 require('./pass').hash(command.newpass, function (err, salt, hash, tag) {
2563 if (err) {
2564 // Send user notification of error
2565 - displayNotificationMessage('Error, password not changed.', 'Account Settings', 'ServerNotify');
2565 + displayNotificationMessage("Error, password not changed.", "Account Settings", 'ServerNotify', 4, 19);
2566 } else {
2567 const nowSeconds = Math.floor(Date.now() / 1000);
2568
@@ -2592,7 +2592,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2592 parent.parent.DispatchEvent(targets, obj, event);
2593
2594 // Send user notification of password change
2595 - displayNotificationMessage('Password changed.', 'Account Settings', 'ServerNotify');
2595 + displayNotificationMessage("Password changed.", "Account Settings", 'ServerNotify', 4, 20);
2596
2597 // Log in the auth log
2598 if (parent.parent.authlog) { parent.parent.authLog('https', 'User ' + user.name + ' changed this password'); }
@@ -2602,7 +2602,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2602 });
2603 } else {
2604 // Send user notification of error
2605 - displayNotificationMessage('Current password not correct.', 'Account Settings', 'ServerNotify');
2605 + displayNotificationMessage("Current password not correct.", "Account Settings", 'ServerNotify', 4, 21);
2606 }
2607 });
2608 break;
@@ -2699,7 +2699,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2699
2700 // Create the notification message
2701 var notification = {
2702 - 'action': 'msg', 'type': 'notify', id: Math.random(), 'value': "Chat Request, Click here to accept.", 'title': user.name, 'userid': user._id, 'username': user.name, 'tag': 'meshmessenger/' + encodeURIComponent(command.userid) + '/' + encodeURIComponent(user._id)
2702 + 'action': 'msg', 'type': 'notify', id: Math.random(), 'value': "Chat Request, Click here to accept.", 'title': user.name, 'userid': user._id, 'username': user.name, 'tag': 'meshmessenger/' + encodeURIComponent(command.userid) + '/' + encodeURIComponent(user._id), msgid: 11
2703 };
2704
2705 // Get the list of sessions for this user
@@ -2977,7 +2977,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2977 }
2978 if (dup != null) {
2979 // A duplicate was found, don't allow this change.
2980 - displayNotificationMessage('Error, invite code \"' + dup + '\" already in use.', 'Invite Codes');
2980 + displayNotificationMessage("Error, invite code \"" + dup + "\" already in use.", "Invite Codes", null, 6, 22, [ dup ]);
2981 return;
2982 }
2983 mesh.invite = { codes: command.invite.codes, flags: command.invite.flags };
@@ -3123,7 +3123,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3123
3124 if (unknownUsers.length > 0) {
3125 // Send error back, user not found.
3126 - displayNotificationMessage('User' + ((unknownUsers.length > 1) ? 's' : '') + ' ' + EscapeHtml(unknownUsers.join(', ')) + ' not found.', 'Device Group', 'ServerNotify');
3126 + displayNotificationMessage('User' + ((unknownUsers.length > 1) ? 's' : '') + ' ' + EscapeHtml(unknownUsers.join(', ')) + ' not found.', "Device Group", 'ServerNotify', 5, (unknownUsers.length > 1) ? 16 : 15, [EscapeHtml(unknownUsers.join(', '))]);
3127 }
3128
3129 if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: msgs.join(', '), success: successCount, failed: failCount })); } catch (ex) { } }
@@ -4489,24 +4489,24 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
4489 break;
4490 }
4491 case 'smsuser': { // Send a SMS message to a user
4492 - var errMsg = null, smsuser = null;
4493 - if (parent.parent.smsserver == null) { errMsg = 'SMS gateway not enabled'; }
4494 - else if ((user.siteadmin & 2) == 0) { errMsg = 'No user management rights'; }
4495 - else if (common.validateString(command.userid, 1, 2048) == false) { errMsg = 'Invalid userid'; }
4496 - else if (common.validateString(command.msg, 1, 160) == false) { errMsg = 'Invalid SMS message'; }
4492 + var errMsg = null, errId = 0, smsuser = null;
4493 + if (parent.parent.smsserver == null) { errMsg = "SMS gateway not enabled"; errId = 23; }
4494 + else if ((user.siteadmin & 2) == 0) { errMsg = "No user management rights"; errId = 24; }
4495 + else if (common.validateString(command.userid, 1, 2048) == false) { errMsg = "Invalid username"; errId = 2; }
4496 + else if (common.validateString(command.msg, 1, 160) == false) { errMsg = "Invalid SMS message"; errId = 25; }
4497 else {
4498 smsuser = parent.users[command.userid];
4499 - if (smsuser == null) { errMsg = 'Invalid userid'; }
4500 - else if (smsuser.phone == null) { errMsg = 'No phone number for this user'; }
4499 + if (smsuser == null) { errMsg = "Invalid username"; errId = 2; }
4500 + else if (smsuser.phone == null) { errMsg = "No phone number for this user"; errId = 26; }
4501 }
4502
4503 if (errMsg != null) { displayNotificationMessage(errMsg); break; }
4504
4505 parent.parent.smsserver.sendSMS(smsuser.phone, command.msg, function (success, msg) {
4506 if (success) {
4507 - displayNotificationMessage('SMS succesfuly sent.');
4507 + displayNotificationMessage("SMS succesfuly sent.", null, null, null, 27);
4508 } else {
4509 - if (typeof msg == 'string') { displayNotificationMessage('SMS error: ' + msg); } else { displayNotificationMessage('SMS error'); }
4509 + if (typeof msg == 'string') { displayNotificationMessage("SMS error: " + msg, null, null, null, 29, [msg]); } else { displayNotificationMessage("SMS error", null, null, null, 28); }
4510 }
4511 });
4512 break;
@@ -4527,7 +4527,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
4527
4528 if (errMsg != null) { displayNotificationMessage(errMsg); break; }
4529 parent.parent.mailserver.sendMail(emailuser.email, command.subject, command.msg);
4530 - displayNotificationMessage("Email sent.");
4530 + displayNotificationMessage("Email sent.", null, null, null, 14);
4531 break;
4532 }
4533 case 'getClip': {
@@ -5105,7 +5105,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5105 }
5106
5107 // Display a notification message for this session only.
5108 - function displayNotificationMessage(msg, title, tag) { ws.send(JSON.stringify({ 'action': 'msg', 'type': 'notify', id: Math.random(), 'value': msg, 'title': title, 'userid': user._id, 'username': user.name, 'tag': tag })); }
5108 + function displayNotificationMessage(msg, title, tag, titleid, msgid, args) {
5109 + ws.send(JSON.stringify({ 'action': 'msg', 'type': 'notify', id: Math.random(), 'value': msg, 'title': title, 'userid': user._id, 'username': user.name, 'tag': tag, 'titleid': titleid, 'msgid': msgid, 'args': args }));
5110 + }
5111
5112 // Read the folder and all sub-folders and serialize that into json.
5113 function readFilesRec(path) {
translate/translate.json
+309 -85
@@ -2775,11 +2775,18 @@
2775 "default-mobile.handlebars->container->page_content->column_l->p3->p3info->1->p3AccountActions->p2AccountSecurity->1->0",
2776 "default.handlebars->29->1298",
2777 "default.handlebars->29->1300",
2778 - "default.handlebars->29->2149",
2778 + "default.handlebars->29->2184",
2779 "default.handlebars->29->540",
2780 "default.handlebars->29->542"
2781 ]
2782 },
2783 + {
2784 + "en": "Account Settings",
2785 + "fr": "Paramètres du compte",
2786 + "xloc": [
2787 + "default.handlebars->29->2082"
2788 + ]
2789 + },
2790 {
2791 "cs": "Ověření účtu",
2792 "de": "Bestätigung des Kontos",
@@ -2919,6 +2926,7 @@
2926 "zh-chs": "达到帐户限制。",
2927 "zh-cht": "達到帳戶限制。",
2928 "xloc": [
2929 + "default.handlebars->29->2094",
2930 "login-mobile.handlebars->5->6",
2931 "login.handlebars->5->6",
2932 "login2.handlebars->7->7"
@@ -4356,7 +4364,7 @@
4364 "zh-chs": "代理错误计数器",
4365 "zh-cht": "代理錯誤計數器",
4366 "xloc": [
4359 - "default.handlebars->29->2084"
4367 + "default.handlebars->29->2119"
4368 ]
4369 },
4370 {
@@ -4459,7 +4467,7 @@
4467 "zh-chs": "代理时段",
4468 "zh-cht": "代理時段",
4469 "xloc": [
4462 - "default.handlebars->29->2100"
4470 + "default.handlebars->29->2135"
4471 ]
4472 },
4473 {
@@ -4644,7 +4652,7 @@
4652 "zh-chs": "代理",
4653 "zh-cht": "代理",
4654 "xloc": [
4647 - "default.handlebars->29->2116"
4655 + "default.handlebars->29->2151"
4656 ]
4657 },
4658 {
@@ -5664,7 +5672,7 @@
5672 "zh-chs": "您确定要{0}插件吗:{1}",
5673 "zh-cht": "你確定要{0}外掛嗎:{1}",
5674 "xloc": [
5667 - "default.handlebars->29->2158"
5675 + "default.handlebars->29->2193"
5676 ]
5677 },
5678 {
@@ -5995,7 +6003,7 @@
6003 "zh-chs": "可用內存",
6004 "zh-cht": "可用內存",
6005 "xloc": [
5998 - "default.handlebars->29->2109"
6006 + "default.handlebars->29->2144"
6007 ]
6008 },
6009 {
@@ -6239,7 +6247,7 @@
6247 "zh-chs": "错误的签名",
6248 "zh-cht": "錯誤的簽名",
6249 "xloc": [
6242 - "default.handlebars->29->2091"
6250 + "default.handlebars->29->2126"
6251 ]
6252 },
6253 {
@@ -6259,7 +6267,7 @@
6267 "zh-chs": "错误的网络证书",
6268 "zh-cht": "錯誤的網絡憑證",
6269 "xloc": [
6262 - "default.handlebars->29->2090"
6270 + "default.handlebars->29->2125"
6271 ]
6272 },
6273 {
@@ -6626,7 +6634,7 @@
6634 "zh-chs": "CIRA服务器",
6635 "zh-cht": "CIRA伺服器",
6636 "xloc": [
6629 - "default.handlebars->29->2144"
6637 + "default.handlebars->29->2179"
6638 ]
6639 },
6640 {
@@ -6646,7 +6654,7 @@
6654 "zh-chs": "CIRA服务器命令",
6655 "zh-cht": "CIRA伺服器指令",
6656 "xloc": [
6649 - "default.handlebars->29->2145"
6657 + "default.handlebars->29->2180"
6658 ]
6659 },
6660 {
@@ -6707,7 +6715,7 @@
6715 "zh-chs": "CPU负载",
6716 "zh-cht": "CPU負載",
6717 "xloc": [
6710 - "default.handlebars->29->2105"
6718 + "default.handlebars->29->2140"
6719 ]
6720 },
6721 {
@@ -6727,7 +6735,7 @@
6735 "zh-chs": "最近15分钟的CPU负载",
6736 "zh-cht": "最近15分鐘的CPU負載",
6737 "xloc": [
6730 - "default.handlebars->29->2108"
6738 + "default.handlebars->29->2143"
6739 ]
6740 },
6741 {
@@ -6747,7 +6755,7 @@
6755 "zh-chs": "最近5分钟的CPU负载",
6756 "zh-cht": "最近5分鐘的CPU負載",
6757 "xloc": [
6750 - "default.handlebars->29->2107"
6758 + "default.handlebars->29->2142"
6759 ]
6760 },
6761 {
@@ -6767,7 +6775,7 @@
6775 "zh-chs": "最近一分钟的CPU负载",
6776 "zh-cht": "最近一分鐘的CPU負載",
6777 "xloc": [
6770 - "default.handlebars->29->2106"
6778 + "default.handlebars->29->2141"
6779 ]
6780 },
6781 {
@@ -6874,7 +6882,7 @@
6882 "zh-chs": "呼叫错误",
6883 "zh-cht": "呼叫錯誤",
6884 "xloc": [
6877 - "default.handlebars->29->2159"
6885 + "default.handlebars->29->2194"
6886 ]
6887 },
6888 {
@@ -7428,6 +7436,13 @@
7436 "default.handlebars->29->1515"
7437 ]
7438 },
7439 + {
7440 + "en": "Chat Request, Click here to accept.",
7441 + "fr": "Demande de chat, cliquez ici pour accepter.",
7442 + "xloc": [
7443 + "default.handlebars->29->2095"
7444 + ]
7445 + },
7446 {
7447 "cs": "ChatSession",
7448 "de": "ChatSession",
@@ -7566,7 +7581,7 @@
7581 "zh-cht": "檢查...",
7582 "xloc": [
7583 "default.handlebars->29->1067",
7569 - "default.handlebars->29->2153"
7584 + "default.handlebars->29->2188"
7585 ]
7586 },
7587 {
@@ -9234,7 +9249,7 @@
9249 "zh-chs": "已连接的英特尔®AMT",
9250 "zh-cht": "已連接的Intel® AMT",
9251 "xloc": [
9237 - "default.handlebars->29->2096"
9252 + "default.handlebars->29->2131"
9253 ]
9254 },
9255 {
@@ -9254,7 +9269,7 @@
9269 "zh-chs": "已连接的用户",
9270 "zh-cht": "已连接的用户",
9271 "xloc": [
9257 - "default.handlebars->29->2101"
9272 + "default.handlebars->29->2136"
9273 ]
9274 },
9275 {
@@ -9345,7 +9360,7 @@
9360 "zh-chs": "连接数量",
9361 "zh-cht": "連接數量",
9362 "xloc": [
9348 - "default.handlebars->29->2115"
9363 + "default.handlebars->29->2150"
9364 ]
9365 },
9366 {
@@ -9365,7 +9380,7 @@
9380 "zh-chs": "连接转发器",
9381 "zh-cht": "連接轉發器",
9382 "xloc": [
9368 - "default.handlebars->29->2143"
9383 + "default.handlebars->29->2178"
9384 ]
9385 },
9386 {
@@ -9515,7 +9530,7 @@
9530 "zh-chs": "Cookie编码器",
9531 "zh-cht": "Cookie編碼器",
9532 "xloc": [
9518 - "default.handlebars->29->2129"
9533 + "default.handlebars->29->2164"
9534 ]
9535 },
9536 {
@@ -9922,7 +9937,7 @@
9937 "zh-chs": "核心服务器",
9938 "zh-cht": "核心伺服器",
9939 "xloc": [
9925 - "default.handlebars->29->2128"
9940 + "default.handlebars->29->2163"
9941 ]
9942 },
9943 {
@@ -10534,6 +10549,13 @@
10549 "default.handlebars->29->110"
10550 ]
10551 },
10552 + {
10553 + "en": "Current password not correct.",
10554 + "fr": "Le mot de passe actuel n'est pas correct.",
10555 + "xloc": [
10556 + "default.handlebars->29->2105"
10557 + ]
10558 + },
10559 {
10560 "cs": "Vyjmout",
10561 "de": "Ausschneiden",
@@ -11752,7 +11774,8 @@
11774 "default.handlebars->29->1895",
11775 "default.handlebars->29->1901",
11776 "default.handlebars->29->2013",
11755 - "default.handlebars->29->2064"
11777 + "default.handlebars->29->2064",
11778 + "default.handlebars->29->2083"
11779 ]
11780 },
11781 {
@@ -11798,7 +11821,7 @@
11821 "default.handlebars->29->1842",
11822 "default.handlebars->29->1882",
11823 "default.handlebars->29->1953",
11801 - "default.handlebars->29->2099",
11824 + "default.handlebars->29->2134",
11825 "default.handlebars->container->column_l->p2->p2info->7"
11826 ]
11827 },
@@ -13523,7 +13546,7 @@
13546 "zh-chs": "代理重复",
13547 "zh-cht": "代理重複",
13548 "xloc": [
13526 - "default.handlebars->29->2095"
13549 + "default.handlebars->29->2130"
13550 ]
13551 },
13552 {
@@ -14627,6 +14650,7 @@
14650 "zh-chs": "电邮已发送。",
14651 "zh-cht": "電郵已發送。",
14652 "xloc": [
14653 + "default.handlebars->29->2098",
14654 "login-mobile.handlebars->5->2",
14655 "login.handlebars->5->2",
14656 "login2.handlebars->7->3"
@@ -14691,7 +14715,7 @@
14715 "zh-chs": "电邮/短信流量",
14716 "zh-cht": "電郵/短信流量",
14717 "xloc": [
14694 - "default.handlebars->29->2137"
14718 + "default.handlebars->29->2172"
14719 ]
14720 },
14721 {
@@ -15405,6 +15429,34 @@
15429 "default.handlebars->29->150"
15430 ]
15431 },
15432 + {
15433 + "en": "Error, invite code \\\"{0}\\\" already in use.",
15434 + "fr": "Erreur, code d'invitation \\\"{0}\\\" déjà utilisé.",
15435 + "xloc": [
15436 + "default.handlebars->29->2106"
15437 + ]
15438 + },
15439 + {
15440 + "en": "Error, password not changed.",
15441 + "fr": "Erreur, mot de passe non modifié.",
15442 + "xloc": [
15443 + "default.handlebars->29->2103"
15444 + ]
15445 + },
15446 + {
15447 + "en": "Error, unable to change to commonly used password.",
15448 + "fr": "Erreur, impossible de changer le mot de passe couramment utilisé.",
15449 + "xloc": [
15450 + "default.handlebars->29->2102"
15451 + ]
15452 + },
15453 + {
15454 + "en": "Error, unable to change to previously used password.",
15455 + "fr": "Erreur, impossible de changer le mot de passe précédemment utilisé.",
15456 + "xloc": [
15457 + "default.handlebars->29->2101"
15458 + ]
15459 + },
15460 {
15461 "cs": "Chyba: nebyl zadán klíč pro připojení.",
15462 "de": "Fehler: Kein Verbindungsschlüssel angegeben.",
@@ -15732,7 +15784,7 @@
15784 "zh-chs": "外部",
15785 "zh-cht": "外部",
15786 "xloc": [
15735 - "default.handlebars->29->2122"
15787 + "default.handlebars->29->2157"
15788 ]
15789 },
15790 {
@@ -15815,6 +15867,13 @@
15867 "default.handlebars->29->67"
15868 ]
15869 },
15870 + {
15871 + "en": "Failed to change email address, another account already using: {0}.",
15872 + "fr": "Échec de la modification de l'adresse e-mail, un autre compte utilise déjà: {0}.",
15873 + "xloc": [
15874 + "default.handlebars->29->2097"
15875 + ]
15876 + },
15877 {
15878 "cs": "Vzdálenou plochu se nepodařilo spustit po odmítnutí místním uživatelem",
15879 "de": "Fehler beim Starten des Remotedesktops, nachdem der lokale Benutzer abgelehnt wurde",
@@ -16563,8 +16622,8 @@
16622 "zh-chs": "自由",
16623 "zh-cht": "自由",
16624 "xloc": [
16566 - "default.handlebars->29->2080",
16567 - "default.handlebars->29->2082"
16625 + "default.handlebars->29->2115",
16626 + "default.handlebars->29->2117"
16627 ]
16628 },
16629 {
@@ -17879,7 +17938,7 @@
17938 "zh-chs": "堆总数",
17939 "zh-cht": "堆總數",
17940 "xloc": [
17882 - "default.handlebars->29->2124"
17941 + "default.handlebars->29->2159"
17942 ]
17943 },
17944 {
@@ -17899,7 +17958,7 @@
17958 "zh-chs": "堆使用",
17959 "zh-cht": "堆使用",
17960 "xloc": [
17902 - "default.handlebars->29->2123"
17961 + "default.handlebars->29->2158"
17962 ]
17963 },
17964 {
@@ -19069,7 +19128,7 @@
19128 "zh-chs": "英特尔AMT",
19129 "zh-cht": "英特爾AMT",
19130 "xloc": [
19072 - "default.handlebars->29->2120"
19131 + "default.handlebars->29->2155"
19132 ]
19133 },
19134 {
@@ -19117,7 +19176,7 @@
19176 "default.handlebars->29->1380",
19177 "default.handlebars->29->1551",
19178 "default.handlebars->29->1559",
19120 - "default.handlebars->29->2142",
19179 + "default.handlebars->29->2177",
19180 "default.handlebars->29->526",
19181 "default.handlebars->29->584",
19182 "default.handlebars->29->611"
@@ -19987,7 +20046,7 @@
20046 "zh-chs": "无效的设备组类型",
20047 "zh-cht": "無效的裝置群類型",
20048 "xloc": [
19990 - "default.handlebars->29->2094"
20049 + "default.handlebars->29->2129"
20050 ]
20051 },
20052 {
@@ -20007,7 +20066,7 @@
20066 "zh-chs": "无效的JSON",
20067 "zh-cht": "無效的JSON",
20068 "xloc": [
20010 - "default.handlebars->29->2088"
20069 + "default.handlebars->29->2123"
20070 ]
20071 },
20072 {
@@ -20068,7 +20127,7 @@
20127 "zh-chs": "无效的PKCS签名",
20128 "zh-cht": "無效的PKCS簽名",
20129 "xloc": [
20071 - "default.handlebars->29->2086"
20130 + "default.handlebars->29->2121"
20131 ]
20132 },
20133 {
@@ -20088,7 +20147,14 @@
20147 "zh-chs": "無效的RSA密碼",
20148 "zh-cht": "無效的RSA密碼",
20149 "xloc": [
20091 - "default.handlebars->29->2087"
20150 + "default.handlebars->29->2122"
20151 + ]
20152 + },
20153 + {
20154 + "en": "Invalid SMS message",
20155 + "fr": "Message SMS non valide",
20156 + "xloc": [
20157 + "default.handlebars->29->2109"
20158 ]
20159 },
20160 {
@@ -20113,6 +20179,20 @@
20179 "login2.handlebars->7->9"
20180 ]
20181 },
20182 + {
20183 + "en": "Invalid domain",
20184 + "fr": "Domaine non valide",
20185 + "xloc": [
20186 + "default.handlebars->29->2089"
20187 + ]
20188 + },
20189 + {
20190 + "en": "Invalid email",
20191 + "fr": "Email invalide",
20192 + "xloc": [
20193 + "default.handlebars->29->2088"
20194 + ]
20195 + },
20196 {
20197 "cs": "Neplatný e-mail.",
20198 "de": "Ungültige E-Mail.",
@@ -20176,6 +20256,20 @@
20256 "invite.handlebars->3->1"
20257 ]
20258 },
20259 + {
20260 + "en": "Invalid password",
20261 + "fr": "Mot de passe incorrect",
20262 + "xloc": [
20263 + "default.handlebars->29->2087"
20264 + ]
20265 + },
20266 + {
20267 + "en": "Invalid site permissions",
20268 + "fr": "Autorisations de site non valides",
20269 + "xloc": [
20270 + "default.handlebars->29->2090"
20271 + ]
20272 + },
20273 {
20274 "cs": "Neplatný token, zkuste to znovu.",
20275 "de": "Ungültiges Token, versuchen Sie es erneut.",
@@ -20198,6 +20292,13 @@
20292 "login2.handlebars->7->14"
20293 ]
20294 },
20295 + {
20296 + "en": "Invalid username",
20297 + "fr": "Nom d'utilisateur invalide",
20298 + "xloc": [
20299 + "default.handlebars->29->2086"
20300 + ]
20301 + },
20302 {
20303 "cs": "Zrušení platnosti e-mailu",
20304 "de": "E-Mail ungültig machen",
@@ -20358,7 +20459,8 @@
20459 "default.handlebars->29->1531",
20460 "default.handlebars->29->1536",
20461 "default.handlebars->29->1538",
20361 - "default.handlebars->29->1543"
20462 + "default.handlebars->29->1543",
20463 + "default.handlebars->29->2084"
20464 ]
20465 },
20466 {
@@ -21591,7 +21693,7 @@
21693 "zh-chs": "减",
21694 "zh-cht": "減",
21695 "xloc": [
21594 - "default.handlebars->29->2161"
21696 + "default.handlebars->29->2196"
21697 ]
21698 },
21699 {
@@ -23099,6 +23201,7 @@
23201 },
23202 {
23203 "en": "MacOS Installer",
23204 + "fr": "Installateur MacOS",
23205 "xloc": [
23206 "default.handlebars->29->807"
23207 ]
@@ -23120,7 +23223,7 @@
23223 "zh-chs": "主服务器信息",
23224 "zh-cht": "主伺服器訊息",
23225 "xloc": [
23123 - "default.handlebars->29->2131"
23226 + "default.handlebars->29->2166"
23227 ]
23228 },
23229 {
@@ -23630,7 +23733,7 @@
23733 "zh-chs": "达到连接数量上限",
23734 "zh-cht": "達到連接數量上限",
23735 "xloc": [
23633 - "default.handlebars->29->2092"
23736 + "default.handlebars->29->2127"
23737 ]
23738 },
23739 {
@@ -23695,7 +23798,7 @@
23798 "zh-chs": "Megabyte",
23799 "zh-cht": "Megabyte",
23800 "xloc": [
23698 - "default.handlebars->29->2121"
23801 + "default.handlebars->29->2156"
23802 ]
23803 },
23804 {
@@ -23717,7 +23820,7 @@
23820 "xloc": [
23821 "default-mobile.handlebars->9->396",
23822 "default.handlebars->29->1021",
23720 - "default.handlebars->29->2112",
23823 + "default.handlebars->29->2147",
23824 "default.handlebars->container->column_l->p40->3->1->p40type->3"
23825 ]
23826 },
@@ -23916,7 +24019,7 @@
24019 "zh-chs": "MeshAgent流量",
24020 "zh-cht": "MeshAgent流量",
24021 "xloc": [
23919 - "default.handlebars->29->2133"
24022 + "default.handlebars->29->2168"
24023 ]
24024 },
24025 {
@@ -23936,7 +24039,7 @@
24039 "zh-chs": "MeshAgent更新",
24040 "zh-cht": "MeshAgent更新",
24041 "xloc": [
23939 - "default.handlebars->29->2134"
24042 + "default.handlebars->29->2169"
24043 ]
24044 },
24045 {
@@ -24057,7 +24160,7 @@
24160 "zh-chs": "MeshCentral服务器同级化",
24161 "zh-cht": "MeshCentral伺服器同級化",
24162 "xloc": [
24060 - "default.handlebars->29->2132"
24163 + "default.handlebars->29->2167"
24164 ]
24165 },
24166 {
@@ -24436,7 +24539,7 @@
24539 "zh-chs": "消息调度器",
24540 "zh-cht": "電郵調度器",
24541 "xloc": [
24439 - "default.handlebars->29->2130"
24542 + "default.handlebars->29->2165"
24543 ]
24544 },
24545 {
@@ -24619,7 +24722,7 @@
24722 "zh-chs": "更多",
24723 "zh-cht": "更多",
24724 "xloc": [
24622 - "default.handlebars->29->2160"
24725 + "default.handlebars->29->2195"
24726 ]
24727 },
24728 {
@@ -25383,6 +25486,13 @@
25486 "default.handlebars->29->1698"
25487 ]
25488 },
25489 + {
25490 + "en": "New Account",
25491 + "fr": "Nouveau compte",
25492 + "xloc": [
25493 + "default.handlebars->29->2079"
25494 + ]
25495 + },
25496 {
25497 "cs": "Nový účet…",
25498 "de": "Neues Konto...",
@@ -26410,6 +26520,13 @@
26520 "default.handlebars->29->798"
26521 ]
26522 },
26523 + {
26524 + "en": "No phone number for this user",
26525 + "fr": "Aucun numéro de téléphone pour cet utilisateur",
26526 + "xloc": [
26527 + "default.handlebars->29->2110"
26528 + ]
26529 + },
26530 {
26531 "cs": "Žádné zásuvné moduly na serveru.",
26532 "de": "Keine Plugins auf dem Server.",
@@ -26490,6 +26607,13 @@
26607 "default.handlebars->29->2020"
26608 ]
26609 },
26610 + {
26611 + "en": "No user management rights",
26612 + "fr": "Aucun droit de gestion des utilisateurs",
26613 + "xloc": [
26614 + "default.handlebars->29->2108"
26615 + ]
26616 + },
26617 {
26618 "cs": "Nenalezeni žádní uživatelé.",
26619 "de": "Keine Benutzer gefunden.",
@@ -28018,6 +28142,13 @@
28142 "login2.handlebars->7->19"
28143 ]
28144 },
28145 + {
28146 + "en": "Password changed.",
28147 + "fr": "Mot de passe changé.",
28148 + "xloc": [
28149 + "default.handlebars->29->2104"
28150 + ]
28151 + },
28152 {
28153 "cs": "Heslo pro účet {0} bylo obnoveno na:",
28154 "de": "Das Passwort für Konto {0} wurde zurückgesetzt auf:",
@@ -28472,6 +28603,13 @@
28603 "default.handlebars->29->1631"
28604 ]
28605 },
28606 + {
28607 + "en": "Permission denied",
28608 + "fr": "Permission refusée",
28609 + "xloc": [
28610 + "default.handlebars->29->2085"
28611 + ]
28612 + },
28613 {
28614 "cs": "Práva",
28615 "de": "Berechtigungen",
@@ -28759,7 +28897,7 @@
28897 "zh-cht": "外掛指令",
28898 "xloc": [
28899 "default.handlebars->29->201",
28762 - "default.handlebars->29->2157"
28900 + "default.handlebars->29->2192"
28901 ]
28902 },
28903 {
@@ -29804,7 +29942,7 @@
29942 "zh-chs": "RSS",
29943 "zh-cht": "RSS",
29944 "xloc": [
29807 - "default.handlebars->29->2125"
29945 + "default.handlebars->29->2160"
29946 ]
29947 },
29948 {
@@ -30219,7 +30357,7 @@
30357 "zh-chs": "中继数量",
30358 "zh-cht": "中繼數量",
30359 "xloc": [
30222 - "default.handlebars->29->2104"
30360 + "default.handlebars->29->2139"
30361 ]
30362 },
30363 {
@@ -30239,7 +30377,7 @@
30377 "zh-chs": "中继错误",
30378 "zh-cht": "中繼錯誤",
30379 "xloc": [
30242 - "default.handlebars->29->2097"
30380 + "default.handlebars->29->2132"
30381 ]
30382 },
30383 {
@@ -30259,8 +30397,8 @@
30397 "zh-chs": "中继连接",
30398 "zh-cht": "中繼連接",
30399 "xloc": [
30262 - "default.handlebars->29->2103",
30263 - "default.handlebars->29->2119"
30400 + "default.handlebars->29->2138",
30401 + "default.handlebars->29->2154"
30402 ]
30403 },
30404 {
@@ -32353,6 +32491,7 @@
32491 },
32492 {
32493 "en": "SCP",
32494 + "fr": "SCP",
32495 "xloc": [
32496 "default.handlebars->29->647"
32497 ]
@@ -32403,6 +32542,27 @@
32542 "default.handlebars->29->1988"
32543 ]
32544 },
32545 + {
32546 + "en": "SMS error",
32547 + "fr": "Erreur SMS",
32548 + "xloc": [
32549 + "default.handlebars->29->2112"
32550 + ]
32551 + },
32552 + {
32553 + "en": "SMS error: {0}",
32554 + "fr": "Erreur SMS: {0}",
32555 + "xloc": [
32556 + "default.handlebars->29->2113"
32557 + ]
32558 + },
32559 + {
32560 + "en": "SMS gateway not enabled",
32561 + "fr": "Passerelle SMS non activée",
32562 + "xloc": [
32563 + "default.handlebars->29->2107"
32564 + ]
32565 + },
32566 {
32567 "cs": "SMS odeslána.",
32568 "de": "SMS gesendet.",
@@ -32425,8 +32585,16 @@
32585 "login2.handlebars->7->5"
32586 ]
32587 },
32588 + {
32589 + "en": "SMS succesfuly sent.",
32590 + "fr": "SMS envoyé avec succès.",
32591 + "xloc": [
32592 + "default.handlebars->29->2111"
32593 + ]
32594 + },
32595 {
32596 "en": "SSH",
32597 + "fr": "SSH",
32598 "xloc": [
32599 "default.handlebars->29->645"
32600 ]
@@ -32983,6 +33151,13 @@
33151 "default.handlebars->29->1969"
33152 ]
33153 },
33154 + {
33155 + "en": "Security Warning",
33156 + "fr": "Avertissement de sécurité",
33157 + "xloc": [
33158 + "default.handlebars->29->2081"
33159 + ]
33160 + },
33161 {
33162 "cs": "Hledám",
33163 "de": "Ich suche",
@@ -33689,7 +33864,7 @@
33864 "zh-chs": "服务器证书",
33865 "zh-cht": "伺服器憑證",
33866 "xloc": [
33692 - "default.handlebars->29->2135"
33867 + "default.handlebars->29->2170"
33868 ]
33869 },
33870 {
@@ -33709,7 +33884,7 @@
33884 "zh-chs": "服务器数据库",
33885 "zh-cht": "伺服器數據庫",
33886 "xloc": [
33712 - "default.handlebars->29->2136"
33887 + "default.handlebars->29->2171"
33888 ]
33889 },
33890 {
@@ -33758,6 +33933,13 @@
33933 "agent-translations.json"
33934 ]
33935 },
33936 + {
33937 + "en": "Server Limit",
33938 + "fr": "Limite du serveur",
33939 + "xloc": [
33940 + "default.handlebars->29->2080"
33941 + ]
33942 + },
33943 {
33944 "cs": "Oprávnění serveru",
33945 "de": "Server-Berechtigungen",
@@ -33856,7 +34038,7 @@
34038 "zh-chs": "服务器状态",
34039 "zh-cht": "伺服器狀態",
34040 "xloc": [
33859 - "default.handlebars->29->2083"
34041 + "default.handlebars->29->2118"
34042 ]
34043 },
34044 {
@@ -33896,7 +34078,7 @@
34078 "zh-chs": "服务器跟踪",
34079 "zh-cht": "伺服器追蹤",
34080 "xloc": [
33899 - "default.handlebars->29->2146"
34081 + "default.handlebars->29->2181"
34082 ]
34083 },
34084 {
@@ -34122,7 +34304,7 @@
34304 "zh-chs": "ServerStats.csv",
34305 "zh-cht": "ServerStats.csv",
34306 "xloc": [
34125 - "default.handlebars->29->2127"
34307 + "default.handlebars->29->2162"
34308 ]
34309 },
34310 {
@@ -37727,6 +37909,13 @@
37909 "default.handlebars->29->2075"
37910 ]
37911 },
37912 + {
37913 + "en": "There has been {0} failed login attempts on this account since the last login.",
37914 + "fr": "Il y a eu {0} tentatives de connexion infructueuses sur ce compte depuis la dernière connexion.",
37915 + "xloc": [
37916 + "default.handlebars->29->2096"
37917 + ]
37918 + },
37919 {
37920 "cs": "Tyto soubory jsou veřejné, kliknutím na „odkaz“ získáte veřejnou url adresu.",
37921 "de": "Diese Dateien werden öffentlich geteilt, klicken Sie auf \"Link\", um die öffentliche URL zu erhalten.",
@@ -39260,10 +39449,17 @@
39449 "zh-cht": "在啟用兩因素身份驗證之前,無法訪問此功能。這是額外的安全性所必需的。轉到“我的帳戶”標籤,然後查看“帳戶安全性”部分。",
39450 "xloc": [
39451 "default.handlebars->29->1301",
39263 - "default.handlebars->29->2150",
39452 + "default.handlebars->29->2185",
39453 "default.handlebars->29->543"
39454 ]
39455 },
39456 + {
39457 + "en": "Unable to add user in this mode",
39458 + "fr": "Impossible d'ajouter un utilisateur dans ce mode",
39459 + "xloc": [
39460 + "default.handlebars->29->2092"
39461 + ]
39462 + },
39463 {
39464 "cs": "Nedaří se připojit k web socketu",
39465 "de": "Web-Socket kann nicht verbunden werden",
@@ -39532,7 +39728,7 @@
39728 "zh-chs": "未知动作",
39729 "zh-cht": "未知動作",
39730 "xloc": [
39535 - "default.handlebars->29->2089"
39731 + "default.handlebars->29->2124"
39732 ]
39733 },
39734 {
@@ -39575,7 +39771,7 @@
39771 "xloc": [
39772 "default.handlebars->29->1893",
39773 "default.handlebars->29->2011",
39578 - "default.handlebars->29->2093"
39774 + "default.handlebars->29->2128"
39775 ]
39776 },
39777 {
@@ -39595,7 +39791,7 @@
39791 "zh-chs": "未知群组",
39792 "zh-cht": "未知群組",
39793 "xloc": [
39598 - "default.handlebars->29->2085"
39794 + "default.handlebars->29->2120"
39795 ]
39796 },
39797 {
@@ -39783,7 +39979,7 @@
39979 "zh-chs": "最新",
39980 "zh-cht": "最新",
39981 "xloc": [
39786 - "default.handlebars->29->2155"
39982 + "default.handlebars->29->2190"
39983 ]
39984 },
39985 {
@@ -40201,8 +40397,8 @@
40397 "zh-chs": "用过的",
40398 "zh-cht": "用過的",
40399 "xloc": [
40204 - "default.handlebars->29->2079",
40205 - "default.handlebars->29->2081"
40400 + "default.handlebars->29->2114",
40401 + "default.handlebars->29->2116"
40402 ]
40403 },
40404 {
@@ -40291,7 +40487,7 @@
40487 "zh-chs": "用户帐户",
40488 "zh-cht": "用戶帳戶",
40489 "xloc": [
40294 - "default.handlebars->29->2098"
40490 + "default.handlebars->29->2133"
40491 ]
40492 },
40493 {
@@ -40582,7 +40778,7 @@
40778 "zh-chs": "用户节",
40779 "zh-cht": "用戶節",
40780 "xloc": [
40585 - "default.handlebars->29->2118"
40781 + "default.handlebars->29->2153"
40782 ]
40783 },
40784 {
@@ -40669,6 +40865,13 @@
40865 "desktop.handlebars->3->17"
40866 ]
40867 },
40868 + {
40869 + "en": "User already exists",
40870 + "fr": "L'utilisateur existe déjà",
40871 + "xloc": [
40872 + "default.handlebars->29->2091"
40873 + ]
40874 + },
40875 {
40876 "cs": "Převzít z webového prohlížeče",
40877 "de": "Browsereinstellung des Benutzers",
@@ -40775,6 +40978,13 @@
40978 "terms.handlebars->container->topbar"
40979 ]
40980 },
40981 + {
40982 + "en": "User {0} not found.",
40983 + "fr": "Utilisateur {0} introuvable.",
40984 + "xloc": [
40985 + "default.handlebars->29->2099"
40986 + ]
40987 + },
40988 {
40989 "cs": "Identif. uživatele",
40990 "de": "Benutzer-ID",
@@ -40889,7 +41099,7 @@
41099 "xloc": [
41100 "default.handlebars->29->1841",
41101 "default.handlebars->29->1881",
40892 - "default.handlebars->29->2117",
41102 + "default.handlebars->29->2152",
41103 "default.handlebars->container->topbar->1->1->UsersSubMenuSpan->UsersSubMenu->1->0->UsersGeneral"
41104 ]
41105 },
@@ -40910,7 +41120,14 @@
41120 "zh-chs": "用户会话",
41121 "zh-cht": "用戶節",
41122 "xloc": [
40913 - "default.handlebars->29->2102"
41123 + "default.handlebars->29->2137"
41124 + ]
41125 + },
41126 + {
41127 + "en": "Users {0} not found.",
41128 + "fr": "Utilisateurs {0} introuvables.",
41129 + "xloc": [
41130 + "default.handlebars->29->2100"
41131 ]
41132 },
41133 {
@@ -40954,6 +41171,13 @@
41171 "default.handlebars->29->1763"
41172 ]
41173 },
41174 + {
41175 + "en": "Validation exception",
41176 + "fr": "Exception de validation",
41177 + "xloc": [
41178 + "default.handlebars->29->2093"
41179 + ]
41180 + },
41181 {
41182 "cs": "Doba platnosti",
41183 "de": "Gültigkeit",
@@ -41207,7 +41431,7 @@
41431 "zh-chs": "版本不兼容,请先升级您的MeshCentral",
41432 "zh-cht": "版本不兼容,請先升級你的MeshCentral",
41433 "xloc": [
41210 - "default.handlebars->29->2151"
41434 + "default.handlebars->29->2186"
41435 ]
41436 },
41437 {
@@ -41309,8 +41533,8 @@
41533 "zh-chs": "查看变更日志",
41534 "zh-cht": "查看變更日誌",
41535 "xloc": [
41312 - "default.handlebars->29->2154",
41313 - "default.handlebars->29->2156"
41536 + "default.handlebars->29->2189",
41537 + "default.handlebars->29->2191"
41538 ]
41539 },
41540 {
@@ -41722,8 +41946,8 @@
41946 "zh-chs": "网络服务器",
41947 "zh-cht": "網絡伺服器",
41948 "xloc": [
41725 - "default.handlebars->29->2138",
41726 - "default.handlebars->29->2139"
41949 + "default.handlebars->29->2173",
41950 + "default.handlebars->29->2174"
41951 ]
41952 },
41953 {
@@ -41743,7 +41967,7 @@
41967 "zh-chs": "Web服务器请求",
41968 "zh-cht": "Web伺服器請求",
41969 "xloc": [
41746 - "default.handlebars->29->2140"
41970 + "default.handlebars->29->2175"
41971 ]
41972 },
41973 {
@@ -41763,7 +41987,7 @@
41987 "zh-chs": "Web套接字中继",
41988 "zh-cht": "Web插座中繼",
41989 "xloc": [
41766 - "default.handlebars->29->2141"
41990 + "default.handlebars->29->2176"
41991 ]
41992 },
41993 {
@@ -43254,7 +43478,7 @@
43478 "zh-chs": "\\\\'",
43479 "zh-cht": "\\\\'",
43480 "xloc": [
43257 - "default.handlebars->29->2152"
43481 + "default.handlebars->29->2187"
43482 ]
43483 },
43484 {
@@ -43682,8 +43906,8 @@
43906 "zh-chs": "免费",
43907 "zh-cht": "免費",
43908 "xloc": [
43685 - "default.handlebars->29->2110",
43686 - "default.handlebars->29->2113"
43909 + "default.handlebars->29->2145",
43910 + "default.handlebars->29->2148"
43911 ]
43912 },
43913 {
@@ -44351,7 +44575,7 @@
44575 "zh-chs": "servertrace.csv",
44576 "zh-cht": "servertrace.csv",
44577 "xloc": [
44354 - "default.handlebars->29->2148"
44578 + "default.handlebars->29->2183"
44579 ]
44580 },
44581 {
@@ -44417,7 +44641,7 @@
44641 "zh-chs": "time, conn.agent, conn.users, conn.usersessions, conn.relaysession, conn.intelamt, mem.external, mem.heapused, mem.heaptotal, mem.rss",
44642 "zh-cht": "time, conn.agent, conn.users, conn.usersessions, conn.relaysession, conn.intelamt, mem.external, mem.heapused, mem.heaptotal, mem.rss",
44643 "xloc": [
44420 - "default.handlebars->29->2126"
44644 + "default.handlebars->29->2161"
44645 ]
44646 },
44647 {
@@ -44437,7 +44661,7 @@
44661 "zh-chs": "时间,来源,信息",
44662 "zh-cht": "時間,來源,訊息",
44663 "xloc": [
44440 - "default.handlebars->29->2147"
44664 + "default.handlebars->29->2182"
44665 ]
44666 },
44667 {
@@ -44474,8 +44698,8 @@
44698 "zh-chs": "总计",
44699 "zh-cht": "總",
44700 "xloc": [
44477 - "default.handlebars->29->2111",
44478 - "default.handlebars->29->2114"
44701 + "default.handlebars->29->2146",
44702 + "default.handlebars->29->2149"
44703 ]
44704 },
44705 {
views/default.handlebars
+48 -3
@@ -2185,7 +2185,7 @@
2185 else if (message.type == 'notify') { // This is a notification message.
2186 var n = getstore('notifications', 0);
2187 if (((n & 8) == 0) && (message.amtMessage != null)) { break; } // Intel AMT desktop & terminal messages should be ignored.
2188 - var n = { text: message.value, title: message.title, icon: message.icon };
2188 + var n = { text: message.value, title: message.title, icon: message.icon, titleid: message.titleid, msgid: message.msgid, args: message.args };
2189 if (message.id != null) { n.id = message.id; }
2190 if (message.nodeid != null) { n.nodeid = message.nodeid; }
2191 if (message.tag != null) { n.tag = message.tag; }
@@ -2226,7 +2226,7 @@
2226 }
2227 } else {
2228 if (message.type == 'notify') { // This is a notification message.
2229 - var n = { text: message.value, title: message.title, icon: message.icon };
2229 + var n = { text: message.value, title: message.title, icon: message.icon, titleid: message.titleid, msgid: message.msgid, args: message.args };
2230 if (message.id != null) { n.id = message.id; }
2231 if (message.tag != null) { n.tag = message.tag; }
2232 if (message.username != null) { n.username = message.username; }
@@ -3027,7 +3027,7 @@
3027 break;
3028 }
3029 case 'notify': {
3030 - var n = { text: message.event.value, title: message.event.title, icon: message.event.icon };
3030 + var n = { text: message.event.value, title: message.event.title, icon: message.event.icon, titleid: message.titleid, msgid: message.msgid, args: message.args };
3031 if (message.id != null) { n.id = message.id; }
3032 if (message.event.tag != null) { n.tag = message.event.tag; }
3033 if (typeof message.maxtime == 'number') { n.maxtime = message.maxtime; }
@@ -13168,6 +13168,51 @@
13168
13169 // Add a new notification and play the notification sound
13170 function addNotification(n) {
13171 + // Perform message translation
13172 + var translatedTitles = [
13173 + null,
13174 + "New Account", // 1
13175 + "Server Limit",
13176 + "Security Warning",
13177 + "Account Settings",
13178 + "Device Group",
13179 + "Invite Codes"
13180 + ];
13181 + var translatedMessages = [
13182 + null,
13183 + "Permission denied", // 1
13184 + "Invalid username",
13185 + "Invalid password",
13186 + "Invalid email",
13187 + "Invalid domain",
13188 + "Invalid site permissions",
13189 + "User already exists",
13190 + "Unable to add user in this mode",
13191 + "Validation exception",
13192 + "Account limit reached.", // 10
13193 + "Chat Request, Click here to accept.",
13194 + "There has been {0} failed login attempts on this account since the last login.",
13195 + "Failed to change email address, another account already using: {0}.",
13196 + "Email sent.",
13197 + "User {0} not found.",
13198 + "Users {0} not found.",
13199 + "Error, unable to change to previously used password.",
13200 + "Error, unable to change to commonly used password.",
13201 + "Error, password not changed.",
13202 + "Password changed.", // 20
13203 + "Current password not correct.",
13204 + "Error, invite code \"{0}\" already in use.",
13205 + "SMS gateway not enabled",
13206 + "No user management rights",
13207 + "Invalid SMS message",
13208 + "No phone number for this user",
13209 + "SMS succesfuly sent.",
13210 + "SMS error",
13211 + "SMS error: {0}"
13212 + ];
13213 + if (typeof n.titleid == 'number') { try { n.title = translatedTitles[n.titleid]; } catch (ex) {} }
13214 + if (typeof n.msgid == 'number') { try { n.text = translatedMessages[n.msgid]; if (Array.isArray(n.args)) { format(n.text, ...n.args); } } catch (ex) {} }
13215 +
13216 // Show notification within the web page.
13217 if (n.time == null) { n.time = Date.now(); }
13218 if (n.id == null) { n.id = Math.random(); }