fix: wipe user secrets when user is soft-deleted (#24985)

Extend the delete_deleted_user_resources() trigger so that secrets
belonging to a soft-deleted user are removed in the same transaction as
the existing api_keys and user_links cleanup.

user_secrets.user_id has ON DELETE CASCADE, but Coder soft-deletes users
by flipping users.deleted rather than removing the row, so the foreign key
cascade never fires and secrets would otherwise survive deletion.

Assisted by Coder Agents.
This commit is contained in:
Zach
2026-05-11 09:07:30 -06:00
committed by GitHub
parent 81e2be69e9
commit b221632615
9 changed files with 207 additions and 27 deletions
@@ -0,0 +1,27 @@
-- Drop the BEFORE INSERT/UPDATE guard added by 000489.
DROP TRIGGER IF EXISTS trigger_upsert_user_secrets ON user_secrets;
DROP FUNCTION IF EXISTS insert_user_secret_fail_if_user_deleted;
-- Restore the previous body of delete_deleted_user_resources() from
-- 000194_trigger_delete_user_user_link.up.sql, dropping the
-- user_secrets cleanup added by 000489.
CREATE OR REPLACE FUNCTION delete_deleted_user_resources() RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
BEGIN
IF (NEW.deleted) THEN
-- Remove their api_keys
DELETE FROM api_keys
WHERE user_id = OLD.id;
-- Remove their user_links
-- Their login_type is preserved in the users table.
-- Matching this user back to the link can still be done by their
-- email if the account is undeleted. Although that is not a guarantee.
DELETE FROM user_links
WHERE user_id = OLD.id;
END IF;
RETURN NEW;
END;
$$;