diff options
Diffstat (limited to 'apps/files_sharing/src/models')
-rw-r--r-- | apps/files_sharing/src/models/Share.js | 550 | ||||
-rw-r--r-- | apps/files_sharing/src/models/Share.ts | 496 |
2 files changed, 496 insertions, 550 deletions
diff --git a/apps/files_sharing/src/models/Share.js b/apps/files_sharing/src/models/Share.js deleted file mode 100644 index db9351fb52c..00000000000 --- a/apps/files_sharing/src/models/Share.js +++ /dev/null @@ -1,550 +0,0 @@ -/** - * @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com> - * - * @author John Molakvoæ <skjnldsv@protonmail.com> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -export default class Share { - - #share; - - /** - * Create the share object - * - * @param {Object} ocsData ocs request response - */ - constructor(ocsData) { - if (ocsData.ocs && ocsData.ocs.data && ocsData.ocs.data[0]) { - ocsData = ocsData.ocs.data[0] - } - - // convert int into boolean - ocsData.hide_download = !!ocsData.hide_download - ocsData.mail_send = !!ocsData.mail_send - - // store state - this.#share = ocsData - } - - /** - * Get the share state - * ! used for reactivity purpose - * Do not remove. It allow vuejs to - * inject its watchers into the #share - * state and make the whole class reactive - * - * @returns {Object} the share raw state - * @readonly - * @memberof Sidebar - */ - get state() { - return this.#share - } - - /** - * get the share id - * - * @returns {int} - * @readonly - * @memberof Share - */ - get id() { - return this.#share.id - } - - /** - * Get the share type - * - * @returns {int} - * @readonly - * @memberof Share - */ - get type() { - return this.#share.share_type - } - - /** - * Get the share permissions - * See OC.PERMISSION_* variables - * - * @returns {int} - * @readonly - * @memberof Share - */ - get permissions() { - return this.#share.permissions - } - - /** - * Set the share permissions - * See OC.PERMISSION_* variables - * - * @param {int} permissions valid permission, See OC.PERMISSION_* variables - * @memberof Share - */ - set permissions(permissions) { - this.#share.permissions = permissions - } - - // SHARE OWNER -------------------------------------------------- - /** - * Get the share owner uid - * - * @returns {string} - * @readonly - * @memberof Share - */ - get owner() { - return this.#share.uid_owner - } - - /** - * Get the share owner's display name - * - * @returns {string} - * @readonly - * @memberof Share - */ - get ownerDisplayName() { - return this.#share.displayname_owner - } - - // SHARED WITH -------------------------------------------------- - /** - * Get the share with entity uid - * - * @returns {string} - * @readonly - * @memberof Share - */ - get shareWith() { - return this.#share.share_with - } - - /** - * Get the share with entity display name - * fallback to its uid if none - * - * @returns {string} - * @readonly - * @memberof Share - */ - get shareWithDisplayName() { - return this.#share.share_with_displayname - || this.#share.share_with - } - - get shareWithDisplayNameUnique() { - return this.#share.share_with_displayname_unique || this.#share.share_with - } - - /** - * Get the share with entity link - * - * @returns {string} - * @readonly - * @memberof Share - */ - get shareWithLink() { - return this.#share.share_with_link - } - - /** - * Get the share with avatar if any - * - * @returns {string} - * @readonly - * @memberof Share - */ - get shareWithAvatar() { - return this.#share.share_with_avatar - } - - // SHARED FILE OR FOLDER OWNER ---------------------------------- - /** - * Get the shared item owner uid - * - * @returns {string} - * @readonly - * @memberof Share - */ - get uidFileOwner() { - return this.#share.uid_file_owner - } - - /** - * Get the shared item display name - * fallback to its uid if none - * - * @returns {string} - * @readonly - * @memberof Share - */ - get displaynameFileOwner() { - return this.#share.displayname_file_owner - || this.#share.uid_file_owner - } - - // TIME DATA ---------------------------------------------------- - /** - * Get the share creation timestamp - * - * @returns {int} - * @readonly - * @memberof Share - */ - get createdTime() { - return this.#share.stime - } - - /** - * Get the expiration date as a string format - * - * @returns {string} - * @readonly - * @memberof Share - */ - get expireDate() { - return this.#share.expiration - } - - /** - * Set the expiration date as a string format - * e.g. YYYY-MM-DD - * - * @param {string} date the share expiration date - * @memberof Share - */ - set expireDate(date) { - this.#share.expiration = date - } - - // EXTRA DATA --------------------------------------------------- - /** - * Get the public share token - * - * @returns {string} the token - * @readonly - * @memberof Share - */ - get token() { - return this.#share.token - } - - /** - * Get the share note if any - * - * @returns {string} - * @readonly - * @memberof Share - */ - get note() { - return this.#share.note - } - - /** - * Set the share note if any - * - * @param {string} note the note - * @memberof Share - */ - set note(note) { - this.#share.note = note - } - - /** - * Get the share label if any - * Should only exist on link shares - * - * @returns {string} - * @readonly - * @memberof Share - */ - get label() { - return this.#share.label - } - - /** - * Set the share label if any - * Should only be set on link shares - * - * @param {string} label the label - * @memberof Share - */ - set label(label) { - this.#share.label = label - } - - /** - * Have a mail been sent - * - * @returns {boolean} - * @readonly - * @memberof Share - */ - get mailSend() { - return this.#share.mail_send === true - } - - /** - * Hide the download button on public page - * - * @returns {boolean} - * @readonly - * @memberof Share - */ - get hideDownload() { - return this.#share.hide_download === true - } - - /** - * Hide the download button on public page - * - * @param {boolean} state hide the button ? - * @memberof Share - */ - set hideDownload(state) { - this.#share.hide_download = state === true - } - - /** - * Password protection of the share - * - * @returns {string} - * @readonly - * @memberof Share - */ - get password() { - return this.#share.password - } - - /** - * Password protection of the share - * - * @param {string} password the share password - * @memberof Share - */ - set password(password) { - this.#share.password = password - } - - /** - * Password protection by Talk of the share - * - * @returns {Boolean} - * @readonly - * @memberof Share - */ - get sendPasswordByTalk() { - return this.#share.send_password_by_talk - } - - /** - * Password protection by Talk of the share - * - * @param {Boolean} sendPasswordByTalk whether to send the password by Talk - * or not - * @memberof Share - */ - set sendPasswordByTalk(sendPasswordByTalk) { - this.#share.send_password_by_talk = sendPasswordByTalk - } - - // SHARED ITEM DATA --------------------------------------------- - /** - * Get the shared item absolute full path - * - * @returns {string} - * @readonly - * @memberof Share - */ - get path() { - return this.#share.path - } - - /** - * Return the item type: file or folder - * - * @returns {string} 'folder' or 'file' - * @readonly - * @memberof Share - */ - get itemType() { - return this.#share.item_type - } - - /** - * Get the shared item mimetype - * - * @returns {string} - * @readonly - * @memberof Share - */ - get mimetype() { - return this.#share.mimetype - } - - /** - * Get the shared item id - * - * @returns {int} - * @readonly - * @memberof Share - */ - get fileSource() { - return this.#share.file_source - } - - /** - * Get the target path on the receiving end - * e.g the file /xxx/aaa will be shared in - * the receiving root as /aaa, the fileTarget is /aaa - * - * @returns {string} - * @readonly - * @memberof Share - */ - get fileTarget() { - return this.#share.file_target - } - - /** - * Get the parent folder id if any - * - * @returns {int} - * @readonly - * @memberof Share - */ - get fileParent() { - return this.#share.file_parent - } - - // PERMISSIONS Shortcuts - /** - * Does this share have CREATE permissions - * - * @returns {boolean} - * @readonly - * @memberof Share - */ - get hasCreatePermission() { - return !!((this.permissions & OC.PERMISSION_CREATE)) - } - - /** - * Does this share have DELETE permissions - * - * @returns {boolean} - * @readonly - * @memberof Share - */ - get hasDeletePermission() { - return !!((this.permissions & OC.PERMISSION_DELETE)) - } - - /** - * Does this share have UPDATE permissions - * - * @returns {boolean} - * @readonly - * @memberof Share - */ - get hasUpdatePermission() { - return !!((this.permissions & OC.PERMISSION_UPDATE)) - } - - /** - * Does this share have SHARE permissions - * - * @returns {boolean} - * @readonly - * @memberof Share - */ - get hasSharePermission() { - return !!((this.permissions & OC.PERMISSION_SHARE)) - } - - // PERMISSIONS Shortcuts for the CURRENT USER - // ! the permissions above are the share settings, - // ! meaning the permissions for the recipient - /** - * Can the current user EDIT this share ? - * - * @returns {boolean} - * @readonly - * @memberof Share - */ - get canEdit() { - return this.#share.can_edit === true - } - - /** - * Can the current user DELETE this share ? - * - * @returns {boolean} - * @readonly - * @memberof Share - */ - get canDelete() { - return this.#share.can_delete === true - } - - /** - * Top level accessible shared folder fileid for the current user - * @returns {string} - * @readonly - * @memberof Share - */ - get viaFileid() { - return this.#share.via_fileid - } - - /** - * Top level accessible shared folder path for the current user - * @returns {string} - * @readonly - * @memberof Share - */ - get viaPath() { - return this.#share.via_path - } - - // TODO: SORT THOSE PROPERTIES - - get parent() { - return this.#share.parent - } - - get storageId() { - return this.#share.storage_id - } - - get storage() { - return this.#share.storage - } - - get itemSource() { - return this.#share.item_source - } - - get status() { - return this.#share.status - } - -} diff --git a/apps/files_sharing/src/models/Share.ts b/apps/files_sharing/src/models/Share.ts new file mode 100644 index 00000000000..b0638b29448 --- /dev/null +++ b/apps/files_sharing/src/models/Share.ts @@ -0,0 +1,496 @@ +/** + * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import type { ShareType } from '@nextcloud/sharing' +import type { ShareAttribute } from '../sharing' +import { isFileRequest } from '../services/SharingService' + +export default class Share { + + _share + + /** + * Create the share object + * + * @param {object} ocsData ocs request response + */ + constructor(ocsData) { + if (ocsData.ocs && ocsData.ocs.data && ocsData.ocs.data[0]) { + ocsData = ocsData.ocs.data[0] + } + + // string to int + if (typeof ocsData.id === 'string') { + ocsData.id = Number.parseInt(ocsData.id) + } + // convert int into boolean + ocsData.hide_download = !!ocsData.hide_download + ocsData.mail_send = !!ocsData.mail_send + + if (ocsData.attributes && typeof ocsData.attributes === 'string') { + try { + ocsData.attributes = JSON.parse(ocsData.attributes) + } catch (e) { + console.warn('Could not parse share attributes returned by server', ocsData.attributes) + } + } + ocsData.attributes = ocsData.attributes ?? [] + + // store state + this._share = ocsData + } + + /** + * Get the share state + * ! used for reactivity purpose + * Do not remove. It allow vuejs to + * inject its watchers into the #share + * state and make the whole class reactive + * + * @return {object} the share raw state + */ + get state() { + return this._share + } + + /** + * get the share id + */ + get id(): number { + return this._share.id + } + + /** + * Get the share type + */ + get type(): ShareType { + return this._share.share_type + } + + /** + * Get the share permissions + * See window.OC.PERMISSION_* variables + */ + get permissions(): number { + return this._share.permissions + } + + /** + * Get the share attributes + */ + get attributes(): Array<ShareAttribute> { + return this._share.attributes || [] + } + + /** + * Set the share permissions + * See window.OC.PERMISSION_* variables + */ + set permissions(permissions: number) { + this._share.permissions = permissions + } + + // SHARE OWNER -------------------------------------------------- + /** + * Get the share owner uid + */ + get owner(): string { + return this._share.uid_owner + } + + /** + * Get the share owner's display name + */ + get ownerDisplayName(): string { + return this._share.displayname_owner + } + + // SHARED WITH -------------------------------------------------- + /** + * Get the share with entity uid + */ + get shareWith(): string { + return this._share.share_with + } + + /** + * Get the share with entity display name + * fallback to its uid if none + */ + get shareWithDisplayName(): string { + return this._share.share_with_displayname + || this._share.share_with + } + + /** + * Unique display name in case of multiple + * duplicates results with the same name. + */ + get shareWithDisplayNameUnique(): string { + return this._share.share_with_displayname_unique + || this._share.share_with + } + + /** + * Get the share with entity link + */ + get shareWithLink(): string { + return this._share.share_with_link + } + + /** + * Get the share with avatar if any + */ + get shareWithAvatar(): string { + return this._share.share_with_avatar + } + + // SHARED FILE OR FOLDER OWNER ---------------------------------- + /** + * Get the shared item owner uid + */ + get uidFileOwner(): string { + return this._share.uid_file_owner + } + + /** + * Get the shared item display name + * fallback to its uid if none + */ + get displaynameFileOwner(): string { + return this._share.displayname_file_owner + || this._share.uid_file_owner + } + + // TIME DATA ---------------------------------------------------- + /** + * Get the share creation timestamp + */ + get createdTime(): number { + return this._share.stime + } + + /** + * Get the expiration date + * @return {string} date with YYYY-MM-DD format + */ + get expireDate(): string { + return this._share.expiration + } + + /** + * Set the expiration date + * @param {string} date the share expiration date with YYYY-MM-DD format + */ + set expireDate(date: string) { + this._share.expiration = date + } + + // EXTRA DATA --------------------------------------------------- + /** + * Get the public share token + */ + get token(): string { + return this._share.token + } + + /** + * Set the public share token + */ + set token(token: string) { + this._share.token = token + } + + /** + * Get the share note if any + */ + get note(): string { + return this._share.note + } + + /** + * Set the share note if any + */ + set note(note: string) { + this._share.note = note + } + + /** + * Get the share label if any + * Should only exist on link shares + */ + get label(): string { + return this._share.label ?? '' + } + + /** + * Set the share label if any + * Should only be set on link shares + */ + set label(label: string) { + this._share.label = label + } + + /** + * Have a mail been sent + */ + get mailSend(): boolean { + return this._share.mail_send === true + } + + /** + * Hide the download button on public page + */ + get hideDownload(): boolean { + return this._share.hide_download === true + || this.attributes.find?.(({ scope, key, value }) => scope === 'permissions' && key === 'download' && !value) !== undefined + } + + /** + * Hide the download button on public page + */ + set hideDownload(state: boolean) { + // disabling hide-download also enables the download permission + // needed for regression in Nextcloud 31.0.0 until (incl.) 31.0.3 + if (!state) { + const attribute = this.attributes.find(({ key, scope }) => key === 'download' && scope === 'permissions') + if (attribute) { + attribute.value = true + } + } + + this._share.hide_download = state === true + } + + /** + * Password protection of the share + */ + get password():string { + return this._share.password + } + + /** + * Password protection of the share + */ + set password(password: string) { + this._share.password = password + } + + /** + * Password expiration time + * @return {string} date with YYYY-MM-DD format + */ + get passwordExpirationTime(): string { + return this._share.password_expiration_time + } + + /** + * Password expiration time + * @param {string} passwordExpirationTime date with YYYY-MM-DD format + */ + set passwordExpirationTime(passwordExpirationTime: string) { + this._share.password_expiration_time = passwordExpirationTime + } + + /** + * Password protection by Talk of the share + */ + get sendPasswordByTalk(): boolean { + return this._share.send_password_by_talk + } + + /** + * Password protection by Talk of the share + * + * @param {boolean} sendPasswordByTalk whether to send the password by Talk or not + */ + set sendPasswordByTalk(sendPasswordByTalk: boolean) { + this._share.send_password_by_talk = sendPasswordByTalk + } + + // SHARED ITEM DATA --------------------------------------------- + /** + * Get the shared item absolute full path + */ + get path(): string { + return this._share.path + } + + /** + * Return the item type: file or folder + * @return {string} 'folder' | 'file' + */ + get itemType(): string { + return this._share.item_type + } + + /** + * Get the shared item mimetype + */ + get mimetype(): string { + return this._share.mimetype + } + + /** + * Get the shared item id + */ + get fileSource(): number { + return this._share.file_source + } + + /** + * Get the target path on the receiving end + * e.g the file /xxx/aaa will be shared in + * the receiving root as /aaa, the fileTarget is /aaa + */ + get fileTarget(): string { + return this._share.file_target + } + + /** + * Get the parent folder id if any + */ + get fileParent(): number { + return this._share.file_parent + } + + // PERMISSIONS Shortcuts + + /** + * Does this share have READ permissions + */ + get hasReadPermission(): boolean { + return !!((this.permissions & window.OC.PERMISSION_READ)) + } + + /** + * Does this share have CREATE permissions + */ + get hasCreatePermission(): boolean { + return !!((this.permissions & window.OC.PERMISSION_CREATE)) + } + + /** + * Does this share have DELETE permissions + */ + get hasDeletePermission(): boolean { + return !!((this.permissions & window.OC.PERMISSION_DELETE)) + } + + /** + * Does this share have UPDATE permissions + */ + get hasUpdatePermission(): boolean { + return !!((this.permissions & window.OC.PERMISSION_UPDATE)) + } + + /** + * Does this share have SHARE permissions + */ + get hasSharePermission(): boolean { + return !!((this.permissions & window.OC.PERMISSION_SHARE)) + } + + /** + * Does this share have download permissions + */ + get hasDownloadPermission(): boolean { + const hasDisabledDownload = (attribute) => { + return attribute.scope === 'permissions' && attribute.key === 'download' && attribute.value === false + } + return this.attributes.some(hasDisabledDownload) + } + + /** + * Is this mail share a file request ? + */ + get isFileRequest(): boolean { + return isFileRequest(JSON.stringify(this.attributes)) + } + + set hasDownloadPermission(enabled) { + this.setAttribute('permissions', 'download', !!enabled) + } + + setAttribute(scope, key, value) { + const attrUpdate = { + scope, + key, + value, + } + + // try and replace existing + for (const i in this._share.attributes) { + const attr = this._share.attributes[i] + if (attr.scope === attrUpdate.scope && attr.key === attrUpdate.key) { + this._share.attributes.splice(i, 1, attrUpdate) + return + } + } + + this._share.attributes.push(attrUpdate) + } + + // PERMISSIONS Shortcuts for the CURRENT USER + // ! the permissions above are the share settings, + // ! meaning the permissions for the recipient + /** + * Can the current user EDIT this share ? + */ + get canEdit(): boolean { + return this._share.can_edit === true + } + + /** + * Can the current user DELETE this share ? + */ + get canDelete(): boolean { + return this._share.can_delete === true + } + + /** + * Top level accessible shared folder fileid for the current user + */ + get viaFileid(): string { + return this._share.via_fileid + } + + /** + * Top level accessible shared folder path for the current user + */ + get viaPath(): string { + return this._share.via_path + } + + // TODO: SORT THOSE PROPERTIES + + get parent() { + return this._share.parent + } + + get storageId(): string { + return this._share.storage_id + } + + get storage(): number { + return this._share.storage + } + + get itemSource(): number { + return this._share.item_source + } + + get status() { + return this._share.status + } + + /** + * Is the share from a trusted server + */ + get isTrustedServer(): boolean { + return !!this._share.is_trusted_server + } + +} |