enhance: サーバーのお問い合わせ先URLを設定できるように

This commit is contained in:
syuilo 2024-05-31 10:12:23 +09:00
parent ac4a001e9f
commit be11fd7508
13 changed files with 88 additions and 7 deletions

View file

@ -20,6 +20,7 @@
- Enhance: Goneを出さずに終了したサーバーへの配信停止を自動的に行うように - Enhance: Goneを出さずに終了したサーバーへの配信停止を自動的に行うように
- もしそのようなサーバーからから配信が届いた場合には自動的に配信を再開します - もしそのようなサーバーからから配信が届いた場合には自動的に配信を再開します
- Enhance: 配信停止の理由を表示するように - Enhance: 配信停止の理由を表示するように
- Enhance: サーバーのお問い合わせ先URLを設定できるようになりました
- Fix: Play作成時に設定した公開範囲が機能していない問題を修正 - Fix: Play作成時に設定した公開範囲が機能していない問題を修正
- Fix: 正規化されていない状態のhashtagが連合されてきたhtmlに含まれているとhashtagが正しくhashtagに復元されない問題を修正 - Fix: 正規化されていない状態のhashtagが連合されてきたhtmlに含まれているとhashtagが正しくhashtagに復元されない問題を修正
- Fix: みつけるのアンケート欄にてチャンネルのアンケートが含まれてしまう問題を修正 - Fix: みつけるのアンケート欄にてチャンネルのアンケートが含まれてしまう問題を修正

8
locales/index.d.ts vendored
View file

