mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-30 20:49:20 +03:00
CRLF to LF
This commit is contained in:
parent
4468d5bd22
commit
6e0d0b3b6e
209 changed files with 23729 additions and 22109 deletions
|
|
@ -1,40 +1,40 @@
|
|||
<?php
|
||||
|
||||
class AddXOriginatingIpHeaderPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('filter.build-message', 'FilterBuildMessage');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Mime\Message $oMessage
|
||||
*/
|
||||
public function FilterBuildMessage(&$oMessage)
|
||||
{
|
||||
if ($oMessage instanceof \MailSo\Mime\Message)
|
||||
{
|
||||
$sIP = $this->Manager()->Actions()->Http()->GetClientIp(
|
||||
!!$this->Config()->Get('plugin', 'check_proxy', false));
|
||||
|
||||
$oMessage->SetCustomHeader(
|
||||
\MailSo\Mime\Enumerations\Header::X_ORIGINATING_IP,
|
||||
$this->Manager()->Actions()->Http()->IsLocalhost($sIP) ? '127.0.0.1' : $sIP
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('check_proxy')
|
||||
->SetLabel('Сheck User Proxy')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetDescription('Enable, if you need to check proxy header')
|
||||
->SetDefaultValue(false)
|
||||
);
|
||||
}
|
||||
<?php
|
||||
|
||||
class AddXOriginatingIpHeaderPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('filter.build-message', 'FilterBuildMessage');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Mime\Message $oMessage
|
||||
*/
|
||||
public function FilterBuildMessage(&$oMessage)
|
||||
{
|
||||
if ($oMessage instanceof \MailSo\Mime\Message)
|
||||
{
|
||||
$sIP = $this->Manager()->Actions()->Http()->GetClientIp(
|
||||
!!$this->Config()->Get('plugin', 'check_proxy', false));
|
||||
|
||||
$oMessage->SetCustomHeader(
|
||||
\MailSo\Mime\Enumerations\Header::X_ORIGINATING_IP,
|
||||
$this->Manager()->Actions()->Http()->IsLocalhost($sIP) ? '127.0.0.1' : $sIP
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('check_proxy')
|
||||
->SetLabel('Сheck User Proxy')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetDescription('Enable, if you need to check proxy header')
|
||||
->SetDefaultValue(false)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,15 +7,15 @@
|
|||
*
|
||||
* Based on:
|
||||
* https://github.com/RainLoop/rainloop-webmail/blob/master/plugins/override-smtp-credentials/index.php
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class AutoDomainGrabPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
|
||||
|
||||
private $imap_prefix = "mail.";
|
||||
private $smtp_prefix = "mail.";
|
||||
|
||||
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('filter.smtp-credentials', 'FilterSmtpCredentials');
|
||||
|
|
@ -41,7 +41,7 @@ class AutoDomainGrabPlugin extends \RainLoop\Plugins\AbstractPlugin
|
|||
{
|
||||
$aImapCredentials['Host'] = $mxhosts[0];
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
$aImapCredentials['Host'] = $this->imap_prefix.$domain;
|
||||
}
|
||||
|
|
@ -67,8 +67,8 @@ class AutoDomainGrabPlugin extends \RainLoop\Plugins\AbstractPlugin
|
|||
if(getmxrr($domain, $mxhosts) && sizeof($mxhosts) > 0)
|
||||
{
|
||||
$aSmtpCredentials['Host'] = $mxhosts[0];
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
$aSmtpCredentials['Host'] = $this->smtp_prefix.$domain;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,237 +1,237 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordCustomSqlDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mHost = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mPass = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mDatabase = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mTable = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mSql = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $mHost
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmHost($mHost)
|
||||
{
|
||||
$this->mHost = $mHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mUser
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmUser($mUser)
|
||||
{
|
||||
$this->mUser = $mUser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mPass
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmPass($mPass)
|
||||
{
|
||||
$this->mPass = $mPass;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mDatabase
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmDatabase($mDatabase)
|
||||
{
|
||||
$this->mDatabase = $mDatabase;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mTable
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmTable($mTable)
|
||||
{
|
||||
$this->mTable = $mTable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mSql
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmSql($mSql)
|
||||
{
|
||||
$this->mSql = $mSql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
if ($oLogger instanceof \MailSo\Log\Logger)
|
||||
{
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PasswordChangePossibility($oAccount)
|
||||
{
|
||||
return $oAccount && $oAccount->Email();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
|
||||
$dsn = 'mysql:host='.$this->mHost.';dbname='.$this->mDatabase.';charset=utf8';
|
||||
$options = array(
|
||||
PDO::ATTR_EMULATE_PREPARES => true,
|
||||
PDO::ATTR_PERSISTENT => true,
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
$conn = new PDO($dsn,$this->mUser,$this->mPass,$options);
|
||||
|
||||
//prepare SQL varaibles
|
||||
$sEmail = $oAccount->Email();
|
||||
$sEmailUser = \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail);
|
||||
$sEmailDomain = \MailSo\Base\Utils::GetDomainFromEmail($sEmail);
|
||||
|
||||
// some variables cannot be prepared
|
||||
$this->mSql = str_replace(array(
|
||||
':table'
|
||||
), array(
|
||||
$this->mTable
|
||||
), $this->mSql);
|
||||
|
||||
$placeholders = array(
|
||||
':email' => $sEmail,
|
||||
':oldpass' => $sPrevPassword,
|
||||
':newpass' => $sNewPassword,
|
||||
':domain' => $sEmailDomain,
|
||||
':username' => $sEmailUser
|
||||
);
|
||||
|
||||
// we have to check that all placehoders are used in the query, passing any unused placeholders will generate an error
|
||||
$used_placeholders = array();
|
||||
|
||||
foreach($placeholders as $placeholder => $value) {
|
||||
if(preg_match_all('/'.$placeholder . '(?![a-zA-Z0-9\-])'.'/', $this->mSql) === 1) {
|
||||
// backwards-compabitibility: remove single and double quotes around placeholders
|
||||
$this->mSql = str_replace('`'.$placeholder.'`', $placeholder, $this->mSql);
|
||||
$this->mSql = str_replace("'".$placeholder."'", $placeholder, $this->mSql);
|
||||
$this->mSql = str_replace('"'.$placeholder.'"', $placeholder, $this->mSql);
|
||||
$used_placeholders[$placeholder] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$statement = $conn->prepare($this->mSql);
|
||||
|
||||
// everything is ready (hopefully), bind the values
|
||||
foreach($used_placeholders as $placeholder => $value) {
|
||||
$statement->bindValue($placeholder, $value);
|
||||
}
|
||||
|
||||
// and execute
|
||||
$mSqlReturn = $statement->execute();
|
||||
|
||||
/* can be used for debugging
|
||||
ob_start();
|
||||
$statement->debugDumpParams();
|
||||
$r = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->oLogger->Write($r);
|
||||
*/
|
||||
|
||||
if ($mSqlReturn == true)
|
||||
{
|
||||
$bResult = true;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Success! Password changed.');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Something went wrong. Either current password is incorrect, or new password does not match criteria.');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class ChangePasswordCustomSqlDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mHost = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mPass = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mDatabase = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mTable = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mSql = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $mHost
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmHost($mHost)
|
||||
{
|
||||
$this->mHost = $mHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mUser
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmUser($mUser)
|
||||
{
|
||||
$this->mUser = $mUser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mPass
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmPass($mPass)
|
||||
{
|
||||
$this->mPass = $mPass;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mDatabase
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmDatabase($mDatabase)
|
||||
{
|
||||
$this->mDatabase = $mDatabase;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mTable
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmTable($mTable)
|
||||
{
|
||||
$this->mTable = $mTable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mSql
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmSql($mSql)
|
||||
{
|
||||
$this->mSql = $mSql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
if ($oLogger instanceof \MailSo\Log\Logger)
|
||||
{
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PasswordChangePossibility($oAccount)
|
||||
{
|
||||
return $oAccount && $oAccount->Email();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
|
||||
$dsn = 'mysql:host='.$this->mHost.';dbname='.$this->mDatabase.';charset=utf8';
|
||||
$options = array(
|
||||
PDO::ATTR_EMULATE_PREPARES => true,
|
||||
PDO::ATTR_PERSISTENT => true,
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
$conn = new PDO($dsn,$this->mUser,$this->mPass,$options);
|
||||
|
||||
//prepare SQL varaibles
|
||||
$sEmail = $oAccount->Email();
|
||||
$sEmailUser = \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail);
|
||||
$sEmailDomain = \MailSo\Base\Utils::GetDomainFromEmail($sEmail);
|
||||
|
||||
// some variables cannot be prepared
|
||||
$this->mSql = str_replace(array(
|
||||
':table'
|
||||
), array(
|
||||
$this->mTable
|
||||
), $this->mSql);
|
||||
|
||||
$placeholders = array(
|
||||
':email' => $sEmail,
|
||||
':oldpass' => $sPrevPassword,
|
||||
':newpass' => $sNewPassword,
|
||||
':domain' => $sEmailDomain,
|
||||
':username' => $sEmailUser
|
||||
);
|
||||
|
||||
// we have to check that all placehoders are used in the query, passing any unused placeholders will generate an error
|
||||
$used_placeholders = array();
|
||||
|
||||
foreach($placeholders as $placeholder => $value) {
|
||||
if(preg_match_all('/'.$placeholder . '(?![a-zA-Z0-9\-])'.'/', $this->mSql) === 1) {
|
||||
// backwards-compabitibility: remove single and double quotes around placeholders
|
||||
$this->mSql = str_replace('`'.$placeholder.'`', $placeholder, $this->mSql);
|
||||
$this->mSql = str_replace("'".$placeholder."'", $placeholder, $this->mSql);
|
||||
$this->mSql = str_replace('"'.$placeholder.'"', $placeholder, $this->mSql);
|
||||
$used_placeholders[$placeholder] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$statement = $conn->prepare($this->mSql);
|
||||
|
||||
// everything is ready (hopefully), bind the values
|
||||
foreach($used_placeholders as $placeholder => $value) {
|
||||
$statement->bindValue($placeholder, $value);
|
||||
}
|
||||
|
||||
// and execute
|
||||
$mSqlReturn = $statement->execute();
|
||||
|
||||
/* can be used for debugging
|
||||
ob_start();
|
||||
$statement->debugDumpParams();
|
||||
$r = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->oLogger->Write($r);
|
||||
*/
|
||||
|
||||
if ($mSqlReturn == true)
|
||||
{
|
||||
$bResult = true;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Success! Password changed.');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Something went wrong. Either current password is incorrect, or new password does not match criteria.');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,53 +1,53 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordCustomSqlPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
include_once __DIR__.'/ChangePasswordCustomSqlDriver.php';
|
||||
$oProvider = new ChangePasswordCustomSqlDriver();
|
||||
$oProvider
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
->SetmHost($this->Config()->Get('plugin', 'mHost', ''))
|
||||
->SetmUser($this->Config()->Get('plugin', 'mUser', ''))
|
||||
->SetmPass($this->Config()->Get('plugin', 'mPass', ''))
|
||||
->SetmDatabase($this->Config()->Get('plugin', 'mDatabase', ''))
|
||||
->SetmTable($this->Config()->Get('plugin', 'mTable', ''))
|
||||
->SetmSql($this->Config()->Get('plugin', 'mSql', ''))
|
||||
;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('mHost')->SetLabel('MySQL Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mUser')->SetLabel('MySQL User'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mPass')->SetLabel('MySQL Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD),
|
||||
\RainLoop\Plugins\Property::NewInstance('mDatabase')->SetLabel('MySQL Database'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mTable')->SetLabel('MySQL Table'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mSql')->SetLabel('SQL statement')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('SQL statement (allowed wildcards :table, :email, :oldpass, :newpass, :domain, :username). Use SQL functions for encryption.')
|
||||
->SetDefaultValue('UPDATE :table SET password = md5(:newpass) WHERE domain = :domain AND username = :username and oldpass = md5(:oldpass)')
|
||||
);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class ChangePasswordCustomSqlPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
include_once __DIR__.'/ChangePasswordCustomSqlDriver.php';
|
||||
$oProvider = new ChangePasswordCustomSqlDriver();
|
||||
$oProvider
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
->SetmHost($this->Config()->Get('plugin', 'mHost', ''))
|
||||
->SetmUser($this->Config()->Get('plugin', 'mUser', ''))
|
||||
->SetmPass($this->Config()->Get('plugin', 'mPass', ''))
|
||||
->SetmDatabase($this->Config()->Get('plugin', 'mDatabase', ''))
|
||||
->SetmTable($this->Config()->Get('plugin', 'mTable', ''))
|
||||
->SetmSql($this->Config()->Get('plugin', 'mSql', ''))
|
||||
;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('mHost')->SetLabel('MySQL Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mUser')->SetLabel('MySQL User'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mPass')->SetLabel('MySQL Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD),
|
||||
\RainLoop\Plugins\Property::NewInstance('mDatabase')->SetLabel('MySQL Database'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mTable')->SetLabel('MySQL Table'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mSql')->SetLabel('SQL statement')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('SQL statement (allowed wildcards :table, :email, :oldpass, :newpass, :domain, :username). Use SQL functions for encryption.')
|
||||
->SetDefaultValue('UPDATE :table SET password = md5(:newpass) WHERE domain = :domain AND username = :username and oldpass = md5(:oldpass)')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,138 +1,138 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordCyberPanel implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mHost = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mPass = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $mHost
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetmHost($mHost)
|
||||
{
|
||||
$this->mHost = $mHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mUser
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetmUser($mUser)
|
||||
{
|
||||
$this->mUser = $mUser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mPass
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetmPass($mPass)
|
||||
{
|
||||
$this->mPass = $mPass;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
if ($oLogger instanceof \MailSo\Log\Logger)
|
||||
{
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PasswordChangePossibility($oAccount)
|
||||
{
|
||||
return $oAccount && $oAccount->Email();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
$db = mysqli_connect($this->mHost, $this->mUser, $this->mPass, 'cyberpanel');
|
||||
|
||||
try
|
||||
{
|
||||
$sEmail = mysqli_real_escape_string($db, $oAccount->Email());
|
||||
$sEmailUser = mysqli_real_escape_string($db, \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail));
|
||||
$sEmailDomain = mysqli_real_escape_string($db, \MailSo\Base\Utils::GetDomainFromEmail($sEmail));
|
||||
|
||||
$password_check_query = "SELECT * FROM e_users WHERE emailOwner_id = '$sEmailDomain' AND email = '$sEmail'";
|
||||
$result = mysqli_query($db, $password_check_query);
|
||||
$password_check = mysqli_fetch_assoc($result);
|
||||
|
||||
if (password_verify($sPrevPassword, substr($password_check['password'], 7))) {
|
||||
$hashed_password = mysqli_real_escape_string($db, '{CRYPT}'.password_hash($sNewPassword, PASSWORD_BCRYPT, ['cost' => 12,]));
|
||||
$password_update_query = "UPDATE e_users SET password = '$hashed_password' WHERE emailOwner_id = '$sEmailDomain' AND email = '$sEmail'";
|
||||
mysqli_query($db, $password_update_query);
|
||||
$bResult = true;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Success! The password was changed.');
|
||||
}
|
||||
} else {
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Something went wrong. Either the current password is incorrect or the new password does not meet the criteria.');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class ChangePasswordCyberPanel implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mHost = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mPass = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $mHost
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetmHost($mHost)
|
||||
{
|
||||
$this->mHost = $mHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mUser
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetmUser($mUser)
|
||||
{
|
||||
$this->mUser = $mUser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mPass
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetmPass($mPass)
|
||||
{
|
||||
$this->mPass = $mPass;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
if ($oLogger instanceof \MailSo\Log\Logger)
|
||||
{
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PasswordChangePossibility($oAccount)
|
||||
{
|
||||
return $oAccount && $oAccount->Email();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
$db = mysqli_connect($this->mHost, $this->mUser, $this->mPass, 'cyberpanel');
|
||||
|
||||
try
|
||||
{
|
||||
$sEmail = mysqli_real_escape_string($db, $oAccount->Email());
|
||||
$sEmailUser = mysqli_real_escape_string($db, \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail));
|
||||
$sEmailDomain = mysqli_real_escape_string($db, \MailSo\Base\Utils::GetDomainFromEmail($sEmail));
|
||||
|
||||
$password_check_query = "SELECT * FROM e_users WHERE emailOwner_id = '$sEmailDomain' AND email = '$sEmail'";
|
||||
$result = mysqli_query($db, $password_check_query);
|
||||
$password_check = mysqli_fetch_assoc($result);
|
||||
|
||||
if (password_verify($sPrevPassword, substr($password_check['password'], 7))) {
|
||||
$hashed_password = mysqli_real_escape_string($db, '{CRYPT}'.password_hash($sNewPassword, PASSWORD_BCRYPT, ['cost' => 12,]));
|
||||
$password_update_query = "UPDATE e_users SET password = '$hashed_password' WHERE emailOwner_id = '$sEmailDomain' AND email = '$sEmail'";
|
||||
mysqli_query($db, $password_update_query);
|
||||
$bResult = true;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Success! The password was changed.');
|
||||
}
|
||||
} else {
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Something went wrong. Either the current password is incorrect or the new password does not meet the criteria.');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,44 +1,44 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordCyberPanelPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
include_once __DIR__.'/ChangePasswordCyberPanel.php';
|
||||
$oProvider = new ChangePasswordCyberPanel();
|
||||
$oProvider
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
->SetmHost($this->Config()->Get('plugin', 'mHost', ''))
|
||||
->SetmUser($this->Config()->Get('plugin', 'mUser', ''))
|
||||
->SetmPass($this->Config()->Get('plugin', 'mPass', ''))
|
||||
;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('mHost')->SetLabel('MySQL Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mUser')->SetLabel('MySQL User'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mPass')->SetLabel('MySQL Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class ChangePasswordCyberPanelPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
include_once __DIR__.'/ChangePasswordCyberPanel.php';
|
||||
$oProvider = new ChangePasswordCyberPanel();
|
||||
$oProvider
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
->SetmHost($this->Config()->Get('plugin', 'mHost', ''))
|
||||
->SetmUser($this->Config()->Get('plugin', 'mUser', ''))
|
||||
->SetmPass($this->Config()->Get('plugin', 'mPass', ''))
|
||||
;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('mHost')->SetLabel('MySQL Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mUser')->SetLabel('MySQL User'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mPass')->SetLabel('MySQL Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class DirectAdminChangePasswordDriver implements \RainLoop\Providers\ChangePassw
|
|||
* @var string
|
||||
*/
|
||||
private $iPort = 2222;
|
||||
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -21,7 +21,7 @@ class DirectAdminChangePasswordDriver implements \RainLoop\Providers\ChangePassw
|
|||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
|
||||
/**
|
||||
* @param string $sHost
|
||||
* @param int $iPort
|
||||
|
|
@ -97,7 +97,7 @@ class DirectAdminChangePasswordDriver implements \RainLoop\Providers\ChangePassw
|
|||
$sHost = \str_replace('{user:host-smtp}', $oAccount->Domain()->OutHost(), $sHost);
|
||||
$sHost = \str_replace('{user:domain}', \MailSo\Base\Utils::GetDomainFromEmail($sEmail), $sHost);
|
||||
$sHost = \rtrim($this->sHost, '/\\');
|
||||
|
||||
|
||||
if (!\preg_match('/^http[s]?:\/\//i', $sHost))
|
||||
{
|
||||
$sHost = 'http://'.$sHost;
|
||||
|
|
|
|||
|
|
@ -1,76 +1,76 @@
|
|||
<?php
|
||||
|
||||
class FroxlorchangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
if (!extension_loaded('pdo') || !class_exists('PDO'))
|
||||
{
|
||||
return 'The PHP exention PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || !in_array('mysql', $aDrivers))
|
||||
{
|
||||
return 'The PHP exention PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
$sDsn = \trim($this->Config()->Get('plugin', 'pdo_dsn', ''));
|
||||
$sUser = (string) $this->Config()->Get('plugin', 'user', '');
|
||||
$sPassword = (string) $this->Config()->Get('plugin', 'password', '');
|
||||
|
||||
if (!empty($sDsn) && 0 < \strlen($sUser) && 0 < \strlen($sPassword))
|
||||
{
|
||||
include_once __DIR__.'/FroxlorChangePasswordDriver.php';
|
||||
|
||||
$oProvider = new FroxlorChangePasswordDriver();
|
||||
$oProvider->SetLogger($this->Manager()->Actions()->Logger());
|
||||
$oProvider->SetConfig($sDsn, $sUser, $sPassword);
|
||||
$oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('pdo_dsn')->SetLabel('Froxlor PDO dsn')
|
||||
->SetDefaultValue('mysql:host=127.0.0.1;dbname=froxlor'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('DB User')
|
||||
->SetDefaultValue('root'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('DB Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net')
|
||||
->SetDefaultValue('*')
|
||||
);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class FroxlorchangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
if (!extension_loaded('pdo') || !class_exists('PDO'))
|
||||
{
|
||||
return 'The PHP exention PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || !in_array('mysql', $aDrivers))
|
||||
{
|
||||
return 'The PHP exention PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
$sDsn = \trim($this->Config()->Get('plugin', 'pdo_dsn', ''));
|
||||
$sUser = (string) $this->Config()->Get('plugin', 'user', '');
|
||||
$sPassword = (string) $this->Config()->Get('plugin', 'password', '');
|
||||
|
||||
if (!empty($sDsn) && 0 < \strlen($sUser) && 0 < \strlen($sPassword))
|
||||
{
|
||||
include_once __DIR__.'/FroxlorChangePasswordDriver.php';
|
||||
|
||||
$oProvider = new FroxlorChangePasswordDriver();
|
||||
$oProvider->SetLogger($this->Manager()->Actions()->Logger());
|
||||
$oProvider->SetConfig($sDsn, $sUser, $sPassword);
|
||||
$oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('pdo_dsn')->SetLabel('Froxlor PDO dsn')
|
||||
->SetDefaultValue('mysql:host=127.0.0.1;dbname=froxlor'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('DB User')
|
||||
->SetDefaultValue('root'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('DB Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net')
|
||||
->SetDefaultValue('*')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,49 @@
|
|||
<?php
|
||||
|
||||
class GoogleAnalyticsPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function Init()
|
||||
{
|
||||
if ('' !== $this->Config()->Get('plugin', 'account', ''))
|
||||
{
|
||||
$this->addJs('js/include.js');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
$oAccount = \RainLoop\Plugins\Property::NewInstance('account')->SetLabel('Account')
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue('')
|
||||
;
|
||||
|
||||
if (\method_exists($oAccount, 'SetPlaceholder'))
|
||||
{
|
||||
$oAccount->SetPlaceholder('UA-XXXXXXXX-X');
|
||||
}
|
||||
|
||||
return array($oAccount,
|
||||
\RainLoop\Plugins\Property::NewInstance('domain_name')->SetLabel('Domain Name')
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('universal_analytics')->SetLabel('Use Universal Analytics')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(true),
|
||||
\RainLoop\Plugins\Property::NewInstance('track_pageview')->SetLabel('Track Pageview')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(true),
|
||||
\RainLoop\Plugins\Property::NewInstance('send_events')->SetLabel('Send Events')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(false)
|
||||
);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class GoogleAnalyticsPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function Init()
|
||||
{
|
||||
if ('' !== $this->Config()->Get('plugin', 'account', ''))
|
||||
{
|
||||
$this->addJs('js/include.js');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
$oAccount = \RainLoop\Plugins\Property::NewInstance('account')->SetLabel('Account')
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue('')
|
||||
;
|
||||
|
||||
if (\method_exists($oAccount, 'SetPlaceholder'))
|
||||
{
|
||||
$oAccount->SetPlaceholder('UA-XXXXXXXX-X');
|
||||
}
|
||||
|
||||
return array($oAccount,
|
||||
\RainLoop\Plugins\Property::NewInstance('domain_name')->SetLabel('Domain Name')
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('universal_analytics')->SetLabel('Use Universal Analytics')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(true),
|
||||
\RainLoop\Plugins\Property::NewInstance('track_pageview')->SetLabel('Track Pageview')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(true),
|
||||
\RainLoop\Plugins\Property::NewInstance('send_events')->SetLabel('Send Events')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(false)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,95 +1,95 @@
|
|||
<?php
|
||||
|
||||
class IspmailChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
if (!extension_loaded('pdo') || !class_exists('PDO'))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || !in_array('mysql', $aDrivers))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
include_once __DIR__.'/ChangePasswordISPmailDriver.php';
|
||||
|
||||
$oProvider = new ChangePasswordISPmailDriver();
|
||||
|
||||
$oProvider
|
||||
->SetHost($this->Config()->Get('plugin', 'host', ''))
|
||||
->SetPort((int) $this->Config()->Get('plugin', 'port', 3306))
|
||||
->SetDatabase($this->Config()->Get('plugin', 'database', ''))
|
||||
->SetTable($this->Config()->Get('plugin', 'table', ''))
|
||||
->SetUserColumn($this->Config()->Get('plugin', 'usercol', ''))
|
||||
->SetPasswordColumn($this->Config()->Get('plugin', 'passcol', ''))
|
||||
->SetUser($this->Config()->Get('plugin', 'user', ''))
|
||||
->SetPassword($this->Config()->Get('plugin', 'password', ''))
|
||||
->SetEncrypt($this->Config()->Get('plugin', 'encrypt', ''))
|
||||
->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))))
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('host')->SetLabel('MySQL Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('port')->SetLabel('MySQL Port')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
|
||||
->SetDefaultValue(3306),
|
||||
\RainLoop\Plugins\Property::NewInstance('database')->SetLabel('MySQL Database')
|
||||
->SetDefaultValue('mailserver'),
|
||||
\RainLoop\Plugins\Property::NewInstance('table')->SetLabel('MySQL table')
|
||||
->SetDefaultValue('virtual_users'),
|
||||
\RainLoop\Plugins\Property::NewInstance('usercol')->SetLabel('MySQL username column')
|
||||
->SetDefaultValue('email'),
|
||||
\RainLoop\Plugins\Property::NewInstance('passcol')->SetLabel('MySQL password column')
|
||||
->SetDefaultValue('password'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('MySQL User')
|
||||
->SetDefaultValue('mailuser'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('MySQL Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('encrypt')->SetLabel('Encrypt')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('PLAIN-MD5', 'SHA256-CRYPT'))
|
||||
->SetDescription('In what way do you want the passwords to be crypted ?'),
|
||||
\RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net')
|
||||
->SetDefaultValue('*')
|
||||
);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class IspmailChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
if (!extension_loaded('pdo') || !class_exists('PDO'))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || !in_array('mysql', $aDrivers))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
include_once __DIR__.'/ChangePasswordISPmailDriver.php';
|
||||
|
||||
$oProvider = new ChangePasswordISPmailDriver();
|
||||
|
||||
$oProvider
|
||||
->SetHost($this->Config()->Get('plugin', 'host', ''))
|
||||
->SetPort((int) $this->Config()->Get('plugin', 'port', 3306))
|
||||
->SetDatabase($this->Config()->Get('plugin', 'database', ''))
|
||||
->SetTable($this->Config()->Get('plugin', 'table', ''))
|
||||
->SetUserColumn($this->Config()->Get('plugin', 'usercol', ''))
|
||||
->SetPasswordColumn($this->Config()->Get('plugin', 'passcol', ''))
|
||||
->SetUser($this->Config()->Get('plugin', 'user', ''))
|
||||
->SetPassword($this->Config()->Get('plugin', 'password', ''))
|
||||
->SetEncrypt($this->Config()->Get('plugin', 'encrypt', ''))
|
||||
->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))))
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('host')->SetLabel('MySQL Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('port')->SetLabel('MySQL Port')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
|
||||
->SetDefaultValue(3306),
|
||||
\RainLoop\Plugins\Property::NewInstance('database')->SetLabel('MySQL Database')
|
||||
->SetDefaultValue('mailserver'),
|
||||
\RainLoop\Plugins\Property::NewInstance('table')->SetLabel('MySQL table')
|
||||
->SetDefaultValue('virtual_users'),
|
||||
\RainLoop\Plugins\Property::NewInstance('usercol')->SetLabel('MySQL username column')
|
||||
->SetDefaultValue('email'),
|
||||
\RainLoop\Plugins\Property::NewInstance('passcol')->SetLabel('MySQL password column')
|
||||
->SetDefaultValue('password'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('MySQL User')
|
||||
->SetDefaultValue('mailuser'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('MySQL Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('encrypt')->SetLabel('Encrypt')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('PLAIN-MD5', 'SHA256-CRYPT'))
|
||||
->SetDescription('In what way do you want the passwords to be crypted ?'),
|
||||
\RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net')
|
||||
->SetDefaultValue('*')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,162 +1,162 @@
|
|||
<?php
|
||||
|
||||
class MailcowChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDsn = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sDsn
|
||||
* @param string $sUser
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return \IspConfigChangePasswordDriver
|
||||
*/
|
||||
public function SetConfig($sDsn, $sUser, $sPassword)
|
||||
{
|
||||
$this->sDsn = $sDsn;
|
||||
$this->sUser = $sUser;
|
||||
$this->sPassword = $sPassword;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \IspConfigChangePasswordDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \IspConfigChangePasswordDriver
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
if ($oLogger instanceof \MailSo\Log\Logger)
|
||||
{
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PasswordChangePossibility($oAccount)
|
||||
{
|
||||
return $oAccount && $oAccount->Email() &&
|
||||
\RainLoop\Plugins\Helper::ValidateWildcardValues($oAccount->Email(), $this->sAllowedEmails);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Mailcow: Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
if (!empty($this->sDsn) && 0 < \strlen($this->sUser) && 0 < \strlen($this->sPassword) && $oAccount)
|
||||
{
|
||||
try
|
||||
{
|
||||
$oPdo = new \PDO($this->sDsn, $this->sUser, $this->sPassword);
|
||||
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$oStmt = $oPdo->prepare('SELECT password, username FROM mailbox WHERE username = ? LIMIT 1');
|
||||
if ($oStmt->execute(array($oAccount->IncLogin())))
|
||||
{
|
||||
$aFetchResult = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
if (\is_array($aFetchResult) && isset($aFetchResult[0]['password'], $aFetchResult[0]['username']))
|
||||
{
|
||||
$sDbPassword = $aFetchResult[0]['password'];
|
||||
if (\substr($sDbPassword, 0, 14) === '{SHA512-CRYPT}') {
|
||||
$sDbSalt = \substr($sDbPassword, 17, 16);
|
||||
} else {
|
||||
$sDbSalt = \substr($sDbPassword, 3, 16);
|
||||
}
|
||||
|
||||
if ('{SHA512-CRYPT}'.\crypt($sPrevPassword, '$6$'.$sDbSalt) === $sDbPassword)
|
||||
{
|
||||
$oStmt = $oPdo->prepare('UPDATE mailbox SET password = ? WHERE username = ?');
|
||||
if ($oStmt->execute(array($this->cryptPassword($sNewPassword), $aFetchResult[0]['username']))) {
|
||||
$oStmt = $oPdo ->prepare('UPDATE users SET digesta1=MD5(CONCAT(?, ":SabreDAV:", ?)) WHERE username=?');
|
||||
if ($oStmt->execute(array($aFetchResult[0]['username'],$sNewPassword,$aFetchResult[0]['username']))) {
|
||||
//the MailCow & SabreDav have been updated, now update the doveadm password
|
||||
exec("/usr/bin/doveadm pw -s SHA512-CRYPT -p $sNewPassword", $hash, $return);
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
* @return string
|
||||
*/
|
||||
private function cryptPassword($sPassword)
|
||||
{
|
||||
$sSalt = '';
|
||||
$sBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
|
||||
for ($iIndex = 0; $iIndex < 16; $iIndex++)
|
||||
{
|
||||
$sSalt .= $sBase64[\rand(0, 63)];
|
||||
}
|
||||
|
||||
$crypted = \crypt($sPassword, '$6$'.$sSalt);
|
||||
return '{SHA512-CRYPT}'.$crypted;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class MailcowChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDsn = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sDsn
|
||||
* @param string $sUser
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return \IspConfigChangePasswordDriver
|
||||
*/
|
||||
public function SetConfig($sDsn, $sUser, $sPassword)
|
||||
{
|
||||
$this->sDsn = $sDsn;
|
||||
$this->sUser = $sUser;
|
||||
$this->sPassword = $sPassword;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \IspConfigChangePasswordDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \IspConfigChangePasswordDriver
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
if ($oLogger instanceof \MailSo\Log\Logger)
|
||||
{
|
||||
$this->oLogger = $oLogger;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function PasswordChangePossibility($oAccount)
|
||||
{
|
||||
return $oAccount && $oAccount->Email() &&
|
||||
\RainLoop\Plugins\Helper::ValidateWildcardValues($oAccount->Email(), $this->sAllowedEmails);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RainLoop\Account $oAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Mailcow: Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
if (!empty($this->sDsn) && 0 < \strlen($this->sUser) && 0 < \strlen($this->sPassword) && $oAccount)
|
||||
{
|
||||
try
|
||||
{
|
||||
$oPdo = new \PDO($this->sDsn, $this->sUser, $this->sPassword);
|
||||
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$oStmt = $oPdo->prepare('SELECT password, username FROM mailbox WHERE username = ? LIMIT 1');
|
||||
if ($oStmt->execute(array($oAccount->IncLogin())))
|
||||
{
|
||||
$aFetchResult = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
if (\is_array($aFetchResult) && isset($aFetchResult[0]['password'], $aFetchResult[0]['username']))
|
||||
{
|
||||
$sDbPassword = $aFetchResult[0]['password'];
|
||||
if (\substr($sDbPassword, 0, 14) === '{SHA512-CRYPT}') {
|
||||
$sDbSalt = \substr($sDbPassword, 17, 16);
|
||||
} else {
|
||||
$sDbSalt = \substr($sDbPassword, 3, 16);
|
||||
}
|
||||
|
||||
if ('{SHA512-CRYPT}'.\crypt($sPrevPassword, '$6$'.$sDbSalt) === $sDbPassword)
|
||||
{
|
||||
$oStmt = $oPdo->prepare('UPDATE mailbox SET password = ? WHERE username = ?');
|
||||
if ($oStmt->execute(array($this->cryptPassword($sNewPassword), $aFetchResult[0]['username']))) {
|
||||
$oStmt = $oPdo ->prepare('UPDATE users SET digesta1=MD5(CONCAT(?, ":SabreDAV:", ?)) WHERE username=?');
|
||||
if ($oStmt->execute(array($aFetchResult[0]['username'],$sNewPassword,$aFetchResult[0]['username']))) {
|
||||
//the MailCow & SabreDav have been updated, now update the doveadm password
|
||||
exec("/usr/bin/doveadm pw -s SHA512-CRYPT -p $sNewPassword", $hash, $return);
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
* @return string
|
||||
*/
|
||||
private function cryptPassword($sPassword)
|
||||
{
|
||||
$sSalt = '';
|
||||
$sBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
|
||||
for ($iIndex = 0; $iIndex < 16; $iIndex++)
|
||||
{
|
||||
$sSalt .= $sBase64[\rand(0, 63)];
|
||||
}
|
||||
|
||||
$crypted = \crypt($sPassword, '$6$'.$sSalt);
|
||||
return '{SHA512-CRYPT}'.$crypted;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +1,76 @@
|
|||
<?php
|
||||
|
||||
class MailcowChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
if (!extension_loaded('pdo') || !class_exists('PDO'))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || !in_array('mysql', $aDrivers))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
$sDsn = \trim($this->Config()->Get('plugin', 'pdo_dsn', ''));
|
||||
$sUser = (string) $this->Config()->Get('plugin', 'user', '');
|
||||
$sPassword = (string) $this->Config()->Get('plugin', 'password', '');
|
||||
|
||||
if (!empty($sDsn) && 0 < \strlen($sUser) && 0 < \strlen($sPassword))
|
||||
{
|
||||
include_once __DIR__.'/MailcowChangePasswordDriver.php';
|
||||
|
||||
$oProvider = new MailcowChangePasswordDriver();
|
||||
$oProvider->SetLogger($this->Manager()->Actions()->Logger());
|
||||
$oProvider->SetConfig($sDsn, $sUser, $sPassword);
|
||||
$oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('pdo_dsn')->SetLabel('Mailcow PDO dsn')
|
||||
->SetDefaultValue('mysql:host=127.0.0.1;dbname=mailcow'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('DB User')
|
||||
->SetDefaultValue('mailcow'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('DB Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net')
|
||||
->SetDefaultValue('*')
|
||||
);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class MailcowChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
if (!extension_loaded('pdo') || !class_exists('PDO'))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || !in_array('mysql', $aDrivers))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
$sDsn = \trim($this->Config()->Get('plugin', 'pdo_dsn', ''));
|
||||
$sUser = (string) $this->Config()->Get('plugin', 'user', '');
|
||||
$sPassword = (string) $this->Config()->Get('plugin', 'password', '');
|
||||
|
||||
if (!empty($sDsn) && 0 < \strlen($sUser) && 0 < \strlen($sPassword))
|
||||
{
|
||||
include_once __DIR__.'/MailcowChangePasswordDriver.php';
|
||||
|
||||
$oProvider = new MailcowChangePasswordDriver();
|
||||
$oProvider->SetLogger($this->Manager()->Actions()->Logger());
|
||||
$oProvider->SetConfig($sDsn, $sUser, $sPassword);
|
||||
$oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('pdo_dsn')->SetLabel('Mailcow PDO dsn')
|
||||
->SetDefaultValue('mysql:host=127.0.0.1;dbname=mailcow'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('DB User')
|
||||
->SetDefaultValue('mailcow'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('DB Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net')
|
||||
->SetDefaultValue('*')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ class ChangePasswordPostfixAdminDriver implements \RainLoop\Providers\ChangePass
|
|||
if (function_exists('random_bytes')) {
|
||||
$sSalt = substr(base64_encode(random_bytes(32)), 0, 16);
|
||||
} else {
|
||||
$sSalt = substr(str_shuffle('./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'), 0, 16);
|
||||
$sSalt = substr(str_shuffle('./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'), 0, 16);
|
||||
}
|
||||
switch (strtolower($this->sEncrypt))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,100 +1,100 @@
|
|||
<?php
|
||||
|
||||
class PostfixadminChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
if (!extension_loaded('pdo') || !class_exists('PDO'))
|
||||
{
|
||||
return 'The PHP extension PDO must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || (!in_array('mysql', $aDrivers) && !in_array('pgsql', $aDrivers)))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql or pgsql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
include_once __DIR__.'/ChangePasswordPostfixAdminDriver.php';
|
||||
|
||||
$oProvider = new ChangePasswordPostfixAdminDriver();
|
||||
|
||||
$oProvider
|
||||
->SetEngine($this->Config()->Get('plugin', 'engine',''))
|
||||
->SetHost($this->Config()->Get('plugin', 'host', ''))
|
||||
->SetPort((int) $this->Config()->Get('plugin', 'port', 3306))
|
||||
->SetDatabase($this->Config()->Get('plugin', 'database', ''))
|
||||
->SetTable($this->Config()->Get('plugin', 'table', ''))
|
||||
->SetUserColumn($this->Config()->Get('plugin', 'usercol', ''))
|
||||
->SetPasswordColumn($this->Config()->Get('plugin', 'passcol', ''))
|
||||
->SetUser($this->Config()->Get('plugin', 'user', ''))
|
||||
->SetPassword($this->Config()->Get('plugin', 'password', ''))
|
||||
->SetEncrypt($this->Config()->Get('plugin', 'encrypt', ''))
|
||||
->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))))
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('engine')->SetLabel('Engine')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('MySQL', 'PostgreSQL'))
|
||||
->SetDescription('Database Engine'),
|
||||
\RainLoop\Plugins\Property::NewInstance('host')->SetLabel('Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('port')->SetLabel('Port')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
|
||||
->SetDefaultValue(3306),
|
||||
\RainLoop\Plugins\Property::NewInstance('database')->SetLabel('Database')
|
||||
->SetDefaultValue('postfixadmin'),
|
||||
\RainLoop\Plugins\Property::NewInstance('table')->SetLabel('table')
|
||||
->SetDefaultValue('mailbox'),
|
||||
\RainLoop\Plugins\Property::NewInstance('usercol')->SetLabel('username column')
|
||||
->SetDefaultValue('username'),
|
||||
\RainLoop\Plugins\Property::NewInstance('passcol')->SetLabel('password column')
|
||||
->SetDefaultValue('password'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('User')
|
||||
->SetDefaultValue('postfixadmin'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('encrypt')->SetLabel('Encrypt')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('md5crypt', 'md5', 'system', 'cleartext', 'mysql_encrypt', 'SHA256-CRYPT', 'SHA512-CRYPT'))
|
||||
->SetDescription('In what way do you want the passwords to be crypted ?'),
|
||||
\RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net')
|
||||
->SetDefaultValue('*')
|
||||
);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class PostfixadminChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
if (!extension_loaded('pdo') || !class_exists('PDO'))
|
||||
{
|
||||
return 'The PHP extension PDO must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || (!in_array('mysql', $aDrivers) && !in_array('pgsql', $aDrivers)))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql or pgsql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
include_once __DIR__.'/ChangePasswordPostfixAdminDriver.php';
|
||||
|
||||
$oProvider = new ChangePasswordPostfixAdminDriver();
|
||||
|
||||
$oProvider
|
||||
->SetEngine($this->Config()->Get('plugin', 'engine',''))
|
||||
->SetHost($this->Config()->Get('plugin', 'host', ''))
|
||||
->SetPort((int) $this->Config()->Get('plugin', 'port', 3306))
|
||||
->SetDatabase($this->Config()->Get('plugin', 'database', ''))
|
||||
->SetTable($this->Config()->Get('plugin', 'table', ''))
|
||||
->SetUserColumn($this->Config()->Get('plugin', 'usercol', ''))
|
||||
->SetPasswordColumn($this->Config()->Get('plugin', 'passcol', ''))
|
||||
->SetUser($this->Config()->Get('plugin', 'user', ''))
|
||||
->SetPassword($this->Config()->Get('plugin', 'password', ''))
|
||||
->SetEncrypt($this->Config()->Get('plugin', 'encrypt', ''))
|
||||
->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))))
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('engine')->SetLabel('Engine')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('MySQL', 'PostgreSQL'))
|
||||
->SetDescription('Database Engine'),
|
||||
\RainLoop\Plugins\Property::NewInstance('host')->SetLabel('Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('port')->SetLabel('Port')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
|
||||
->SetDefaultValue(3306),
|
||||
\RainLoop\Plugins\Property::NewInstance('database')->SetLabel('Database')
|
||||
->SetDefaultValue('postfixadmin'),
|
||||
\RainLoop\Plugins\Property::NewInstance('table')->SetLabel('table')
|
||||
->SetDefaultValue('mailbox'),
|
||||
\RainLoop\Plugins\Property::NewInstance('usercol')->SetLabel('username column')
|
||||
->SetDefaultValue('username'),
|
||||
\RainLoop\Plugins\Property::NewInstance('passcol')->SetLabel('password column')
|
||||
->SetDefaultValue('password'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('User')
|
||||
->SetDefaultValue('postfixadmin'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('encrypt')->SetLabel('Encrypt')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('md5crypt', 'md5', 'system', 'cleartext', 'mysql_encrypt', 'SHA256-CRYPT', 'SHA512-CRYPT'))
|
||||
->SetDescription('In what way do you want the passwords to be crypted ?'),
|
||||
\RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net')
|
||||
->SetDefaultValue('*')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ function md5crypt($pw, $salt = "", $magic = "")
|
|||
{
|
||||
$ctx .= $pw[0];
|
||||
}
|
||||
|
||||
|
||||
$i = $i >> 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,151 +1,151 @@
|
|||
<?php
|
||||
|
||||
class RecaptchaPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function Init()
|
||||
{
|
||||
$this->UseLangs(true);
|
||||
|
||||
$this->addJs('js/recaptcha.js');
|
||||
|
||||
$this->addHook('ajax.action-pre-call', 'AjaxActionPreCall');
|
||||
$this->addHook('filter.ajax-response', 'FilterAjaxResponse');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('public_key')->SetLabel('Site key')
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('private_key')->SetLabel('Secret key')
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('theme')->SetLabel('Theme')
|
||||
->SetAllowedInJs(true)
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('light', 'dark')),
|
||||
\RainLoop\Plugins\Property::NewInstance('error_limit')->SetLabel('Limit')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array(0, 1, 2, 3, 4, 5))
|
||||
->SetDescription('')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getCaptchaCacherKey()
|
||||
{
|
||||
return 'CaptchaNew/Login/'.\RainLoop\Utils::GetConnectionToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function getLimit()
|
||||
{
|
||||
$iConfigLimit = $this->Config()->Get('plugin', 'error_limit', 0);
|
||||
if (0 < $iConfigLimit)
|
||||
{
|
||||
$oCacher = $this->Manager()->Actions()->Cacher();
|
||||
$sLimit = $oCacher && $oCacher->IsInited() ? $oCacher->Get($this->getCaptchaCacherKey()) : '0';
|
||||
|
||||
if (0 < \strlen($sLimit) && \is_numeric($sLimit))
|
||||
{
|
||||
$iConfigLimit -= (int) $sLimit;
|
||||
}
|
||||
}
|
||||
|
||||
return $iConfigLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function FilterAppDataPluginSection($bAdmin, $bAuth, &$aData)
|
||||
{
|
||||
if (!$bAdmin && !$bAuth && \is_array($aData))
|
||||
{
|
||||
$aData['show_captcha_on_login'] = 1 > $this->getLimit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAction
|
||||
*/
|
||||
public function AjaxActionPreCall($sAction)
|
||||
{
|
||||
if ('Login' === $sAction && 0 >= $this->getLimit())
|
||||
{
|
||||
$bResult = false;
|
||||
|
||||
$sResult = $this->Manager()->Actions()->Http()->SendPostRequest(
|
||||
'https://www.google.com/recaptcha/api/siteverify',
|
||||
array(
|
||||
'secret' => $this->Config()->Get('plugin', 'private_key', ''),
|
||||
'response' => $this->Manager()->Actions()->GetActionParam('RecaptchaResponse', '')
|
||||
)
|
||||
);
|
||||
|
||||
if ($sResult)
|
||||
{
|
||||
$aResp = @\json_decode($sResult, true);
|
||||
if (\is_array($aResp) && isset($aResp['success']) && $aResp['success'])
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bResult)
|
||||
{
|
||||
$this->Manager()->Actions()->Logger()->Write('RecaptchaResponse:'.$sResult);
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CaptchaError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAction
|
||||
* @param array $aResponseItem
|
||||
*/
|
||||
public function FilterAjaxResponse($sAction, &$aResponseItem)
|
||||
{
|
||||
if ('Login' === $sAction && $aResponseItem && isset($aResponseItem['Result']))
|
||||
{
|
||||
$oCacher = $this->Manager()->Actions()->Cacher();
|
||||
$iConfigLimit = (int) $this->Config()->Get('plugin', 'error_limit', 0);
|
||||
|
||||
$sKey = $this->getCaptchaCacherKey();
|
||||
|
||||
if (0 < $iConfigLimit && $oCacher && $oCacher->IsInited())
|
||||
{
|
||||
if (false === $aResponseItem['Result'])
|
||||
{
|
||||
$iLimit = 0;
|
||||
$sLimut = $oCacher->Get($sKey);
|
||||
if (0 < \strlen($sLimut) && \is_numeric($sLimut))
|
||||
{
|
||||
$iLimit = (int) $sLimut;
|
||||
}
|
||||
|
||||
$oCacher->Set($sKey, ++$iLimit);
|
||||
|
||||
if ($iConfigLimit <= $iLimit)
|
||||
{
|
||||
$aResponseItem['Captcha'] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oCacher->Delete($sKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
class RecaptchaPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function Init()
|
||||
{
|
||||
$this->UseLangs(true);
|
||||
|
||||
$this->addJs('js/recaptcha.js');
|
||||
|
||||
$this->addHook('ajax.action-pre-call', 'AjaxActionPreCall');
|
||||
$this->addHook('filter.ajax-response', 'FilterAjaxResponse');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('public_key')->SetLabel('Site key')
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('private_key')->SetLabel('Secret key')
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('theme')->SetLabel('Theme')
|
||||
->SetAllowedInJs(true)
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('light', 'dark')),
|
||||
\RainLoop\Plugins\Property::NewInstance('error_limit')->SetLabel('Limit')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array(0, 1, 2, 3, 4, 5))
|
||||
->SetDescription('')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getCaptchaCacherKey()
|
||||
{
|
||||
return 'CaptchaNew/Login/'.\RainLoop\Utils::GetConnectionToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function getLimit()
|
||||
{
|
||||
$iConfigLimit = $this->Config()->Get('plugin', 'error_limit', 0);
|
||||
if (0 < $iConfigLimit)
|
||||
{
|
||||
$oCacher = $this->Manager()->Actions()->Cacher();
|
||||
$sLimit = $oCacher && $oCacher->IsInited() ? $oCacher->Get($this->getCaptchaCacherKey()) : '0';
|
||||
|
||||
if (0 < \strlen($sLimit) && \is_numeric($sLimit))
|
||||
{
|
||||
$iConfigLimit -= (int) $sLimit;
|
||||
}
|
||||
}
|
||||
|
||||
return $iConfigLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function FilterAppDataPluginSection($bAdmin, $bAuth, &$aData)
|
||||
{
|
||||
if (!$bAdmin && !$bAuth && \is_array($aData))
|
||||
{
|
||||
$aData['show_captcha_on_login'] = 1 > $this->getLimit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAction
|
||||
*/
|
||||
public function AjaxActionPreCall($sAction)
|
||||
{
|
||||
if ('Login' === $sAction && 0 >= $this->getLimit())
|
||||
{
|
||||
$bResult = false;
|
||||
|
||||
$sResult = $this->Manager()->Actions()->Http()->SendPostRequest(
|
||||
'https://www.google.com/recaptcha/api/siteverify',
|
||||
array(
|
||||
'secret' => $this->Config()->Get('plugin', 'private_key', ''),
|
||||
'response' => $this->Manager()->Actions()->GetActionParam('RecaptchaResponse', '')
|
||||
)
|
||||
);
|
||||
|
||||
if ($sResult)
|
||||
{
|
||||
$aResp = @\json_decode($sResult, true);
|
||||
if (\is_array($aResp) && isset($aResp['success']) && $aResp['success'])
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bResult)
|
||||
{
|
||||
$this->Manager()->Actions()->Logger()->Write('RecaptchaResponse:'.$sResult);
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CaptchaError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAction
|
||||
* @param array $aResponseItem
|
||||
*/
|
||||
public function FilterAjaxResponse($sAction, &$aResponseItem)
|
||||
{
|
||||
if ('Login' === $sAction && $aResponseItem && isset($aResponseItem['Result']))
|
||||
{
|
||||
$oCacher = $this->Manager()->Actions()->Cacher();
|
||||
$iConfigLimit = (int) $this->Config()->Get('plugin', 'error_limit', 0);
|
||||
|
||||
$sKey = $this->getCaptchaCacherKey();
|
||||
|
||||
if (0 < $iConfigLimit && $oCacher && $oCacher->IsInited())
|
||||
{
|
||||
if (false === $aResponseItem['Result'])
|
||||
{
|
||||
$iLimit = 0;
|
||||
$sLimut = $oCacher->Get($sKey);
|
||||
if (0 < \strlen($sLimut) && \is_numeric($sLimut))
|
||||
{
|
||||
$iLimit = (int) $sLimut;
|
||||
}
|
||||
|
||||
$oCacher->Set($sKey, ++$iLimit);
|
||||
|
||||
if ($iConfigLimit <= $iLimit)
|
||||
{
|
||||
$aResponseItem['Captcha'] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oCacher->Delete($sKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,95 +1,95 @@
|
|||
(function ($, window) {
|
||||
|
||||
$(function () {
|
||||
|
||||
var
|
||||
nId = null,
|
||||
bStarted = false
|
||||
;
|
||||
|
||||
function ShowRecaptcha()
|
||||
{
|
||||
if (window.grecaptcha && window.rl)
|
||||
{
|
||||
if (null === nId)
|
||||
{
|
||||
var
|
||||
oEl = null,
|
||||
oLink = $('.plugin-mark-Login-BottomControlGroup')
|
||||
;
|
||||
|
||||
if (oLink && oLink[0])
|
||||
{
|
||||
oEl = $('<div class="controls"></div>');
|
||||
|
||||
$(oLink[0]).after(oEl);
|
||||
|
||||
nId = window.grecaptcha.render(oEl[0], {
|
||||
'sitekey': window.rl.pluginSettingsGet('recaptcha', 'public_key'),
|
||||
'theme': window.rl.pluginSettingsGet('recaptcha', 'theme')
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.__globalShowRecaptcha = ShowRecaptcha;
|
||||
|
||||
function StartRecaptcha()
|
||||
{
|
||||
if (!window.grecaptcha && window.rl)
|
||||
{
|
||||
$.getScript('https://www.google.com/recaptcha/api.js?onload=__globalShowRecaptcha&render=explicit&hl=' + window.rl.settingsGet('Language'));
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowRecaptcha();
|
||||
}
|
||||
}
|
||||
|
||||
if (window.rl)
|
||||
{
|
||||
window.rl.addHook('user-login-submit', function (fSubmitResult) {
|
||||
if (null !== nId && !window.grecaptcha.getResponse(nId))
|
||||
{
|
||||
fSubmitResult(105);
|
||||
}
|
||||
});
|
||||
|
||||
window.rl.addHook('view-model-on-show', function (sName, oViewModel) {
|
||||
if (!bStarted && oViewModel &&
|
||||
('View:RainLoop:Login' === sName || 'View/App/Login' === sName || 'LoginViewModel' === sName || 'LoginAppView' === sName) &&
|
||||
window.rl.pluginSettingsGet('recaptcha', 'show_captcha_on_login'))
|
||||
{
|
||||
bStarted = true;
|
||||
StartRecaptcha();
|
||||
}
|
||||
});
|
||||
|
||||
window.rl.addHook('ajax-default-request', function (sAction, oParameters) {
|
||||
if ('Login' === sAction && oParameters && null !== nId && window.grecaptcha)
|
||||
{
|
||||
oParameters['RecaptchaResponse'] = window.grecaptcha.getResponse(nId);
|
||||
}
|
||||
});
|
||||
|
||||
window.rl.addHook('ajax-default-response', function (sAction, oData, sType) {
|
||||
if ('Login' === sAction)
|
||||
{
|
||||
if (!oData || 'success' !== sType || !oData['Result'])
|
||||
{
|
||||
if (null !== nId && window.grecaptcha)
|
||||
{
|
||||
window.grecaptcha.reset(nId);
|
||||
}
|
||||
else if (oData && oData['Captcha'])
|
||||
{
|
||||
StartRecaptcha();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
(function ($, window) {
|
||||
|
||||
$(function () {
|
||||
|
||||
var
|
||||
nId = null,
|
||||
bStarted = false
|
||||
;
|
||||
|
||||
function ShowRecaptcha()
|
||||
{
|
||||
if (window.grecaptcha && window.rl)
|
||||
{
|
||||
if (null === nId)
|
||||
{
|
||||
var
|
||||
oEl = null,
|
||||
oLink = $('.plugin-mark-Login-BottomControlGroup')
|
||||
;
|
||||
|
||||
if (oLink && oLink[0])
|
||||
{
|
||||
oEl = $('<div class="controls"></div>');
|
||||
|
||||
$(oLink[0]).after(oEl);
|
||||
|
||||
nId = window.grecaptcha.render(oEl[0], {
|
||||
'sitekey': window.rl.pluginSettingsGet('recaptcha', 'public_key'),
|
||||
'theme': window.rl.pluginSettingsGet('recaptcha', 'theme')
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.__globalShowRecaptcha = ShowRecaptcha;
|
||||
|
||||
function StartRecaptcha()
|
||||
{
|
||||
if (!window.grecaptcha && window.rl)
|
||||
{
|
||||
$.getScript('https://www.google.com/recaptcha/api.js?onload=__globalShowRecaptcha&render=explicit&hl=' + window.rl.settingsGet('Language'));
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowRecaptcha();
|
||||
}
|
||||
}
|
||||
|
||||
if (window.rl)
|
||||
{
|
||||
window.rl.addHook('user-login-submit', function (fSubmitResult) {
|
||||
if (null !== nId && !window.grecaptcha.getResponse(nId))
|
||||
{
|
||||
fSubmitResult(105);
|
||||
}
|
||||
});
|
||||
|
||||
window.rl.addHook('view-model-on-show', function (sName, oViewModel) {
|
||||
if (!bStarted && oViewModel &&
|
||||
('View:RainLoop:Login' === sName || 'View/App/Login' === sName || 'LoginViewModel' === sName || 'LoginAppView' === sName) &&
|
||||
window.rl.pluginSettingsGet('recaptcha', 'show_captcha_on_login'))
|
||||
{
|
||||
bStarted = true;
|
||||
StartRecaptcha();
|
||||
}
|
||||
});
|
||||
|
||||
window.rl.addHook('ajax-default-request', function (sAction, oParameters) {
|
||||
if ('Login' === sAction && oParameters && null !== nId && window.grecaptcha)
|
||||
{
|
||||
oParameters['RecaptchaResponse'] = window.grecaptcha.getResponse(nId);
|
||||
}
|
||||
});
|
||||
|
||||
window.rl.addHook('ajax-default-response', function (sAction, oData, sType) {
|
||||
if ('Login' === sAction)
|
||||
{
|
||||
if (!oData || 'success' !== sType || !oData['Result'])
|
||||
{
|
||||
if (null !== nId && window.grecaptcha)
|
||||
{
|
||||
window.grecaptcha.reset(nId);
|
||||
}
|
||||
else if (oData && oData['Captcha'])
|
||||
{
|
||||
StartRecaptcha();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}($, window));
|
||||
|
|
@ -1,275 +1,275 @@
|
|||
/* Snowfall pure js
|
||||
====================================================================
|
||||
LICENSE
|
||||
====================================================================
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
====================================================================
|
||||
|
||||
1.0
|
||||
Wanted to rewrite my snow plugin to use pure JS so you werent necessarily tied to using a framework.
|
||||
Does not include a selector engine or anything, just pass elements to it using standard JS selectors.
|
||||
|
||||
Does not clear snow currently. Collection portion removed just for ease of testing will add back in next version
|
||||
|
||||
Theres a few ways to call the snow you could do it the following way by directly passing the selector,
|
||||
|
||||
snowFall.snow(document.getElementsByTagName("body"), {options});
|
||||
|
||||
or you could save the selector results to a variable, and then call it
|
||||
|
||||
var elements = document.getElementsByClassName('yourclass');
|
||||
snowFall.snow(elements, {options});
|
||||
|
||||
Options are all the same as the plugin except clear, and collection
|
||||
|
||||
values for snow options are
|
||||
|
||||
flakeCount,
|
||||
flakeColor,
|
||||
flakeIndex,
|
||||
minSize,
|
||||
maxSize,
|
||||
minSpeed,
|
||||
maxSpeed,
|
||||
round, true or false, makes the snowflakes rounded if the browser supports it.
|
||||
shadow true or false, gives the snowflakes a shadow if the browser supports it.
|
||||
|
||||
*/
|
||||
|
||||
// Paul Irish requestAnimationFrame polyfill
|
||||
(function(window) {
|
||||
var lastTime = 0;
|
||||
var vendors = ['webkit', 'moz'];
|
||||
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
||||
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
|
||||
window.cancelAnimationFrame =
|
||||
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
|
||||
}
|
||||
|
||||
if (!window.requestAnimationFrame)
|
||||
window.requestAnimationFrame = function(callback, element) {
|
||||
var currTime = new Date().getTime();
|
||||
var timeToCall = window.Math.max(0, 16 - (currTime - lastTime));
|
||||
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
|
||||
timeToCall);
|
||||
lastTime = currTime + timeToCall;
|
||||
return id;
|
||||
};
|
||||
|
||||
if (!window.cancelAnimationFrame)
|
||||
window.cancelAnimationFrame = function(id) {
|
||||
clearTimeout(id);
|
||||
};
|
||||
}(window));
|
||||
|
||||
var snowFall = (function(){
|
||||
function jSnow(){
|
||||
// local methods
|
||||
var defaults = {
|
||||
flakeCount : 35,
|
||||
flakeColor : '#ffffff',
|
||||
flakeIndex: 999999,
|
||||
minSize : 1,
|
||||
maxSize : 2,
|
||||
minSpeed : 1,
|
||||
maxSpeed : 5,
|
||||
round : false,
|
||||
shadow : false,
|
||||
collection : false,
|
||||
image : false,
|
||||
collectionHeight : 40
|
||||
},
|
||||
element = {},
|
||||
flakes = [],
|
||||
flakeId = 0,
|
||||
elHeight = 0,
|
||||
elWidth = 0,
|
||||
elTop = 0,
|
||||
elLeft = 0,
|
||||
widthOffset = 0,
|
||||
snowTimeout = 0,
|
||||
// For extending the default object with properties
|
||||
extend = function(obj, extObj){
|
||||
for(var i in extObj){
|
||||
if(obj.hasOwnProperty(i)){
|
||||
obj[i] = extObj[i];
|
||||
}
|
||||
}
|
||||
},
|
||||
// random between range
|
||||
random = function random(min, max){
|
||||
return window.Math.round(min + window.Math.random()*(max-min));
|
||||
},
|
||||
// Set multiple styles at once.
|
||||
setStyle = function(element, props)
|
||||
{
|
||||
for (var property in props){
|
||||
element.style[property] = props[property] + ((property === 'width' || property === 'height') ? 'px' : '');
|
||||
}
|
||||
},
|
||||
// snowflake
|
||||
flake = function(_x, _y, _size, _speed, _id)
|
||||
{
|
||||
// Flake properties
|
||||
this.id = _id;
|
||||
this.x = _x + elLeft;
|
||||
this.y = _y + elTop;
|
||||
this.size = _size;
|
||||
this.speed = _speed;
|
||||
this.step = 0;
|
||||
this.stepSize = random(1,10) / 100;
|
||||
|
||||
if(defaults.collection){
|
||||
this.target = defaults.collection[random(0,defaults.collection.length-1)];
|
||||
}
|
||||
|
||||
var flakeObj = null;
|
||||
|
||||
if(defaults.image){
|
||||
flakeObj = new Image();
|
||||
flakeObj.src = defaults.image;
|
||||
}else{
|
||||
flakeObj = window.document.createElement("div");
|
||||
setStyle(flakeObj, {'background' : defaults.flakeColor});
|
||||
}
|
||||
|
||||
flakeObj.className = 'snowfall-flakes';
|
||||
flakeObj.setAttribute('id','flake-' + this.id);
|
||||
setStyle(flakeObj, {'width' : this.size, 'height' : this.size, 'position' : 'absolute', 'top' : this.y, 'left' : this.x, 'fontSize' : 0, 'zIndex' : defaults.flakeIndex});
|
||||
|
||||
// This adds the style to make the snowflakes round via border radius property
|
||||
if(defaults.round){
|
||||
setStyle(flakeObj,{'-moz-border-radius' : ~~(defaults.maxSize) + 'px', '-webkit-border-radius' : ~~(defaults.maxSize) + 'px', 'borderRadius' : ~~(defaults.maxSize) + 'px'});
|
||||
}
|
||||
|
||||
// This adds shadows just below the snowflake so they pop a bit on lighter colored web pages
|
||||
if(defaults.shadow){
|
||||
setStyle(flakeObj,{'-moz-box-shadow' : '1px 1px 1px #555', '-webkit-box-shadow' : '1px 1px 1px #555', 'boxShadow' : '1px 1px 1px #555'});
|
||||
}
|
||||
|
||||
window.document.body.appendChild(flakeObj);
|
||||
|
||||
this.element = flakeObj;
|
||||
|
||||
// Update function, used to update the snow flakes, and checks current snowflake against bounds
|
||||
this.update = function(){
|
||||
this.y += this.speed;
|
||||
|
||||
if(this.y > (elTop + elHeight) - (this.size + 6)){
|
||||
this.reset();
|
||||
}
|
||||
|
||||
this.element.style.top = this.y + 'px';
|
||||
this.element.style.left = ~~this.x + 'px';
|
||||
|
||||
this.step += this.stepSize;
|
||||
this.x += window.Math.cos(this.step);
|
||||
|
||||
if(this.x > (elLeft + elWidth) - widthOffset || this.x < widthOffset){
|
||||
this.reset();
|
||||
}
|
||||
};
|
||||
|
||||
// Resets the snowflake once it reaches one of the bounds set
|
||||
this.reset = function(){
|
||||
this.y = elTop;
|
||||
this.x = elLeft + random(widthOffset, elWidth - widthOffset);
|
||||
this.stepSize = random(1,10) / 100;
|
||||
this.size = random((defaults.minSize * 100), (defaults.maxSize * 100)) / 100;
|
||||
this.speed = random(defaults.minSpeed, defaults.maxSpeed);
|
||||
};
|
||||
},
|
||||
// this controls flow of the updating snow
|
||||
animateSnow = function(){
|
||||
for(var i = 0; i < flakes.length; i += 1){
|
||||
flakes[i].update();
|
||||
}
|
||||
snowTimeout = requestAnimationFrame(function(){animateSnow();});
|
||||
};
|
||||
return{
|
||||
snow : function(_element, _options){
|
||||
extend(defaults, _options);
|
||||
|
||||
//init the element vars
|
||||
element = _element;
|
||||
elHeight = element.clientHeight,
|
||||
elWidth = element.offsetWidth;
|
||||
elTop = element.offsetTop;
|
||||
elLeft = element.offsetLeft;
|
||||
|
||||
element.snow = this;
|
||||
|
||||
// if this is the body the offset is a little different
|
||||
if(element.tagName.toLowerCase() === 'body'){
|
||||
widthOffset = 25;
|
||||
}
|
||||
|
||||
// Bind the window resize event so we can get the innerHeight again
|
||||
window.onresize = function(){
|
||||
elHeight = element.clientHeight;
|
||||
elWidth = element.offsetWidth;
|
||||
elTop = element.offsetTop;
|
||||
elLeft = element.offsetLeft;
|
||||
};
|
||||
|
||||
// initialize the flakes
|
||||
for(var i = 0; i < defaults.flakeCount; i+=1){
|
||||
flakeId = flakes.length;
|
||||
flakes.push(new flake(random(widthOffset,elWidth - widthOffset), random(0, elHeight), random((defaults.minSize * 100), (defaults.maxSize * 100)) / 100, random(defaults.minSpeed, defaults.maxSpeed), flakeId));
|
||||
}
|
||||
// start the snow
|
||||
animateSnow();
|
||||
},
|
||||
clear : function(){
|
||||
var flakeChildren = null;
|
||||
|
||||
if(!element.getElementsByClassName){
|
||||
flakeChildren = element.querySelectorAll('.snowfall-flakes');
|
||||
}else{
|
||||
flakeChildren = element.getElementsByClassName('snowfall-flakes');
|
||||
}
|
||||
|
||||
var flakeChilLen = flakeChildren.length;
|
||||
while(flakeChilLen--){
|
||||
element.removeChild(flakeChildren[flakeChilLen]);
|
||||
}
|
||||
|
||||
flakes = [];
|
||||
cancelAnimationFrame(snowTimeout);
|
||||
}
|
||||
};
|
||||
};
|
||||
return{
|
||||
snow : function(elements, options){
|
||||
if(typeof(options) === 'string'){
|
||||
if(elements.length > 0){
|
||||
for(var i = 0; i < elements.length; i++){
|
||||
if(elements[i].snow){
|
||||
elements[i].snow.clear();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
elements.snow.clear();
|
||||
}
|
||||
}else{
|
||||
if(elements.length > 0){
|
||||
for(var i = 0; i < elements.length; i++){
|
||||
new jSnow().snow(elements[i], options);
|
||||
}
|
||||
}else{
|
||||
new jSnow().snow(elements, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/* Snowfall pure js
|
||||
====================================================================
|
||||
LICENSE
|
||||
====================================================================
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
====================================================================
|
||||
|
||||
1.0
|
||||
Wanted to rewrite my snow plugin to use pure JS so you werent necessarily tied to using a framework.
|
||||
Does not include a selector engine or anything, just pass elements to it using standard JS selectors.
|
||||
|
||||
Does not clear snow currently. Collection portion removed just for ease of testing will add back in next version
|
||||
|
||||
Theres a few ways to call the snow you could do it the following way by directly passing the selector,
|
||||
|
||||
snowFall.snow(document.getElementsByTagName("body"), {options});
|
||||
|
||||
or you could save the selector results to a variable, and then call it
|
||||
|
||||
var elements = document.getElementsByClassName('yourclass');
|
||||
snowFall.snow(elements, {options});
|
||||
|
||||
Options are all the same as the plugin except clear, and collection
|
||||
|
||||
values for snow options are
|
||||
|
||||
flakeCount,
|
||||
flakeColor,
|
||||
flakeIndex,
|
||||
minSize,
|
||||
maxSize,
|
||||
minSpeed,
|
||||
maxSpeed,
|
||||
round, true or false, makes the snowflakes rounded if the browser supports it.
|
||||
shadow true or false, gives the snowflakes a shadow if the browser supports it.
|
||||
|
||||
*/
|
||||
|
||||
// Paul Irish requestAnimationFrame polyfill
|
||||
(function(window) {
|
||||
var lastTime = 0;
|
||||
var vendors = ['webkit', 'moz'];
|
||||
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
||||
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
|
||||
window.cancelAnimationFrame =
|
||||
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
|
||||
}
|
||||
|
||||
if (!window.requestAnimationFrame)
|
||||
window.requestAnimationFrame = function(callback, element) {
|
||||
var currTime = new Date().getTime();
|
||||
var timeToCall = window.Math.max(0, 16 - (currTime - lastTime));
|
||||
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
|
||||
timeToCall);
|
||||
lastTime = currTime + timeToCall;
|
||||
return id;
|
||||
};
|
||||
|
||||
if (!window.cancelAnimationFrame)
|
||||
window.cancelAnimationFrame = function(id) {
|
||||
clearTimeout(id);
|
||||
};
|
||||
}(window));
|
||||
|
||||
var snowFall = (function(){
|
||||
function jSnow(){
|
||||
// local methods
|
||||
var defaults = {
|
||||
flakeCount : 35,
|
||||
flakeColor : '#ffffff',
|
||||
flakeIndex: 999999,
|
||||
minSize : 1,
|
||||
maxSize : 2,
|
||||
minSpeed : 1,
|
||||
maxSpeed : 5,
|
||||
round : false,
|
||||
shadow : false,
|
||||
collection : false,
|
||||
image : false,
|
||||
collectionHeight : 40
|
||||
},
|
||||
element = {},
|
||||
flakes = [],
|
||||
flakeId = 0,
|
||||
elHeight = 0,
|
||||
elWidth = 0,
|
||||
elTop = 0,
|
||||
elLeft = 0,
|
||||
widthOffset = 0,
|
||||
snowTimeout = 0,
|
||||
// For extending the default object with properties
|
||||
extend = function(obj, extObj){
|
||||
for(var i in extObj){
|
||||
if(obj.hasOwnProperty(i)){
|
||||
obj[i] = extObj[i];
|
||||
}
|
||||
}
|
||||
},
|
||||
// random between range
|
||||
random = function random(min, max){
|
||||
return window.Math.round(min + window.Math.random()*(max-min));
|
||||
},
|
||||
// Set multiple styles at once.
|
||||
setStyle = function(element, props)
|
||||
{
|
||||
for (var property in props){
|
||||
element.style[property] = props[property] + ((property === 'width' || property === 'height') ? 'px' : '');
|
||||
}
|
||||
},
|
||||
// snowflake
|
||||
flake = function(_x, _y, _size, _speed, _id)
|
||||
{
|
||||
// Flake properties
|
||||
this.id = _id;
|
||||
this.x = _x + elLeft;
|
||||
this.y = _y + elTop;
|
||||
this.size = _size;
|
||||
this.speed = _speed;
|
||||
this.step = 0;
|
||||
this.stepSize = random(1,10) / 100;
|
||||
|
||||
if(defaults.collection){
|
||||
this.target = defaults.collection[random(0,defaults.collection.length-1)];
|
||||
}
|
||||
|
||||
var flakeObj = null;
|
||||
|
||||
if(defaults.image){
|
||||
flakeObj = new Image();
|
||||
flakeObj.src = defaults.image;
|
||||
}else{
|
||||
flakeObj = window.document.createElement("div");
|
||||
setStyle(flakeObj, {'background' : defaults.flakeColor});
|
||||
}
|
||||
|
||||
flakeObj.className = 'snowfall-flakes';
|
||||
flakeObj.setAttribute('id','flake-' + this.id);
|
||||
setStyle(flakeObj, {'width' : this.size, 'height' : this.size, 'position' : 'absolute', 'top' : this.y, 'left' : this.x, 'fontSize' : 0, 'zIndex' : defaults.flakeIndex});
|
||||
|
||||
// This adds the style to make the snowflakes round via border radius property
|
||||
if(defaults.round){
|
||||
setStyle(flakeObj,{'-moz-border-radius' : ~~(defaults.maxSize) + 'px', '-webkit-border-radius' : ~~(defaults.maxSize) + 'px', 'borderRadius' : ~~(defaults.maxSize) + 'px'});
|
||||
}
|
||||
|
||||
// This adds shadows just below the snowflake so they pop a bit on lighter colored web pages
|
||||
if(defaults.shadow){
|
||||
setStyle(flakeObj,{'-moz-box-shadow' : '1px 1px 1px #555', '-webkit-box-shadow' : '1px 1px 1px #555', 'boxShadow' : '1px 1px 1px #555'});
|
||||
}
|
||||
|
||||
window.document.body.appendChild(flakeObj);
|
||||
|
||||
this.element = flakeObj;
|
||||
|
||||
// Update function, used to update the snow flakes, and checks current snowflake against bounds
|
||||
this.update = function(){
|
||||
this.y += this.speed;
|
||||
|
||||
if(this.y > (elTop + elHeight) - (this.size + 6)){
|
||||
this.reset();
|
||||
}
|
||||
|
||||
this.element.style.top = this.y + 'px';
|
||||
this.element.style.left = ~~this.x + 'px';
|
||||
|
||||
this.step += this.stepSize;
|
||||
this.x += window.Math.cos(this.step);
|
||||
|
||||
if(this.x > (elLeft + elWidth) - widthOffset || this.x < widthOffset){
|
||||
this.reset();
|
||||
}
|
||||
};
|
||||
|
||||
// Resets the snowflake once it reaches one of the bounds set
|
||||
this.reset = function(){
|
||||
this.y = elTop;
|
||||
this.x = elLeft + random(widthOffset, elWidth - widthOffset);
|
||||
this.stepSize = random(1,10) / 100;
|
||||
this.size = random((defaults.minSize * 100), (defaults.maxSize * 100)) / 100;
|
||||
this.speed = random(defaults.minSpeed, defaults.maxSpeed);
|
||||
};
|
||||
},
|
||||
// this controls flow of the updating snow
|
||||
animateSnow = function(){
|
||||
for(var i = 0; i < flakes.length; i += 1){
|
||||
flakes[i].update();
|
||||
}
|
||||
snowTimeout = requestAnimationFrame(function(){animateSnow();});
|
||||
};
|
||||
return{
|
||||
snow : function(_element, _options){
|
||||
extend(defaults, _options);
|
||||
|
||||
//init the element vars
|
||||
element = _element;
|
||||
elHeight = element.clientHeight,
|
||||
elWidth = element.offsetWidth;
|
||||
elTop = element.offsetTop;
|
||||
elLeft = element.offsetLeft;
|
||||
|
||||
element.snow = this;
|
||||
|
||||
// if this is the body the offset is a little different
|
||||
if(element.tagName.toLowerCase() === 'body'){
|
||||
widthOffset = 25;
|
||||
}
|
||||
|
||||
// Bind the window resize event so we can get the innerHeight again
|
||||
window.onresize = function(){
|
||||
elHeight = element.clientHeight;
|
||||
elWidth = element.offsetWidth;
|
||||
elTop = element.offsetTop;
|
||||
elLeft = element.offsetLeft;
|
||||
};
|
||||
|
||||
// initialize the flakes
|
||||
for(var i = 0; i < defaults.flakeCount; i+=1){
|
||||
flakeId = flakes.length;
|
||||
flakes.push(new flake(random(widthOffset,elWidth - widthOffset), random(0, elHeight), random((defaults.minSize * 100), (defaults.maxSize * 100)) / 100, random(defaults.minSpeed, defaults.maxSpeed), flakeId));
|
||||
}
|
||||
// start the snow
|
||||
animateSnow();
|
||||
},
|
||||
clear : function(){
|
||||
var flakeChildren = null;
|
||||
|
||||
if(!element.getElementsByClassName){
|
||||
flakeChildren = element.querySelectorAll('.snowfall-flakes');
|
||||
}else{
|
||||
flakeChildren = element.getElementsByClassName('snowfall-flakes');
|
||||
}
|
||||
|
||||
var flakeChilLen = flakeChildren.length;
|
||||
while(flakeChilLen--){
|
||||
element.removeChild(flakeChildren[flakeChilLen]);
|
||||
}
|
||||
|
||||
flakes = [];
|
||||
cancelAnimationFrame(snowTimeout);
|
||||
}
|
||||
};
|
||||
};
|
||||
return{
|
||||
snow : function(elements, options){
|
||||
if(typeof(options) === 'string'){
|
||||
if(elements.length > 0){
|
||||
for(var i = 0; i < elements.length; i++){
|
||||
if(elements[i].snow){
|
||||
elements[i].snow.clear();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
elements.snow.clear();
|
||||
}
|
||||
}else{
|
||||
if(elements.length > 0){
|
||||
for(var i = 0; i < elements.length; i++){
|
||||
new jSnow().snow(elements[i], options);
|
||||
}
|
||||
}else{
|
||||
new jSnow().snow(elements, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue