aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/auth.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-31 17:19:24 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-31 17:19:24 +0200
commit51d2d734c228f1e46670962480258abfe586d6c4 (patch)
tree12e869044c80c889f83b588210cc0ac500cd7a6a /packages/meshbay-hub/src/meshbay_hub/auth.py
parentf4c6628c8e85513d9fd110ead95682368a15a0fd (diff)
parentc6fd7ea89b6e0a96eb1d81989de891b4768b1044 (diff)
downloadmeshbay-51d2d734c228f1e46670962480258abfe586d6c4.tar.gz
Merge branch 'feat/email-verification'
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/auth.py')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/auth.py15
1 files changed, 15 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/auth.py b/packages/meshbay-hub/src/meshbay_hub/auth.py
index 28f13a5..2bf59db 100644
--- a/packages/meshbay-hub/src/meshbay_hub/auth.py
+++ b/packages/meshbay-hub/src/meshbay_hub/auth.py
@@ -189,6 +189,21 @@ def decrypt_email(stored: str) -> str:
return AESGCM(_email_key).decrypt(nonce, ct, None).decode()
+def hash_email_blind(email: str) -> str:
+ """Deterministic HMAC-SHA256 of the lowercased email for uniqueness checks.
+
+ The encrypted email uses a random nonce, so two encryptions of the same
+ address produce different ciphertexts. This blind index allows a DB-level
+ uniqueness constraint without decrypting every row.
+ """
+ if _email_key is None:
+ raise RuntimeError("Hub keypair not loaded")
+ import hmac as _hmac
+ return _hmac.new(
+ _email_key, email.strip().lower().encode(), hashlib.sha256,
+ ).hexdigest()
+
+
# ── Refresh tokens ────────────────────────────────────────────────────────────
def generate_refresh_token() -> tuple[str, str]: