@@ -59,6 +59,9 @@ import { UtilityService } from '@/core/UtilityService.js';
59
59
import { UserBlockingService } from '@/core/UserBlockingService.js' ;
60
60
import { isReply } from '@/misc/is-reply.js' ;
61
61
import { trackPromise } from '@/misc/promise-tracker.js' ;
62
+ import { IdentifiableError } from '@/misc/identifiable-error.js' ;
63
+ import { LoggerService } from '@/core/LoggerService.js' ;
64
+ import type Logger from '@/logger.js' ;
62
65
63
66
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention' ;
64
67
@@ -149,6 +152,7 @@ type Option = {
149
152
150
153
@Injectable ( )
151
154
export class NoteCreateService implements OnApplicationShutdown {
155
+ private logger : Logger ;
152
156
#shutdownController = new AbortController ( ) ;
153
157
154
158
public static ContainsProhibitedWordsError = class extends Error { } ;
@@ -219,7 +223,10 @@ export class NoteCreateService implements OnApplicationShutdown {
219
223
private instanceChart : InstanceChart ,
220
224
private utilityService : UtilityService ,
221
225
private userBlockingService : UserBlockingService ,
222
- ) { }
226
+ private loggerService : LoggerService ,
227
+ ) {
228
+ this . logger = this . loggerService . getLogger ( 'note:create' ) ;
229
+ }
223
230
224
231
@bindThis
225
232
public async create ( user : {
@@ -359,6 +366,16 @@ export class NoteCreateService implements OnApplicationShutdown {
359
366
mentionedUsers = data . apMentions ?? await this . extractMentionedUsers ( user , combinedTokens ) ;
360
367
}
361
368
369
+ const willCauseNotification = mentionedUsers . filter ( u => u . host === null ) . length > 0 || data . reply ?. userHost === null || data . renote ?. userHost === null ;
370
+
371
+ if ( this . config . nirila . blockMentionsFromUnfamiliarRemoteUsers && user . host !== null && willCauseNotification ) {
372
+ const userEntity = await this . usersRepository . findOneBy ( { id : user . id } ) ;
373
+ if ( ( userEntity ?. followersCount ?? 0 ) === 0 ) {
374
+ this . logger . error ( 'Request rejected because user has no local followers' , { user : user . id , note : data } ) ;
375
+ 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.' ) ;
376
+ }
377
+ }
378
+
362
379
tags = tags . filter ( tag => Array . from ( tag ) . length <= 128 ) . splice ( 0 , 32 ) ;
363
380
364
381
if ( data . reply && ( user . id !== data . reply . userId ) && ! mentionedUsers . some ( u => u . id === data . reply ! . userId ) ) {
0 commit comments