CRLF to LF

This commit is contained in:
djmaze 2020-03-11 14:17:52 +01:00
parent 4468d5bd22
commit 6e0d0b3b6e
209 changed files with 23729 additions and 22109 deletions

View file

@ -1,6 +1,7 @@
module.exports = {
parser: 'babel-eslint',
extends: ['eslint:recommended', 'plugin:prettier/recommended'],
// extends: ['eslint:recommended', 'plugin:prettier/recommended'],
extends: ['eslint:recommended'],
plugins: ['prettier'],
parserOptions: {
ecmaVersion: 6,
@ -18,8 +19,8 @@ module.exports = {
// http://eslint.org/docs/rules/
rules: {
// plugins
'prettier/prettier': 'error',
// 'prettier/prettier': 'error',
'no-mixed-spaces-and-tabs': 'off',
'no-console': 'error',
'max-len': [
'error',

View file

@ -1,21 +1,21 @@
<?php
// Name this file as "include.php" to enable it.
/**
* @return string
*/
function __get_custom_data_full_path()
{
return '';
return '/var/external-rainloop-data-folder/'; // custom data folder path
}
/**
* @return string
*/
function __get_additional_configuration_name()
{
return '';
return defined('APP_SITE') && 0 < strlen(APP_SITE) ? APP_SITE.'.ini' : ''; // additional configuration file name
}
<?php
// Name this file as "include.php" to enable it.
/**
* @return string
*/
function __get_custom_data_full_path()
{
return '';
return '/var/external-rainloop-data-folder/'; // custom data folder path
}
/**
* @return string
*/
function __get_additional_configuration_name()
{
return '';
return defined('APP_SITE') && 0 < strlen(APP_SITE) ? APP_SITE.'.ini' : ''; // additional configuration file name
}

View file

@ -1125,8 +1125,7 @@ class AppUser extends AbstractApp {
let contactsSyncInterval = pInt(Settings.settingsGet('ContactsSyncInterval'));
const jsHash = Settings.appSettingsGet('jsHash'),
startupUrl = pString(Settings.settingsGet('StartupUrl'));
const startupUrl = pString(Settings.settingsGet('StartupUrl'));
if (progressJs) {
progressJs.set(90);

View file

@ -1,8 +1,6 @@
import _ from '_';
import { Capa, MessageSetAction } from 'Common/Enums';
import { MessageSetAction } from 'Common/Enums';
import { trim, pInt, isArray } from 'Common/Utils';
import * as Links from 'Common/Links';
import * as Settings from 'Storage/Settings';
let FOLDERS_CACHE = {},
FOLDERS_NAME_CACHE = {},
@ -12,8 +10,7 @@ let FOLDERS_CACHE = {},
NEW_MESSAGE_CACHE = {},
inboxFolderName = '';
const REQUESTED_MESSAGE_CACHE = {},
capaGravatar = Settings.capa(Capa.Gravatar);
const REQUESTED_MESSAGE_CACHE = {};
/**
* @returns {void}
@ -33,7 +30,7 @@ export function clear() {
*/
export function getUserPic(email, callback) {
email = trim(email);
callback(capaGravatar && '' !== email ? Links.avatarLink(email) : '', email);
callback('', email);
}
/**

View file

@ -83,11 +83,6 @@ export const bDisableNanoScroll = bMobileDevice;
export const bAnimationSupported =
!bMobileDevice && $html.hasClass('csstransitions') && $html.hasClass('cssanimations');
/**
* @type {boolean}
*/
export const bXMLHttpRequestSupported = !!window.XMLHttpRequest;
/**
* @type {boolean}
*/

View file

@ -37,7 +37,6 @@ class GeneralAdminSettings {
this.capaThemes = CapaAdminStore.themes;
this.capaUserBackground = CapaAdminStore.userBackground;
this.capaGravatar = CapaAdminStore.gravatar;
this.capaAdditionalAccounts = CapaAdminStore.additionalAccounts;
this.capaIdentities = CapaAdminStore.identities;
this.capaAttachmentThumbnails = CapaAdminStore.attachmentThumbnails;
@ -135,12 +134,6 @@ class GeneralAdminSettings {
});
});
this.capaGravatar.subscribe((value) => {
Remote.saveAdminConfig(null, {
'CapaGravatar': boolToAjax(value)
});
});
this.capaAttachmentThumbnails.subscribe((value) => {
Remote.saveAdminConfig(null, {
'CapaAttachmentThumbnails': boolToAjax(value)

View file

@ -6,7 +6,6 @@ class CapaAdminStore {
constructor() {
this.additionalAccounts = ko.observable(false);
this.identities = ko.observable(false);
this.gravatar = ko.observable(false);
this.attachmentThumbnails = ko.observable(false);
this.sieve = ko.observable(false);
this.filters = ko.observable(false);
@ -21,7 +20,6 @@ class CapaAdminStore {
populate() {
this.additionalAccounts(Settings.capa(Capa.AdditionalAccounts));
this.identities(Settings.capa(Capa.Identities));
this.gravatar(Settings.capa(Capa.Gravatar));
this.attachmentThumbnails(Settings.capa(Capa.AttachmentThumbnails));
this.sieve(Settings.capa(Capa.Sieve));
this.filters(Settings.capa(Capa.Filters));

View file

@ -1,63 +1,63 @@
.progressjs-theme-rainloop {
z-index: 2000;
}
.progressjs-theme-rainloop .progressjs-inner {
background-color: #939595;
position: relative;
z-index: 2000;
height: 3px;
overflow: hidden;
-webkit-transition: width .5s;
-moz-transition: width .5s;
-o-transition: width .5s;
transition: width .5s;
}
.progressjs-theme-rainloop .progressjs-percent {
position: absolute;
top: 0;
left: 0;
right: -32px;
bottom: 0;
background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.3)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.3)), color-stop(0.75, rgba(255, 255, 255, 0.3)), color-stop(0.75, transparent), to(transparent));
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
-webkit-background-size: 32px 32px;
-moz-background-size: 32px 32px;
-o-background-size: 32px 32px;
background-size: 32px 32px;
-webkit-animation: simple-pace-stripe-animation 500ms linear infinite;
-moz-animation: simple-pace-stripe-animation 500ms linear infinite;
-ms-animation: simple-pace-stripe-animation 500ms linear infinite;
-o-animation: simple-pace-stripe-animation 500ms linear infinite;
animation: simple-pace-stripe-animation 500ms linear infinite;
}
@-webkit-keyframes simple-pace-stripe-animation {
0% { -webkit-transform: none; transform: none; }
100% { -webkit-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@-moz-keyframes simple-pace-stripe-animation {
0% { -moz-transform: none; transform: none; }
100% { -moz-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@-o-keyframes simple-pace-stripe-animation {
0% { -o-transform: none; transform: none; }
100% { -o-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@-ms-keyframes simple-pace-stripe-animation {
0% { -ms-transform: none; transform: none; }
100% { -ms-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@keyframes simple-pace-stripe-animation {
0% { transform: none; transform: none; }
100% { transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
.progressjs-theme-rainloop {
z-index: 2000;
}
.progressjs-theme-rainloop .progressjs-inner {
background-color: #939595;
position: relative;
z-index: 2000;
height: 3px;
overflow: hidden;
-webkit-transition: width .5s;
-moz-transition: width .5s;
-o-transition: width .5s;
transition: width .5s;
}
.progressjs-theme-rainloop .progressjs-percent {
position: absolute;
top: 0;
left: 0;
right: -32px;
bottom: 0;
background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.3)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.3)), color-stop(0.75, rgba(255, 255, 255, 0.3)), color-stop(0.75, transparent), to(transparent));
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
-webkit-background-size: 32px 32px;
-moz-background-size: 32px 32px;
-o-background-size: 32px 32px;
background-size: 32px 32px;
-webkit-animation: simple-pace-stripe-animation 500ms linear infinite;
-moz-animation: simple-pace-stripe-animation 500ms linear infinite;
-ms-animation: simple-pace-stripe-animation 500ms linear infinite;
-o-animation: simple-pace-stripe-animation 500ms linear infinite;
animation: simple-pace-stripe-animation 500ms linear infinite;
}
@-webkit-keyframes simple-pace-stripe-animation {
0% { -webkit-transform: none; transform: none; }
100% { -webkit-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@-moz-keyframes simple-pace-stripe-animation {
0% { -moz-transform: none; transform: none; }
100% { -moz-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@-o-keyframes simple-pace-stripe-animation {
0% { -o-transform: none; transform: none; }
100% { -o-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@-ms-keyframes simple-pace-stripe-animation {
0% { -ms-transform: none; transform: none; }
100% { -ms-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@keyframes simple-pace-stripe-animation {
0% { transform: none; transform: none; }
100% { transform: translate(-32px, 0); transform: translate(-32px, 0); }
}

View file

@ -34,13 +34,13 @@ import {
} from 'Common/Utils';
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { bXMLHttpRequestSupported, bMobileDevice } from 'Common/Globals';
import { upload } from 'Common/Links';
import { i18n, getNotification, getUploadErrorDescByCode } from 'Common/Translator';
import { format as momentorFormat } from 'Common/Momentor';
import { getMessageFlagsFromCache, setMessageFlagsToCache, setFolderHash } from 'Common/Cache';
import { HtmlEditor } from 'Common/HtmlEditor';
import { bMobileDevice } from 'Common/Globals';
import AppStore from 'Stores/User/App';
import SettingsStore from 'Stores/User/Settings';

View file

@ -1,4 +1,3 @@
import window from 'window';
import _ from '_';
import ko from 'ko';
@ -11,7 +10,7 @@ import {
Notification
} from 'Common/Enums';
import { trim, inArray, pInt, convertLangName, triggerAutocompleteInputChange } from 'Common/Utils';
import { trim, inArray, convertLangName, triggerAutocompleteInputChange } from 'Common/Utils';
import { $win } from 'Common/Globals';
import { getNotification, getNotificationFromResponse, reload as translatorReload } from 'Common/Translator';
@ -289,8 +288,7 @@ class LoginUserView extends AbstractViewNext {
onBuild() {
const signMeLocal = Local.get(ClientSideKeyName.LastSignMe),
signMe = (Settings.settingsGet('SignMe') || 'unused').toLowerCase(),
jsHash = Settings.appSettingsGet('jsHash');
signMe = (Settings.settingsGet('SignMe') || 'unused').toLowerCase();
switch (signMe) {
case LoginSignMeTypeAsString.DefaultOff:

View file

@ -1,4 +1,3 @@
import window from 'window';
import _ from '_';
import $ from '$';
import ko from 'ko';
@ -22,7 +21,6 @@ import { $html, leftPanelDisabled, keyScopeReal, useKeyboardShortcuts, moveActio
import {
inArray,
isArray,
isNonEmptyArray,
trim,
noop,

View file

@ -1,19 +1,19 @@
<?php
if (!defined('APP_VERSION'))
{
define('APP_VERSION', '0.0.0');
define('APP_VERSION_TYPE', 'source');
define('APP_INDEX_ROOT_FILE', __FILE__);
define('APP_INDEX_ROOT_PATH', str_replace('\\', '/', rtrim(dirname(__FILE__), '\\/').'/'));
}
if (file_exists(APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php'))
{
include APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php';
}
else
{
echo '[105] Missing version directory';
exit(105);
}
<?php
if (!defined('APP_VERSION'))
{
define('APP_VERSION', '0.0.0');
define('APP_VERSION_TYPE', 'source');
define('APP_INDEX_ROOT_FILE', __FILE__);
define('APP_INDEX_ROOT_PATH', str_replace('\\', '/', rtrim(dirname(__FILE__), '\\/').'/'));
}
if (file_exists(APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php'))
{
include APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php';
}
else
{
echo '[105] Missing version directory';
exit(105);
}

View file

@ -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)
);
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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)')
);
}
}

View file

@ -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;
}
}

View file

@ -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)
);
}
}

View file

@ -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;

View file

@ -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('*')
);
}
}

View file

@ -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)
);
}
}

View file

@ -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('*')
);
}
}

View file

@ -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;
}
}

View file

@ -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('*')
);
}
}

View file

@ -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))
{

View file

@ -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('*')
);
}
}

View file

@ -52,7 +52,7 @@ function md5crypt($pw, $salt = "", $magic = "")
{
$ctx .= $pw[0];
}
$i = $i >> 1;
}

