summaryrefslogtreecommitdiff
path: root/packages/backend/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend/src')
-rw-r--r--packages/backend/src/core/RoleService.ts29
-rw-r--r--packages/backend/src/core/UserListService.ts4
-rw-r--r--packages/backend/src/core/entities/NotificationEntityService.ts11
-rw-r--r--packages/backend/src/models/Notification.ts8
-rw-r--r--packages/backend/src/models/json-schema/user.ts2
-rw-r--r--packages/backend/src/types.ts17
6 files changed, 56 insertions, 15 deletions
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index 4de719d6a0..d354faa7c2 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -6,7 +6,14 @@
import { Inject, Injectable } from '@nestjs/common';
import * as Redis from 'ioredis';
import { In } from 'typeorm';
-import type { MiRole, MiRoleAssignment, RoleAssignmentsRepository, RolesRepository, UsersRepository } from '@/models/_.js';
+import { ModuleRef } from '@nestjs/core';
+import type {
+ MiRole,
+ MiRoleAssignment,
+ RoleAssignmentsRepository,
+ RolesRepository,
+ UsersRepository,
+} from '@/models/_.js';
import { MemoryKVCache, MemorySingleCache } from '@/misc/cache.js';
import type { MiUser } from '@/models/User.js';
import { DI } from '@/di-symbols.js';
@@ -16,12 +23,13 @@ import { CacheService } from '@/core/CacheService.js';
import type { RoleCondFormulaValue } from '@/models/Role.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import type { GlobalEvents } from '@/core/GlobalEventService.js';
-import { IdService } from '@/core/IdService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
+import { IdService } from '@/core/IdService.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
import type { Packed } from '@/misc/json-schema.js';
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
-import type { OnApplicationShutdown } from '@nestjs/common';
+import { NotificationService } from '@/core/NotificationService.js';
+import type { OnApplicationShutdown, OnModuleInit } from '@nestjs/common';
export type RolePolicies = {
gtlAvailable: boolean;
@@ -78,14 +86,17 @@ export const DEFAULT_POLICIES: RolePolicies = {
};
@Injectable()
-export class RoleService implements OnApplicationShutdown {
+export class RoleService implements OnApplicationShutdown, OnModuleInit {
private rolesCache: MemorySingleCache<MiRole[]>;
private roleAssignmentByUserIdCache: MemoryKVCache<MiRoleAssignment[]>;
+ private notificationService: NotificationService;
public static AlreadyAssignedError = class extends Error {};
public static NotAssignedError = class extends Error {};
constructor(
+ private moduleRef: ModuleRef,
+
@Inject(DI.redis)
private redisClient: Redis.Redis,
@@ -120,6 +131,10 @@ export class RoleService implements OnApplicationShutdown {
this.redisForSub.on('message', this.onMessage);
}
+ async onModuleInit() {
+ this.notificationService = this.moduleRef.get(NotificationService.name);
+ }
+
@bindThis
private async onMessage(_: string, data: string): Promise<void> {
const obj = JSON.parse(data);
@@ -427,6 +442,12 @@ export class RoleService implements OnApplicationShutdown {
this.globalEventService.publishInternalEvent('userRoleAssigned', created);
+ if (role.isPublic) {
+ this.notificationService.createNotification(userId, 'roleAssigned', {
+ roleId: roleId,
+ });
+ }
+
if (moderator) {
const user = await this.usersRepository.findOneByOrFail({ id: userId });
this.moderationLogService.log(moderator, 'assignRole', {
diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts
index 702c731fc3..832b715d97 100644
--- a/packages/backend/src/core/UserListService.ts
+++ b/packages/backend/src/core/UserListService.ts
@@ -10,15 +10,15 @@ import type { MiUser } from '@/models/User.js';
import type { MiUserList } from '@/models/UserList.js';
import type { MiUserListMembership } from '@/models/UserListMembership.js';
import { IdService } from '@/core/IdService.js';
+import type { GlobalEvents } from '@/core/GlobalEventService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { DI } from '@/di-symbols.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { ProxyAccountService } from '@/core/ProxyAccountService.js';
import { bindThis } from '@/decorators.js';
-import { RoleService } from '@/core/RoleService.js';
import { QueueService } from '@/core/QueueService.js';
import { RedisKVCache } from '@/misc/cache.js';
-import type { GlobalEvents } from '@/core/GlobalEventService.js';
+import { RoleService } from '@/core/RoleService.js';
@Injectable()
export class UserListService implements OnApplicationShutdown {
diff --git a/packages/backend/src/core/entities/NotificationEntityService.ts b/packages/backend/src/core/entities/NotificationEntityService.ts
index e723ea5a55..f2124998ac 100644
--- a/packages/backend/src/core/entities/NotificationEntityService.ts
+++ b/packages/backend/src/core/entities/NotificationEntityService.ts
@@ -15,8 +15,8 @@ import type { Packed } from '@/misc/json-schema.js';
import { bindThis } from '@/decorators.js';
import { isNotNull } from '@/misc/is-not-null.js';
import { FilterUnionByProperty, notificationTypes } from '@/types.js';
+import { RoleEntityService } from './RoleEntityService.js';
import type { OnModuleInit } from '@nestjs/common';
-import type { CustomEmojiService } from '../CustomEmojiService.js';
import type { UserEntityService } from './UserEntityService.js';
import type { NoteEntityService } from './NoteEntityService.js';
@@ -27,7 +27,7 @@ const NOTE_REQUIRED_GROUPED_NOTIFICATION_TYPES = new Set(['note', 'mention', 're
export class NotificationEntityService implements OnModuleInit {
private userEntityService: UserEntityService;
private noteEntityService: NoteEntityService;
- private customEmojiService: CustomEmojiService;
+ private roleEntityService: RoleEntityService;
constructor(
private moduleRef: ModuleRef,
@@ -43,14 +43,13 @@ export class NotificationEntityService implements OnModuleInit {
//private userEntityService: UserEntityService,
//private noteEntityService: NoteEntityService,
- //private customEmojiService: CustomEmojiService,
) {
}
onModuleInit() {
this.userEntityService = this.moduleRef.get('UserEntityService');
this.noteEntityService = this.moduleRef.get('NoteEntityService');
- this.customEmojiService = this.moduleRef.get('CustomEmojiService');
+ this.roleEntityService = this.moduleRef.get('RoleEntityService');
}
@bindThis
@@ -81,6 +80,7 @@ export class NotificationEntityService implements OnModuleInit {
detail: false,
})
) : undefined;
+ const role = notification.type === 'roleAssigned' ? await this.roleEntityService.pack(notification.roleId) : undefined;
return await awaitAll({
id: notification.id,
@@ -92,6 +92,9 @@ export class NotificationEntityService implements OnModuleInit {
...(notification.type === 'reaction' ? {
reaction: notification.reaction,
} : {}),
+ ...(notification.type === 'roleAssigned' ? {
+ role: role,
+ } : {}),
...(notification.type === 'achievementEarned' ? {
achievement: notification.achievement,
} : {}),
diff --git a/packages/backend/src/models/Notification.ts b/packages/backend/src/models/Notification.ts
index 1d5fc124e2..3bc2edaa0d 100644
--- a/packages/backend/src/models/Notification.ts
+++ b/packages/backend/src/models/Notification.ts
@@ -3,11 +3,10 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { notificationTypes } from '@/types.js';
import { MiUser } from './User.js';
import { MiNote } from './Note.js';
-import { MiFollowRequest } from './FollowRequest.js';
import { MiAccessToken } from './AccessToken.js';
+import { MiRole } from './Role.js';
export type MiNotification = {
type: 'note';
@@ -69,6 +68,11 @@ export type MiNotification = {
createdAt: string;
notifierId: MiUser['id'];
} | {
+ type: 'roleAssigned';
+ id: string;
+ createdAt: string;
+ roleId: MiRole['id'];
+} | {
type: 'achievementEarned';
id: string;
createdAt: string;
diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts
index 1b86b1bf10..6a0d43b1ac 100644
--- a/packages/backend/src/models/json-schema/user.ts
+++ b/packages/backend/src/models/json-schema/user.ts
@@ -554,9 +554,7 @@ export const packedMeDetailedOnlySchema = {
mention: notificationRecieveConfig,
reaction: notificationRecieveConfig,
pollEnded: notificationRecieveConfig,
- achievementEarned: notificationRecieveConfig,
receiveFollowRequest: notificationRecieveConfig,
- followRequestAccepted: notificationRecieveConfig,
},
},
emailNotificationTypes: {
diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts
index e085407de0..361a4931eb 100644
--- a/packages/backend/src/types.ts
+++ b/packages/backend/src/types.ts
@@ -14,11 +14,26 @@
* pollEnded - 自分のアンケートもしくは自分が投票したアンケートが終了した
* receiveFollowRequest - フォローリクエストされた
* followRequestAccepted - 自分の送ったフォローリクエストが承認された
+ * roleAssigned - ロールが付与された
* achievementEarned - 実績を獲得
* app - アプリ通知
* test - テスト通知(サーバー側)
*/
-export const notificationTypes = ['note', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app', 'test'] as const;
+export const notificationTypes = [
+ 'note',
+ 'follow',
+ 'mention',
+ 'reply',
+ 'renote',
+ 'quote',
+ 'reaction',
+ 'pollEnded',
+ 'receiveFollowRequest',
+ 'followRequestAccepted',
+ 'roleAssigned',
+ 'achievementEarned',
+ 'app',
+ 'test'] as const;
export const obsoleteNotificationTypes = ['pollVote', 'groupInvited'] as const;
export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const;