diff --git a/changelog/unreleased/enhancement-delete-public-links-passwords-when-password-is-enforced b/changelog/unreleased/enhancement-delete-public-links-passwords-when-password-is-enforced new file mode 100644 index 00000000000..9df9c4ef3c9 --- /dev/null +++ b/changelog/unreleased/enhancement-delete-public-links-passwords-when-password-is-enforced @@ -0,0 +1,8 @@ +Enhancement: Add permission to delete link passwords when password is enforced + +We've enabled to ability to allow delete passwords on public links, even if the password is enforced. +Therefore, the user needs respective permission, granted by the server. +This feature is only possible on public links that have the viewer role. + +https://github.com/owncloud/web/pull/9857 +https://github.com/owncloud/ocis/issues/7538 diff --git a/packages/web-pkg/src/helpers/share/link.ts b/packages/web-pkg/src/helpers/share/link.ts index 2caf157c77a..6ad3e6d1cbd 100644 --- a/packages/web-pkg/src/helpers/share/link.ts +++ b/packages/web-pkg/src/helpers/share/link.ts @@ -18,7 +18,6 @@ import { showQuickLinkPasswordModal } from '../../quickActions' export interface CreateQuicklink { clientService: ClientService - passwordPolicyService: PasswordPolicyService language: Language store: Store storageId?: any @@ -27,6 +26,10 @@ export interface CreateQuicklink { ability: Ability } +export interface CopyQuickLink extends CreateQuicklink { + passwordPolicyService: PasswordPolicyService +} + // doCopy creates the requested link and copies the url to the clipboard, // the copy action uses the clipboard // clipboardItem api to work around the webkit limitations. // @@ -68,12 +71,12 @@ const doCopy = async ({ }) } } -export const copyQuicklink = async (args: CreateQuicklink) => { +export const copyQuicklink = async (args: CopyQuickLink) => { const { store, language, resource, clientService, passwordPolicyService } = args const { $gettext } = language const linkSharesForResource = await clientService.owncloudSdk.shares.getShares(resource.path, { - share_types: ShareTypes.link.value.toString(), + share_types: ShareTypes?.link?.value?.toString(), include_tags: false }) diff --git a/packages/web-pkg/tests/unit/helpers/share/link.spec.ts b/packages/web-pkg/tests/unit/helpers/share/link.spec.ts index 38cfc5f97d2..65fee84f516 100644 --- a/packages/web-pkg/tests/unit/helpers/share/link.spec.ts +++ b/packages/web-pkg/tests/unit/helpers/share/link.spec.ts @@ -1,7 +1,7 @@ import { copyQuicklink, createQuicklink, CreateQuicklink } from '../../../../src/helpers/share' import { DateTime } from 'luxon' import { Store } from 'vuex' -import { ClientService } from '../../../../src/services' +import { ClientService, PasswordPolicyService } from '../../../../src/services' import { useClipboard } from '@vueuse/core' import { Ability } from '@ownclouders/web-client/src/helpers/resource/types' import { mock, mockDeep } from 'jest-mock-extended' @@ -13,6 +13,19 @@ jest.mock('@vueuse/core', () => ({ })) const mockStore = { + getters: { + capabilities: { + files_sharing: { + public: { + password: { + enforced_for: { + read_only: false + } + } + } + } + } + }, state: { user: { capabilities: { @@ -24,6 +37,11 @@ const mockStore = { expire_date: { enforced: true, days: 5 + }, + password: { + enforced_for: { + read_only: false + } } } } @@ -51,6 +69,8 @@ jest.mock('@ownclouders/web-client/src/helpers/share', () => ({ describe('createQuicklink', () => { it('should create a quicklink with the correct parameters', async () => { const clientService = mockDeep() + clientService.owncloudSdk.shares.getShares.mockResolvedValue([]) + const passwordPolicyService = mockDeep() const args: CreateQuicklink = { store: mockStore as unknown as Store, resource: mockResource, @@ -65,7 +85,7 @@ describe('createQuicklink', () => { expect(link).toBeDefined() expect(link.url).toBeDefined() - await copyQuicklink(args) + await copyQuicklink({ ...args, passwordPolicyService }) expect(useClipboard).toHaveBeenCalled() expect(mockStore.dispatch).toHaveBeenCalledWith('Files/addLink', { @@ -91,6 +111,8 @@ describe('createQuicklink', () => { 'should create a quicklink without a password if no password is provided and capabilities set to default %s', async (role) => { const clientService = mockDeep() + clientService.owncloudSdk.shares.getShares.mockResolvedValue([]) + const passwordPolicyService = mockDeep() returnBitmask = role === 'viewer' ? 1 : 0 mockStore.state.user.capabilities.files_sharing.quickLink.default_role = role @@ -107,7 +129,7 @@ describe('createQuicklink', () => { expect(link).toBeDefined() expect(link.url).toBeDefined() - await copyQuicklink(args) + await copyQuicklink({ ...args, passwordPolicyService }) expect(useClipboard).toHaveBeenCalled() expect(mockStore.dispatch).toHaveBeenCalledWith('Files/addLink', {