summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2021-09-22 17:34:48 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2021-09-22 17:34:48 +0900
commit9208825975f56bab8aca7ae8d6507f6cfe0f599a (patch)
tree2472c0ba06fd4adf6bdb150a1ddb48059b449034 /src
parentenhance(client): リスト、アンテナタイムラインを個別ページ... (diff)
downloadmisskey-9208825975f56bab8aca7ae8d6507f6cfe0f599a.tar.gz
misskey-9208825975f56bab8aca7ae8d6507f6cfe0f599a.tar.bz2
misskey-9208825975f56bab8aca7ae8d6507f6cfe0f599a.zip
feat(server): 管理者用アカウント削除API実装
動作確認済み Resolve #7735
Diffstat (limited to 'src')
-rw-r--r--src/queue/index.ts5
-rw-r--r--src/queue/processors/db/delete-account.ts11
-rw-r--r--src/queue/types.ts7
-rw-r--r--src/server/api/endpoints/admin/accounts/delete.ts58
-rw-r--r--src/server/api/endpoints/i/delete-account.ts4
5 files changed, 78 insertions, 7 deletions
diff --git a/src/queue/index.ts b/src/queue/index.ts
index ee34ed47e4..0ce10a4c60 100644
--- a/src/queue/index.ts
+++ b/src/queue/index.ts
@@ -173,9 +173,10 @@ export function createImportUserListsJob(user: ThinUser, fileId: DriveFile['id']
});
}
-export function createDeleteAccountJob(user: ThinUser) {
+export function createDeleteAccountJob(user: ThinUser, opts: { soft?: boolean; }) {
return dbQueue.add('deleteAccount', {
- user: user
+ user: user,
+ soft: opts.soft
}, {
removeOnComplete: true,
removeOnFail: true
diff --git a/src/queue/processors/db/delete-account.ts b/src/queue/processors/db/delete-account.ts
index 65327754c2..e54f38e35e 100644
--- a/src/queue/processors/db/delete-account.ts
+++ b/src/queue/processors/db/delete-account.ts
@@ -1,7 +1,7 @@
import * as Bull from 'bull';
import { queueLogger } from '../../logger';
import { DriveFiles, Notes, UserProfiles, Users } from '@/models/index';
-import { DbUserJobData } from '@/queue/types';
+import { DbUserDeleteJobData } from '@/queue/types';
import { Note } from '@/models/entities/note';
import { DriveFile } from '@/models/entities/drive-file';
import { MoreThan } from 'typeorm';
@@ -10,7 +10,7 @@ import { sendEmail } from '@/services/send-email';
const logger = queueLogger.createSubLogger('delete-account');
-export async function deleteAccount(job: Bull.Job<DbUserJobData>): Promise<string | void> {
+export async function deleteAccount(job: Bull.Job<DbUserDeleteJobData>): Promise<string | void> {
logger.info(`Deleting account of ${job.data.user.id} ...`);
const user = await Users.findOne(job.data.user.id);
@@ -83,7 +83,12 @@ export async function deleteAccount(job: Bull.Job<DbUserJobData>): Promise<strin
}
}
- await Users.delete(job.data.user.id);
+ // soft指定されている場合は物理削除しない
+ if (job.data.soft) {
+ // nop
+ } else {
+ await Users.delete(job.data.user.id);
+ }
return 'Account deleted';
}
diff --git a/src/queue/types.ts b/src/queue/types.ts
index a782fc6b97..39cab29966 100644
--- a/src/queue/types.ts
+++ b/src/queue/types.ts
@@ -17,12 +17,17 @@ export type InboxJobData = {
signature: httpSignature.IParsedSignature;
};
-export type DbJobData = DbUserJobData | DbUserImportJobData;
+export type DbJobData = DbUserJobData | DbUserImportJobData | DbUserDeleteJobData;
export type DbUserJobData = {
user: ThinUser;
};
+export type DbUserDeleteJobData = {
+ user: ThinUser;
+ soft?: boolean;
+};
+
export type DbUserImportJobData = {
user: ThinUser;
fileId: DriveFile['id'];
diff --git a/src/server/api/endpoints/admin/accounts/delete.ts b/src/server/api/endpoints/admin/accounts/delete.ts
new file mode 100644
index 0000000000..4e8a559805
--- /dev/null
+++ b/src/server/api/endpoints/admin/accounts/delete.ts
@@ -0,0 +1,58 @@
+import $ from 'cafy';
+import define from '../../../define';
+import { Users } from '@/models/index';
+import { doPostSuspend } from '@/services/suspend-user';
+import { publishUserEvent } from '@/services/stream';
+import { createDeleteAccountJob } from '@/queue';
+import { ID } from '@/misc/cafy-id';
+
+export const meta = {
+ tags: ['admin'],
+
+ requireCredential: true as const,
+ requireModerator: true,
+
+ params: {
+ userId: {
+ validator: $.type(ID),
+ },
+ }
+};
+
+export default define(meta, async (ps, me) => {
+ const user = await Users.findOne(ps.userId);
+
+ if (user == null) {
+ throw new Error('user not found');
+ }
+
+ if (user.isAdmin) {
+ throw new Error('cannot suspend admin');
+ }
+
+ if (user.isModerator) {
+ throw new Error('cannot suspend moderator');
+ }
+
+ if (Users.isLocalUser(user)) {
+ // 物理削除する前にDelete activityを送信する
+ await doPostSuspend(user).catch(e => {});
+
+ createDeleteAccountJob(user, {
+ soft: false
+ });
+ } else {
+ createDeleteAccountJob(user, {
+ soft: true // リモートユーザーの削除は、完全にDBから物理削除してしまうと再度連合してきてアカウントが復活する可能性があるため、soft指定する
+ });
+ }
+
+ await Users.update(user.id, {
+ isDeleted: true,
+ });
+
+ if (Users.isLocalUser(user)) {
+ // Terminate streaming
+ publishUserEvent(user.id, 'terminate', {});
+ }
+});
diff --git a/src/server/api/endpoints/i/delete-account.ts b/src/server/api/endpoints/i/delete-account.ts
index 77f11925cd..10e5adf64a 100644
--- a/src/server/api/endpoints/i/delete-account.ts
+++ b/src/server/api/endpoints/i/delete-account.ts
@@ -35,7 +35,9 @@ export default define(meta, async (ps, user) => {
// 物理削除する前にDelete activityを送信する
await doPostSuspend(user).catch(e => {});
- createDeleteAccountJob(user);
+ createDeleteAccountJob(user, {
+ soft: false
+ });
await Users.update(user.id, {
isDeleted: true,