add delete account cron
This commit is contained in:
parent
706387b9ad
commit
04b4761aee
@ -31,6 +31,7 @@
|
||||
"@nestjs/graphql": "^13.1.0",
|
||||
"@nestjs/mapped-types": "*",
|
||||
"@nestjs/platform-express": "^11.0.1",
|
||||
"@nestjs/schedule": "^6.0.0",
|
||||
"@prisma/client": "^6.10.1",
|
||||
"@react-email/components": "^0.1.1",
|
||||
"@react-email/html": "^0.0.11",
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { getGraphQLConfig } from '@/src/core/config/graphql.config'
|
||||
import { AccountModule } from '@/src/module/auth/account/account.module'
|
||||
import { DeactivateModule } from '@/src/module/auth/deactivate/deactivate.module';
|
||||
import { DeactivateModule } from '@/src/module/auth/deactivate/deactivate.module'
|
||||
import { PasswordRecoveryModule } from '@/src/module/auth/password-recovery/password-recovery.module'
|
||||
import { SessionModule } from '@/src/module/auth/session/session.module'
|
||||
import { TotpModule } from '@/src/module/auth/totp/totp.module'
|
||||
import { VerificationModule } from '@/src/module/auth/verification/verification.module'
|
||||
import { CronModule } from '@/src/module/cron/cron.module'
|
||||
import { MailModule } from '@/src/module/libs/mail/mail.module'
|
||||
import { IS_DEV } from '@/src/shared/util/is-dev.util'
|
||||
import { ApolloDriver } from '@nestjs/apollo'
|
||||
@ -29,6 +30,7 @@ import { RedisModule } from './redis/redis.module'
|
||||
PrismaModule,
|
||||
RedisModule,
|
||||
MailModule,
|
||||
CronModule,
|
||||
AccountModule,
|
||||
SessionModule,
|
||||
VerificationModule,
|
||||
|
||||
9
backend/src/module/cron/cron.module.ts
Normal file
9
backend/src/module/cron/cron.module.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { ScheduleModule } from '@nestjs/schedule'
|
||||
import { CronService } from './cron.service'
|
||||
|
||||
@Module({
|
||||
imports: [ScheduleModule.forRoot()],
|
||||
providers: [CronService],
|
||||
})
|
||||
export class CronModule {}
|
||||
42
backend/src/module/cron/cron.service.ts
Normal file
42
backend/src/module/cron/cron.service.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { PrismaService } from '@/src/core/prisma/prisma.service'
|
||||
import { MailService } from '@/src/module/libs/mail/mail.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { Cron, CronExpression } from '@nestjs/schedule'
|
||||
|
||||
@Injectable()
|
||||
export class CronService {
|
||||
constructor(
|
||||
private readonly prismaService: PrismaService,
|
||||
private readonly mailService: MailService,
|
||||
) {
|
||||
}
|
||||
|
||||
@Cron(CronExpression.EVERY_DAY_AT_NOON)
|
||||
private async deleteDeactivatedAccounts() {
|
||||
const sevenDayAgo = new Date()
|
||||
sevenDayAgo.setDate(sevenDayAgo.getDay() - 7)
|
||||
|
||||
const deactivatedAccounts = await this.prismaService.user.findMany({
|
||||
where: {
|
||||
isDeactivated: true,
|
||||
deactivatedAt: {
|
||||
lte: sevenDayAgo,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
for (const user of deactivatedAccounts) {
|
||||
console.log('Deactivate user', user.name, user.email)
|
||||
await this.mailService.sendAccountDeletion(user.email)
|
||||
}
|
||||
|
||||
await this.prismaService.user.deleteMany({
|
||||
where: {
|
||||
isDeactivated: true,
|
||||
deactivatedAt: {
|
||||
lte: sevenDayAgo,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
import { AccountDeletionTemplate } from '@/src/module/libs/mail/templates/account-deletion.template'
|
||||
import { DeactivateTemplate } from '@/src/module/libs/mail/templates/deactivate.template'
|
||||
import PasswordRecoveryTemplate from '@/src/module/libs/mail/templates/password-recovery.template'
|
||||
import { SessionInfo } from '@/src/shared/types/session-metadata.types'
|
||||
@ -35,6 +36,13 @@ export class MailService {
|
||||
void this.sendMail(email, 'Деактивация аккаунта', html)
|
||||
}
|
||||
|
||||
public async sendAccountDeletion(email: string) {
|
||||
const domain = this.configService.getOrThrow<string>('ALLOWED_ORIGIN')
|
||||
const html = await render(AccountDeletionTemplate({ domain }))
|
||||
|
||||
void this.sendMail(email, 'Удаление аккаунта', html)
|
||||
}
|
||||
|
||||
private sendMail(email: string, subject: string, html: string) {
|
||||
return this.mailerService.sendMail({
|
||||
to: email,
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
import {
|
||||
Body,
|
||||
Head,
|
||||
Heading,
|
||||
Html,
|
||||
Link,
|
||||
Preview,
|
||||
Section,
|
||||
Tailwind,
|
||||
Text,
|
||||
} from '@react-email/components'
|
||||
import * as React from 'react'
|
||||
|
||||
interface AccountDeletionTemplateProps {
|
||||
domain: string
|
||||
}
|
||||
|
||||
export function AccountDeletionTemplate({ domain }: AccountDeletionTemplateProps) {
|
||||
const registerLink = `${domain}/account/create`
|
||||
|
||||
return (
|
||||
<Html>
|
||||
<Head />
|
||||
<Preview>Аккаунт удалён</Preview>
|
||||
<Tailwind>
|
||||
<Body className="max-w-2xl mx-auto p-6 bg-slate-50">
|
||||
<Section className="text-center">
|
||||
<Heading className="text-3xl text-black font-bold">
|
||||
Ваш аккаунт был полностью удалён
|
||||
</Heading>
|
||||
<Text className="text-base text-black mt-2">
|
||||
Ваш аккаунт был полностью стерт из базы данных TeaStream. Все ваши данные и информация были удалены безвозвратно.
|
||||
</Text>
|
||||
</Section>
|
||||
|
||||
<Section className="bg-white text-black text-center rounded-lg shadow-md p-6 mb-4">
|
||||
<Text>
|
||||
Вы больше не будете получать уведомления в Telegram и на почту.
|
||||
</Text>
|
||||
<Text>
|
||||
Если вы захотите вернуться на платформу, вы можете зарегистрироваться по следующей ссылке:
|
||||
</Text>
|
||||
<Link
|
||||
href={registerLink}
|
||||
className="inline-flex justify-center items-center rounded-md mt-2 text-sm font-medium text-white bg-[#18B9AE] px-5 py-2 rounded-full"
|
||||
>
|
||||
Зарегистрироваться на Teastream
|
||||
</Link>
|
||||
</Section>
|
||||
|
||||
<Section className="text-center text-black">
|
||||
<Text>
|
||||
Спасибо, что были с нами! Мы всегда будем рады видеть вас на платформе.
|
||||
</Text>
|
||||
</Section>
|
||||
</Body>
|
||||
</Tailwind>
|
||||
</Html>
|
||||
)
|
||||
}
|
||||
@ -1408,6 +1408,13 @@
|
||||
path-to-regexp "8.2.0"
|
||||
tslib "2.8.1"
|
||||
|
||||
"@nestjs/schedule@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@nestjs/schedule/-/schedule-6.0.0.tgz#c8069d1f19742e418a617af76311ab853cb48f0a"
|
||||
integrity sha512-aQySMw6tw2nhitELXd3EiRacQRgzUKD9mFcUZVOJ7jPLqIBvXOyvRWLsK9SdurGA+jjziAlMef7iB5ZEFFoQpw==
|
||||
dependencies:
|
||||
cron "4.3.0"
|
||||
|
||||
"@nestjs/schematics@^11.0.0", "@nestjs/schematics@^11.0.1":
|
||||
version "11.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@nestjs/schematics/-/schematics-11.0.5.tgz#cee2fb26f3273fb3874398aad3006517e6b802f9"
|
||||
@ -2096,6 +2103,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a"
|
||||
integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==
|
||||
|
||||
"@types/luxon@~3.6.0":
|
||||
version "3.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-3.6.2.tgz#be6536931801f437eafcb9c0f6d6781f72308041"
|
||||
integrity sha512-R/BdP7OxEMc44l2Ex5lSXHoIXTB2JLNa3y2QISIbr58U/YcsffyQrYW//hZSdrfxrjRZj3GcUoxMPGdO8gSYuw==
|
||||
|
||||
"@types/methods@^1.1.4":
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/methods/-/methods-1.1.4.tgz#d3b7ac30ac47c91054ea951ce9eed07b1051e547"
|
||||
@ -3479,6 +3491,14 @@ create-require@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
|
||||
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
|
||||
|
||||
cron@4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/cron/-/cron-4.3.0.tgz#c5a62872f74f72294cf1cadef34c72ad8d8f50b5"
|
||||
integrity sha512-ciiYNLfSlF9MrDqnbMdRWFiA6oizSF7kA1osPP9lRzNu0Uu+AWog1UKy7SkckiDY2irrNjeO6qLyKnXC8oxmrw==
|
||||
dependencies:
|
||||
"@types/luxon" "~3.6.0"
|
||||
luxon "~3.6.0"
|
||||
|
||||
cross-inspect@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cross-inspect/-/cross-inspect-1.0.1.tgz#15f6f65e4ca963cf4cc1a2b5fef18f6ca328712b"
|
||||
@ -5861,6 +5881,11 @@ lru-cache@^7.10.1, lru-cache@^7.14.1:
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89"
|
||||
integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==
|
||||
|
||||
luxon@~3.6.0:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.6.1.tgz#d283ffc4c0076cb0db7885ec6da1c49ba97e47b0"
|
||||
integrity sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==
|
||||
|
||||
magic-string@0.30.17:
|
||||
version "0.30.17"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user