Stable release of v3.1.19

We fixed #972 so that custom code (in the header) will be added after the power namespaces. We added a message to show when a server move failed. We fixed the BaseConfig to not use '_' as separator. We fixed the footable loading issue. We removed the need for passing placeholders by reference. We added the option to generate a CHANGELOG. We fixed the server class to load new client if server details changed. We fixed the readme placeholder issue #978. We fixed the empty server url issue #978. Fixed Package import to now use the phplibsec version 3.
This commit is contained in:
2023-02-27 14:27:41 +02:00
parent 339aec221e
commit 737bd03e46
55 changed files with 1900 additions and 1048 deletions

View File

@ -56,9 +56,6 @@ abstract class BaseConfig extends JoomlaRegistry
$this->input = $input ?: Factory::getApplication()->input;
$this->params = $params ?: Helper::getParams('com_componentbuilder');
// use underscore as the separator
$this->separator = '_';
// Instantiate the internal data object.
$this->data = new \stdClass();
}

View File

@ -31,6 +31,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Model\Sqltweaking;
use VDM\Joomla\Componentbuilder\Compiler\Model\Adminviews;
use VDM\Joomla\Componentbuilder\Compiler\Model\Siteviews;
use VDM\Joomla\Componentbuilder\Compiler\Model\Customadminviews;
use VDM\Joomla\Componentbuilder\Compiler\Model\Updateserver;
use VDM\Joomla\Componentbuilder\Compiler\Model\Joomlamodules;
use VDM\Joomla\Componentbuilder\Compiler\Model\Joomlaplugins;
use VDM\Joomla\Utilities\StringHelper;
@ -182,6 +183,14 @@ class Data
*/
protected Customadminviews $customadminviews;
/**
* The modelling Update Server
*
* @var Updateserver
* @since 3.2.0
*/
protected Updateserver $updateserver;
/**
* The modelling Joomla Modules
*
@ -226,6 +235,7 @@ class Data
* @param Adminviews|null $adminviews The modelling adminviews object.
* @param Siteviews|null $siteviews The modelling siteviews object.
* @param Customadminviews|null $customadminviews The modelling customadminviews object.
* @param Updateserver|null $updateserver The modelling update server object.
* @param Joomlamodules|null $modules The modelling modules object.
* @param Joomlaplugins|null $plugins The modelling plugins object.
* @param \JDatabaseDriver|null $db The database object.
@ -238,8 +248,8 @@ class Data
?Field $field = null, ?FieldName $fieldName = null, ?UniqueName $uniqueName = null,
?Filesfolders $filesFolders = null, ?Historycomponent $history = null, ?Whmcs $whmcs = null,
?Sqltweaking $sqltweaking = null, ?Adminviews $adminviews = null, ?Siteviews $siteviews = null,
?Customadminviews $customadminviews = null, ?Joomlamodules $modules = null,
?Joomlaplugins $plugins = null, ?\JDatabaseDriver $db = null)
?Customadminviews $customadminviews = null, ?Updateserver $updateserver = null,
?Joomlamodules $modules = null, ?Joomlaplugins $plugins = null, ?\JDatabaseDriver $db = null)
{
$this->config = $config ?: Compiler::_('Config');
$this->event = $event ?: Compiler::_('Event');
@ -258,6 +268,7 @@ class Data
$this->adminviews = $adminviews ?: Compiler::_('Model.Adminviews');
$this->siteviews = $siteviews ?: Compiler::_('Model.Siteviews');
$this->customadminviews = $customadminviews ?: Compiler::_('Model.Customadminviews');
$this->updateserver = $updateserver ?: Compiler::_('Model.Updateserver');
$this->modules = $modules ?: Compiler::_('Model.Joomlamodules');
$this->plugins = $plugins ?: Compiler::_('Model.Joomlaplugins');
$this->db = $db ?: Factory::getDbo();
@ -397,10 +408,10 @@ class Data
$this->whmcs->set($component);
// set the footable switch
if ($component->addfootable)
if ($component->addfootable > 0)
{
// force add footable
$this->config->set('footable ', true);
$this->config->set('footable', true);
// add the version
$this->config->set('footable_version', (3 == $component->addfootable) ? 3 : 2);
}
@ -472,15 +483,7 @@ class Data
unset($component->addcontributors);
// set the version updates
$component->version_update = (isset($component->version_update)
&& JsonHelper::check($component->version_update))
? json_decode((string) $component->version_update, true) : null;
if (ArrayHelper::check($component->version_update))
{
$component->version_update = array_values(
$component->version_update
);
}
$this->updateserver->set($component);
// build the build date
if ($this->config->get('add_build_date', 1) == 3)
@ -569,11 +572,8 @@ class Data
{
foreach ($addScriptTypes as $scriptType)
{
if (isset(
$component->{'add_' . $scriptMethod . '_' . $scriptType}
)
&& $component->{'add_' . $scriptMethod . '_' . $scriptType}
== 1
if (isset($component->{'add_' . $scriptMethod . '_' . $scriptType})
&& $component->{'add_' . $scriptMethod . '_' . $scriptType} == 1
&& StringHelper::check(
$component->{$scriptMethod . '_' . $scriptType}
))
@ -795,14 +795,24 @@ class Data
// reset back to now lang
$this->config->lang_target = $nowLang;
// catch empty URL to update server TODO: we need to fix this in better way later
if ($component->add_update_server == 1 && $component->update_server_target !== 3
&& (
!StringHelper::check($component->update_server_url)
|| strpos($component->update_server_url, 'http') === false
))
{
// we fall back to other, since we can't work with an empty update server URL
$component->add_update_server = 0;
$component->update_server_target = 3;
}
// add the update/sales server FTP details if that is the expected protocol
$serverArray = array('update_server', 'sales_server');
foreach ($serverArray as $server)
{
if ($component->{'add_' . $server} == 1
&& is_numeric(
$component->{$server}
)
&& is_numeric($component->{$server})
&& $component->{$server} > 0)
{
// get the server protocol

View File

@ -192,6 +192,9 @@ class Structuresingle
// do README check
$README = $this->doReadmeCheck();
// do CHANGELOG check
$CHANGELOG = $this->doChangelogCheck();
// start moving
foreach ($this->settings->single() as $target => $details)
{
@ -208,6 +211,12 @@ class Structuresingle
continue;
}
// if not needed do not add
if ($details->naam === 'CHANGELOG.md' && !$CHANGELOG)
{
continue;
}
// set new name
$this->setNewName($details);
@ -264,12 +273,18 @@ class Structuresingle
*/
private function doReadmeCheck(): bool
{
if ($this->component->get('addreadme', false))
{
return true;
}
return (bool) $this->component->get('addreadme', false);
}
return false;
/**
* Check if changelog must be added
*
* @return bool
* @since 3.2.0
*/
private function doChangelogCheck(): bool
{
return (bool) $this->component->get('changelog', false);
}
/**

View File

@ -213,7 +213,7 @@ interface PlaceholderInterface
* @return string
* @since 3.2.0
*/
public function update(string $data, array &$placeholder, int $action = 1): string;
public function update(string $data, array $placeholder, int $action = 1): string;
/**
* Update the data with the active placeholders

View File

@ -813,50 +813,47 @@ class Data
$this->libraries->set($module->code_name, $module);
// add PHP in module install
$module->add_install_script = false;
$addScriptMethods = array('php_preflight',
$module->add_install_script = true;
$addScriptMethods = [
'php_script',
'php_preflight',
'php_postflight',
'php_method');
$addScriptTypes = array('install', 'update',
'uninstall');
'php_method'
];
$addScriptTypes = [
'install',
'update',
'uninstall'
];
// the next are php placeholders
$guiMapper['type'] = 'php';
foreach ($addScriptMethods as $scriptMethod)
{
foreach ($addScriptTypes as $scriptType)
{
if (isset(
$module->{'add_' . $scriptMethod . '_'
. $scriptType}
)
&& $module->{'add_' . $scriptMethod . '_'
. $scriptType} == 1
if (isset($module->{'add_' . $scriptMethod . '_' . $scriptType})
&& $module->{'add_' . $scriptMethod . '_' . $scriptType} == 1
&& StringHelper::check(
$module->{$scriptMethod . '_' . $scriptType}
))
{
// set GUI mapper field
$guiMapper['field'] = $scriptMethod . '_'
. $scriptType;
$guiMapper['field'] = $scriptMethod . '_' . $scriptType;
$module->{$scriptMethod . '_' . $scriptType} = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode(
(string) $module->{$scriptMethod . '_'
. $scriptType}
(string) $module->{$scriptMethod . '_' . $scriptType}
)
)
),
$guiMapper
);
$module->add_install_script = true;
}
else
{
unset($module->{$scriptMethod . '_' . $scriptType});
$module->{'add_' . $scriptMethod . '_'
. $scriptType}
= 0;
$module->{'add_' . $scriptMethod . '_' . $scriptType} = 0;
}
}
}

View File

@ -307,19 +307,17 @@ class Structure
// set install script if needed
if ($module->add_install_script)
{
$fileDetails = array('path' => $module->folder_path
. '/script.php',
'name' => 'script.php',
'zip' => 'script.php');
$fileDetails = [
'path' => $module->folder_path . '/script.php',
'name' => 'script.php',
'zip' => 'script.php'
];
$this->file->write(
$fileDetails['path'],
'<?php' . PHP_EOL . '// Script template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL
.
PHP_EOL . '// No direct access to this file'
. PHP_EOL .
"defined('_JEXEC') or die('Restricted access');"
. PHP_EOL .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" . PHP_EOL .
Placefix::_h('INSTALLCLASS')
);
$this->files->appendArray($module->key, $fileDetails);
@ -331,10 +329,11 @@ class Structure
// set readme if found
if ($module->addreadme)
{
$fileDetails = array('path' => $module->folder_path
. '/README.md',
'name' => 'README.md',
'zip' => 'README.md');
$fileDetails = [
'path' => $module->folder_path . '/README.md',
'name' => 'README.md',
'zip' => 'README.md'
];
$this->file->write($fileDetails['path'], $module->readme);
$this->files->appendArray($module->key, $fileDetails);
@ -369,10 +368,11 @@ class Structure
$this->folder->create($module->folder_path . '/css');
// add the CSS file
$fileDetails = array('path' => $module->folder_path
. '/css/mod_admin.css',
'name' => 'mod_admin.css',
'zip' => 'mod_admin.css');
$fileDetails = [
'path' => $module->folder_path . '/css/mod_admin.css',
'name' => 'mod_admin.css',
'zip' => 'mod_admin.css'
];
$this->file->write(
$fileDetails['path'],
Placefix::_h('BOM') . PHP_EOL
@ -409,10 +409,11 @@ class Structure
$this->folder->create($module->folder_path . '/js');
// add the CSS file
$fileDetails = array('path' => $module->folder_path
. '/js/mod_admin.js',
'name' => 'mod_admin.js',
'zip' => 'mod_admin.js');
$fileDetails = [
'path' => $module->folder_path . '/js/mod_admin.js',
'name' => 'mod_admin.js',
'zip' => 'mod_admin.js'
];
$this->file->write(
$fileDetails['path'],
Placefix::_h('BOM') . PHP_EOL
@ -484,11 +485,11 @@ class Structure
foreach ($module->form_files as $file => $fields)
{
// set file details
$fileDetails = array('path' => $module->folder_path
. '/forms/' . $file . '.xml',
'name' => $file . '.xml',
'zip' => 'forms/' . $file
. '.xml');
$fileDetails = [
'path' => $module->folder_path . '/forms/' . $file . '.xml',
'name' => $file . '.xml',
'zip' => 'forms/' . $file . '.xml'
];
// build basic XML
$xml = '<?xml version="1.0" encoding="utf-8"?>';

View File

@ -735,49 +735,44 @@ class Data
$this->filesFolders->set($plugin);
// add PHP in plugin install
$plugin->add_install_script = false;
$addScriptMethods = array('php_preflight',
$plugin->add_install_script = true;
$addScriptMethods = [
'php_preflight',
'php_postflight',
'php_method');
$addScriptTypes = array('install', 'update',
'uninstall');
'php_method'
];
$addScriptTypes = [
'install',
'update',
'uninstall'
];
foreach ($addScriptMethods as $scriptMethod)
{
foreach ($addScriptTypes as $scriptType)
{
if (isset(
$plugin->{'add_' . $scriptMethod . '_'
. $scriptType}
)
&& $plugin->{'add_' . $scriptMethod . '_'
. $scriptType} == 1
if (isset( $plugin->{'add_' . $scriptMethod . '_' . $scriptType})
&& $plugin->{'add_' . $scriptMethod . '_' . $scriptType} == 1
&& StringHelper::check(
$plugin->{$scriptMethod . '_' . $scriptType}
))
{
// set GUI mapper field
$guiMapper['field'] = $scriptMethod . '_'
. $scriptType;
$plugin->{$scriptMethod . '_' . $scriptType}
= $this->gui->set(
$guiMapper['field'] = $scriptMethod . '_' . $scriptType;
$plugin->{$scriptMethod . '_' . $scriptType} = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode(
(string) $plugin->{$scriptMethod . '_'
. $scriptType}
(string) $plugin->{$scriptMethod . '_' . $scriptType}
)
)
),
$guiMapper
);
$plugin->add_install_script = true;
}
else
{
unset($plugin->{$scriptMethod . '_' . $scriptType});
$plugin->{'add_' . $scriptMethod . '_'
. $scriptType}
= 0;
$plugin->{'add_' . $scriptMethod . '_' . $scriptType} = 0;
}
}
}

View File

@ -228,19 +228,17 @@ class Structure
// set install script if needed
if ($plugin->add_install_script)
{
$fileDetails = array('path' => $plugin->folder_path
. '/script.php',
'name' => 'script.php',
'zip' => 'script.php');
$fileDetails = [
'path' => $plugin->folder_path . '/script.php',
'name' => 'script.php',
'zip' => 'script.php'
];
$this->file->write(
$fileDetails['path'],
'<?php' . PHP_EOL . '// Script template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL
.
PHP_EOL . '// No direct access to this file'
. PHP_EOL .
"defined('_JEXEC') or die('Restricted access');"
. PHP_EOL .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" . PHP_EOL .
Placefix::_h('INSTALLCLASS')
);
$this->files->appendArray($plugin->key, $fileDetails);
@ -252,10 +250,11 @@ class Structure
// set readme if found
if ($plugin->addreadme)
{
$fileDetails = array('path' => $plugin->folder_path
. '/README.md',
'name' => 'README.md',
'zip' => 'README.md');
$fileDetails = [
'path' => $plugin->folder_path . '/README.md',
'name' => 'README.md',
'zip' => 'README.md'
];
$this->file->write($fileDetails['path'], $plugin->readme);
$this->files->appendArray($plugin->key, $fileDetails);
@ -287,11 +286,11 @@ class Structure
foreach ($plugin->form_files as $file => $fields)
{
// set file details
$fileDetails = array('path' => $plugin->folder_path
. '/forms/' . $file . '.xml',
'name' => $file . '.xml',
'zip' => 'forms/' . $file
. '.xml');
$fileDetails = [
'path' => $plugin->folder_path . '/forms/' . $file . '.xml',
'name' => $file . '.xml',
'zip' => 'forms/' . $file . '.xml'
];
// build basic XML
$xml = '<?xml version="1.0" encoding="utf-8"?>';

View File

@ -79,7 +79,7 @@ class Loader
$this->registry->
set('builder.footable_scripts.' . $target . '.' . $key, true);
$this->config->set('footable ', true);
$this->config->set('footable', true);
}
}

View File

@ -0,0 +1,102 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Model;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\StringHelper;
/**
* Model Joomla Update Server Class
*
* @since 3.2.0
*/
class Updateserver
{
/**
* Compiler Registry Class
*
* @var Registry
* @since 3.2.0
*/
protected Registry $registry;
/**
* Constructor
*
* @param Registry|null $registry The compiler registry object.
*
* @since 3.2.0
*/
public function __construct(?Registry $registry = null)
{
$this->registry = $registry ?: Compiler::_('Registry');
}
/**
* Set version updates
*
* @param object $item The item data
*
* @return void
* @since 3.2.0
*/
public function set(object &$item)
{
// set the version updates
$item->version_update = (isset($item->version_update)
&& JsonHelper::check($item->version_update))
? json_decode((string) $item->version_update, true) : null;
if (ArrayHelper::check($item->version_update))
{
$item->version_update = array_values(
$item->version_update
);
// set the change log details
$this->changelog($item);
}
}
/**
* Set changelog values to registry
*
* @param array $updates The update data
*
* @return void
* @since 3.2.0
*/
protected function changelog(object &$item)
{
// set the version updates
foreach ($item->version_update as $update)
{
$bucket = [];
if (isset($update['change_log']) && StringHelper::check($update['change_log'])
&& isset($update['version']) && StringHelper::check($update['version']))
{
$bucket[] = '# v' . $update['version'] . PHP_EOL . PHP_EOL . $update['change_log'];
}
}
if (ArrayHelper::check($bucket))
{
$item->changelog = implode(PHP_EOL . PHP_EOL, $bucket);
}
}
}

