merge: latest changes
This commit is contained in:
commit
85355813ad
91 changed files with 1103 additions and 494 deletions
|
|
@ -408,7 +408,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
|
|||
*/
|
||||
@bindThis
|
||||
public checkDuplicate(name: string): Promise<boolean> {
|
||||
return this.emojisRepository.exist({ where: { name, host: IsNull() } });
|
||||
return this.emojisRepository.exists({ where: { name, host: IsNull() } });
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ export class HashtagService {
|
|||
const instance = await this.metaService.fetch();
|
||||
const hiddenTags = instance.hiddenTags.map(t => normalizeForSearch(t));
|
||||
if (hiddenTags.includes(hashtag)) return;
|
||||
if (this.utilityService.isSensitiveWordIncluded(hashtag, instance.sensitiveWords)) return;
|
||||
if (this.utilityService.isKeyWordIncluded(hashtag, instance.sensitiveWords)) return;
|
||||
|
||||
// YYYYMMDDHHmm (10分間隔)
|
||||
const now = new Date();
|
||||
|
|
|
|||
|
|
@ -153,6 +153,8 @@ type Option = {
|
|||
export class NoteCreateService implements OnApplicationShutdown {
|
||||
#shutdownController = new AbortController();
|
||||
|
||||
public static ContainsProhibitedWordsError = class extends Error {};
|
||||
|
||||
constructor(
|
||||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
|
@ -429,13 +431,19 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
|
||||
if (data.visibility === 'public' && data.channel == null) {
|
||||
const sensitiveWords = meta.sensitiveWords;
|
||||
if (this.utilityService.isSensitiveWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) {
|
||||
if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) {
|
||||
data.visibility = 'home';
|
||||
} else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) {
|
||||
data.visibility = 'home';
|
||||
}
|
||||
}
|
||||
|
||||
if (!user.host) {
|
||||
if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', meta.prohibitedWords)) {
|
||||
throw new NoteCreateService.ContainsProhibitedWordsError();
|
||||
}
|
||||
}
|
||||
|
||||
const inSilencedInstance = this.utilityService.isSilencedHost(meta.silencedHosts, user.host);
|
||||
|
||||
if (data.visibility === 'public' && inSilencedInstance && user.host !== null) {
|
||||
|
|
@ -795,7 +803,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
});
|
||||
// 通知
|
||||
if (data.reply.userHost === null) {
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exist({
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exists({
|
||||
where: {
|
||||
userId: data.reply.userId,
|
||||
threadId: data.reply.threadId ?? data.reply.id,
|
||||
|
|
@ -830,7 +838,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
|
||||
// Notify
|
||||
if (data.renote.userHost === null) {
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exist({
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exists({
|
||||
where: {
|
||||
userId: data.renote.userId,
|
||||
threadId: data.renote.threadId ?? data.renote.id,
|
||||
|
|
@ -1057,7 +1065,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
@bindThis
|
||||
private async createMentionedEvents(mentionedUsers: MinimumUser[], note: MiNote, nm: NotificationManager) {
|
||||
for (const u of mentionedUsers.filter(u => this.userEntityService.isLocalUser(u))) {
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exist({
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exists({
|
||||
where: {
|
||||
userId: u.id,
|
||||
threadId: note.threadId ?? note.id,
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
|||
if (data.reply) {
|
||||
// 通知
|
||||
if (data.reply.userHost === null) {
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exist({
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exists({
|
||||
where: {
|
||||
userId: data.reply.userId,
|
||||
threadId: data.reply.threadId ?? data.reply.id,
|
||||
|
|
@ -647,7 +647,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
|||
|
||||
// Notify
|
||||
if (data.renote.userHost === null) {
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exist({
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exists({
|
||||
where: {
|
||||
userId: data.renote.userId,
|
||||
threadId: data.renote.threadId ?? data.renote.id,
|
||||
|
|
@ -751,7 +751,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
|||
@bindThis
|
||||
private async createMentionedEvents(mentionedUsers: MinimumUser[], note: MiNote, nm: NotificationManager) {
|
||||
for (const u of mentionedUsers.filter(u => this.userEntityService.isLocalUser(u))) {
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exist({
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exists({
|
||||
where: {
|
||||
userId: u.id,
|
||||
threadId: note.threadId ?? note.id,
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export class NoteReadService implements OnApplicationShutdown {
|
|||
//#endregion
|
||||
|
||||
// スレッドミュート
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exist({
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exists({
|
||||
where: {
|
||||
userId: userId,
|
||||
threadId: note.threadId ?? note.id,
|
||||
|
|
@ -70,7 +70,7 @@ export class NoteReadService implements OnApplicationShutdown {
|
|||
|
||||
// 2秒経っても既読にならなかったら「未読の投稿がありますよ」イベントを発行する
|
||||
setTimeout(2000, 'unread note', { signal: this.#shutdownController.signal }).then(async () => {
|
||||
const exist = await this.noteUnreadsRepository.exist({ where: { id: unread.id } });
|
||||
const exist = await this.noteUnreadsRepository.exists({ where: { id: unread.id } });
|
||||
|
||||
if (!exist) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ export class ReactionService {
|
|||
|
||||
// リアクションされたユーザーがローカルユーザーなら通知を作成
|
||||
if (note.userHost === null) {
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exist({
|
||||
const isThreadMuted = await this.noteThreadMutingsRepository.exists({
|
||||
where: {
|
||||
userId: note.userId,
|
||||
threadId: note.threadId ?? note.id,
|
||||
|
|
|
|||
|
|
@ -77,12 +77,12 @@ export class SignupService {
|
|||
const secret = generateUserToken();
|
||||
|
||||
// Check username duplication
|
||||
if (await this.usersRepository.exist({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) {
|
||||
if (await this.usersRepository.exists({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) {
|
||||
throw new Error('DUPLICATED_USERNAME');
|
||||
}
|
||||
|
||||
// Check deleted username duplication
|
||||
if (await this.usedUsernamesRepository.exist({ where: { username: username.toLowerCase() } })) {
|
||||
if (await this.usedUsernamesRepository.exists({ where: { username: username.toLowerCase() } })) {
|
||||
throw new Error('USED_USERNAME');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||
let autoAccept = false;
|
||||
|
||||
// 鍵アカウントであっても、既にフォローされていた場合はスルー
|
||||
const isFollowing = await this.followingsRepository.exist({
|
||||
const isFollowing = await this.followingsRepository.exists({
|
||||
where: {
|
||||
followerId: follower.id,
|
||||
followeeId: followee.id,
|
||||
|
|
@ -156,7 +156,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||
|
||||
// フォローしているユーザーは自動承認オプション
|
||||
if (!autoAccept && (this.userEntityService.isLocalUser(followee) && followeeProfile.autoAcceptFollowed)) {
|
||||
const isFollowed = await this.followingsRepository.exist({
|
||||
const isFollowed = await this.followingsRepository.exists({
|
||||
where: {
|
||||
followerId: followee.id,
|
||||
followeeId: follower.id,
|
||||
|
|
@ -170,7 +170,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||
if (followee.isLocked && !autoAccept) {
|
||||
autoAccept = !!(await this.accountMoveService.validateAlsoKnownAs(
|
||||
follower,
|
||||
(oldSrc, newSrc) => this.followingsRepository.exist({
|
||||
(oldSrc, newSrc) => this.followingsRepository.exists({
|
||||
where: {
|
||||
followeeId: followee.id,
|
||||
followerId: newSrc.id,
|
||||
|
|
@ -233,7 +233,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||
|
||||
this.cacheService.userFollowingsCache.refresh(follower.id);
|
||||
|
||||
const requestExist = await this.followRequestsRepository.exist({
|
||||
const requestExist = await this.followRequestsRepository.exists({
|
||||
where: {
|
||||
followeeId: followee.id,
|
||||
followerId: follower.id,
|
||||
|
|
@ -531,7 +531,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||
}
|
||||
}
|
||||
|
||||
const requestExist = await this.followRequestsRepository.exist({
|
||||
const requestExist = await this.followRequestsRepository.exists({
|
||||
where: {
|
||||
followeeId: followee.id,
|
||||
followerId: follower.id,
|
||||
|
|
|
|||
|
|
@ -43,13 +43,13 @@ export class UtilityService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public isSensitiveWordIncluded(text: string, sensitiveWords: string[]): boolean {
|
||||
if (sensitiveWords.length === 0) return false;
|
||||
public isKeyWordIncluded(text: string, keyWords: string[]): boolean {
|
||||
if (keyWords.length === 0) return false;
|
||||
if (text === '') return false;
|
||||
|
||||
const regexpregexp = /^\/(.+)\/(.*)$/;
|
||||
|
||||
const matched = sensitiveWords.some(filter => {
|
||||
const matched = keyWords.some(filter => {
|
||||
// represents RegExp
|
||||
const regexp = filter.match(regexpregexp);
|
||||
// This should never happen due to input sanitisation.
|
||||
|
|
|
|||
|
|
@ -629,7 +629,7 @@ export class ApInboxService {
|
|||
return 'skip: follower not found';
|
||||
}
|
||||
|
||||
const isFollowing = await this.followingsRepository.exist({
|
||||
const isFollowing = await this.followingsRepository.exists({
|
||||
where: {
|
||||
followerId: follower.id,
|
||||
followeeId: actor.id,
|
||||
|
|
@ -686,14 +686,14 @@ export class ApInboxService {
|
|||
return 'skip: フォロー解除しようとしているユーザーはローカルユーザーではありません';
|
||||
}
|
||||
|
||||
const requestExist = await this.followRequestsRepository.exist({
|
||||
const requestExist = await this.followRequestsRepository.exists({
|
||||
where: {
|
||||
followerId: actor.id,
|
||||
followeeId: followee.id,
|
||||
},
|
||||
});
|
||||
|
||||
const isFollowing = await this.followingsRepository.exist({
|
||||
const isFollowing = await this.followingsRepository.exists({
|
||||
where: {
|
||||
followerId: actor.id,
|
||||
followeeId: followee.id,
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ export class ApRendererService {
|
|||
inReplyToNote = await this.notesRepository.findOneBy({ id: note.replyId });
|
||||
|
||||
if (inReplyToNote != null) {
|
||||
const inReplyToUserExist = await this.usersRepository.exist({ where: { id: inReplyToNote.userId } });
|
||||
const inReplyToUserExist = await this.usersRepository.exists({ where: { id: inReplyToNote.userId } });
|
||||
|
||||
if (inReplyToUserExist) {
|
||||
if (inReplyToNote.uri) {
|
||||
|
|
@ -636,7 +636,7 @@ export class ApRendererService {
|
|||
inReplyToNote = await this.notesRepository.findOneBy({ id: note.replyId });
|
||||
|
||||
if (inReplyToNote != null) {
|
||||
const inReplyToUserExist = await this.usersRepository.exist({ where: { id: inReplyToNote.userId } });
|
||||
const inReplyToUserExist = await this.usersRepository.exists({ where: { id: inReplyToNote.userId } });
|
||||
|
||||
if (inReplyToUserExist) {
|
||||
if (inReplyToNote.uri) {
|
||||
|
|
|
|||
|
|
@ -51,14 +51,14 @@ export class ChannelEntityService {
|
|||
|
||||
const banner = channel.bannerId ? await this.driveFilesRepository.findOneBy({ id: channel.bannerId }) : null;
|
||||
|
||||
const isFollowing = meId ? await this.channelFollowingsRepository.exist({
|
||||
const isFollowing = meId ? await this.channelFollowingsRepository.exists({
|
||||
where: {
|
||||
followerId: meId,
|
||||
followeeId: channel.id,
|
||||
},
|
||||
}) : false;
|
||||
|
||||
const isFavorited = meId ? await this.channelFavoritesRepository.exist({
|
||||
const isFavorited = meId ? await this.channelFavoritesRepository.exists({
|
||||
where: {
|
||||
userId: meId,
|
||||
channelId: channel.id,
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ export class ClipEntityService {
|
|||
description: clip.description,
|
||||
isPublic: clip.isPublic,
|
||||
favoritedCount: await this.clipFavoritesRepository.countBy({ clipId: clip.id }),
|
||||
isFavorited: meId ? await this.clipFavoritesRepository.exist({ where: { clipId: clip.id, userId: meId } }) : undefined,
|
||||
isFavorited: meId ? await this.clipFavoritesRepository.exists({ where: { clipId: clip.id, userId: meId } }) : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export class FlashEntityService {
|
|||
summary: flash.summary,
|
||||
script: flash.script,
|
||||
likedCount: flash.likedCount,
|
||||
isLiked: meId ? await this.flashLikesRepository.exist({ where: { flashId: flash.id, userId: meId } }) : undefined,
|
||||
isLiked: meId ? await this.flashLikesRepository.exists({ where: { flashId: flash.id, userId: meId } }) : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export class GalleryPostEntityService {
|
|||
tags: post.tags.length > 0 ? post.tags : undefined,
|
||||
isSensitive: post.isSensitive,
|
||||
likedCount: post.likedCount,
|
||||
isLiked: meId ? await this.galleryLikesRepository.exist({ where: { postId: post.id, userId: meId } }) : undefined,
|
||||
isLiked: meId ? await this.galleryLikesRepository.exists({ where: { postId: post.id, userId: meId } }) : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ export class NoteEntityService implements OnModuleInit {
|
|||
hide = false;
|
||||
} else {
|
||||
if (packedNote.renote) {
|
||||
const isFollowing = await this.followingsRepository.exist({
|
||||
const isFollowing = await this.followingsRepository.exists({
|
||||
where: {
|
||||
followeeId: packedNote.renote.userId,
|
||||
followerId: meId,
|
||||
|
|
@ -124,7 +124,7 @@ export class NoteEntityService implements OnModuleInit {
|
|||
hide = !isFollowing;
|
||||
} else {
|
||||
// フォロワーかどうか
|
||||
const isFollowing = await this.followingsRepository.exist({
|
||||
const isFollowing = await this.followingsRepository.exists({
|
||||
where: {
|
||||
followeeId: packedNote.userId,
|
||||
followerId: meId,
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ export class PageEntityService {
|
|||
eyeCatchingImage: page.eyeCatchingImageId ? await this.driveFileEntityService.pack(page.eyeCatchingImageId) : null,
|
||||
attachedFiles: this.driveFileEntityService.packMany((await Promise.all(attachedFiles)).filter((x): x is MiDriveFile => x != null)),
|
||||
likedCount: page.likedCount,
|
||||
isLiked: meId ? await this.pageLikesRepository.exist({ where: { pageId: page.id, userId: meId } }) : undefined,
|
||||
isLiked: meId ? await this.pageLikesRepository.exists({ where: { pageId: page.id, userId: meId } }) : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,43 +153,43 @@ export class UserEntityService implements OnModuleInit {
|
|||
followerId: me,
|
||||
followeeId: target,
|
||||
}),
|
||||
this.followingsRepository.exist({
|
||||
this.followingsRepository.exists({
|
||||
where: {
|
||||
followerId: target,
|
||||
followeeId: me,
|
||||
},
|
||||
}),
|
||||
this.followRequestsRepository.exist({
|
||||
this.followRequestsRepository.exists({
|
||||
where: {
|
||||
followerId: me,
|
||||
followeeId: target,
|
||||
},
|
||||
}),
|
||||
this.followRequestsRepository.exist({
|
||||
this.followRequestsRepository.exists({
|
||||
where: {
|
||||
followerId: target,
|
||||
followeeId: me,
|
||||
},
|
||||
}),
|
||||
this.blockingsRepository.exist({
|
||||
this.blockingsRepository.exists({
|
||||
where: {
|
||||
blockerId: me,
|
||||
blockeeId: target,
|
||||
},
|
||||
}),
|
||||
this.blockingsRepository.exist({
|
||||
this.blockingsRepository.exists({
|
||||
where: {
|
||||
blockerId: target,
|
||||
blockeeId: me,
|
||||
},
|
||||
}),
|
||||
this.mutingsRepository.exist({
|
||||
this.mutingsRepository.exists({
|
||||
where: {
|
||||
muterId: me,
|
||||
muteeId: target,
|
||||
},
|
||||
}),
|
||||
this.renoteMutingsRepository.exist({
|
||||
this.renoteMutingsRepository.exists({
|
||||
where: {
|
||||
muterId: me,
|
||||
muteeId: target,
|
||||
|
|
@ -216,7 +216,7 @@ export class UserEntityService implements OnModuleInit {
|
|||
/*
|
||||
const myAntennas = (await this.antennaService.getAntennas()).filter(a => a.userId === userId);
|
||||
|
||||
const isUnread = (myAntennas.length > 0 ? await this.antennaNotesRepository.exist({
|
||||
const isUnread = (myAntennas.length > 0 ? await this.antennaNotesRepository.exists({
|
||||
where: {
|
||||
antennaId: In(myAntennas.map(x => x.id)),
|
||||
read: false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue