aboutsummaryrefslogtreecommitdiffstats
path: root/core/src/components/PublicPageMenu/PublicPageMenuExternalDialog.vue
blob: 0f02bdf7524631fc7cd671e732ed99948d546684 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<!--
 - SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
 - SPDX-License-Identifier: AGPL-3.0-or-later
 -->
<template>
	<NcDialog is-form
		:name="label"
		:open.sync="open"
		@submit="createFederatedShare">
		<NcTextField ref="input"
			:label="t('core', 'Federated user')"
			:placeholder="t('core', 'user@your-nextcloud.org')"
			required
			:value.sync="remoteUrl" />
		<template #actions>
			<NcButton :disabled="loading" type="primary" native-type="submit">
				<template v-if="loading" #icon>
					<NcLoadingIcon />
				</template>
				{{ t('core', 'Create share') }}
			</NcButton>
		</template>
	</NcDialog>
</template>

<script setup lang="ts">
import type Vue from 'vue'

import { t } from '@nextcloud/l10n'
import { showError } from '@nextcloud/dialogs'
import { generateUrl } from '@nextcloud/router'
import { getSharingToken } from '@nextcloud/sharing/public'
import { nextTick, onMounted, ref, watch } from 'vue'
import axios from '@nextcloud/axios'
import NcButton from '@nextcloud/vue/components/NcButton'
import NcDialog from '@nextcloud/vue/components/NcDialog'
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
import NcTextField from '@nextcloud/vue/components/NcTextField'
import logger from '../../logger'

defineProps<{
	label: string
}>()

const loading = ref(false)
const remoteUrl = ref('')
// Todo: @nextcloud/vue should expose the types correctly
const input = ref<Vue & { focus: () => void }>()
const open = ref(true)

// Focus when mounted
onMounted(() => nextTick(() => input.value!.focus()))

// Check validity
watch(remoteUrl, () => {
	let validity = ''
	if (!remoteUrl.value.includes('@')) {
		validity = t('core', 'The remote URL must include the user.')
	} else if (!remoteUrl.value.match(/@(.+\..{2,}|localhost)(:\d\d+)?$/)) {
		validity = t('core', 'Invalid remote URL.')
	}
	input.value!.$el.querySelector('input')!.setCustomValidity(validity)
	input.value!.$el.querySelector('input')!.reportValidity()
})

/**
 * Create a federated share for the current share
 */
async function createFederatedShare() {
	loading.value = true

	try {
		const url = generateUrl('/apps/federatedfilesharing/createFederatedShare')
		const { data } = await axios.post<{ remoteUrl: string }>(url, {
			shareWith: remoteUrl.value,
			token: getSharingToken(),
		})
		if (data.remoteUrl.includes('://')) {
			window.location.href = data.remoteUrl
		} else {
			window.location.href = `${window.location.protocol}//${data.remoteUrl}`
		}
	} catch (error) {
		logger.error('Failed to create federated share', { error })
		showError(t('files_sharing', 'Failed to add the public link to your Nextcloud'))
	} finally {
		loading.value = false
	}
}
</script>