mirror of
https://activitypub.software/TransFem-org/Sharkey.git
synced 2024-12-17 02:49:01 +01:00
61fae45390
* feat: 通報を受けた際にメールまたはWebhookで通知を送出出来るようにする
* モデログに対応&エンドポイントを単一オブジェクトでのサポートに変更(API経由で大量に作るシチュエーションもないと思うので)
* fix spdx
* fix migration
* fix migration
* fix models
* add e2e webhook
* tweak
* fix modlog
* fix bugs
* add tests and fix bugs
* add tests and fix bugs
* add tests
* fix path
* regenerate locale
* 混入除去
* 混入除去
* add abuseReportResolved
* fix pnpm-lock.yaml
* add abuseReportResolved test
* fix bugs
* fix ui
* add tests
* fix CHANGELOG.md
* add tests
* add RoleService.getModeratorIds tests
* WebhookServiceをUserとSystemに分割
* fix CHANGELOG.md
* fix test
* insertOneを使う用に
* fix
* regenerate locales
* revert version
* separate webhook job queue
* fix
* 🎨
* Update QueueProcessorService.ts
---------
Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com>
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
217 lines
5.5 KiB
Vue
217 lines
5.5 KiB
Vue
<!--
|
|
SPDX-FileCopyrightText: syuilo and misskey-project
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
-->
|
|
|
|
<template>
|
|
<MkModalWindow
|
|
:width="450"
|
|
:height="590"
|
|
:canClose="true"
|
|
:withOkButton="false"
|
|
:okButtonDisabled="false"
|
|
@click="onCancelClicked"
|
|
@close="onCancelClicked"
|
|
@closed="onCancelClicked"
|
|
>
|
|
<template #header>
|
|
{{ mode === 'create' ? i18n.ts._webhookSettings.createWebhook : i18n.ts._webhookSettings.modifyWebhook }}
|
|
</template>
|
|
<MkSpacer :marginMin="20" :marginMax="28">
|
|
<MkLoading v-if="loading !== 0"/>
|
|
<div v-else :class="$style.root" class="_gaps_m">
|
|
<MkInput v-model="title">
|
|
<template #label>{{ i18n.ts._webhookSettings.name }}</template>
|
|
</MkInput>
|
|
<MkInput v-model="url">
|
|
<template #label>URL</template>
|
|
</MkInput>
|
|
<MkInput v-model="secret">
|
|
<template #label>{{ i18n.ts._webhookSettings.secret }}</template>
|
|
</MkInput>
|
|
<MkFolder :defaultOpen="true">
|
|
<template #label>{{ i18n.ts._webhookSettings.events }}</template>
|
|
|
|
<div class="_gaps_s">
|
|
<MkSwitch v-model="events.abuseReport" :disabled="disabledEvents.abuseReport">
|
|
<template #label>{{ i18n.ts._webhookSettings._systemEvents.abuseReport }}</template>
|
|
</MkSwitch>
|
|
<MkSwitch v-model="events.abuseReportResolved" :disabled="disabledEvents.abuseReportResolved">
|
|
<template #label>{{ i18n.ts._webhookSettings._systemEvents.abuseReportResolved }}</template>
|
|
</MkSwitch>
|
|
</div>
|
|
</MkFolder>
|
|
|
|
<MkSwitch v-model="isActive">
|
|
<template #label>{{ i18n.ts.enable }}</template>
|
|
</MkSwitch>
|
|
|
|
<div :class="$style.footer" class="_buttonsCenter">
|
|
<MkButton primary :disabled="disableSubmitButton" @click="onSubmitClicked">
|
|
<i class="ti ti-check"></i>
|
|
{{ i18n.ts.ok }}
|
|
</MkButton>
|
|
<MkButton @click="onCancelClicked"><i class="ti ti-x"></i> {{ i18n.ts.cancel }}</MkButton>
|
|
</div>
|
|
</div>
|
|
</MkSpacer>
|
|
</MkModalWindow>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, onMounted, ref, toRefs } from 'vue';
|
|
import FormSection from '@/components/form/section.vue';
|
|
import MkInput from '@/components/MkInput.vue';
|
|
import MkSwitch from '@/components/MkSwitch.vue';
|
|
import {
|
|
MkSystemWebhookEditorProps,
|
|
MkSystemWebhookResult,
|
|
SystemWebhookEventType,
|
|
} from '@/components/MkSystemWebhookEditor.impl.js';
|
|
import { i18n } from '@/i18n.js';
|
|
import MkButton from '@/components/MkButton.vue';
|
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
|
import MkModalWindow from '@/components/MkModalWindow.vue';
|
|
import MkFolder from '@/components/MkFolder.vue';
|
|
import * as os from '@/os.js';
|
|
|
|
type EventType = {
|
|
abuseReport: boolean;
|
|
abuseReportResolved: boolean;
|
|
}
|
|
|
|
const emit = defineEmits<{
|
|
(ev: 'submitted', result: MkSystemWebhookResult): void;
|
|
(ev: 'closed'): void;
|
|
}>();
|
|
|
|
const props = defineProps<MkSystemWebhookEditorProps>();
|
|
|
|
const { mode, id, requiredEvents } = toRefs(props);
|
|
|
|
const loading = ref<number>(0);
|
|
|
|
const title = ref<string>('');
|
|
const url = ref<string>('');
|
|
const secret = ref<string>('');
|
|
const events = ref<EventType>({
|
|
abuseReport: true,
|
|
abuseReportResolved: true,
|
|
});
|
|
const isActive = ref<boolean>(true);
|
|
|
|
const disabledEvents = ref<EventType>({
|
|
abuseReport: false,
|
|
abuseReportResolved: false,
|
|
});
|
|
|
|
const disableSubmitButton = computed(() => {
|
|
if (!title.value) {
|
|
return true;
|
|
}
|
|
if (!url.value) {
|
|
return true;
|
|
}
|
|
if (!secret.value) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
async function onSubmitClicked() {
|
|
await loadingScope(async () => {
|
|
const params = {
|
|
isActive: isActive.value,
|
|
name: title.value,
|
|
url: url.value,
|
|
secret: secret.value,
|
|
on: Object.keys(events.value).filter(ev => events.value[ev as keyof EventType]) as SystemWebhookEventType[],
|
|
};
|
|
|
|
try {
|
|
switch (mode.value) {
|
|
case 'create': {
|
|
const result = await misskeyApi('admin/system-webhook/create', params);
|
|
emit('submitted', result);
|
|
break;
|
|
}
|
|
case 'edit': {
|
|
// eslint-disable-next-line
|
|
const result = await misskeyApi('admin/system-webhook/update', { id: id.value!, ...params });
|
|
emit('submitted', result);
|
|
break;
|
|
}
|
|
}
|
|
// eslint-disable-next-line
|
|
} catch (ex: any) {
|
|
const msg = ex.message ?? i18n.ts.internalServerErrorDescription;
|
|
await os.alert({ type: 'error', title: i18n.ts.error, text: msg });
|
|
emit('closed');
|
|
}
|
|
});
|
|
}
|
|
|
|
function onCancelClicked() {
|
|
emit('closed');
|
|
}
|
|
|
|
async function loadingScope<T>(fn: () => Promise<T>): Promise<T> {
|
|
loading.value++;
|
|
try {
|
|
return await fn();
|
|
} finally {
|
|
loading.value--;
|
|
}
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await loadingScope(async () => {
|
|
switch (mode.value) {
|
|
case 'edit': {
|
|
if (!id.value) {
|
|
throw new Error('id is required');
|
|
}
|
|
|
|
try {
|
|
const res = await misskeyApi('admin/system-webhook/show', { id: id.value });
|
|
|
|
title.value = res.name;
|
|
url.value = res.url;
|
|
secret.value = res.secret;
|
|
isActive.value = res.isActive;
|
|
for (const ev of Object.keys(events.value)) {
|
|
events.value[ev] = res.on.includes(ev as SystemWebhookEventType);
|
|
}
|
|
// eslint-disable-next-line
|
|
} catch (ex: any) {
|
|
const msg = ex.message ?? i18n.ts.internalServerErrorDescription;
|
|
await os.alert({ type: 'error', title: i18n.ts.error, text: msg });
|
|
emit('closed');
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (const ev of requiredEvents.value ?? []) {
|
|
disabledEvents.value[ev] = true;
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<style module lang="scss">
|
|
.root {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.footer {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: flex-end;
|
|
margin-top: 20px;
|
|
}
|
|
</style>
|