Avatars extension added option to preload known service icons

This commit is contained in:
the-djmaze 2022-12-02 14:28:15 +01:00
parent bff88e9f6a
commit 543725dd42
2 changed files with 47 additions and 11 deletions

View file

@ -161,8 +161,12 @@
if (url) { if (url) {
fn(url); fn(url);
} else if (msg.avatar) { } else if (msg.avatar) {
element.onerror = () => setIdenticon(from, fn); if (msg.avatar.startsWith('data:')) {
fn(`?Avatar/${'pass' == from.dkimStatus ? 1 : 0}/${msg.avatar}`); fn(msg.avatar);
} else {
element.onerror = () => setIdenticon(from, fn);
fn(`?Avatar/${'pass' == from.dkimStatus ? 1 : 0}/${msg.avatar}`);
}
} else { } else {
addQueue(msg, fn); addQueue(msg, fn);
} }
@ -198,7 +202,8 @@
if (url) { if (url) {
fn(url); fn(url);
} else if (msg.avatar) { } else if (msg.avatar) {
fn(`?Avatar/${'pass' == msg.from[0].dkimStatus ? 1 : 0}/${msg.avatar}`); fn(msg.avatar.startsWith('data:') ? msg.avatar
: `?Avatar/${'pass' == msg.from[0].dkimStatus ? 1 : 0}/${msg.avatar}`);
} else { } else {
// let from = msg.from[0]; // let from = msg.from[0];
// view.viewUserPic(`?Avatar/${'pass' == from.dkimStatus ? 1 : 0}/${encodeURIComponent(from.email)}`); // view.viewUserPic(`?Avatar/${'pass' == from.dkimStatus ? 1 : 0}/${encodeURIComponent(from.email)}`);

View file

@ -24,28 +24,36 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin
$this->addJs("{$identicon}.js"); $this->addJs("{$identicon}.js");
} }
// https://github.com/the-djmaze/snappymail/issues/714 // https://github.com/the-djmaze/snappymail/issues/714
$this->Config()->Get('plugin', 'delay', true) || $this->addHook('filter.json-response', 'FilterJsonResponse'); if ($this->Config()->Get('plugin', 'service', true) || !$this->Config()->Get('plugin', 'delay', true)) {
$this->addHook('filter.json-response', 'FilterJsonResponse');
}
} }
public function FilterJsonResponse(string $sAction, array &$aResponseItem) public function FilterJsonResponse(string $sAction, array &$aResponseItem)
{ {
if ('MessageList' === $sAction && !empty($aResponseItem['Result']['@Collection'])) { if ('MessageList' === $sAction && !empty($aResponseItem['Result']['@Collection'])) {
foreach ($aResponseItem['Result']['@Collection'] as $id => $message) { foreach ($aResponseItem['Result']['@Collection'] as $id => $message) {
$aResponseItem['Result']['@Collection'][$id]['Avatar'] = static::encryptFrom($message['From'][0]); $aResponseItem['Result']['@Collection'][$id]['Avatar'] = $this->encryptFrom($message['From'][0]);
} }
} else if ('Message' === $sAction && !empty($aResponseItem['Result']['From'])) { } else if ('Message' === $sAction && !empty($aResponseItem['Result']['From'])) {
$aResponseItem['Result']['Avatar'] = static::encryptFrom($aResponseItem['Result']['From'][0]); $aResponseItem['Result']['Avatar'] = $this->encryptFrom($aResponseItem['Result']['From'][0]);
} }
} }
private static function encryptFrom($mFrom) private function encryptFrom($mFrom)
{ {
if ($mFrom instanceof \MailSo\Mime\Email) { if ($mFrom instanceof \MailSo\Mime\Email) {
$mFrom = $mFrom->jsonSerialize(); $mFrom = $mFrom->jsonSerialize();
} }
return \is_array($mFrom) if (!\is_array($mFrom)) {
? \SnappyMail\Crypt::EncryptUrlSafe($mFrom['Email']) return null;
: null; }
if ('pass' == $mFrom['DkimStatus'] && $this->Config()->Get('plugin', 'service', true) && ($sIcon = static::getServiceIcon($mFrom['Email']))) {
return $sIcon;
}
return $this->Config()->Get('plugin', 'delay', true)
? null
: \SnappyMail\Crypt::EncryptUrlSafe($mFrom['Email']);
} }
/** /**
@ -94,6 +102,9 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin
['id' => 'jdenticon', 'name' => 'Triangles shape'] ['id' => 'jdenticon', 'name' => 'Triangles shape']
]) ])
->SetDescription('https://wikipedia.org/wiki/Identicon'), ->SetDescription('https://wikipedia.org/wiki/Identicon'),
\RainLoop\Plugins\Property::NewInstance('service')->SetLabel('Preload valid domain icons')
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
->SetDefaultValue(true),
\RainLoop\Plugins\Property::NewInstance('bimi')->SetLabel('Lookup BIMI') \RainLoop\Plugins\Property::NewInstance('bimi')->SetLabel('Lookup BIMI')
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
->SetDefaultValue(false) ->SetDefaultValue(false)
@ -117,6 +128,25 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin
return $aResult; return $aResult;
} }
// Only allow service icon when DKIM is valid. $bBimi is true when DKIM is valid.
private static function getServiceIcon(string $sEmail) : ?string
{
$sDomain = \explode('@', $sEmail);
$sDomain = \array_pop($sDomain);
$aServices = [
"services/{$sDomain}",
'services/' . \preg_replace('/^.+\\.([^.]+\\.[^.]+)$/D', '$1', $sDomain),
'services/' . \preg_replace('/^(.+\\.)?(paypal\\.[a-z][a-z])$/D', 'paypal.com', $sDomain)
];
foreach ($aServices as $service) {
$file = __DIR__ . "/images/{$service}.png";
if (\file_exists($file)) {
return 'data:image/png;base64,' . \base64_encode(\file_get_contents($file));
}
}
return null;
}
private function getAvatar(string $sEmail, bool $bBimi) : ?array private function getAvatar(string $sEmail, bool $bBimi) : ?array
{ {
if (!\strpos($sEmail, '@')) { if (!\strpos($sEmail, '@')) {
@ -202,7 +232,8 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin
\MailSo\Base\Http::setLastModified(\time()); \MailSo\Base\Http::setLastModified(\time());
} }
if (!$aResult) { // Only allow service icon when DKIM is valid. $bBimi is true when DKIM is valid.
if ($bBimi && !$aResult) {
$aServices = [ $aServices = [
"services/{$sDomain}", "services/{$sDomain}",
'services/' . \preg_replace('/^.+\\.([^.]+\\.[^.]+)$/D', '$1', $sDomain), 'services/' . \preg_replace('/^.+\\.([^.]+\\.[^.]+)$/D', '$1', $sDomain),