From d33e57a05f48ea045f05ac9294b41782b194c36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Fournier?= Date: Tue, 23 Sep 2025 14:43:53 +0200 Subject: [PATCH] feat: enforce email null when deleted is set (#10680) ## About the changes When deleting a user we set the email to null and deleted_at to the current date, there's no case where email is set and deleted_at is also set. We found some situations where this happens, specifically when SAML and SCIM are used in conjunction --- .../getLicensedUsers.e2e.test.ts | 2 +- .../20250922151744-amend-deleted-at.js | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/migrations/20250922151744-amend-deleted-at.js diff --git a/src/lib/features/instance-stats/getLicensedUsers.e2e.test.ts b/src/lib/features/instance-stats/getLicensedUsers.e2e.test.ts index 3e96eb3484..efbbcf6855 100644 --- a/src/lib/features/instance-stats/getLicensedUsers.e2e.test.ts +++ b/src/lib/features/instance-stats/getLicensedUsers.e2e.test.ts @@ -16,7 +16,7 @@ const mockUser = (deletedDaysAgo: number | null, uniqueId: number) => { ? new Date(Date.now() - deletedDaysAgo * 24 * 60 * 60 * 1000) : null; return { - email: `${uniqueId}.user@example.com`, + email: deletedAt === null ? `${uniqueId}.user@example.com` : null, email_hash: `${uniqueId}.user@example.com`, deleted_at: deletedAt, }; diff --git a/src/migrations/20250922151744-amend-deleted-at.js b/src/migrations/20250922151744-amend-deleted-at.js new file mode 100644 index 0000000000..d9f28c94c8 --- /dev/null +++ b/src/migrations/20250922151744-amend-deleted-at.js @@ -0,0 +1,25 @@ + +exports.up = (db, callback) => { + db.runSql( + ` + UPDATE users + SET deleted_at = NULL + WHERE deleted_at IS NOT NULL and length(email) > 0; + + ALTER TABLE users + ADD CONSTRAINT deleted_at_requires_email_null + CHECK (deleted_at IS NULL OR email IS NULL); + `, + callback, + ); +}; + +exports.down = (db, callback) => { + db.runSql( + ` + ALTER TABLE users + DROP CONSTRAINT deleted_at_requires_email_null; + `, + callback, + ); +};