21
21
-->
22
22
23
23
<template>
24
- <section id="general_settings " class="federation section">
24
+ <section id="federation_settings " class="federation section">
25
25
<h2>
26
26
{{ t('spreed', 'Federation') }}
27
27
<small>{{ t('spreed', 'Beta') }}</small>
33
33
@update:checked="saveFederationEnabled">
34
34
{{ t('spreed', 'Enable Federation in Talk app') }}
35
35
</NcCheckboxRadioSwitch>
36
+
37
+ <template v-if="isFederationEnabled">
38
+ <h3>{{ t('spreed', 'Permissions') }}</h3>
39
+
40
+ <NcCheckboxRadioSwitch :checked="isFederationIncomingEnabled"
41
+ :disabled="loading"
42
+ type="switch"
43
+ @update:checked="saveFederationIncomingEnabled">
44
+ {{ t('spreed', 'Allow users to be invited to federated conversations') }}
45
+ </NcCheckboxRadioSwitch>
46
+
47
+ <NcCheckboxRadioSwitch :checked="isFederationOutgoingEnabled"
48
+ :disabled="loading"
49
+ type="switch"
50
+ @update:checked="saveFederationOutgoingEnabled">
51
+ {{ t('spreed', 'Allow users to invite federated users into conversation') }}
52
+ </NcCheckboxRadioSwitch>
53
+
54
+ <NcCheckboxRadioSwitch :checked="isFederationOnlyTrustedServersEnabled"
55
+ :disabled="loading"
56
+ type="switch"
57
+ @update:checked="saveFederationOnlyTrustedServersEnabled">
58
+ {{ t('spreed', 'Only allow to federate with trusted servers') }}
59
+ </NcCheckboxRadioSwitch>
60
+ <!-- eslint-disable-next-line vue/no-v-html -->
61
+ <p class="settings-hint additional-top-margin" v-html="trustedServersLink" />
62
+
63
+ <h3>{{ t('spreed', 'Limit to groups') }}</h3>
64
+
65
+ <p class="settings-hint additional-top-margin">
66
+ {{ t('spreed', 'When at least one group is selected, only people of the listed groups can invite federated users to conversations.') }}
67
+ </p>
68
+
69
+ <div class="form">
70
+ <NcSelect v-model="allowedGroups"
71
+ input-id="allow_groups_invite_federated"
72
+ :input-label="t('spreed', 'Groups allowed to invite federated users')"
73
+ name="allow_groups_invite_federated"
74
+ class="form__select"
75
+ :options="groups"
76
+ :placeholder="t('spreed', 'Select groups …')"
77
+ :disabled="loading"
78
+ multiple
79
+ searchable
80
+ :tag-width="60"
81
+ :loading="loadingGroups"
82
+ :show-no-options="false"
83
+ :close-on-select="false"
84
+ track-by="id"
85
+ label="displayname"
86
+ no-wrap
87
+ @search-change="debounceSearchGroup" />
88
+
89
+ <NcButton type="primary"
90
+ :disabled="loading"
91
+ @click="saveAllowedGroups">
92
+ {{ saveLabelAllowedGroups }}
93
+ </NcButton>
94
+ </div>
95
+ </template>
36
96
</section>
37
97
</template>
38
98
39
99
<script>
100
+ import debounce from 'debounce'
101
+
102
+ import axios from '@nextcloud/axios'
40
103
import { loadState } from '@nextcloud/initial-state'
104
+ import { generateOcsUrl, generateUrl } from '@nextcloud/router'
41
105
106
+ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
42
107
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
108
+ import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
109
+
110
+ const FEDERATION_ENABLED = loadState('spreed', 'federation_enabled', 'no') === 'yes'
111
+ const FEDERATION_INCOMING_ENABLED = loadState('spreed', 'federation_incoming_enabled', '0') === '1'
112
+ const FEDERATION_OUTGOING_ENABLED = loadState('spreed', 'federation_outgoing_enabled', '0') === '1'
113
+ const FEDERATION_ONLY_TRUSTED_SERVERS = loadState('spreed', 'federation_only_trusted_servers', '0') === '1'
114
+ const FEDERATION_ALLOWED_GROUPS = JSON.parse(loadState('spreed', 'federation_allowed_groups', '[]'))
43
115
44
116
export default {
45
117
name: 'Federation',
46
118
47
119
components: {
120
+ NcButton,
48
121
NcCheckboxRadioSwitch,
122
+ NcSelect,
49
123
},
50
124
51
125
data() {
52
126
return {
53
127
loading: false,
54
- isFederationEnabled: loadState('spreed', 'federation_enabled') === 'yes',
128
+ isFederationEnabled: FEDERATION_ENABLED,
129
+ isFederationIncomingEnabled: FEDERATION_INCOMING_ENABLED,
130
+ isFederationOutgoingEnabled: FEDERATION_OUTGOING_ENABLED,
131
+ isFederationOnlyTrustedServersEnabled: FEDERATION_ONLY_TRUSTED_SERVERS,
132
+ loadingGroups: false,
133
+ groups: [],
134
+ allowedGroups: [],
135
+ saveLabelAllowedGroups: t('spreed', 'Save changes'),
136
+ debounceSearchGroup: () => {},
55
137
}
56
138
},
57
139
140
+ computed: {
141
+ trustedServersLink() {
142
+ const href = generateUrl('/settings/admin/sharing#ocFederationSettings')
143
+ return t('spreed', 'Trusted servers can be configured at {linkstart}Sharing settings page{linkend}.')
144
+ .replace('{linkstart}', `<a target="_blank" rel="noreferrer nofollow" class="external" href="${href}">`)
145
+ .replaceAll('{linkend}', ' ↗</a>')
146
+ },
147
+ },
148
+
149
+ mounted() {
150
+ // allowed groups come as an array of string ids here
151
+ this.allowedGroups = FEDERATION_ALLOWED_GROUPS.sort((a, b) => a.localeCompare(b))
152
+ this.debounceSearchGroup = debounce(this.searchGroup, 500)
153
+ this.debounceSearchGroup('')
154
+ },
155
+
156
+ beforeDestroy() {
157
+ this.debounceSearchGroup.clear?.()
158
+ },
159
+
58
160
methods: {
59
161
saveFederationEnabled(value) {
60
162
this.loading = true
@@ -66,6 +168,80 @@ export default {
66
168
}.bind(this),
67
169
})
68
170
},
171
+
172
+ saveFederationIncomingEnabled(value) {
173
+ this.loading = true
174
+
175
+ OCP.AppConfig.setValue('spreed', 'federation_incoming_enabled', value ? '1' : '0', {
176
+ success: function() {
177
+ this.loading = false
178
+ this.isFederationIncomingEnabled = value
179
+ }.bind(this),
180
+ })
181
+ },
182
+
183
+ saveFederationOutgoingEnabled(value) {
184
+ this.loading = true
185
+
186
+ OCP.AppConfig.setValue('spreed', 'federation_outgoing_enabled', value ? '1' : '0', {
187
+ success: function() {
188
+ this.loading = false
189
+ this.isFederationOutgoingEnabled = value
190
+ }.bind(this),
191
+ })
192
+ },
193
+
194
+ saveFederationOnlyTrustedServersEnabled(value) {
195
+ this.loading = true
196
+
197
+ OCP.AppConfig.setValue('spreed', 'federation_only_trusted_servers', value ? '1' : '0', {
198
+ success: function() {
199
+ this.loading = false
200
+ this.isFederationOnlyTrustedServersEnabled = value
201
+ }.bind(this),
202
+ })
203
+ },
204
+
205
+ async searchGroup(query) {
206
+ this.loadingGroups = true
207
+ try {
208
+ const response = await axios.get(generateOcsUrl('cloud/groups/details'), {
209
+ search: query,
210
+ limit: 20,
211
+ offset: 0,
212
+ })
213
+ this.groups = response.data.ocs.data.groups.sort(function(a, b) {
214
+ return a.displayname.localeCompare(b.displayname)
215
+ })
216
+
217
+ // repopulate allowed groups with full group objects to show display name
218
+ const allowedGroupIds = this.allowedGroups.map(group => typeof group === 'object' ? group.id : group)
219
+ this.allowedGroups = this.groups.filter(group => allowedGroupIds.includes(group.id))
220
+ } catch (err) {
221
+ console.error('Could not fetch groups', err)
222
+ } finally {
223
+ this.loadingGroups = false
224
+ }
225
+ },
226
+
227
+ saveAllowedGroups() {
228
+ this.loading = true
229
+ this.loadingGroups = true
230
+ this.saveLabelAllowedGroups = t('spreed', 'Saving …')
231
+
232
+ const groups = this.allowedGroups.map(group => typeof group === 'object' ? group.id : group)
233
+
234
+ OCP.AppConfig.setValue('spreed', 'federation_allowed_groups', JSON.stringify(groups), {
235
+ success: function() {
236
+ this.loading = false
237
+ this.loadingGroups = false
238
+ this.saveLabelAllowedGroups = t('spreed', 'Saved!')
239
+ setTimeout(function() {
240
+ this.saveLabelAllowedGroups = t('spreed', 'Save changes')
241
+ }.bind(this), 5000)
242
+ }.bind(this),
243
+ })
244
+ },
69
245
},
70
246
}
71
247
</script>
@@ -77,4 +253,24 @@ small {
77
253
border-radius: 16px;
78
254
padding: 0 9px;
79
255
}
256
+
257
+ h3 {
258
+ margin-top: 24px;
259
+ font-weight: bold;
260
+ }
261
+
262
+ .additional-top-margin {
263
+ margin-top: 10px;
264
+ }
265
+
266
+ .form {
267
+ display: flex;
268
+ align-items: flex-end;
269
+ gap: 10px;
270
+ padding-top: 5px;
271
+
272
+ &__select {
273
+ min-width: 300px !important;
274
+ }
275
+ }
80
276
</style>
0 commit comments