Merge branch 'bar' into staging
commit
bd90df9d1e
|
@ -13,7 +13,8 @@ define([], function () {
|
|||
right: 0px;
|
||||
background: linear-gradient(to right, #326599 0%, #326599 50%, #4591c4 50%, #4591c4 100%);
|
||||
color: #fafafa;
|
||||
font-size: 1.5em;
|
||||
font-size: 1.3em;
|
||||
line-height: 120%;
|
||||
opacity: 1;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
@ -77,13 +78,11 @@ define([], function () {
|
|||
background: #FFF;
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
color: #000;
|
||||
text-align: center;
|
||||
color: #3F4141;
|
||||
text-align: left;
|
||||
display: none;
|
||||
}
|
||||
#cp-loading-password-prompt {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
#cp-loading-password-prompt .cp-password-error {
|
||||
color: white;
|
||||
background: #9e0000;
|
||||
|
@ -94,24 +93,49 @@ define([], function () {
|
|||
text-align: left;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
p.cp-password-info{
|
||||
text-align: left;
|
||||
}
|
||||
#cp-loading-password-prompt .cp-password-form {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
#cp-loading-password-prompt .cp-password-form button,
|
||||
#cp-loading-password-prompt .cp-password-form .cp-password-input {
|
||||
#cp-loading-password-prompt .cp-password-form button{
|
||||
background-color: #4591c4;
|
||||
color: white;
|
||||
border: 1px solid #4591c4;
|
||||
}
|
||||
|
||||
.cp-password-input{
|
||||
font-size:16px;
|
||||
border: 1px solid #4591c4;
|
||||
background-color: white;
|
||||
border-radius 0;
|
||||
}
|
||||
|
||||
.cp-password-form button{
|
||||
padding: 8px 12px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
#cp-loading-password-prompt .cp-password-form{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#cp-loading-password-prompt .cp-password-form .cp-password-container {
|
||||
flex-shrink: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
#cp-loading-password-prompt .cp-password-form .cp-password-container .cp-password-reveal{
|
||||
color: #4591c4;
|
||||
padding: 0px 24px;
|
||||
}
|
||||
|
||||
#cp-loading-password-prompt .cp-password-form input {
|
||||
flex: 1;
|
||||
padding: 0 5px;
|
||||
padding: 12px;
|
||||
min-width: 0;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
@ -119,7 +143,7 @@ define([], function () {
|
|||
background-color: #326599;
|
||||
}
|
||||
#cp-loading-password-prompt ::placeholder {
|
||||
color: #d9d9d9;
|
||||
color: #999999;
|
||||
opacity: 1;
|
||||
}
|
||||
#cp-loading-password-prompt :-ms-input-placeholder {
|
||||
|
@ -154,7 +178,7 @@ define([], function () {
|
|||
background: #222;
|
||||
color: #fafafa;
|
||||
text-align: center;
|
||||
font-size: 1.5em;
|
||||
font-size: 1.3em;
|
||||
opacity: 0.7;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
padding: 15px;
|
||||
|
@ -201,6 +225,19 @@ define([], function () {
|
|||
animation-timing-function: cubic-bezier(.6,0.15,0.4,0.85);
|
||||
}
|
||||
|
||||
button.primary{
|
||||
border: 1px solid #4591c4;
|
||||
padding: 8px 12px;
|
||||
text-transform: uppercase;
|
||||
background-color: #4591c4;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
button.primary:hover{
|
||||
background-color: rgb(52, 118, 162);
|
||||
}
|
||||
|
||||
*/}).toString().slice(14, -3);
|
||||
var urlArgs = window.location.href.replace(/^.*\?([^\?]*)$/, function (all, x) { return x; });
|
||||
var elem = document.createElement('div');
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
.radio-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
&:not(:last-child){
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.cp-radio {
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
|
|
@ -97,6 +97,12 @@
|
|||
|
||||
.ckeditor_fix();
|
||||
|
||||
.cp-burn-after-reading {
|
||||
text-align: center;
|
||||
font-size: @colortheme_app-font-size !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.cp-markdown-toolbar {
|
||||
height: @toolbar_line-height;
|
||||
background-color: @toolbar-bg-color-l20;
|
||||
|
|
|
@ -254,6 +254,40 @@ define([
|
|||
!secret.hashData.present);
|
||||
}, "test support for trailing slashes in version 1 hash failed to parse");
|
||||
|
||||
// test support for ownerKey
|
||||
assert(function (cb) {
|
||||
var secret = Hash.parsePadUrl('/pad/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI/present/uPmJDtDJ9okhdIyQ-8zphYlpaAonJDOC6MAcYY6iBwWBQr+XmrQ9uGY9WkApJTfEfAu5QcqaDCw1Ul+JXKcYkA/embed');
|
||||
return cb(secret.hashData.version === 1 &&
|
||||
secret.hashData.mode === "edit" &&
|
||||
secret.hashData.channel === "3Ujt4F2Sjnjbis6CoYWpoQ" &&
|
||||
secret.hashData.key === "usn4+9CqVja8Q7RZOGTfRgqI" &&
|
||||
secret.hashData.ownerKey === "uPmJDtDJ9okhdIyQ-8zphYlpaAonJDOC6MAcYY6iBwWBQr+XmrQ9uGY9WkApJTfEfAu5QcqaDCw1Ul+JXKcYkA" &&
|
||||
secret.hashData.embed &&
|
||||
secret.hashData.present);
|
||||
}, "test support for owner key in version 1 hash failed to parse");
|
||||
assert(function (cb) {
|
||||
var parsed = Hash.parsePadUrl('/pad/#/2/pad/edit/oRE0oLCtEXusRDyin7GyLGcS/p/uPmJDtDJ9okhdIyQ-8zphYlpaAonJDOC6MAcYY6iBwWBQr+XmrQ9uGY9WkApJTfEfAu5QcqaDCw1Ul+JXKcYkA/embed');
|
||||
var secret = Hash.getSecrets('pad', parsed.hash);
|
||||
return cb(parsed.hashData.version === 2 &&
|
||||
parsed.hashData.mode === "edit" &&
|
||||
parsed.hashData.type === "pad" &&
|
||||
parsed.hashData.key === "oRE0oLCtEXusRDyin7GyLGcS" &&
|
||||
secret.channel === "d8d51b4aea863f3f050f47f8ad261753" &&
|
||||
window.nacl.util.encodeBase64(secret.keys.cryptKey) === "0Ts1M6VVEozErV2Nx/LTv6Im5SCD7io2LlhasyyBPQo=" &&
|
||||
secret.keys.validateKey === "f5A1FM9Gp55tnOcM75RyHD1oxBG9ZPh9WDA7qe2Fvps=" &&
|
||||
parsed.hashData.ownerKey === "uPmJDtDJ9okhdIyQ-8zphYlpaAonJDOC6MAcYY6iBwWBQr+XmrQ9uGY9WkApJTfEfAu5QcqaDCw1Ul+JXKcYkA" &&
|
||||
parsed.hashData.embed &&
|
||||
parsed.hashData.password);
|
||||
}, "test support for owner key in version 2 hash failed to parse");
|
||||
assert(function (cb) {
|
||||
var secret = Hash.parsePadUrl('/file/#/1/TRplGM-WsVkXR+LkJ0tD3D45A1YFZ-Cy/eO4RJwh8yHEEDhl1aHfuwQ2IzosPBZx-HDaWc1lW+hY=/uPmJDtDJ9okhdIyQ-8zphYlpaAonJDOC6MAcYY6iBwWBQr+XmrQ9uGY9WkApJTfEfAu5QcqaDCw1Ul+JXKcYkA/');
|
||||
return cb(secret.hashData.version === 1 &&
|
||||
secret.hashData.channel === "TRplGM/WsVkXR+LkJ0tD3D45A1YFZ/Cy" &&
|
||||
secret.hashData.key === "eO4RJwh8yHEEDhl1aHfuwQ2IzosPBZx/HDaWc1lW+hY=" &&
|
||||
secret.hashData.ownerKey === "uPmJDtDJ9okhdIyQ-8zphYlpaAonJDOC6MAcYY6iBwWBQr+XmrQ9uGY9WkApJTfEfAu5QcqaDCw1Ul+JXKcYkA" &&
|
||||
!secret.hashData.present);
|
||||
}, "test support for owner key in version 1 file hash failed to parse");
|
||||
|
||||
assert(function (cb) {
|
||||
var secret = Hash.parsePadUrl('/invite/#/2/invite/edit/oRE0oLCtEXusRDyin7GyLGcS/p/');
|
||||
var hd = secret.hashData;
|
||||
|
|
|
@ -98,6 +98,7 @@ define([
|
|||
};
|
||||
var mkHelpMenu = function (framework) {
|
||||
var $codeMirrorContainer = $('#cp-app-code-container');
|
||||
$codeMirrorContainer.prepend(framework._.sfCommon.getBurnAfterReadingWarning());
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['text', 'code']);
|
||||
$codeMirrorContainer.prepend(helpMenu.menu);
|
||||
|
||||
|
|
|
@ -15,6 +15,20 @@ var factory = function (Util, Crypto, Nacl) {
|
|||
.decodeUTF8(JSON.stringify(list))));
|
||||
};
|
||||
|
||||
// XXX move this code?
|
||||
Hash.generateSignPair = function () {
|
||||
var ed = Nacl.sign.keyPair();
|
||||
var makeSafe = function (key) {
|
||||
return Crypto.b64RemoveSlashes(key).replace(/=+$/g, '');
|
||||
};
|
||||
return {
|
||||
validateKey: Hash.encodeBase64(ed.publicKey),
|
||||
signKey: Hash.encodeBase64(ed.secretKey),
|
||||
safeValidateKey: makeSafe(Hash.encodeBase64(ed.publicKey)),
|
||||
safeSignKey: makeSafe(Hash.encodeBase64(ed.secretKey)),
|
||||
};
|
||||
};
|
||||
|
||||
var getEditHashFromKeys = Hash.getEditHashFromKeys = function (secret) {
|
||||
var version = secret.version;
|
||||
var data = secret.keys;
|
||||
|
@ -134,6 +148,17 @@ Version 1
|
|||
/code/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI
|
||||
*/
|
||||
|
||||
var getOwnerKey = function (hashArr) {
|
||||
var k;
|
||||
// Check if we have a ownerKey for this pad
|
||||
hashArr.some(function (data) {
|
||||
if (data.length === 86) { // XXX 88 characters - 2 trailing "="...
|
||||
k = data;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return k;
|
||||
};
|
||||
var parseTypeHash = Hash.parseTypeHash = function (type, hash) {
|
||||
if (!hash) { return; }
|
||||
var options;
|
||||
|
@ -158,9 +183,12 @@ Version 1
|
|||
options = hashArr.slice(5);
|
||||
parsed.present = options.indexOf('present') !== -1;
|
||||
parsed.embed = options.indexOf('embed') !== -1;
|
||||
parsed.ownerKey = getOwnerKey(options);
|
||||
|
||||
parsed.getHash = function (opts) {
|
||||
var hash = hashArr.slice(0, 5).join('/') + '/';
|
||||
var owner = typeof(opts.ownerKey) !== "undefined" ? opts.ownerKey : parsed.ownerKey;
|
||||
if (owner) { hash += owner + '/'; }
|
||||
if (opts.embed) { hash += 'embed/'; }
|
||||
if (opts.present) { hash += 'present/'; }
|
||||
return hash;
|
||||
|
@ -177,9 +205,12 @@ Version 1
|
|||
parsed.password = options.indexOf('p') !== -1;
|
||||
parsed.present = options.indexOf('present') !== -1;
|
||||
parsed.embed = options.indexOf('embed') !== -1;
|
||||
parsed.ownerKey = getOwnerKey(options);
|
||||
|
||||
parsed.getHash = function (opts) {
|
||||
var hash = hashArr.slice(0, 5).join('/') + '/';
|
||||
var owner = typeof(opts.ownerKey) !== "undefined" ? opts.ownerKey : parsed.ownerKey;
|
||||
if (owner) { hash += owner + '/'; }
|
||||
if (parsed.password) { hash += 'p/'; }
|
||||
if (opts.embed) { hash += 'embed/'; }
|
||||
if (opts.present) { hash += 'present/'; }
|
||||
|
@ -196,6 +227,8 @@ Version 1
|
|||
parsed.version = 1;
|
||||
parsed.channel = hashArr[2].replace(/-/g, '/');
|
||||
parsed.key = hashArr[3].replace(/-/g, '/');
|
||||
options = hashArr.slice(4);
|
||||
parsed.ownerKey = getOwnerKey(options);
|
||||
return parsed;
|
||||
}
|
||||
if (hashArr[1] && hashArr[1] === '2') { // Version 2
|
||||
|
@ -207,9 +240,12 @@ Version 1
|
|||
parsed.password = options.indexOf('p') !== -1;
|
||||
parsed.present = options.indexOf('present') !== -1;
|
||||
parsed.embed = options.indexOf('embed') !== -1;
|
||||
parsed.ownerKey = getOwnerKey(options);
|
||||
|
||||
parsed.getHash = function (opts) {
|
||||
var hash = hashArr.slice(0, 4).join('/') + '/';
|
||||
var owner = typeof(opts.ownerKey) !== "undefined" ? opts.ownerKey : parsed.ownerKey;
|
||||
if (owner) { hash += owner + '/'; }
|
||||
if (parsed.password) { hash += 'p/'; }
|
||||
if (opts.embed) { hash += 'embed/'; }
|
||||
if (opts.present) { hash += 'present/'; }
|
||||
|
|
|
@ -209,10 +209,16 @@ define([
|
|||
$(title).prepend(' ').prepend(icon);
|
||||
}
|
||||
$(title).click(function () {
|
||||
var old = tabs[active];
|
||||
if (old.onHide) { old.onHide(); }
|
||||
titles.forEach(function (t) { $(t).removeClass('alertify-tabs-active'); });
|
||||
contents.forEach(function (c) { $(c).removeClass('alertify-tabs-content-active'); });
|
||||
if (tab.onShow) {
|
||||
tab.onShow();
|
||||
}
|
||||
$(title).addClass('alertify-tabs-active');
|
||||
$(content).addClass('alertify-tabs-content-active');
|
||||
active = i;
|
||||
});
|
||||
titles.push(title);
|
||||
contents.push(content);
|
||||
|
|
|
@ -917,60 +917,79 @@ define([
|
|||
className: 'primary cp-share-with-friends',
|
||||
name: Messages.share_withFriends,
|
||||
onClick: function () {
|
||||
var href = Hash.getRelativeHref(linkGetter());
|
||||
var $friends = $div.find('.cp-usergrid-user.cp-selected');
|
||||
$friends.each(function (i, el) {
|
||||
var curve = $(el).attr('data-curve');
|
||||
// Check if the selected element is a friend or a team
|
||||
if (curve) { // Friend
|
||||
if (!curve || !friends[curve]) { return; }
|
||||
var friend = friends[curve];
|
||||
if (!friend.notifications || !friend.curvePublic) { return; }
|
||||
common.mailbox.sendTo("SHARE_PAD", {
|
||||
href: href,
|
||||
password: config.password,
|
||||
isTemplate: config.isTemplate,
|
||||
name: myName,
|
||||
title: title
|
||||
}, {
|
||||
channel: friend.notifications,
|
||||
curvePublic: friend.curvePublic
|
||||
});
|
||||
var href;
|
||||
NThen(function (waitFor) {
|
||||
var w = waitFor();
|
||||
// linkGetter can be async if this is a burn after reading URL
|
||||
var res = linkGetter({}, function (url) {
|
||||
if (!url) {
|
||||
waitFor.abort();
|
||||
return;
|
||||
}
|
||||
console.warn('BAR');
|
||||
href = url;
|
||||
setTimeout(w);
|
||||
});
|
||||
if (res && /^http/.test(res)) {
|
||||
href = Hash.getRelativeHref(res);
|
||||
setTimeout(w);
|
||||
return;
|
||||
}
|
||||
// Team
|
||||
var ed = $(el).attr('data-ed');
|
||||
var team = teams[ed];
|
||||
if (!team) { return; }
|
||||
sframeChan.query('Q_STORE_IN_TEAM', {
|
||||
href: href,
|
||||
password: config.password,
|
||||
path: config.isTemplate ? ['template'] : undefined,
|
||||
title: title,
|
||||
teamId: team.id
|
||||
}, function (err) {
|
||||
if (err) { return void console.error(err); }
|
||||
}).nThen(function () {
|
||||
var $friends = $div.find('.cp-usergrid-user.cp-selected');
|
||||
$friends.each(function (i, el) {
|
||||
var curve = $(el).attr('data-curve');
|
||||
// Check if the selected element is a friend or a team
|
||||
if (curve) { // Friend
|
||||
if (!curve || !friends[curve]) { return; }
|
||||
var friend = friends[curve];
|
||||
if (!friend.notifications || !friend.curvePublic) { return; }
|
||||
common.mailbox.sendTo("SHARE_PAD", {
|
||||
href: href,
|
||||
password: config.password,
|
||||
isTemplate: config.isTemplate,
|
||||
name: myName,
|
||||
title: title
|
||||
}, {
|
||||
channel: friend.notifications,
|
||||
curvePublic: friend.curvePublic
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Team
|
||||
var ed = $(el).attr('data-ed');
|
||||
var team = teams[ed];
|
||||
if (!team) { return; }
|
||||
sframeChan.query('Q_STORE_IN_TEAM', {
|
||||
href: href,
|
||||
password: config.password,
|
||||
path: config.isTemplate ? ['template'] : undefined,
|
||||
title: title,
|
||||
teamId: team.id
|
||||
}, function (err) {
|
||||
if (err) { return void console.error(err); }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
UI.findCancelButton().click();
|
||||
UI.findCancelButton().click();
|
||||
|
||||
// Update the "recently shared with" array:
|
||||
// Get the selected curves
|
||||
var curves = $friends.toArray().map(function (el) {
|
||||
return ($(el).attr('data-curve') || '').slice(0,8);
|
||||
}).filter(function (x) { return x; });
|
||||
// Prepend them to the "order" array
|
||||
Array.prototype.unshift.apply(order, curves);
|
||||
order = Util.deduplicateString(order);
|
||||
// Make sure we don't have "old" friends and save
|
||||
order = order.filter(function (curve) {
|
||||
return smallCurves.indexOf(curve) !== -1;
|
||||
// Update the "recently shared with" array:
|
||||
// Get the selected curves
|
||||
var curves = $friends.toArray().map(function (el) {
|
||||
return ($(el).attr('data-curve') || '').slice(0,8);
|
||||
}).filter(function (x) { return x; });
|
||||
// Prepend them to the "order" array
|
||||
Array.prototype.unshift.apply(order, curves);
|
||||
order = Util.deduplicateString(order);
|
||||
// Make sure we don't have "old" friends and save
|
||||
order = order.filter(function (curve) {
|
||||
return smallCurves.indexOf(curve) !== -1;
|
||||
});
|
||||
common.setAttribute(['general', 'share-friends'], order);
|
||||
if (onShare) {
|
||||
onShare.fire();
|
||||
}
|
||||
});
|
||||
common.setAttribute(['general', 'share-friends'], order);
|
||||
if (onShare) {
|
||||
onShare.fire();
|
||||
}
|
||||
},
|
||||
keys: [13]
|
||||
};
|
||||
|
@ -1049,6 +1068,29 @@ define([
|
|||
}
|
||||
};
|
||||
|
||||
var makeBurnAfterReadingUrl = function (common, href, channel, cb) {
|
||||
var keyPair = Hash.generateSignPair();
|
||||
var parsed = Hash.parsePadUrl(href);
|
||||
console.error(href, parsed);
|
||||
var newHref = parsed.getUrl({
|
||||
ownerKey: keyPair.safeSignKey
|
||||
});
|
||||
var sframeChan = common.getSframeChannel();
|
||||
NThen(function (waitFor) {
|
||||
sframeChan.query('Q_SET_PAD_METADATA', {
|
||||
channel: channel,
|
||||
command: 'ADD_OWNERS',
|
||||
value: [keyPair.validateKey]
|
||||
}, waitFor(function (err) {
|
||||
if (err) {
|
||||
waitFor.abort();
|
||||
UI.warn(Messages.error);
|
||||
}
|
||||
}));
|
||||
}).nThen(function () {
|
||||
cb(newHref);
|
||||
});
|
||||
};
|
||||
UIElements.createShareModal = function (config) {
|
||||
var origin = config.origin;
|
||||
var pathname = config.pathname;
|
||||
|
@ -1078,6 +1120,7 @@ define([
|
|||
var parsed = Hash.parsePadUrl(pathname);
|
||||
var canPresent = ['code', 'slide'].indexOf(parsed.type) !== -1;
|
||||
|
||||
var burnAfterReading;
|
||||
var rights = h('div.msg.cp-inline-radio-group', [
|
||||
h('label', Messages.share_linkAccess),
|
||||
h('div.radio-group',[
|
||||
|
@ -1086,9 +1129,33 @@ define([
|
|||
canPresent ? UI.createRadio('accessRights', 'cp-share-present',
|
||||
Messages.share_linkPresent, false, { mark: {tabindex:1} }) : undefined,
|
||||
UI.createRadio('accessRights', 'cp-share-editable-true',
|
||||
Messages.share_linkEdit, false, { mark: {tabindex:1} })])
|
||||
Messages.share_linkEdit, false, { mark: {tabindex:1} })]),
|
||||
burnAfterReading = hashes.viewHash ? UI.createRadio('accessRights', 'cp-share-bar', Messages.burnAfterReading_linkBurnAfterReading ||
|
||||
'View once and self-destruct', false, { mark: {tabindex:1}, label: {style: "display: none;"} }) : undefined // XXX temp KEY
|
||||
]);
|
||||
|
||||
// Burn after reading
|
||||
// Check if we are an owner of this pad. If we are, we can show the burn after reading option.
|
||||
// When BAR is selected, display a red message indicating the consequence and add
|
||||
// the options to generate the BAR url
|
||||
var barAlert = h('div.alert.alert-danger.cp-alertify-bar-selected', {
|
||||
style: 'display: none;'
|
||||
}, Messages.burnAfterReading_warningLink || " You have set this pad to self-destruct. Once a recipient opens this pad, it will be permanently deleted from the server."); // XXX temp KEY
|
||||
var channel = Hash.getSecrets('pad', hash, config.password).channel;
|
||||
common.getPadMetadata({
|
||||
channel: channel
|
||||
}, function (obj) {
|
||||
if (!obj || obj.error) { return; }
|
||||
var priv = common.getMetadataMgr().getPrivateData();
|
||||
// Not an owner: don't display the burn after reading option
|
||||
if (!Array.isArray(obj.owners) || obj.owners.indexOf(priv.edPublic) === -1) {
|
||||
$(burnAfterReading).remove();
|
||||
return;
|
||||
}
|
||||
// When the burn after reading option is selected, transform the modal buttons
|
||||
$(burnAfterReading).show();
|
||||
});
|
||||
|
||||
var $rights = $(rights);
|
||||
|
||||
var saveValue = function () {
|
||||
|
@ -1100,13 +1167,25 @@ define([
|
|||
});
|
||||
};
|
||||
|
||||
var getLinkValue = function (initValue) {
|
||||
var burnAfterReadingUrl;
|
||||
|
||||
var getLinkValue = function (initValue, cb) {
|
||||
var val = initValue || {};
|
||||
var edit = val.edit !== undefined ? val.edit : Util.isChecked($rights.find('#cp-share-editable-true'));
|
||||
var embed = val.embed;
|
||||
var present = val.present !== undefined ? val.present : Util.isChecked($rights.find('#cp-share-present'));
|
||||
var burnAfterReading = Util.isChecked($rights.find('#cp-share-bar'));
|
||||
if (burnAfterReading && !burnAfterReadingUrl) {
|
||||
if (cb) { // Called from the contacts tab, "share" button
|
||||
var barHref = origin + pathname + '#' + (hashes.viewHash || hashes.editHash);
|
||||
return makeBurnAfterReadingUrl(common, barHref, channel, function (url) {
|
||||
cb(url);
|
||||
});
|
||||
}
|
||||
return Messages.burnAfterReading_generateLink || 'Click on the button below to generate a link'; // XXX temp KEY
|
||||
}
|
||||
var hash = (!hashes.viewHash || (edit && hashes.editHash)) ? hashes.editHash : hashes.viewHash;
|
||||
var href = origin + pathname + '#' + hash;
|
||||
var href = burnAfterReading ? burnAfterReadingUrl : (origin + pathname + '#' + hash);
|
||||
var parsed = Hash.parsePadUrl(href);
|
||||
return origin + parsed.getUrl({embed: embed, present: present});
|
||||
};
|
||||
|
@ -1160,8 +1239,8 @@ define([
|
|||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
linkContent.push($(barAlert).clone()[0]); // Burn after reading
|
||||
|
||||
var link = h('div.cp-share-modal', linkContent);
|
||||
var $link = $(link);
|
||||
|
@ -1169,7 +1248,7 @@ define([
|
|||
var linkButtons = [
|
||||
makeCancelButton(),
|
||||
!config.sharedFolder && {
|
||||
className: 'secondary',
|
||||
className: 'secondary cp-nobar',
|
||||
name: Messages.share_linkOpen,
|
||||
onClick: function () {
|
||||
saveValue();
|
||||
|
@ -1180,9 +1259,8 @@ define([
|
|||
return true;
|
||||
},
|
||||
keys: [[13, 'ctrl']]
|
||||
},
|
||||
{
|
||||
className: 'primary',
|
||||
}, {
|
||||
className: 'primary cp-nobar',
|
||||
name: Messages.share_linkCopy,
|
||||
onClick: function () {
|
||||
saveValue();
|
||||
|
@ -1193,26 +1271,26 @@ define([
|
|||
if (success) { UI.log(Messages.shareSuccess); }
|
||||
},
|
||||
keys: [13]
|
||||
}, {
|
||||
className: 'primary cp-bar',
|
||||
name: 'GENERATE LINK',
|
||||
onClick: function () {
|
||||
var barHref = origin + pathname + '#' + (hashes.viewHash || hashes.editHash);
|
||||
makeBurnAfterReadingUrl(common, barHref, channel, function (url) {
|
||||
burnAfterReadingUrl = url;
|
||||
$rights.find('input[type="radio"]').trigger('change');
|
||||
});
|
||||
return true;
|
||||
},
|
||||
keys: []
|
||||
}
|
||||
];
|
||||
|
||||
// update values for link preview when radio btns change
|
||||
$link.find('#cp-share-link-preview').val(getLinkValue());
|
||||
$rights.find('input[type="radio"]').on('change', function () {
|
||||
$link.find('#cp-share-link-preview').val(getLinkValue({
|
||||
embed: Util.isChecked($link.find('#cp-share-embed'))
|
||||
}));
|
||||
});
|
||||
$link.find('input[type="checkbox"]').on('change', function () {
|
||||
$link.find('#cp-share-link-preview').val(getLinkValue({
|
||||
embed: Util.isChecked($link.find('#cp-share-embed'))
|
||||
}));
|
||||
});
|
||||
|
||||
var frameLink = UI.dialog.customModal(link, {
|
||||
buttons: linkButtons,
|
||||
onClose: config.onClose,
|
||||
});
|
||||
$(frameLink).find('.cp-bar').hide();
|
||||
|
||||
// Share with contacts tab
|
||||
|
||||
|
@ -1240,10 +1318,17 @@ define([
|
|||
]));
|
||||
}
|
||||
|
||||
$(contactsContent).append($(barAlert).clone()); // Burn after reading
|
||||
|
||||
var contactButtons = friendsObject.buttons;
|
||||
contactButtons.unshift(makeCancelButton());
|
||||
|
||||
|
||||
var onShowContacts = function () {
|
||||
if (!hasFriends) {
|
||||
$rights.hide();
|
||||
}
|
||||
};
|
||||
|
||||
var frameContacts = UI.dialog.customModal(contactsContent, {
|
||||
buttons: contactButtons,
|
||||
onClose: config.onClose,
|
||||
|
@ -1282,26 +1367,60 @@ define([
|
|||
keys: [13]
|
||||
}];
|
||||
|
||||
var onShowEmbed = function () {
|
||||
$rights.find('#cp-share-bar').closest('label').hide();
|
||||
$rights.find('input[type="radio"]:enabled').first().prop('checked', 'checked');
|
||||
$rights.find('input[type="radio"]').trigger('change');
|
||||
};
|
||||
|
||||
var embed = h('div.cp-share-modal', embedContent);
|
||||
var $embed = $(embed);
|
||||
|
||||
// update values for link preview when radio btns change
|
||||
$embed.find('#cp-embed-link-preview').val(getEmbedValue());
|
||||
$rights.find('input[type="radio"]').on('change', function () {
|
||||
$embed.find('#cp-embed-link-preview').val(getEmbedValue());
|
||||
});
|
||||
|
||||
var frameEmbed = UI.dialog.customModal(embed, {
|
||||
buttons: embedButtons,
|
||||
onClose: config.onClose,
|
||||
});
|
||||
|
||||
// update values for link and embed preview when radio btns change
|
||||
$embed.find('#cp-embed-link-preview').val(getEmbedValue());
|
||||
$link.find('#cp-share-link-preview').val(getLinkValue());
|
||||
$rights.find('input[type="radio"]').on('change', function () {
|
||||
$link.find('#cp-share-link-preview').val(getLinkValue({
|
||||
embed: Util.isChecked($link.find('#cp-share-embed'))
|
||||
}));
|
||||
// Hide or show the burn after reading alert
|
||||
if (Util.isChecked($rights.find('#cp-share-bar')) && !burnAfterReadingUrl) {
|
||||
$('.cp-alertify-bar-selected').show();
|
||||
// Show burn after reading button
|
||||
$('.alertify').find('.cp-bar').show();
|
||||
$('.alertify').find('.cp-nobar').hide();
|
||||
return;
|
||||
}
|
||||
$embed.find('#cp-embed-link-preview').val(getEmbedValue());
|
||||
// Hide burn after reading button
|
||||
$('.alertify').find('.cp-nobar').show();
|
||||
$('.alertify').find('.cp-bar').hide();
|
||||
$('.cp-alertify-bar-selected').hide();
|
||||
});
|
||||
$link.find('input[type="checkbox"]').on('change', function () {
|
||||
$link.find('#cp-share-link-preview').val(getLinkValue({
|
||||
embed: Util.isChecked($link.find('#cp-share-embed'))
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
// Create modal
|
||||
var resetTab = function () {
|
||||
$rights.show();
|
||||
$rights.find('label.cp-radio').show();
|
||||
};
|
||||
var tabs = [{
|
||||
title: Messages.share_contactCategory,
|
||||
icon: "fa fa-address-book",
|
||||
content: frameContacts,
|
||||
active: hasFriends
|
||||
active: hasFriends,
|
||||
onShow: onShowContacts,
|
||||
onHide: resetTab
|
||||
}, {
|
||||
title: Messages.share_linkCategory,
|
||||
icon: "fa fa-link",
|
||||
|
@ -1310,7 +1429,9 @@ define([
|
|||
}, {
|
||||
title: Messages.share_embedCategory,
|
||||
icon: "fa fa-code",
|
||||
content: frameEmbed
|
||||
content: frameEmbed,
|
||||
onShow: onShowEmbed,
|
||||
onHide: resetTab
|
||||
}];
|
||||
if (typeof(AppConfig.customizeShareOptions) === 'function') {
|
||||
AppConfig.customizeShareOptions(hashes, tabs, {
|
||||
|
@ -3866,6 +3987,7 @@ define([
|
|||
|
||||
UIElements.onServerError = function (common, err, toolbar, cb) {
|
||||
if (["EDELETED", "EEXPIRED"].indexOf(err.type) === -1) { return; }
|
||||
var priv = common.getMetadataMgr().getPrivateData();
|
||||
var msg = err.type;
|
||||
if (err.type === 'EEXPIRED') {
|
||||
msg = Messages.expiredError;
|
||||
|
@ -3873,11 +3995,14 @@ define([
|
|||
msg += Messages.errorCopy;
|
||||
}
|
||||
} else if (err.type === 'EDELETED') {
|
||||
if (priv.burnAfterReading) { return void cb(); }
|
||||
msg = Messages.deletedError;
|
||||
if (err.loaded) {
|
||||
msg += Messages.errorCopy;
|
||||
}
|
||||
}
|
||||
var sframeChan = common.getSframeChannel();
|
||||
sframeChan.event('EV_SHARE_OPEN', {hidden: true});
|
||||
if (toolbar && typeof toolbar.deleted === "function") { toolbar.deleted(); }
|
||||
UI.errorLoadingScreen(msg, true, true);
|
||||
(cb || function () {})();
|
||||
|
@ -3922,6 +4047,26 @@ define([
|
|||
$password.find('.cp-password-input').focus();
|
||||
};
|
||||
|
||||
UIElements.displayBurnAfterReadingPage = function (common, cb) {
|
||||
var info = h('p.cp-password-info', Messages.burnAfterReading_warning || 'This document will self-destruct as soon as you open it. It will be removed form the server, once you close this window you will not be able to access it again. If you are not ready to proceed you can close this window and come back later. '); // XXX temp KEY
|
||||
var button = h('button.primary', Messages.burnAfterReading_proceed || 'view and delete'); // XXX temp KEY
|
||||
|
||||
$(button).on('click', function () {
|
||||
cb();
|
||||
});
|
||||
|
||||
var block = h('div#cp-loading-burn-after-reading', [
|
||||
info,
|
||||
button
|
||||
]);
|
||||
UI.errorLoadingScreen(block);
|
||||
};
|
||||
UIElements.getBurnAfterReadingWarning = function (common) {
|
||||
var priv = common.getMetadataMgr().getPrivateData();
|
||||
if (!priv.burnAfterReading) { return; }
|
||||
return h('div.alert.alert-danger.cp-burn-after-reading', Messages.burnAfterReading_warningDeleted || 'This pad has been deleted from the server, once you close this window you will not be able to access it again.'); // XXX temp KEY
|
||||
};
|
||||
|
||||
var crowdfundingState = false;
|
||||
UIElements.displayCrowdfunding = function (common) {
|
||||
if (crowdfundingState) { return; }
|
||||
|
@ -3979,6 +4124,9 @@ define([
|
|||
if (data && data.stored) { return; } // We won't display the popup for dropped files
|
||||
var priv = common.getMetadataMgr().getPrivateData();
|
||||
|
||||
// This pad will be deleted automatically, it shouldn't be stored
|
||||
if (priv.burnAfterReading) { return; }
|
||||
|
||||
var typeMsg = priv.pathname.indexOf('/file/') !== -1 ? Messages.autostore_file :
|
||||
priv.pathname.indexOf('/drive/') !== -1 ? Messages.autostore_sf :
|
||||
Messages.autostore_pad;
|
||||
|
|
|
@ -847,6 +847,10 @@ define([
|
|||
postMessage('GET_PAD_METADATA', data, cb);
|
||||
};
|
||||
|
||||
common.burnPad = function (data) {
|
||||
postMessage('BURN_PAD', data);
|
||||
};
|
||||
|
||||
common.changePadPassword = function (Crypt, Crypto, data, cb) {
|
||||
var href = data.href;
|
||||
var newPassword = data.password;
|
||||
|
|
|
@ -926,6 +926,7 @@ define([
|
|||
$rightside.append($forget);
|
||||
|
||||
var helpMenu = common.createHelpMenu(['beta', 'oo']);
|
||||
$('#cp-app-oo-editor').prepend(common.getBurnAfterReadingWarning());
|
||||
$('#cp-app-oo-editor').prepend(helpMenu.menu);
|
||||
toolbar.$drawer.append(helpMenu.button);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ define([
|
|||
'/common/common-feedback.js',
|
||||
'/common/common-realtime.js',
|
||||
'/common/common-messaging.js',
|
||||
'/common/pinpad.js',
|
||||
'/common/outer/sharedfolder.js',
|
||||
'/common/outer/cursor.js',
|
||||
'/common/outer/onlyoffice.js',
|
||||
|
@ -26,7 +27,7 @@ define([
|
|||
'/bower_components/nthen/index.js',
|
||||
'/bower_components/saferphore/index.js',
|
||||
], function (Sortify, UserObject, ProxyManager, Migrate, Hash, Util, Constants, Feedback,
|
||||
Realtime, Messaging,
|
||||
Realtime, Messaging, Pinpad,
|
||||
SF, Cursor, OnlyOffice, Mailbox, Profile, Team, Messenger,
|
||||
NetConfig, AppConfig,
|
||||
Crypto, ChainPad, CpNetflux, Listmap, nThen, Saferphore) {
|
||||
|
@ -409,19 +410,17 @@ define([
|
|||
var initRpc = function (clientId, data, cb) {
|
||||
if (!store.loggedIn) { return cb(); }
|
||||
if (store.rpc) { return void cb(account); }
|
||||
require(['/common/pinpad.js'], function (Pinpad) {
|
||||
Pinpad.create(store.network, store.proxy, function (e, call) {
|
||||
if (e) { return void cb({error: e}); }
|
||||
Pinpad.create(store.network, store.proxy, function (e, call) {
|
||||
if (e) { return void cb({error: e}); }
|
||||
|
||||
store.rpc = call;
|
||||
store.rpc = call;
|
||||
|
||||
Store.getPinLimit(null, null, function (obj) {
|
||||
if (obj.error) { console.error(obj.error); }
|
||||
account.limit = obj.limit;
|
||||
account.plan = obj.plan;
|
||||
account.note = obj.note;
|
||||
cb(obj);
|
||||
});
|
||||
Store.getPinLimit(null, null, function (obj) {
|
||||
if (obj.error) { console.error(obj.error); }
|
||||
account.limit = obj.limit;
|
||||
account.plan = obj.plan;
|
||||
account.note = obj.note;
|
||||
cb(obj);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -1653,6 +1652,73 @@ define([
|
|||
cb();
|
||||
};
|
||||
|
||||
// Delete a pad received with a burn after reading URL
|
||||
|
||||
var notifyOwnerPadRemoved = function (data, obj) {
|
||||
var channel = data.channel;
|
||||
var href = data.href;
|
||||
var parsed = Hash.parsePadUrl(href);
|
||||
var secret = Hash.getSecrets(parsed.type, parsed.hash, data.password);
|
||||
if (obj && obj.error) { return; }
|
||||
if (!obj.mailbox) { return; }
|
||||
|
||||
// Decrypt the mailbox
|
||||
var crypto = Crypto.createEncryptor(secret.keys);
|
||||
var m = [];
|
||||
try {
|
||||
if (typeof (obj.mailbox) === "string") {
|
||||
m.push(crypto.decrypt(obj.mailbox, true, true));
|
||||
} else {
|
||||
Object.keys(obj.mailbox).forEach(function (k) {
|
||||
m.push(crypto.decrypt(obj.mailbox[k], true, true));
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
// Tell all the owners that the pad was deleted from the server
|
||||
var curvePublic = store.proxy.curvePublic;
|
||||
var myData = Messaging.createData(store.proxy, false);
|
||||
m.forEach(function (obj) {
|
||||
var mb = JSON.parse(obj);
|
||||
if (mb.curvePublic === curvePublic) { return; }
|
||||
store.mailbox.sendTo('OWNED_PAD_REMOVED', {
|
||||
channel: channel,
|
||||
user: myData
|
||||
}, {
|
||||
channel: mb.notifications,
|
||||
curvePublic: mb.curvePublic
|
||||
}, function () {});
|
||||
});
|
||||
};
|
||||
|
||||
Store.burnPad = function (clientId, data) {
|
||||
var channel = data.channel;
|
||||
var ownerKey = Crypto.b64AddSlashes(data.ownerKey || '');
|
||||
if (!channel || !ownerKey) { return void console.error("Can't delete BAR pad"); }
|
||||
try {
|
||||
var signKey = Hash.decodeBase64(ownerKey);
|
||||
var pair = Crypto.Nacl.sign.keyPair.fromSecretKey(signKey);
|
||||
Pinpad.create(store.network, {
|
||||
edPublic: Hash.encodeBase64(pair.publicKey),
|
||||
edPrivate: Hash.encodeBase64(pair.secretKey)
|
||||
}, function (e, rpc) {
|
||||
if (e) { return void console.error(e); }
|
||||
Store.getPadMetadata(null, {
|
||||
channel: channel
|
||||
}, function (md) {
|
||||
rpc.removeOwnedChannel(channel, function (err) {
|
||||
if (err) { return void console.error(err); }
|
||||
// Notify owners that the pad was removed
|
||||
notifyOwnerPadRemoved(data, md);
|
||||
});
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
// Fetch the latest version of the metadata on the server and return it.
|
||||
// If the pad is stored in our drive, update the local values of "owners" and "expire"
|
||||
Store.getPadMetadata = function (clientId, data, cb) {
|
||||
|
@ -2109,6 +2175,11 @@ define([
|
|||
updateMetadata: function () {
|
||||
broadcast([], "UPDATE_METADATA");
|
||||
},
|
||||
updateDrive: function () {
|
||||
sendDriveEvent('DRIVE_CHANGE', {
|
||||
path: ['drive', 'filesData']
|
||||
});
|
||||
},
|
||||
pinPads: function (data, cb) { Store.pinPads(null, data, cb); },
|
||||
}, waitFor, function (ev, data, clients, _cb) {
|
||||
var cb = Util.once(_cb || function () {});
|
||||
|
|
|
@ -17,6 +17,7 @@ var factory = function (Util, Cred, Nacl) {
|
|||
};
|
||||
};
|
||||
|
||||
// XXX move this function?
|
||||
Invite.generateSignPair = function () {
|
||||
var ed = Nacl.sign.keyPair();
|
||||
return {
|
||||
|
|
|
@ -482,6 +482,31 @@ define([
|
|||
cb(true);
|
||||
};
|
||||
|
||||
handlers['OWNED_PAD_REMOVED'] = function (ctx, box, data, cb) {
|
||||
var msg = data.msg;
|
||||
var content = msg.content;
|
||||
|
||||
if (msg.author !== content.user.curvePublic) { return void cb(true); }
|
||||
if (!content.channel) {
|
||||
console.log('Remove invalid notification');
|
||||
return void cb(true);
|
||||
}
|
||||
|
||||
var channel = content.channel;
|
||||
var res = ctx.store.manager.findChannel(channel);
|
||||
|
||||
res.forEach(function (obj) {
|
||||
var paths = ctx.store.manager.findFile(obj.id);
|
||||
ctx.store.manager.delete({
|
||||
paths: paths
|
||||
}, function () {
|
||||
ctx.updateDrive();
|
||||
});
|
||||
});
|
||||
|
||||
cb(true);
|
||||
};
|
||||
|
||||
|
||||
|
||||
return {
|
||||
|
|
|
@ -422,6 +422,7 @@ proxy.mailboxes = {
|
|||
store: store,
|
||||
pinPads: cfg.pinPads,
|
||||
updateMetadata: cfg.updateMetadata,
|
||||
updateDrive: cfg.updateDrive,
|
||||
emit: emit,
|
||||
clients: [],
|
||||
boxes: {},
|
||||
|
|
|
@ -80,6 +80,7 @@ define([
|
|||
IS_NEW_CHANNEL: Store.isNewChannel,
|
||||
REQUEST_PAD_ACCESS: Store.requestPadAccess,
|
||||
GIVE_PAD_ACCESS: Store.givePadAccess,
|
||||
BURN_PAD: Store.burnPad,
|
||||
GET_PAD_METADATA: Store.getPadMetadata,
|
||||
SET_PAD_METADATA: Store.setPadMetadata,
|
||||
CHANGE_PAD_PASSWORD_PIN: Store.changePadPasswordPin,
|
||||
|
|
|
@ -119,6 +119,7 @@ define([
|
|||
// If it's not a shared folder, check the pads
|
||||
if (!data) { data = Env.user.userObject.getFileData(id, editable); }
|
||||
ret.push({
|
||||
id: id,
|
||||
data: data,
|
||||
userObject: Env.user.userObject
|
||||
});
|
||||
|
@ -126,6 +127,7 @@ define([
|
|||
Object.keys(Env.folders).forEach(function (fId) {
|
||||
Env.folders[fId].userObject.findChannels([channel]).forEach(function (id) {
|
||||
ret.push({
|
||||
id: id,
|
||||
fId: fId,
|
||||
data: Env.folders[fId].userObject.getFileData(id, editable),
|
||||
userObject: Env.folders[fId].userObject
|
||||
|
@ -1095,9 +1097,11 @@ define([
|
|||
// Store
|
||||
getChannelsList: callWithEnv(getChannelsList),
|
||||
addPad: callWithEnv(addPad),
|
||||
delete: callWithEnv(_delete),
|
||||
// Tools
|
||||
findChannel: callWithEnv(findChannel),
|
||||
findHref: callWithEnv(findHref),
|
||||
findFile: callWithEnv(findFile),
|
||||
getEditHash: callWithEnv(getEditHash),
|
||||
user: Env.user,
|
||||
folders: Env.folders
|
||||
|
|
|
@ -81,8 +81,8 @@ define([
|
|||
});
|
||||
localStorage.CRYPTPAD_URLARGS = ApiConfig.requireConf.urlArgs;
|
||||
}
|
||||
var cache = {};
|
||||
var localStore = {};
|
||||
var cache = window.cpCache = {};
|
||||
var localStore = window.localStore = {};
|
||||
Object.keys(localStorage).forEach(function (k) {
|
||||
if (k.indexOf('CRYPTPAD_CACHE|') === 0) {
|
||||
cache[k.slice(('CRYPTPAD_CACHE|').length)] = localStorage[k];
|
||||
|
@ -323,6 +323,7 @@ define([
|
|||
}
|
||||
Utils.crypto = Utils.Crypto.createEncryptor(Utils.secret.keys);
|
||||
var parsed = Utils.Hash.parsePadUrl(window.location.href);
|
||||
var burnAfterReading = parsed && parsed.hashData && parsed.hashData.ownerKey;
|
||||
if (!parsed.type) { throw new Error(); }
|
||||
var defaultTitle = Utils.UserObject.getDefaultName(parsed);
|
||||
var edPublic, curvePublic, notifications, isTemplate;
|
||||
|
@ -376,6 +377,7 @@ define([
|
|||
fromFileData: Cryptpad.fromFileData ? {
|
||||
title: Cryptpad.fromFileData.title
|
||||
} : undefined,
|
||||
burnAfterReading: burnAfterReading,
|
||||
storeInTeam: Cryptpad.initialTeam || (Cryptpad.initialPath ? -1 : undefined)
|
||||
};
|
||||
if (window.CryptPad_newSharedFolder) {
|
||||
|
@ -507,6 +509,17 @@ define([
|
|||
}
|
||||
});
|
||||
|
||||
sframeChan.on('Q_GET_PAD_METADATA', function (data, cb) {
|
||||
if (!data || !data.channel) {
|
||||
data = {
|
||||
channel: secret.channel
|
||||
};
|
||||
}
|
||||
Cryptpad.getPadMetadata(data, cb);
|
||||
});
|
||||
sframeChan.on('Q_SET_PAD_METADATA', function (data, cb) {
|
||||
Cryptpad.setPadMetadata(data, cb);
|
||||
});
|
||||
};
|
||||
addCommonRpc(sframeChan);
|
||||
|
||||
|
@ -1170,18 +1183,6 @@ define([
|
|||
});
|
||||
});
|
||||
|
||||
sframeChan.on('Q_GET_PAD_METADATA', function (data, cb) {
|
||||
if (!data || !data.channel) {
|
||||
data = {
|
||||
channel: secret.channel
|
||||
};
|
||||
}
|
||||
Cryptpad.getPadMetadata(data, cb);
|
||||
});
|
||||
sframeChan.on('Q_SET_PAD_METADATA', function (data, cb) {
|
||||
Cryptpad.setPadMetadata(data, cb);
|
||||
});
|
||||
|
||||
if (cfg.messaging) {
|
||||
Notifier.getPermission();
|
||||
|
||||
|
@ -1236,6 +1237,16 @@ define([
|
|||
window.location.hash = hash;
|
||||
};
|
||||
|
||||
if (burnAfterReading) {
|
||||
Cryptpad.padRpc.onReadyEvent.reg(function () {
|
||||
Cryptpad.burnPad({
|
||||
password: password,
|
||||
href: window.location.href,
|
||||
channel: secret.channel,
|
||||
ownerKey: burnAfterReading
|
||||
});
|
||||
});
|
||||
}
|
||||
var cpNfCfg = {
|
||||
sframeChan: sframeChan,
|
||||
channel: secret.channel,
|
||||
|
@ -1359,12 +1370,17 @@ define([
|
|||
});
|
||||
});
|
||||
|
||||
sframeChan.on('EV_BURN_AFTER_READING', function () {
|
||||
startRealtime();
|
||||
});
|
||||
|
||||
sframeChan.ready();
|
||||
|
||||
Utils.Feedback.reportAppUsage();
|
||||
|
||||
if (!realtime && !Test.testing) { return; }
|
||||
if (isNewFile && cfg.useCreationScreen && !Test.testing) { return; }
|
||||
if (burnAfterReading) { return; }
|
||||
//if (isNewFile && Utils.LocalStore.isLoggedIn()
|
||||
// && AppConfig.displayCreationScreen && cfg.useCreationScreen) { return; }
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ define([
|
|||
funcs.createMarkdownToolbar = callWithCommon(UIElements.createMarkdownToolbar);
|
||||
funcs.createHelpMenu = callWithCommon(UIElements.createHelpMenu);
|
||||
funcs.getPadCreationScreen = callWithCommon(UIElements.getPadCreationScreen);
|
||||
funcs.getBurnAfterReadingWarning = callWithCommon(UIElements.getBurnAfterReadingWarning);
|
||||
funcs.createNewPadModal = callWithCommon(UIElements.createNewPadModal);
|
||||
funcs.onServerError = callWithCommon(UIElements.onServerError);
|
||||
funcs.importMediaTagMenu = callWithCommon(UIElements.importMediaTagMenu);
|
||||
|
@ -300,6 +301,13 @@ define([
|
|||
}
|
||||
// If we display the pad creation screen, it will handle deleted pads directly
|
||||
funcs.getPadCreationScreen(c, config, waitFor());
|
||||
return;
|
||||
}
|
||||
if (priv.burnAfterReading) {
|
||||
UIElements.displayBurnAfterReadingPage(funcs, waitFor(function () {
|
||||
UI.addLoadingScreen();
|
||||
ctx.sframeChan.event('EV_BURN_AFTER_READING');
|
||||
}));
|
||||
}
|
||||
};
|
||||
funcs.createPad = function (cfg, cb) {
|
||||
|
|
|
@ -58,7 +58,7 @@ define([
|
|||
// Remove the listener once we've received the READY message
|
||||
window.removeEventListener('message', whenReady);
|
||||
// Answer with the requested data
|
||||
postMsg(JSON.stringify({ txid: data.txid, language: Cryptpad.getLanguage() }));
|
||||
postMsg(JSON.stringify({ txid: data.txid, language: Cryptpad.getLanguage(), localStore: window.localStore, cache: window.cpCache }));
|
||||
|
||||
// Then start the channel
|
||||
window.addEventListener('message', function (msg) {
|
||||
|
|
|
@ -350,6 +350,8 @@ define([
|
|||
|
||||
var mkHelpMenu = function (framework) {
|
||||
var $toolbarContainer = $('#cp-app-kanban-container');
|
||||
$toolbarContainer.prepend(framework._.sfCommon.getBurnAfterReadingWarning());
|
||||
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['kanban']);
|
||||
$toolbarContainer.prepend(helpMenu.menu);
|
||||
|
||||
|
|
|
@ -190,6 +190,7 @@ define([
|
|||
|
||||
var mkHelpMenu = function (framework) {
|
||||
var $toolbarContainer = $('.cke_toolbox_main');
|
||||
$toolbarContainer.before(framework._.sfCommon.getBurnAfterReadingWarning());
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['text', 'pad']);
|
||||
$toolbarContainer.before(helpMenu.menu);
|
||||
|
||||
|
|
|
@ -1187,6 +1187,7 @@ define([
|
|||
$drawer.append($export);
|
||||
|
||||
var helpMenu = common.createHelpMenu(['poll']);
|
||||
$('#cp-app-poll-form').prepend(common.getBurnAfterReadingWarning());
|
||||
$('#cp-app-poll-form').prepend(helpMenu.menu);
|
||||
$drawer.append(helpMenu.button);
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ define([
|
|||
// Remove the listener once we've received the READY message
|
||||
window.removeEventListener('message', whenReady);
|
||||
// Answer with the requested data
|
||||
postMsg(JSON.stringify({ txid: data.txid, language: Cryptpad.getLanguage() }));
|
||||
postMsg(JSON.stringify({ txid: data.txid, language: Cryptpad.getLanguage(), localStore: window.localStore, cache: window.cpCache }));
|
||||
|
||||
// Then start the channel
|
||||
window.addEventListener('message', function (msg) {
|
||||
|
@ -105,6 +105,21 @@ define([
|
|||
|
||||
config.addCommonRpc(sframeChan);
|
||||
|
||||
sframeChan.on('EV_CACHE_PUT', function (x) {
|
||||
Object.keys(x).forEach(function (k) {
|
||||
localStorage['CRYPTPAD_CACHE|' + k] = x[k];
|
||||
});
|
||||
});
|
||||
sframeChan.on('EV_LOCALSTORE_PUT', function (x) {
|
||||
Object.keys(x).forEach(function (k) {
|
||||
if (typeof(x[k]) === "undefined") {
|
||||
delete localStorage['CRYPTPAD_STORE|' + k];
|
||||
return;
|
||||
}
|
||||
localStorage['CRYPTPAD_STORE|' + k] = x[k];
|
||||
});
|
||||
});
|
||||
|
||||
sframeChan.on('Q_GET_FILES_LIST', function (types, cb) {
|
||||
Cryptpad.getSecureFilesList(types, function (err, data) {
|
||||
cb({
|
||||
|
|
|
@ -410,6 +410,7 @@ define([
|
|||
|
||||
var mkHelpMenu = function (framework) {
|
||||
var $codeMirrorContainer = $('#cp-app-slide-editor-container');
|
||||
$codeMirrorContainer.prepend(framework._.sfCommon.getBurnAfterReadingWarning());
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['text', 'slide']);
|
||||
$codeMirrorContainer.prepend(helpMenu.menu);
|
||||
|
||||
|
|
|
@ -270,6 +270,7 @@ define([
|
|||
|
||||
var mkHelpMenu = function (framework) {
|
||||
var $appContainer = $('#cp-app-whiteboard-container');
|
||||
$appContainer.prepend(framework._.sfCommon.getBurnAfterReadingWarning());
|
||||
var helpMenu = framework._.sfCommon.createHelpMenu(['whiteboard']);
|
||||
$appContainer.prepend(helpMenu.menu);
|
||||
framework._.toolbar.$drawer.append(helpMenu.button);
|
||||
|
|
Loading…
Reference in New Issue