View File

@ -368,7 +368,7 @@ class Placeholder implements PlaceholderInterface
* @return string
* @since 3.2.0
*/
public function update(string $data, array &$placeholder, int $action = 1): string
public function update(string $data, array $placeholder, int $action = 1): string
{
// make sure the placeholders is an array
if (!ArrayHelper::check($placeholder))

View File

@ -162,6 +162,7 @@ class Component implements ServiceProviderInterface
$container->get('Model.Adminviews'),
$container->get('Model.Siteviews'),
$container->get('Model.Customadminviews'),
$container->get('Model.Updateserver'),
$container->get('Model.Joomlamodules'),
$container->get('Model.Joomlaplugins')
);

View File

@ -52,6 +52,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Model\Whmcs;
use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders;
use VDM\Joomla\Componentbuilder\Compiler\Model\Modifieddate;
use VDM\Joomla\Componentbuilder\Compiler\Model\Createdate;
use VDM\Joomla\Componentbuilder\Compiler\Model\Updateserver;
/**
@ -173,15 +174,18 @@ class Model implements ServiceProviderInterface
$container->alias(Whmcs::class, 'Model.Whmcs')
->share('Model.Whmcs', [$this, 'getModelWhmcs'], true);
$container->alias(Filesfolders::class, 'Model.Filesfolders')
->share('Model.Filesfolders', [$this, 'getModelFilesfolders'], true);
$container->alias(Modifieddate::class, 'Model.Modifieddate')
->share('Model.Modifieddate', [$this, 'getModifieddate'], true);
$container->alias(Createdate::class, 'Model.Createdate')
->share('Model.Createdate', [$this, 'getCreatedate'], true);
$container->alias(Updateserver::class, 'Model.Updateserver')
->share('Model.Updateserver', [$this, 'getUpdateserver'], true);
$container->alias(Filesfolders::class, 'Model.Filesfolders')
->share('Model.Filesfolders', [$this, 'getModelFilesfolders'], true);
$container->alias(ServerLoad::class, 'Model.Server.Load')
->share('Model.Server.Load', [$this, 'getServerLoad'], true);
}
@ -758,6 +762,21 @@ class Model implements ServiceProviderInterface
return new Createdate();
}
/**
* Get the update server Model
*
* @param Container $container The DI container.
*
* @return Updateserver
* @since 3.2.0
*/
public function getUpdateserver(Container $container): Updateserver
{
return new Updateserver(
$container->get('Registry')
);
}
/**
* Get the files folders Model
*

View File

@ -13,7 +13,11 @@ namespace VDM\Joomla\Componentbuilder;
use VDM\Joomla\Componentbuilder\Crypt\FOF;
use VDM\Joomla\Componentbuilder\Crypt\Aes;
use VDM\Joomla\Componentbuilder\Crypt\Aes\Legacy;
use VDM\Joomla\Componentbuilder\Crypt\Password;
use VDM\Joomla\Componentbuilder\Interfaces\Cryptinterface;
use VDM\Joomla\Utilities\StringHelper;
/**
@ -32,6 +36,22 @@ class Crypt
*/
protected FOF $fof;
/**
* The Crypt AES CBC class
*
* @var Aes
* @since 3.2.0
*/
protected Aes $aes;
/**
* The Crypt AES Legacy class
*
* @var Legacy
* @since 3.2.0
*/
protected Legacy $legacy;
/**
* The Password class
*
@ -46,7 +66,11 @@ class Crypt
* @var array
* @since 3.2.0
*/
protected array $options = ['basic' => true, 'medium' => true];
protected array $options = [
'basic' => 'fof',
'medium' => 'fof',
'local' => 'aes'
];
/**
* Active passwords
@ -54,19 +78,23 @@ class Crypt
* @var array
* @since 3.2.0
*/
protected array $passwords = ['basic' => null, 'medium' => null];
protected array $passwords = [];
/**
* Constructor
*
* @param FOF $fof The FOF class
* @param Aes $aes The AES CBC class
* @param Legacy $legacy The AES Legacy class
* @param Password $password The Password class
*
* @since 3.2.0
*/
public function __construct(FOF $fof, Password $password)
public function __construct(FOF $fof, Aes $aes, Legacy $legacy, Password $password)
{
$this->fof = $fof;
$this->aes = $aes;
$this->legacy = $legacy;
$this->password = $password;
}
@ -74,18 +102,19 @@ class Crypt
* Encrypt a string as needed
*
* @param string $string The string to encrypt
* @param string $method The encryption method to use
* @param string|null $default The default password
* @param string $method The encryption method to use
* @param string|null $password The password
*
* @return string
* @since 3.2.0
**/
public function encrypt(string $string, string $method,
?string $default = null): string
?string $password = null): string
{
if (($password = $this->getPassword($method, $default)) !== null)
if (($password = $this->getPassword($method, $password)) !== null
&& ($name = $this->getClassName($method)) !== null)
{
return $this->fof->encrypt($string, $password);
return $this->{$name}->encrypt($string, $password);
}
return $string;
@ -104,49 +133,152 @@ class Crypt
public function decrypt(string $string, string $method,
?string $default = null): string
{
if (($password = $this->getPassword($method, $default)) !== null)
if (($password = $this->getPassword($method, $default)) !== null
&& ($name = $this->getClassName($method)) !== null)
{
return $this->fof->decrypt($string, $password);
return $this->{$name}->decrypt($string, $password);
}
return $string;
}
/**
* Check if a decryption method exist and is supported
*
* @param string $method The encryption method to find
*
* @return bool true it it exist
* Check if a decryption method exist and is supported
*
* @param string $method The encryption method to find
*
* @return bool true if it exist
* @since 3.2.0
**/
**/
public function exist(string $method): bool
{
return $this->options[$method] ?? false;
return is_string($this->getClassName($method)) ?? false;
}
/**
* Get crypto class name to use
*
* @param string $method The encryption method to find
*
* @return string|null The crypto class name
* @since 3.2.0
**/
private function getClassName(string $method): ?string
{
if (($name = $this->getClassNameFromRegistry($method)) !== null)
{
return $name;
}
return $this->getClassNameFromOptions($method);
}
/**
* Get the crypto class name from the registry
*
* @param string $method The encryption method to use
*
* @return string|null The crypto class name, or null if not found
* @since 3.2.0
**/
private function getClassNameFromRegistry(string $method): ?string
{
$name = $this->name($method);
if (isset($this->{$name}) && $this->{$name} instanceof Cryptinterface)
{
return $name;
}
return null;
}
/**
* Get the crypto class name for the given encryption method and options
*
* @param string $method The encryption method to use
*
* @return string|null The crypto class name, or null if not found
* @since 3.2.0
**/
private function getClassNameFromOptions(string $method): ?string
{
$key = $this->getPasswordKey($method);
if (isset($this->options[$key]))
{
$name = $this->options[$key];
if (isset($this->{$name}) && $this->{$name} instanceof Cryptinterface)
{
return $name;
}
}
return null;
}
/**
* Get the password
*
* @param string $method The encryption method to find
* @param string|null $default The default password
* @param string $method The encryption method to find
* @param string|null $password The password
*
* @return string|null the password or null
* @since 3.2.0
**/
protected function getPassword(string $method, ?string $default = null): ?string
private function getPassword(string $method, ?string $password = null): ?string
{
if ($this->exist($method))
if (StringHelper::check($password))
{
if (empty($this->passwords[$method]))
{
$this->passwords[$method] = $this->password->get($method, $default);
}
return $this->passwords[$method];
return $password;
}
return null;
// get password key name
$key = $this->getPasswordKey($method);
if (empty($this->passwords[$key]))
{
$this->passwords[$key] = $this->password->get($key);
}
return $this->passwords[$key];
}
/**
* Get the key
*
* @param string $method The encryption method to find
*
* @return string the password key name
* @since 3.2.0
**/
private function getPasswordKey(string $method): string
{
if (($pos = strpos($method, '.')) !== false)
{
return substr($method, 0, $pos);
}
return $method;
}
/**
* Get the class name
*
* @param string $method The encryption method to find
*
* @return string the class name
* @since 3.2.0
**/
private function name(string $method): string
{
if (($pos = strpos($method, '.')) !== false)
{
return substr($method, $pos + 1);
}
return $method;
}
}

