Currently, many objects have a `mailKey` field, and copy/pasted logic to populate it. This key is used as a seed to generate unique addresses for each `<object, user>` pair so that I send mail to `T123+1+abe2h3f2` and you send mail to `T123+2+fo1m213n` and I can't just fiddle with my "+1" and impersonate someone else.
This could much more simply be a Mail table which stores `<objectPHID, mailKey>` and generates new keys lazily on first use.
This would allow us to remove a substantial amount of copy/pasted code:
```
epriestley@orbital ~/dev/phabricator $ git grep -i mailkey
src/applications/almanac/storage/AlmanacBinding.php: protected $mailKey;
src/applications/almanac/storage/AlmanacBinding.php: 'mailKey' => 'bytes20',
src/applications/almanac/storage/AlmanacBinding.php: if (!$this->mailKey) {
src/applications/almanac/storage/AlmanacBinding.php: $this->mailKey = Filesystem::readRandomCharacters(20);
src/applications/almanac/storage/AlmanacDevice.php: protected $mailKey;
src/applications/almanac/storage/AlmanacDevice.php: 'mailKey' => 'bytes20',
src/applications/almanac/storage/AlmanacDevice.php: if (!$this->mailKey) {
src/applications/almanac/storage/AlmanacDevice.php: $this->mailKey = Filesystem::readRandomCharacters(20);
src/applications/almanac/storage/AlmanacNamespace.php: protected $mailKey;
src/applications/almanac/storage/AlmanacNamespace.php: 'mailKey' => 'bytes20',
src/applications/almanac/storage/AlmanacNamespace.php: if (!$this->mailKey) {
src/applications/almanac/storage/AlmanacNamespace.php: $this->mailKey = Filesystem::readRandomCharacters(20);
src/applications/almanac/storage/AlmanacNetwork.php: protected $mailKey;
src/applications/almanac/storage/AlmanacNetwork.php: 'mailKey' => 'bytes20',
src/applications/almanac/storage/AlmanacNetwork.php: if (!$this->mailKey) {
src/applications/almanac/storage/AlmanacNetwork.php: $this->mailKey = Filesystem::readRandomCharacters(20);
src/applications/almanac/storage/AlmanacService.php: protected $mailKey;
src/applications/almanac/storage/AlmanacService.php: 'mailKey' => 'bytes20',
src/applications/almanac/storage/AlmanacService.php: if (!$this->mailKey) {
...
```
This change needs to keep mail keys stable, so all the existing mail keys should be copied into the new table before they are deleted.
There should be a very small number of readers (2-3?) of this field, so it should be possible to blind them safely like this:
# If the object is a lisk object with a `mailKey` property, continue calling `getMailKey()`.
# Otherwise, read the new mail key table; use the result if a row exists.
# Otherwise, insert a new result into the table; use that.
Then copy and remove all the `mailKey` properties one by one until we can delete the chunk of code in (1).