feat: auto note removal

This commit is contained in:
아르페 2024-02-16 08:21:04 +09:00 committed by 무라쿠모
parent ee6d918d99
commit 82a7cdb204
No known key found for this signature in database
GPG key ID: 139D6573F92DA9F7
10 changed files with 166 additions and 14 deletions

View file

@ -13,6 +13,7 @@ import { DI } from '@/di-symbols.js';
import type Logger from '@/logger.js';
import generateUserToken from '@/misc/generate-native-user-token.js';
import type { UsedUsernamesRepository, UsersRepository } from '@/models/_.js';
import { MiAutoRemovalCondition } from '@/models/AutoRemovalCondition.js';
import { MiUser } from '@/models/User.js';
import { MiUserProfile } from '@/models/UserProfile.js';
import { MiUserKeypair } from '@/models/UserKeypair.js';
@ -137,12 +138,20 @@ export class SignupService {
if (exist) throw new Error(' the username is already used');
const condition = await transactionalEntityManager.save(new MiAutoRemovalCondition({
id: this.idService.gen(),
deleteAfter: 7,
noPiningNotes: false,
noSpecifiedNotes: false,
}));
account = await transactionalEntityManager.save(new MiUser({
id: this.idService.gen(),
username: username,
usernameLower: username.toLowerCase(),
host: this.utilityService.toPunyNullable(host),
token: secret,
autoRemovalConditionId: condition.id,
isRoot: isTheFirstUser,
}));

View file

@ -612,6 +612,8 @@ export class UserEntityService implements OnModuleInit {
notificationRecieveConfig: profile?.notificationRecieveConfig,
emailNotificationTypes: profile?.emailNotificationTypes,
achievements: profile?.achievements,
autoRemoval: user.autoRemoval,
autoRemovalCondition: user.autoRemovalCondition,
loggedInDays: profile?.loggedInDates.length,
policies: policies,
} : {}),

View file

@ -641,6 +641,34 @@ export const packedMeDetailedOnlySchema = {
},
},
},
autoRemoval: {
type: 'boolean',
nullable: false, optional: false,
},
autoRemovalCondition: {
type: 'object',
nullable: false, optional: false,
properties: {
id: {
type: 'string',
nullable: false, optional: false,
format: 'id',
example: 'xxxxxxxxxx',
},
deleteAfter: {
type: 'number',
nullable: false, optional: false,
},
noPiningNotes: {
type: 'boolean',
nullable: false, optional: false,
},
noSpecifiedNotes: {
type: 'boolean',
nullable: false, optional: false,
},
},
},
loggedInDays: {
type: 'number',
nullable: false, optional: false,

View file

@ -259,6 +259,7 @@ import * as ep___i_signinHistory from './endpoints/i/signin-history.js';
import * as ep___i_unpin from './endpoints/i/unpin.js';
import * as ep___i_updateEmail from './endpoints/i/update-email.js';
import * as ep___i_update from './endpoints/i/update.js';
import * as ep___i_updateRemovalCondition from './endpoints/i/update-removal-condition.js';
import * as ep___i_move from './endpoints/i/move.js';
import * as ep___i_webhooks_create from './endpoints/i/webhooks/create.js';
import * as ep___i_webhooks_show from './endpoints/i/webhooks/show.js';
@ -652,6 +653,7 @@ const $i_signinHistory: Provider = { provide: 'ep:i/signin-history', useClass: e
const $i_unpin: Provider = { provide: 'ep:i/unpin', useClass: ep___i_unpin.default };
const $i_updateEmail: Provider = { provide: 'ep:i/update-email', useClass: ep___i_updateEmail.default };
const $i_update: Provider = { provide: 'ep:i/update', useClass: ep___i_update.default };
const $i_updateRemovalCondition: Provider = { provide: 'ep:i/update-removal-condition', useClass: ep___i_updateRemovalCondition.default };
const $i_move: Provider = { provide: 'ep:i/move', useClass: ep___i_move.default };
const $i_webhooks_create: Provider = { provide: 'ep:i/webhooks/create', useClass: ep___i_webhooks_create.default };
const $i_webhooks_list: Provider = { provide: 'ep:i/webhooks/list', useClass: ep___i_webhooks_list.default };
@ -1049,6 +1051,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$i_unpin,
$i_updateEmail,
$i_update,
$i_updateRemovalCondition,
$i_move,
$i_webhooks_create,
$i_webhooks_list,
@ -1440,6 +1443,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$i_unpin,
$i_updateEmail,
$i_update,
$i_updateRemovalCondition,
$i_move,
$i_webhooks_create,
$i_webhooks_list,

View file

@ -259,6 +259,7 @@ import * as ep___i_signinHistory from './endpoints/i/signin-history.js';
import * as ep___i_unpin from './endpoints/i/unpin.js';
import * as ep___i_updateEmail from './endpoints/i/update-email.js';
import * as ep___i_update from './endpoints/i/update.js';
import * as ep___i_update_removal_condition from './endpoints/i/update-removal-condition.js';
import * as ep___i_move from './endpoints/i/move.js';
import * as ep___i_webhooks_create from './endpoints/i/webhooks/create.js';
import * as ep___i_webhooks_show from './endpoints/i/webhooks/show.js';
@ -650,6 +651,7 @@ const eps = [
['i/unpin', ep___i_unpin],
['i/update-email', ep___i_updateEmail],
['i/update', ep___i_update],
['i/update-removal-condition', ep___i_update_removal_condition],
['i/move', ep___i_move],
['i/webhooks/create', ep___i_webhooks_create],
['i/webhooks/list', ep___i_webhooks_list],

View file

@ -0,0 +1,61 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey, cherrypick contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { AutoRemovalConditionRepository, UsersRepository } from '@/models/_.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['account'],
requireCredential: true,
kind: 'write:account',
errors: {
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5',
},
},
res: {
type: 'object',
ref: 'MeDetailed',
},
} as const;
export const paramDef = {
type: 'object',
properties: {
active: { type: 'boolean' },
deleteAfter: { type: 'number' },
noPiningNotes: { type: 'boolean' },
noSpecifiedNotes: { type: 'boolean' },
},
} as const;
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.autoRemovalConditionRepository)
private autoRemovalConditionRepository: AutoRemovalConditionRepository,
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
) {
super(meta, paramDef, async (ps, me) => {
await this.usersRepository.update(me.id, { autoRemoval: false });
const updated = {
deleteAfter: ps.deleteAfter,
noPiningNotes: ps.noPiningNotes,
noSpecifiedNotes: ps.noSpecifiedNotes,
};
await this.autoRemovalConditionRepository.update(me.autoRemovalConditionId, updated);
});
}
}