View File

@ -0,0 +1,131 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Crypt;
use phpseclib3\Crypt\AES as BASEAES;
use VDM\Joomla\Componentbuilder\Crypt\Random;
use VDM\Joomla\Componentbuilder\Interfaces\Cryptinterface;
/**
* Class for Aes Encryption
*
* @since 3.2.0
*/
class Aes implements Cryptinterface
{
/**
* The Aes class
*
* @var BASEAES
* @since 3.2.0
*/
protected BASEAES $aes;
/**
* The Random class
*
* @var Random
* @since 3.2.0
*/
protected Random $random;
/**
* The block size
*
* @var int
* @since 3.2.0
*/
protected int $size = 256;
/**
* Constructor
*
* @param BASEAES $aes The Aes class
* @param Random $random The Random class
*
* @since 3.2.0
*/
public function __construct(BASEAES $aes, Random $random)
{
$this->aes = $aes;
$this->random = $random;
// we set the length once
$this->aes->setKeyLength($this->size);
// enable padding
$this->aes->enablePadding();
}
/**
* Encrypt a string as needed
*
* @param string $string The string to encrypt
* @param string $key The encryption key
*
* @return string
* @since 3.2.0
**/
public function encrypt(string $string, string $key): string
{
// we get the IV length
$iv_length = (int) $this->aes->getBlockLength() >> 3;
// get the IV value
$iv = $this->random::string($iv_length);
// Load the IV
$this->aes->setIV($iv);
// set the password
$this->aes->setPassword($key, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt');
// encrypt the string, and base 64 encode the result
return base64_encode($iv . $this->aes->encrypt($string));
}
/**
* Decrypt a string as needed
*
* @param string $string The string to decrypt
* @param string $key The decryption key
*
* @return string
* @since 3.2.0
**/
public function decrypt(string $string, string $key): string
{
// we get the IV length
$iv_length = (int) $this->aes->getBlockLength() >> 3;
// remove base 64 encoding
$string = base64_decode($string);
// get the IV
$iv = substr($string, 0, $iv_length);
// remove the IV
$string = substr($string, $iv_length);
// set the IV
$this->aes->setIV($iv);
// set the password
$this->aes->setPassword($key, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt');
return $this->aes->decrypt($string);
}
}

View File

@ -0,0 +1,117 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Crypt\Aes;
use phpseclib3\Crypt\AES as BASEAES;
use VDM\Joomla\Componentbuilder\Interfaces\Cryptinterface;
/**
* Legacy Class for Aes Encryption
*
* @since 3.2.0
*/
class Legacy implements Cryptinterface
{
/**
* The Aes class
*
* @var BASEAES
* @since 3.2.0
*/
protected BASEAES $aes;
/**
* The block size
*
* @var int
* @since 3.2.0
*/
protected int $size = 128;
/**
* Constructor
*
* @param BASEAES $aes The Aes class
*
* @since 3.2.0
*/
public function __construct(BASEAES $aes)
{
$this->aes = $aes;
// we set the length once
$this->aes->setKeyLength($this->size);
// enable padding
$this->aes->enablePadding();
}
/**
* Encrypt a string as needed
*
* @param string $string The string to encrypt
* @param string $key The encryption key
*
* @return string
* @since 3.2.0
**/
public function encrypt(string $string, string $key): string
{
// we get the IV length
$iv_length = (int) $this->aes->getBlockLength() >> 3;
// get the IV value
$iv = str_repeat("\0", $iv_length);
// Load the IV
$this->aes->setIV($iv);
// set the password
$this->aes->setPassword($key, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt');
// encrypt the string, and base 64 encode the result
return base64_encode($this->aes->encrypt($string));
}
/**
* Decrypt a string as needed
*
* @param string $string The string to decrypt
* @param string $key The decryption key
*
* @return string
* @since 3.2.0
**/
public function decrypt(string $string, string $key): string
{
// remove base 64 encoding
$string = base64_decode($string);
// we get the IV length
$iv_length = (int) $this->aes->getBlockLength() >> 3;
// get the IV value
$iv = str_repeat("\0", $iv_length);
// Load the IV
$this->aes->setIV($iv);
// set the password
$this->aes->setPassword($key, 'pbkdf2', 'sha256', 'VastDevelopmentMethod/salt');
return $this->aes->decrypt($string);
}
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@ -12,6 +12,7 @@
namespace VDM\Joomla\Componentbuilder\Crypt;
use Joomla\CMS\Language\Text;
use VDM\Joomla\Utilities\Component\Helper;
@ -34,13 +35,34 @@ class Password
*/
public function get(string $type, ?string $default = null): ?string
{
if (($password = Helper::_('getCryptKey', [$type, $default])) !== null)
// we have a local key for JCB only use
if ('local' === $type)
{
return $this->local();
}
elseif (($password = Helper::_('getCryptKey', [$type, $default])) !== null)
{
return $password;
}
return $default;
}
/**
* Get the local password
*
* @return string
* @since 3.2.0
*/
private function local(): string
{
return base64_decode(
Text::sprintf(
'COM_COMPONENTBUILDER_VJRZDESSMHBTRWFIFTYTWVZEROAESFLVVXJTMTHREEJTWOIXM',
'QzdmV', '9kQ'
)
);
}
}

View File

@ -0,0 +1,281 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage encrypt
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
* @note This file has been modified by the Joomla! Project and no longer reflects the original work of its author.
*/
namespace VDM\Joomla\Componentbuilder\Package\Display;
use Joomla\CMS\Language\Text;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\ArrayHelper;
/**
* Package Display Details Class
*
* @since 3.2.0
*/
class Details
{
/**
* The Owner details template
*
* @var array
* @since 3.2.0
*/
private array $owner = [
'company' => 'COM_COMPONENTBUILDER_DTCOMPANYDTDDSDD',
'owner' => 'COM_COMPONENTBUILDER_DTOWNERDTDDSDD',
'email' => 'COM_COMPONENTBUILDER_DTEMAILDTDDSDD',
'website' => 'COM_COMPONENTBUILDER_DTWEBSITEDTDDSDD',
'license' => 'COM_COMPONENTBUILDER_DTLICENSEDTDDSDD',
'copyright' => 'COM_COMPONENTBUILDER_DTCOPYRIGHTDTDDSDD'
];
/**
* The Component details template
*
* @var array
* @since 3.2.0
*/
private array $component = [
'ul' => [
'companyname' => 'COM_COMPONENTBUILDER_ICOMPANYI_BSB',
'author' => 'COM_COMPONENTBUILDER_IAUTHORI_BSB',
'email' => 'COM_COMPONENTBUILDER_IEMAILI_BSB',
'website' => 'COM_COMPONENTBUILDER_IWEBSITEI_BSB',
],
'other' => [
'license' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERLICENSEHFOURPSP',
'copyright' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERCOPYRIGHTHFOURPSP'
]
];
/**
* get the JCB package owner details display
*
* @param array $info The package info object
* @param bool $trust The trust switch
*
* @return string
* @since 3.2.0
**/
public function owner(array $info, $trust = false): string
{
$hasOwner = false;
$ownerDetails = '<h2 class="module-title nav-header">' . Text::_('COM_COMPONENTBUILDER_PACKAGE_OWNER_DETAILS') . '</h2>';
$ownerDetails .= '<dl class="uk-description-list-horizontal">';
// load the list items
foreach ($this->owner as $key => $dd)
{
if ($value = $this->getInfoValue($key, $info))
{
$ownerDetails .= Text::sprintf($dd, $value);
// check if we have a owner/source name
if (('owner' === $key || 'company' === $key) && !$hasOwner)
{
$hasOwner = true;
$owner = $value;
}
}
}
$ownerDetails .= '</dl>';
// provide some details to how the user can get a key
if ($hasOwner && isset($info['getKeyFrom']['buy_link']) && StringHelper::check($info['getKeyFrom']['buy_link']))
{
$ownerDetails .= '<hr />';
$ownerDetails .= Text::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROMB_A_SSA', 'class="btn btn-primary" href="' . $info['getKeyFrom']['buy_link'] . '" target="_blank" title="get a key from ' . $owner . '"', $owner);
}
// add more custom links
elseif ($hasOwner && isset($info['getKeyFrom']['buy_links']) && ArrayHelper::check($info['getKeyFrom']['buy_links']))
{
$buttons = array();
foreach ($info['getKeyFrom']['buy_links'] as $keyName => $link)
{
$buttons[] = Text::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROM_SB_FOR_A_SSA', $owner, 'class="btn btn-primary" href="' . $link . '" target="_blank" title="get a key from ' . $owner . '"', $keyName);
}
$ownerDetails .= '<hr />';
$ownerDetails .= implode('<br />', $buttons);
}
// return the owner details
if (!$hasOwner)
{
$ownerDetails = '<h2>' . Text::_('COM_COMPONENTBUILDER_PACKAGE_OWNER_DETAILS_NOT_FOUND') . '</h2>';
if (!$trust)
{
$ownerDetails .= '<p style="color: #922924;">' . Text::_('COM_COMPONENTBUILDER_BE_CAUTIOUS_DO_NOT_CONTINUE_UNLESS_YOU_TRUST_THE_ORIGIN_OF_THIS_PACKAGE') . '</p>';
}
}
return '<div>'.$ownerDetails.'</div>';
}
/**
* Check if info details has owner values set
*
* @param array $info The package info object
*
* @return bool
* @since 3.2.0
**/
public function hasOwner(array &$info): bool
{
if ($this->getInfoValue('owner', $info) || $this->getInfoValue('company', $info))
{
return true;
}
return false;
}
/**
* get the JCB package components details display
*
* @param array $info The package info object
*
* @return string
* @since 3.2.0
**/
public function components(array &$info): string
{
// check if these components need a key
$needKey = $this->hasKey($info);
if (isset($info['name']) && ArrayHelper::check($info['name']))
{
$cAmount = count((array) $info['name']);
$class2 = ($cAmount == 1) ? 'span12' : 'span6';
$counter = 1;
$display = array();
foreach ($info['name'] as $key => $value)
{
// set the name
$name = $value . ' v' . $info['component_version'][$key];
if ($cAmount > 1 && $counter == 3)
{
$display[] = '</div>';
$counter = 1;
}
if ($cAmount > 1 && $counter == 1)
{
$display[] = '<div>';
}
$display[] = '<div class="well well-small ' . $class2 . '">';
$display[] = '<h3>';
$display[] = $name;
if ($needKey)
{
$display[] = ' - <em>' . Text::sprintf('COM_COMPONENTBUILDER_PAIDLOCKED') . '</em>';
}
else
{
$display[] = ' - <em>' . Text::sprintf('COM_COMPONENTBUILDER_FREEOPEN') . '</em>';
}
$display[] = '</h3><h4>';
$display[] = $info['short_description'][$key];
$display[] = '</h4>';
$display[] = '<ul class="uk-list uk-list-striped">';
// load the list items
foreach ($this->component['ul'] as $li => $value)
{
if (isset($info[$li]) && isset($info[$li][$key]))
{
$display[] = '<li>'.Text::sprintf($value, $info[$li][$key]).'</li>';
}
}
$display[] = '</ul>';
// if we have a source link we add it
if (isset($info['joomla_source_link']) && ArrayHelper::check($info['joomla_source_link']) && isset($info['joomla_source_link'][$key]) && StringHelper::check($info['joomla_source_link'][$key]))
{
$display[] = '<a class="uk-button uk-button-mini uk-width-1-1 uk-margin-small-bottom" href="' .
$info['joomla_source_link'][$key] . '" target="_blank" title="' . Text::_('COM_COMPONENTBUILDER_SOURCE_CODE_FOR_JOOMLA_COMPONENT') . ' ('. $name . ')">' . Text::_('COM_COMPONENTBUILDER_SOURCE_CODE') . '</a>';
}
// load other
foreach ($this->component['other'] as $other => $value)
{
if (isset($info[$other]) && isset($info[$other][$key]))
{
$display[] = Text::sprintf($value, $info[$other][$key]);
}
}
$display[] = '</div>';
$counter++;
}
// close the div if needed
if ($cAmount > 1)
{
$display[] = '</div>';
}
return implode(PHP_EOL, $display);
}
return '<div>' . Text::_('COM_COMPONENTBUILDER_NO_COMPONENT_DETAILS_FOUND_SO_IT_IS_NOT_SAFE_TO_CONTINUE') . '</div>';
}
/**
* get the value from INFO array
*
* @param string $key The value key
* @param array $info The package info object
*
* @return string|null
* @since 3.2.0
**/
private function getInfoValue(string $key, array &$info): ?string
{
$source = (isset($info['source']) && isset($info['source'][$key])) ? 'source' : ((isset($info['getKeyFrom']) && isset($info['getKeyFrom'][$key])) ? 'getKeyFrom' : null);
if ($source && StringHelper::check($info[$source][$key]))
{
return $info[$source][$key];
}
return null;
}
/**
* Check if the JCB package has a key
*
* @param array $info The package info object
*
* @return bool
* @since 3.2.0
**/
private function hasKey(array &$info): bool
{
// check the package key status
if (!isset($info['key']))
{
if (isset($info['getKeyFrom']) && isset($info['getKeyFrom']['owner']))
{
// has a key
$info['key'] = true;
}
else
{
// does not have a key
$info['key'] = false;
}
}
return (bool) $info['key'];
}
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@ -16,6 +16,7 @@ use Joomla\DI\Container;
use VDM\Joomla\Componentbuilder\Service\Crypt;
use VDM\Joomla\Componentbuilder\Package\Service\Database;
use VDM\Joomla\Componentbuilder\Service\Server;
use VDM\Joomla\Componentbuilder\Package\Service\Display;
use VDM\Joomla\Componentbuilder\Interfaces\FactoryInterface;
@ -74,7 +75,8 @@ abstract class Factory implements FactoryInterface
return (new Container())
->registerServiceProvider(new Database())
->registerServiceProvider(new Crypt())
->registerServiceProvider(new Server());
->registerServiceProvider(new Server())
->registerServiceProvider(new Display());
}
}

View File

@ -0,0 +1,55 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Package\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use VDM\Joomla\Componentbuilder\Package\Display\Details;
/**
* Display Service Provider
*
* @since 3.2.0
*/
class Display implements ServiceProviderInterface
{
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
* @since 3.2.0
*/
public function register(Container $container)
{
$container->alias(Details::class, 'Display.Details')
->share('Display.Details', [$this, 'getDetails'], true);
}
/**
* Get the Display Details
*
* @param Container $container The DI container.
*
* @return Details
* @since 3.2.0
*/
public function getDetails(Container $container): Details
{
return new Details();
}
}

View File

@ -15,6 +15,7 @@ namespace VDM\Joomla\Componentbuilder\Server;
use Joomla\CMS\Client\FtpClient;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Serverinterface;
@ -39,7 +40,7 @@ class Ftp implements Serverinterface
* @var object
* @since 3.2.0
**/
protected object $details;
protected ?object $details = null;
/**
* set the server details
@ -51,8 +52,15 @@ class Ftp implements Serverinterface
**/
public function set(object $details): Ftp
{
// set the details
$this->details = $details;
// we need to make sure the if the details changed to get a new server client
if (!ObjectHelper::equal($details, $this->details))
{
// set the details
$this->details = $details;
// reset the client if it was set before
$this->client = null;
}
return $this;
}

View File

@ -16,6 +16,7 @@ use phpseclib3\Net\SFTP as SftpClient;
use VDM\Joomla\Componentbuilder\Crypt\KeyLoader;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\FileHelper;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Serverinterface;
@ -48,7 +49,7 @@ class Sftp implements Serverinterface
* @var object
* @since 3.2.0
**/
protected object $details;
protected ?object $details = null;
/**
* Constructor
@ -72,8 +73,15 @@ class Sftp implements Serverinterface
**/
public function set(object $details): Sftp
{
// set the details
$this->details = $details;
// we need to make sure the if the details changed to get a new server client
if (!ObjectHelper::equal($details, $this->details))
{
// set the details
$this->details = $details;
// reset the client if it was set before
$this->client = null;
}
return $this;
}

View File

@ -14,14 +14,14 @@ namespace VDM\Joomla\Componentbuilder\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use phpseclib3\Crypt\AES;
use phpseclib3\Crypt\Rijndael;
use phpseclib3\Crypt\DES;
use phpseclib3\Crypt\AES as BASEAES;
use VDM\Joomla\Componentbuilder\Crypt as Crypto;
use VDM\Joomla\Componentbuilder\Crypt\KeyLoader;
use VDM\Joomla\Componentbuilder\Crypt\Random;
use VDM\Joomla\Componentbuilder\Crypt\Password;
use VDM\Joomla\Componentbuilder\Crypt\FOF;
use VDM\Joomla\Componentbuilder\Crypt\Aes;
use VDM\Joomla\Componentbuilder\Crypt\Aes\Legacy;
/**
@ -50,45 +50,20 @@ class Crypt implements ServiceProviderInterface
$container->alias(Password::class, 'Crypt.Password')
->share('Crypt.Password', [$this, 'getPassword'], true);
$container->alias(FOF::class, 'Crypt.FOF')
->share('Crypt.FOF', [$this, 'getFOF'], true);
$container->alias(KeyLoader::class, 'Crypt.Key')
->share('Crypt.Key', [$this, 'getKeyLoader'], true);
$container->alias(AES::class, 'Crypt.AES')
->share('Crypt.AES', [$this, 'getAesCBC'], true)
->share('Crypt.AES.CBC', [$this, 'getAesCBC'], true)
->share('Crypt.AES.CTR', [$this, 'getAesCTR'], true)
->share('Crypt.AES.ECB', [$this, 'getAesECB'], true)
->share('Crypt.AES.CBC3', [$this, 'getAesCBC3'], true)
->share('Crypt.AES.CFB', [$this, 'getAesCFB'], true)
->share('Crypt.AES.CFB8', [$this, 'getAesCFB8'], true)
->share('Crypt.AES.OFB', [$this, 'getAesOFB'], true)
->share('Crypt.AES.GCM', [$this, 'getAesGCM'], true);
$container->alias(BASEAES::class, 'Crypt.AESCBC')
->share('Crypt.AESCBC', [$this, 'getBASEAESCBC'], false);
$container->alias(Rijndael::class, 'Crypt.Rijndael')
->share('Crypt.Rijndael', [$this, 'getRijndaelCBC'], true)
->share('Crypt.Rijndael.CBC', [$this, 'getRijndaelCBC'], true)
->share('Crypt.Rijndael.CTR', [$this, 'getRijndaelCTR'], true)
->share('Crypt.Rijndael.ECB', [$this, 'getRijndaelECB'], true)
->share('Crypt.Rijndael.CBC3', [$this, 'getRijndaelCBC3'], true)
->share('Crypt.Rijndael.CFB', [$this, 'getRijndaelCFB'], true)
->share('Crypt.Rijndael.CFB8', [$this, 'getRijndaelCFB8'], true)
->share('Crypt.Rijndael.OFB', [$this, 'getRijndaelOFB'], true)
->share('Crypt.Rijndael.GCM', [$this, 'getRijndaelGCM'], true);
$container->alias(FOF::class, 'Crypt.FOF')
->share('Crypt.FOF', [$this, 'getFOF'], true);
$container->alias(DES::class, 'Crypt.DES')
->share('Crypt.DES', [$this, 'getDesCBC'], true)
->share('Crypt.DES.CBC', [$this, 'getDesCBC'], true)
->share('Crypt.DES.CTR', [$this, 'getDesCTR'], true)
->share('Crypt.DES.ECB', [$this, 'getDesECB'], true)
->share('Crypt.DES.CBC3', [$this, 'getDesCBC3'], true)
->share('Crypt.DES.CFB', [$this, 'getDesCFB'], true)
->share('Crypt.DES.CFB8', [$this, 'getDesCFB8'], true)
->share('Crypt.DES.OFB', [$this, 'getDesOFB'], true)
->share('Crypt.DES.GCM', [$this, 'getDesGCM'], true)
->share('Crypt.DES.STREAM', [$this, 'getDesSTREAM'], true);
$container->alias(Aes::class, 'Crypt.AES.CBC')
->share('Crypt.AES.CBC', [$this, 'getAesCBC'], true);
$container->alias(Legacy::class, 'Crypt.AES.LEGACY')
->share('Crypt.AES.LEGACY', [$this, 'getAesLEGACY'], true);
}
/**
@ -103,6 +78,8 @@ class Crypt implements ServiceProviderInterface
{
return new Crypto(
$container->get('Crypt.FOF'),
$container->get('Crypt.AES.CBC'),
$container->get('Crypt.AES.LEGACY'),
$container->get('Crypt.Password')
);
}
@ -133,22 +110,6 @@ class Crypt implements ServiceProviderInterface
return new Random();
}
/**
* Get the FOF AES Cyper with CBC mode
*
* @param Container $container The DI container.
*
* @return FOF
* @since 3.2.0
*/
public function getFOF(Container $container): FOF
{
return new FOF(
$container->get('Crypt.AES.CBC'),
$container->get('Crypt.Random')
);
}
/**
* Get the KeyLoader class
*
@ -167,324 +128,59 @@ class Crypt implements ServiceProviderInterface
*
* @param Container $container The DI container.
*
* @return AES
* @return BASEAES
* @since 3.2.0
*/
public function getAesCBC(Container $container): AES
public function getBASEAESCBC(Container $container): BASEAES
{
return new AES('cbc');
return new BASEAES('cbc');
}
/**
* Get the AES Cyper with CTR mode
* Get the Wrapper AES Cyper with CBC mode
*
* @param Container $container The DI container.
*
* @return AES
* @return Aes
* @since 3.2.0
*/
public function getAesCTR(Container $container): AES
public function getAesCBC(Container $container): Aes
{
return new AES('ctr');
return new Aes(
$container->get('Crypt.AESCBC'),
$container->get('Crypt.Random')
);
}
/**
* Get the AES Cyper with ECB mode
* Get the Wrapper AES Legacy Cyper with CBC mode
*
* @param Container $container The DI container.
*
* @return AES
* @return Legacy
* @since 3.2.0
*/
public function getAesECB(Container $container): AES
public function getAesLEGACY(Container $container): Legacy
{
return new AES('ecb');
return new Legacy(
$container->get('Crypt.AESCBC')
);
}
/**
* Get the AES Cyper with CBC3 mode
* Get the FOF AES Cyper with CBC mode
*
* @param Container $container The DI container.
*
* @return AES
* @return FOF
* @since 3.2.0
*/
public function getAesCBC3(Container $container): AES
public function getFOF(Container $container): FOF
{
return new AES('cbc3');
}
/**
* Get the AES Cyper with CFB mode
*
* @param Container $container The DI container.
*
* @return AES
* @since 3.2.0
*/
public function getAesCFB(Container $container): AES
{
return new AES('cfb');
}
/**
* Get the AES Cyper with CFB8 mode
*
* @param Container $container The DI container.
*
* @return AES
* @since 3.2.0
*/
public function getAesCFB8(Container $container): AES
{
return new AES('cfb8');
}
/**
* Get the AES Cyper with OFB mode
*
* @param Container $container The DI container.
*
* @return AES
* @since 3.2.0
*/
public function getAesOFB(Container $container): AES
{
return new AES('ofb');
}
/**
* Get the AES Cyper with GCM mode
*
* @param Container $container The DI container.
*
* @return AES
* @since 3.2.0
*/
public function getAesGCM(Container $container): AES
{
return new AES('gcm');
}
/**
* Get the Rijndael Cyper with CBC mode
*
* @param Container $container The DI container.
*
* @return Rijndael
* @since 3.2.0
*/
public function getRijndaelCBC(Container $container): Rijndael
{
return new Rijndael('cbc');
}
/**
* Get the Rijndael Cyper with CTR mode
*
* @param Container $container The DI container.
*
* @return Rijndael
* @since 3.2.0
*/
public function getRijndaelCTR(Container $container): Rijndael
{
return new Rijndael('ctr');
}
/**
* Get the Rijndael Cyper with ECB mode
*
* @param Container $container The DI container.
*
* @return Rijndael
* @since 3.2.0
*/
public function getRijndaelECB(Container $container): Rijndael
{
return new Rijndael('ecb');
}
/**
* Get the Rijndael Cyper with CBC3 mode
*
* @param Container $container The DI container.
*
* @return Rijndael
* @since 3.2.0
*/
public function getRijndaelCBC3(Container $container): Rijndael
{
return new Rijndael('cbc3');
}
/**
* Get the Rijndael Cyper with CFB mode
*
* @param Container $container The DI container.
*
* @return Rijndael
* @since 3.2.0
*/
public function getRijndaelCFB(Container $container): Rijndael
{
return new Rijndael('cfb');
}
/**
* Get the Rijndael Cyper with CFB8 mode
*
* @param Container $container The DI container.
*
* @return Rijndael
* @since 3.2.0
*/
public function getRijndaelCFB8(Container $container): Rijndael
{
return new Rijndael('cfb8');
}
/**
* Get the Rijndael Cyper with OFB mode
*
* @param Container $container The DI container.
*
* @return Rijndael
* @since 3.2.0
*/
public function getRijndaelOFB(Container $container): Rijndael
{
return new Rijndael('ofb');
}
/**
* Get the Rijndael Cyper with GCM mode
*
* @param Container $container The DI container.
*
* @return Rijndael
* @since 3.2.0
*/
public function getRijndaelGCM(Container $container): Rijndael
{
return new Rijndael('gcm');
}
/**
* Get the DES Cyper with CBC mode
*
* @param Container $container The DI container.
*
* @return DES
* @since 3.2.0
*/
public function getDesCBC(Container $container): DES
{
return new DES('cbc');
}
/**
* Get the DES Cyper with CTR mode
*
* @param Container $container The DI container.
*
* @return DES
* @since 3.2.0
*/
public function getDesCTR(Container $container): DES
{
return new DES('ctr');
}
/**
* Get the DES Cyper with ECB mode
*
* @param Container $container The DI container.
*
* @return DES
* @since 3.2.0
*/
public function getDesECB(Container $container): DES
{
return new DES('ecb');
}
/**
* Get the DES Cyper with CBC3 mode
*
* @param Container $container The DI container.
*
* @return DES
* @since 3.2.0
*/
public function getDesCBC3(Container $container): DES
{
return new DES('cbc3');
}
/**
* Get the DES Cyper with CFB mode
*
* @param Container $container The DI container.
*
* @return DES
* @since 3.2.0
*/
public function getDesCFB(Container $container): DES
{
return new DES('cfb');
}
/**
* Get the DES Cyper with CFB8 mode
*
* @param Container $container The DI container.
*
* @return DES
* @since 3.2.0
*/
public function getDesCFB8(Container $container): DES
{
return new DES('cfb8');
}
/**
* Get the DES Cyper with OFB mode
*
* @param Container $container The DI container.
*
* @return DES
* @since 3.2.0
*/
public function getDesOFB(Container $container): DES
{
return new DES('ofb');
}
/**
* Get the DES Cyper with GCM mode
*
* @param Container $container The DI container.
*
* @return DES
* @since 3.2.0
*/
public function getDesGCM(Container $container): DES
{
return new DES('gcm');
}
/**
* Get the DES Cyper with STREAM mode
*
* @param Container $container The DI container.
*
* @return DES
* @since 3.2.0
*/
public function getDesSTREAM(Container $container): DES
{
return new DES('stream');
return new FOF(
$container->get('Crypt.AESCBC'),
$container->get('Crypt.Random')
);
}
}

View File

@ -37,6 +37,42 @@ abstract class ObjectHelper
return false;
}
/**
* Compare two objects for equality based on their property values.
*
* Note that this method works only for simple objects that don't
* contain any nested objects or resource references. If you need
* to compare more complex objects, you may need to use a
* more advanced method such as serialization or reflection.
*
* @param object|null $obj1 The first object to compare.
* @param object|null $obj2 The second object to compare.
*
* @return bool True if the objects have the same key-value pairs and false otherwise.
*/
public static function equal(?object $obj1, ?object $obj2): bool
{
// if any is null we return false as that means there is a none object
// we are not comparing null but objects
// but we allow null as some objects while
// not instantiate are still null
if (is_null($obj1) || is_null($obj2))
{
return false;
}
// Convert the objects to arrays of their property values using get_object_vars.
$array1 = get_object_vars($obj1);
$array2 = get_object_vars($obj2);
// Compare the arrays using array_diff_assoc to detect any differences.
$diff1 = array_diff_assoc($array1, $array2);
$diff2 = array_diff_assoc($array2, $array1);
// If the arrays have the same key-value pairs, they will have no differences, so return true.
return empty($diff1) && empty($diff2);
}
}

View File

@ -392,11 +392,12 @@ abstract class StringHelper
/**
* Random Key
*
* @input int $size The size of the random string
*
* @returns a string
*
* @since 3.0.9
*/
public static function random($size): string
public static function random(int $size): string
{
$bag = "abcefghijknopqrstuwxyzABCDDEFGHIJKLLMMNOPQRSTUVVWXYZabcddefghijkllmmnopqrstuvvwxyzABCEFGHIJKNOPQRSTUWXYZ";
$key = [];

View File

@ -2590,11 +2590,11 @@ abstract class SymmetricKey
$length = ord($text[strlen($text) - 1]);
if (!$length) {
// temp fix for FOFEncryptAes conversions
// Added by Llewellyn van der Merwe <joomla@vdm.io>
return rtrim($text, "\0");
// temp fix for FOFEncryptAes conversions
// Added by Llewellyn van der Merwe <joomla@vdm.io>
return rtrim($text);
} elseif ($length > $this->block_size) {
throw new BadDecryptionException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})");
throw new BadDecryptionException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})");
}
return substr($text, 0, -$length);