From cd43912a2fe7d7646d26dfd39c085c4876d7ef51 Mon Sep 17 00:00:00 2001 From: Monica Khoury <99693443+monicakh@users.noreply.github.com> Date: Thu, 23 May 2024 12:02:47 +0300 Subject: [PATCH] Chore: block multiple account deletion requests (#26304) * Chore: block multiple account deletion requests * add key to LOCAL_STORAGE_KEYS --- .../Preferences/DeleteAccountButton.tsx | 27 +++++++++++++++++++ apps/studio/lib/constants/index.ts | 4 +++ 2 files changed, 31 insertions(+) diff --git a/apps/studio/components/interfaces/Account/Preferences/DeleteAccountButton.tsx b/apps/studio/components/interfaces/Account/Preferences/DeleteAccountButton.tsx index 24b54aa6002..e08e83410d1 100644 --- a/apps/studio/components/interfaces/Account/Preferences/DeleteAccountButton.tsx +++ b/apps/studio/components/interfaces/Account/Preferences/DeleteAccountButton.tsx @@ -4,6 +4,7 @@ import { useEffect, useState } from 'react' import { useForm } from 'react-hook-form' import toast from 'react-hot-toast' import * as z from 'zod' +import { LOCAL_STORAGE_KEYS } from 'lib/constants' import { useSendSupportTicketMutation } from 'data/feedback/support-ticket-send' import { useOrganizationsQuery } from 'data/organizations/organizations-query' @@ -26,6 +27,27 @@ import { Input_Shadcn_, } from 'ui' +const setDeletionRequestFlag = () => { + const expiryDate = new Date() + expiryDate.setDate(expiryDate.getDate() + 30) + localStorage.setItem(LOCAL_STORAGE_KEYS.ACCOUNT_DELETION_REQUEST, expiryDate.toString()) +} + +const hasActiveDeletionRequest = () => { + const expiryDateStr = localStorage.getItem(LOCAL_STORAGE_KEYS.ACCOUNT_DELETION_REQUEST) + if (!expiryDateStr) return false + + const expiryDate = new Date(expiryDateStr) + const now = new Date() + + if (now > expiryDate) { + localStorage.removeItem(LOCAL_STORAGE_KEYS.ACCOUNT_DELETION_REQUEST) + return false + } + + return true +} + export const DeleteAccountButton = () => { const { profile } = useProfile() const [isOpen, setIsOpen] = useState(false) @@ -44,6 +66,7 @@ export const DeleteAccountButton = () => { const { mutate: submitSupportTicket, isLoading } = useSendSupportTicketMutation({ onSuccess: () => { setIsOpen(false) + setDeletionRequestFlag() toast.success( 'Successfully submitted account deletion request - we will reach out to you via email once the request is completed!', { duration: 8000 } @@ -57,6 +80,10 @@ export const DeleteAccountButton = () => { const onConfirmDelete = async () => { if (!accountEmail) return console.error('Account information is required') + if (hasActiveDeletionRequest()) { + return toast.error('You have already submitted a deletion request within the last 30 days.') + } + const payload = { subject: 'Account Deletion Request', message: 'I want to delete my account.', diff --git a/apps/studio/lib/constants/index.ts b/apps/studio/lib/constants/index.ts index f5a20630865..9a9686681c2 100644 --- a/apps/studio/lib/constants/index.ts +++ b/apps/studio/lib/constants/index.ts @@ -51,6 +51,10 @@ export const LOCAL_STORAGE_KEYS = { PROJECT_LINT_IGNORE_LIST: 'supabase-project-lint-ignore-list', QUERY_PERF_SHOW_BOTTOM_SECTION: 'supabase-query-perf-show-bottom-section', + + // Key to track account deletion requests + ACCOUNT_DELETION_REQUEST: 'supabase-account-deletion-request', + // Used for storing a user id when sending reports to Sentry. The id is hashed for anonymity. SENTRY_USER_ID: 'supabase-sentry-user-id', }