View file

@ -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);
}
}
}
}
}

View file

@ -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));

View file

@ -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);
}
}
}
};
})();

View file

@ -1282,7 +1282,6 @@ class Actions
'forgotPasswordLinkUrl' => \trim($oConfig->Get('login', 'forgot_password_link_url', '')),
'registrationLinkUrl' => \trim($oConfig->Get('login', 'registration_link_url', '')),
'hideSubmitButton' => (bool) $oConfig->Get('login', 'hide_submit_button', true),
'jsHash' => \md5(\RainLoop\Utils::GetConnectionToken()),
'useImapThread' => (bool) $oConfig->Get('labs', 'use_imap_thread', false),
'useImapSubscribe' => (bool) $oConfig->Get('labs', 'use_imap_list_subscribe', true),
'allowAppendMessage' => (bool) $oConfig->Get('labs', 'allow_message_append', false),

View file

@ -29,7 +29,7 @@
function ProgressJs(obj) {
if (typeof obj.length != 'undefined') {
this._targetElement = obj;
this._targetElement = obj;
} else {
this._targetElement = [obj];
}
@ -37,7 +37,7 @@
if (typeof window._progressjsId === 'undefined')
window._progressjsId = 1;
if (typeof window._progressjsIntervals === 'undefined')
if (typeof window._progressjsIntervals === 'undefined')
window._progressjsIntervals = {};
this._options = {
@ -54,7 +54,7 @@
* Start progress for specific element(s)
*
* @api private
* @method _createContainer
* @method _createContainer
*/
function _startProgress() {
@ -79,7 +79,7 @@
* @param {Object} targetElement
*/
function _setProgress(targetElement) {
//if the target element already as `data-progressjs`, ignore the init
if (targetElement.hasAttribute("data-progressjs"))
return;
@ -88,7 +88,7 @@
var targetElementOffset = _getOffset.call(this, targetElement);
targetElement.setAttribute("data-progressjs", window._progressjsId);
var progressElementContainer = document.createElement('div');
progressElementContainer.className = 'progressjs-progress progressjs-theme-' + this._options.theme;
@ -110,7 +110,7 @@
progressPercentElement.innerHTML = "1%";
progressElement.appendChild(progressPercentElement);
if (this._options.overlayMode && targetElement.tagName.toLowerCase() === 'body') {
//if we have `body` for target element and also overlay mode is enable, we should use a different
//position for progress bar container element
@ -164,7 +164,7 @@
*/
function _setPercentFor(targetElement, percent) {
var self = this;
//prevent overflow!
if (percent >= 100)
percent = 100;
@ -191,7 +191,7 @@
if (existingPercent > currentPercent) {
increasement = false;
}
var intervalIn = 10;
function changePercentTimer(percentElement, existingPercent, currentPercent) {
//calculate the distance between two percents
@ -210,17 +210,17 @@
setTimeout(function() { changePercentTimer(percentElement, existingPercent, currentPercent); }, intervalIn);
}
}
changePercentTimer(percentElement, existingPercent, currentPercent);
})(percentElement, existingPercent, parseInt(percent));
}, 50);
}
}
/**
* Get the progress bar element
* Get the progress bar element
*
* @api private
* @method _getPercentElement
@ -228,7 +228,7 @@
*/
function _getPercentElement(targetElement) {
var progressjsId = parseInt(targetElement.getAttribute('data-progressjs'));
return document.querySelector('.progressjs-container > .progressjs-progress[data-progressjs="' + progressjsId + '"] > .progressjs-inner');
return document.querySelector('.progressjs-container > .progressjs-progress[data-progressjs="' + progressjsId + '"] > .progressjs-inner');
}
/**
@ -241,9 +241,9 @@
*/
function _autoIncrease(size, millisecond) {
var self = this;
var progressjsId = parseInt(this._targetElement[0].getAttribute('data-progressjs'));
if (typeof window._progressjsIntervals[progressjsId] != 'undefined') {
clearInterval(window._progressjsIntervals[progressjsId]);
}
@ -273,7 +273,7 @@
}
/**
* Close and remove progress bar
* Close and remove progress bar
*
* @api private
* @method _end
@ -288,10 +288,10 @@
} else {
this._onBeforeEndCallback.call(this);
}
}
}
var progressjsId = parseInt(this._targetElement[0].getAttribute('data-progressjs'));
for (var i = 0, elmsLength = this._targetElement.length; i < elmsLength; i++) {
var currentElement = this._targetElement[i];
var percentElement = _getPercentElement(currentElement);
@ -300,7 +300,7 @@
return;
var existingPercent = parseInt(percentElement.style.width.replace('%', ''));
var timeoutSec = 1;
if (existingPercent < 100) {
_setPercentFor.call(this, currentElement, 100);
@ -412,7 +412,7 @@
} else if (typeof (targetElm) === 'string') {
//select the target element with query selector
var targetElement = document.querySelectorAll(targetElm);
if (targetElement) {
return new ProgressJs(targetElement);
} else {

View file

@ -1,216 +1,216 @@
(function() {
var
selectRange = function (el, start, end) {
if (!el) {
return;
}
if (end === undefined) {
end = start;
}
if('selectionStart' in el) {
el.selectionStart = start;
el.selectionEnd = end;
} else if(el.setSelectionRange) {
el.setSelectionRange(start, end);
} else if(el.createTextRange) {
var range = el.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
},
toTop = function (el) {
selectRange(el, 0);
if (el) {
el.scrollTop = 0;
}
},
simplePlainToHtml = function (sPlain) {
return sPlain
.replace(/&/g, '&amp;')
.replace(/>/g, '&gt;').replace(/</g, '&lt;')
.replace(/[\-_~]{10,}/g, '<hr />')
.replace(/\n/g, '<br />')
.replace(/ /g, '&nbsp;')
;
},
simpleHtmlToPlain = function (sHtml) {
var sText = sHtml
.replace(/[\s]+/gm, ' ')
.replace(/<br[^>]*>/gmi, '\n')
.replace(/<\/h[\d]>/gi, '\n')
.replace(/<\/p>/gi, '\n\n')
.replace(/<\/li>/gi, '\n')
.replace(/<\/td>/gi, '\n')
.replace(/<\/tr>/gi, '\n')
.replace(/<\/div>/gi, '\n')
.replace(/<blockquote[^>]*>/gmi, '\n')
.replace(/<\/blockquote>/gi, '\n')
.replace(/<hr[^>]*>/gmi, '\n_______________________________\n\n')
.replace(/&nbsp;/gi, ' ')
.replace(/&quot;/gi, '"')
.replace(/<[^>]*>/gm, '')
;
sText = $('<div></div>').html(sText).text();
sText = sText
.replace(/\n[ \t]+/gm, '\n')
.replace(/[\n]{3,}/gm, '\n\n')
.replace(/&gt;/gi, '>')
.replace(/&lt;/gi, '<')
.replace(/&amp;/gi, '&')
;
return sText;
}
;
CKEDITOR.plugins.add('plain', {
lang: '',
icons: 'plain',
hidpi: true,
init: function(editor)
{
if (editor.elementMode === CKEDITOR.ELEMENT_MODE_INLINE) {
return;
}
editor.__textUtils = {
plainToHtml: function(data) {
return window.rainloop_Utils_plainToHtml ?
window.rainloop_Utils_plainToHtml(data, true) : simplePlainToHtml(data);
},
htmlToPlain: function(data) {
return window.rainloop_Utils_htmlToPlain ?
window.rainloop_Utils_htmlToPlain(data, true) : simpleHtmlToPlain(data);
}
};
var plain = CKEDITOR.plugins.plain;
editor.addMode('plain', function(callback) {
var
contentsSpace = editor.ui.space('contents'),
textarea = contentsSpace.getDocument().createElement('textarea')
;
textarea.setStyles(
CKEDITOR.tools.extend({
width: CKEDITOR.env.ie7Compat ? '99%' : '100%',
height: '100%',
resize: 'none',
outline: 'none',
'text-align': 'left'
},
CKEDITOR.tools.cssVendorPrefix('tab-size', 4)))
;
textarea.setAttribute('dir', 'ltr');
textarea.addClass('cke_plain');
CKEDITOR.plugins.clipboard.preventDefaultDropOnElement(textarea);
contentsSpace.append(textarea);
var editable = editor.editable(new plainEditable(editor, textarea));
editable.setData(editor.getData(1));
editor.__plain = editable;
editor.__textarea = textarea.$;
if (CKEDITOR.env.ie) {
editable.attachListener(editor, 'resize', onResize, editable);
editable.attachListener(CKEDITOR.document.getWindow(), 'resize', onResize, editable);
CKEDITOR.tools.setTimeout(onResize, 0, editable);
}
editor.fire('ariaWidget', this);
callback();
});
editor.addCommand('plain', plain.commands.plain);
if (editor.ui.addButton) {
editor.ui.addButton('plain', {
label: window.rl && window.rl.i18n ? window.rl.i18n('EDITOR/TEXT_SWITCHER_PLAINT_TEXT') : 'Plain',
command: 'plain',
toolbar: 'spec,10'
});
}
editor.on('mode', function() {
editor.getCommand('plain').setState(editor.mode === 'plain' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF);
editor.editable().addClass('cke_enable_context_menu');
editor.focus();
if (editor.mode === 'plain') {
toTop(editor.__textarea);
}
});
function onResize() {
this.hide();
this.setStyle('height', this.getParent().$.clientHeight + 'px');
this.setStyle('width', this.getParent().$.clientWidth + 'px');
this.show();
}
}
});
var plainEditable = CKEDITOR.tools.createClass({
base: CKEDITOR.editable,
proto: {
setData: function(data) {
this.setValue(this.editor.__textUtils.htmlToPlain(data));
this.editor.fire('dataReady');
},
setRawData: function(data) {
this.setValue(data);
this.editor.fire('dataReady');
},
getData: function() {
return this.editor.__textUtils.plainToHtml(this.getValue());
},
getRawData: function() {
return this.getValue();
},
insertHtml: function() {},
insertElement: function() {},
insertText: function() {},
setReadOnly: function( isReadOnly ) {
this[(isReadOnly ? 'set' : 'remove') + 'Attribute' ]('readOnly', 'readonly');
},
detach: function() {
plainEditable.baseProto.detach.call( this );
this.clearCustomData();
this.remove();
}
}
});
CKEDITOR.plugins.plain = {
commands: {
plain: {
modes: {
wysiwyg: 1, plain: 1
},
editorFocus: true,
readOnly: false,
exec: function(editor) {
if (editor.mode === 'wysiwyg') {
editor.fire('saveSnapshot');
}
editor.getCommand('plain').setState(CKEDITOR.TRISTATE_DISABLED);
editor.setMode(editor.mode === 'plain' ? 'wysiwyg' : 'plain');
},
canUndo: false
}
}
};
}());
(function() {
var
selectRange = function (el, start, end) {
if (!el) {
return;
}
if (end === undefined) {
end = start;
}
if('selectionStart' in el) {
el.selectionStart = start;
el.selectionEnd = end;
} else if(el.setSelectionRange) {
el.setSelectionRange(start, end);
} else if(el.createTextRange) {
var range = el.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
},
toTop = function (el) {
selectRange(el, 0);
if (el) {
el.scrollTop = 0;
}
},
simplePlainToHtml = function (sPlain) {
return sPlain
.replace(/&/g, '&amp;')
.replace(/>/g, '&gt;').replace(/</g, '&lt;')
.replace(/[\-_~]{10,}/g, '<hr />')
.replace(/\n/g, '<br />')
.replace(/ /g, '&nbsp;')
;
},
simpleHtmlToPlain = function (sHtml) {
var sText = sHtml
.replace(/[\s]+/gm, ' ')
.replace(/<br[^>]*>/gmi, '\n')
.replace(/<\/h[\d]>/gi, '\n')
.replace(/<\/p>/gi, '\n\n')
.replace(/<\/li>/gi, '\n')
.replace(/<\/td>/gi, '\n')
.replace(/<\/tr>/gi, '\n')
.replace(/<\/div>/gi, '\n')
.replace(/<blockquote[^>]*>/gmi, '\n')
.replace(/<\/blockquote>/gi, '\n')
.replace(/<hr[^>]*>/gmi, '\n_______________________________\n\n')
.replace(/&nbsp;/gi, ' ')
.replace(/&quot;/gi, '"')
.replace(/<[^>]*>/gm, '')
;
sText = $('<div></div>').html(sText).text();
sText = sText
.replace(/\n[ \t]+/gm, '\n')
.replace(/[\n]{3,}/gm, '\n\n')
.replace(/&gt;/gi, '>')
.replace(/&lt;/gi, '<')
.replace(/&amp;/gi, '&')
;
return sText;
}
;
CKEDITOR.plugins.add('plain', {
lang: '',
icons: 'plain',
hidpi: true,
init: function(editor)
{
if (editor.elementMode === CKEDITOR.ELEMENT_MODE_INLINE) {
return;
}
editor.__textUtils = {
plainToHtml: function(data) {
return window.rainloop_Utils_plainToHtml ?
window.rainloop_Utils_plainToHtml(data, true) : simplePlainToHtml(data);
},
htmlToPlain: function(data) {
return window.rainloop_Utils_htmlToPlain ?
window.rainloop_Utils_htmlToPlain(data, true) : simpleHtmlToPlain(data);
}
};
var plain = CKEDITOR.plugins.plain;
editor.addMode('plain', function(callback) {
var
contentsSpace = editor.ui.space('contents'),
textarea = contentsSpace.getDocument().createElement('textarea')
;
textarea.setStyles(
CKEDITOR.tools.extend({
width: CKEDITOR.env.ie7Compat ? '99%' : '100%',
height: '100%',
resize: 'none',
outline: 'none',
'text-align': 'left'
},
CKEDITOR.tools.cssVendorPrefix('tab-size', 4)))
;
textarea.setAttribute('dir', 'ltr');
textarea.addClass('cke_plain');
CKEDITOR.plugins.clipboard.preventDefaultDropOnElement(textarea);
contentsSpace.append(textarea);
var editable = editor.editable(new plainEditable(editor, textarea));
editable.setData(editor.getData(1));
editor.__plain = editable;
editor.__textarea = textarea.$;
if (CKEDITOR.env.ie) {
editable.attachListener(editor, 'resize', onResize, editable);
editable.attachListener(CKEDITOR.document.getWindow(), 'resize', onResize, editable);
CKEDITOR.tools.setTimeout(onResize, 0, editable);
}
editor.fire('ariaWidget', this);
callback();
});
editor.addCommand('plain', plain.commands.plain);
if (editor.ui.addButton) {
editor.ui.addButton('plain', {
label: window.rl && window.rl.i18n ? window.rl.i18n('EDITOR/TEXT_SWITCHER_PLAINT_TEXT') : 'Plain',
command: 'plain',
toolbar: 'spec,10'
});
}
editor.on('mode', function() {
editor.getCommand('plain').setState(editor.mode === 'plain' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF);
editor.editable().addClass('cke_enable_context_menu');
editor.focus();
if (editor.mode === 'plain') {
toTop(editor.__textarea);
}
});
function onResize() {
this.hide();
this.setStyle('height', this.getParent().$.clientHeight + 'px');
this.setStyle('width', this.getParent().$.clientWidth + 'px');
this.show();
}
}
});
var plainEditable = CKEDITOR.tools.createClass({
base: CKEDITOR.editable,
proto: {
setData: function(data) {
this.setValue(this.editor.__textUtils.htmlToPlain(data));
this.editor.fire('dataReady');
},
setRawData: function(data) {
this.setValue(data);
this.editor.fire('dataReady');
},
getData: function() {
return this.editor.__textUtils.plainToHtml(this.getValue());
},
getRawData: function() {
return this.getValue();
},
insertHtml: function() {},
insertElement: function() {},
insertText: function() {},
setReadOnly: function( isReadOnly ) {
this[(isReadOnly ? 'set' : 'remove') + 'Attribute' ]('readOnly', 'readonly');
},
detach: function() {
plainEditable.baseProto.detach.call( this );
this.clearCustomData();
this.remove();
}
}
});
CKEDITOR.plugins.plain = {
commands: {
plain: {
modes: {
wysiwyg: 1, plain: 1
},
editorFocus: true,
readOnly: false,
exec: function(editor) {
if (editor.mode === 'wysiwyg') {
editor.fire('saveSnapshot');
}
editor.getCommand('plain').setState(CKEDITOR.TRISTATE_DISABLED);
editor.setMode(editor.mode === 'plain' ? 'wysiwyg' : 'plain');
},
canUndo: false
}
}
};
}());

View file

@ -1,141 +1,141 @@
(function(CKEDITOR, $, undefined) {
'use strict';
var rl_signature_replacer = function(editor, text, signature, isHtml, insertBefore) {
var
skipInsert = false,
isEmptyText = false,
newLine = (isHtml ? '<br />' : "\n"),
clearHtmlLine = function(html) {
return $.trim(editor.__textUtils.htmlToPlain(html));
};
isEmptyText = '' === $.trim(text);
if (!isEmptyText && isHtml)
{
isEmptyText = '' === clearHtmlLine(text);
}
if (editor.__previos_signature && !isEmptyText)
{
if (isHtml && !editor.__previos_signature_is_html)
{
editor.__previos_signature = editor.__textUtils.plainToHtml(editor.__previos_signature);
editor.__previos_signature_is_html = true;
}
else if (!isHtml && editor.__previos_signature_is_html)
{
editor.__previos_signature = editor.__textUtils.htmlToPlain(editor.__previos_signature);
editor.__previos_signature_is_html = false;
}
skipInsert = false;
if (isHtml)
{
var clearSig = clearHtmlLine(editor.__previos_signature);
text = text.replace(/<signature>([\s\S]*)<\/signature>/igm, function(all){
var c = clearSig === clearHtmlLine(all);
if (!c) {
skipInsert = true;
}
return c ? '' : all;
});
}
else
{
var textLen = text.length;
text = text
.replace('' + editor.__previos_signature, '')
.replace('' + editor.__previos_signature, '');
if (textLen === text.length)
{
skipInsert = true;
}
}
}
if (!skipInsert)
{
signature = newLine + newLine + (isHtml ? '<signature>' : '') + signature + (isHtml ? '</signature>' : '');
text = insertBefore ? signature + text : text + signature;
if (10 < signature.length)
{
editor.__previos_signature = signature;
editor.__previos_signature_is_html = isHtml;
}
}
return text;
};
CKEDITOR.plugins.add('signature', {
init: function(editor) {
editor.addCommand('insertSignature', {
modes: {wysiwyg: 1, plain: 1},
exec: function(editor, cfg) {
if (cfg && cfg.clearCache)
{
editor.__previos_signature = undefined;
editor.__previos_signature_is_html = undefined;
return true;
}
var
bIsHtml = false,
bInsertBefore = false,
sSignature = '',
sResultSignature = '';
if (cfg)
{
bIsHtml = undefined === cfg.isHtml ? false : !!cfg.isHtml;
bInsertBefore = undefined === cfg.insertBefore ? false : !!cfg.insertBefore;
sSignature = undefined === cfg.signature ? '' : cfg.signature;
}
sResultSignature = sSignature;
try
{
if ('plain' === editor.mode && editor.__plain && editor.__textUtils)
{
if (editor.__textUtils && editor.__textUtils.htmlToPlain)
{
if (bIsHtml)
{
sResultSignature = editor.__textUtils.htmlToPlain(sResultSignature);
}
}
editor.__plain.setRawData(
rl_signature_replacer(editor, editor.__plain.getRawData(), sResultSignature, false, bInsertBefore));
}
else
{
if (editor.__textUtils && editor.__textUtils.plainToHtml)
{
if (!bIsHtml)
{
sResultSignature = editor.__textUtils.plainToHtml(sResultSignature);
}
}
editor.setData(
rl_signature_replacer(editor, editor.getData(), sResultSignature, true, bInsertBefore));
}
}
catch (e) {}
}
});
}
});
}(CKEDITOR, $));
(function(CKEDITOR, $, undefined) {
'use strict';
var rl_signature_replacer = function(editor, text, signature, isHtml, insertBefore) {
var
skipInsert = false,
isEmptyText = false,
newLine = (isHtml ? '<br />' : "\n"),
clearHtmlLine = function(html) {
return $.trim(editor.__textUtils.htmlToPlain(html));
};
isEmptyText = '' === $.trim(text);
if (!isEmptyText && isHtml)
{
isEmptyText = '' === clearHtmlLine(text);
}
if (editor.__previos_signature && !isEmptyText)
{
if (isHtml && !editor.__previos_signature_is_html)
{
editor.__previos_signature = editor.__textUtils.plainToHtml(editor.__previos_signature);
editor.__previos_signature_is_html = true;
}
else if (!isHtml && editor.__previos_signature_is_html)
{
editor.__previos_signature = editor.__textUtils.htmlToPlain(editor.__previos_signature);
editor.__previos_signature_is_html = false;
}
skipInsert = false;
if (isHtml)
{
var clearSig = clearHtmlLine(editor.__previos_signature);
text = text.replace(/<signature>([\s\S]*)<\/signature>/igm, function(all){
var c = clearSig === clearHtmlLine(all);
if (!c) {
skipInsert = true;
}
return c ? '' : all;
});
}
else
{
var textLen = text.length;
text = text
.replace('' + editor.__previos_signature, '')
.replace('' + editor.__previos_signature, '');
if (textLen === text.length)
{
skipInsert = true;
}
}
}
if (!skipInsert)
{
signature = newLine + newLine + (isHtml ? '<signature>' : '') + signature + (isHtml ? '</signature>' : '');
text = insertBefore ? signature + text : text + signature;
if (10 < signature.length)
{
editor.__previos_signature = signature;
editor.__previos_signature_is_html = isHtml;
}
}
return text;
};
CKEDITOR.plugins.add('signature', {
init: function(editor) {
editor.addCommand('insertSignature', {
modes: {wysiwyg: 1, plain: 1},
exec: function(editor, cfg) {
if (cfg && cfg.clearCache)
{
editor.__previos_signature = undefined;
editor.__previos_signature_is_html = undefined;
return true;
}
var
bIsHtml = false,
bInsertBefore = false,
sSignature = '',
sResultSignature = '';
if (cfg)
{
bIsHtml = undefined === cfg.isHtml ? false : !!cfg.isHtml;
bInsertBefore = undefined === cfg.insertBefore ? false : !!cfg.insertBefore;
sSignature = undefined === cfg.signature ? '' : cfg.signature;
}
sResultSignature = sSignature;
try
{
if ('plain' === editor.mode && editor.__plain && editor.__textUtils)
{
if (editor.__textUtils && editor.__textUtils.htmlToPlain)
{
if (bIsHtml)
{
sResultSignature = editor.__textUtils.htmlToPlain(sResultSignature);
}
}
editor.__plain.setRawData(
rl_signature_replacer(editor, editor.__plain.getRawData(), sResultSignature, false, bInsertBefore));
}
else
{
if (editor.__textUtils && editor.__textUtils.plainToHtml)
{
if (!bIsHtml)
{
sResultSignature = editor.__textUtils.plainToHtml(sResultSignature);
}
}
editor.setData(
rl_signature_replacer(editor, editor.getData(), sResultSignature, true, bInsertBefore));
}
}
catch (e) {}
}
});
}
});
}(CKEDITOR, $));

View file

@ -1,12 +1,12 @@
:(t=!!k[n],"br"!=n||!e.data("cke-eol")
:(t=!k||!!k[n],"br"!=n||!e.data("cke-eol")
---
for(F=null;y&&!p[y.getName()][L.name];){
for(F=null;y&&(!p||!p[y.getName()]||!p[y.getName()][L.name]);){
---
a.window.$.getSelection().removeAllRanges()
a.window&&a.window.$&&a.window.$.getSelection().removeAllRanges()
:(t=!!k[n],"br"!=n||!e.data("cke-eol")
:(t=!k||!!k[n],"br"!=n||!e.data("cke-eol")
---
for(F=null;y&&!p[y.getName()][L.name];){
for(F=null;y&&(!p||!p[y.getName()]||!p[y.getName()][L.name]);){
---
a.window.$.getSelection().removeAllRanges()
a.window&&a.window.$&&a.window.$.getSelection().removeAllRanges()

View file

@ -1,4 +1,4 @@
/*
/*
Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/

View file

@ -1,54 +1,54 @@
/**
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or http://ckeditor.com/license
*/
/**
* This file was added automatically by CKEditor builder.
* You may re-use it at any time to build CKEditor again.
*
* If you would like to build CKEditor online again
* (for example to upgrade), visit one the following links:
*
* (1) http://ckeditor.com/builder
* Visit online builder to build CKEditor from scratch.
*
* (2) http://ckeditor.com/builder/9b9471acfb896c4f73b825ccf971b5bc
* Visit online builder to build CKEditor, starting with the same setup as before.
*
* (3) http://ckeditor.com/builder/download/9b9471acfb896c4f73b825ccf971b5bc
* Straight download link to the latest version of CKEditor (Optimized) with the same setup as before.
*
* NOTE:
* This file is not used by CKEditor, you may remove it.
* Changing this file will not change your CKEditor configuration.
*/
var CKBUILDER_CONFIG = {
skin: 'moono-lisa',
preset: 'basic',
ignore: [
'.bender',
'bender.js',
'bender-err.log',
'bender-out.log',
'dev',
'.DS_Store',
'.editorconfig',
'.gitattributes',
'.gitignore',
'gruntfile.js',
'.idea',
'.jscsrc',
'.jshintignore',
'.jshintrc',
'less',
'.mailmap',
'node_modules',
'package.json',
'README.md',
'tests'
],
/**
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or http://ckeditor.com/license
*/
/**
* This file was added automatically by CKEditor builder.
* You may re-use it at any time to build CKEditor again.
*
* If you would like to build CKEditor online again
* (for example to upgrade), visit one the following links:
*
* (1) http://ckeditor.com/builder
* Visit online builder to build CKEditor from scratch.
*
* (2) http://ckeditor.com/builder/9b9471acfb896c4f73b825ccf971b5bc
* Visit online builder to build CKEditor, starting with the same setup as before.
*
* (3) http://ckeditor.com/builder/download/9b9471acfb896c4f73b825ccf971b5bc
* Straight download link to the latest version of CKEditor (Optimized) with the same setup as before.
*
* NOTE:
* This file is not used by CKEditor, you may remove it.
* Changing this file will not change your CKEditor configuration.
*/
var CKBUILDER_CONFIG = {
skin: 'moono-lisa',
preset: 'basic',
ignore: [
'.bender',
'bender.js',
'bender-err.log',
'bender-out.log',
'dev',
'.DS_Store',
'.editorconfig',
'.gitattributes',
'.gitignore',
'gruntfile.js',
'.idea',
'.jscsrc',
'.jshintignore',
'.jshintrc',
'less',
'.mailmap',
'node_modules',
'package.json',
'README.md',
'tests'
],
plugins : {
'about' : 1,
'autolink' : 1,

View file

@ -1,4 +1,4 @@
/*
/*
Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/

View file

@ -1,4 +1,4 @@
/*
/*
Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/

View file

@ -1,208 +1,208 @@
/*
Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
body
{
/* Font */
font-family: sans-serif, Arial, Verdana, "Trebuchet MS";
font-size: 12px;
/* Text color */
color: #333;
/* Remove the background color to make it transparent */
background-color: #fff;
margin: 20px;
}
.cke_editable
{
font-size: 13px;
line-height: 1.6;
/* Fix for missing scrollbars with RTL texts. (#10488) */
word-wrap: break-word;
}
blockquote
{
font-style: italic;
font-family: Georgia, Times, "Times New Roman", serif;
padding: 2px 0;
border-style: solid;
border-color: #ccc;
border-width: 0;
}
.cke_contents_ltr blockquote
{
padding-left: 20px;
padding-right: 8px;
border-left-width: 5px;
}
.cke_contents_rtl blockquote
{
padding-left: 8px;
padding-right: 20px;
border-right-width: 5px;
}
a
{
color: #0782C1;
}
ol,ul,dl
{
/* IE7: reset rtl list margin. (#7334) */
*margin-right: 0px;
/* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/
padding: 0 40px;
}
h1,h2,h3,h4,h5,h6
{
font-weight: normal;
line-height: 1.2;
}
hr
{
border: 0px;
border-top: 1px solid #ccc;
}
img.right
{
border: 1px solid #ccc;
float: right;
margin-left: 15px;
padding: 5px;
}
img.left
{
border: 1px solid #ccc;
float: left;
margin-right: 15px;
padding: 5px;
}
pre
{
white-space: pre-wrap; /* CSS 2.1 */
word-wrap: break-word; /* IE7 */
-moz-tab-size: 4;
tab-size: 4;
}
.marker
{
background-color: Yellow;
}
span[lang]
{
font-style: italic;
}
figure
{
text-align: center;
border: solid 1px #ccc;
border-radius: 2px;
background: rgba(0,0,0,0.05);
padding: 10px;
margin: 10px 20px;
display: inline-block;
}
figure > figcaption
{
text-align: center;
display: block; /* For IE8 */
}
a > img {
padding: 1px;
margin: 1px;
border: none;
outline: 1px solid #0782C1;
}
/* Widget Styles */
.code-featured
{
border: 5px solid red;
}
.math-featured
{
padding: 20px;
box-shadow: 0 0 2px rgba(200, 0, 0, 1);
background-color: rgba(255, 0, 0, 0.05);
margin: 10px;
}
.image-clean
{
border: 0;
background: none;
padding: 0;
}
.image-clean > figcaption
{
font-size: .9em;
text-align: right;
}
.image-grayscale
{
background-color: white;
color: #666;
}
.image-grayscale img, img.image-grayscale
{
filter: grayscale(100%);
}
.embed-240p
{
max-width: 426px;
max-height: 240px;
margin:0 auto;
}
.embed-360p
{
max-width: 640px;
max-height: 360px;
margin:0 auto;
}
.embed-480p
{
max-width: 854px;
max-height: 480px;
margin:0 auto;
}
.embed-720p
{
max-width: 1280px;
max-height: 720px;
margin:0 auto;
}
.embed-1080p
{
max-width: 1920px;
max-height: 1080px;
margin:0 auto;
}
/*
Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
body
{
/* Font */
font-family: sans-serif, Arial, Verdana, "Trebuchet MS";
font-size: 12px;
/* Text color */
color: #333;
/* Remove the background color to make it transparent */
background-color: #fff;
margin: 20px;
}
.cke_editable
{
font-size: 13px;
line-height: 1.6;
/* Fix for missing scrollbars with RTL texts. (#10488) */
word-wrap: break-word;
}
blockquote
{
font-style: italic;
font-family: Georgia, Times, "Times New Roman", serif;
padding: 2px 0;
border-style: solid;
border-color: #ccc;
border-width: 0;
}
.cke_contents_ltr blockquote
{
padding-left: 20px;
padding-right: 8px;
border-left-width: 5px;
}
.cke_contents_rtl blockquote
{
padding-left: 8px;
padding-right: 20px;
border-right-width: 5px;
}
a
{
color: #0782C1;
}
ol,ul,dl
{
/* IE7: reset rtl list margin. (#7334) */
*margin-right: 0px;
/* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/
padding: 0 40px;
}
h1,h2,h3,h4,h5,h6
{
font-weight: normal;
line-height: 1.2;
}
hr
{
border: 0px;
border-top: 1px solid #ccc;
}
img.right
{
border: 1px solid #ccc;
float: right;
margin-left: 15px;
padding: 5px;
}
img.left
{
border: 1px solid #ccc;
float: left;
margin-right: 15px;
padding: 5px;
}
pre
{
white-space: pre-wrap; /* CSS 2.1 */
word-wrap: break-word; /* IE7 */
-moz-tab-size: 4;
tab-size: 4;
}
.marker
{
background-color: Yellow;
}
span[lang]
{
font-style: italic;
}
figure
{
text-align: center;
border: solid 1px #ccc;
border-radius: 2px;
background: rgba(0,0,0,0.05);
padding: 10px;
margin: 10px 20px;
display: inline-block;
}
figure > figcaption
{
text-align: center;
display: block; /* For IE8 */
}
a > img {
padding: 1px;
margin: 1px;
border: none;
outline: 1px solid #0782C1;
}
/* Widget Styles */
.code-featured
{
border: 5px solid red;
}
.math-featured
{
padding: 20px;
box-shadow: 0 0 2px rgba(200, 0, 0, 1);
background-color: rgba(255, 0, 0, 0.05);
margin: 10px;
}
.image-clean
{
border: 0;
background: none;
padding: 0;
}
.image-clean > figcaption
{
font-size: .9em;
text-align: right;
}
.image-grayscale
{
background-color: white;
color: #666;
}
.image-grayscale img, img.image-grayscale
{
filter: grayscale(100%);
}
.embed-240p
{
max-width: 426px;
max-height: 240px;
margin:0 auto;
}
.embed-360p
{
max-width: 640px;
max-height: 360px;
margin:0 auto;
}
.embed-480p
{
max-width: 854px;
max-height: 480px;
margin:0 auto;
}
.embed-720p
{
max-width: 1280px;
max-height: 720px;
margin:0 auto;
}
.embed-1080p
{
max-width: 1920px;
max-height: 1080px;
margin:0 auto;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show more