mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-09-06 21:24:12 +08:00
OpenPGP first look (#53)
This commit is contained in:
parent
74991b16d9
commit
098a04eab6
15 changed files with 175 additions and 20 deletions
|
@ -112,6 +112,13 @@ module.exports = function (grunt) {
|
|||
],
|
||||
dest: 'rainloop/v/<%= cfg.devVersion %>/static/js/boot.js'
|
||||
},
|
||||
js_openpgp: {
|
||||
nonull: true,
|
||||
src: [
|
||||
"vendors/openpgp.min.js",
|
||||
],
|
||||
dest: 'rainloop/v/<%= cfg.devVersion %>/static/js/openpgp.js'
|
||||
},
|
||||
js_libs: {
|
||||
nonull: true,
|
||||
options: {
|
||||
|
@ -383,7 +390,7 @@ module.exports = function (grunt) {
|
|||
nospawn: true
|
||||
},
|
||||
files: ['dev/**/*.js', 'vendors/**/*.js'],
|
||||
tasks: ['concat:js_libs', 'concat:js_admin', 'concat:js_app']
|
||||
tasks: ['concat:js_libs', 'concat:js_openpgp', 'concat:js_admin', 'concat:js_app']
|
||||
},
|
||||
styles: {
|
||||
options: {
|
||||
|
|
|
@ -785,6 +785,18 @@ RainLoopApp.prototype.bootstart = function ()
|
|||
|
||||
if (bValue)
|
||||
{
|
||||
// if (window.crypto && window.crypto.getRandomValues)
|
||||
// {
|
||||
// $.ajax({
|
||||
// 'url': RL.link().openPgpJs(),
|
||||
// 'dataType': 'script',
|
||||
// 'cache': true,
|
||||
// 'success': function () {
|
||||
// window.console.log('openPgpJs');
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
kn.startScreens([MailBoxScreen, SettingsScreen]);
|
||||
|
||||
// setup maito protocol
|
||||
|
@ -849,7 +861,6 @@ RainLoopApp.prototype.bootstart = function ()
|
|||
}
|
||||
|
||||
if (!Globals.bMobileDevice)
|
||||
// if (false)
|
||||
{
|
||||
_.defer(function () {
|
||||
Utils.initLayoutResizer('#rl-left', '#rl-right', Enums.ClientSideKeyName.FolderListSize);
|
||||
|
|
|
@ -257,6 +257,15 @@ LinkBuilder.prototype.notificationMailIcon = function ()
|
|||
this.sVersion + '/static/css/images/icom-message-notification.png';
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
LinkBuilder.prototype.openPgpJs = function ()
|
||||
{
|
||||
return ('' === this.sCdnStaticDomain ? 'rainloop/v/' : this.sCdnStaticDomain) +
|
||||
this.sVersion + '/static/js/openpgp.js';
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "RainLoop",
|
||||
"title": "RainLoop Webmail",
|
||||
"version": "1.6.2",
|
||||
"release": "660",
|
||||
"release": "661",
|
||||
"description": "Simple, modern & fast web-based email client",
|
||||
"homepage": "http://rainloop.net",
|
||||
"main": "Gruntfile.js",
|
||||
|
|
|
@ -248,6 +248,14 @@ class BodyStructure
|
|||
return 'doc' === \MailSo\Base\Utils::ContentTypeType($this->ContentType(), $this->FileName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsPgpSignature()
|
||||
{
|
||||
return 'application/pgp-signature' === \strtolower($this->ContentType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
|
|
|
@ -356,18 +356,30 @@ class MailClient
|
|||
|
||||
$oBodyStructure = null;
|
||||
$oMessage = false;
|
||||
$aTextMimeIndexes = array();
|
||||
$aBodyPeekMimeIndexes = array();
|
||||
|
||||
$aFetchResponse = $this->oImapClient->Fetch(array(\MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE), $iIndex, $bIndexIsUid);
|
||||
if (0 < \count($aFetchResponse))
|
||||
if (0 < \count($aFetchResponse) && isset($aFetchResponse[0]))
|
||||
{
|
||||
$oBodyStructure = $aFetchResponse[0]->GetFetchBodyStructure();
|
||||
$aTextParts = $oBodyStructure ? $oBodyStructure->SearchHtmlOrPlainParts() : null;
|
||||
if (is_array($aTextParts) && 0 < \count($aTextParts))
|
||||
if ($oBodyStructure)
|
||||
{
|
||||
foreach ($aTextParts as $oPart)
|
||||
$aTextParts = $oBodyStructure->SearchHtmlOrPlainParts();
|
||||
if (is_array($aTextParts) && 0 < \count($aTextParts))
|
||||
{
|
||||
$aTextMimeIndexes[] = $oPart->PartID();
|
||||
foreach ($aTextParts as $oPart)
|
||||
{
|
||||
$aBodyPeekMimeIndexes[] = $oPart->PartID();
|
||||
}
|
||||
}
|
||||
|
||||
$aSignatureParts = $oBodyStructure->SearchByContentType('application/pgp-signature');
|
||||
if (is_array($aSignatureParts) && 0 < \count($aSignatureParts))
|
||||
{
|
||||
foreach ($aSignatureParts as $oPart)
|
||||
{
|
||||
$aBodyPeekMimeIndexes[] = $oPart->PartID();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -381,9 +393,9 @@ class MailClient
|
|||
$this->getEnvelopeOrHeadersRequestString()
|
||||
);
|
||||
|
||||
if (0 < \count($aTextMimeIndexes))
|
||||
if (0 < \count($aBodyPeekMimeIndexes))
|
||||
{
|
||||
foreach ($aTextMimeIndexes as $sTextMimeIndex)
|
||||
foreach ($aBodyPeekMimeIndexes as $sTextMimeIndex)
|
||||
{
|
||||
$aFetchItems[] = \MailSo\Imap\Enumerations\FetchType::BODY_PEEK.'['.$sTextMimeIndex.']';
|
||||
}
|
||||
|
|
|
@ -103,6 +103,11 @@ class Message
|
|||
*/
|
||||
private $sPlain;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPlainRaw;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
@ -158,6 +163,11 @@ class Message
|
|||
*/
|
||||
private $iThreadsLen;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPgpSignature;
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
|
@ -191,6 +201,7 @@ class Message
|
|||
$this->oBcc = null;
|
||||
|
||||
$this->sPlain = '';
|
||||
$this->sPlainRaw = '';
|
||||
$this->sHtml = '';
|
||||
|
||||
$this->oAttachments = null;
|
||||
|
@ -208,6 +219,8 @@ class Message
|
|||
$this->iThreadsLen = 0;
|
||||
$this->iParentThread = 0;
|
||||
|
||||
$this->sPgpSignature = '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -227,6 +240,14 @@ class Message
|
|||
return $this->sPlain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function PlainRaw()
|
||||
{
|
||||
return $this->sPlainRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -235,6 +256,14 @@ class Message
|
|||
return $this->sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function PgpSignature()
|
||||
{
|
||||
return $this->sPgpSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHtml
|
||||
*
|
||||
|
@ -527,8 +556,6 @@ class Message
|
|||
$oBodyStructure = $oFetchResponse->GetFetchBodyStructure();
|
||||
}
|
||||
|
||||
$aTextParts = $oBodyStructure ? $oBodyStructure->SearchHtmlOrPlainParts() : array();
|
||||
|
||||
$sUid = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID);
|
||||
$sSize = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::RFC822_SIZE);
|
||||
$sInternalDate = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::INTERNALDATE);
|
||||
|
@ -704,6 +731,7 @@ class Message
|
|||
$this->sInReplyTo = $oFetchResponse->GetFetchEnvelopeValue(8, '');
|
||||
}
|
||||
|
||||
$aTextParts = $oBodyStructure ? $oBodyStructure->SearchHtmlOrPlainParts() : null;
|
||||
if (\is_array($aTextParts) && 0 < \count($aTextParts))
|
||||
{
|
||||
if (0 === \strlen($sCharset))
|
||||
|
@ -749,9 +777,43 @@ class Message
|
|||
else
|
||||
{
|
||||
$this->sPlain = \implode("\n", $sPlainParts);
|
||||
$this->sPlainRaw = $this->sPlain;
|
||||
}
|
||||
|
||||
unset($sHtmlParts, $sPlainParts);
|
||||
$aMatch = array();
|
||||
if (\preg_match('/-----BEGIN PGP SIGNATURE-----(.+)-----END PGP SIGNATURE-----/ism', $this->sPlain, $aMatch) && !empty($aMatch[0]))
|
||||
{
|
||||
$this->sPgpSignature = $aMatch[0];
|
||||
$this->sPlain = \trim($this->sPlain);
|
||||
}
|
||||
|
||||
$aMatch = array();
|
||||
if (!empty($this->sPgpSignature) &&
|
||||
\preg_match('/-----BEGIN PGP SIGNED MESSAGE-----(.+)-----BEGIN PGP SIGNATURE-----(.+)-----END PGP SIGNATURE-----/ism', $this->sPlain, $aMatch) &&
|
||||
!empty($aMatch[0]) && isset($aMatch[1]))
|
||||
{
|
||||
$this->sPlain = \str_replace($aMatch[0], $aMatch[1], $this->sPlain);
|
||||
$this->sPlain = \trim(\preg_replace('/^Hash: [^\s]+/i', '', \trim($this->sPlain)));
|
||||
}
|
||||
|
||||
unset($sHtmlParts, $sPlainParts, $aMatch);
|
||||
}
|
||||
|
||||
if (empty($this->sPgpSignature) && 'multipart/signed' === \strtolower($this->sContentType) &&
|
||||
'application/pgp-signature' === \strtolower($oHeaders->ParameterValue(
|
||||
\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
|
||||
\MailSo\Mime\Enumerations\Parameter::PROTOCOL
|
||||
)))
|
||||
{
|
||||
$aPgpSignatureParts = $oBodyStructure ? $oBodyStructure->SearchByContentType('application/pgp-signature') : null;
|
||||
if (\is_array($aPgpSignatureParts) && 0 < \count($aPgpSignatureParts) && isset($aPgpSignatureParts[0]))
|
||||
{
|
||||
$sPgpSignatureText = $oFetchResponse->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::BODY.'['.$aPgpSignatureParts[0]->PartID().']');
|
||||
if (\is_string($sPgpSignatureText) && 0 < \strlen($sPgpSignatureText) && 0 < \strpos($sPgpSignatureText, 'BEGIN PGP SIGNATURE'))
|
||||
{
|
||||
$this->sPgpSignature = \trim($sPgpSignatureText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($oBodyStructure)
|
||||
|
|
|
@ -13,4 +13,5 @@ class Parameter
|
|||
const NAME = 'name';
|
||||
const FILENAME = 'filename';
|
||||
const BOUNDARY = 'boundary';
|
||||
const PROTOCOL = 'protocol';
|
||||
}
|
||||
|
|
|
@ -6320,13 +6320,14 @@ class Actions
|
|||
}
|
||||
}
|
||||
|
||||
$sPlain = '';
|
||||
$sPlain = $sPlainRaw = '';
|
||||
$sHtml = $mResponse->Html();
|
||||
$bRtl = false;
|
||||
|
||||
if (0 === \strlen($sHtml))
|
||||
{
|
||||
$sPlain = $mResponse->Plain();
|
||||
$sPlainRaw = $mResponse->PlainRaw();
|
||||
$bRtl = \MailSo\Base\Utils::IsRTL($sPlain);
|
||||
}
|
||||
else
|
||||
|
@ -6341,9 +6342,12 @@ class Actions
|
|||
$sHtml, $bHasExternals, $mFoundedCIDs, $aContentLocationUrls, $mFoundedContentLocationUrls);
|
||||
|
||||
$mResult['Plain'] = 0 === \strlen($sPlain) ? '' : \MailSo\Base\HtmlUtils::ConvertPlainToHtml($sPlain);
|
||||
$mResult['PlainRaw'] = $sPlainRaw;
|
||||
$mResult['Rtl'] = $bRtl;
|
||||
|
||||
unset($sHtml, $sPlain);
|
||||
$mResult['PgpSignature'] = $mResponse->PgpSignature();
|
||||
|
||||
unset($sHtml, $sPlain, $sPlainRaw);
|
||||
|
||||
$mResult['HasExternals'] = $bHasExternals;
|
||||
$mResult['HasInternals'] = (\is_array($mFoundedCIDs) && 0 < \count($mFoundedCIDs)) ||
|
||||
|
|
|
@ -3222,6 +3222,15 @@ LinkBuilder.prototype.notificationMailIcon = function ()
|
|||
this.sVersion + '/static/css/images/icom-message-notification.png';
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
LinkBuilder.prototype.openPgpJs = function ()
|
||||
{
|
||||
return ('' === this.sCdnStaticDomain ? 'rainloop/v/' : this.sCdnStaticDomain) +
|
||||
this.sVersion + '/static/js/openpgp.js';
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
|
|
2
rainloop/v/0.0.0/static/js/admin.min.js
vendored
2
rainloop/v/0.0.0/static/js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -3222,6 +3222,15 @@ LinkBuilder.prototype.notificationMailIcon = function ()
|
|||
this.sVersion + '/static/css/images/icom-message-notification.png';
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
LinkBuilder.prototype.openPgpJs = function ()
|
||||
{
|
||||
return ('' === this.sCdnStaticDomain ? 'rainloop/v/' : this.sCdnStaticDomain) +
|
||||
this.sVersion + '/static/js/openpgp.js';
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
|
@ -17362,6 +17371,18 @@ RainLoopApp.prototype.bootstart = function ()
|
|||
|
||||
if (bValue)
|
||||
{
|
||||
// if (window.crypto && window.crypto.getRandomValues)
|
||||
// {
|
||||
// $.ajax({
|
||||
// 'url': RL.link().openPgpJs(),
|
||||
// 'dataType': 'script',
|
||||
// 'cache': true,
|
||||
// 'success': function () {
|
||||
// window.console.log('openPgpJs');
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
kn.startScreens([MailBoxScreen, SettingsScreen]);
|
||||
|
||||
// setup maito protocol
|
||||
|
@ -17426,7 +17447,6 @@ RainLoopApp.prototype.bootstart = function ()
|
|||
}
|
||||
|
||||
if (!Globals.bMobileDevice)
|
||||
// if (false)
|
||||
{
|
||||
_.defer(function () {
|
||||
Utils.initLayoutResizer('#rl-left', '#rl-right', Enums.ClientSideKeyName.FolderListSize);
|
||||
|
|
4
rainloop/v/0.0.0/static/js/app.min.js
vendored
4
rainloop/v/0.0.0/static/js/app.min.js
vendored
File diff suppressed because one or more lines are too long
6
rainloop/v/0.0.0/static/js/openpgp.js
Normal file
6
rainloop/v/0.0.0/static/js/openpgp.js
Normal file
File diff suppressed because one or more lines are too long
6
vendors/openpgp.min.js
vendored
Normal file
6
vendors/openpgp.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue