運営者情報・プライバシーポリシーリンクを追加
This commit is contained in:
parent
5edc885c22
commit
ed39bb1f14
|
|
@ -1129,6 +1129,9 @@ export interface Locale {
|
|||
"notificationRecieveConfig": string;
|
||||
"mutualFollow": string;
|
||||
"fileAttachedOnly": string;
|
||||
"impressum": string;
|
||||
"impressumDescription": string;
|
||||
"privacyPolicy": string;
|
||||
"_announcement": {
|
||||
"forExistingUsers": string;
|
||||
"forExistingUsersDescription": string;
|
||||
|
|
|
|||
|
|
@ -1126,6 +1126,9 @@ edited: "編集済み"
|
|||
notificationRecieveConfig: "通知の受信設定"
|
||||
mutualFollow: "相互フォロー"
|
||||
fileAttachedOnly: "ファイル付きのみ"
|
||||
impressum: "運営者情報"
|
||||
impressumDescription: "ドイツなどの一部の国と地域では表示が義務付けられています(Impressum)。"
|
||||
privacyPolicy: "プライバシーポリシー"
|
||||
|
||||
_announcement:
|
||||
forExistingUsers: "既存ユーザーのみ"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class AddSomeUrls1696003580220 {
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "impressumUrl" character varying(1024)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "privacyPolicyUrl" character varying(1024)`);
|
||||
}
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "impressumUrl"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "privacyPolicyUrl"`);
|
||||
}
|
||||
}
|
||||
|
|
@ -335,6 +335,18 @@ export class MiMeta {
|
|||
})
|
||||
public feedbackUrl: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 1024,
|
||||
nullable: true,
|
||||
})
|
||||
public impressumUrl: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 1024,
|
||||
nullable: true,
|
||||
})
|
||||
public privacyPolicyUrl: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 8192,
|
||||
nullable: true,
|
||||
|
|
|
|||
|
|
@ -328,6 +328,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
tosUrl: instance.termsOfServiceUrl,
|
||||
repositoryUrl: instance.repositoryUrl,
|
||||
feedbackUrl: instance.feedbackUrl,
|
||||
impressumUrl: instance.impressumUrl,
|
||||
privacyPolicyUrl: instance.privacyPolicyUrl,
|
||||
disableRegistration: instance.disableRegistration,
|
||||
emailRequiredForSignup: instance.emailRequiredForSignup,
|
||||
enableHcaptcha: instance.enableHcaptcha,
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ export const paramDef = {
|
|||
tosUrl: { type: 'string', nullable: true },
|
||||
repositoryUrl: { type: 'string' },
|
||||
feedbackUrl: { type: 'string' },
|
||||
impressumUrl: { type: 'string' },
|
||||
privacyPolicyUrl: { type: 'string' },
|
||||
useObjectStorage: { type: 'boolean' },
|
||||
objectStorageBaseUrl: { type: 'string', nullable: true },
|
||||
objectStorageBucket: { type: 'string', nullable: true },
|
||||
|
|
@ -341,6 +343,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
set.feedbackUrl = ps.feedbackUrl;
|
||||
}
|
||||
|
||||
if (ps.impressumUrl !== undefined) {
|
||||
set.impressumUrl = ps.impressumUrl;
|
||||
}
|
||||
|
||||
if (ps.privacyPolicyUrl !== undefined) {
|
||||
set.privacyPolicyUrl = ps.privacyPolicyUrl;
|
||||
}
|
||||
|
||||
if (ps.useObjectStorage !== undefined) {
|
||||
set.useObjectStorage = ps.useObjectStorage;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,6 +299,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
tosUrl: instance.termsOfServiceUrl,
|
||||
repositoryUrl: instance.repositoryUrl,
|
||||
feedbackUrl: instance.feedbackUrl,
|
||||
impressumUrl: instance.impressumUrl,
|
||||
privacyPolicyUrl: instance.privacyPolicyUrl,
|
||||
disableRegistration: instance.disableRegistration,
|
||||
emailRequiredForSignup: instance.emailRequiredForSignup,
|
||||
enableHcaptcha: instance.enableHcaptcha,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,15 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkSwitch :modelValue="agreeTos" style="margin-top: 16px;" @update:modelValue="updateAgreeTos">{{ i18n.ts.agree }}</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="availablePrivacyPolicy" :defaultOpen="true">
|
||||
<template #label>{{ i18n.ts.privacyPolicy }}</template>
|
||||
<template #suffix><i v-if="agreePrivacyPolicy" class="ti ti-check" style="color: var(--success)"></i></template>
|
||||
|
||||
<a :href="instance.privacyPolicyUrl" class="_link" target="_blank">{{ i18n.ts.privacyPolicy }} <i class="ti ti-external-link"></i></a>
|
||||
|
||||
<MkSwitch :modelValue="agreePrivacyPolicy" style="margin-top: 16px;" @update:modelValue="updateAgreePrivacyPolicy">{{ i18n.ts.agree }}</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder :defaultOpen="true">
|
||||
<template #label>{{ i18n.ts.basicNotesBeforeCreateAccount }}</template>
|
||||
<template #suffix><i v-if="agreeNote" class="ti ti-check" style="color: var(--success)"></i></template>
|
||||
|
|
@ -71,13 +80,15 @@ import * as os from '@/os.js';
|
|||
|
||||
const availableServerRules = instance.serverRules.length > 0;
|
||||
const availableTos = instance.tosUrl != null;
|
||||
const availablePrivacyPolicy = instance.privacyPolicyUrl != null;
|
||||
|
||||
const agreeServerRules = ref(false);
|
||||
const agreeTos = ref(false);
|
||||
const agreePrivacyPolicy = ref(false);
|
||||
const agreeNote = ref(false);
|
||||
|
||||
const agreed = computed(() => {
|
||||
return (!availableServerRules || agreeServerRules.value) && (!availableTos || agreeTos.value) && agreeNote.value;
|
||||
return (!availableServerRules || agreeServerRules.value) && (!availableTos || agreeTos.value) && (!availablePrivacyPolicy || agreePrivacyPolicy.value) && agreeNote.value;
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
|
@ -113,6 +124,20 @@ async function updateAgreeTos(v: boolean) {
|
|||
}
|
||||
}
|
||||
|
||||
async function updateAgreePrivacyPolicy(v: boolean) {
|
||||
if (v) {
|
||||
const confirm = await os.confirm({
|
||||
type: 'question',
|
||||
title: i18n.ts.doYouAgree,
|
||||
text: i18n.t('iHaveReadXCarefullyAndAgree', { x: i18n.ts.privacyPolicy }),
|
||||
});
|
||||
if (confirm.canceled) return;
|
||||
agreePrivacyPolicy.value = true;
|
||||
} else {
|
||||
agreePrivacyPolicy.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function updateAgreeNote(v: boolean) {
|
||||
if (v) {
|
||||
const confirm = await os.confirm({
|
||||
|
|
|
|||
|
|
@ -104,7 +104,25 @@ function showMenu(ev) {
|
|||
action: () => {
|
||||
os.pageWindow('/about-misskey');
|
||||
},
|
||||
}, null, {
|
||||
}, null, (instance.impressumUrl) ? {
|
||||
text: i18n.ts.impressum,
|
||||
icon: 'ti ti-file-invoice',
|
||||
action: () => {
|
||||
window.open(instance.impressumUrl, '_blank');
|
||||
},
|
||||
} : undefined, (instance.tosUrl) ? {
|
||||
text: i18n.ts.termsOfService,
|
||||
icon: 'ti ti-notebook',
|
||||
action: () => {
|
||||
window.open(instance.tosUrl, '_blank');
|
||||
},
|
||||
} : undefined, (instance.privacyPolicyUrl) ? {
|
||||
text: i18n.ts.privacyPolicy,
|
||||
icon: 'ti ti-shield-lock',
|
||||
action: () => {
|
||||
window.open(instance.privacyPolicyUrl, '_blank');
|
||||
},
|
||||
} : undefined, (!instance.impressumUrl && !instance.tosUrl && !instance.privacyPolicyUrl) ? undefined : null, {
|
||||
text: i18n.ts.help,
|
||||
icon: 'ti ti-help-circle',
|
||||
action: () => {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<li v-for="item in instance.serverRules" :class="$style.rule"><div :class="$style.ruleText" v-html="item"></div></li>
|
||||
</ol>
|
||||
</MkFolder>
|
||||
<FormLink v-if="instance.impressumUrl" :to="instance.impressumUrl" external>{{ i18n.ts.impressum }}</FormLink>
|
||||
<FormLink v-if="instance.tosUrl" :to="instance.tosUrl" external>{{ i18n.ts.termsOfService }}</FormLink>
|
||||
<FormLink v-if="instance.privacyPolicyUrl" :to="instance.privacyPolicyUrl" external>{{ i18n.ts.privacyPolicy }}</FormLink>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template #label>{{ i18n.ts.tosUrl }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkInput v-model="privacyPolicyUrl">
|
||||
<template #prefix><i class="ti ti-link"></i></template>
|
||||
<template #label>{{ i18n.ts.privacyPolicy }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkTextarea v-model="preservedUsernames">
|
||||
<template #label>{{ i18n.ts.preservedUsernames }}</template>
|
||||
<template #caption>{{ i18n.ts.preservedUsernamesDescription }}</template>
|
||||
|
|
@ -69,6 +74,7 @@ let emailRequiredForSignup: boolean = $ref(false);
|
|||
let sensitiveWords: string = $ref('');
|
||||
let preservedUsernames: string = $ref('');
|
||||
let tosUrl: string | null = $ref(null);
|
||||
let privacyPolicyUrl: string | null = $ref(null);
|
||||
|
||||
async function init() {
|
||||
const meta = await os.api('admin/meta');
|
||||
|
|
@ -77,6 +83,7 @@ async function init() {
|
|||
sensitiveWords = meta.sensitiveWords.join('\n');
|
||||
preservedUsernames = meta.preservedUsernames.join('\n');
|
||||
tosUrl = meta.tosUrl;
|
||||
privacyPolicyUrl = meta.privacyPolicyUrl;
|
||||
}
|
||||
|
||||
function save() {
|
||||
|
|
@ -84,6 +91,7 @@ function save() {
|
|||
disableRegistration: !enableRegistration,
|
||||
emailRequiredForSignup,
|
||||
tosUrl,
|
||||
privacyPolicyUrl,
|
||||
sensitiveWords: sensitiveWords.split('\n'),
|
||||
preservedUsernames: preservedUsernames.split('\n'),
|
||||
}).then(() => {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</MkInput>
|
||||
</FormSplit>
|
||||
|
||||
<MkInput v-model="impressumUrl">
|
||||
<template #label>{{ i18n.ts.impressum }}</template>
|
||||
<template #prefix><i class="ti ti-link"></i></template>
|
||||
<template #caption>{{ i18n.ts.impressumDescription }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkTextarea v-model="pinnedUsers">
|
||||
<template #label>{{ i18n.ts.pinnedUsers }}</template>
|
||||
<template #caption>{{ i18n.ts.pinnedUsersDescription }}</template>
|
||||
|
|
@ -127,6 +133,7 @@ let shortName: string | null = $ref(null);
|
|||
let description: string | null = $ref(null);
|
||||
let maintainerName: string | null = $ref(null);
|
||||
let maintainerEmail: string | null = $ref(null);
|
||||
let impressumUrl: string | null = $ref(null);
|
||||
let pinnedUsers: string = $ref('');
|
||||
let cacheRemoteFiles: boolean = $ref(false);
|
||||
let cacheRemoteSensitiveFiles: boolean = $ref(false);
|
||||
|
|
@ -143,6 +150,7 @@ async function init(): Promise<void> {
|
|||
description = meta.description;
|
||||
maintainerName = meta.maintainerName;
|
||||
maintainerEmail = meta.maintainerEmail;
|
||||
impressumUrl = meta.impressumUrl;
|
||||
pinnedUsers = meta.pinnedUsers.join('\n');
|
||||
cacheRemoteFiles = meta.cacheRemoteFiles;
|
||||
cacheRemoteSensitiveFiles = meta.cacheRemoteSensitiveFiles;
|
||||
|
|
@ -160,6 +168,7 @@ function save(): void {
|
|||
description,
|
||||
maintainerName,
|
||||
maintainerEmail,
|
||||
impressumUrl,
|
||||
pinnedUsers: pinnedUsers.split('\n'),
|
||||
cacheRemoteFiles,
|
||||
cacheRemoteSensitiveFiles,
|
||||
|
|
|
|||
|
|
@ -68,7 +68,25 @@ export function openInstanceMenu(ev: MouseEvent) {
|
|||
text: i18n.ts.manageCustomEmojis,
|
||||
icon: 'ti ti-icons',
|
||||
} : undefined],
|
||||
}, null, {
|
||||
}, null, (instance.impressumUrl) ? {
|
||||
text: i18n.ts.impressum,
|
||||
icon: 'ti ti-file-invoice',
|
||||
action: () => {
|
||||
window.open(instance.impressumUrl, '_blank');
|
||||
},
|
||||
} : undefined, (instance.tosUrl) ? {
|
||||
text: i18n.ts.termsOfService,
|
||||
icon: 'ti ti-notebook',
|
||||
action: () => {
|
||||
window.open(instance.tosUrl, '_blank');
|
||||
},
|
||||
} : undefined, (instance.privacyPolicyUrl) ? {
|
||||
text: i18n.ts.privacyPolicy,
|
||||
icon: 'ti ti-shield-lock',
|
||||
action: () => {
|
||||
window.open(instance.privacyPolicyUrl, '_blank');
|
||||
},
|
||||
} : undefined, (!instance.impressumUrl && !instance.tosUrl && !instance.privacyPolicyUrl) ? undefined : null, {
|
||||
text: i18n.ts.help,
|
||||
icon: 'ti ti-help-circle',
|
||||
action: () => {
|
||||
|
|
|
|||
|
|
@ -323,6 +323,8 @@ export type LiteInstanceMetadata = {
|
|||
tosUrl: string | null;
|
||||
repositoryUrl: string;
|
||||
feedbackUrl: string;
|
||||
impressumUrl: string | null;
|
||||
privacyPolicyUrl: string | null;
|
||||
disableRegistration: boolean;
|
||||
disableLocalTimeline: boolean;
|
||||
disableGlobalTimeline: boolean;
|
||||
|
|
|
|||
Loading…
Reference in New Issue