mirror of
https://github.com/nextcloud/server.git
synced 2026-06-08 16:26:59 -04:00
fix(files_sharing): do not double escape the share title
The title is already escaped by vue so special characters would result in incorrect strings. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
3cf84b7a0f
commit
ae3027f852
2 changed files with 74 additions and 29 deletions
|
|
@ -217,22 +217,23 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { generateUrl, getBaseUrl } from '@nextcloud/router'
|
||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
||||
import { ShareType } from '@nextcloud/sharing'
|
||||
import VueQrcode from '@chenfengyuan/vue-qrcode'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import moment from '@nextcloud/moment'
|
||||
import { generateUrl, getBaseUrl } from '@nextcloud/router'
|
||||
import { ShareType } from '@nextcloud/sharing'
|
||||
|
||||
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
|
||||
import NcActionCheckbox from '@nextcloud/vue/dist/Components/NcActionCheckbox.js'
|
||||
import NcActionInput from '@nextcloud/vue/dist/Components/NcActionInput.js'
|
||||
import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
|
||||
import NcActionText from '@nextcloud/vue/dist/Components/NcActionText.js'
|
||||
import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.js'
|
||||
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
|
||||
import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js'
|
||||
import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'
|
||||
import VueQrcode from '@chenfengyuan/vue-qrcode'
|
||||
import NcActionButton from '@nextcloud/vue/components/NcActionButton'
|
||||
import NcActionCheckbox from '@nextcloud/vue/components/NcActionCheckbox'
|
||||
import NcActionInput from '@nextcloud/vue/components/NcActionInput'
|
||||
import NcActionLink from '@nextcloud/vue/components/NcActionLink'
|
||||
import NcActionText from '@nextcloud/vue/components/NcActionText'
|
||||
import NcActionSeparator from '@nextcloud/vue/components/NcActionSeparator'
|
||||
import NcActions from '@nextcloud/vue/components/NcActions'
|
||||
import NcAvatar from '@nextcloud/vue/components/NcAvatar'
|
||||
import NcDialog from '@nextcloud/vue/components/NcDialog'
|
||||
|
||||
import Tune from 'vue-material-design-icons/Tune.vue'
|
||||
import IconCalendarBlank from 'vue-material-design-icons/CalendarBlank.vue'
|
||||
|
|
@ -251,7 +252,7 @@ import GeneratePassword from '../utils/GeneratePassword.ts'
|
|||
import Share from '../models/Share.ts'
|
||||
import SharesMixin from '../mixins/SharesMixin.js'
|
||||
import ShareDetails from '../mixins/ShareDetails.js'
|
||||
import { getLoggerBuilder } from '@nextcloud/logger'
|
||||
import logger from '../services/logger.ts'
|
||||
|
||||
export default {
|
||||
name: 'SharingEntryLink',
|
||||
|
|
@ -305,10 +306,6 @@ export default {
|
|||
|
||||
ExternalLegacyLinkActions: OCA.Sharing.ExternalLinkActions.state,
|
||||
ExternalShareActions: OCA.Sharing.ExternalShareActions.state,
|
||||
logger: getLoggerBuilder()
|
||||
.setApp('files_sharing')
|
||||
.detectUser()
|
||||
.build(),
|
||||
|
||||
// tracks whether modal should be opened or not
|
||||
showQRCode: false,
|
||||
|
|
@ -322,6 +319,8 @@ export default {
|
|||
* @return {string}
|
||||
*/
|
||||
title() {
|
||||
const l10nOptions = { escape: false /* no escape as this string is already escaped by Vue */ }
|
||||
|
||||
// if we have a valid existing share (not pending)
|
||||
if (this.share && this.share.id) {
|
||||
if (!this.isShareOwner && this.share.ownerDisplayName) {
|
||||
|
|
@ -329,26 +328,26 @@ export default {
|
|||
return t('files_sharing', '{shareWith} by {initiator}', {
|
||||
shareWith: this.share.shareWith,
|
||||
initiator: this.share.ownerDisplayName,
|
||||
})
|
||||
}, l10nOptions)
|
||||
}
|
||||
return t('files_sharing', 'Shared via link by {initiator}', {
|
||||
initiator: this.share.ownerDisplayName,
|
||||
})
|
||||
}, l10nOptions)
|
||||
}
|
||||
if (this.share.label && this.share.label.trim() !== '') {
|
||||
if (this.isEmailShareType) {
|
||||
if (this.isFileRequest) {
|
||||
return t('files_sharing', 'File request ({label})', {
|
||||
label: this.share.label.trim(),
|
||||
})
|
||||
}, l10nOptions)
|
||||
}
|
||||
return t('files_sharing', 'Mail share ({label})', {
|
||||
label: this.share.label.trim(),
|
||||
})
|
||||
}, l10nOptions)
|
||||
}
|
||||
return t('files_sharing', 'Share link ({label})', {
|
||||
label: this.share.label.trim(),
|
||||
})
|
||||
}, l10nOptions)
|
||||
}
|
||||
if (this.isEmailShareType) {
|
||||
if (!this.share.shareWith || this.share.shareWith.trim() === '') {
|
||||
|
|
@ -383,6 +382,7 @@ export default {
|
|||
}
|
||||
return null
|
||||
},
|
||||
|
||||
passwordExpirationTime() {
|
||||
if (this.share.passwordExpirationTime === null) {
|
||||
return null
|
||||
|
|
@ -605,7 +605,7 @@ export default {
|
|||
* @param {boolean} shareReviewComplete if the share was reviewed
|
||||
*/
|
||||
async onNewLinkShare(shareReviewComplete = false) {
|
||||
this.logger.debug('onNewLinkShare called (with this.share)', this.share)
|
||||
logger.debug('onNewLinkShare called (with this.share)', this.share)
|
||||
// do not run again if already loading
|
||||
if (this.loading) {
|
||||
return
|
||||
|
|
@ -620,7 +620,7 @@ export default {
|
|||
shareDefaults.expiration = this.formatDateToString(this.config.defaultExpirationDate)
|
||||
}
|
||||
|
||||
this.logger.debug('Missing required properties?', this.enforcedPropertiesMissing)
|
||||
logger.debug('Missing required properties?', this.enforcedPropertiesMissing)
|
||||
// Do not push yet if we need a password or an expiration date: show pending menu
|
||||
// A share would require a review for example is default expiration date is set but not enforced, this allows
|
||||
// the user to review the share and remove the expiration date if they don't want it
|
||||
|
|
@ -628,7 +628,7 @@ export default {
|
|||
this.pending = true
|
||||
this.shareCreationComplete = false
|
||||
|
||||
this.logger.info('Share policy requires a review or has mandated properties (password, expirationDate)...')
|
||||
logger.info('Share policy requires a review or has mandated properties (password, expirationDate)...')
|
||||
|
||||
// ELSE, show the pending popovermenu
|
||||
// if password default or enforced, pre-fill with random one
|
||||
|
|
@ -656,13 +656,13 @@ export default {
|
|||
// if the share is valid, create it on the server
|
||||
if (this.checkShare(this.share)) {
|
||||
try {
|
||||
this.logger.info('Sending existing share to server', this.share)
|
||||
logger.info('Sending existing share to server', this.share)
|
||||
await this.pushNewLinkShare(this.share, true)
|
||||
this.shareCreationComplete = true
|
||||
this.logger.info('Share created on server', this.share)
|
||||
logger.info('Share created on server', this.share)
|
||||
} catch (e) {
|
||||
this.pending = false
|
||||
this.logger.error('Error creating share', e)
|
||||
logger.error('Error creating share', e)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
|
|
|||
45
cypress/e2e/files_sharing/public-share/sidebar-tab.cy.ts
Normal file
45
cypress/e2e/files_sharing/public-share/sidebar-tab.cy.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*!
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import type { User } from "@nextcloud/cypress"
|
||||
import { createShare } from "./FilesSharingUtils"
|
||||
import { createLinkShare, openLinkShareDetails } from "./PublicShareUtils"
|
||||
|
||||
describe('files_sharing: sidebar tab', () => {
|
||||
let alice: User
|
||||
|
||||
beforeEach(() => {
|
||||
cy.createRandomUser()
|
||||
.then((user) => {
|
||||
alice = user
|
||||
cy.mkdir(user, '/test')
|
||||
cy.login(user)
|
||||
cy.visit('/apps/files')
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Regression tests of https://github.com/nextcloud/server/issues/53566
|
||||
* Where the ' char was shown as '
|
||||
*/
|
||||
it('correctly lists shares by label with special characters', () => {
|
||||
createLinkShare({ user: alice }, 'test')
|
||||
openLinkShareDetails(0)
|
||||
cy.findByRole('textbox', { name: /share label/i })
|
||||
.should('be.visible')
|
||||
.type('Alice\' share')
|
||||
|
||||
cy.intercept('PUT', '**/ocs/v2.php/apps/files_sharing/api/v1/shares/*').as('PUT')
|
||||
cy.findByRole('button', { name: /update share/i }).click()
|
||||
cy.wait('@PUT')
|
||||
|
||||
// see the label is shown correctly
|
||||
cy.findByRole('list', { name: /link shares/i })
|
||||
.findAllByRole('listitem')
|
||||
.should('have.length', 1)
|
||||
.first()
|
||||
.should('contain.text', 'Share link (Alice\' share)')
|
||||
})
|
||||
})
|
||||
Loading…
Reference in a new issue