This commit is contained in:
syuilo 2024-10-19 21:00:38 +09:00
parent 2250e521e4
commit 6432033c32
13 changed files with 79 additions and 4 deletions

12
locales/index.d.ts vendored
View File

@ -5190,6 +5190,18 @@ export interface Locale extends ILocale {
* 使
*/
"yourNameContainsProhibitedWordsDescription": string;
"_accountSettings": {
/**
*
*/
"signinRequiredForShowContents": string;
/**
*
*
* URLのプレビューや使
*/
"signinRequiredForShowContentsDescription": string;
};
"_abuseUserReport": {
/**
*

View File

@ -1294,6 +1294,10 @@ prohibitedWordsForNameOfUserDescription: "このリストに含まれる文字
yourNameContainsProhibitedWords: "変更しようとした名前に禁止された文字列が含まれています"
yourNameContainsProhibitedWordsDescription: "名前に禁止されている文字列が含まれています。この名前を使用したい場合は、サーバー管理者にお問い合わせください。"
_accountSettings:
signinRequiredForShowContents: "コンテンツの閲覧にログインを必須にする"
signinRequiredForShowContentsDescription: "あなたのプロフィールやノートなどの作成したコンテンツの閲覧にログイン必須にします。\nクローラーから情報を収集されるのを防ぐ効果が期待できます。\nURLのプレビューや、コンテンツの埋め込みも使用不可になります。"
_abuseUserReport:
forward: "転送"
forwardDescription: "匿名のシステムアカウントとして、リモートサーバーに通報を転送します。"

View File

@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class SigninRequiredForShowContents1729333924409 {
name = 'SigninRequiredForShowContents1729333924409'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" ADD "signinRequiredForShowContents" boolean NOT NULL DEFAULT false`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "signinRequiredForShowContents"`);
}
}

View File

@ -149,6 +149,10 @@ export class NoteEntityService implements OnModuleInit {
}
}
if (packedNote.user.signinRequiredForShowContents && meId == null) {
hide = true;
}
if (hide) {
packedNote.visibleUserIds = undefined;
packedNote.fileIds = [];

View File

@ -490,6 +490,7 @@ export class UserEntityService implements OnModuleInit {
}))) : [],
isBot: user.isBot,
isCat: user.isCat,
signinRequiredForShowContents: user.signinRequiredForShowContents === false ? undefined : true,
instance: user.host ? this.federatedInstanceService.federatedInstanceCache.fetch(user.host).then(instance => instance ? {
name: instance.name,
softwareName: instance.softwareName,

View File

@ -202,6 +202,11 @@ export class MiUser {
})
public isHibernated: boolean;
@Column('boolean', {
default: false,
})
public signinRequiredForShowContents: boolean;
// アカウントが削除されたかどうかのフラグだが、完全に削除される際は物理削除なので実質削除されるまでの「削除が進行しているかどうか」のフラグ
@Column('boolean', {
default: false,

View File

@ -115,6 +115,10 @@ export const packedUserLiteSchema = {
type: 'boolean',
nullable: false, optional: true,
},
signinRequiredForShowContents: {
type: 'boolean',
nullable: false, optional: true,
},
instance: {
type: 'object',
nullable: false, optional: true,

View File

@ -179,6 +179,7 @@ export const paramDef = {
autoAcceptFollowed: { type: 'boolean' },
noCrawle: { type: 'boolean' },
preventAiLearning: { type: 'boolean' },
signinRequiredForShowContents: { type: 'boolean' },
isBot: { type: 'boolean' },
isCat: { type: 'boolean' },
injectFeaturedNote: { type: 'boolean' },
@ -334,6 +335,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;
if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle;
if (typeof ps.preventAiLearning === 'boolean') profileUpdates.preventAiLearning = ps.preventAiLearning;
if (typeof ps.signinRequiredForShowContents === 'boolean') updates.signinRequiredForShowContents = ps.signinRequiredForShowContents;
if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat;
if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote;
if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail;

View File

@ -26,6 +26,12 @@ export const meta = {
code: 'NO_SUCH_NOTE',
id: '24fcbfc6-2e37-42b6-8388-c29b3861a08d',
},
signinRequired: {
message: 'Signin required.',
code: 'SIGNIN_REQUIRED',
id: '8e75455b-738c-471d-9f80-62693f33372e',
},
},
} as const;
@ -49,6 +55,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw err;
});
if (note.user!.signinRequiredForShowContents && me == null) {
throw new ApiError(meta.errors.signinRequired);
}
return await this.noteEntityService.pack(note, me, {
detail: true,
});

View File

@ -42,6 +42,12 @@ export const meta = {
code: 'BOTH_WITH_REPLIES_AND_WITH_FILES',
id: '91c8cb9f-36ed-46e7-9ca2-7df96ed6e222',
},
signinRequired: {
message: 'Signin required.',
code: 'SIGNIN_REQUIRED',
id: 'd1588a9e-4b4d-4c07-807f-16f1486577a2',
},
},
} as const;

View File

@ -601,12 +601,15 @@ export class ClientServerService {
fastify.get<{ Params: { note: string; } }>('/notes/:note', async (request, reply) => {
vary(reply.raw, 'Accept');
const note = await this.notesRepository.findOneBy({
id: request.params.note,
visibility: In(['public', 'home']),
const note = await this.notesRepository.findOne({
where: {
id: request.params.note,
visibility: In(['public', 'home']),
},
relations: ['user'],
});
if (note) {
if (note && !note.user!.signinRequiredForShowContents) {
const _note = await this.noteEntityService.pack(note);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: note.userId });
reply.header('Cache-Control', 'public, max-age=15');

View File

@ -43,6 +43,10 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.makeExplorable }}
<template #caption>{{ i18n.ts.makeExplorableDescription }}</template>
</MkSwitch>
<MkSwitch v-model="signinRequiredForShowContents" @update:modelValue="save()">
{{ i18n.ts._accountSettings.signinRequiredForShowContents }}
<template #caption>{{ i18n.ts._accountSettings.signinRequiredForShowContentsDescription }}</template>
</MkSwitch>
<FormSection>
<div class="_gaps_m">
@ -90,6 +94,7 @@ const autoAcceptFollowed = ref($i.autoAcceptFollowed);
const noCrawle = ref($i.noCrawle);
const preventAiLearning = ref($i.preventAiLearning);
const isExplorable = ref($i.isExplorable);
const signinRequiredForShowContents = ref($i.signinRequiredForShowContents ?? false);
const hideOnlineStatus = ref($i.hideOnlineStatus);
const publicReactions = ref($i.publicReactions);
const followingVisibility = ref($i.followingVisibility);
@ -107,6 +112,7 @@ function save() {
noCrawle: !!noCrawle.value,
preventAiLearning: !!preventAiLearning.value,
isExplorable: !!isExplorable.value,
signinRequiredForShowContents: !!signinRequiredForShowContents.value,
hideOnlineStatus: !!hideOnlineStatus.value,
publicReactions: !!publicReactions.value,
followingVisibility: followingVisibility.value,

View File

@ -3736,6 +3736,7 @@ export type components = {
}[];
isBot?: boolean;
isCat?: boolean;
signinRequiredForShowContents?: boolean;
instance?: {
name: string | null;
softwareName: string | null;
@ -19844,6 +19845,7 @@ export type operations = {
autoAcceptFollowed?: boolean;
noCrawle?: boolean;
preventAiLearning?: boolean;
signinRequiredForShowContents?: boolean;
isBot?: boolean;
isCat?: boolean;
injectFeaturedNote?: boolean;