PageSourceSearch

https://cloud.altij.fr/core/js/sharedialoglinkshareview.js?v=c7fa988cdc506ff356994056e06735ba

js altij.fr collected 2026-10-04 11:27:07 UTC 12,544 bytes, 388 lines download raw bytes

1/*
2 * Copyright (c) 2015
3 *
4 * This file is licensed under the Affero General Public License version 3
5 * or later.
6 *
7 * See the COPYING-README file.
8 *
9 */
10
11(function () {
12	if (!OC.Share) {
13		OC.Share = {};
14	}
15
16	var PASSWORD_PLACEHOLDER_STARS = '**********';
17	var PASSWORD_PLACEHOLDER_MESSAGE = t('core', 'Choose a password');
18	var TEMPLATE =
19		'<div class="error-message-global hidden"></div>' +
20		'<div class="public-link-modal">'+
21			'<div class="public-link-modal--item">' +
22				'<label class="public-link-modal--label">{{linkNameLabel}}</label>' +
23				'<input class="public-link-modal--input" type="text" name="linkName" placeholder="{{namePlaceholder}}" value="{{name}}" maxlength="64" />' +
24			'</div>' +
25			'<div id="allowPublicRead-{{cid}}" class="public-link-modal--item">' +
26				'<input type="radio" value="{{publicReadValue}}" name="publicPermissions" id="sharingDialogAllowPublicRead-{{cid}}" class="checkbox publicPermissions" {{#if publicReadSelected}}checked{{/if}} />' +
27				'<label class="bold" for="sharingDialogAllowPublicRead-{{cid}}">{{publicReadLabel}}</label>' +
28				'<p><em>{{publicReadDescription}}</em></p>' +
29			'</div>' +
30			'{{#if publicUploadPossible}}' +
31			'<div id="allowPublicReadWrite-{{cid}}" class="public-link-modal--item">' +
32				'<input type="radio" value="{{publicReadWriteValue}}" name="publicPermissions" id="sharingDialogAllowPublicReadWrite-{{cid}}" class="checkbox publicPermissions" {{#if publicReadWriteSelected}}checked{{/if}} />' +
33				'<label class="bold" for="sharingDialogAllowPublicReadWrite-{{cid}}">{{publicReadWriteLabel}}</label>' +
34				'<p><em>{{publicReadWriteDescription}}</em></p>' +
35			'</div>' +
36			'<div id="allowPublicUploadWrapper-{{cid}}" class="public-link-modal--item">' +
37				'<input type="radio" value="{{publicUploadValue}}" name="publicPermissions" id="sharingDialogAllowPublicUpload-{{cid}}" class="checkbox publicPermissions" {{#if publicUploadSelected}}checked{{/if}} />' +
38				'<label class="bold" for="sharingDialogAllowPublicUpload-{{cid}}">{{publicUploadLabel}}</label>' +
39				'<p><em>{{publicUploadDescription}}</em></p>' +
40			'</div>' +
41			'{{/if}}' +
42			'<div id="linkPass-{{cid}}" class="public-link-modal--item linkPass">' +
43				'<label class="public-link-modal--label" for="linkPassText-{{cid}}">{{passwordLabel}}</label>' +
44				'<input class="public-link-modal--input linkPassText" id="linkPassText-{{cid}}" type="password" autocomplete="off" placeholder="{{passwordPlaceholder}}" />' +
45				'<span class="error-message hidden"></span>' +
46			'</div>' +
47			'<div class="expirationDateContainer"></div>' +
48			'{{#if isMailEnabled}}' +
49			'<div class="mailView"></div>' +
50			'{{/if}}' +
51		'</div>'
52	;
53
54	/**
55	 * @class OCA.Share.ShareDialogLinkShareView
56	 * @member {OC.Share.ShareItemModel} model
57	 * @member {jQuery} $el
58	 * @memberof OCA.Sharing
59	 * @classdesc
60	 *
61	 * Represents the GUI of the share dialogue
62	 *
63	 */
64	var ShareDialogLinkShareView = OC.Backbone.View.extend({
65		/** @type {string} **/
66		id: 'shareDialogLinkShare',
67
68		className: 'shareDialogLinkShare',
69
70		/** @type {OC.Share.ShareConfigModel} **/
71		configModel: undefined,
72
73		/** @type {OC.Share.ShareItemModel} **/
74		itemModel: undefined,
75
76		/** @type {Function} **/
77		_template: undefined,
78
79		initialize: function (options) {
80			if (!_.isUndefined(options.itemModel)) {
81				this.itemModel = options.itemModel;
82				this.configModel = this.itemModel.configModel;
83			} else {
84				throw 'missing OC.Share.ShareItemModel';
85			}
86
87			this.expirationView = new OC.Share.ShareDialogExpirationView({
88				model: this.model,
89				itemModel: this.itemModel
90			});
91
92			OC.Plugins.attach('OCA.Share.ShareDialogLinkShareView', this);
93		},
94
95		/**
96		 * Returns the selected permissions as read from the checkboxes or
97		 * the absence thereof.
98		 *
99		 * @return {int} permissions
100		 */
101		_getPermissions: function() {
102			var permissions = this.$('input[name="publicPermissions"]:checked').val();
103
104			return (permissions) ? parseInt(permissions, 10) : OC.PERMISSION_READ;
105		},
106
107		_shouldRequirePassword: function() {
108			// matching passwordMustBeEnforced from server side
109			var permissions = this._getPermissions();
110			var roEnforcement = permissions === OC.PERMISSION_READ && this.configModel.get('enforceLinkPasswordReadOnly');
111			var woEnforcement = permissions === OC.PERMISSION_CREATE && this.configModel.get('enforceLinkPasswordWriteOnly');
112			var rwEnforcement = (permissions !== OC.PERMISSION_READ && permissions !== OC.PERMISSION_CREATE) && this.configModel.get('enforceLinkPasswordReadWrite');
113			if (roEnforcement || woEnforcement || rwEnforcement) {
114				return true;
115			} else {
116				return false;
117			}
118		},
119
120		_save: function () {
121			var deferred = $.Deferred();
122			var $el = this.$el;
123
124			var $formElements       = $el.find('input, textarea, select, button'),
125				$select2Elements    = $el.find('.select2-search-choice-close'),
126				$password           = $el.find('.linkPassText'),
127				$inputs             = $el.find('.linkPassText, .expirationDate, .permission'), // all input fields combined
128				$errorMessageGlobal = $el.find('.error-message-global'),
129				$loading            = $el.find('.loading'),
130
131				password            = $password.val(),
132				expirationDate      = this.expirationView.getValue();
133
134			$el.find('.error-message').addClass('hidden');
135
136			// prevent tinkering with form while loading
137			$formElements.attr('disabled', true);
138			$select2Elements.addClass('hidden');
139
140			// remove errors
141			$inputs.removeClass('error');
142			$errorMessageGlobal.addClass('hidden');
143
144			// explicit attributes to be saved
145			var attributes = {
146				expireDate: expirationDate,
147				permissions: this._getPermissions(),
148				name: this.$('[name=linkName]').val(),
149				shareType: this.model.get('shareType')
150			};
151
152			// Reset password for the time being
153			if (this.model.get("resetPassword")) {
154				attributes.password = '';
155			}
156
157			if (password) {
158				// only set password explicitly if changed
159				attributes.password = password;
160			}
161
162			var validates = true;
163			validates &= this.expirationView.validate();
164
165			if (!password
166				&& this._shouldRequirePassword()
167				&& (this.model.isNew() || !this.model.get('encryptedPassword'))
168			) {
169				$password.addClass('error');
170				$password.next('.error-message').removeClass('hidden').text(t('core', 'Password required'));
171				validates = false;
172			}
173
174			if (!validates) {
175				$loading.addClass('hidden');
176				$formElements.removeAttr('disabled');
177				$select2Elements.removeClass('hidden');
178				return deferred.reject(this.model);
179			}
180
181			if (this.model.isNew()) {
182				// the API is inconsistent
183				attributes.path = this.itemModel.getFileInfo().getFullPath();
184			}
185
186			var self = this;
187
188			var done = function() {
189				$loading.addClass('hidden');
190				deferred.resolve(self.model);
191				self.trigger('saved', self.model);
192			};
193
194			$loading.removeClass('hidden');
195
196			// save it
197			// ***
198			this.model.save(attributes, {
199				// explicit attributes for patch-like PUT to avoid
200				// passing all attributes
201				attrs: attributes,
202				success: function() {
203					if (self.mailView) {
204						// also send out email first
205						// do not resolve on errors
206						self.mailView.sendEmails().then(done);
207					} else {
208						done();
209					}
210					self.model.unset("resetPassword");
211				},
212				error: function (model, xhr) {
213					var msg = xhr.responseJSON.ocs.meta.message;
214					// destroy old tooltips
215					$loading.addClass('hidden');
216					$formElements.removeAttr('disabled');
217					$select2Elements.removeClass('hidden');
218					$errorMessageGlobal.removeClass('hidden').text(msg);
219					deferred.reject(self.model);
220				}
221			});
222
223			return deferred.promise();
224		},
225
226		_remove: function () {
227			this.model.destroy();
228		},
229
230		_isPublicUploadPossible: function() {
231			// TODO: in the future to read directly from the FileInfoModel
232			return this.itemModel.isFolder() && this.itemModel.createPermissionPossible() && this.configModel.isPublicUploadEnabled();
233		},
234
235		render: function () {
236			var isPasswordSet = !!this.model.get('encryptedPassword');
237
238			// only show email field for new shares and if enabled globally
239			var showEmailField = this.configModel.isMailPublicNotificationEnabled();
240
241			this.$el.html(this.template({
242				cid: this.cid,
243				passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER_STARS : PASSWORD_PLACEHOLDER_MESSAGE,
244				linkNameLabel: t('core', 'Link name'),
245				namePlaceholder: t('core', 'Name'),
246				name: this.model.get('name'),
247				isPasswordSet: isPasswordSet,
248
249				fileNameLabel              : t('core', 'Filename'),
250				passwordLabel              : t('core', 'Password'),
251
252				publicUploadPossible       : this._isPublicUploadPossible(),
253
254				publicUploadLabel          : t('core', 'Upload only') + ' (File Drop)',
255				publicUploadDescription    : t('core', 'Receive files from multiple recipients without reveal
255ing the contents of the folder.'),
256				publicUploadValue          : OC.PERMISSION_CREATE,
257				publicUploadSelected       : this.model.get('permissions') === OC.PERMISSION_CREATE,
258
259				publicReadLabel            : t('core', 'Download / View'),
260				publicReadDescription      : t('core', 'Recipients can view or download contents.'),
261				publicReadValue            : OC.PERMISSION_READ,
262				publicReadSelected         : this.model.get('permissions') === OC.PERMISSION_READ,
263
264				publicReadWriteLabel       : t('core', 'Download / View / Upload'),
265				publicReadWriteDescription : t('core', 'Recipients can view, download, edit, delete and upload contents.'),
266				publicReadWriteValue       : OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_DELETE,
267				publicReadWriteSelected    : this.model.get('permissions') >= (OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_DELETE),
268
269				isMailEnabled: showEmailField
270			}));
271
272			this.$('.datepicker').datepicker({dateFormat : 'dd-mm-yy'});
273
274			if (showEmailField) {
275				this.mailView = new OC.Share.ShareDialogMailView({
276					itemModel: this.itemModel,
277					configModel: this.configModel,
278					model: this.model
279				});
280				this.mailView.render();
281				this.$('.mailView').append(this.mailView.$el);
282			} else {
283				this.mailView = null;
284			}
285
286			this.expirationView.render();
287			this.$('.expirationDateContainer').append(this.expirationView.$el);
288
289			this.delegateEvents();
290
291			return this;
292		},
293
294		_onClickReset: function () {
295			var $dialog        = $('.oc-dialog:visible'),
296				$inputPassword = $dialog.find('.linkPassText'),
297				$buttonReset   = $dialog.find('.removePassword');
298
299			this.model.set("resetPassword", true);
300
301			$inputPassword
302				.val('')
303				.attr('placeholder', PASSWORD_PLACEHOLDER_MESSAGE);
304
305			$buttonReset.remove();
306		},
307
308		_onClickSave: function() {
309			var self = this;
310			this._save().then(function() {
311				self.$dialog.ocdialog('close');
312			});
313		},
314
315		_onClickCancel: function() {
316			this.$dialog.ocdialog('close');
317			this.model.unset("resetPassword");
318		},
319		/**
320		 * @returns {Function} from Handlebars
321		 * @private
322		 */
323		template: function (data) {
324			if (!this._template) {
325				this._template = Handlebars.compile(TEMPLATE);
326			}
327			return this._template(data);
328		},
329
330		/**
331		 * Display this view inside a popup window
332		 */
333		show: function() {
334			var self = this;
335			var title = t('core', 'Edit link share: {name}', {name: this.itemModel.getFileInfo().getFullPath()});
336			var buttons = [{
337				text: t('core', 'Cancel'),
338				click: _.bind(this._onClickCancel, this)
339			}];
340
341			if (this.model.isNew()) {
342				title = t('core', 'Create link share: {name}', {name: this.itemModel.getFileInfo().getFullPath()});
343				buttons.push({
344					text: t('core', 'Share'),
345					click: _.bind(this._onClickSave, this),
346					defaultButton: true
347				})
348			}
349			else {
350				buttons.push({
351					text: t('core', 'Save'),
352					click: _.bind(this._onClickSave, this),
353					defaultButton: true
354				})
355			}
356
357			if (this.model.get('encryptedPassword')) {
358				buttons.push({
359					classes: 'removePassword',
360					text: t('core', 'Remove password'),
361					click: _.bind(this._onClickReset, this),
362					defaultButton: false
363				});
364			}
365
366			// hack the dialogs
367			OC.dialogs.message(
368				'',
369				title,
370				'custom',
371				buttons,
372				null,
373				true,
374				'public-link-modal'
375			).then(function adjustDialog() {
376				var $dialogShell = $('.oc-dialog:visible');
377				self.render();
378				self.$dialog = $dialogShell.find('.oc-dialog-content');
379				self.$dialog.html(self.$el);
380				self.$el.find('input:first').focus();
381			});
382		}
383
384});
385
386	OC.Share.ShareDialogLinkShareView = ShareDialogLinkShareView;
387
388})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.