diff --git a/.github/ISSUE_TEMPLATE/bug_resolution.yml b/.github/ISSUE_TEMPLATE/bug_resolution.yml index 6017ecc5e..9016f70eb 100644 --- a/.github/ISSUE_TEMPLATE/bug_resolution.yml +++ b/.github/ISSUE_TEMPLATE/bug_resolution.yml @@ -89,7 +89,7 @@ body: label: Version description: What version of CryptPad are you running? options: - - 2024.3.0 + - 2024.3.0 - 5.7.0 - 5.6.0 - 5.5.0 diff --git a/customize.dist/messages.js b/customize.dist/messages.js index ffc7e6b32..579dcd31e 100755 --- a/customize.dist/messages.js +++ b/customize.dist/messages.js @@ -129,84 +129,6 @@ define(req, function(AppConfig, Default, Language) { } }; - // XXX Temporary keys - Messages.admin_cat_customize = "Customize"; - Messages.admin_cat_security = "Security"; - Messages.admin_logoTitle = "Custom Logo"; - Messages.admin_logoHint = "SVG, PNG or JPG, maximum size 200KB"; - Messages.admin_logoButton = "Upload new"; - Messages.admin_logoRemoveButton = "Restore default"; - Messages.admin_colorTitle = "Accent color"; - Messages.admin_colorHint = "Change the accent color of your CryptPad instance. Please ensure text and buttons are readable with sufficient contrast in both light and dark themes."; - Messages.admin_colorCurrent = "Current accent color"; - Messages.admin_colorChange = "Change color"; - Messages.admin_colorPick = "Pick a color"; - Messages.admin_colorPreview = "Preview color"; - Messages.admin_supportSetupHint = "Create or update the support keys."; - Messages.admin_supportSetupTitle = "Initialize support"; - Messages.admin_supportEnabled = "Modern support system is enabled."; - Messages.admin_supportDisabled = "Modern support system is disabled."; - Messages.admin_supportInit = "Initialize support page on this instance"; - Messages.admin_supportDelete = "Disable support"; - Messages.admin_supportConfirm = "Are you sure? This will delete all existing tickets and block access for all moderators."; - Messages.admin_supportMembers = "Support team"; - Messages.admin_supportAdd = "Add a contact to the support team"; - Messages.admin_supportRotateNotify = "Warning: new keys have been generated but an unenexpected error prevented the system to send them to the moderators. Please remove and re-add all members of the support team"; - - Messages.admin_supportTeamTitle = "admin_supportTeamTitle"; - Messages.admin_supportTeamHint = "admin_supportTeamHint"; - Messages.admin_supportOpen = "Open helpdesk"; - - Messages.support_userNotification = "New support ticket or response: {0}"; - Messages.support_moderatorNotification = "You have been added to the moderators list"; - - Messages.moderationPage = "Support mailbox"; // XXX - - Messages.support_cat_open = "Inbox"; - Messages.support_cat_closed = "Closed"; - Messages.support_cat_search = "Search"; - Messages.support_cat_settings = "Settings"; - Messages.support_cat_legacy = "Legacy"; - - Messages.support_pending = "Archived tickets:"; - Messages.support_pending_tag = "Archived"; - Messages.support_active_tag = "Inbox"; - Messages.support_closed_tag = "Closed"; - - Messages.support_privacyTitle = "Answer anonymously"; - Messages.support_privacyHint = "Check this option to reply as 'The Support Team' instead of your own username"; - - Messages.support_notificationsTitle = "Disable notifications"; - Messages.support_notificationsHint = "Check this option to disable notifications for new tickets and replies"; - Messages.support_openTicketTitle = "Open a ticket with a user"; - Messages.support_openTicketHint = "Copy the recipient user's data from their profile page or an existing support ticket. They will receive a CryptPad notification about this message."; - Messages.support_userChannel = "User's notifications channel ID"; - Messages.support_userKey = "User's public key"; - Messages.support_invalChan = "Invalid notifications channel"; - - Messages.support_pasteUserData = "Paste user data here"; - - Messages.support_recordedTitle = "Snippets"; - Messages.support_recordedHint = "Store common text as one-click shortcuts to insert in support messages."; - Messages.support_recordedEmpty = "No snippets"; - Messages.support_recordedId = "Snippet ID (unique)"; - Messages.support_recordedContent = "Content"; - - Messages.support_legacyTitle = "View old support data"; - Messages.support_legacyHint = "View tickets from the legacy support system and recreate them in the new one."; - Messages.support_legacyButton = "Get active"; - Messages.support_legacyDump = "Export all"; - Messages.support_legacyClear = "Delete from my account"; - - Messages.support_searchLabel = "Search (title or ticketId)"; - - Messages.support_team = "The Support Team"; // XXX - Messages.support_answerAs = "Answering as {0}"; // XXX - Messages.support_movePending = "Move to archive"; - Messages.support_moveActive = "Move to active"; - Messages.support_copyUserData = "Copy user data"; - Messages.support_insertRecorded = "Insert snippet"; - return Messages; diff --git a/customize.dist/pages.js b/customize.dist/pages.js index 4ae8ac0ef..51ebb4d08 100644 --- a/customize.dist/pages.js +++ b/customize.dist/pages.js @@ -5,12 +5,13 @@ define([ '/common/hyperscript.js', '/common/common-language.js', + '/common/common-util.js', '/customize/application_config.js', '/customize/messages.js', 'jquery', '/api/config', 'optional!/api/instance', -], function (h, Language, AppConfig, Msg, $, ApiConfig, Instance) { +], function (h, Language, Util, AppConfig, Msg, $, ApiConfig, Instance) { var Pages = {}; Pages.setHTML = function (e, html) { @@ -98,7 +99,8 @@ define([ return h('a', attrs, [icon, text]); }; - Pages.versionString = "5.7.0"; + let urlArgs = ApiConfig.requireConf && ApiConfig.requireConf.urlArgs; + Pages.versionString = Util.getVersionFromUrlArgs(urlArgs); var customURLs = Pages.customURLs = {}; (function () { diff --git a/customize.dist/src/less2/include/forms.less b/customize.dist/src/less2/include/forms.less index 82e4ebd7b..2f5777771 100644 --- a/customize.dist/src/less2/include/forms.less +++ b/customize.dist/src/less2/include/forms.less @@ -130,12 +130,15 @@ text-align: center; text-transform: uppercase; font-size: 14px; - font-family: inherit; text-decoration: none; cursor: pointer; border-radius: @variables_radius; transition: none; + &:not(.fa):not(.cptools) { + font-family: inherit; + } + i, .fa, .cptools { &:not(.nomargin) { margin-right: 5px; diff --git a/customize.dist/src/less2/include/support.less b/customize.dist/src/less2/include/support.less index f937314d2..090b0946d 100644 --- a/customize.dist/src/less2/include/support.less +++ b/customize.dist/src/less2/include/support.less @@ -6,6 +6,7 @@ @import (reference) "./colortheme-all.less"; @import (reference) './tokenfield.less'; +@import (reference) './variables.less'; @import (reference) './sidebar-layout.less'; .support_main () { @ticket-bg: @cp_support-bg; @@ -33,7 +34,8 @@ } textarea { box-sizing: border-box; - width: 2*@sidebar_block-width !important; + resize: vertical; + width: 100%; max-width: 100% !important; padding: 10px 15px; height: 300px; @@ -78,7 +80,16 @@ justify-content: space-between; flex: 1; min-width: 0; + .cp-support-ticket-title { + width: 100%; + margin-bottom: @sidebar_base-margin; + word-break: break-word; + } .cp-tags-list { + &:empty { + display: none !important; + } + margin-top: @sidebar_base-margin; width: 100%; } } @@ -86,6 +97,11 @@ margin-left: 1em; } } + .cp-support-ticket-tags { + .cp-tokenfield-form button.cp-token-close { + border-radius: @variables_radius !important; + } + } &.cp-filtered { display: none; } diff --git a/lib/hk-util.js b/lib/hk-util.js index 2c5054f51..da0a63ab8 100644 --- a/lib/hk-util.js +++ b/lib/hk-util.js @@ -311,14 +311,13 @@ var trimMapByOffset = function (map, offset) { * to guarantee that offset computation is always atomic with writes */ // FIXME 'optionalMessageHash' is always supplied, so we could consider renaming it for clarity -const storeMessage = function (Env, channel, msg, isCp, optionalMessageHash, cb) { +const storeMessage = function (Env, channel, msg, isCp, optionalMessageHash, time, cb) { const id = channel.id; const Log = Env.Log; if (typeof(cb) !== "function") { cb = function () {}; } Env.queueStorage(id, function (next) { const msgBin = Buffer.from(msg + '\n', 'utf8'); - const time = Array.isArray(msg) && msg[msg.length - 1]; // Store the message first, and update the index only once it's stored. // store.messageBin can be async so updating the index first may // result in a wrong cpIndex @@ -1033,11 +1032,12 @@ HK.onChannelMessage = function (Env, Server, channel, msgStruct, cb) { } // add the time to the message - msgStruct.push(now()); + let time = now(); + msgStruct.push(time); // storeMessage //console.log(+new Date(), "Storing message"); - storeMessage(Env, channel, JSON.stringify(msgStruct), isCp, getHash(msgStruct[4], Log), cb); + storeMessage(Env, channel, JSON.stringify(msgStruct), isCp, getHash(msgStruct[4], Log), time, cb); //console.log(+new Date(), "Message stored"); }); }; diff --git a/lib/storage/moderator.js b/lib/storage/moderator.js index 0251e7fa9..b889497c1 100644 --- a/lib/storage/moderator.js +++ b/lib/storage/moderator.js @@ -40,7 +40,8 @@ Moderator.getAllKeys = function (Env) { }); return keys; } catch (e) { - return; + // ENOENT, return empty array + return []; } }; Moderator.getAll = function (Env, cb) { diff --git a/package-lock.json b/package-lock.json index 5b076db0d..d8e177a61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "croppie": "^2.5.0", "dragula": "3.7.2", "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+5", - "express": "~4.18.2", + "express": "~4.19.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", "get-folder-size": "^2.0.1", @@ -1598,9 +1598,9 @@ } }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -2232,16 +2232,16 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -2272,43 +2272,6 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", diff --git a/package.json b/package.json index 958780fef..715da158a 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,19 @@ }, "dependencies": { "@mcrowe/minibloom": "^0.2.0", + "chainpad-crypto": "^0.2.5", + "chainpad-server": "^5.1.0", + "cookie-parser": "^1.4.6", + "body-parser": "^1.20.2", + "express": "~4.19.2", + "fs-extra": "^7.0.0", + "get-folder-size": "^2.0.1", + "netflux-websocket": "^1.0.0", + "http-proxy-middleware": "^2.0.6", + "jsonwebtoken": "^9.0.0", + "notp": "^2.0.3", + "nthen": "0.1.8", + "openid-client": "^5.4.2", "@node-saml/node-saml": "^4.0.5", "alertify.js": "1.0.11", "body-parser": "^1.20.2", diff --git a/www/admin/inner.js b/www/admin/inner.js index a3d48a903..cd1360d9c 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -98,13 +98,6 @@ define([ 'users' ] }, - 'support' : { // Msg.admin_cat_support - icon : 'fa fa-ambulance', - content : [ - 'support-setup', - 'support-team', - ] - }, 'quota': { // Msg.admin_cat_quota icon: 'fa fa-hdd-o', content: [ @@ -123,6 +116,13 @@ define([ ] }, + 'support' : { // Msg.admin_cat_support + icon : 'fa fa-ambulance', + content : [ + 'support-setup', + 'support-team', + ] + }, 'stats' : { // Msg.admin_cat_stats icon : 'fa fa-line-chart', content : [ diff --git a/www/code/inner.js b/www/code/inner.js index 6fe038064..670e2097a 100644 --- a/www/code/inner.js +++ b/www/code/inner.js @@ -113,6 +113,7 @@ define([ window.focus(); window.print(); framework.feedback('PRINT_CODE'); + UI.clearTooltipsDelay(); }); var $print = UIElements.getEntryFromButton($printButton); framework._.toolbar.$drawer.append($print); diff --git a/www/common/common-interface.js b/www/common/common-interface.js index e8d55c59b..e34037d30 100644 --- a/www/common/common-interface.js +++ b/www/common/common-interface.js @@ -1112,6 +1112,10 @@ define([ }); }; + UI.clearTooltipsDelay = function () { + setTimeout(UI.clearTooltips, 500); + }; + var delay = typeof(AppConfig.tooltipDelay) === "number" ? AppConfig.tooltipDelay : 500; $.extend(true, Tippy.defaults, { placement: 'bottom', diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index cccce667d..537fb89de 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -584,8 +584,10 @@ define([ let attributes = {}; let btnClass = $button.attr('class'); let btnId = $button.attr('id'); + let btnTitle = $button.attr('title'); if (btnClass) { attributes['class'] = btnClass; } if (btnId) { attributes['id'] = btnId; } + if (btnTitle && !attributes.title) { attributes['title'] = btnTitle; } return UIElements.createDropdownEntry({ tag: 'a', @@ -616,7 +618,9 @@ define([ title: Messages.exportButtonTitle, }).append($('', {'class': 'cp-toolbar-drawer-element'}).text(Messages.exportButton)); - button.click(common.prepareFeedback(type)); + button + .click(common.prepareFeedback(type)) + .click(UI.clearTooltipsDelay); if (callback) { button.click(callback); } @@ -626,38 +630,6 @@ define([ 'class': 'fa fa-upload cp-toolbar-icon-import', title: Messages.importButtonTitle, }).append($('', {'class': 'cp-toolbar-drawer-element'}).text(Messages.importButton)); - /*if (data.types) { - // New import button in the toolbar - var importFunction = { - template: function () { - UIElements.openTemplatePicker(common, true); - }, - file: function (cb) { - importContent('text/plain', function (content, file) { - cb(content, file); - }, {accept: data ? data.accept : undefined}) - } - }; - var toImport = []; - Object.keys(data.types).forEach(function (importType) { - if (!importFunction[importType] || !data.types[importType]) { return; } - var option = h('button', importType); - $(option).click(function () { - importFunction[importType](data.types[importType]); - }); - toImport.push(options); - }); - - button.click(common.prepareFeedback(type)); - - if (toImport.length === 1) { - button.click(function () { $(toImport[0]).click(); }); - } else { - Cryptpad.alert(h('p.cp-import-container', toImport)); - } - } - else if (callback) {*/ - // Old import button, used in settings var importer = importContent((data && data.binary) ? 'application/octet-stream' : 'text/plain', callback, { accept: data ? data.accept : undefined, binary: data ? data.binary : undefined @@ -673,6 +645,7 @@ define([ .click(common.prepareFeedback(type)) .click(function () { handler(); + UI.clearTooltipsDelay(); }); //} break; @@ -706,7 +679,10 @@ define([ if (callback) { callback(); } }); if (data.accept) { $input.attr('accept', data.accept); } - button.click(function () { $input.click(); }); + button.click(function () { + $input.click(); + UI.clearTooltipsDelay(); + }); break; case 'copy': button = $('