From f9be77ec7c3491014c5d5ae20c43351c1f3927a7 Mon Sep 17 00:00:00 2001
From: _ <>
Date: Sun, 12 Jan 2025 23:24:33 +0000
Subject: [PATCH] updates
---
emailflow.md | 33 ++++++++++++++++++++++++++++-----
1 file changed, 28 insertions(+), 5 deletions(-)
diff --git a/emailflow.md b/emailflow.md
index 7190e60..52689f0 100644
--- a/emailflow.md
+++ b/emailflow.md
@@ -1,5 +1,26 @@
# Email Flow
+In creating an email flow that maintains PRIVACY and SECURITY whilst also being convenient to use, the following principles were observed:
+
+- Keypair must be generated client-side
+- Keypair must be protected by a password
+- There must be protection from keyloggers
+- It must be possible to change the password
+- It must remain possible to work offline
+- Network traffic must not contain identifying metadata
+
+All of the above is achieved using a high level flow as follows:
+
+1. Generate temporary key pair for secure server communication
+2. Validate email using a 6 digit code
+3. Provide some server side entropy to client
+4. Combine entropy + complex user password to encrypt the final keypair
+5. Store the encrypted keypair on the server
+
+The password is only used to encrypt the key and is never stored or sent anywhere. Hence, the server cannot decrypt the backup. All key signing / encryption operations happen on client side using [private class properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_properties).
+
+## SIGNUP FLOW
+
```mermaid
sequenceDiagram
@@ -12,11 +33,11 @@ sequenceDiagram
U->>W: Click SIGNUP and enter
email address
Note over W: Ephemeral key generated
to communicate with DVM
W->>D: Request Account
- Note right of W: Event uses PoW and
encrypts only EMAIL
to DVM pubkey
+ Note right of W: Event uses PoW and
encrypts only EMAIL
to dvm@sigit.io pubkey
D -x DB: Verify PoW and check
if email exists
Note over D: If email already exists,
send user to LOGIN.
Otherwise#58;
- D->>DB: Create Account
- Note over DB: Create entries#58;
#128274;user.id=uid()
user.email=lowcase(email())
user.verified=false
user.activated=false
user.entropy=""
user.pubkey=""
user.created_at=now()
user.bkp=""
#128274;session.pubkey="ephemeral pubkey"
session.user_id=user.id
session.email_code=INT (6 digits)
session.created_at=now()
+ D->>DB: Create Temp Session
+ Note over DB: SESSION entry#58;
#128274;session.pubkey="ephemeral pubkey"
session.email=lowcase($EMAIL)
session.email_code=INT (6 digits)
session.created_at=now()
D->>U: Send session.email_code via email
D->>W: Account created
Note left of D: Payload is an empty string or
an encrypted (and detailed)
error message
@@ -26,12 +47,14 @@ sequenceDiagram
W->>D: Verify Account
Note right of W: Event uses PoW and
encrypts only CODE
to DVM pubkey
D -x DB: Check email_code where
session pk=event pk
- D->>DB: If code matches,
Update Account
- Note over DB: user.verified=true
user.entropy=uid()
+ D->>DB: If code matches,
create User Account
+ Note over DB: USER entry#58;
#128274;user.id=uid()
user.email=session.email
user.pubkey=""
user.activated=false
user.created_at=now()
user.bkp=""
user.entropy=uid()
D->>W: Provide user.entropy
Note left of D: Payload encrypted to ephemeral
pubkey. Is either a UID or a
detailed error message.
+ Note over W: Client verifies that
DVM response came from
DVM pubkey
W->>U: Ask for secure password
Note right of U: This password is what prevents
backend from decrypting the nsec
+ Note right of U: User is warned that they CANNOT
RESET PASSWORD, should USE
PASSWORD MANAGER etc
U->>W: Enter password (twice)
Note over W: Nostr Keypair Generated
& Encrypted inside a
PRIVATE METHOD,
using password + entropy.
Password variable is not
stored, sent or printed
anywhere. Temporary
variables are destroyed.