diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index c3bb4f7756..9390af40a9 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1486,6 +1486,8 @@ admin/views/federation.vue: chart-spans: hour: "1時間ごと" day: "1日ごと" + blocked-hosts: "ブロック" + blocked-hosts-info: "ブロックしたいホストを改行で区切って記述します。" desktop/views/pages/welcome.vue: about: "詳しく..." diff --git a/src/client/app/admin/views/federation.vue b/src/client/app/admin/views/federation.vue index 25400393b9..4d0b4b7c77 100644 --- a/src/client/app/admin/views/federation.vue +++ b/src/client/app/admin/views/federation.vue @@ -54,7 +54,6 @@ <span>{{ $t('latest-request-received-at') }}</span> <template #prefix><fa :icon="faInbox"/></template> </ui-input> - <ui-switch v-model="instance.isBlocked" @change="updateInstance()">{{ $t('block') }}</ui-switch> <ui-switch v-model="instance.isMarkedAsClosed" @change="updateInstance()">{{ $t('marked-as-closed') }}</ui-switch> <details> <summary>{{ $t('charts') }}</summary> @@ -142,6 +141,16 @@ <ui-info v-if="instances.length == limit">{{ $t('result-is-truncated', { n: limit }) }}</ui-info> </section> </ui-card> + + <ui-card> + <template #title><fa :icon="faBan"/> {{ $t('blocked-hosts') }}</template> + <section class="fit-top"> + <ui-textarea v-model="blockedHosts"> + <template #desc>{{ $t('blocked-hosts-info') }}</template> + </ui-textarea> + <ui-button @click="saveBlockedHosts">{{ $t('save') }}</ui-button> + </section> + </ui-card> </div> </template> @@ -149,7 +158,7 @@ import Vue from 'vue'; import i18n from '../../i18n'; import { faPaperPlane } from '@fortawesome/free-regular-svg-icons'; -import { faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faTrafficLight, faInbox } from '@fortawesome/free-solid-svg-icons'; +import { faBan, faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faTrafficLight, faInbox } from '@fortawesome/free-solid-svg-icons'; import ApexCharts from 'apexcharts'; import * as tinycolor from 'tinycolor2'; @@ -176,7 +185,8 @@ export default Vue.extend({ chartSrc: 'requests', chartSpan: 'hour', chartInstance: null, - faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faPaperPlane, faTrafficLight, faInbox + blockedHosts: '', + faBan, faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faPaperPlane, faTrafficLight, faInbox }; }, @@ -246,6 +256,10 @@ export default Vue.extend({ mounted() { this.fetchInstances(); + + this.$root.getMeta().then(meta => { + this.blockedHosts = meta.blockedHosts.join('\n'); + }); }, beforeDestroy() { @@ -477,6 +491,22 @@ export default Vue.extend({ }] }; }, + + saveBlockedHosts() { + this.$root.api('admin/update-meta', { + blockedHosts: this.blockedHosts.split('\n') + }).then(() => { + this.$root.dialog({ + type: 'success', + text: this.$t('saved') + }); + }).catch(e => { + this.$root.dialog({ + type: 'error', + text: e + }); + }); + } } }); </script> diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts index e34840e907..e4f2e86aaa 100644 --- a/src/server/api/endpoints/admin/update-meta.ts +++ b/src/server/api/endpoints/admin/update-meta.ts @@ -70,6 +70,13 @@ export const meta = { } }, + blockedHosts: { + validator: $.optional.nullable.arr($.str), + desc: { + 'ja-JP': 'ブロックするホスト' + } + }, + mascotImageUrl: { validator: $.optional.nullable.str, desc: { @@ -389,6 +396,10 @@ export default define(meta, async (ps) => { set.hiddenTags = ps.hiddenTags; } + if (Array.isArray(ps.blockedHosts)) { + set.blockedHosts = ps.blockedHosts; + } + if (ps.mascotImageUrl !== undefined) { set.mascotImageUrl = ps.mascotImageUrl; } diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts index e29edae266..1bd88a1e6d 100644 --- a/src/server/api/endpoints/meta.ts +++ b/src/server/api/endpoints/meta.ts @@ -165,6 +165,7 @@ export default define(meta, async (ps, me) => { response.useStarForReactionFallback = instance.useStarForReactionFallback; response.pinnedUsers = instance.pinnedUsers; response.hiddenTags = instance.hiddenTags; + response.blockedHosts = instance.blockedHosts; response.recaptchaSecretKey = instance.recaptchaSecretKey; response.proxyAccount = instance.proxyAccount; response.twitterConsumerKey = instance.twitterConsumerKey;