Skip to content

Commit

Permalink
feat: log user data to NirilaDeleteUserLogRepository
Browse files Browse the repository at this point in the history
  • Loading branch information
anatawa12 committed Feb 15, 2024
1 parent deba202 commit 9e58ab0
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
4 changes: 3 additions & 1 deletion packages/backend/src/core/entities/UserEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,18 +310,20 @@ export class UserEntityService implements OnModuleInit {
detail?: D,
includeSecrets?: boolean,
userProfile?: MiUserProfile,
asModerator?: boolean,
},
): Promise<IsMeAndIsUserDetailed<ExpectsMe, D>> {
const opts = Object.assign({
detail: false,
includeSecrets: false,
asModerator: undefined as boolean | undefined,
}, options);

const user = typeof src === 'object' ? src : await this.usersRepository.findOneByOrFail({ id: src });

const meId = me ? me.id : null;
const isMe = meId === user.id;
const iAmModerator = me ? await this.roleService.isModerator(me as MiUser) : false;
const iAmModerator = opts.asModerator ?? (me ? await this.roleService.isModerator(me as MiUser) : false);

const relation = meId && !isMe && opts.detail ? await this.getRelation(meId, user.id) : null;
const pins = opts.detail ? await this.userNotePiningsRepository.createQueryBuilder('pin')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@
import { Inject, Injectable } from '@nestjs/common';
import { MoreThan } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { DriveFilesRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import type { DriveFilesRepository, MiUser, NotesRepository, UserProfilesRepository, UsersRepository, NirilaDeleteUserLogRepository, SigninsRepository } from '@/models/_.js';
import type Logger from '@/logger.js';
import { DriveService } from '@/core/DriveService.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import type { MiNote } from '@/models/Note.js';
import { EmailService } from '@/core/EmailService.js';
import { bindThis } from '@/decorators.js';
import { SearchService } from '@/core/SearchService.js';
import { RoleService } from '@/core/RoleService.js';
import { RoleEntityService } from '@/core/entities/RoleEntityService.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type * as Bull from 'bullmq';
import type { DbUserDeleteJobData } from '../types.js';
Expand All @@ -35,6 +39,17 @@ export class DeleteAccountProcessorService {
@Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository,

@Inject(DI.nirilaDeleteUserLogRepository)
private nirilaDeleteUserLogRepository: NirilaDeleteUserLogRepository,

@Inject(DI.signinsRepository)
private signinsRepository: SigninsRepository,

private roleService: RoleService,
private roleEntityService: RoleEntityService,
private idService: IdService,
private userEntityService: UserEntityService,

private driveService: DriveService,
private emailService: EmailService,
private queueLoggerService: QueueLoggerService,
Expand All @@ -43,6 +58,70 @@ export class DeleteAccountProcessorService {
this.logger = this.queueLoggerService.logger.createSubLogger('delete-account');
}

@bindThis
async logDelete(user: MiUser) {
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id });

// data from src/server/api/endpoints/users/show.ts
const detailedUser = await this.userEntityService.pack(user, null, {
detail: true,
asModerator: true,
});

// data from src/server/api/endpoints/admin/show-user.ts

const isModerator = await this.roleService.isModerator(user);
const isSilenced = !(await this.roleService.getUserPolicies(user.id)).canPublicNote;

const signins = await this.signinsRepository.findBy({ userId: user.id });

const roleAssigns = await this.roleService.getUserAssigns(user.id);
const roles = await this.roleService.getUserRoles(user.id);

const adminInfo = {
email: profile.email,
emailVerified: profile.emailVerified,
autoAcceptFollowed: profile.autoAcceptFollowed,
noCrawle: profile.noCrawle,
preventAiLearning: profile.preventAiLearning,
alwaysMarkNsfw: profile.alwaysMarkNsfw,
autoSensitive: profile.autoSensitive,
carefulBot: profile.carefulBot,
injectFeaturedNote: profile.injectFeaturedNote,
receiveAnnouncementEmail: profile.receiveAnnouncementEmail,
mutedWords: profile.mutedWords,
mutedInstances: profile.mutedInstances,
notificationRecieveConfig: profile.notificationRecieveConfig,
isModerator: isModerator,
isSilenced: isSilenced,
isSuspended: user.isSuspended,
isHibernated: user.isHibernated,
lastActiveDate: user.lastActiveDate,
moderationNote: profile.moderationNote ?? '',
signins,
policies: await this.roleService.getUserPolicies(user.id),
roles: await this.roleEntityService.packMany(roles, { id: user.id }), // note: me is unused param
roleAssigns: roleAssigns.map(a => ({
createdAt: this.idService.parse(a.id).date.toISOString(),
expiresAt: a.expiresAt ? a.expiresAt.toISOString() : null,
roleId: a.roleId,
})),
};

const info: Record<string, any> = {
user: detailedUser,
adminInfo,
};

await this.nirilaDeleteUserLogRepository.insert({
id: this.idService.gen(),
userId: user.id,
username: user.username,
email: profile.email,
info,
});
}

@bindThis
public async process(job: Bull.Job<DbUserDeleteJobData>): Promise<string | void> {
this.logger.info(`Deleting account of ${job.data.user.id} ...`);
Expand All @@ -52,6 +131,12 @@ export class DeleteAccountProcessorService {
return;
}

try {
this.logDelete(user);
} catch (e) {
this.logger.error(`Failed to log delete: ${e}`);
}

{ // Delete notes
let cursor: MiNote['id'] | null = null;

Expand Down

0 comments on commit 9e58ab0

Please sign in to comment.