Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spec(backend/NoteCreateService): ローカルユーザーがまだ誰もフォローしていないリモートユーザーによる通知を引き起こす可能性のある投稿を拒否できるように (MisskeyIO#462) (patched) #149

Merged
merged 4 commits into from
Feb 19, 2024
Next Next commit
spec(backend/NoteCreateService): ローカルユーザーがまだ誰もフォローしていないリモートユーザーによる通知を…
…引き起こす可能性のある投稿を拒否できるように (MisskeyIO#462)

Cherry-picked from 738b4d6, 1b3adcc, 33cb507, a27af00, 5c6236b

Co-authored-by: Ebise Lutica <[email protected]>
Co-authored-by: anatawa12 <[email protected]>
3 people committed Feb 19, 2024

Verified

This commit was signed with the committer’s verified signature.
anatawa12 anatawa12
commit 011436d56b7d130b50885f93b935cf94b5ed00d9
19 changes: 18 additions & 1 deletion packages/backend/src/core/NoteCreateService.ts
Original file line number Diff line number Diff line change
@@ -59,6 +59,9 @@ import { UtilityService } from '@/core/UtilityService.js';
import { UserBlockingService } from '@/core/UserBlockingService.js';
import { isReply } from '@/misc/is-reply.js';
import { trackPromise } from '@/misc/promise-tracker.js';
import { IdentifiableError } from '@/misc/identifiable-error.js';
import { LoggerService } from '@/core/LoggerService.js';
import type Logger from '@/logger.js';

type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';

@@ -149,6 +152,7 @@ type Option = {

@Injectable()
export class NoteCreateService implements OnApplicationShutdown {
private logger: Logger;
#shutdownController = new AbortController();

public static ContainsProhibitedWordsError = class extends Error {};
@@ -219,7 +223,10 @@ export class NoteCreateService implements OnApplicationShutdown {
private instanceChart: InstanceChart,
private utilityService: UtilityService,
private userBlockingService: UserBlockingService,
) { }
private loggerService: LoggerService,
) {
this.logger = this.loggerService.getLogger('note:create');
}

@bindThis
public async create(user: {
@@ -359,6 +366,16 @@ export class NoteCreateService implements OnApplicationShutdown {
mentionedUsers = data.apMentions ?? await this.extractMentionedUsers(user, combinedTokens);
}

const willCauseNotification = mentionedUsers.filter(u => u.host === null).length > 0 || data.reply?.userHost === null || data.renote?.userHost === null;

if (process.env.MISSKEY_BLOCK_MENTIONS_FROM_UNFAMILIAR_REMOTE_USERS === 'true' && user.host !== null && willCauseNotification) {
const userEntity = await this.usersRepository.findOneBy({ id: user.id });
if ((userEntity?.followersCount ?? 0) === 0) {
this.logger.error('Request rejected because user has no local followers', { user: user.id, note: data });
throw new IdentifiableError('e11b3a16-f543-4885-8eb1-66cad131dbfd', 'Notes including mentions, replies, or renotes from remote users are not allowed until user has at least one local follower.');
}
}

tags = tags.filter(tag => Array.from(tag).length <= 128).splice(0, 32);

if (data.reply && (user.id !== data.reply.userId) && !mentionedUsers.some(u => u.id === data.reply!.userId)) {