mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-10-22 08:25:26 +00:00
feat: account deletion for Dokploy Cloud
Self-service deletion from Settings > Profile confirmed with the account password (when present) plus a 6-digit code sent by email, and a root-only "delete by email" tool in the impersonation bar to fulfil GDPR requests. Both paths run the same flow: cancel every Stripe subscription (customer is kept for invoicing), delete the user and all owned organizations in one transaction, anonymize audit trail left in other organizations, reassign pending invitations to the org owner, remove the HubSpot contact when HUBSPOT_ACCESS_TOKEN is configured, and log a JSON deletion record. Also blocks better-auth's raw /admin/remove-user endpoint and makes the Stripe webhook tolerate subscription/customer events for already deleted users.
This commit is contained in:
@@ -123,3 +123,48 @@ export async function submitToHubSpot(
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export type HubSpotDeletionResult =
|
||||
| "deleted"
|
||||
| "not_found"
|
||||
| "skipped"
|
||||
| "failed";
|
||||
|
||||
export async function deleteHubSpotContactByEmail(
|
||||
email: string,
|
||||
accessToken = process.env.HUBSPOT_ACCESS_TOKEN,
|
||||
): Promise<HubSpotDeletionResult> {
|
||||
if (!accessToken) {
|
||||
return "skipped";
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
"https://api.hubapi.com/crm/v3/objects/contacts/gdpr-delete",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ idProperty: "email", objectId: email }),
|
||||
},
|
||||
);
|
||||
|
||||
if (response.ok) {
|
||||
return "deleted";
|
||||
}
|
||||
if (response.status === 404) {
|
||||
return "not_found";
|
||||
}
|
||||
console.error(
|
||||
"HubSpot GDPR delete error:",
|
||||
response.status,
|
||||
await response.text(),
|
||||
);
|
||||
return "failed";
|
||||
} catch (error) {
|
||||
console.error("Error deleting HubSpot contact:", error);
|
||||
return "failed";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user