aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/src/models
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_sharing/src/models')
-rw-r--r--apps/files_sharing/src/models/Share.ts (renamed from apps/files_sharing/src/models/Share.js)383
1 files changed, 110 insertions, 273 deletions
diff --git a/apps/files_sharing/src/models/Share.js b/apps/files_sharing/src/models/Share.ts
index 5504c63b345..b0638b29448 100644
--- a/apps/files_sharing/src/models/Share.js
+++ b/apps/files_sharing/src/models/Share.ts
@@ -1,30 +1,12 @@
/**
- * @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
- *
- * @author Daniel Calviño Sánchez <danxuliu@gmail.com>
- * @author Gary Kim <gary@garykim.dev>
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author John Molakvoæ <skjnldsv@protonmail.com>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0-or-later
- *
- * 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/>.
- *
+ * 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
@@ -39,15 +21,19 @@ export default class Share {
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) {
+ 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 + '"')
+ console.warn('Could not parse share attributes returned by server', ocsData.attributes)
}
}
ocsData.attributes = ocsData.attributes ?? []
@@ -64,8 +50,6 @@ export default class Share {
* state and make the whole class reactive
*
* @return {object} the share raw state
- * @readonly
- * @memberof Sidebar
*/
get state() {
return this._share
@@ -73,104 +57,69 @@ export default class Share {
/**
* get the share id
- *
- * @return {number}
- * @readonly
- * @memberof Share
*/
- get id() {
+ get id(): number {
return this._share.id
}
/**
* Get the share type
- *
- * @return {number}
- * @readonly
- * @memberof Share
*/
- get type() {
+ get type(): ShareType {
return this._share.share_type
}
/**
* Get the share permissions
- * See OC.PERMISSION_* variables
- *
- * @return {number}
- * @readonly
- * @memberof Share
+ * See window.OC.PERMISSION_* variables
*/
- get permissions() {
+ get permissions(): number {
return this._share.permissions
}
/**
* Get the share attributes
- *
- * @return {Array}
- * @readonly
- * @memberof Share
*/
- get attributes() {
- return this._share.attributes
+ get attributes(): Array<ShareAttribute> {
+ return this._share.attributes || []
}
/**
* Set the share permissions
- * See OC.PERMISSION_* variables
- *
- * @param {number} permissions valid permission, See OC.PERMISSION_* variables
- * @memberof Share
+ * See window.OC.PERMISSION_* variables
*/
- set permissions(permissions) {
+ set permissions(permissions: number) {
this._share.permissions = permissions
}
// SHARE OWNER --------------------------------------------------
/**
* Get the share owner uid
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get owner() {
+ get owner(): string {
return this._share.uid_owner
}
/**
* Get the share owner's display name
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get ownerDisplayName() {
+ get ownerDisplayName(): string {
return this._share.displayname_owner
}
// SHARED WITH --------------------------------------------------
/**
* Get the share with entity uid
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get shareWith() {
+ get shareWith(): string {
return this._share.share_with
}
/**
* Get the share with entity display name
* fallback to its uid if none
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get shareWithDisplayName() {
+ get shareWithDisplayName(): string {
return this._share.share_with_displayname
|| this._share.share_with
}
@@ -178,59 +127,39 @@ export default class Share {
/**
* Unique display name in case of multiple
* duplicates results with the same name.
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get shareWithDisplayNameUnique() {
+ get shareWithDisplayNameUnique(): string {
return this._share.share_with_displayname_unique
|| this._share.share_with
}
/**
* Get the share with entity link
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get shareWithLink() {
+ get shareWithLink(): string {
return this._share.share_with_link
}
/**
* Get the share with avatar if any
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get shareWithAvatar() {
+ get shareWithAvatar(): string {
return this._share.share_with_avatar
}
// SHARED FILE OR FOLDER OWNER ----------------------------------
/**
* Get the shared item owner uid
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get uidFileOwner() {
+ get uidFileOwner(): string {
return this._share.uid_file_owner
}
/**
* Get the shared item display name
* fallback to its uid if none
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get displaynameFileOwner() {
+ get displaynameFileOwner(): string {
return this._share.displayname_file_owner
|| this._share.uid_file_owner
}
@@ -238,230 +167,176 @@ export default class Share {
// TIME DATA ----------------------------------------------------
/**
* Get the share creation timestamp
- *
- * @return {number}
- * @readonly
- * @memberof Share
*/
- get createdTime() {
+ get createdTime(): number {
return this._share.stime
}
/**
* Get the expiration date
- *
* @return {string} date with YYYY-MM-DD format
- * @readonly
- * @memberof Share
*/
- get expireDate() {
+ get expireDate(): string {
return this._share.expiration
}
/**
* Set the expiration date
- *
* @param {string} date the share expiration date with YYYY-MM-DD format
- * @memberof Share
*/
- set expireDate(date) {
+ set expireDate(date: string) {
this._share.expiration = date
}
// EXTRA DATA ---------------------------------------------------
/**
* Get the public share token
- *
- * @return {string} the token
- * @readonly
- * @memberof Share
*/
- get 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
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get note() {
+ get note(): string {
return this._share.note
}
/**
* Set the share note if any
- *
- * @param {string} note the note
- * @memberof Share
*/
- set note(note) {
+ set note(note: string) {
this._share.note = note
}
/**
* Get the share label if any
* Should only exist on link shares
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get label() {
- return this._share.label
+ get label(): string {
+ 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) {
+ set label(label: string) {
this._share.label = label
}
/**
* Have a mail been sent
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get mailSend() {
+ get mailSend(): boolean {
return this._share.mail_send === true
}
/**
* Hide the download button on public page
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get hideDownload() {
+ 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
- *
- * @param {boolean} state hide the button ?
- * @memberof Share
*/
- set hideDownload(state) {
+ 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
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get password() {
+ get password():string {
return this._share.password
}
/**
* Password protection of the share
- *
- * @param {string} password the share password
- * @memberof Share
*/
- set password(password) {
+ set password(password: string) {
this._share.password = password
}
/**
* Password expiration time
- *
- * @return {string}
- * @readonly
- * @memberof Share
+ * @return {string} date with YYYY-MM-DD format
*/
- get passwordExpirationTime() {
+ get passwordExpirationTime(): string {
return this._share.password_expiration_time
}
/**
* Password expiration time
- *
- * @param {string} password expiration time
- * @memberof Share
+ * @param {string} passwordExpirationTime date with YYYY-MM-DD format
*/
- set passwordExpirationTime(passwordExpirationTime) {
+ set passwordExpirationTime(passwordExpirationTime: string) {
this._share.password_expiration_time = passwordExpirationTime
}
/**
* Password protection by Talk of the share
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get sendPasswordByTalk() {
+ 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
- * @memberof Share
+ * @param {boolean} sendPasswordByTalk whether to send the password by Talk or not
*/
- set sendPasswordByTalk(sendPasswordByTalk) {
+ set sendPasswordByTalk(sendPasswordByTalk: boolean) {
this._share.send_password_by_talk = sendPasswordByTalk
}
// SHARED ITEM DATA ---------------------------------------------
/**
* Get the shared item absolute full path
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get path() {
+ get path(): string {
return this._share.path
}
/**
* Return the item type: file or folder
- *
- * @return {string} 'folder' or 'file'
- * @readonly
- * @memberof Share
+ * @return {string} 'folder' | 'file'
*/
- get itemType() {
+ get itemType(): string {
return this._share.item_type
}
/**
* Get the shared item mimetype
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get mimetype() {
+ get mimetype(): string {
return this._share.mimetype
}
/**
* Get the shared item id
- *
- * @return {number}
- * @readonly
- * @memberof Share
*/
- get fileSource() {
+ get fileSource(): number {
return this._share.file_source
}
@@ -469,23 +344,15 @@ export default class Share {
* 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
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get fileTarget() {
+ get fileTarget(): string {
return this._share.file_target
}
/**
* Get the parent folder id if any
- *
- * @return {number}
- * @readonly
- * @memberof Share
*/
- get fileParent() {
+ get fileParent(): number {
return this._share.file_parent
}
@@ -493,86 +360,65 @@ export default class Share {
/**
* Does this share have READ permissions
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get hasReadPermission() {
- return !!((this.permissions & OC.PERMISSION_READ))
+ get hasReadPermission(): boolean {
+ return !!((this.permissions & window.OC.PERMISSION_READ))
}
/**
* Does this share have CREATE permissions
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get hasCreatePermission() {
- return !!((this.permissions & OC.PERMISSION_CREATE))
+ get hasCreatePermission(): boolean {
+ return !!((this.permissions & window.OC.PERMISSION_CREATE))
}
/**
* Does this share have DELETE permissions
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get hasDeletePermission() {
- return !!((this.permissions & OC.PERMISSION_DELETE))
+ get hasDeletePermission(): boolean {
+ return !!((this.permissions & window.OC.PERMISSION_DELETE))
}
/**
* Does this share have UPDATE permissions
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get hasUpdatePermission() {
- return !!((this.permissions & OC.PERMISSION_UPDATE))
+ get hasUpdatePermission(): boolean {
+ return !!((this.permissions & window.OC.PERMISSION_UPDATE))
}
/**
* Does this share have SHARE permissions
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get hasSharePermission() {
- return !!((this.permissions & OC.PERMISSION_SHARE))
+ get hasSharePermission(): boolean {
+ return !!((this.permissions & window.OC.PERMISSION_SHARE))
}
/**
* Does this share have download permissions
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get hasDownloadPermission() {
- for (const i in this._share.attributes) {
- const attr = this._share.attributes[i]
- if (attr.scope === 'permissions' && attr.key === 'download') {
- return attr.enabled
- }
+ get hasDownloadPermission(): boolean {
+ const hasDisabledDownload = (attribute) => {
+ return attribute.scope === 'permissions' && attribute.key === 'download' && attribute.value === false
}
+ return this.attributes.some(hasDisabledDownload)
+ }
- return true
+ /**
+ * 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, enabled) {
+ setAttribute(scope, key, value) {
const attrUpdate = {
scope,
key,
- enabled,
+ value,
}
// try and replace existing
@@ -592,45 +438,29 @@ export default class Share {
// ! meaning the permissions for the recipient
/**
* Can the current user EDIT this share ?
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get canEdit() {
+ get canEdit(): boolean {
return this._share.can_edit === true
}
/**
* Can the current user DELETE this share ?
- *
- * @return {boolean}
- * @readonly
- * @memberof Share
*/
- get canDelete() {
+ get canDelete(): boolean {
return this._share.can_delete === true
}
/**
* Top level accessible shared folder fileid for the current user
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get viaFileid() {
+ get viaFileid(): string {
return this._share.via_fileid
}
/**
* Top level accessible shared folder path for the current user
- *
- * @return {string}
- * @readonly
- * @memberof Share
*/
- get viaPath() {
+ get viaPath(): string {
return this._share.via_path
}
@@ -640,15 +470,15 @@ export default class Share {
return this._share.parent
}
- get storageId() {
+ get storageId(): string {
return this._share.storage_id
}
- get storage() {
+ get storage(): number {
return this._share.storage
}
- get itemSource() {
+ get itemSource(): number {
return this._share.item_source
}
@@ -656,4 +486,11 @@ export default class Share {
return this._share.status
}
+ /**
+ * Is the share from a trusted server
+ */
+ get isTrustedServer(): boolean {
+ return !!this._share.is_trusted_server
+ }
+
}