Merge branch 'support' into notifications
This commit is contained in:
commit
134d18f966
@ -3,8 +3,6 @@
|
|||||||
const Nacl = require('tweetnacl');
|
const Nacl = require('tweetnacl');
|
||||||
|
|
||||||
const keyPair = Nacl.box.keyPair();
|
const keyPair = Nacl.box.keyPair();
|
||||||
console.log(keyPair);
|
|
||||||
|
|
||||||
console.log("You've just generated a new key pair for your support mailbox.");
|
console.log("You've just generated a new key pair for your support mailbox.");
|
||||||
|
|
||||||
console.log("The public key should first be added to your config.js file ('supportMailboxPublicKey'), then save and restart the server.");
|
console.log("The public key should first be added to your config.js file ('supportMailboxPublicKey'), then save and restart the server.");
|
||||||
|
|||||||
@ -232,11 +232,11 @@ define([
|
|||||||
create['support-init'] = function () {
|
create['support-init'] = function () {
|
||||||
var $div = makeBlock('support-init');
|
var $div = makeBlock('support-init');
|
||||||
if (!supportKey) {
|
if (!supportKey) {
|
||||||
$div.append(h('p', Messages.admin_supportInitHelp || "Your server is not configured to have a support mailbox. If you want a support mailbox to receive messages from your users, you should ask your server administrator to run the script located in './scripts/generate-admin-keys.js', store the public key in the 'config.js' file, and send you the private key.")); // XXX
|
$div.append(h('p', Messages.admin_supportInitHelp));
|
||||||
return $div;
|
return $div;
|
||||||
}
|
}
|
||||||
if (!APP.privateKey || !checkAdminKey(APP.privateKey)) {
|
if (!APP.privateKey || !checkAdminKey(APP.privateKey)) {
|
||||||
$div.append(h('p', Messages.admin_supportInitPrivate || "Your CryptPad instance is configured to use a support mailbox but your account doesn't have the correct private key to access it. Please use the following form to add or update the private key to your account")); // XXX
|
$div.append(h('p', Messages.admin_supportInitPrivate));
|
||||||
|
|
||||||
var error = h('div.cp-admin-support-error');
|
var error = h('div.cp-admin-support-error');
|
||||||
var input = h('input.cp-admin-add-private-key');
|
var input = h('input.cp-admin-add-private-key');
|
||||||
|
|||||||
@ -162,7 +162,7 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
var parsed = Hash.parsePadUrl(data.href || data.roHref);
|
var parsed = Hash.parsePadUrl(data.href || data.roHref);
|
||||||
if (!data.noEditPassword && owned && parsed.hashData.type === 'pad') {
|
if (!data.noEditPassword && owned && parsed.hashData.type === 'pad' && parsed.type !== "sheet") { // FIXME SHEET fix password change for sheets
|
||||||
var sframeChan = common.getSframeChannel();
|
var sframeChan = common.getSframeChannel();
|
||||||
var changePwTitle = Messages.properties_changePassword;
|
var changePwTitle = Messages.properties_changePassword;
|
||||||
var changePwConfirm = Messages.properties_confirmChange;
|
var changePwConfirm = Messages.properties_confirmChange;
|
||||||
@ -412,6 +412,7 @@ define([
|
|||||||
if (!friend.notifications || !friend.curvePublic) { return; }
|
if (!friend.notifications || !friend.curvePublic) { return; }
|
||||||
common.mailbox.sendTo("SHARE_PAD", {
|
common.mailbox.sendTo("SHARE_PAD", {
|
||||||
href: href,
|
href: href,
|
||||||
|
password: config.password,
|
||||||
name: myName,
|
name: myName,
|
||||||
title: title
|
title: title
|
||||||
}, {
|
}, {
|
||||||
|
|||||||
@ -78,7 +78,12 @@ define([
|
|||||||
return Messages._getKey(key, [msg.content.name || Messages.anonymous, msg.content.title]);
|
return Messages._getKey(key, [msg.content.name || Messages.anonymous, msg.content.title]);
|
||||||
};
|
};
|
||||||
content.handler = function () {
|
content.handler = function () {
|
||||||
common.openURL(msg.content.href);
|
var todo = function () { common.openURL(msg.content.href); };
|
||||||
|
if (!msg.content.password) { return void todo(); }
|
||||||
|
common.getSframeChannel().query('Q_SESSIONSTORAGE_PUT', {
|
||||||
|
key: 'newPadPassword',
|
||||||
|
value: msg.content.password
|
||||||
|
}, todo);
|
||||||
};
|
};
|
||||||
if (!content.archived) {
|
if (!content.archived) {
|
||||||
content.dismissHandler = defaultDismiss(common, data);
|
content.dismissHandler = defaultDismiss(common, data);
|
||||||
|
|||||||
@ -102,9 +102,12 @@ define([
|
|||||||
Cryptpad.onlyoffice.onEvent.reg(function (obj) {
|
Cryptpad.onlyoffice.onEvent.reg(function (obj) {
|
||||||
if (obj.ev === 'MESSAGE' && !/^cp\|/.test(obj.data)) {
|
if (obj.ev === 'MESSAGE' && !/^cp\|/.test(obj.data)) {
|
||||||
try {
|
try {
|
||||||
|
var validateKey = obj.data.validateKey || true;
|
||||||
|
var skipCheck = validateKey === true;
|
||||||
|
var msg = obj.data.msg;
|
||||||
obj.data = {
|
obj.data = {
|
||||||
msg: JSON.parse(Utils.crypto.decrypt(obj.data, Utils.secret.keys.validateKey)),
|
msg: JSON.parse(Utils.crypto.decrypt(msg, validateKey, skipCheck)),
|
||||||
hash: obj.data.slice(0,64)
|
hash: msg.slice(0,64)
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
define([
|
define([
|
||||||
'/common/common-messaging.js',
|
'/common/common-messaging.js',
|
||||||
], function (Messaging) {
|
'/common/common-hash.js',
|
||||||
|
], function (Messaging, Hash) {
|
||||||
|
|
||||||
var getRandomTimeout = function (ctx) {
|
var getRandomTimeout = function (ctx) {
|
||||||
var lag = ctx.store.realtime.getLag().lag || 0;
|
var lag = ctx.store.realtime.getLag().lag || 0;
|
||||||
@ -156,6 +157,50 @@ define([
|
|||||||
cb(true);
|
cb(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hide duplicates when receiving a SHARE_PAD notification:
|
||||||
|
// Keep only one notification per channel: the stronger and more recent one
|
||||||
|
var channels = {};
|
||||||
|
handlers['SHARE_PAD'] = function (ctx, box, data, cb) {
|
||||||
|
var msg = data.msg;
|
||||||
|
var hash = data.hash;
|
||||||
|
var content = msg.content;
|
||||||
|
// content.name, content.title, content.href, content.password
|
||||||
|
|
||||||
|
var channel = Hash.hrefToHexChannelId(content.href, content.password);
|
||||||
|
var parsed = Hash.parsePadUrl(content.href);
|
||||||
|
var mode = parsed.hashData && parsed.hashData.mode || 'n/a';
|
||||||
|
|
||||||
|
var old = channels[channel];
|
||||||
|
var toRemove;
|
||||||
|
if (old) {
|
||||||
|
// New hash is weaker, ignore
|
||||||
|
if (old.mode === 'edit' && mode === 'view') {
|
||||||
|
return void cb(true);
|
||||||
|
}
|
||||||
|
// New hash is not weaker, clear the old one
|
||||||
|
toRemove = old.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the data
|
||||||
|
channels[channel] = {
|
||||||
|
mode: mode,
|
||||||
|
data: {
|
||||||
|
type: box.type,
|
||||||
|
hash: hash
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
cb(false, toRemove);
|
||||||
|
};
|
||||||
|
removeHandlers['SHARE_PAD'] = function (ctx, box, data, hash) {
|
||||||
|
var content = data.content;
|
||||||
|
var channel = Hash.hrefToHexChannelId(content.href, content.password);
|
||||||
|
var old = channels[channel];
|
||||||
|
if (old && old.data && old.data.hash === hash) {
|
||||||
|
delete channels[channel];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
add: function (ctx, box, data, cb) {
|
add: function (ctx, box, data, cb) {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -187,6 +187,7 @@ proxy.mailboxes = {
|
|||||||
var openChannel = function (ctx, type, m, onReady) {
|
var openChannel = function (ctx, type, m, onReady) {
|
||||||
var box = ctx.boxes[type] = {
|
var box = ctx.boxes[type] = {
|
||||||
channel: m.channel,
|
channel: m.channel,
|
||||||
|
type: type,
|
||||||
queue: [], // Store the messages to send when the channel is ready
|
queue: [], // Store the messages to send when the channel is ready
|
||||||
history: [], // All the hashes loaded from the server in corretc order
|
history: [], // All the hashes loaded from the server in corretc order
|
||||||
content: {}, // Content of the messages that should be displayed
|
content: {}, // Content of the messages that should be displayed
|
||||||
@ -259,8 +260,8 @@ proxy.mailboxes = {
|
|||||||
msg: msg,
|
msg: msg,
|
||||||
hash: hash
|
hash: hash
|
||||||
};
|
};
|
||||||
Handlers.add(ctx, box, message, function (toDismiss) {
|
Handlers.add(ctx, box, message, function (dismissed, toDismiss) {
|
||||||
if (toDismiss) {
|
if (dismissed) { // This message should be removed
|
||||||
dismiss(ctx, {
|
dismiss(ctx, {
|
||||||
type: type,
|
type: type,
|
||||||
hash: hash
|
hash: hash
|
||||||
@ -269,6 +270,11 @@ proxy.mailboxes = {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (toDismiss) { // List of other messages to remove
|
||||||
|
dismiss(ctx, toDismiss, '', function () {
|
||||||
|
console.log('Notification handled automatically');
|
||||||
|
});
|
||||||
|
}
|
||||||
box.content[hash] = msg;
|
box.content[hash] = msg;
|
||||||
showMessage(ctx, type, message);
|
showMessage(ctx, type, message);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -26,7 +26,10 @@ define([
|
|||||||
if (!c.id) { c.id = chan.wc.myID + '-' + client; }
|
if (!c.id) { c.id = chan.wc.myID + '-' + client; }
|
||||||
|
|
||||||
chan.history.forEach(function (msg) {
|
chan.history.forEach(function (msg) {
|
||||||
ctx.emit('MESSAGE', msg, [client]);
|
ctx.emit('MESSAGE', {
|
||||||
|
msg: msg,
|
||||||
|
validateKey: chan.validateKey
|
||||||
|
}, [client]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ==> And push the new tab to the list
|
// ==> And push the new tab to the list
|
||||||
@ -37,7 +40,8 @@ define([
|
|||||||
var onOpen = function (wc) {
|
var onOpen = function (wc) {
|
||||||
|
|
||||||
ctx.channels[channel] = ctx.channels[channel] || {
|
ctx.channels[channel] = ctx.channels[channel] || {
|
||||||
history: []
|
history: [],
|
||||||
|
validateKey: obj.validateKey
|
||||||
};
|
};
|
||||||
|
|
||||||
chan = ctx.channels[channel];
|
chan = ctx.channels[channel];
|
||||||
@ -61,7 +65,10 @@ define([
|
|||||||
});
|
});
|
||||||
wc.on('message', function (msg) {
|
wc.on('message', function (msg) {
|
||||||
chan.history.push(msg);
|
chan.history.push(msg);
|
||||||
ctx.emit('MESSAGE', msg, chan.clients);
|
ctx.emit('MESSAGE', {
|
||||||
|
msg: msg,
|
||||||
|
validateKey: chan.validateKey
|
||||||
|
}, chan.clients);
|
||||||
});
|
});
|
||||||
|
|
||||||
chan.wc = wc;
|
chan.wc = wc;
|
||||||
@ -101,6 +108,7 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
network.on('message', function (msg, sender) {
|
network.on('message', function (msg, sender) {
|
||||||
|
if (!ctx.channels[channel]) { return; }
|
||||||
var hk = network.historyKeeper;
|
var hk = network.historyKeeper;
|
||||||
if (sender !== hk) { return; }
|
if (sender !== hk) { return; }
|
||||||
|
|
||||||
@ -115,7 +123,12 @@ define([
|
|||||||
// Keep only metadata messages for the current channel
|
// Keep only metadata messages for the current channel
|
||||||
if (parsed.channel && parsed.channel !== channel) { return; }
|
if (parsed.channel && parsed.channel !== channel) { return; }
|
||||||
// Ignore the metadata message
|
// Ignore the metadata message
|
||||||
if (parsed.validateKey && parsed.channel) { return; }
|
if (parsed.validateKey && parsed.channel) {
|
||||||
|
if (!chan.validateKey) {
|
||||||
|
chan.validateKey = parsed.validateKey;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
// End of history: emit READY
|
// End of history: emit READY
|
||||||
if (parsed.state && parsed.state === 1 && parsed.channel) {
|
if (parsed.state && parsed.state === 1 && parsed.channel) {
|
||||||
ctx.emit('READY', '', chan.clients);
|
ctx.emit('READY', '', chan.clients);
|
||||||
@ -132,7 +145,9 @@ define([
|
|||||||
if (hash === chan.lastKnownHash || hash === chan.lastCpHash) { return; }
|
if (hash === chan.lastKnownHash || hash === chan.lastCpHash) { return; }
|
||||||
|
|
||||||
chan.lastKnownHash = hash;
|
chan.lastKnownHash = hash;
|
||||||
ctx.emit('MESSAGE', msg, chan.clients);
|
ctx.emit('MESSAGE', {
|
||||||
|
msg: msg,
|
||||||
|
}, chan.clients);
|
||||||
chan.history.push(msg);
|
chan.history.push(msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -176,7 +191,9 @@ define([
|
|||||||
return void chan.sendMsg(data.isCp, cb);
|
return void chan.sendMsg(data.isCp, cb);
|
||||||
}
|
}
|
||||||
chan.sendMsg(data.msg, cb);
|
chan.sendMsg(data.msg, cb);
|
||||||
ctx.emit('MESSAGE', data.msg, chan.clients.filter(function (cl) {
|
ctx.emit('MESSAGE', {
|
||||||
|
msg: data.msg
|
||||||
|
}, chan.clients.filter(function (cl) {
|
||||||
return cl !== clientId;
|
return cl !== clientId;
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|||||||
@ -625,6 +625,11 @@ define([
|
|||||||
var root = exp.find([ROOT]);
|
var root = exp.find([ROOT]);
|
||||||
var toClean = [];
|
var toClean = [];
|
||||||
for (var id in fd) {
|
for (var id in fd) {
|
||||||
|
if (String(id) !== String(Number(id))) {
|
||||||
|
debug("Invalid file ID in filesData.", id);
|
||||||
|
toClean.push(id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
id = Number(id);
|
id = Number(id);
|
||||||
var el = fd[id];
|
var el = fd[id];
|
||||||
|
|
||||||
|
|||||||
@ -342,7 +342,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Remove the elements from the old location (without unpinning)
|
// Remove the elements from the old location (without unpinning)
|
||||||
Env.user.userObject.delete(resolved.main, waitFor());
|
Env.user.userObject.delete(resolved.main, waitFor()); // FIXME waitFor() is called synchronously
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -369,7 +369,7 @@ define([
|
|||||||
if (copy) { return; }
|
if (copy) { return; }
|
||||||
|
|
||||||
// Remove the elements from the old location (without unpinning)
|
// Remove the elements from the old location (without unpinning)
|
||||||
uoFrom.delete(paths, waitFor());
|
uoFrom.delete(paths, waitFor()); // FIXME waitFor() is called synchronously
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -707,6 +707,7 @@ define([
|
|||||||
if (type === 'expirable') {
|
if (type === 'expirable') {
|
||||||
return function (fileId) {
|
return function (fileId) {
|
||||||
var data = userObject.getFileData(fileId);
|
var data = userObject.getFileData(fileId);
|
||||||
|
if (!data) { return; }
|
||||||
// Don't push duplicates
|
// Don't push duplicates
|
||||||
if (result.indexOf(data.channel) !== -1) { return; }
|
if (result.indexOf(data.channel) !== -1) { return; }
|
||||||
// Return pads owned by someone else or expired by time
|
// Return pads owned by someone else or expired by time
|
||||||
@ -718,6 +719,7 @@ define([
|
|||||||
if (type === 'owned') {
|
if (type === 'owned') {
|
||||||
return function (fileId) {
|
return function (fileId) {
|
||||||
var data = userObject.getFileData(fileId);
|
var data = userObject.getFileData(fileId);
|
||||||
|
if (!data) { return; }
|
||||||
// Don't push duplicates
|
// Don't push duplicates
|
||||||
if (result.indexOf(data.channel) !== -1) { return; }
|
if (result.indexOf(data.channel) !== -1) { return; }
|
||||||
// Return owned pads
|
// Return owned pads
|
||||||
@ -729,6 +731,7 @@ define([
|
|||||||
if (type === "pin") {
|
if (type === "pin") {
|
||||||
return function (fileId) {
|
return function (fileId) {
|
||||||
var data = userObject.getFileData(fileId);
|
var data = userObject.getFileData(fileId);
|
||||||
|
if (!data) { return; }
|
||||||
// Don't pin pads owned by someone else
|
// Don't pin pads owned by someone else
|
||||||
if (_ownedByOther(Env, data.owners)) { return; }
|
if (_ownedByOther(Env, data.owners)) { return; }
|
||||||
// Don't push duplicates
|
// Don't push duplicates
|
||||||
|
|||||||
@ -223,6 +223,11 @@ define([
|
|||||||
sframeChan.event("EV_PAD_PASSWORD");
|
sframeChan.event("EV_PAD_PASSWORD");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!val && sessionStorage.newPadPassword) {
|
||||||
|
val = sessionStorage.newPadPassword;
|
||||||
|
delete sessionStorage.newPadPassword;
|
||||||
|
}
|
||||||
|
|
||||||
if (val) {
|
if (val) {
|
||||||
password = val;
|
password = val;
|
||||||
Cryptpad.getFileSize(window.location.href, password, waitFor(function (e, size) {
|
Cryptpad.getFileSize(window.location.href, password, waitFor(function (e, size) {
|
||||||
|
|||||||
@ -832,11 +832,17 @@ MessengerUI, Messages) {
|
|||||||
return $spin;
|
return $spin;
|
||||||
};
|
};
|
||||||
|
|
||||||
var createLimit = function (toolbar) {
|
var createLimit = function (toolbar, config) {
|
||||||
var $limitIcon = $('<span>', {'class': 'fa fa-exclamation-triangle'});
|
var $limitIcon = $('<span>', {'class': 'fa fa-exclamation-triangle'});
|
||||||
var $limit = toolbar.$userAdmin.find('.'+LIMIT_CLS).attr({
|
var $limit = toolbar.$userAdmin.find('.'+LIMIT_CLS).attr({
|
||||||
'title': Messages.pinLimitReached
|
'title': Messages.pinLimitReached
|
||||||
}).append($limitIcon).hide();
|
}).append($limitIcon).hide();
|
||||||
|
|
||||||
|
var priv = config.metadataMgr.getPrivateData();
|
||||||
|
var origin = priv.origin;
|
||||||
|
var l = document.createElement("a");
|
||||||
|
l.href = origin;
|
||||||
|
|
||||||
var todo = function (e, overLimit) {
|
var todo = function (e, overLimit) {
|
||||||
if (e) { return void console.error("Unable to get the pinned usage", e); }
|
if (e) { return void console.error("Unable to get the pinned usage", e); }
|
||||||
if (overLimit) {
|
if (overLimit) {
|
||||||
@ -845,7 +851,7 @@ MessengerUI, Messages) {
|
|||||||
key = 'pinLimitReachedAlertNoAccounts';
|
key = 'pinLimitReachedAlertNoAccounts';
|
||||||
}
|
}
|
||||||
$limit.show().click(function () {
|
$limit.show().click(function () {
|
||||||
UI.alert(Messages._getKey(key, [encodeURIComponent(window.location.hostname)]), null, true);
|
UI.alert(Messages._getKey(key, [encodeURIComponent(l.hostname)]), null, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -565,7 +565,7 @@
|
|||||||
"download_step1": "Laden...",
|
"download_step1": "Laden...",
|
||||||
"download_step2": "Entschlüsselung...",
|
"download_step2": "Entschlüsselung...",
|
||||||
"todo_title": "CryptTodo",
|
"todo_title": "CryptTodo",
|
||||||
"todo_newTodoNamePlaceholder": "Beschreibe deine Aufgabe...",
|
"todo_newTodoNamePlaceholder": "Beschreibe deine Aufgabe…",
|
||||||
"todo_newTodoNameTitle": "Diese Aufgabe zu deiner ToDo-Liste hinzufügen",
|
"todo_newTodoNameTitle": "Diese Aufgabe zu deiner ToDo-Liste hinzufügen",
|
||||||
"todo_markAsCompleteTitle": "Diese Aufgabe als erledigt markieren",
|
"todo_markAsCompleteTitle": "Diese Aufgabe als erledigt markieren",
|
||||||
"todo_markAsIncompleteTitle": "Diese Aufgabe als nicht erledigt markieren",
|
"todo_markAsIncompleteTitle": "Diese Aufgabe als nicht erledigt markieren",
|
||||||
@ -830,7 +830,7 @@
|
|||||||
"generic": {
|
"generic": {
|
||||||
"more": "Erfahre mehr über die Nutzung von CryptPad, indem du unsere <a href=\"/faq.html\" target=\"_blank\">FAQ</a> liest",
|
"more": "Erfahre mehr über die Nutzung von CryptPad, indem du unsere <a href=\"/faq.html\" target=\"_blank\">FAQ</a> liest",
|
||||||
"share": "Benutze das Teilen-Menü (<span class=\"fa fa-share-alt\"></span>), um Links zu generieren, die Mitarbeiter zum Lesen oder Bearbeiten einladen",
|
"share": "Benutze das Teilen-Menü (<span class=\"fa fa-share-alt\"></span>), um Links zu generieren, die Mitarbeiter zum Lesen oder Bearbeiten einladen",
|
||||||
"save": "Alle Änderungen werden automatisch synchronisiert. Du misst sie also nicht speichern"
|
"save": "Alle Änderungen werden automatisch synchronisiert. Du musst sie also nicht selbst speichern"
|
||||||
},
|
},
|
||||||
"text": {
|
"text": {
|
||||||
"formatting": "Du kannst die Werkzeugleiste anzeigen oder verbergen, indem du auf <span class=\"fa fa-caret-down\"></span> oder <span class=\"fa fa-caret-up\"></span> klickst",
|
"formatting": "Du kannst die Werkzeugleiste anzeigen oder verbergen, indem du auf <span class=\"fa fa-caret-down\"></span> oder <span class=\"fa fa-caret-up\"></span> klickst",
|
||||||
|
|||||||
@ -1075,5 +1075,33 @@
|
|||||||
"share_withFriends": "Share",
|
"share_withFriends": "Share",
|
||||||
"notifications_dismiss": "Dismiss",
|
"notifications_dismiss": "Dismiss",
|
||||||
"fm_info_sharedFolderHistory": "This is only the history of your shared folder: <b>{0}</b><br/>Your CryptDrive will stay in read-only mode while you navigate.",
|
"fm_info_sharedFolderHistory": "This is only the history of your shared folder: <b>{0}</b><br/>Your CryptDrive will stay in read-only mode while you navigate.",
|
||||||
"share_description": "Choose what you'd like to share and either get the link or send it directly to your CryptPad friends."
|
"share_description": "Choose what you'd like to share and either get the link or send it directly to your CryptPad friends.",
|
||||||
|
"supportPage": "Support",
|
||||||
|
"admin_cat_support": "Support",
|
||||||
|
"admin_supportInitHelp": "Your server is not yet configured to have a support mailbox. If you want a support mailbox to receive messages from your users, you should ask your server administrator to run the script located in \"./scripts/generate-admin-keys.js\", then store the public key in the \"config.js\" file and send you the private key.",
|
||||||
|
"admin_supportInitPrivate": "Your CryptPad instance is configured to use a support mailbox but your account doesn't have the correct private key to access it. Please use the following form to add or update the private key to your account.",
|
||||||
|
"admin_supportAddKey": "Add private key",
|
||||||
|
"admin_supportAddError": "Invalid private key",
|
||||||
|
"admin_supportInitTitle": "Support mailbox initialization",
|
||||||
|
"admin_supportInitHint": "You can configure a support mailbox in order to give users of your CryptPad instance a way to contact you securely if they have an issue with their account.",
|
||||||
|
"admin_supportListTitle": "Support mailbox",
|
||||||
|
"admin_supportListHint": "Here is the list of tickets sent by the users to the support mailbox. All the administrators can see the messages and the answers. A closed ticket cannot be reopened. You can only remove (hide) closed tickets, and the removed tickets are still visible by the other administrators.",
|
||||||
|
"support_disabledTitle": "Support is not enabled",
|
||||||
|
"support_disabledHint": "This CryptPad instance is not yet configured to use a support form.",
|
||||||
|
"support_cat_new": "New ticket",
|
||||||
|
"support_formTitle": "Ticket title",
|
||||||
|
"support_formHint": "This form can be used to create a new support ticket. Using this form, you can contact the administrators to solve issues or ask any question in a secure way. Please don't create a new ticket if you already have an open ticket about the same issue, but use reply button to provide more information.",
|
||||||
|
"support_formButton": "Send",
|
||||||
|
"support_formTitleError": "Error: title is empty",
|
||||||
|
"support_formContentError": "Error: content is empty",
|
||||||
|
"support_formMessage": "Type your message...",
|
||||||
|
"support_cat_tickets": "Existing tickets",
|
||||||
|
"support_listTitle": "Support tickets",
|
||||||
|
"support_listHint": "Here is the list of tickets sent to the administrators and their answers. A closed ticket cannot be re-opened, you have to make a new one. You can hide tickets that have been closed but they will still be visible by the administrators.",
|
||||||
|
"support_answer": "Reply",
|
||||||
|
"support_close": "Close the ticket",
|
||||||
|
"support_remove": "Remove the ticket",
|
||||||
|
"support_showData": "Show/hide user data",
|
||||||
|
"support_from": "<b>From:</b> {0}",
|
||||||
|
"support_closed": "This ticket has been closed"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -311,12 +311,12 @@ define([
|
|||||||
_getFiles[FILES_DATA] = function () {
|
_getFiles[FILES_DATA] = function () {
|
||||||
var ret = [];
|
var ret = [];
|
||||||
if (!files[FILES_DATA]) { return ret; }
|
if (!files[FILES_DATA]) { return ret; }
|
||||||
return Object.keys(files[FILES_DATA]).map(Number);
|
return Object.keys(files[FILES_DATA]).map(Number).filter(Boolean);
|
||||||
};
|
};
|
||||||
_getFiles[SHARED_FOLDERS] = function () {
|
_getFiles[SHARED_FOLDERS] = function () {
|
||||||
var ret = [];
|
var ret = [];
|
||||||
if (!files[SHARED_FOLDERS]) { return ret; }
|
if (!files[SHARED_FOLDERS]) { return ret; }
|
||||||
return Object.keys(files[SHARED_FOLDERS]).map(Number);
|
return Object.keys(files[SHARED_FOLDERS]).map(Number).filter(Boolean);
|
||||||
};
|
};
|
||||||
var getFiles = exp.getFiles = function (categories) {
|
var getFiles = exp.getFiles = function (categories) {
|
||||||
var ret = [];
|
var ret = [];
|
||||||
|
|||||||
@ -2173,6 +2173,7 @@ define([
|
|||||||
pathname: "/drive/",
|
pathname: "/drive/",
|
||||||
friends: friends,
|
friends: friends,
|
||||||
title: data.title,
|
title: data.title,
|
||||||
|
password: data.password,
|
||||||
common: common,
|
common: common,
|
||||||
hashes: {
|
hashes: {
|
||||||
editHash: parsed.hash
|
editHash: parsed.hash
|
||||||
@ -3510,6 +3511,7 @@ define([
|
|||||||
friends: friends,
|
friends: friends,
|
||||||
title: data.title,
|
title: data.title,
|
||||||
common: common,
|
common: common,
|
||||||
|
password: data.password,
|
||||||
hashes: {
|
hashes: {
|
||||||
editHash: parsed.hash
|
editHash: parsed.hash
|
||||||
}
|
}
|
||||||
@ -3523,6 +3525,7 @@ define([
|
|||||||
origin: APP.origin,
|
origin: APP.origin,
|
||||||
pathname: "/" + padType + "/",
|
pathname: "/" + padType + "/",
|
||||||
friends: friends,
|
friends: friends,
|
||||||
|
password: data.password,
|
||||||
hashes: {
|
hashes: {
|
||||||
editHash: parsed.hash,
|
editHash: parsed.hash,
|
||||||
viewHash: roParsed.hash,
|
viewHash: roParsed.hash,
|
||||||
|
|||||||
@ -42,6 +42,7 @@ define([
|
|||||||
var modal = f({
|
var modal = f({
|
||||||
origin: origin,
|
origin: origin,
|
||||||
pathname: pathname,
|
pathname: pathname,
|
||||||
|
password: priv.password,
|
||||||
hashes: hashes,
|
hashes: hashes,
|
||||||
common: common,
|
common: common,
|
||||||
title: data.title,
|
title: data.title,
|
||||||
|
|||||||
@ -151,6 +151,7 @@ define([
|
|||||||
channel: privateData.support,
|
channel: privateData.support,
|
||||||
curvePublic: user.curvePublic
|
curvePublic: user.curvePublic
|
||||||
});
|
});
|
||||||
|
id = Util.uid();
|
||||||
if (sent) {
|
if (sent) {
|
||||||
$('.cp-sidebarlayout-category[data-category="tickets"]').click();
|
$('.cp-sidebarlayout-category[data-category="tickets"]').click();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,13 +41,13 @@ define([
|
|||||||
var $title = $(form).find('.cp-support-form-title');
|
var $title = $(form).find('.cp-support-form-title');
|
||||||
var $content = $(form).find('.cp-support-form-msg');
|
var $content = $(form).find('.cp-support-form-msg');
|
||||||
|
|
||||||
var title = $title.val();
|
var title = $title.val().trim();
|
||||||
if (!title) {
|
if (!title) {
|
||||||
return void UI.alert(Messages.support_formTitleError);
|
return void UI.alert(Messages.support_formTitleError);
|
||||||
}
|
}
|
||||||
var content = $content.val();
|
var content = $content.val().trim();
|
||||||
if (!content) {
|
if (!content) {
|
||||||
return void UI.alert(form, Messages.support_formContentError);
|
return void UI.alert(Messages.support_formContentError);
|
||||||
}
|
}
|
||||||
$content.val('');
|
$content.val('');
|
||||||
$title.val('');
|
$title.val('');
|
||||||
@ -160,7 +160,7 @@ define([
|
|||||||
'data-hash': hash
|
'data-hash': hash
|
||||||
}, [
|
}, [
|
||||||
h('div.cp-support-message-from' + (fromMe ? '.cp-support-fromme' : ''), [
|
h('div.cp-support-message-from' + (fromMe ? '.cp-support-fromme' : ''), [
|
||||||
h('span', Messages._getKey('support_from', [content.sender.name])),
|
UI.setHTML(h('span'), Messages._getKey('support_from', [content.sender.name])),
|
||||||
h('span.cp-support-message-time', content.time ? new Date(content.time).toLocaleString() : '')
|
h('span.cp-support-message-time', content.time ? new Date(content.time).toLocaleString() : '')
|
||||||
]),
|
]),
|
||||||
h('pre.cp-support-message-content', content.message),
|
h('pre.cp-support-message-content', content.message),
|
||||||
@ -177,7 +177,7 @@ define([
|
|||||||
'data-hash': hash
|
'data-hash': hash
|
||||||
}, [
|
}, [
|
||||||
h('div.cp-support-message-from' + (fromMe ? '.cp-support-fromme' : ''), [
|
h('div.cp-support-message-from' + (fromMe ? '.cp-support-fromme' : ''), [
|
||||||
h('span', Messages._getKey('support_from', [content.sender.name])),
|
UI.setHTML(h('span'), Messages._getKey('support_from', [content.sender.name])),
|
||||||
h('span.cp-support-message-time', content.time ? new Date(content.time).toLocaleString() : '')
|
h('span.cp-support-message-time', content.time ? new Date(content.time).toLocaleString() : '')
|
||||||
]),
|
]),
|
||||||
h('pre.cp-support-message-content', Messages.support_closed)
|
h('pre.cp-support-message-content', Messages.support_closed)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user