You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cryptpad/www/common/inner/share.js

854 lines
33 KiB
JavaScript

define([
'jquery',
'/common/common-util.js',
'/common/common-hash.js',
'/common/common-interface.js',
'/common/common-ui-elements.js',
'/common/inner/common-modal.js',
'/common/hyperscript.js',
'/common/clipboard.js',
'/customize/messages.js',
'/bower_components/nthen/index.js',
], function ($, Util, Hash, UI, UIElements, Modal, h, Clipboard,
Messages, nThen) {
var Share = {};
var createShareWithFriends = function (config, onShare, linkGetter) {
var common = config.common;
var sframeChan = common.getSframeChannel();
var title = config.title;
var friends = config.friends || {};
var teams = config.teams || {};
var myName = common.getMetadataMgr().getUserData().name;
var order = [];
var smallCurves = Object.keys(friends).map(function (c) {
return friends[c].curvePublic.slice(0,8);
});
var div = h('div.contains-nav');
var $div = $(div);
// Replace "copy link" by "share with friends" if at least one friend is selected
// Also create the "share with friends" button if it doesn't exist
var refreshButtons = function () {
var $nav = $div.closest('.alertify').find('nav');
var friendMode = $div.find('.cp-usergrid-user.cp-selected').length;
if (friendMode) {
$nav.find('button.cp-share-with-friends').prop('disabled', '');
} else {
$nav.find('button.cp-share-with-friends').prop('disabled', 'disabled');
}
};
config.noInclude = true;
Object.keys(friends).forEach(function (curve) {
var data = friends[curve];
if (curve.length > 40 && data.notifications) { return; }
delete friends[curve];
});
var others = [];
if (Object.keys(friends).length) {
var friendsList = UIElements.getUserGrid(Messages.share_linkFriends, {
common: common,
data: friends,
noFilter: false,
large: true
}, refreshButtons);
var friendDiv = friendsList.div;
$div.append(friendDiv);
others = friendsList.icons;
}
if (Object.keys(teams).length) {
var teamsList = UIElements.getUserGrid(Messages.share_linkTeam, {
common: common,
noFilter: true,
large: true,
data: teams
}, refreshButtons);
$div.append(teamsList.div);
}
var shareButton = {
className: 'primary cp-share-with-friends',
name: Messages.share_withFriends,
onClick: function () {
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;
}
href = url;
setTimeout(w);
});
if (res && /^http/.test(res)) {
href = Hash.getRelativeHref(res);
setTimeout(w);
return;
}
}).nThen(function () {
var $friends = $div.find('.cp-usergrid-user.cp-selected');
$friends.each(function (i, el) {
var curve = $(el).attr('data-curve');
var ed = $(el).attr('data-ed');
var friend = curve && friends[curve];
var team = teams[ed];
// If the selected element is a friend or a team without edit right,
// send a notification
var mailbox = friend || ((team && team.viewer) ? team : undefined);
if (mailbox) { // Friend
if (friends[curve] && !mailbox.notifications) { return; }
if (mailbox.notifications && mailbox.curvePublic) {
common.mailbox.sendTo("SHARE_PAD", {
href: href,
password: config.password,
isTemplate: config.isTemplate,
name: myName,
title: title
}, {
viewed: team && team.id,
channel: mailbox.notifications,
curvePublic: mailbox.curvePublic
});
return;
}
}
// If it's a team with edit right, add the pad directly
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();
// 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();
}
});
},
keys: [13]
};
common.getAttribute(['general', 'share-friends'], function (err, val) {
order = val || [];
// Sort friends by "recently shared with"
others.sort(function (a, b) {
var ca = ($(a).attr('data-curve') || '').slice(0,8);
var cb = ($(b).attr('data-curve') || '').slice(0,8);
if (!ca && !cb) { return 0; }
if (!ca) { return 1; }
if (!cb) { return -1; }
var ia = order.indexOf(ca);
var ib = order.indexOf(cb);
if (ia === -1 && ib === -1) { return 0; }
if (ia === -1) { return 1; }
if (ib === -1) { return -1; }
return ia - ib;
});
// Reorder the friend icons
others.forEach(function (el, i) {
$(el).attr('data-order', i).css('order', i);
});
// Display them
$(friendDiv).find('.cp-usergrid-grid').detach();
$(friendDiv).append(h('div.cp-usergrid-grid', others));
refreshButtons();
});
return {
content: div,
buttons: [shareButton]
};
};
var getEditableTeams = function (common, config) {
var privateData = common.getMetadataMgr().getPrivateData();
var teamsData = Util.tryParse(JSON.stringify(privateData.teams)) || {};
var teams = {};
Object.keys(teamsData).forEach(function (id) {
// config.teamId only exists when we're trying to share a pad from a team drive
// In this case, we don't want to share the pad with the current team
if (config.teamId && config.teamId === id) { return; }
var t = teamsData[id];
teams[t.edPublic] = {
viewer: !teamsData[id].hasSecondaryKey,
notifications: t.notifications,
curvePublic: t.curvePublic,
displayName: t.name,
edPublic: t.edPublic,
avatar: t.avatar,
id: id
};
});
return teams;
};
var makeBurnAfterReadingUrl = function (common, href, channel, cb) {
var keyPair = Hash.generateSignPair();
var parsed = Hash.parsePadUrl(href);
var newHref = parsed.getUrl({
ownerKey: keyPair.safeSignKey
});
var sframeChan = common.getSframeChannel();
var rtChannel;
nThen(function (waitFor) {
if (parsed.type !== "sheet") { return; }
common.getPadAttribute('rtChannel', waitFor(function (err, chan) {
rtChannel = chan;
}));
}).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);
}
}));
if (rtChannel) {
sframeChan.query('Q_SET_PAD_METADATA', {
channel: rtChannel,
command: 'ADD_OWNERS',
value: [keyPair.validateKey]
}, waitFor(function (err) {
if (err) { console.error(err); }
}));
}
}).nThen(function () {
cb(newHref);
});
};
var makeFaqLink = function (opts) {
var link = h('span', [
h('i.fa.fa-question-circle'),
h('a', {href: '#'}, Messages.passwordFaqLink)
]);
$(link).click(function () {
4 years ago
opts.common.openURL(opts.origin + "/faq.html#security-pad_password");
});
return link;
};
var makeCancelButton = function() {
return {
className: 'cancel',
name: Messages.cancel,
onClick: function () {},
keys: [27]
};
};
var getContactsTab = function (Env, data, opts, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var common = Env.common;
var hasFriends = opts.hasFriends;
var onFriendShare = Util.mkEvent();
4 years ago
var friendsObject = hasFriends ? createShareWithFriends(opts, onFriendShare, opts.getLinkValue) : UIElements.noContactsMessage(common);
var friendsList = friendsObject.content;
onFriendShare.reg(opts.saveValue);
var contactsContent = h('div.cp-share-modal');
var $contactsContent = $(contactsContent);
$contactsContent.append(friendsList);
// Show alert if the pad is password protected
if (opts.hasPassword) {
$contactsContent.append(h('div.alert.alert-primary', [
h('i.fa.fa-unlock'),
Messages.share_contactPasswordAlert, h('br'),
makeFaqLink(opts)
]));
}
// Burn after reading warning
if (opts.barAlert) { $contactsContent.append(opts.barAlert.cloneNode(true)); }
var contactButtons = friendsObject.buttons;
contactButtons.unshift(makeCancelButton());
cb(void 0, {
content: contactsContent,
buttons: contactButtons
});
};
var getLinkTab = function (Env, data, opts, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var common = Env.common;
var origin = opts.origin;
var pathname = opts.pathname;
var hashes = opts.hashes;
// Create modal
var linkContent = opts.sharedFolder ? [
h('label', Messages.sharedFolders_share),
h('br'),
] : [
UI.createCheckbox('cp-share-embed', Messages.share_linkEmbed, false, { mark: {tabindex:1} }),
];
linkContent.push(h('div.cp-spacer'));
linkContent.push(UI.dialog.selectableArea('', { id: 'cp-share-link-preview', tabindex: 1, rows:3}));
// Show alert if the pad is password protected
if (opts.hasPassword) {
linkContent.push(h('div.alert.alert-primary', [
h('i.fa.fa-lock'),
Messages.share_linkPasswordAlert, h('br'),
makeFaqLink(opts)
]));
}
// warning about sharing links
var localStore = window.cryptpadStore;
var dismissButton = h('span.fa.fa-times');
var shareLinkWarning = h('div.alert.alert-warning.dismissable',
{ style: 'display: none;' },
[
h('span.cp-inline-alert-text', Messages.share_linkWarning),
dismissButton
]);
linkContent.push(shareLinkWarning);
localStore.get('hide-alert-shareLinkWarning', function (val) {
if (val === '1') { return; }
$(shareLinkWarning).css('display', 'flex');
$(dismissButton).on('click', function () {
localStore.put('hide-alert-shareLinkWarning', '1');
$(shareLinkWarning).remove();
});
});
// Burn after reading
if (opts.barAlert) { linkContent.push(opts.barAlert.cloneNode(true)); }
var link = h('div.cp-share-modal', linkContent);
var $link = $(link);
$link.find('#cp-share-link-preview').val(opts.getLinkValue());
$link.find('input[type="checkbox"]').on('change', function () {
$link.find('#cp-share-link-preview').val(opts.getLinkValue({
embed: Util.isChecked($link.find('#cp-share-embed'))
}));
});
Messages.share_bar = "Generate link"; // XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX
var linkButtons = [
makeCancelButton(),
!opts.sharedFolder && {
className: 'secondary cp-nobar',
name: Messages.share_linkOpen,
onClick: function () {
opts.saveValue();
var v = opts.getLinkValue({
embed: Util.isChecked($link.find('#cp-share-embed'))
});
window.open(v);
return true;
},
keys: [[13, 'ctrl']]
}, {
className: 'primary cp-nobar',
name: Messages.share_linkCopy,
onClick: function () {
opts.saveValue();
var v = opts.getLinkValue({
embed: Util.isChecked($link.find('#cp-share-embed'))
});
var success = Clipboard.copy(v);
if (success) { UI.log(Messages.shareSuccess); }
},
keys: [13]
}, {
className: 'primary cp-bar',
name: Messages.share_bar,
onClick: function () {
var barHref = origin + pathname + '#' + (hashes.viewHash || hashes.editHash);
makeBurnAfterReadingUrl(common, barHref, opts.channel, function (url) {
opts.burnAfterReadingUrl = url;
opts.$rights.find('input[type="radio"]').trigger('change');
});
return true;
},
keys: []
}
];
$link.find('.cp-bar').hide();
cb(void 0, {
content: link,
buttons: linkButtons
});
};
var getEmbedTab = function (Env, data, opts, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var embedContent = [
h('p', Messages.viewEmbedTag),
UI.dialog.selectableArea(opts.getEmbedValue(), { id: 'cp-embed-link-preview', tabindex: 1, rows: 3})
];
// Show alert if the pad is password protected
if (opts.hasPassword) {
embedContent.push(h('div.alert.alert-primary', [
h('i.fa.fa-lock'), ' ',
Messages.share_embedPasswordAlert, h('br'),
makeFaqLink(opts)
]));
}
var embedButtons = [
makeCancelButton(),
{
className: 'primary',
name: Messages.share_linkCopy,
onClick: function () {
var v = opts.getEmbedValue();
var success = Clipboard.copy(v);
if (success) { UI.log(Messages.shareSuccess); }
},
keys: [13]
}];
var embed = h('div.cp-share-modal', embedContent);
var $embed = $(embed);
$embed.find('#cp-embed-link-preview').val(opts.getEmbedValue());
cb(void 0, {
content: embed,
buttons: embedButtons
});
};
var getRightsHeader = function (common, opts) {
var hashes = opts.hashes;
var hash = hashes.editHash || hashes.viewHash;
var origin = opts.origin;
var pathname = opts.pathname;
var parsed = Hash.parsePadUrl(pathname);
var canPresent = ['code', 'slide'].indexOf(parsed.type) !== -1;
var canBAR = parsed.type !== 'drive';
var burnAfterReading = (hashes.viewHash && canBAR) ?
UI.createRadio('accessRights', 'cp-share-bar', Messages.burnAfterReading_linkBurnAfterReading, false, {
mark: {tabindex:1},
label: {style: "display: none;"}
}) : undefined;
var rights = h('div.msg.cp-inline-radio-group', [
h('label', Messages.share_linkAccess),
h('div.radio-group',[
UI.createRadio('accessRights', 'cp-share-editable-false',
Messages.share_linkView, true, { mark: {tabindex:1} }),
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} })]),
burnAfterReading
]);
// 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
opts.barAlert = h('div.alert.alert-danger.cp-alertify-bar-selected', {
style: 'display: none;'
}, Messages.burnAfterReading_warningLink);
var channel = opts.channel = Hash.getSecrets('pad', hash, opts.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).css({
display: 'flex'
});
});
var $rights = $(rights);
opts.saveValue = function () {
var edit = Util.isChecked($rights.find('#cp-share-editable-true'));
var present = Util.isChecked($rights.find('#cp-share-present'));
common.setAttribute(['general', 'share'], {
edit: edit,
present: present
});
};
opts.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 && !opts.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;
}
var hash = (!hashes.viewHash || (edit && hashes.editHash)) ? hashes.editHash
: hashes.viewHash;
var href = burnAfterReading ? opts.burnAfterReadingUrl
: (origin + pathname + '#' + hash);
var parsed = Hash.parsePadUrl(href);
return origin + parsed.getUrl({embed: embed, present: present});
};
opts.getEmbedValue = function () {
var url = opts.getLinkValue({
embed: true
});
return '<iframe src="' + url + '"></iframe>';
};
// disable edit share options if you don't have edit rights
if (!hashes.editHash) {
$rights.find('#cp-share-editable-false').attr('checked', true);
$rights.find('#cp-share-editable-true').removeAttr('checked').attr('disabled', true);
} else if (!hashes.viewHash) {
$rights.find('#cp-share-editable-false').removeAttr('checked').attr('disabled', true);
$rights.find('#cp-share-present').removeAttr('checked').attr('disabled', true);
$rights.find('#cp-share-editable-true').attr('checked', true);
}
var getLink = function () {
return $rights.parent().find('#cp-share-link-preview');
};
var getEmbed = function () {
return $rights.parent().find('#cp-embed-link-preview');
};
// update values for link and embed preview when radio btns change
$rights.find('input[type="radio"]').on('change', function () {
getLink().val(opts.getLinkValue({
embed: Util.isChecked($('.alertify').find('#cp-share-embed'))
}));
// Hide or show the burn after reading alert
if (Util.isChecked($rights.find('#cp-share-bar')) && !opts.burnAfterReadingUrl) {
$('.cp-alertify-bar-selected').show();
// Show burn after reading button
$('.alertify').find('.cp-bar').show();
$('.alertify').find('.cp-nobar').hide();
return;
}
getEmbed().val(opts.getEmbedValue());
// Hide burn after reading button
$('.alertify').find('.cp-nobar').show();
$('.alertify').find('.cp-bar').hide();
$('.cp-alertify-bar-selected').hide();
});
// Set default values
common.getAttribute(['general', 'share'], function (err, val) {
val = val || {};
if (val.present && canPresent) {
$rights.find('#cp-share-editable-false').prop('checked', false);
$rights.find('#cp-share-editable-true').prop('checked', false);
$rights.find('#cp-share-present').prop('checked', true);
} else if ((val.edit === false && hashes.viewHash) || !hashes.editHash) {
$rights.find('#cp-share-editable-false').prop('checked', true);
$rights.find('#cp-share-editable-true').prop('checked', false);
$rights.find('#cp-share-present').prop('checked', false);
} else {
$rights.find('#cp-share-editable-true').prop('checked', true);
$rights.find('#cp-share-editable-false').prop('checked', false);
$rights.find('#cp-share-present').prop('checked', false);
}
delete val.embed;
if (!canPresent) {
delete val.present;
}
getLink().val(opts.getLinkValue(val));
});
common.getMetadataMgr().onChange(function () {
// "hashes" is only available is the secure "share" app
var _hashes = common.getMetadataMgr().getPrivateData().hashes;
if (!_hashes) { return; }
hashes = _hashes;
getLink().val(opts.getLinkValue());
});
return $rights;
};
// In the share modal, tabs need to share data between themselves.
// To do so we're using "opts" to store data and functions
Share.getShareModal = function (common, opts, cb) {
cb = cb || function () {};
opts = opts || {};
opts.access = true; // Allow the use of the modal even if the pad is not stored
var hashes = opts.hashes;
if (!hashes || (!hashes.editHash && !hashes.viewHash)) { return; }
var teams = getEditableTeams(common, opts);
opts.teams = teams;
var hasFriends = opts.hasFriends = Object.keys(opts.friends || {}).length ||
Object.keys(teams).length;
// check if the pad is password protected
var pathname = opts.pathname;
var hash = hashes.editHash || hashes.viewHash;
var href = pathname + '#' + hash;
var parsedHref = Hash.parsePadUrl(href);
opts.hasPassword = parsedHref.hashData.password;
var $rights = opts.$rights = getRightsHeader(common, opts);
var resetTab = function () {
$rights.show();
$rights.find('label.cp-radio').show();
};
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 onShowContacts = function () {
if (!hasFriends) {
$rights.hide();
}
};
var tabs = [{
getTab: getContactsTab,
title: Messages.share_contactCategory,
icon: "fa fa-addess-book",
active: hasFriends,
onShow: onShowContacts,
onHide: resetTab
}, {
getTab: getLinkTab,
title: Messages.share_linkCategory,
icon: "fa fa-link",
active: !hasFriends,
}, {
getTab: getEmbedTab,
title: Messages.share_embedCategory,
icon: "fa fa-code",
onShow: onShowEmbed,
onHide: resetTab
}];
Modal.getModal(common, opts, tabs, function (err, modal) {
$(modal).find('.cp-bar').hide();
// Prepend the "rights" radio selection
$(modal).find('.alertify-tabs-titles').after($rights);
// callback
cb(err, modal);
});
};
var getFileContactsTab = function (Env, data, opts, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var common = Env.common;
4 years ago
var friendsObject = opts.hasFriends ? createShareWithFriends(opts, null, opts.getLinkValue) : UIElements.noContactsMessage(common);
var friendsList = friendsObject.content;
var contactsContent = h('div.cp-share-modal');
var $contactsContent = $(contactsContent);
$contactsContent.append(friendsList);
// Show alert if the pad is password protected
if (opts.hasPassword) {
4 years ago
$contactsContent.append(h('div.alert.alert-primary', [
h('i.fa.fa-lock'),
Messages.share_linkPasswordAlert, h('br'),
makeFaqLink(opts)
]));
}
var contactButtons = friendsObject.buttons;
contactButtons.unshift(makeCancelButton());
cb(void 0, {
content: contactsContent,
buttons: contactButtons
});
};
var getFileLinkTab = function (Env, data, opts, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var linkContent = [
UI.dialog.selectableArea(opts.getLinkValue(), {
id: 'cp-share-link-preview', tabindex: 1, rows:2
})
];
// Show alert if the pad is password protected
if (opts.hasPassword) {
linkContent.push(h('div.alert.alert-primary', [
h('i.fa.fa-lock'),
Messages.share_linkPasswordAlert, h('br'),
makeFaqLink(opts)
]));
}
// warning about sharing links
var localStore = window.cryptpadStore;
var dismissButton = h('span.fa.fa-times');
var shareLinkWarning = h('div.alert.alert-warning.dismissable',
{ style: 'display: none;' },
[
h('span.cp-inline-alert-text', Messages.share_linkWarning),
dismissButton
]);
linkContent.push(shareLinkWarning);
localStore.get('hide-alert-shareLinkWarning', function (val) {
if (val === '1') { return; }
$(shareLinkWarning).css('display', 'flex');
$(dismissButton).on('click', function () {
localStore.put('hide-alert-shareLinkWarning', '1');
$(shareLinkWarning).remove();
});
});
var link = h('div.cp-share-modal', linkContent);
var linkButtons = [
makeCancelButton(),
{
className: 'primary',
name: Messages.share_linkCopy,
onClick: function () {
var v = opts.getLinkValue();
var success = Clipboard.copy(v);
if (success) { UI.log(Messages.shareSuccess);
}
},
keys: [13]
}
];
cb(void 0, {
content: link,
buttons: linkButtons
});
};
var getFileEmbedTab = function (Env, data, opts, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
var common = Env.common;
var fileData = opts.fileData;
var embed = h('div.cp-share-modal', [
h('p', Messages.fileEmbedScript),
UI.dialog.selectable(common.getMediatagScript()),
h('p', Messages.fileEmbedTag),
UI.dialog.selectable(common.getMediatagFromHref(fileData)),
]);
// Show alert if the pad is password protected
if (opts.hasPassword) {
4 years ago
$(embed).append(h('div.alert.alert-primary', [
h('i.fa.fa-lock'),
Messages.share_linkPasswordAlert, h('br'),
makeFaqLink(opts)
]));
}
var embedButtons = [{
className: 'cancel',
name: Messages.cancel,
onClick: function () {},
keys: [27]
}, {
className: 'primary',
name: Messages.share_mediatagCopy,
onClick: function () {
var v = common.getMediatagFromHref(opts.fileData);
var success = Clipboard.copy(v);
if (success) { UI.log(Messages.shareSuccess); }
},
keys: [13]
}];
cb(void 0, {
content: embed,
buttons: embedButtons
});
};
Share.getFileShareModal = function (common, opts, cb) {
cb = cb || function () {};
opts = opts || {};
opts.access = true; // Allow the use of the modal even if the pad is not stored
var hashes = opts.hashes;
if (!hashes || !hashes.fileHash) { return; }
var teams = getEditableTeams(common, opts);
opts.teams = teams;
var hasFriends = opts.hasFriends = Object.keys(opts.friends || {}).length ||
Object.keys(teams).length;
// check if the pad is password protected
var origin = opts.origin;
var pathname = opts.pathname;
var url = opts.url = origin + pathname + '#' + hashes.fileHash;
var parsedHref = Hash.parsePadUrl(url);
opts.hasPassword = parsedHref.hashData.password;
opts.getLinkValue = function () { return url; };
var tabs = [{
getTab: getFileContactsTab,
title: Messages.share_contactCategory,
icon: "fa fa-addess-book",
active: hasFriends,
}, {
getTab: getFileLinkTab,
title: Messages.share_linkCategory,
icon: "fa fa-link",
active: !hasFriends,
}, {
getTab: getFileEmbedTab,
title: Messages.share_embedCategory,
icon: "fa fa-code",
}];
Modal.getModal(common, opts, tabs, cb);
};
return Share;
});