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>
|