diff --git a/modules/mails/package.json b/modules/mails/package.json
index 863e5baa6bbaf38780c810181b88f322df99ee12..1bc5ca9819d4ae2f7d58fa0b823ac89fe8eb87c9 100644
--- a/modules/mails/package.json
+++ b/modules/mails/package.json
@@ -45,5 +45,8 @@
         ]
       }
     }
+  },
+  "devDependencies": {
+    "@types/mocha": "^10.0.1"
   }
 }
diff --git a/modules/mails/server/whitelist.ts b/modules/mails/server/whitelist.ts
index e5cd659ec3c76f5ee320783317528f0fc72d1d65..4b9db5ad6bf5d1293eb46f411e29dbc5c806b97e 100644
--- a/modules/mails/server/whitelist.ts
+++ b/modules/mails/server/whitelist.ts
@@ -43,16 +43,26 @@ export function checkWhitelists({
   return true;
 }
 
-function _isInDomainWhitelist(address: string, domainWhitelist?: string[]) {
+/**
+ * @deprecated only internal use
+ */
+export function _isInDomainWhitelist(address: string, domainWhitelist?: string[]) {
   const thisDomain = address.split('@')[1];
   if (!thisDomain) return false;
   if (!domainWhitelist) return false;
   return domainWhitelist.some(whitelistedDomain => {
-    return new RegExp(`${whitelistedDomain}$`).test(thisDomain);
+    return new RegExp(`${whitelistedDomain}$`, 'i').test(thisDomain);
   });
 }
 
-function _isInEmailWhitelist(address: string, emailWhitelist?: string[]) {
+/**
+ * @deprecated only internal use
+ */
+export function _isInEmailWhitelist(address: string, emailWhitelist?: string[]) {
   if (!emailWhitelist) return false;
-  return emailWhitelist.includes(address) || emailWhitelist.includes(address.replace(/\+[^@+]+@/, '@'));
+  const lowerCasedWhitelist = emailWhitelist.map(email => email.toLowerCase());
+  return (
+    lowerCasedWhitelist.includes(address.toLowerCase()) ||
+    lowerCasedWhitelist.includes(address.toLowerCase().replace(/\+[^@+]+@/, '@'))
+  );
 }
diff --git a/modules/mails/tests/whitelist.ts b/modules/mails/tests/whitelist.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9ecf7da46c40fdf7140812a313720d2b56fc6c0c
--- /dev/null
+++ b/modules/mails/tests/whitelist.ts
@@ -0,0 +1,26 @@
+import { strictEqual } from 'assert';
+import { _isInDomainWhitelist, _isInEmailWhitelist } from '../server/whitelist.js';
+
+describe('whitelist', () => {
+  it('insensitive email whitelist matching (positive)', () => {
+    strictEqual(_isInEmailWhitelist('e@mail.invalid', ['e@mail.invalid']), true);
+    strictEqual(_isInEmailWhitelist('e@mail.invalid', ['E@mail.invalid']), true);
+  });
+
+  it('email whitelist matching (negative)', () => {
+    strictEqual(_isInEmailWhitelist('e@mail.invalid', ['a@mail.invalid']), false);
+    strictEqual(_isInEmailWhitelist('e@mail.invalid', ['e@mail2.invalid']), false);
+    strictEqual(_isInEmailWhitelist('e@mail.invalid', ['e@mail.invalid2']), false);
+  });
+
+  it('insensitive domain whitelist matching (positive)', () => {
+    strictEqual(_isInDomainWhitelist('e@mail.invalid', ['mail.invalid']), true);
+    strictEqual(_isInDomainWhitelist('e@mail.invalid', ['Mail.invalid']), true);
+    strictEqual(_isInDomainWhitelist('e@mail.invalid', ['Mail.Invalid']), true);
+  });
+
+  it('domain whitelist matching (negative)', () => {
+    strictEqual(_isInDomainWhitelist('e@mail.invalid', ['mail2.invalid']), false);
+    strictEqual(_isInDomainWhitelist('e@mail.invalid', ['mail.invalid2']), false);
+  });
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a1b8fd14411c055c92b0d42d1f9308c0531aed8b..6f7e76063b4fcde798010b46494409e9c077f1f5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2385,6 +2385,10 @@ importers:
       twilio:
         specifier: ^4.19.0
         version: 4.23.0
+    devDependencies:
+      '@types/mocha':
+        specifier: ^10.0.1
+        version: 10.0.10
 
   modules/maps:
     dependencies: