docs.sigit.io/emailflow.md
_ e209cea19c
All checks were successful
Release to Production / build_and_release (push) Successful in 24s
removing entropy part as it didn't add anything
2025-01-13 00:37:43 +00:00

3.9 KiB

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 long and complex password
  • 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 signup flow as follows:

  1. User provides email and complex password
  2. These are used to encrypt a locally generated keypair into a backup
  3. Email address, Public Key and encrypted backup are sent to the server
  4. Account is validated

The password is only used to encrypt/decrypt the local backup and is never stored or sent anywhere.

When perforing a login, the flow is:

  1. Generate a temporary key pair for secure server communication
  2. Validate the email
  3. Provide the encrypted keypair for the user to unlock

All key signing / encryption operations happen on client side using private class properties.

SIGNUP FLOW

sequenceDiagram
    autoNumber
    actor U as SIGit User
    participant W as SIGit Website
    participant D as Server
    Participant DB 
    Note over W,D: All comms encrypted with throwaway <br>(ephemeral) client keys and a <br>.well-known server key
    U->>W: Click SIGNUP 
    U->>W: Provide Email and Complex Password
    Note over W: Validate Email<br>Ensure Complex Password

    Note right of U: User is warned that they CANNOT<br>RESET PASSWORD, should USE <br>PASSWORD MANAGER etc

    
    Note over W: Nostr Keypair Generated <br> & Encrypted inside a <br> PRIVATE method,<br>with COMPLEX password.<br> Password variable is not <br>stored, sent or printed <br> anywhere. <br>Any sensitive variables <br>are immediately destroyed.
    W->>D: Request account activation 
    Note right of W: Event uses PoW and<br> encrypts PUBKEY, EMAIL,<br> and the encrypted BACKUP<br> to the dvm@sigit.io pubkey<br> using the ephemeral key
    Note over D: Verify PoW, <br>event.created_at,<br>event.id
    D -x DB: Check if email exists
    Note over D: If email already exists, and <br>user.last_seen <> null then <br>send user to LOGIN.<br><br>If email exists and last_seen<br> is null, then DELETE the <br>current entry.<br><br> Otherwise#58;
    D->>DB: Create DB entries
    Note over DB: USER insert#58;<br>#128274;user.id=uid()<br>user.pubkey=lowcase($PUBKEY)<br>user.email=lowcase($EMAIL)<br>user.last_seen=null<br>user.created_at=now()<br>user.bkp=$BACKUP
    Note over DB: SESSION insert#58;<br>#128274;session.pubkey="ephemeral pubkey"<br>session.email_code=INT (6 digits)<br>session.user_id=user.id<br>session.created_at=now()
    D->>U: Send session.email_code via email
    D->>W: Account created
    Note left of D: Payload is the user.id and/or<br> an encrypted (and detailed)<br> error message
    Note over W: Verify DVM pubkey, <br> event.created_at,<br>event.id
    W->>U: Tell user to check email and<br>to open it in the <br> SAME BROWSER SESSION
    Note over W: Screen to accept the 6 digits <br> is already displayed<br>(mobile optimised if relevant)
    U->>W: User opens link or enters the code
    W->>D: Verify Account
    Note right of W: Event uses PoW and <br>encrypts both user_id <br>and email_code<br> to DVM pubkey
    D -x DB: Check email_code where <br>session pk=event pk
    D->>DB: If email_code matches, <br>update USER table where<br> session.user_id=user.id


    Note over DB: USER update#58;<br>user.last_seen=now()
    D->>W: Account activated
    Note left of D: Payload is an empty string or<br> an encrypted (and detailed)<br> error message
    Note over W: Verify DVM pubkey, <br> event.created_at,<br>event.id
    W->>U: User is automatically logged in
    Note over W: Ephemeral key is destroyed<br>Default relay list is broadcast<br> using the user pubkey