|
1 | 1 | import { NextFunction, Request, Response } from 'express' |
2 | 2 | import { StatusCodes } from 'http-status-codes' |
| 3 | +import { QueryRunner } from 'typeorm' |
| 4 | +import { InternalFlowiseError } from '../../errors/internalFlowiseError' |
| 5 | +import { GeneralErrorMessage } from '../../utils/constants' |
3 | 6 | import { getRunningExpressApp } from '../../utils/getRunningExpressApp' |
| 7 | +import { emitEvent, TelemetryEventCategory, TelemetryEventResult } from '../../utils/telemetry' |
4 | 8 | import { Organization } from '../database/entities/organization.entity' |
5 | 9 | import { User } from '../database/entities/user.entity' |
6 | 10 | import { AccountDTO, AccountService } from '../services/account.service' |
@@ -146,6 +150,45 @@ export class AccountController { |
146 | 150 | return res.json({ message: 'Authentication failed' }) |
147 | 151 | } |
148 | 152 | } |
| 153 | + |
| 154 | + public async delete(req: Request, res: Response, next: NextFunction) { |
| 155 | + let queryRunner: QueryRunner | undefined |
| 156 | + try { |
| 157 | + const { confirmationText } = req.body |
| 158 | + if (confirmationText !== 'permanently delete') { |
| 159 | + throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, 'Confirmation text must match "permanently delete"') |
| 160 | + } |
| 161 | + |
| 162 | + queryRunner = getRunningExpressApp().AppDataSource.createQueryRunner() |
| 163 | + await queryRunner.connect() |
| 164 | + if (!req.user || !req.ip) throw new InternalFlowiseError(StatusCodes.UNAUTHORIZED, GeneralErrorMessage.UNAUTHORIZED) |
| 165 | + |
| 166 | + const accountService = new AccountService() |
| 167 | + await accountService.delete(queryRunner, req.user, req.ip) |
| 168 | + |
| 169 | + return res.status(StatusCodes.OK).json({ message: 'Account deleted' }) |
| 170 | + } catch (error) { |
| 171 | + if (queryRunner && queryRunner.isTransactionActive) await queryRunner.rollbackTransaction() |
| 172 | + |
| 173 | + await emitEvent({ |
| 174 | + category: TelemetryEventCategory.AUDIT, |
| 175 | + eventType: 'account-deleted', |
| 176 | + actionType: 'delete', |
| 177 | + userId: req.user?.id ?? 'unknown', |
| 178 | + orgId: req.user?.activeOrganizationId ?? 'unknown', |
| 179 | + resourceId: req.user?.id ?? 'unknown', |
| 180 | + ipAddress: req.ip, |
| 181 | + result: TelemetryEventResult.FAILED, |
| 182 | + metadata: { |
| 183 | + failureReason: error instanceof InternalFlowiseError ? error.message : 'internal_error' |
| 184 | + } |
| 185 | + }) |
| 186 | + |
| 187 | + next(error) |
| 188 | + } finally { |
| 189 | + if (queryRunner && !queryRunner.isReleased) await queryRunner.release() |
| 190 | + } |
| 191 | + } |
149 | 192 | } |
150 | 193 |
|
151 | 194 | function sanitizeRegistrationDTO(data: AccountDTO): AccountDTO { |
|
0 commit comments