Files
Termix/src/backend/database/routes/delete-user-data.ts
T

144 lines
5.9 KiB
TypeScript
Raw Normal View History

2026-06-04 15:16:53 -04:00
import { authLogger } from "../../utils/logger.js";
import {
+5
2026-08-19 14:12:06 -05:00
createCurrentAiRepository,
+8
2026-07-19 12:29:52 -05:00
createCurrentAlertRepository,
createCurrentApiKeyRepository,
createCurrentAuditLogRepository,
createCurrentC2sTunnelPresetRepository,
createCurrentCommandHistoryRepository,
createCurrentCredentialRepository,
createCurrentDashboardServiceLinkRepository,
createCurrentDismissedAlertRepository,
createCurrentFileManagerBookmarkRepository,
createCurrentHomepageItemRepository,
createCurrentHomepageLayoutRepository,
createCurrentHostHealthRepository,
createCurrentHostFolderRepository,
createCurrentHostMetricsPreferenceRepository,
createCurrentHostRepository,
+5
2026-08-19 14:12:06 -05:00
createCurrentHostSidebarPreferenceRepository,
createCurrentCredentialSidebarPreferenceRepository,
createCurrentUiPreferenceRepository,
+8
2026-07-19 12:29:52 -05:00
createCurrentNetworkTopologyRepository,
createCurrentOpksshTokenRepository,
createCurrentOpenTabRepository,
createCurrentRecentActivityRepository,
createCurrentRbacAccessRepository,
createCurrentRoleRepository,
createCurrentSessionRepository,
createCurrentSessionRecordingRepository,
createCurrentSettingsRepository,
createCurrentSharedHostSecretsRepository,
createCurrentSnippetRepository,
createCurrentSshCredentialUsageRepository,
createCurrentTermixIdentityCaRepository,
createCurrentTermixIdentityRepository,
createCurrentTmuxSessionTagRepository,
createCurrentTrustedDeviceRepository,
createCurrentUserPreferenceRepository,
createCurrentUserRepository,
createCurrentTransferRecentRepository,
createCurrentVaultProfileRepository,
+17
2026-09-20 14:56:39 -05:00
createCurrentSecretSourceRepository,
createCurrentSharedCredentialSecretsRepository,
createCurrentCredentialAccessRepository,
+8
2026-07-19 12:29:52 -05:00
createCurrentVaultTokenRepository,
} from "../repositories/factory.js";
2026-06-04 15:16:53 -04:00
+17
2026-09-20 14:56:39 -05:00
export async function deleteUserAndRelatedData(
userId: string,
options: { successorUserId?: string } = {},
): Promise<void> {
2026-06-04 15:16:53 -04:00
try {
+17
2026-09-20 14:56:39 -05:00
// With a successor, hosts and credentials (and the shares on them)
// change owner instead of disappearing with the account.
if (options.successorUserId) {
const { transferOwnership } =
await import("../../utils/transfer-ownership.js");
await transferOwnership(userId, options.successorUserId);
}
+8
2026-07-19 12:29:52 -05:00
await createCurrentSharedHostSecretsRepository().deleteByTargetUserId(
userId,
);
+17
2026-09-20 14:56:39 -05:00
await createCurrentSharedCredentialSecretsRepository().deleteByTargetUserId(
userId,
);
await createCurrentCredentialAccessRepository().deleteForUserReferences(
userId,
);
2026-06-04 15:16:53 -04:00
+3
2026-08-06 14:41:39 -05:00
// Retained rather than deleted: these outlive the account by design.
// See anonymizeByUserId on each repository.
await createCurrentSessionRecordingRepository().anonymizeByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentRbacAccessRepository().deleteHostAccessForUserReferences(
userId,
);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentSessionRepository().revokeAllForUser(userId);
await createCurrentApiKeyRepository().deleteByUserId(userId);
await createCurrentTrustedDeviceRepository().deleteByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentRoleRepository().removeAllRolesFromUser(userId);
+5
2026-08-19 14:12:06 -05:00
await createCurrentAiRepository().deleteByUserId(userId);
+8
2026-07-19 12:29:52 -05:00
await createCurrentAlertRepository().deleteByUserId(userId);
+3
2026-08-06 14:41:39 -05:00
await createCurrentAuditLogRepository().anonymizeByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentSshCredentialUsageRepository().deleteByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentFileManagerBookmarkRepository().deleteByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentTransferRecentRepository().deleteByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentRecentActivityRepository().deleteByUserId(userId);
await createCurrentDismissedAlertRepository().deleteByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentSnippetRepository().deleteByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentHostFolderRepository().deleteByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentCommandHistoryRepository().deleteByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentHostHealthRepository().deleteByUserId(userId);
await createCurrentHostMetricsPreferenceRepository().deleteByUserId(userId);
+5
2026-08-19 14:12:06 -05:00
await createCurrentHostSidebarPreferenceRepository().deleteByUserId(userId);
await createCurrentCredentialSidebarPreferenceRepository().deleteByUserId(
userId,
);
await createCurrentUiPreferenceRepository().deleteByUserId(userId);
+8
2026-07-19 12:29:52 -05:00
await createCurrentHostRepository().deleteByUserId(userId);
await createCurrentCredentialRepository().deleteByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentNetworkTopologyRepository().deleteByUserId(userId);
await createCurrentDashboardServiceLinkRepository().deleteByUserId(userId);
await createCurrentHomepageItemRepository().deleteByUserId(userId);
await createCurrentHomepageLayoutRepository().deleteByUserId(userId);
await createCurrentC2sTunnelPresetRepository().deleteByUserId(userId);
await createCurrentOpksshTokenRepository().deleteByUserId(userId);
await createCurrentVaultTokenRepository().deleteByUserId(userId);
await createCurrentVaultProfileRepository().deleteByUserId(userId);
+17
2026-09-20 14:56:39 -05:00
await createCurrentSecretSourceRepository().deleteByUserId(userId);
+8
2026-07-19 12:29:52 -05:00
await createCurrentTermixIdentityCaRepository().deleteByUserId(userId);
await createCurrentTermixIdentityRepository().deleteByUserId(userId);
await createCurrentTmuxSessionTagRepository().deleteByUserId(userId);
await createCurrentOpenTabRepository().deleteByUserId(userId);
await createCurrentUserPreferenceRepository().deleteByUserId(userId);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentSettingsRepository().deleteLike(`user_%_${userId}`);
2026-06-04 15:16:53 -04:00
+8
2026-07-19 12:29:52 -05:00
await createCurrentUserRepository().delete(userId);
2026-06-04 15:16:53 -04:00
authLogger.success("User and all related data deleted successfully", {
operation: "delete_user_and_related_data_complete",
userId,
});
} catch (error) {
authLogger.error("Failed to delete user and related data", error, {
operation: "delete_user_and_related_data_failed",
userId,
});
throw error;
}
}