mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	enhance(backend): センシティブワードの設定がハッシュタグトレンドにも適用されるように
This commit is contained in:
		
							parent
							
								
									2201cd6d0c
								
							
						
					
					
						commit
						42cc909c5b
					
				
					 4 changed files with 43 additions and 26 deletions
				
			
		
							
								
								
									
										11
									
								
								CHANGELOG.md
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								CHANGELOG.md
									
										
									
									
									
								
							| 
						 | 
					@ -12,6 +12,17 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-->
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 2023.12.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### General
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Client
 | 
				
			||||||
 | 
					- 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Server
 | 
				
			||||||
 | 
					- Enhance: センシティブワードの設定がハッシュタグトレンドにも適用されるようになりました
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 2023.12.0
 | 
					## 2023.12.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Note
 | 
					### Note
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
 | 
				
			||||||
import { bindThis } from '@/decorators.js';
 | 
					import { bindThis } from '@/decorators.js';
 | 
				
			||||||
import { FeaturedService } from '@/core/FeaturedService.js';
 | 
					import { FeaturedService } from '@/core/FeaturedService.js';
 | 
				
			||||||
import { MetaService } from '@/core/MetaService.js';
 | 
					import { MetaService } from '@/core/MetaService.js';
 | 
				
			||||||
 | 
					import { UtilityService } from '@/core/UtilityService.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Injectable()
 | 
					@Injectable()
 | 
				
			||||||
export class HashtagService {
 | 
					export class HashtagService {
 | 
				
