From a1e3098322f3747181466632f11764ee6a8232a0 Mon Sep 17 00:00:00 2001 From: Daniel Calviño Sánchez Date: Mon, 22 Oct 2018 11:06:53 +0200 Subject: Add "Hide download" to the menu of link shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hiding the download does not depend on other settings and it does not affect other settings either (for example, it would be possible to hide the downloads yet make the share editable), so a simple checkbox was added to the menu. However, note that this option is only available for files, but not for folders. Signed-off-by: Daniel Calviño Sánchez --- core/js/shareitemmodel.js | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'core/js/shareitemmodel.js') diff --git a/core/js/shareitemmodel.js b/core/js/shareitemmodel.js index f4a3caf1370..3f92a8591e5 100644 --- a/core/js/shareitemmodel.js +++ b/core/js/shareitemmodel.js @@ -18,6 +18,7 @@ * @typedef {object} OC.Share.Types.LinkShareInfo * @property {bool} isLinkShare * @property {string} token + * @property {bool} hideDownload * @property {string|null} password * @property {string} link * @property {number} permissions @@ -136,6 +137,7 @@ call = this.updateShare(shareId, attributes, options); } else { attributes = _.defaults(attributes, { + hideDownload: false, password: '', passwordChanged: false, permissions: OC.PERMISSION_READ, @@ -866,6 +868,9 @@ isLinkShare: true, id: share.id, token: share.token, + // hide_download is returned as an int, so force it + // to a boolean + hideDownload: !!share.hide_download, password: share.share_with, link: link, permissions: share.permissions, -- cgit v1.2.3 From 2c990ade77f73ce4cde7ecd7cb4ef116e1b8cd8d Mon Sep 17 00:00:00 2001 From: Julius Härtl Date: Wed, 31 Oct 2018 11:23:23 +0100 Subject: Do not set indeterminate state for file shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- core/js/sharedialogshareelistview.js | 4 +++- core/js/shareitemmodel.js | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'core/js/shareitemmodel.js') diff --git a/core/js/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js index 93373a54435..94abf55a358 100644 --- a/core/js/sharedialogshareelistview.js +++ b/core/js/sharedialogshareelistview.js @@ -314,7 +314,9 @@ var $edit = _this.$('#canEdit-' + _this.cid + '-' + sharee.shareId); if($edit.length === 1) { $edit.prop('checked', sharee.editPermissionState === 'checked'); - $edit.prop('indeterminate', sharee.editPermissionState === 'indeterminate'); + if (sharee.isFolder) { + $edit.prop('indeterminate', sharee.editPermissionState === 'indeterminate'); + } } }); this.$('.popovermenu').on('afterHide', function() { diff --git a/core/js/shareitemmodel.js b/core/js/shareitemmodel.js index 3f92a8591e5..84715ec87c1 100644 --- a/core/js/shareitemmodel.js +++ b/core/js/shareitemmodel.js @@ -616,6 +616,12 @@ var hcp = this.hasCreatePermission(shareIndex); var hup = this.hasUpdatePermission(shareIndex); var hdp = this.hasDeletePermission(shareIndex); + if (this.isFile()) { + if (hcp || hup || hdp) { + return 'checked'; + } + return ''; + } if (!hcp && !hup && !hdp) { return ''; } -- cgit v1.2.3 From 1bd6d39b39dd527ad095510173e9012afaafd3b0 Mon Sep 17 00:00:00 2001 From: "John Molakvoæ (skjnldsv)" Date: Mon, 29 Oct 2018 13:58:14 +0100 Subject: Migrate link shares to array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files_sharing/css/sharetabview.scss | 36 +- apps/files_sharing/js/share.js | 14 +- core/js/share/sharedialoglinkshareview.handlebars | 27 +- ...haredialoglinkshareview_popover_menu.handlebars | 17 +- core/js/share/sharedialogshareelistview.handlebars | 2 +- core/js/sharedialoglinkshareview.js | 421 ++++++++++++++------- core/js/shareitemmodel.js | 59 ++- core/js/sharetemplates.js | 57 +-- 8 files changed, 390 insertions(+), 243 deletions(-) (limited to 'core/js/shareitemmodel.js') diff --git a/apps/files_sharing/css/sharetabview.scss b/apps/files_sharing/css/sharetabview.scss index 0d277c58bd7..9611580baad 100644 --- a/apps/files_sharing/css/sharetabview.scss +++ b/apps/files_sharing/css/sharetabview.scss @@ -194,31 +194,29 @@ display: flex; align-items: center; white-space: nowrap; - // can edit label - > .shareOption > label { - padding: 13px; - padding-right: 0; - } - // more menu - > .share-menu { - position: relative; + + // icons + > .icon:not(.hidden), + .share-menu > .icon:not(.hidden) { + padding: 14px; + height: 44px; + width: 44px; + opacity: .5; display: block; - .icon-more { - padding: 14px; - height: 44px; - width: 44px; - opacity: .5; - display: block; - cursor: pointer; - } + cursor: pointer; + &:hover, &:focus, &:active { - .icon-more { - opacity: .7;; - } + opacity: .7;; } } + + // more menu + > .share-menu { + position: relative; + display: block; + } } .username { padding: 0 8px; diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 68529fd882f..b02c6e3d9ee 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -193,15 +193,15 @@ var $tr = fileList.findFileEl(fileInfoModel.get('name')); // We count email shares as link share - var hasLinkShare = shareModel.hasLinkShare(); + var hasLinkShares = shareModel.hasLinkShares(); shareModel.get('shares').forEach(function (share) { if (share.share_type === OC.Share.SHARE_TYPE_EMAIL) { - hasLinkShare = true; + hasLinkShares = true; } }); OCA.Sharing.Util._updateFileListDataAttributes(fileList, $tr, shareModel); - if (!OCA.Sharing.Util._updateFileActionIcon($tr, shareModel.hasUserShares(), hasLinkShare)) { + if (!OCA.Sharing.Util._updateFileActionIcon($tr, shareModel.hasUserShares(), hasLinkShares)) { // remove icon, if applicable OC.Share.markFileAsShared($tr, false, false); } @@ -249,15 +249,15 @@ * * @param $tr file element of the file to update * @param {boolean} hasUserShares true if a user share exists - * @param {boolean} hasLinkShare true if a link share exists + * @param {boolean} hasLinkShares true if a link share exists * * @return {boolean} true if the icon was set, false otherwise */ - _updateFileActionIcon: function($tr, hasUserShares, hasLinkShare) { + _updateFileActionIcon: function($tr, hasUserShares, hasLinkShares) { // if the statuses are loaded already, use them for the icon // (needed when scrolling to the next page) - if (hasUserShares || hasLinkShare || $tr.attr('data-share-recipient-data') || $tr.attr('data-share-owner')) { - OC.Share.markFileAsShared($tr, true, hasLinkShare); + if (hasUserShares || hasLinkShares || $tr.attr('data-share-recipient-data') || $tr.attr('data-share-owner')) { + OC.Share.markFileAsShared($tr, true, hasLinkShares); return true; } return false; diff --git a/core/js/share/sharedialoglinkshareview.handlebars b/core/js/share/sharedialoglinkshareview.handlebars index bc7051683a2..a8a6e795839 100644 --- a/core/js/share/sharedialoglinkshareview.handlebars +++ b/core/js/share/sharedialoglinkshareview.handlebars @@ -1,14 +1,19 @@ {{#if shareAllowed}} {{else}} {{#if noSharingPlaceholder}}{{/if}} diff --git a/core/js/share/sharedialoglinkshareview_popover_menu.handlebars b/core/js/share/sharedialoglinkshareview_popover_menu.handlebars index baee3aa6630..6f504811be4 100644 --- a/core/js/share/sharedialoglinkshareview_popover_menu.handlebars +++ b/core/js/share/sharedialoglinkshareview_popover_menu.handlebars @@ -6,6 +6,13 @@ {{copyLabel}} +
  • + + + + {{newShareTitle}} + +
  • + {{#if hasExpireDate}}checked="checked"{{/if}} {{#if isExpirationEnforced}}disabled="disabled"{{/if}} />
  • - +
  • @@ -88,7 +96,7 @@
  • - {{/each}} +
  • + {{unshareLabel}} +
  • diff --git a/core/js/share/sharedialogshareelistview.handlebars b/core/js/share/sharedialogshareelistview.handlebars index a95949c8157..dc2496daaa8 100644 --- a/core/js/share/sharedialogshareelistview.handlebars +++ b/core/js/share/sharedialogshareelistview.handlebars @@ -15,7 +15,7 @@ - {{/each}} + {{/each}} {{#each linkReshares}}
  • diff --git a/core/js/sharedialoglinkshareview.js b/core/js/sharedialoglinkshareview.js index 7603b058a96..6e3fce04dfe 100644 --- a/core/js/sharedialoglinkshareview.js +++ b/core/js/sharedialoglinkshareview.js @@ -43,8 +43,6 @@ showPending: false, events: { - // enable/disable - 'change .linkCheckbox': 'onLinkCheckBoxChange', // open menu 'click .share-menu .icon-more': 'onToggleMenu', // hide download @@ -67,7 +65,11 @@ // note 'click .share-add': 'showNoteForm', 'click .share-note-delete': 'deleteNote', - 'click .share-note-submit': 'updateNote' + 'click .share-note-submit': 'updateNote', + // remove + 'click .unshare': 'onUnshare', + // new share + 'click .new-share': 'newShare', }, initialize: function(options) { @@ -89,10 +91,6 @@ view.render(); }); - this.model.on('change:linkShare', function() { - view.render(); - }); - if(!_.isUndefined(options.configModel)) { this.configModel = options.configModel; } else { @@ -102,7 +100,6 @@ var clipboard = new Clipboard('.clipboardButton'); clipboard.on('success', function(e) { var $menu = $(e.trigger); - var $linkTextMenu = $menu.parent().next('li.linkTextMenu') $menu.tooltip('hide') .attr('data-original-title', t('core', 'Copied!')) @@ -143,46 +140,44 @@ }); }, - onLinkCheckBoxChange: function() { - var $checkBox = this.$el.find('.linkCheckbox'); - var $loading = $checkBox.siblings('.icon-loading-small'); + newShare: function() { + var self = this; + var $loading = this.$el.find('.icon-loading-small').eq(0); if(!$loading.hasClass('hidden')) { + // in process return false; } - - if($checkBox.is(':checked')) { - if(this.configModel.get('enforcePasswordForPublicLink') === false) { - $loading.removeClass('hidden'); - // this will create it - this.model.saveLinkShare(); - $('.share-menu .icon-more').click(); - $('.share-menu .icon-more + .popovermenu .clipboardButton').click(); - } else { - // force the rendering of the menu - this.showPending = true; - this.render() - $('.share-menu .icon-more').click(); - $('.share-menu .icon-more + .popovermenu input:eq(1)').focus() - } - } else { - if (this.model.get('linkShare').isLinkShare) { - $loading.removeClass('hidden'); - this.model.removeLinkShare(); - } else { - this.showPending = false; - this.render() + // hide all icons and show loading + this.$el.find('.icon').addClass('hidden'); + $loading.removeClass('hidden'); + + this.model.saveLinkShare({}, { + success: function() { + $loading.addClass('hidden'); + self.$el.find('.icon').removeClass('hidden'); + self.render(); + }, + error: function(obj, msg) { + OC.Notification.showTemporary(t('core', 'Unable to create a link share')); + $loading.addClass('hidden'); + self.$el.find('.icon').removeClass('hidden'); } - } + }) }, - onLinkTextClick: function() { - var $el = this.$el.find('.linkText'); + onLinkTextClick: function(event) { + var $element = $(event.target); + var $li = $element.closest('li[data-share-id]'); + var $el = $li.find('.linkText'); $el.focus(); $el.select(); }, - onHideDownloadChange: function() { - var $checkbox = this.$('.hideDownloadCheckbox'); + onHideDownloadChange: function(event) { + var $element = $(event.target); + var $li = $element.closest('li[data-share-id]'); + var shareId = $li.data('share-id'); + var $checkbox = $li.find('.hideDownloadCheckbox'); $checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock'); var hideDownload = false; @@ -191,41 +186,57 @@ } this.model.saveLinkShare({ - hideDownload: hideDownload + hideDownload: hideDownload, + cid: shareId + }, { + success: function() { + $checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock'); + }, + error: function(obj, msg) { + OC.Notification.showTemporary(t('core', 'Unable to toggle this option')); + $checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock'); + } }); }, - onShowPasswordClick: function() { - this.$el.find('.linkPass').slideToggle(OC.menuSpeed); - this.$el.find('.linkPassMenu').toggleClass('hidden'); - if(!this.$el.find('.showPasswordCheckbox').is(':checked')) { + onShowPasswordClick: function(event) { + var $element = $(event.target); + var $li = $element.closest('li[data-share-id]'); + var shareId = $li.data('share-id'); + $li.find('.linkPass').slideToggle(OC.menuSpeed); + $li.find('.linkPassMenu').toggleClass('hidden'); + if(!$li.find('.showPasswordCheckbox').is(':checked')) { this.model.saveLinkShare({ - password: '' + password: '', + cid: shareId }); } else { if (!OC.Util.isIE()) { - this.$el.find('.linkPassText').focus(); + $li.find('.linkPassText').focus(); } } }, onPasswordKeyUp: function(event) { if(event.keyCode === 13) { - this.onPasswordEntered(); + this.onPasswordEntered(event); } }, - onPasswordEntered: function() { - var $loading = this.$el.find('.linkPassMenu .icon-loading-small'); + onPasswordEntered: function(event) { + var $element = $(event.target); + var $li = $element.closest('li[data-share-id]'); + var shareId = $li.data('share-id'); + var $loading = $li.find('.linkPassMenu .icon-loading-small'); if (!$loading.hasClass('hidden')) { // still in process return; } - var $input = this.$el.find('.linkPassText'); + var $input = $li.find('.linkPassText'); $input.removeClass('error'); var password = $input.val(); - if (this.$el.find('.linkPassText').attr('placeholder') === PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL) { + if ($li.find('.linkPassText').attr('placeholder') === PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL) { // in IE9 the password might be the placeholder due to bugs in the placeholders polyfill if(password === PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL) { @@ -244,7 +255,8 @@ .addClass('inlineblock'); this.model.saveLinkShare({ - password: password + password: password, + cid: shareId }, { complete: function(model) { $loading.removeClass('inlineblock').addClass('hidden'); @@ -260,8 +272,11 @@ }); }, - onAllowPublicEditingChange: function() { - var $checkbox = this.$('.publicEditingCheckbox'); + onAllowPublicEditingChange: function(event) { + var $element = $(event.target); + var $li = $element.closest('li[data-share-id]'); + var shareId = $li.data('share-id'); + var $checkbox = $li.find('.publicEditingCheckbox'); $checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock'); var permissions = OC.PERMISSION_READ; @@ -270,15 +285,28 @@ } this.model.saveLinkShare({ - permissions: permissions + permissions: permissions, + cid: shareId + }, { + success: function() { + $checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock'); + }, + error: function(obj, msg) { + OC.Notification.showTemporary(t('core', 'Unable to toggle this option')); + $checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock'); + } }); }, - onPublicUploadChange: function(e) { - var permissions = e.currentTarget.value; + onPublicUploadChange: function(event) { + var $element = $(event.target); + var $li = $element.closest('li[data-share-id]'); + var shareId = $li.data('share-id'); + var permissions = event.currentTarget.value; this.model.saveLinkShare({ - permissions: permissions + permissions: permissions, + cid: shareId }); }, @@ -386,46 +414,21 @@ && this.model.createPermissionPossible() && this.configModel.isPublicUploadEnabled(); - var publicUploadRWChecked = ''; - var publicUploadRChecked = ''; - var publicUploadWChecked = ''; - - switch (this.model.linkSharePermissions()) { - case OC.PERMISSION_READ: - publicUploadRChecked = 'checked'; - break; - case OC.PERMISSION_CREATE: - publicUploadWChecked = 'checked'; - break; - case OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE: - publicUploadRWChecked = 'checked'; - break; - } var publicEditingChecked = ''; if(this.model.isPublicEditingAllowed()) { publicEditingChecked = 'checked="checked"'; } - var isLinkShare = this.model.get('linkShare').isLinkShare; - var isPasswordSet = !!this.model.get('linkShare').password; var isPasswordEnforced = this.configModel.get('enforcePasswordForPublicLink'); var isPasswordEnabledByDefault = this.configModel.get('enableLinkPasswordByDefault') === true; - var showPasswordCheckBox = isLinkShare - && ( !this.configModel.get('enforcePasswordForPublicLink') - || !this.model.get('linkShare').password); var passwordPlaceholderInitial = this.configModel.get('enforcePasswordForPublicLink') ? PASSWORD_PLACEHOLDER_MESSAGE : PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL; - var showHideDownloadCheckbox = !this.model.isFolder(); - var hideDownload = this.model.get('linkShare').hideDownload; - var publicEditable = !this.model.isFolder() - && isLinkShare && this.model.updatePermissionPossible(); - var link = this.model.get('linkShare').link; var social = []; OC.Share.Social.Collection.each(function(model) { var url = model.get('url'); @@ -439,60 +442,28 @@ newWindow: model.get('newWindow') }); }); - - var defaultExpireDays = this.configModel.get('defaultExpireDate'); var isExpirationEnforced = this.configModel.get('isDefaultExpireDateEnforced'); - var hasExpireDate = !!this.model.get('linkShare').expiration || isExpirationEnforced; - - var expireDate; - if (hasExpireDate) { - expireDate = moment(this.model.get('linkShare').expiration, 'YYYY-MM-DD').format('DD-MM-YYYY'); - } - + // what if there is another date picker on that page? var minDate = new Date(); - var maxDate = null; // min date should always be the next day minDate.setDate(minDate.getDate()+1); - if(hasExpireDate) { - if(isExpirationEnforced) { - // TODO: hack: backend returns string instead of integer - var shareTime = this.model.get('linkShare').stime; - if (_.isNumber(shareTime)) { - shareTime = new Date(shareTime * 1000); - } - if (!shareTime) { - shareTime = new Date(); // now - } - shareTime = OC.Util.stripTime(shareTime).getTime(); - maxDate = new Date(shareTime + defaultExpireDays * 24 * 3600 * 1000); - } - } $.datepicker.setDefaults({ - minDate: minDate, - maxDate: maxDate + minDate: minDate }); this.$el.find('.datepicker').datepicker({dateFormat : 'dd-mm-yy'}); - var popover = this.popoverMenuTemplate({ - cid: this.model.get('linkShare').id, + var popoverBase = { copyLabel: t('core', 'Copy link'), social: social, - - shareLinkURL: this.model.get('linkShare').link, urlLabel: t('core', 'Link'), - showHideDownloadCheckbox: showHideDownloadCheckbox, - hideDownload: hideDownload, hideDownloadLabel: t('core', 'Hide download'), enablePasswordLabel: t('core', 'Password protect'), passwordLabel: t('core', 'Password'), - passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE, passwordPlaceholderInitial: passwordPlaceholderInitial, - isPasswordSet: isPasswordSet || isPasswordEnabledByDefault || isPasswordEnforced, - showPasswordCheckBox: showPasswordCheckBox, - publicUpload: publicUpload && isLinkShare, + publicUpload: publicUpload, publicEditing: publicEditable, publicEditingChecked: publicEditingChecked, publicEditingLabel: t('core', 'Allow editing'), @@ -504,41 +475,40 @@ publicUploadRWValue: OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE, publicUploadRValue: OC.PERMISSION_READ, publicUploadWValue: OC.PERMISSION_CREATE, - publicUploadRWChecked: publicUploadRWChecked, - publicUploadRChecked: publicUploadRChecked, - publicUploadWChecked: publicUploadWChecked, expireDateLabel: t('core', 'Set expiration date'), expirationLabel: t('core', 'Expiration'), expirationDatePlaceholder: t('core', 'Expiration date'), - hasExpireDate: hasExpireDate, isExpirationEnforced: isExpirationEnforced, isPasswordEnforced: isPasswordEnforced, - expireDate: expireDate, defaultExpireDate: moment().add(1, 'day').format('DD-MM-YYYY'), // Can't expire today - shareNote: this.model.get('linkShare').note, addNoteLabel: t('core', 'Note to recipient'), - }); + unshareLabel: t('core', 'Unshare'), + newShareLabel: t('core', 'New share link'), + }; - var pendingPopover = this.pendingPopoverMenuTemplate({ - cid: this.model.get('linkShare').id, + var pendingPopoverBase = { enablePasswordLabel: t('core', 'Password protect'), passwordLabel: t('core', 'Password'), - passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE, passwordPlaceholderInitial: passwordPlaceholderInitial, - showPasswordCheckBox: showPasswordCheckBox, isPasswordEnforced: isPasswordEnforced, - }); + }; + + var linkShares = this.getShareeList(); + if(_.isArray(linkShares)) { + for (var i = 0; i < linkShares.length; i++) { + var popover = this.getPopoverObject(linkShares[i]) + var pendingPopover = this.getPendingPopoverObject(linkShares[i]) + linkShares[i].popoverMenu = this.popoverMenuTemplate(_.extend({}, popoverBase, popover)); + linkShares[i].pendingPopoverMenu = this.pendingPopoverMenuTemplate(_.extend({}, pendingPopoverBase, pendingPopover)); + } + } this.$el.html(linkShareTemplate({ - cid: this.model.get('linkShare').id, + linkShares: linkShares, shareAllowed: true, - isLinkShare: isLinkShare, - linkShareLabel: t('core', 'Share link'), - linkShareEnableLabel: t('core', 'Enable'), - popoverMenu: popover, - pendingPopoverMenu: pendingPopover, - showMenu: isLinkShare || this.showPending, - showPending: this.showPending && !isLinkShare + nolinkShares: linkShares.length === 0, + newShareLabel: t('core', 'Share link'), + newShareTitle: t('core', 'New share link'), })); this.delegateEvents(); @@ -555,9 +525,10 @@ var $element = $(event.target); var $li = $element.closest('li[data-share-id]'); var $menu = $li.find('.sharingOptionsGroup .popovermenu'); + var shareId = $li.data('share-id'); OC.showMenu(null, $menu); - this._menuOpen = $li.data('share-id'); + this._menuOpen = shareId; }, /** @@ -635,24 +606,188 @@ var $element = $(event.target); var li = $element.closest('li[data-share-id]'); var shareId = li.data('share-id'); + var maxDate = $element.data('max-date'); var expirationDatePicker = '#expirationDatePicker-' + shareId; var self = this; $(expirationDatePicker).datepicker({ dateFormat : 'dd-mm-yy', onSelect: function (expireDate) { - self.setExpirationDate(expireDate); - } + self.setExpirationDate(expireDate, shareId); + }, + maxDate: maxDate }); $(expirationDatePicker).datepicker('show'); $(expirationDatePicker).focus(); }, - setExpirationDate: function(expireDate) { - this.model.saveLinkShare({expireDate: expireDate}); + setExpirationDate: function(expireDate, shareId) { + this.model.saveLinkShare({expireDate: expireDate, cid: shareId}); }, + /** + * get an array of sharees' share properties + * + * @returns {Array} + */ + getShareeList: function() { + var shares = this.model.get('linkShares'); + + if(!this.model.hasLinkShares()) { + return []; + } + + var list = []; + for(var index = 0; index < shares.length; index++) { + var share = this.getShareeObject(index); + // first empty {} is necessary, otherwise we get in trouble + // with references + list.push(_.extend({}, share)); + } + + return list; + }, + + /** + * + * @param {OC.Share.Types.ShareInfo} shareInfo + * @returns {object} + */ + getShareeObject: function(shareIndex) { + var share = this.model.get('linkShares')[shareIndex]; + + return _.extend({}, share, { + cid: share.id, + shareAllowed: true, + linkShareLabel: share.label !== '' ? share.label : t('core', 'Share link'), + popoverMenu: {}, + pendingPopoverMenu: {}, + showPending: this.showPending + }) + }, + + getPopoverObject: function(share) { + var publicUploadRWChecked = ''; + var publicUploadRChecked = ''; + var publicUploadWChecked = ''; + + switch (this.model.linkSharePermissions(share.id)) { + case OC.PERMISSION_READ: + publicUploadRChecked = 'checked'; + break; + case OC.PERMISSION_CREATE: + publicUploadWChecked = 'checked'; + break; + case OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE: + publicUploadRWChecked = 'checked'; + break; + } + + var isPasswordSet = !!share.password; + var isPasswordEnabledByDefault = this.configModel.get('enableLinkPasswordByDefault') === true; + var isPasswordEnforced = this.configModel.get('enforcePasswordForPublicLink'); + var showPasswordCheckBox = !this.configModel.get('enforcePasswordForPublicLink') || !share.password; + var isExpirationEnforced = this.configModel.get('isDefaultExpireDateEnforced'); + var defaultExpireDays = this.configModel.get('defaultExpireDate'); + var hasExpireDate = !!share.expiration || isExpirationEnforced; + var hasExpireDate = false; + + var expireDate; + if (hasExpireDate) { + expireDate = moment(share.expiration, 'YYYY-MM-DD').format('DD-MM-YYYY'); + } + + var showHideDownloadCheckbox = !this.model.isFolder(); + var hideDownload = share.hideDownload; + + var maxDate = null; + + if(hasExpireDate) { + if(isExpirationEnforced) { + // TODO: hack: backend returns string instead of integer + var shareTime = share.stime; + if (_.isNumber(shareTime)) { + shareTime = new Date(shareTime * 1000); + } + if (!shareTime) { + shareTime = new Date(); // now + } + shareTime = OC.Util.stripTime(shareTime).getTime(); + maxDate = new Date(shareTime + defaultExpireDays * 24 * 3600 * 1000); + } + } + + return { + cid: share.id, + shareLinkURL: share.url, + passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE, + isPasswordSet: isPasswordSet || isPasswordEnabledByDefault || isPasswordEnforced, + showPasswordCheckBox: showPasswordCheckBox, + publicUploadRWChecked: publicUploadRWChecked, + publicUploadRChecked: publicUploadRChecked, + publicUploadWChecked: publicUploadWChecked, + hasExpireDate: hasExpireDate, + expireDate: expireDate, + shareNote: share.note, + hasNote: share.note !== '', + maxDate: maxDate, + showHideDownloadCheckbox: showHideDownloadCheckbox, + hideDownload: hideDownload, + newShareTitle: t('core', 'New share link'), + } + }, + + getPendingPopoverObject: function(share) { + var isPasswordSet = !!share.password; + var showPasswordCheckBox = !this.configModel.get('enforcePasswordForPublicLink') || !share.password; + var isPasswordEnforced = this.configModel.get('enforcePasswordForPublicLink'); + + return { + cid: share.id, + enablePasswordLabel: t('core', 'Password protect'), + passwordLabel: t('core', 'Password'), + passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE, + showPasswordCheckBox: showPasswordCheckBox, + isPasswordEnforced: isPasswordEnforced, + } + + }, + + onUnshare: function(event) { + event.preventDefault(); + event.stopPropagation(); + var self = this; + var $element = $(event.target); + if (!$element.is('a')) { + $element = $element.closest('a'); + } + + var $loading = $element.find('.icon-loading-small').eq(0); + if(!$loading.hasClass('hidden')) { + // in process + return false; + } + $loading.removeClass('hidden'); + + var $li = $element.closest('li[data-share-id]'); + + var shareId = $li.data('share-id'); + + self.model.removeShare(shareId, { + success: function() { + $li.remove(); + self.render() + }, + error: function() { + $loading.addClass('hidden'); + OC.Notification.showTemporary(t('core', 'Could not unshare')); + } + }); + return false; + }, + + }); OC.Share.ShareDialogLinkShareView = ShareDialogLinkShareView; diff --git a/core/js/shareitemmodel.js b/core/js/shareitemmodel.js index 3f92a8591e5..ce7bc56ab8a 100644 --- a/core/js/shareitemmodel.js +++ b/core/js/shareitemmodel.js @@ -16,11 +16,9 @@ /** * @typedef {object} OC.Share.Types.LinkShareInfo - * @property {bool} isLinkShare * @property {string} token * @property {bool} hideDownload * @property {string|null} password - * @property {string} link * @property {number} permissions * @property {Date} expiration * @property {number} stime share time @@ -100,7 +98,7 @@ defaults: { allowPublicUploadStatus: false, permissions: 0, - linkShare: {} + linkShares: [] }, /** @@ -130,8 +128,11 @@ delete attributes.expiration; } - if (this.get('linkShare') && this.get('linkShare').isLinkShare) { - shareId = this.get('linkShare').id; + var linkShares = this.get('linkShares'); + var shareIndex = _.findIndex(linkShares, function(share) {return share.id === attributes.cid}) + + if (linkShares.length > 0 && shareIndex !== -1) { + shareId = linkShares[shareIndex].id; // note: update can only update a single value at a time call = this.updateShare(shareId, attributes, options); @@ -151,12 +152,6 @@ return call; }, - removeLinkShare: function() { - if (this.get('linkShare')) { - return this.removeShare(this.get('linkShare').id); - } - }, - addShare: function(attributes, options) { var shareType = attributes.shareType; attributes = _.extend({}, attributes); @@ -316,13 +311,13 @@ }, /** - * Returns whether this item has a link share + * Returns whether this item has link shares * * @return {bool} true if a link share exists, false otherwise */ - hasLinkShare: function() { - var linkShare = this.get('linkShare'); - if (linkShare && linkShare.isLinkShare) { + hasLinkShares: function() { + var linkShares = this.get('linkShares'); + if (linkShares && linkShares.length > 0) { return true; } return false; @@ -630,12 +625,16 @@ /** * @returns {int} */ - linkSharePermissions: function() { - if (!this.hasLinkShare()) { + linkSharePermissions: function(shareId) { + var linkShares = this.get('linkShares'); + var shareIndex = _.findIndex(linkShares, function(share) {return share.id === shareId}) + + if (!this.hasLinkShares()) { return -1; - } else { - return this.get('linkShare').permissions; + } else if (linkShares.length > 0 && shareIndex !== -1) { + return linkShares[shareIndex].permissions; } + return -1; }, _getUrl: function(base, params) { @@ -831,7 +830,7 @@ this._legacyFillCurrentShares(shares); - var linkShare = { isLinkShare: false }; + var linkShares = []; // filter out the share by link shares = _.reject(shares, /** @@ -844,7 +843,7 @@ || share.item_source === this.get('itemSource')); if (isShareLink) { - /* + /** * Ignore reshared link shares for now * FIXME: Find a way to display properly */ @@ -864,20 +863,12 @@ } else { link += OC.generateUrl('/s/') + share.token; } - linkShare = { - isLinkShare: true, - id: share.id, - token: share.token, + linkShares.push(_.extend({}, share, { // hide_download is returned as an int, so force it // to a boolean hideDownload: !!share.hide_download, - password: share.share_with, - link: link, - permissions: share.permissions, - // currently expiration is only effective for link shares. - expiration: share.expiration, - stime: share.stime - }; + password: share.share_with + })); return share; } @@ -888,7 +879,7 @@ return { reshare: data.reshare, shares: shares, - linkShare: linkShare, + linkShares: linkShares, permissions: permissions, allowPublicUploadStatus: allowPublicUploadStatus, allowPublicEditingStatus: allowPublicEditingStatus, @@ -924,7 +915,7 @@ getShareTypes: function() { var result; result = _.pluck(this.getSharesWithCurrentItem(), 'share_type'); - if (this.hasLinkShare()) { + if (this.hasLinkShares()) { result.push(OC.Share.SHARE_TYPE_LINK); } return _.uniq(result); diff --git a/core/js/sharetemplates.js b/core/js/sharetemplates.js index 0c1fee37455..dfda54a853e 100644 --- a/core/js/sharetemplates.js +++ b/core/js/sharetemplates.js @@ -1,33 +1,32 @@ (function() { var template = Handlebars.template, templates = OC.Share.Templates = OC.Share.Templates || {}; templates['sharedialoglinkshareview'] = template({"1":function(container,depth0,helpers,partials,data) { + var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}); + + return "
      \n" + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.nolinkShares : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.linkShares : depth0),{"name":"each","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + "
    \n"; +},"2":function(container,depth0,helpers,partials,data) { + var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; + + return "
  • \n
    \n " + + alias4(((helper = (helper = helpers.newShareLabel || (depth0 != null ? depth0.newShareLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"newShareLabel","hash":{},"data":data}) : helper))) + + "\n \n \n \n \n
  • \n"; +},"4":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; - return "
      \n
    • \n
      \n
      " + alias4(((helper = (helper = helpers.linkShareLabel || (depth0 != null ? depth0.linkShareLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"linkShareLabel","hash":{},"data":data}) : helper))) - + "\n \n \n \n \n \n \n" - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showMenu : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " \n
    • \n
    \n"; -},"2":function(container,depth0,helpers,partials,data) { - return "checked=\"checked\""; -},"4":function(container,depth0,helpers,partials,data) { - var stack1; - - return "
    \n" - + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.showPending : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : "") - + "
    \n"; + + "\n \n
    \n" + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showPending : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : "") + + "
    \n
    \n \n"; },"5":function(container,depth0,helpers,partials,data) { var stack1, helper; @@ -169,6 +168,8 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont + alias4(((helper = (helper = helpers.shareLinkURL || (depth0 != null ? depth0.shareLinkURL : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareLinkURL","hash":{},"data":data}) : helper))) + "\">\n \n " + alias4(((helper = (helper = helpers.copyLabel || (depth0 != null ? depth0.copyLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"copyLabel","hash":{},"data":data}) : helper))) + + "\n \n \n
  • \n \n \n \n " + + alias4(((helper = (helper = helpers.newShareTitle || (depth0 != null ? depth0.newShareTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"newShareTitle","hash":{},"data":data}) : helper))) + "\n \n
  • \n
  • \n \n \n \n
  • \n
  • \n \n \n \n " + alias4(((helper = (helper = helpers.addNoteLabel || (depth0 != null ? depth0.addNoteLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"addNoteLabel","hash":{},"data":data}) : helper))) - + "\n \n \n
  • \n
  • \n \n \n \n \n
  • \n" + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.social : depth0),{"name":"each","hash":{},"fn":container.program(17, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " \n\n"; + + "
  • \n " + + alias4(((helper = (helper = helpers.unshareLabel || (depth0 != null ? depth0.unshareLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"unshareLabel","hash":{},"data":data}) : helper))) + + "\n
  • \n \n\n"; },"useData":true}); templates['sharedialoglinkshareview_popover_menu_pending'] = template({"1":function(container,depth0,helpers,partials,data) { var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; -- cgit v1.2.3 From 376704e83413d093d596f1b9168daf24907189aa Mon Sep 17 00:00:00 2001 From: Daniel Calviño Sánchez Date: Mon, 15 Oct 2018 17:09:46 +0200 Subject: Add "Password protect by Talk" to the menu of link shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When Talk is enabled the menu for link shares now shows a checkbox to protect the password by Talk (that is, to show the "Request password by Talk" UI in the authentication page for the link share). Although in e-mail shares protecting the share with a password and protecting the password by Talk are mutually exclusive actions (as when the password is set it is sent to the sharee, so it must be set again when protecting it by Talk to be able to verify the identity of the sharee), in the case of link shares protecting the password by Talk is an additional step to protecting the share with a password (as just setting the password does not disclose it to anyone). As such, the checkbox is shown only when there is a password set for the link share (even if the field itself for the password is not shown, like when they are enforced in the settings). Note that the icon set for the field, "icon-passwordtalk", does not currently exist; it is the same used for e-mail shares, and it is needed simply to get the right padding in the menu. Signed-off-by: Daniel Calviño Sánchez --- ...haredialoglinkshareview_popover_menu.handlebars | 10 ++ core/js/sharedialoglinkshareview.js | 64 ++++++++++++ core/js/shareitemmodel.js | 5 +- core/js/sharetemplates.js | 29 ++++-- core/js/tests/specs/sharedialoglinkshareview.js | 113 +++++++++++++++++++++ core/js/tests/specs/shareitemmodelSpec.js | 13 ++- 6 files changed, 222 insertions(+), 12 deletions(-) (limited to 'core/js/shareitemmodel.js') diff --git a/core/js/share/sharedialoglinkshareview_popover_menu.handlebars b/core/js/share/sharedialoglinkshareview_popover_menu.handlebars index cc951ce047d..59312bc70b0 100644 --- a/core/js/share/sharedialoglinkshareview_popover_menu.handlebars +++ b/core/js/share/sharedialoglinkshareview_popover_menu.handlebars @@ -62,6 +62,16 @@ {{/if}} + {{#if showPasswordByTalkCheckBox}} +
  • + + + + + +
  • + {{/if}}
  • \n \n \n \n \n \n
  • \n"; },"15":function(container,depth0,helpers,partials,data) { + return "datepicker"; +},"17":function(container,depth0,helpers,partials,data) { var helper; return container.escapeExpression(((helper = (helper = helpers.expireDate || (depth0 != null ? depth0.expireDate : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"expireDate","hash":{},"data":data}) : helper))); -},"17":function(container,depth0,helpers,partials,data) { +},"19":function(container,depth0,helpers,partials,data) { var helper; return container.escapeExpression(((helper = (helper = helpers.defaultExpireDate || (depth0 != null ? depth0.defaultExpireDate : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"defaultExpireDate","hash":{},"data":data}) : helper))); -},"19":function(container,depth0,helpers,partials,data) { - return "readonly"; },"21":function(container,depth0,helpers,partials,data) { + return "readonly"; +},"23":function(container,depth0,helpers,partials,data) { var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; return "
  • \n \n \n \n \n \n \n
  • \n
  • \n \n \n \n " + alias4(((helper = (helper = helpers.addNoteLabel || (depth0 != null ? depth0.addNoteLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"addNoteLabel","hash":{},"data":data}) : helper))) + "\n \n \n \n
  • \n" - + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.social : depth0),{"name":"each","hash":{},"fn":container.program(21, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.social : depth0),{"name":"each","hash":{},"fn":container.program(23, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "
  • \n " + alias4(((helper = (helper = helpers.unshareLinkLabel || (depth0 != null ? depth0.unshareLinkLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"unshareLinkLabel","hash":{},"data":data}) : helper))) + "\n
  • \n
  • \n \n \n \n " diff --git a/core/js/tests/specs/sharedialoglinkshareview.js b/core/js/tests/specs/sharedialoglinkshareview.js index f5fe8725c03..c2d84fd2e87 100644 --- a/core/js/tests/specs/sharedialoglinkshareview.js +++ b/core/js/tests/specs/sharedialoglinkshareview.js @@ -235,4 +235,117 @@ describe('OC.Share.ShareDialogLinkShareView', function () { }); + describe('protect password by Talk', function () { + + var $passwordByTalkCheckbox; + var $workingIcon; + + beforeEach(function () { + // Needed to render the view + configModel.isShareWithLinkAllowed.returns(true); + + // "Enable" Talk + window.oc_appswebroots['spreed'] = window.oc_webroot + '/apps/files/'; + + shareModel.set({ + linkShares: [{ + id: 123, + password: 'password' + }] + }); + view.render(); + + $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox'); + $workingIcon = $passwordByTalkCheckbox.prev('.icon-loading-small'); + + sinon.stub(shareModel, 'saveLinkShare'); + + expect($workingIcon.hasClass('hidden')).toBeTruthy(); + }); + + afterEach(function () { + shareModel.saveLinkShare.restore(); + }); + + it('is shown if Talk is enabled and there is a password set', function() { + expect($passwordByTalkCheckbox.length).toBeTruthy(); + }); + + it('is not shown if Talk is enabled but there is no password set', function() { + // Changing the password value also triggers the rendering + shareModel.set({ + linkShares: [{ + id: 123 + }] + }); + + $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox'); + + expect($passwordByTalkCheckbox.length).toBeFalsy(); + }); + + it('is not shown if there is a password set but Talk is not enabled', function() { + // "Disable" Talk + delete window.oc_appswebroots['spreed']; + + view.render(); + + $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox'); + + expect($passwordByTalkCheckbox.length).toBeFalsy(); + }); + + it('checkbox is checked when the setting is enabled', function () { + shareModel.set({ + linkShares: [{ + id: 123, + password: 'password', + sendPasswordByTalk: true + }] + }); + view.render(); + + $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox'); + + expect($passwordByTalkCheckbox.is(':checked')).toEqual(true); + }); + + it('checkbox is not checked when the setting is disabled', function () { + expect($passwordByTalkCheckbox.is(':checked')).toEqual(false); + }); + + it('enables the setting if clicked when unchecked', function () { + // Simulate the click by checking the checkbox and then triggering + // the "change" event. + $passwordByTalkCheckbox.prop('checked', true); + $passwordByTalkCheckbox.change(); + + expect($workingIcon.hasClass('hidden')).toBeFalsy(); + expect(shareModel.saveLinkShare.withArgs({ sendPasswordByTalk: true, cid: 123 }).calledOnce).toBeTruthy(); + }); + + it('disables the setting if clicked when checked', function () { + shareModel.set({ + linkShares: [{ + id: 123, + password: 'password', + sendPasswordByTalk: true + }] + }); + view.render(); + + $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox'); + $workingIcon = $passwordByTalkCheckbox.prev('.icon-loading-small'); + + // Simulate the click by unchecking the checkbox and then triggering + // the "change" event. + $passwordByTalkCheckbox.prop('checked', false); + $passwordByTalkCheckbox.change(); + + expect($workingIcon.hasClass('hidden')).toBeFalsy(); + expect(shareModel.saveLinkShare.withArgs({ sendPasswordByTalk: false, cid: 123 }).calledOnce).toBeTruthy(); + }); + + }); + }); diff --git a/core/js/tests/specs/shareitemmodelSpec.js b/core/js/tests/specs/shareitemmodelSpec.js index 3b4dc5a960f..e8016950094 100644 --- a/core/js/tests/specs/shareitemmodelSpec.js +++ b/core/js/tests/specs/shareitemmodelSpec.js @@ -169,7 +169,8 @@ describe('OC.Share.ShareItemModel', function() { storage: 1, token: 'tehtoken', uid_owner: 'root', - hide_download: 1 + hide_download: 1, + send_password_by_talk: true } ])); @@ -189,6 +190,7 @@ describe('OC.Share.ShareItemModel', function() { expect(linkShares.length).toEqual(1); var linkShare = linkShares[0]; expect(linkShare.hideDownload).toEqual(true); + expect(linkShare.sendPasswordByTalk).toEqual(true); // TODO: check more attributes }); @@ -293,7 +295,8 @@ describe('OC.Share.ShareItemModel', function() { storage: 1, token: 'tehtoken', uid_owner: 'root', - hide_download: 0 + hide_download: 0, + send_password_by_talk: false }, { displayname_owner: 'root', expiration: '2015-10-15 00:00:00', @@ -312,7 +315,8 @@ describe('OC.Share.ShareItemModel', function() { storage: 1, token: 'anothertoken', uid_owner: 'root', - hide_download: 1 + hide_download: 1, + send_password_by_talk: true }] )); OC.currentUser = 'root'; @@ -327,6 +331,7 @@ describe('OC.Share.ShareItemModel', function() { var linkShare = linkShares[0]; expect(linkShare.token).toEqual('tehtoken'); expect(linkShare.hideDownload).toEqual(false); + expect(linkShare.sendPasswordByTalk).toEqual(false); // TODO: check child too }); @@ -588,6 +593,7 @@ describe('OC.Share.ShareItemModel', function() { hideDownload: false, password: '', passwordChanged: false, + sendPasswordByTalk: false, permissions: OC.PERMISSION_READ, expireDate: '', shareType: OC.Share.SHARE_TYPE_LINK @@ -612,6 +618,7 @@ describe('OC.Share.ShareItemModel', function() { hideDownload: false, password: '', passwordChanged: false, + sendPasswordByTalk: false, permissions: OC.PERMISSION_READ, expireDate: '2015-07-24 00:00:00', shareType: OC.Share.SHARE_TYPE_LINK -- cgit v1.2.3