SECUREMAIL - INSTALLATION
=========================

SecureMail is a webmail: the web page your users open to read and send their email.
It is plain PHP with no database and no other software to install, so it runs on
almost any web server (Apache, nginx, LiteSpeed, Caddy) and any hosting panel
(Plesk, cPanel, DirectAdmin) or none at all. It works with the mailboxes you already
have: it reads email with IMAP and sends it with SMTP.


WHAT YOU NEED
-------------
- A web address for the webmail with HTTPS, for example https://mail.example.com
  (a subdomain of your own domain is ideal).
- PHP 8.1 or newer (8.4 is fine) with these extensions, which most hosting has:
    sodium, openssl, dom, mbstring, curl, fileinfo, zip
  Recommended: intl (international domain names) and gd (logos are resized and cleaned).
- An email server with IMAP (port 993, or 143 with STARTTLS) and SMTP submission
  (port 587 with STARTTLS, or 465). Dovecot and Postfix, as on most Linux hosting, are perfect.
- Optional, for filters and the away reply: ManageSieve on the mail server (Dovecot
  Pigeonhole, port 4190). Plesk has it. Without it those two features are simply hidden.
- Optional, for sending to many people in batches: a mail relay on the same machine
  (127.0.0.1 port 25), as Postfix provides, and something that opens a web address every
  5 minutes (see step 6).


THE FOLDERS
-----------
The zip contains three folders that must stay side by side:

    app/      the program
    public/   the only folder the web server may show   <-- the "document root"
    data/     your settings, keys and address books: PRIVATE, never visible on the web

The important rule: point the web address at the PUBLIC folder, not at the folder that
holds all three. Then nobody can download anything from data/ or app/.


1. MAKE THE WEB ADDRESS
   Create a (sub)domain, for example mail.example.com, and set its document root to the
   public folder:
     Plesk:   Websites & Domains > Add Subdomain > Document root:  mail.example.com/public
     cPanel:  Domains > Create a New Domain > Document Root:      mail.example.com/public
     Apache:  DocumentRoot /var/www/securemail/public
     nginx:   root /var/www/securemail/public;   (see the example at the end)
   On Plesk, do not use "webmail.yourdomain": Plesk keeps that name for its own Roundcube.
   SecureMail and Roundcube can run side by side while people try it.

2. TURN ON HTTPS
   Install a certificate for the address (Let's Encrypt is free in every panel) and
   redirect http to https. Never run it without HTTPS: passwords and email would cross the
   internet unencrypted, and the extra-safe "__Host-" cookies are only used over HTTPS.

3. UPLOAD THE FILES
   Unzip securemail-X.Y.Z-website.zip in the folder ABOVE the document root, so that you
   see app, data and public side by side (with a panel's file manager: upload the zip,
   then "Extract"). The web server's PHP user must be able to write to data/.
   Delete anything the panel put in public/ first (for example index.html).

4. SIGN IN AND BECOME THE ADMINISTRATOR
   Open https://mail.example.com and sign in with your own mailbox and password.
   Open Settings > Administration. It asks for a setup code: open the file
   data/setup-code.txt with your file manager (or ssh) and copy the code.
   Only someone with access to your hosting files can read it, which proves you own it.

5. CHECK THE SETTINGS
   Settings > Administration: press "Test mail servers". The defaults (127.0.0.1, IMAP 993,
   SMTP 587) suit a mail server on the same machine. If the mail server is elsewhere,
   enter its name and ports and switch on "Verify certificate". Set the sending limit
   (for example 50 people every 3 hours) and press "Save settings". Under "Look & domains"
   you can add your own name, logo and colour.
   Turn on two-step verification for your own mailbox first (Settings > Privacy & security):
   the mail servers, the administrator list and the trusted proxies can only be changed with
   it on and your password typed again, and every administrator gets an email about it.

6. SEND BATCHES ON TIME
   Emails to more people than the sending limit wait in the Outbox and go out in batches.
   Have one of these run every 5 minutes:
     - the secret scheduler address shown in Settings > Administration, opened by
       Plesk Scheduled Tasks ("Fetch a URL"), cPanel Cron Jobs (curl -s "ADDRESS"),
       a free service such as cron-job.org, or the "SecureMail Batch Sender" WordPress plugin;
     - or, with a shell: */5 * * * * php /var/www/securemail/app/cli/queue.php
   Without it, waiting batches only go out while someone has the webmail open.

7. CONTACTS ON PHONES (OPTIONAL, ON BY DEFAULT)
   Phones and Thunderbird sync address books at https://mail.example.com/dav.php/ with an
   app password each person makes under Settings > Privacy & security (the webmail shows them
   the exact steps). It needs HTTPS, and the web server must pass two things to PHP:
     - the part of the address after dav.php (nginx: see the example below; Apache does this);
     - the Authorization header (Apache with PHP-FPM: add "CGIPassAuth On" in the <Directory>
       block if phones keep asking for the password; Plesk and most panels already do this).
   Optional: phones find the server from just "mail.example.com" if /.well-known/carddav
   redirects to /dav.php/ (nginx: location = /.well-known/carddav { return 301 /dav.php/; }
   Apache: Redirect 301 /.well-known/carddav /dav.php/). Without it, people type the full address.
   To turn contacts sync off: Settings > Administration > Address books.

8. CHECK THAT THE PRIVATE FOLDER IS PRIVATE
   Settings > Administration checks this for you and shows a green line when it is safe.
   If it shows a red box, the document root is wrong: go back to step 1.


UPDATING
--------
Settings > Administration shows when a new version is available and installs it with one
click. Updates are signed: a damaged or forged update is refused, and the previous version
is kept so you can go back with one click. To update by hand instead, unzip the new version
over the old one ("replace files"). The data folder is never touched.


EXAMPLE: NGINX WITH PHP-FPM
---------------------------
server {
    listen 443 ssl http2;
    server_name mail.example.com;
    root /var/www/securemail/public;
    index index.php;
    client_max_body_size 30m;              # attachments are uploaded in 1 MB pieces anyway
    location / { try_files $uri $uri/ =404; }
    location = /.well-known/carddav { return 301 /dav.php/; }
    location ~ ^(.+\.php)(/.*)?$ {               # also /dav.php/books/... for contacts sync
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        try_files $fastcgi_script_name =404;
        include fastcgi_params;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
}

EXAMPLE: APACHE
---------------
<VirtualHost *:443>
    ServerName mail.example.com
    DocumentRoot /var/www/securemail/public
    <Directory /var/www/securemail/public>
        AllowOverride None
        Require all granted
        # contacts sync: lets PHP see the phone's app password (Apache 2.4.13 or newer)
        CGIPassAuth On
    </Directory>
    Redirect 301 /.well-known/carddav /dav.php/
    # SSLEngine on ... (your certificate)
</VirtualHost>
(data/ also contains a .htaccess that denies everything, as a second lock.)


IF THE DATA FOLDER MUST LIVE ELSEWHERE
--------------------------------------
Set the environment variable SECUREMAIL_DATA_DIR to the folder you want (for example in the
PHP-FPM pool: env[SECUREMAIL_DATA_DIR] = /srv/securemail-data). It must be writable by PHP
and outside the document root.