View file

@ -11,7 +11,7 @@ import { JSDOM } from 'jsdom';
import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js';
import { extractHashtags } from '@/misc/extract-hashtags.js';
import * as Acct from '@/misc/acct.js';
import type { UsersRepository, DriveFilesRepository, UserProfilesRepository, PagesRepository, AutoRemovalConditionRepository } from '@/models/_.js';
import type { UsersRepository, DriveFilesRepository, UserProfilesRepository, PagesRepository } from '@/models/_.js';
import type { MiLocalUser, MiUser } from '@/models/User.js';
import { birthdaySchema, descriptionSchema, locationSchema, nameSchema } from '@/models/User.js';
import type { MiUserProfile } from '@/models/UserProfile.js';
@ -280,9 +280,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
@Inject(DI.pagesRepository)
private pagesRepository: PagesRepository,
@Inject(DI.autoRemovalConditionRepository)
private autoRemovalConditionRepository: AutoRemovalConditionRepository,
private idService: IdService,
private userEntityService: UserEntityService,
private driveFileEntityService: DriveFileEntityService,
@ -350,7 +347,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (typeof ps.isVacation === 'boolean') updates.isVacation = ps.isVacation;
if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote;
if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail;
if (typeof ps.autoRemoval === 'boolean') updates.autoRemoval = ps.autoRemoval;
if (typeof ps.alwaysMarkNsfw === 'boolean') {
if (policy.alwaysMarkNsfw) throw new ApiError(meta.errors.restrictedByRole);
profileUpdates.alwaysMarkNsfw = ps.alwaysMarkNsfw;
@ -527,10 +523,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
this.globalEventService.publishInternalEvent('localUserUpdated', { id: user.id });
}
if (ps.autoRemovalCondition !== undefined) {
await this.autoRemovalConditionRepository.update(user.autoRemovalConditionId, ps.autoRemovalCondition);
}
await this.userProfilesRepository.update(user.id, {
...profileUpdates,
verifiedLinks: [],