@ -5471,6 +5471,14 @@ export interface Locale extends ILocale {
* DBへ追加で問い合わせを行うフォールバック処理を行います * DBへ追加で問い合わせを行うフォールバック処理を行います
*/ */
"fanoutTimelineDbFallbackDescription": string; "fanoutTimelineDbFallbackDescription": string;
/**
* URL
*/
"inquiryUrl": string;
/**
* URLやWebページのURLを指定します
*/
"inquiryUrlDescription": string;
}; };
"_accountMigration": { "_accountMigration": {
/** /**

View file

@ -1383,6 +1383,8 @@ _serverSettings:
fanoutTimelineDescription: "有効にすると、各種タイムラインを取得する際のパフォーマンスが大幅に向上し、データベースへの負荷を軽減することが可能です。ただし、Redisのメモリ使用量は増加します。サーバーのメモリ容量が少ない場合、または動作が不安定な場合は無効にすることができます。" fanoutTimelineDescription: "有効にすると、各種タイムラインを取得する際のパフォーマンスが大幅に向上し、データベースへの負荷を軽減することが可能です。ただし、Redisのメモリ使用量は増加します。サーバーのメモリ容量が少ない場合、または動作が不安定な場合は無効にすることができます。"
fanoutTimelineDbFallback: "データベースへのフォールバック" fanoutTimelineDbFallback: "データベースへのフォールバック"
fanoutTimelineDbFallbackDescription: "有効にすると、タイムラインがキャッシュされていない場合にDBへ追加で問い合わせを行うフォールバック処理を行います。無効にすると、フォールバック処理を行わないことでさらにサーバーの負荷を軽減することができますが、タイムラインが取得できる範囲に制限が生じます。" fanoutTimelineDbFallbackDescription: "有効にすると、タイムラインがキャッシュされていない場合にDBへ追加で問い合わせを行うフォールバック処理を行います。無効にすると、フォールバック処理を行わないことでさらにサーバーの負荷を軽減することができますが、タイムラインが取得できる範囲に制限が生じます。"
inquiryUrl: "問い合わせ先URL"
inquiryUrlDescription: "サーバー運営者へのお問い合わせフォームのURLや、運営者の連絡先等が記載されたWebページのURLを指定します。"
_accountMigration: _accountMigration:
moveFrom: "別のアカウントからこのアカウントに移行" moveFrom: "別のアカウントからこのアカウントに移行"

View file

@ -0,0 +1,20 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class InquiryUrl1717117195275 {
name = 'InquiryUrl1717117195275'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "trustedLinkUrlPatterns" TO "inquiryUrl"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "inquiryUrl"`);
await queryRunner.query(`ALTER TABLE "meta" ADD "inquiryUrl" character varying(1024)`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "inquiryUrl"`);
await queryRunner.query(`ALTER TABLE "meta" ADD "inquiryUrl" character varying(3072) array NOT NULL DEFAULT '{}'`);
await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "inquiryUrl" TO "trustedLinkUrlPatterns"`);
}
}

View file

@ -67,6 +67,7 @@ export class MetaEntityService {
feedbackUrl: instance.feedbackUrl, feedbackUrl: instance.feedbackUrl,
impressumUrl: instance.impressumUrl, impressumUrl: instance.impressumUrl,
privacyPolicyUrl: instance.privacyPolicyUrl, privacyPolicyUrl: instance.privacyPolicyUrl,
inquiryUrl: instance.inquiryUrl,
disableRegistration: instance.disableRegistration, disableRegistration: instance.disableRegistration,
emailRequiredForSignup: instance.emailRequiredForSignup, emailRequiredForSignup: instance.emailRequiredForSignup,
enableHcaptcha: instance.enableHcaptcha, enableHcaptcha: instance.enableHcaptcha,

View file

@ -376,6 +376,12 @@ export class MiMeta {
}) })
public privacyPolicyUrl: string | null; public privacyPolicyUrl: string | null;
@Column('varchar', {
length: 1024,
nullable: true,
})
public inquiryUrl: string | null;
@Column('varchar', { @Column('varchar', {
length: 8192, length: 8192,
nullable: true, nullable: true,

View file

@ -227,6 +227,10 @@ export const packedMetaLiteSchema = {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: true,
}, },
inquiryUrl: {
type: 'string',
optional: false, nullable: true,
},
serverRules: { serverRules: {
type: 'array', type: 'array',
optional: false, nullable: false, optional: false, nullable: false,

View file

@ -37,12 +37,12 @@ export class NodeinfoServerService {
@bindThis @bindThis
public getLinks() { public getLinks() {
return [{ return [{
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.1', rel: 'http://nodeinfo.diaspora.software/ns/schema/2.1',
href: this.config.url + nodeinfo2_1path href: this.config.url + nodeinfo2_1path,
}, { }, {
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0', rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0',
href: this.config.url + nodeinfo2_0path, href: this.config.url + nodeinfo2_0path,
}]; }];
} }
@bindThis @bindThis
@ -108,6 +108,7 @@ export class NodeinfoServerService {
langs: meta.langs, langs: meta.langs,
tosUrl: meta.termsOfServiceUrl, tosUrl: meta.termsOfServiceUrl,
privacyPolicyUrl: meta.privacyPolicyUrl, privacyPolicyUrl: meta.privacyPolicyUrl,
inquiryUrl: meta.inquiryUrl,
impressumUrl: meta.impressumUrl, impressumUrl: meta.impressumUrl,
repositoryUrl: meta.repositoryUrl, repositoryUrl: meta.repositoryUrl,
feedbackUrl: meta.feedbackUrl, feedbackUrl: meta.feedbackUrl,

View file

@ -427,6 +427,10 @@ export const meta = {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: true,
}, },
inquiryUrl: {
type: 'string',
optional: false, nullable: true,
},
repositoryUrl: { repositoryUrl: {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: true,
@ -513,6 +517,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
feedbackUrl: instance.feedbackUrl, feedbackUrl: instance.feedbackUrl,
impressumUrl: instance.impressumUrl, impressumUrl: instance.impressumUrl,
privacyPolicyUrl: instance.privacyPolicyUrl, privacyPolicyUrl: instance.privacyPolicyUrl,
inquiryUrl: instance.inquiryUrl,
disableRegistration: instance.disableRegistration, disableRegistration: instance.disableRegistration,
emailRequiredForSignup: instance.emailRequiredForSignup, emailRequiredForSignup: instance.emailRequiredForSignup,
enableHcaptcha: instance.enableHcaptcha, enableHcaptcha: instance.enableHcaptcha,

View file

@ -107,6 +107,7 @@ export const paramDef = {
feedbackUrl: { type: 'string', nullable: true }, feedbackUrl: { type: 'string', nullable: true },
impressumUrl: { type: 'string', nullable: true }, impressumUrl: { type: 'string', nullable: true },
privacyPolicyUrl: { type: 'string', nullable: true }, privacyPolicyUrl: { type: 'string', nullable: true },
inquiryUrl: { type: 'string', nullable: true },
useObjectStorage: { type: 'boolean' }, useObjectStorage: { type: 'boolean' },
objectStorageBaseUrl: { type: 'string', nullable: true }, objectStorageBaseUrl: { type: 'string', nullable: true },
objectStorageBucket: { type: 'string', nullable: true }, objectStorageBucket: { type: 'string', nullable: true },
@ -422,6 +423,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
set.privacyPolicyUrl = ps.privacyPolicyUrl; set.privacyPolicyUrl = ps.privacyPolicyUrl;
} }
if (ps.inquiryUrl !== undefined) {
set.inquiryUrl = ps.inquiryUrl;
}
if (ps.useObjectStorage !== undefined) { if (ps.useObjectStorage !== undefined) {
set.useObjectStorage = ps.useObjectStorage; set.useObjectStorage = ps.useObjectStorage;
} }

View file

@ -30,6 +30,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>{{ i18n.ts.privacyPolicyUrl }}</template> <template #label>{{ i18n.ts.privacyPolicyUrl }}</template>
</MkInput> </MkInput>
<MkInput v-model="inquiryUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts._serverSettings.inquiryUrl }}</template>
<template #caption>{{ i18n.ts._serverSettings.inquiryUrlDescription }}</template>
</MkInput>
<MkTextarea v-model="preservedUsernames"> <MkTextarea v-model="preservedUsernames">
<template #label>{{ i18n.ts.preservedUsernames }}</template> <template #label>{{ i18n.ts.preservedUsernames }}</template>
<template #caption>{{ i18n.ts.preservedUsernamesDescription }}</template> <template #caption>{{ i18n.ts.preservedUsernamesDescription }}</template>
@ -86,6 +92,7 @@ const hiddenTags = ref<string>('');
const preservedUsernames = ref<string>(''); const preservedUsernames = ref<string>('');
const tosUrl = ref<string | null>(null); const tosUrl = ref<string | null>(null);
const privacyPolicyUrl = ref<string | null>(null); const privacyPolicyUrl = ref<string | null>(null);
const inquiryUrl = ref<string | null>(null);
async function init() { async function init() {
const meta = await misskeyApi('admin/meta'); const meta = await misskeyApi('admin/meta');
@ -97,6 +104,7 @@ async function init() {
preservedUsernames.value = meta.preservedUsernames.join('\n'); preservedUsernames.value = meta.preservedUsernames.join('\n');
tosUrl.value = meta.tosUrl; tosUrl.value = meta.tosUrl;
privacyPolicyUrl.value = meta.privacyPolicyUrl; privacyPolicyUrl.value = meta.privacyPolicyUrl;
inquiryUrl.value = meta.inquiryUrl;
} }
function save() { function save() {
@ -105,6 +113,7 @@ function save() {
emailRequiredForSignup: emailRequiredForSignup.value, emailRequiredForSignup: emailRequiredForSignup.value,
tosUrl: tosUrl.value, tosUrl: tosUrl.value,
privacyPolicyUrl: privacyPolicyUrl.value, privacyPolicyUrl: privacyPolicyUrl.value,
inquiryUrl: inquiryUrl.value,
sensitiveWords: sensitiveWords.value.split('\n'), sensitiveWords: sensitiveWords.value.split('\n'),
prohibitedWords: prohibitedWords.value.split('\n'), prohibitedWords: prohibitedWords.value.split('\n'),
hiddenTags: hiddenTags.value.split('\n'), hiddenTags: hiddenTags.value.split('\n'),

View file

@ -7,7 +7,21 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkStickyContainer> <MkStickyContainer>
<template #header><MkPageHeader/></template> <template #header><MkPageHeader/></template>
<MkSpacer :contentMax="600" :marginMin="20"> <MkSpacer :contentMax="600" :marginMin="20">
<div>{{ instance.maintainerEmail }}</div> <div class="_gaps">
<MkKeyValue>
<template #key>{{ i18n.ts.inquiry }}</template>
<template #value>
<MkLink :url="instance.inquiryUrl" target="_blank">{{ instance.inquiryUrl }}</MkLink>
</template>
</MkKeyValue>
<MkKeyValue>
<template #key>{{ i18n.ts.email }}</template>
<template #value>
<div>{{ instance.maintainerEmail }}</div>
</template>
</MkKeyValue>
</div>
</MkSpacer> </MkSpacer>
</MkStickyContainer> </MkStickyContainer>
</template> </template>
@ -16,6 +30,8 @@ SPDX-License-Identifier: AGPL-3.0-only
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js'; import { definePageMetadata } from '@/scripts/page-metadata.js';
import { instance } from '@/instance.js'; import { instance } from '@/instance.js';
import MkKeyValue from '@/components/MkKeyValue.vue';
import MkLink from '@/components/MkLink.vue';
definePageMetadata(() => ({ definePageMetadata(() => ({
title: i18n.ts.inquiry, title: i18n.ts.inquiry,

View file

@ -4831,6 +4831,7 @@ export type components = {
impressumUrl: string | null; impressumUrl: string | null;
logoImageUrl: string | null; logoImageUrl: string | null;
privacyPolicyUrl: string | null; privacyPolicyUrl: string | null;
inquiryUrl: string | null;
serverRules: string[]; serverRules: string[];
themeColor: string | null; themeColor: string | null;
policies: components['schemas']['RolePolicies']; policies: components['schemas']['RolePolicies'];
@ -4978,6 +4979,7 @@ export type operations = {
shortName: string | null; shortName: string | null;
objectStorageS3ForcePathStyle: boolean; objectStorageS3ForcePathStyle: boolean;
privacyPolicyUrl: string | null; privacyPolicyUrl: string | null;
inquiryUrl: string | null;
repositoryUrl: string | null; repositoryUrl: string | null;
/** /**
* @deprecated * @deprecated
@ -8906,6 +8908,7 @@ export type operations = {
feedbackUrl?: string | null; feedbackUrl?: string | null;
impressumUrl?: string | null; impressumUrl?: string | null;
privacyPolicyUrl?: string | null; privacyPolicyUrl?: string | null;
inquiryUrl?: string | null;
useObjectStorage?: boolean; useObjectStorage?: boolean;
objectStorageBaseUrl?: string | null; objectStorageBaseUrl?: string | null;
objectStorageBucket?: string | null; objectStorageBucket?: string | null;