Merge branch 'develop' into re-ed25519
This commit is contained in:
commit
1721c39f2a
182 changed files with 6500 additions and 4345 deletions
|
|
@ -44,7 +44,7 @@ export class AbuseReportNotificationService implements OnApplicationShutdown {
|
|||
|
||||
/**
|
||||
* 管理者用Redisイベントを用いて{@link abuseReports}の内容を管理者各位に通知する.
|
||||
* 通知先ユーザは{@link RoleService.getModeratorIds}の取得結果に依る.
|
||||
* 通知先ユーザは{@link getModeratorIds}の取得結果に依る.
|
||||
*
|
||||
* @see RoleService.getModeratorIds
|
||||
* @see GlobalEventService.publishAdminStream
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import { RoleService } from '@/core/RoleService.js';
|
|||
import { correctFilename } from '@/misc/correct-filename.js';
|
||||
import { isMimeImage } from '@/misc/is-mime-image.js';
|
||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
|
||||
type AddFileArgs = {
|
||||
/** User who wish to add file */
|
||||
|
|
@ -127,6 +128,7 @@ export class DriveService {
|
|||
private driveChart: DriveChart,
|
||||
private perUserDriveChart: PerUserDriveChart,
|
||||
private instanceChart: InstanceChart,
|
||||
private utilityService: UtilityService,
|
||||
) {
|
||||
const logger = new Logger('drive', 'blue');
|
||||
this.registerLogger = logger.createSubLogger('register', 'yellow');
|
||||
|
|
@ -587,6 +589,7 @@ export class DriveService {
|
|||
sensitive ?? false
|
||||
: false;
|
||||
|
||||
if (user && this.utilityService.isMediaSilencedHost(instance.mediaSilencedHosts, user.host)) file.isSensitive = true;
|
||||
if (info.sensitive && profile!.autoSensitive) file.isSensitive = true;
|
||||
if (info.sensitive && instance.setSensitiveFlagAutomatically) file.isSensitive = true;
|
||||
if (userRoleNSFW) file.isSensitive = true;
|
||||
|
|
|
|||
|
|
@ -364,6 +364,9 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
mentionedUsers = data.apMentions ?? await this.extractMentionedUsers(user, combinedTokens);
|
||||
}
|
||||
|
||||
// if the host is media-silenced, custom emojis are not allowed
|
||||
if (this.utilityService.isMediaSilencedHost(meta.mediaSilencedHosts, user.host)) emojis = [];
|
||||
|
||||
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)) {
|
||||
|
|
@ -933,10 +936,13 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
}
|
||||
}
|
||||
|
||||
if (note.visibility !== 'specified' || !note.visibleUserIds.some(v => v === user.id)) { // 自分自身のHTL
|
||||
this.fanoutTimelineService.push(`homeTimeline:${user.id}`, note.id, meta.perUserHomeTimelineCacheMax, r);
|
||||
if (note.fileIds.length > 0) {
|
||||
this.fanoutTimelineService.push(`homeTimelineWithFiles:${user.id}`, note.id, meta.perUserHomeTimelineCacheMax / 2, r);
|
||||
// 自分自身のHTL
|
||||
if (note.userHost == null) {
|
||||
if (note.visibility !== 'specified' || !note.visibleUserIds.some(v => v === user.id)) {
|
||||
this.fanoutTimelineService.push(`homeTimeline:${user.id}`, note.id, meta.perUserHomeTimelineCacheMax, r);
|
||||
if (note.fileIds.length > 0) {
|
||||
this.fanoutTimelineService.push(`homeTimelineWithFiles:${user.id}`, note.id, meta.perUserHomeTimelineCacheMax / 2, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ export class ReactionService {
|
|||
|
||||
@bindThis
|
||||
public async create(user: { id: MiUser['id']; host: MiUser['host']; isBot: MiUser['isBot'] }, note: MiNote, _reaction?: string | null) {
|
||||
const meta = await this.metaService.fetch();
|
||||
|
||||
// Check blocking
|
||||
if (note.userId !== user.id) {
|
||||
const blocked = await this.userBlockingService.checkBlocked(note.userId, user.id);
|
||||
|
|
@ -148,6 +150,11 @@ export class ReactionService {
|
|||
if ((note.reactionAcceptance === 'nonSensitiveOnly' || note.reactionAcceptance === 'nonSensitiveOnlyForLocalLikeOnlyForRemote') && emoji.isSensitive) {
|
||||
reaction = FALLBACK;
|
||||
}
|
||||
|
||||
// for media silenced host, custom emoji reactions are not allowed
|
||||
if (reacterHost != null && this.utilityService.isMediaSilencedHost(meta.mediaSilencedHosts, reacterHost)) {
|
||||
reaction = FALLBACK;
|
||||
}
|
||||
} else {
|
||||
// リアクションとして使う権限がない
|
||||
reaction = FALLBACK;
|
||||
|
|
@ -220,8 +227,6 @@ export class ReactionService {
|
|||
}
|
||||
}
|
||||
|
||||
const meta = await this.metaService.fetch();
|
||||
|
||||
if (meta.enableChartsForRemoteUser || (user.host == null)) {
|
||||
this.perUserReactionsChart.update(user, note);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -505,14 +505,15 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
|||
|
||||
this.globalEventService.publishInternalEvent('userRoleAssigned', created);
|
||||
|
||||
if (role.isPublic) {
|
||||
const user = await this.usersRepository.findOneByOrFail({ id: userId });
|
||||
|
||||
if (role.isPublic && user.host === null) {
|
||||
this.notificationService.createNotification(userId, 'roleAssigned', {
|
||||
roleId: roleId,
|
||||
});
|
||||
}
|
||||
|
||||
if (moderator) {
|
||||
const user = await this.usersRepository.findOneByOrFail({ id: userId });
|
||||
this.moderationLogService.log(moderator, 'assignRole', {
|
||||
roleId: roleId,
|
||||
roleName: role.name,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import UsersChart from '@/core/chart/charts/users.js';
|
|||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { genRSAAndEd25519KeyPair } from '@/misc/gen-key-pair.js';
|
||||
import { UserService } from '@/core/UserService.js';
|
||||
|
||||
@Injectable()
|
||||
export class SignupService {
|
||||
|
|
@ -35,6 +36,7 @@ export class SignupService {
|
|||
private usedUsernamesRepository: UsedUsernamesRepository,
|
||||
|
||||
private utilityService: UtilityService,
|
||||
private userService: UserService,
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
private metaService: MetaService,
|
||||
|
|
@ -132,7 +134,8 @@ export class SignupService {
|
|||
}));
|
||||
});
|
||||
|
||||
this.usersChart.update(account, true);
|
||||
this.usersChart.update(account, true).then();
|
||||
this.userService.notifySystemWebhook(account, 'userCreated').then();
|
||||
|
||||
return { account, secret };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,8 +279,10 @@ export class UserFollowingService implements OnModuleInit {
|
|||
});
|
||||
|
||||
// 通知を作成
|
||||
this.notificationService.createNotification(follower.id, 'followRequestAccepted', {
|
||||
}, followee.id);
|
||||
if (follower.host === null) {
|
||||
this.notificationService.createNotification(follower.id, 'followRequestAccepted', {
|
||||
}, followee.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyFollowed) return;
|
||||
|
|
|
|||
|
|
@ -8,15 +8,18 @@ import type { FollowingsRepository, UsersRepository } from '@/models/_.js';
|
|||
import type { MiUser } from '@/models/User.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor(
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
@Inject(DI.followingsRepository)
|
||||
private followingsRepository: FollowingsRepository,
|
||||
private systemWebhookService: SystemWebhookService,
|
||||
private userEntityService: UserEntityService,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -50,4 +53,23 @@ export class UserService {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SystemWebhookを用いてユーザに関する操作内容を管理者各位に通知する.
|
||||
* ここではJobQueueへのエンキューのみを行うため、即時実行されない.
|
||||
*
|
||||
* @see SystemWebhookService.enqueueSystemWebhook
|
||||
*/
|
||||
@bindThis
|
||||
public async notifySystemWebhook(user: MiUser, type: 'userCreated') {
|
||||
const packedUser = await this.userEntityService.pack(user, null, { schema: 'UserLite' });
|
||||
const recipientWebhookIds = await this.systemWebhookService.fetchSystemWebhooks({ isActive: true, on: [type] });
|
||||
for (const webhookId of recipientWebhookIds) {
|
||||
await this.systemWebhookService.enqueueSystemWebhook(
|
||||
webhookId,
|
||||
type,
|
||||
packedUser,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ export class UtilityService {
|
|||
return silencedHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public isMediaSilencedHost(silencedHosts: string[] | undefined, host: string | null): boolean {
|
||||
if (!silencedHosts || host == null) return false;
|
||||
return silencedHosts.some(x => host.toLowerCase() === x);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public concatNoteContentsForKeyWordCheck(content: {
|
||||
cw?: string | null;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ export class InstanceEntityService {
|
|||
maintainerName: instance.maintainerName,
|
||||
maintainerEmail: instance.maintainerEmail,
|
||||
isSilenced: this.utilityService.isSilencedHost(meta.silencedHosts, instance.host),
|
||||
isMediaSilenced: this.utilityService.isMediaSilencedHost(meta.mediaSilencedHosts, instance.host),
|
||||
iconUrl: instance.iconUrl,
|
||||
faviconUrl: instance.faviconUrl,
|
||||
themeColor: instance.themeColor,
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ export class MetaEntityService {
|
|||
|
||||
mediaProxy: this.config.mediaProxy,
|
||||
enableUrlPreview: instance.urlPreviewEnabled,
|
||||
noteSearchableScope: (this.config.meilisearch == null || this.config.meilisearch.scope !== 'local') ? 'global' : 'local',
|
||||
};
|
||||
|
||||
return packed;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue