/** * 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] } // 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 { 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 } /** * 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 } /** * Hide the download button on public page */ set hideDownload(state: boolean) { 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 } }