			||||||
| 
						 | 
					@ -29,6 +30,7 @@ export class HashtagService {
 | 
				
			||||||
		private featuredService: FeaturedService,
 | 
							private featuredService: FeaturedService,
 | 
				
			||||||
		private idService: IdService,
 | 
							private idService: IdService,
 | 
				
			||||||
		private metaService: MetaService,
 | 
							private metaService: MetaService,
 | 
				
			||||||
 | 
							private utilityService: UtilityService,
 | 
				
			||||||
	) {
 | 
						) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,6 +163,7 @@ export class HashtagService {
 | 
				
			||||||
		const instance = await this.metaService.fetch();
 | 
							const instance = await this.metaService.fetch();
 | 
				
			||||||
		const hiddenTags = instance.hiddenTags.map(t => normalizeForSearch(t));
 | 
							const hiddenTags = instance.hiddenTags.map(t => normalizeForSearch(t));
 | 
				
			||||||
		if (hiddenTags.includes(hashtag)) return;
 | 
							if (hiddenTags.includes(hashtag)) return;
 | 
				
			||||||
 | 
							if (this.utilityService.isSensitiveWordIncluded(hashtag, instance.sensitiveWords)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// YYYYMMDDHHmm (10分間隔)
 | 
							// YYYYMMDDHHmm (10分間隔)
 | 
				
			||||||
		const now = new Date();
 | 
							const now = new Date();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -422,7 +422,7 @@ export class NoteCreateService implements OnApplicationShutdown {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (data.visibility === 'public' && data.channel == null) {
 | 
							if (data.visibility === 'public' && data.channel == null) {
 | 
				
			||||||
			const sensitiveWords = meta.sensitiveWords;
 | 
								const sensitiveWords = meta.sensitiveWords;
 | 
				
			||||||
			if (this.isSensitive(data, sensitiveWords)) {
 | 
								if (this.utilityService.isSensitiveWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) {
 | 
				
			||||||
				data.visibility = 'home';
 | 
									data.visibility = 'home';
 | 
				
			||||||
			} else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) {
 | 
								} else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) {
 | 
				
			||||||
				data.visibility = 'home';
 | 
									data.visibility = 'home';
 | 
				
			||||||
| 
						 | 
					@ -989,31 +989,6 @@ export class NoteCreateService implements OnApplicationShutdown {
 | 
				
			||||||
		if (!user.noindex) this.index(note);
 | 
							if (!user.noindex) this.index(note);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@bindThis
 | 
					 | 
				
			||||||
	private isSensitive(note: Option, sensitiveWord: string[]): boolean {
 | 
					 | 
				
			||||||
		if (sensitiveWord.length > 0) {
 | 
					 | 
				
			||||||
			const text = note.cw ?? note.text ?? '';
 | 
					 | 
				
			||||||
			if (text === '') return false;
 | 
					 | 
				
			||||||
			const matched = sensitiveWord.some(filter => {
 | 
					 | 
				
			||||||
				// represents RegExp
 | 
					 | 
				
			||||||
				const regexp = filter.match(/^\/(.+)\/(.*)$/);
 | 
					 | 
				
			||||||
				// This should never happen due to input sanitisation.
 | 
					 | 
				
			||||||
				if (!regexp) {
 | 
					 | 
				
			||||||
					const words = filter.split(' ');
 | 
					 | 
				
			||||||
					return words.every(keyword => text.includes(keyword));
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				try {
 | 
					 | 
				
			||||||
					return new RE2(regexp[1], regexp[2]).test(text);
 | 
					 | 
				
			||||||
				} catch (err) {
 | 
					 | 
				
			||||||
					// This should never happen due to input sanitisation.
 | 
					 | 
				
			||||||
					return false;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
			if (matched) return true;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@bindThis
 | 
						@bindThis
 | 
				
			||||||
	private isQuote(note: Option): note is Option & { renote: MiNote } {
 | 
						private isQuote(note: Option): note is Option & { renote: MiNote } {
 | 
				
			||||||
		// sync with misc/is-quote.ts
 | 
							// sync with misc/is-quote.ts
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@
 | 
				
			||||||
import { URL } from 'node:url';
 | 
					import { URL } from 'node:url';
 | 
				
			||||||
import { toASCII } from 'punycode';
 | 
					import { toASCII } from 'punycode';
 | 
				
			||||||
import { Inject, Injectable } from '@nestjs/common';
 | 
					import { Inject, Injectable } from '@nestjs/common';
 | 
				
			||||||
 | 
					import RE2 from 're2';
 | 
				
			||||||
import { DI } from '@/di-symbols.js';
 | 
					import { DI } from '@/di-symbols.js';
 | 
				
			||||||
import type { Config } from '@/config.js';
 | 
					import type { Config } from '@/config.js';
 | 
				
			||||||
import { bindThis } from '@/decorators.js';
 | 
					import { bindThis } from '@/decorators.js';
 | 
				
			||||||
| 
						 | 
					@ -41,6 +42,33 @@ export class UtilityService {
 | 
				
			||||||
		return silencedHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`));
 | 
							return silencedHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@bindThis
 | 
				
			||||||
 | 
						public isSensitiveWordIncluded(text: string, sensitiveWords: string[]): boolean {
 | 
				
			||||||
 | 
							if (sensitiveWords.length === 0) return false;
 | 
				
			||||||
 | 
							if (text === '') return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const regexpregexp = /^\/(.+)\/(.*)$/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const matched = sensitiveWords.some(filter => {
 | 
				
			||||||
 | 
								// represents RegExp
 | 
				
			||||||
 | 
								const regexp = filter.match(regexpregexp);
 | 
				
			||||||
 | 
								// This should never happen due to input sanitisation.
 | 
				
			||||||
 | 
								if (!regexp) {
 | 
				
			||||||
 | 
									const words = filter.split(' ');
 | 
				
			||||||
 | 
									return words.every(keyword => text.includes(keyword));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								try {
 | 
				
			||||||
 | 
									// TODO: RE2インスタンスをキャッシュ
 | 
				
			||||||
 | 
									return new RE2(regexp[1], regexp[2]).test(text);
 | 
				
			||||||
 | 
								} catch (err) {
 | 
				
			||||||
 | 
									// This should never happen due to input sanitisation.
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return matched;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@bindThis
 | 
						@bindThis
 | 
				
			||||||
	public extractDbHost(uri: string): string {
 | 
						public extractDbHost(uri: string): string {
 | 
				
			||||||
		const url = new URL(uri);
 | 
							const url = new URL(uri);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue