# Email Flow
In creating an email flow that maintains PRIVACY and SECURITY whilst also being convenient to use, the following principles are observed:
- Keypair must be generated client-side
- Keypair must be protected by a strong password
- It must be possible to change the password
- It must be possible to work offline
- Network traffic must not contain identifying metadata
All of the above are achieved using a high level signup flow as follows:
1. User provides email and long (min 21 chars) password
2. These are used to encrypt a locally generated keypair
3. Email address, Public Key and encrypted backup are sent to the server
4. Email address is validated
5. Account is activated
The password is only used to encrypt/decrypt the local backup and is never stored or sent outside of the browser
When performing a regular login, the flow is:
1. Validate the email
2. Provide the encrypted keypair for the user to unlock
When performing a password reset:
1. Change the pasword locally
2. Re-encrypt the keypair using the new password
3. Send the new backup to the server
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
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
(ephemeral) client keys and a
.well-known server key
U->>W: Click SIGNUP
U->>W: Provide Email and Complex Password
Note over W: Validate Email
Ensure Complex Password
(Min 21 chars)
Note right of U: User is warned that they CANNOT
RESET PASSWORD, should USE
PASSWORD MANAGER etc
Note over W: Nostr Keypair Generated
& Encrypted inside a
PRIVATE method,
with COMPLEX password.
Password variable is not
stored, sent or printed
anywhere.
Any sensitive variables
are immediately destroyed.
W->>D: Request account activation
Note right of W: Event uses PoW and
encrypts PUBKEY, EMAIL,
and the encrypted BACKUP
to the dvm@sigit.io pubkey
using the ephemeral key
Note over D: Verify PoW,
event.created_at,
event.id
D -x DB: Check if email exists
Note over D: If email already exists, and
user.last_seen <> null then
send user to LOGIN.
If email exists and last_seen
is null, then DELETE the
current entry.
Otherwise#58;
D->>DB: Create DB entries
Note over DB: USER insert#58;
#128274;user.id=uid()
user.pubkey=lowcase($PUBKEY)
user.email=lowcase($EMAIL)
user.last_seen=null
user.created_at=now()
user.bkp=$BACKUP
Note over DB: SESSION insert#58;
#128274;session.pubkey="ephemeral pubkey"
session.email_code=INT (6 digits)
session.user_id=user.id
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
an encrypted (and detailed)
error message
Note over W: Verify DVM pubkey,
event.created_at,
event.id
W->>U: Tell user to check email and
to open it in the
SAME BROWSER SESSION
Note over W: Screen to accept the 6 digits
is already displayed
(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
encrypts both user_id
and email_code
to DVM pubkey
D -x DB: Check email_code where
session pk=event pk
D->>DB: If email_code matches,
update USER table where
session.user_id=user.id
Note over DB: USER update#58;
user.last_seen=now()
D->>W: Account activated
Note left of D: Payload is an empty string or
an encrypted (and detailed)
error message
Note over W: Verify DVM pubkey,
event.created_at,
event.id
W->>U: User is automatically logged in
Note over W: Ephemeral key is destroyed
Default relay list is broadcast
using the user pubkey
```