diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..4b3694ba
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,3 @@
+# These are supported funding model platforms
+
+patreon: tcoding
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..98f1e2b1
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "composer"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 00000000..5c11b93a
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,17 @@
+name: Deploy to WordPress.org
+on:
+ push:
+ tags:
+ - "*"
+jobs:
+ tag:
+ name: New tag
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@master
+ - name: WordPress Plugin Deploy
+ uses: 10up/action-wordpress-plugin-deploy@stable
+ env:
+ SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
+ SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
+ SLUG: jwt-authentication-for-wp-rest-api
\ No newline at end of file
diff --git a/.github/workflows/trunk.yml b/.github/workflows/trunk.yml
new file mode 100644
index 00000000..46100262
--- /dev/null
+++ b/.github/workflows/trunk.yml
@@ -0,0 +1,18 @@
+name: Plugin asset/readme update
+on:
+ push:
+ branches:
+ - trunk
+jobs:
+ trunk:
+ name: Push to trunk
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@master
+ - name: WordPress.org plugin asset/readme update
+ uses: 10up/action-wordpress-plugin-asset-update@stable
+ env:
+ SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
+ SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
+ SLUG: jwt-authentication-for-wp-rest-api
+ IGNORE_OTHER_FILES: true
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..0579dfc4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.vscode
+.DS_Store
+includes/vendor/bin
+includes/vendor/dealerdirect
+includes/vendor/squizlabs
+includes/vendor/wp-coding-standards
diff --git a/.wordpress-org/banner-772x250.jpg b/.wordpress-org/banner-772x250.jpg
new file mode 100644
index 00000000..d71a68a1
Binary files /dev/null and b/.wordpress-org/banner-772x250.jpg differ
diff --git a/.wordpress-org/banner.psd b/.wordpress-org/banner.psd
new file mode 100644
index 00000000..4c12815a
Binary files /dev/null and b/.wordpress-org/banner.psd differ
diff --git a/.wordpress-org/icon.svg b/.wordpress-org/icon.svg
new file mode 100644
index 00000000..ca13697b
--- /dev/null
+++ b/.wordpress-org/icon.svg
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index ce233d87..00e9e5d8 100644
--- a/README.md
+++ b/README.md
@@ -16,11 +16,11 @@ So, to use the **wp-api-jwt-auth** you need to install and activate [WP REST API
**Minimum PHP version: 5.3.0**
-### Eable PHP HTTP Authorization Header
+### Enable PHP HTTP Authorization Header
#### Shared Hosts
-Most of the shared hosts have disabled the **HTTP Authorization Header** by default.
+Most shared hosts have disabled the **HTTP Authorization Header** by default.
To enable this option you'll need to edit your **.htaccess** file by adding the following:
@@ -52,7 +52,7 @@ To add the **secret key**, edit your wp-config.php file and add a new constant c
```php
-define('JWT_AUTH_SECRET_KEY', 'your-top-secrect-key');
+define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key');
```
You can use a string from here https://api.wordpress.org/secret-key/1.1/salt/
@@ -84,19 +84,19 @@ When the plugin is activated, a new namespace is added.
Also, two new endpoints are added to this namespace.
-Endpoint | HTTP Verb
---- | ---
-*/wp-json/jwt-auth/v1/token* | POST
-*/wp-json/jwt-auth/v1/token/validate* | POST
+| Endpoint | HTTP Verb |
+| ------------------------------------- | --------- |
+| */wp-json/jwt-auth/v1/token* | POST |
+| */wp-json/jwt-auth/v1/token/validate* | POST |
-##Usage
+## Usage
### /wp-json/jwt-auth/v1/token
This is the entry point for the JWT Authentication.
Validates the user credentials, *username* and *password*, and returns a token to use in a future request to the API if the authentication is correct or error if the authentication fails.
-####Sample request using AngularJS
+#### Sample request using AngularJS
```javascript
@@ -188,7 +188,7 @@ Host: server.example.com
Authorization: Bearer mF_s9.B5f-4.1JqM
```
-###Errors
+### Errors
If the token is invalid an error will be returned. Here are some samples of errors:
@@ -249,11 +249,11 @@ Valid Token Response:
}
```
-##Available Hooks
+## Available Hooks
The **wp-api-jwt-auth** is dev friendly and has five filters available to override the default settings.
-####jwt_auth_cors_allow_headers
+#### jwt_auth_cors_allow_headers
The **jwt_auth_cors_allow_headers** allows you to modify the available headers when the CORs support is enabled.
@@ -263,7 +263,7 @@ Default Value:
'Access-Control-Allow-Headers, Content-Type, Authorization'
```
-###jwt_auth_not_before
+### jwt_auth_not_before
The **jwt_auth_not_before** allows you to change the [**nbf**](https://tools.ietf.org/html/rfc7519#section-4.1.5) value before the token is created.
@@ -273,7 +273,7 @@ Default Value:
Creation time - time()
```
-###jwt_auth_expire
+### jwt_auth_expire
The **jwt_auth_expire** allows you to change the value [**exp**](https://tools.ietf.org/html/rfc7519#section-4.1.4) before the token is created.
@@ -283,7 +283,7 @@ Default Value:
time() + (DAY_IN_SECONDS * 7)
```
-###jwt_auth_token_before_sign
+### jwt_auth_token_before_sign
The **jwt_auth_token_before_sign** allows you to modify all the token data before to be encoded and signed.
@@ -304,7 +304,7 @@ $token = array(
);
```
-###jwt_auth_token_before_dispatch
+### jwt_auth_token_before_dispatch
The **jwt_auth_token_before_dispatch** allows you to modify all the response array before to dispatch it to the client.
Default value:
@@ -319,7 +319,31 @@ $data = array(
);
```
-##Credits
+### jwt_auth_algorithm
+The **jwt_auth_algorithm** allows you to modify the signing algorithm.
+
+Default value:
+
+```php
+=7.4",
+ "composer/installers": "~1.0",
+ "firebase/php-jwt": "^6.3"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "*",
+ "squizlabs/php_codesniffer": "3.*",
+ "wp-coding-standards/wpcs": "*"
+ }
}
diff --git a/composer.lock b/composer.lock
index 9dd3d1bf..ec7f0030 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,27 +1,190 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "hash": "ed805bddf241eb374d3684456d1182bf",
+ "content-hash": "d38d1c9b0671fe28649b26de42452788",
"packages": [
+ {
+ "name": "composer/installers",
+ "version": "v1.12.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/installers.git",
+ "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/installers/zipball/d20a64ed3c94748397ff5973488761b22f6d3f19",
+ "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0 || ^2.0"
+ },
+ "replace": {
+ "roundcube/plugin-installer": "*",
+ "shama/baton": "*"
+ },
+ "require-dev": {
+ "composer/composer": "1.6.* || ^2.0",
+ "composer/semver": "^1 || ^3",
+ "phpstan/phpstan": "^0.12.55",
+ "phpstan/phpstan-phpunit": "^0.12.16",
+ "symfony/phpunit-bridge": "^4.2 || ^5",
+ "symfony/process": "^2.3"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "Composer\\Installers\\Plugin",
+ "branch-alias": {
+ "dev-main": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Installers\\": "src/Composer/Installers"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kyle Robinson Young",
+ "email": "kyle@dontkry.com",
+ "homepage": "https://github.com/shama"
+ }
+ ],
+ "description": "A multi-framework Composer library installer",
+ "homepage": "https://composer.github.io/installers/",
+ "keywords": [
+ "Craft",
+ "Dolibarr",
+ "Eliasis",
+ "Hurad",
+ "ImageCMS",
+ "Kanboard",
+ "Lan Management System",
+ "MODX Evo",
+ "MantisBT",
+ "Mautic",
+ "Maya",
+ "OXID",
+ "Plentymarkets",
+ "Porto",
+ "RadPHP",
+ "SMF",
+ "Starbug",
+ "Thelia",
+ "Whmcs",
+ "WolfCMS",
+ "agl",
+ "aimeos",
+ "annotatecms",
+ "attogram",
+ "bitrix",
+ "cakephp",
+ "chef",
+ "cockpit",
+ "codeigniter",
+ "concrete5",
+ "croogo",
+ "dokuwiki",
+ "drupal",
+ "eZ Platform",
+ "elgg",
+ "expressionengine",
+ "fuelphp",
+ "grav",
+ "installer",
+ "itop",
+ "joomla",
+ "known",
+ "kohana",
+ "laravel",
+ "lavalite",
+ "lithium",
+ "magento",
+ "majima",
+ "mako",
+ "mediawiki",
+ "miaoxing",
+ "modulework",
+ "modx",
+ "moodle",
+ "osclass",
+ "pantheon",
+ "phpbb",
+ "piwik",
+ "ppi",
+ "processwire",
+ "puppet",
+ "pxcms",
+ "reindex",
+ "roundcube",
+ "shopware",
+ "silverstripe",
+ "sydes",
+ "sylius",
+ "symfony",
+ "tastyigniter",
+ "typo3",
+ "wordpress",
+ "yawik",
+ "zend",
+ "zikula"
+ ],
+ "support": {
+ "issues": "https://github.com/composer/installers/issues",
+ "source": "https://github.com/composer/installers/tree/v1.12.0"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com/",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-09-13T08:19:44+00:00"
+ },
{
"name": "firebase/php-jwt",
- "version": "v3.0.0",
+ "version": "v6.4.0",
"source": {
"type": "git",
"url": "https://github.com/firebase/php-jwt.git",
- "reference": "fa8a06e96526eb7c0eeaa47e4f39be59d21f16e1"
+ "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/firebase/php-jwt/zipball/fa8a06e96526eb7c0eeaa47e4f39be59d21f16e1",
- "reference": "fa8a06e96526eb7c0eeaa47e4f39be59d21f16e1",
+ "url": "https://api.github.com/repos/firebase/php-jwt/zipball/4dd1e007f22a927ac77da5a3fbb067b42d3bc224",
+ "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": "^7.1||^8.0"
+ },
+ "require-dev": {
+ "guzzlehttp/guzzle": "^6.5||^7.4",
+ "phpspec/prophecy-phpunit": "^1.1",
+ "phpunit/phpunit": "^7.5||^9.5",
+ "psr/cache": "^1.0||^2.0",
+ "psr/http-client": "^1.0",
+ "psr/http-factory": "^1.0"
+ },
+ "suggest": {
+ "ext-sodium": "Support EdDSA (Ed25519) signatures",
+ "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
},
"type": "library",
"autoload": {
@@ -47,15 +210,213 @@
],
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
- "time": "2015-07-22 18:31:08"
+ "keywords": [
+ "jwt",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/firebase/php-jwt/issues",
+ "source": "https://github.com/firebase/php-jwt/tree/v6.4.0"
+ },
+ "time": "2023-02-09T21:01:23+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "dealerdirect/phpcodesniffer-composer-installer",
+ "version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPCSStandards/composer-installer.git",
+ "reference": "4be43904336affa5c2f70744a348312336afd0da"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da",
+ "reference": "4be43904336affa5c2f70744a348312336afd0da",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0 || ^2.0",
+ "php": ">=5.4",
+ "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0"
+ },
+ "require-dev": {
+ "composer/composer": "*",
+ "ext-json": "*",
+ "ext-zip": "*",
+ "php-parallel-lint/php-parallel-lint": "^1.3.1",
+ "phpcompatibility/php-compatibility": "^9.0",
+ "yoast/phpunit-polyfills": "^1.0"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
+ },
+ "autoload": {
+ "psr-4": {
+ "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Franck Nijhof",
+ "email": "franck.nijhof@dealerdirect.com",
+ "homepage": "http://www.frenck.nl/",
+ "role": "Developer / IT Manager"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors"
+ }
+ ],
+ "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
+ "homepage": "http://www.dealerdirect.com/",
+ "keywords": [
+ "PHPCodeSniffer",
+ "PHP_CodeSniffer",
+ "code quality",
+ "codesniffer",
+ "composer",
+ "installer",
+ "phpcbf",
+ "phpcs",
+ "plugin",
+ "qa",
+ "quality",
+ "standard",
+ "standards",
+ "style guide",
+ "stylecheck",
+ "tests"
+ ],
+ "support": {
+ "issues": "https://github.com/PHPCSStandards/composer-installer/issues",
+ "source": "https://github.com/PHPCSStandards/composer-installer"
+ },
+ "time": "2023-01-05T11:28:13+00:00"
+ },
+ {
+ "name": "squizlabs/php_codesniffer",
+ "version": "3.7.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
+ "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
+ "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
+ "shasum": ""
+ },
+ "require": {
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "bin": [
+ "bin/phpcs",
+ "bin/phpcbf"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Greg Sherwood",
+ "role": "lead"
+ }
+ ],
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "keywords": [
+ "phpcs",
+ "standards",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
+ "source": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
+ },
+ "time": "2023-02-22T23:07:41+00:00"
+ },
+ {
+ "name": "wp-coding-standards/wpcs",
+ "version": "2.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
+ "reference": "7da1894633f168fe244afc6de00d141f27517b62"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7da1894633f168fe244afc6de00d141f27517b62",
+ "reference": "7da1894633f168fe244afc6de00d141f27517b62",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4",
+ "squizlabs/php_codesniffer": "^3.3.1"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || ^0.6",
+ "phpcompatibility/php-compatibility": "^9.0",
+ "phpcsstandards/phpcsdevtools": "^1.0",
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "suggest": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.6 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically."
+ },
+ "type": "phpcodesniffer-standard",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors"
+ }
+ ],
+ "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
+ "keywords": [
+ "phpcs",
+ "standards",
+ "wordpress"
+ ],
+ "support": {
+ "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues",
+ "source": "https://github.com/WordPress/WordPress-Coding-Standards",
+ "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki"
+ },
+ "time": "2020-05-13T23:57:56+00:00"
}
],
- "packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
- "platform": [],
- "platform-dev": []
+ "platform": {
+ "php": ">=7.4"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.0.0"
}
diff --git a/includes/class-jwt-auth-i18n.php b/includes/class-jwt-auth-i18n.php
index 15533116..fe9ebc27 100755
--- a/includes/class-jwt-auth-i18n.php
+++ b/includes/class-jwt-auth-i18n.php
@@ -20,40 +20,38 @@
*
* @author Enrique Chavez
*/
-class Jwt_Auth_i18n
-{
- /**
- * The domain specified for this plugin.
- *
- * @since 1.0.0
- *
- * @var string The domain identifier for this plugin.
- */
- private $domain;
+class Jwt_Auth_i18n {
+ /**
+ * The domain specified for this plugin.
+ *
+ * @since 1.0.0
+ *
+ * @var string The domain identifier for this plugin.
+ */
+ private string $domain;
- /**
- * Load the plugin text domain for translation.
- *
- * @since 1.0.0
- */
- public function load_plugin_textdomain()
- {
- load_plugin_textdomain(
- $this->domain,
- false,
- dirname(dirname(plugin_basename(__FILE__))).'/languages/'
- );
- }
+ /**
+ * Load the plugin text domain for translation.
+ *
+ * @since 1.0.0
+ */
+ public function load_plugin_textdomain() {
+ load_plugin_textdomain(
+ $this->domain,
+ false,
+ dirname( plugin_basename( __FILE__ ), 2 ) . '/languages/'
+ );
+ }
- /**
- * Set the domain equal to that of the specified domain.
- *
- * @since 1.0.0
- *
- * @param string $domain The domain that represents the locale of this plugin.
- */
- public function set_domain($domain)
- {
- $this->domain = $domain;
- }
+ /**
+ * Set the domain equal to that of the specified domain.
+ *
+ * @param string $domain The domain that represents the locale of this plugin.
+ *
+ * @since 1.0.0
+ *
+ */
+ public function set_domain( string $domain ) {
+ $this->domain = $domain;
+ }
}
diff --git a/includes/class-jwt-auth-loader.php b/includes/class-jwt-auth-loader.php
index 9884930f..519cfc23 100755
--- a/includes/class-jwt-auth-loader.php
+++ b/includes/class-jwt-auth-loader.php
@@ -16,110 +16,105 @@
*
* @author Enrique Chavez
*/
-class Jwt_Auth_Loader
-{
- /**
- * The array of actions registered with WordPress.
- *
- * @since 1.0.0
- *
- * @var array The actions registered with WordPress to fire when the plugin loads.
- */
- protected $actions;
+class Jwt_Auth_Loader {
+ /**
+ * The array of actions registered with WordPress.
+ *
+ * @since 1.0.0
+ *
+ * @var array The actions registered with WordPress to fire when the plugin loads.
+ */
+ protected array $actions;
- /**
- * The array of filters registered with WordPress.
- *
- * @since 1.0.0
- *
- * @var array The filters registered with WordPress to fire when the plugin loads.
- */
- protected $filters;
+ /**
+ * The array of filters registered with WordPress.
+ *
+ * @since 1.0.0
+ *
+ * @var array The filters registered with WordPress to fire when the plugin loads.
+ */
+ protected array $filters;
- /**
- * Initialize the collections used to maintain the actions and filters.
- *
- * @since 1.0.0
- */
- public function __construct()
- {
- $this->actions = array();
- $this->filters = array();
- }
+ /**
+ * Initialize the collections used to maintain the actions and filters.
+ *
+ * @since 1.0.0
+ */
+ public function __construct() {
+ $this->actions = [];
+ $this->filters = [];
+ }
- /**
- * Add a new action to the collection to be registered with WordPress.
- *
- * @since 1.0.0
- *
- * @param string $hook The name of the WordPress action that is being registered.
- * @param object $component A reference to the instance of the object on which the action is defined.
- * @param string $callback The name of the function definition on the $component.
- * @param int Optional $priority The priority at which the function should be fired.
- * @param int Optional $accepted_args The number of arguments that should be passed to the $callback.
- */
- public function add_action($hook, $component, $callback, $priority = 10, $accepted_args = 1)
- {
- $this->actions = $this->add($this->actions, $hook, $component, $callback, $priority, $accepted_args);
- }
+ /**
+ * Add a new action to the collection to be registered with WordPress.
+ *
+ * @param string $hook The name of the WordPress action that is being registered.
+ * @param object $component A reference to the instance of the object on which the action is defined.
+ * @param string $callback The name of the function definition on the $component.
+ * @param int $priority Optional $priority The priority at which the function should be fired.
+ * @param int $accepted_args Optional $accepted_args The number of arguments that should be passed to the $callback.
+ *
+ * @since 1.0.0
+ *
+ */
+ public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
+ $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
+ }
- /**
- * Add a new filter to the collection to be registered with WordPress.
- *
- * @since 1.0.0
- *
- * @param string $hook The name of the WordPress filter that is being registered.
- * @param object $component A reference to the instance of the object on which the filter is defined.
- * @param string $callback The name of the function definition on the $component.
- * @param int Optional $priority The priority at which the function should be fired.
- * @param int Optional $accepted_args The number of arguments that should be passed to the $callback.
- */
- public function add_filter($hook, $component, $callback, $priority = 10, $accepted_args = 1)
- {
- $this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $accepted_args);
- }
+ /**
+ * Add a new filter to the collection to be registered with WordPress.
+ *
+ * @param string $hook The name of the WordPress filter that is being registered.
+ * @param object $component A reference to the instance of the object on which the filter is defined.
+ * @param string $callback The name of the function definition on the $component.
+ * @param int $priority Optional $priority The priority at which the function should be fired.
+ * @param int $accepted_args Optional $accepted_args The number of arguments that should be passed to the $callback.
+ *
+ * @since 1.0.0
+ *
+ */
+ public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
+ $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args );
+ }
- /**
- * A utility function that is used to register the actions and hooks into a single
- * collection.
- *
- * @since 1.0.0
- *
- * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
- * @param string $hook The name of the WordPress filter that is being registered.
- * @param object $component A reference to the instance of the object on which the filter is defined.
- * @param string $callback The name of the function definition on the $component.
- * @param int Optional $priority The priority at which the function should be fired.
- * @param int Optional $accepted_args The number of arguments that should be passed to the $callback.
- *
- * @return type The collection of actions and filters registered with WordPress.
- */
- private function add($hooks, $hook, $component, $callback, $priority, $accepted_args)
- {
- $hooks[] = array(
- 'hook' => $hook,
- 'component' => $component,
- 'callback' => $callback,
- 'priority' => $priority,
- 'accepted_args' => $accepted_args,
- );
+ /**
+ * A utility function that is used to register the actions and hooks into a single
+ * collection.
+ *
+ * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
+ * @param string $hook The name of the WordPress filter that is being registered.
+ * @param object $component A reference to the instance of the object on which the filter is defined.
+ * @param string $callback The name of the function definition on the $component.
+ * @param int $priority Optional $priority The priority at which the function should be fired.
+ * @param int $accepted_args Optional $accepted_args The number of arguments that should be passed to the $callback.
+ *
+ * @since 1.0.0
+ *
+ */
+ private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ): array {
+ $hooks[] = [
+ 'hook' => $hook,
+ 'component' => $component,
+ 'callback' => $callback,
+ 'priority' => $priority,
+ 'accepted_args' => $accepted_args,
+ ];
- return $hooks;
- }
+ return $hooks;
+ }
- /**
- * Register the filters and actions with WordPress.
- *
- * @since 1.0.0
- */
- public function run()
- {
- foreach ($this->filters as $hook) {
- add_filter($hook['hook'], array($hook['component'], $hook['callback']), $hook['priority'], $hook['accepted_args']);
- }
+ /**
+ * Register the filters and actions with WordPress.
+ *
+ * @since 1.0.0
+ */
+ public function run() {
+ foreach ( $this->filters as $hook ) {
+ add_filter( $hook['hook'], [ $hook['component'], $hook['callback'] ], $hook['priority'], $hook['accepted_args'] );
+ }
- foreach ($this->actions as $hook) {
- add_action($hook['hook'], array($hook['component'], $hook['callback']), $hook['priority'], $hook['accepted_args']);
- }
- }
+ foreach ( $this->actions as $hook ) {
+ add_action( $hook['hook'], [ $hook['component'], $hook['callback'] ], $hook['priority'], $hook['accepted_args'] );
+ }
+ }
}
diff --git a/includes/class-jwt-auth.php b/includes/class-jwt-auth.php
index 70800095..433a29e6 100755
--- a/includes/class-jwt-auth.php
+++ b/includes/class-jwt-auth.php
@@ -23,172 +23,171 @@
*
* @author Enrique Chavez
*/
-class Jwt_Auth
-{
- /**
- * The loader that's responsible for maintaining and registering all hooks that power
- * the plugin.
- *
- * @since 1.0.0
- *
- * @var Jwt_Auth_Loader Maintains and registers all hooks for the plugin.
- */
- protected $loader;
-
- /**
- * The unique identifier of this plugin.
- *
- * @since 1.0.0
- *
- * @var string The string used to uniquely identify this plugin.
- */
- protected $plugin_name;
-
- /**
- * The current version of the plugin.
- *
- * @since 1.0.0
- *
- * @var string The current version of the plugin.
- */
- protected $version;
-
- /**
- * Define the core functionality of the plugin.
- *
- * Set the plugin name and the plugin version that can be used throughout the plugin.
- * Load the dependencies, define the locale, and set the hooks for the admin area and
- * the public-facing side of the site.
- *
- * @since 1.0.0
- */
- public function __construct()
- {
- $this->plugin_name = 'jwt-auth';
- $this->version = '1.0.0';
-
- $this->load_dependencies();
- $this->set_locale();
- $this->define_public_hooks();
- }
-
- /**
- * Load the required dependencies for this plugin.
- *
- * Include the following files that make up the plugin:
- *
- * - Jwt_Auth_Loader. Orchestrates the hooks of the plugin.
- * - Jwt_Auth_i18n. Defines internationalization functionality.
- * - Jwt_Auth_Admin. Defines all hooks for the admin area.
- * - Jwt_Auth_Public. Defines all hooks for the public side of the site.
- *
- * Create an instance of the loader which will be used to register the hooks
- * with WordPress.
- *
- * @since 1.0.0
- */
- private function load_dependencies()
- {
-
- /**
- * Load dependecies managed by composer.
- */
- require_once plugin_dir_path(dirname(__FILE__)).'includes/vendor/autoload.php';
-
- /**
- * The class responsible for orchestrating the actions and filters of the
- * core plugin.
- */
- require_once plugin_dir_path(dirname(__FILE__)).'includes/class-jwt-auth-loader.php';
-
- /**
- * The class responsible for defining internationalization functionality
- * of the plugin.
- */
- require_once plugin_dir_path(dirname(__FILE__)).'includes/class-jwt-auth-i18n.php';
-
- /**
- * The class responsible for defining all actions that occur in the public-facing
- * side of the site.
- */
- require_once plugin_dir_path(dirname(__FILE__)).'public/class-jwt-auth-public.php';
-
- $this->loader = new Jwt_Auth_Loader();
- }
-
- /**
- * Define the locale for this plugin for internationalization.
- *
- * Uses the Jwt_Auth_i18n class in order to set the domain and to register the hook
- * with WordPress.
- *
- * @since 1.0.0
- */
- private function set_locale()
- {
- $plugin_i18n = new Jwt_Auth_i18n();
- $plugin_i18n->set_domain($this->get_plugin_name());
- $this->loader->add_action('plugins_loaded', $plugin_i18n, 'load_plugin_textdomain');
- }
- /**
- * Register all of the hooks related to the public-facing functionality
- * of the plugin.
- *
- * @since 1.0.0
- */
- private function define_public_hooks()
- {
- $plugin_public = new Jwt_Auth_Public($this->get_plugin_name(), $this->get_version());
- $this->loader->add_action('rest_api_init', $plugin_public, 'add_api_routes');
- $this->loader->add_filter('rest_api_init', $plugin_public, 'add_cors_support');
- $this->loader->add_filter('determine_current_user', $plugin_public, 'determine_current_user', 99);
- $this->loader->add_filter( 'rest_pre_dispatch', $plugin_public, 'rest_pre_dispatch', 10, 2 );
- }
-
- /**
- * Run the loader to execute all of the hooks with WordPress.
- *
- * @since 1.0.0
- */
- public function run()
- {
- $this->loader->run();
- }
-
- /**
- * The name of the plugin used to uniquely identify it within the context of
- * WordPress and to define internationalization functionality.
- *
- * @since 1.0.0
- *
- * @return string The name of the plugin.
- */
- public function get_plugin_name()
- {
- return $this->plugin_name;
- }
-
- /**
- * The reference to the class that orchestrates the hooks with the plugin.
- *
- * @since 1.0.0
- *
- * @return Jwt_Auth_Loader Orchestrates the hooks of the plugin.
- */
- public function get_loader()
- {
- return $this->loader;
- }
-
- /**
- * Retrieve the version number of the plugin.
- *
- * @since 1.0.0
- *
- * @return string The version number of the plugin.
- */
- public function get_version()
- {
- return $this->version;
- }
+class Jwt_Auth {
+ /**
+ * The loader that's responsible for maintaining and registering all hooks that power
+ * the plugin.
+ *
+ * @since 1.0.0
+ *
+ * @var Jwt_Auth_Loader Maintains and registers all hooks for the plugin.
+ */
+ protected Jwt_Auth_Loader $loader;
+
+ /**
+ * The unique identifier of this plugin.
+ *
+ * @since 1.0.0
+ *
+ * @var string The string used to uniquely identify this plugin.
+ */
+ protected string $plugin_name;
+
+ /**
+ * The current version of the plugin.
+ *
+ * @since 1.0.0
+ *
+ * @var string The current version of the plugin.
+ */
+ protected string $version;
+
+ /**
+ * Define the core functionality of the plugin.
+ *
+ * Set the plugin name and the plugin version that can be used throughout the plugin.
+ * Load the dependencies, define the locale, and set the hooks for the admin area and
+ * the public-facing side of the site.
+ *
+ * @since 1.0.0
+ */
+ public function __construct() {
+ $this->plugin_name = 'jwt-auth';
+ $this->version = '1.3.3';
+
+ $this->load_dependencies();
+ $this->set_locale();
+ $this->define_public_hooks();
+ }
+
+ /**
+ * Load the required dependencies for this plugin.
+ *
+ * Include the following files that make up the plugin:
+ *
+ * - Jwt_Auth_Loader. Orchestrates the hooks of the plugin.
+ * - Jwt_Auth_i18n. Defines internationalization functionality.
+ * - Jwt_Auth_Admin. Defines all hooks for the admin area.
+ * - Jwt_Auth_Public. Defines all hooks for the public side of the site.
+ *
+ * Create an instance of the loader which will be used to register the hooks
+ * with WordPress.
+ *
+ * @since 1.0.0
+ */
+ private function load_dependencies() {
+
+ /**
+ * Load dependencies managed by composer.
+ */
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/vendor/autoload.php';
+
+ /**
+ * The class responsible for orchestrating the actions and filters of the
+ * core plugin.
+ */
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-jwt-auth-loader.php';
+
+ /**
+ * The class responsible for defining internationalization functionality
+ * of the plugin.
+ */
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-jwt-auth-i18n.php';
+
+ /**
+ * Class responsible for creating a `wrapper namespace` to load the Firebase's JWT & Key
+ * classes and prevent conflicts with other plugins using the same library
+ * with different versions.
+ */
+ require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-jwt-namespace-wrapper.php';
+
+ /**
+ * The class responsible for defining all actions that occur in the public-facing
+ * side of the site.
+ */
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-jwt-auth-public.php';
+
+ $this->loader = new Jwt_Auth_Loader();
+ }
+
+ /**
+ * Define the locale for this plugin for internationalization.
+ *
+ * Uses the Jwt_Auth_i18n class in order to set the domain and to register the hook
+ * with WordPress.
+ *
+ * @since 1.0.0
+ */
+ private function set_locale() {
+ $plugin_i18n = new Jwt_Auth_i18n();
+ $plugin_i18n->set_domain( $this->get_plugin_name() );
+ $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' );
+ }
+
+ /**
+ * Register all the hooks related to the public-facing functionality
+ * of the plugin.
+ *
+ * @since 1.0.0
+ */
+ private function define_public_hooks() {
+ $plugin_public = new Jwt_Auth_Public( $this->get_plugin_name(), $this->get_version() );
+ $this->loader->add_action( 'rest_api_init', $plugin_public, 'add_api_routes' );
+ $this->loader->add_filter( 'rest_api_init', $plugin_public, 'add_cors_support' );
+ $this->loader->add_filter( 'rest_pre_dispatch', $plugin_public, 'rest_pre_dispatch', 10, 2 );
+ $this->loader->add_filter( 'determine_current_user', $plugin_public, 'determine_current_user' );
+ }
+
+ /**
+ * Run the loader to execute all the hooks with WordPress.
+ *
+ * @since 1.0.0
+ */
+ public function run() {
+ $this->loader->run();
+ }
+
+ /**
+ * The name of the plugin used to uniquely identify it within the context of
+ * WordPress and to define internationalization functionality.
+ *
+ * @return string The name of the plugin.
+ * @since 1.0.0
+ *
+ */
+ public function get_plugin_name(): string {
+ return $this->plugin_name;
+ }
+
+ /**
+ * The reference to the class that orchestrates the hooks with the plugin.
+ *
+ * @return Jwt_Auth_Loader Orchestrates the hooks of the plugin.
+ * @since 1.0.0
+ *
+ */
+ public function get_loader(): Jwt_Auth_Loader {
+ return $this->loader;
+ }
+
+ /**
+ * Retrieve the version number of the plugin.
+ *
+ * @return string The version number of the plugin.
+ * @since 1.0.0
+ *
+ */
+ public function get_version(): string {
+ return $this->version;
+ }
}
diff --git a/includes/class-jwt-namespace-wrapper.php b/includes/class-jwt-namespace-wrapper.php
new file mode 100644
index 00000000..befcf088
--- /dev/null
+++ b/includes/class-jwt-namespace-wrapper.php
@@ -0,0 +1,18 @@
+
* @author Jordi Boggiano
+ * @see https://www.php-fig.org/psr/psr-0/
+ * @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
+ /** @var \Closure(string):void */
+ private static $includeFile;
+
+ /** @var ?string */
+ private $vendorDir;
+
// PSR-4
+ /**
+ * @var array[]
+ * @psalm-var array>
+ */
private $prefixLengthsPsr4 = array();
+ /**
+ * @var array[]
+ * @psalm-var array>
+ */
private $prefixDirsPsr4 = array();
+ /**
+ * @var array[]
+ * @psalm-var array
+ */
private $fallbackDirsPsr4 = array();
// PSR-0
+ /**
+ * @var array[]
+ * @psalm-var array>
+ */
private $prefixesPsr0 = array();
+ /**
+ * @var array[]
+ * @psalm-var array
+ */
private $fallbackDirsPsr0 = array();
+ /** @var bool */
private $useIncludePath = false;
+
+ /**
+ * @var string[]
+ * @psalm-var array
+ */
private $classMap = array();
+ /** @var bool */
private $classMapAuthoritative = false;
+ /**
+ * @var bool[]
+ * @psalm-var array
+ */
+ private $missingClasses = array();
+
+ /** @var ?string */
+ private $apcuPrefix;
+
+ /**
+ * @var self[]
+ */
+ private static $registeredLoaders = array();
+
+ /**
+ * @param ?string $vendorDir
+ */
+ public function __construct($vendorDir = null)
+ {
+ $this->vendorDir = $vendorDir;
+ self::initializeIncludeClosure();
+ }
+
+ /**
+ * @return string[]
+ */
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
- return call_user_func_array('array_merge', $this->prefixesPsr0);
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
+ /**
+ * @return array[]
+ * @psalm-return array>
+ */
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
+ /**
+ * @return array[]
+ * @psalm-return array
+ */
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
+ /**
+ * @return array[]
+ * @psalm-return array
+ */
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
+ /**
+ * @return string[] Array of classname => path
+ * @psalm-return array
+ */
public function getClassMap()
{
return $this->classMap;
}
/**
- * @param array $classMap Class to filename map
+ * @param string[] $classMap Class to filename map
+ * @psalm-param array $classMap
+ *
+ * @return void
*/
public function addClassMap(array $classMap)
{
@@ -101,9 +179,11 @@ public function addClassMap(array $classMap)
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
- * @param string $prefix The prefix
- * @param array|string $paths The PSR-0 root directories
- * @param bool $prepend Whether to prepend the directories
+ * @param string $prefix The prefix
+ * @param string[]|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @return void
*/
public function add($prefix, $paths, $prepend = false)
{
@@ -146,11 +226,13 @@ public function add($prefix, $paths, $prepend = false)
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
- * @param string $prefix The prefix/namespace, with trailing '\\'
- * @param array|string $paths The PSR-0 base directories
- * @param bool $prepend Whether to prepend the directories
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param string[]|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
+ *
+ * @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
@@ -194,8 +276,10 @@ public function addPsr4($prefix, $paths, $prepend = false)
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
- * @param string $prefix The prefix
- * @param array|string $paths The PSR-0 base directories
+ * @param string $prefix The prefix
+ * @param string[]|string $paths The PSR-0 base directories
+ *
+ * @return void
*/
public function set($prefix, $paths)
{
@@ -210,10 +294,12 @@ public function set($prefix, $paths)
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
- * @param string $prefix The prefix/namespace, with trailing '\\'
- * @param array|string $paths The PSR-4 base directories
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param string[]|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
+ *
+ * @return void
*/
public function setPsr4($prefix, $paths)
{
@@ -233,6 +319,8 @@ public function setPsr4($prefix, $paths)
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
+ *
+ * @return void
*/
public function setUseIncludePath($useIncludePath)
{
@@ -255,6 +343,8 @@ public function getUseIncludePath()
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
+ *
+ * @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
@@ -271,37 +361,81 @@ public function isClassMapAuthoritative()
return $this->classMapAuthoritative;
}
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ *
+ * @return void
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
+ *
+ * @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+
+ if (null === $this->vendorDir) {
+ return;
+ }
+
+ if ($prepend) {
+ self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
+ } else {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ self::$registeredLoaders[$this->vendorDir] = $this;
+ }
}
/**
* Unregisters this instance as an autoloader.
+ *
+ * @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
+
+ if (null !== $this->vendorDir) {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ }
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
- * @return bool|null True if loaded, null otherwise
+ * @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
- includeFile($file);
+ $includeFile = self::$includeFile;
+ $includeFile($file);
return true;
}
+
+ return null;
}
/**
@@ -313,34 +447,54 @@ public function loadClass($class)
*/
public function findFile($class)
{
- // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
- if ('\\' == $class[0]) {
- $class = substr($class, 1);
- }
-
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
- if ($this->classMapAuthoritative) {
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
- if ($file === null && defined('HHVM_VERSION')) {
+ if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
- if ($file === null) {
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
// Remember that this class does not exist.
- return $this->classMap[$class] = false;
+ $this->missingClasses[$class] = true;
}
return $file;
}
+ /**
+ * Returns the currently registered loaders indexed by their corresponding vendor directories.
+ *
+ * @return self[]
+ */
+ public static function getRegisteredLoaders()
+ {
+ return self::$registeredLoaders;
+ }
+
+ /**
+ * @param string $class
+ * @param string $ext
+ * @return string|false
+ */
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
@@ -348,10 +502,14 @@ private function findFileWithExtension($class, $ext)
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
- foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
- if (0 === strpos($class, $prefix)) {
- foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath . '\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
@@ -361,7 +519,7 @@ private function findFileWithExtension($class, $ext)
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
@@ -380,7 +538,7 @@ private function findFileWithExtension($class, $ext)
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
@@ -390,7 +548,7 @@ private function findFileWithExtension($class, $ext)
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
- if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
@@ -399,15 +557,29 @@ private function findFileWithExtension($class, $ext)
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
+
+ return false;
}
-}
-/**
- * Scope isolated include.
- *
- * Prevents access to $this/self from included files.
- */
-function includeFile($file)
-{
- include $file;
+ /**
+ * @return void
+ */
+ private static function initializeIncludeClosure()
+ {
+ if (self::$includeFile !== null) {
+ return;
+ }
+
+ /**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ *
+ * @param string $file
+ * @return void
+ */
+ self::$includeFile = \Closure::bind(static function($file) {
+ include $file;
+ }, null, null);
+ }
}
diff --git a/includes/vendor/composer/InstalledVersions.php b/includes/vendor/composer/InstalledVersions.php
new file mode 100644
index 00000000..51e734a7
--- /dev/null
+++ b/includes/vendor/composer/InstalledVersions.php
@@ -0,0 +1,359 @@
+
+ * Jordi Boggiano
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer;
+
+use Composer\Autoload\ClassLoader;
+use Composer\Semver\VersionParser;
+
+/**
+ * This class is copied in every Composer installed project and available to all
+ *
+ * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
+ *
+ * To require its presence, you can require `composer-runtime-api ^2.0`
+ *
+ * @final
+ */
+class InstalledVersions
+{
+ /**
+ * @var mixed[]|null
+ * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null
+ */
+ private static $installed;
+
+ /**
+ * @var bool|null
+ */
+ private static $canGetVendors;
+
+ /**
+ * @var array[]
+ * @psalm-var array}>
+ */
+ private static $installedByVendor = array();
+
+ /**
+ * Returns a list of all package names which are present, either by being installed, replaced or provided
+ *
+ * @return string[]
+ * @psalm-return list
+ */
+ public static function getInstalledPackages()
+ {
+ $packages = array();
+ foreach (self::getInstalled() as $installed) {
+ $packages[] = array_keys($installed['versions']);
+ }
+
+ if (1 === \count($packages)) {
+ return $packages[0];
+ }
+
+ return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
+ }
+
+ /**
+ * Returns a list of all package names with a specific type e.g. 'library'
+ *
+ * @param string $type
+ * @return string[]
+ * @psalm-return list
+ */
+ public static function getInstalledPackagesByType($type)
+ {
+ $packagesByType = array();
+
+ foreach (self::getInstalled() as $installed) {
+ foreach ($installed['versions'] as $name => $package) {
+ if (isset($package['type']) && $package['type'] === $type) {
+ $packagesByType[] = $name;
+ }
+ }
+ }
+
+ return $packagesByType;
+ }
+
+ /**
+ * Checks whether the given package is installed
+ *
+ * This also returns true if the package name is provided or replaced by another package
+ *
+ * @param string $packageName
+ * @param bool $includeDevRequirements
+ * @return bool
+ */
+ public static function isInstalled($packageName, $includeDevRequirements = true)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (isset($installed['versions'][$packageName])) {
+ return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks whether the given package satisfies a version constraint
+ *
+ * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
+ *
+ * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
+ *
+ * @param VersionParser $parser Install composer/semver to have access to this class and functionality
+ * @param string $packageName
+ * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
+ * @return bool
+ */
+ public static function satisfies(VersionParser $parser, $packageName, $constraint)
+ {
+ $constraint = $parser->parseConstraints((string) $constraint);
+ $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
+
+ return $provided->matches($constraint);
+ }
+
+ /**
+ * Returns a version constraint representing all the range(s) which are installed for a given package
+ *
+ * It is easier to use this via isInstalled() with the $constraint argument if you need to check
+ * whether a given version of a package is installed, and not just whether it exists
+ *
+ * @param string $packageName
+ * @return string Version constraint usable with composer/semver
+ */
+ public static function getVersionRanges($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ $ranges = array();
+ if (isset($installed['versions'][$packageName]['pretty_version'])) {
+ $ranges[] = $installed['versions'][$packageName]['pretty_version'];
+ }
+ if (array_key_exists('aliases', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
+ }
+ if (array_key_exists('replaced', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
+ }
+ if (array_key_exists('provided', $installed['versions'][$packageName])) {
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
+ }
+
+ return implode(' || ', $ranges);
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
+ */
+ public static function getVersion($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['version'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['version'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
+ */
+ public static function getPrettyVersion($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['pretty_version'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['pretty_version'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
+ */
+ public static function getReference($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ if (!isset($installed['versions'][$packageName]['reference'])) {
+ return null;
+ }
+
+ return $installed['versions'][$packageName]['reference'];
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @param string $packageName
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
+ */
+ public static function getInstallPath($packageName)
+ {
+ foreach (self::getInstalled() as $installed) {
+ if (!isset($installed['versions'][$packageName])) {
+ continue;
+ }
+
+ return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
+ }
+
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+ }
+
+ /**
+ * @return array
+ * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
+ */
+ public static function getRootPackage()
+ {
+ $installed = self::getInstalled();
+
+ return $installed[0]['root'];
+ }
+
+ /**
+ * Returns the raw installed.php data for custom implementations
+ *
+ * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
+ * @return array[]
+ * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}
+ */
+ public static function getRawData()
+ {
+ @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
+
+ if (null === self::$installed) {
+ // only require the installed.php file if this file is loaded from its dumped location,
+ // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
+ if (substr(__DIR__, -8, 1) !== 'C') {
+ self::$installed = include __DIR__ . '/installed.php';
+ } else {
+ self::$installed = array();
+ }
+ }
+
+ return self::$installed;
+ }
+
+ /**
+ * Returns the raw data of all installed.php which are currently loaded for custom implementations
+ *
+ * @return array[]
+ * @psalm-return list}>
+ */
+ public static function getAllRawData()
+ {
+ return self::getInstalled();
+ }
+
+ /**
+ * Lets you reload the static array from another file
+ *
+ * This is only useful for complex integrations in which a project needs to use
+ * this class but then also needs to execute another project's autoloader in process,
+ * and wants to ensure both projects have access to their version of installed.php.
+ *
+ * A typical case would be PHPUnit, where it would need to make sure it reads all
+ * the data it needs from this class, then call reload() with
+ * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
+ * the project in which it runs can then also use this class safely, without
+ * interference between PHPUnit's dependencies and the project's dependencies.
+ *
+ * @param array[] $data A vendor/composer/installed.php data set
+ * @return void
+ *
+ * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data
+ */
+ public static function reload($data)
+ {
+ self::$installed = $data;
+ self::$installedByVendor = array();
+ }
+
+ /**
+ * @return array[]
+ * @psalm-return list}>
+ */
+ private static function getInstalled()
+ {
+ if (null === self::$canGetVendors) {
+ self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
+ }
+
+ $installed = array();
+
+ if (self::$canGetVendors) {
+ foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
+ if (isset(self::$installedByVendor[$vendorDir])) {
+ $installed[] = self::$installedByVendor[$vendorDir];
+ } elseif (is_file($vendorDir.'/composer/installed.php')) {
+ /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */
+ $required = require $vendorDir.'/composer/installed.php';
+ $installed[] = self::$installedByVendor[$vendorDir] = $required;
+ if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
+ self::$installed = $installed[count($installed) - 1];
+ }
+ }
+ }
+ }
+
+ if (null === self::$installed) {
+ // only require the installed.php file if this file is loaded from its dumped location,
+ // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
+ if (substr(__DIR__, -8, 1) !== 'C') {
+ /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */
+ $required = require __DIR__ . '/installed.php';
+ self::$installed = $required;
+ } else {
+ self::$installed = array();
+ }
+ }
+
+ if (self::$installed !== array()) {
+ $installed[] = self::$installed;
+ }
+
+ return $installed;
+ }
+}
diff --git a/includes/vendor/composer/LICENSE b/includes/vendor/composer/LICENSE
new file mode 100644
index 00000000..f27399a0
--- /dev/null
+++ b/includes/vendor/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/includes/vendor/composer/autoload_classmap.php b/includes/vendor/composer/autoload_classmap.php
index 71dd9c17..074b09e9 100644
--- a/includes/vendor/composer/autoload_classmap.php
+++ b/includes/vendor/composer/autoload_classmap.php
@@ -2,8 +2,118 @@
// autoload_classmap.php @generated by Composer
-$vendorDir = dirname(dirname(__FILE__));
+$vendorDir = dirname(__DIR__);
$baseDir = dirname(dirname($vendorDir));
return array(
+ 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
+ 'Composer\\Installers\\AglInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AglInstaller.php',
+ 'Composer\\Installers\\AimeosInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AimeosInstaller.php',
+ 'Composer\\Installers\\AnnotateCmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
+ 'Composer\\Installers\\AsgardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
+ 'Composer\\Installers\\AttogramInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AttogramInstaller.php',
+ 'Composer\\Installers\\BaseInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BaseInstaller.php',
+ 'Composer\\Installers\\BitrixInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BitrixInstaller.php',
+ 'Composer\\Installers\\BonefishInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BonefishInstaller.php',
+ 'Composer\\Installers\\CakePHPInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CakePHPInstaller.php',
+ 'Composer\\Installers\\ChefInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ChefInstaller.php',
+ 'Composer\\Installers\\CiviCrmInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CiviCrmInstaller.php',
+ 'Composer\\Installers\\ClanCatsFrameworkInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php',
+ 'Composer\\Installers\\CockpitInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CockpitInstaller.php',
+ 'Composer\\Installers\\CodeIgniterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
+ 'Composer\\Installers\\Concrete5Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
+ 'Composer\\Installers\\CraftInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CraftInstaller.php',
+ 'Composer\\Installers\\CroogoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
+ 'Composer\\Installers\\DecibelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DecibelInstaller.php',
+ 'Composer\\Installers\\DframeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DframeInstaller.php',
+ 'Composer\\Installers\\DokuWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DokuWikiInstaller.php',
+ 'Composer\\Installers\\DolibarrInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DolibarrInstaller.php',
+ 'Composer\\Installers\\DrupalInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DrupalInstaller.php',
+ 'Composer\\Installers\\ElggInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ElggInstaller.php',
+ 'Composer\\Installers\\EliasisInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/EliasisInstaller.php',
+ 'Composer\\Installers\\ExpressionEngineInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php',
+ 'Composer\\Installers\\EzPlatformInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/EzPlatformInstaller.php',
+ 'Composer\\Installers\\FuelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
+ 'Composer\\Installers\\FuelphpInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
+ 'Composer\\Installers\\GravInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/GravInstaller.php',
+ 'Composer\\Installers\\HuradInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
+ 'Composer\\Installers\\ImageCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
+ 'Composer\\Installers\\Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Installer.php',
+ 'Composer\\Installers\\ItopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
+ 'Composer\\Installers\\JoomlaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
+ 'Composer\\Installers\\KanboardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
+ 'Composer\\Installers\\KirbyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
+ 'Composer\\Installers\\KnownInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KnownInstaller.php',
+ 'Composer\\Installers\\KodiCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
+ 'Composer\\Installers\\KohanaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
+ 'Composer\\Installers\\LanManagementSystemInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php',
+ 'Composer\\Installers\\LaravelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
+ 'Composer\\Installers\\LavaLiteInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LavaLiteInstaller.php',
+ 'Composer\\Installers\\LithiumInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
+ 'Composer\\Installers\\MODULEWorkInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
+ 'Composer\\Installers\\MODXEvoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
+ 'Composer\\Installers\\MagentoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
+ 'Composer\\Installers\\MajimaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MajimaInstaller.php',
+ 'Composer\\Installers\\MakoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
+ 'Composer\\Installers\\MantisBTInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MantisBTInstaller.php',
+ 'Composer\\Installers\\MauticInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
+ 'Composer\\Installers\\MayaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
+ 'Composer\\Installers\\MediaWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
+ 'Composer\\Installers\\MiaoxingInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MiaoxingInstaller.php',
+ 'Composer\\Installers\\MicroweberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
+ 'Composer\\Installers\\ModxInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ModxInstaller.php',
+ 'Composer\\Installers\\MoodleInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
+ 'Composer\\Installers\\OctoberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
+ 'Composer\\Installers\\OntoWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OntoWikiInstaller.php',
+ 'Composer\\Installers\\OsclassInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OsclassInstaller.php',
+ 'Composer\\Installers\\OxidInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
+ 'Composer\\Installers\\PPIInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
+ 'Composer\\Installers\\PantheonInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PantheonInstaller.php',
+ 'Composer\\Installers\\PhiftyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
+ 'Composer\\Installers\\PhpBBInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
+ 'Composer\\Installers\\PimcoreInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PimcoreInstaller.php',
+ 'Composer\\Installers\\PiwikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
+ 'Composer\\Installers\\PlentymarketsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
+ 'Composer\\Installers\\Plugin' => $vendorDir . '/composer/installers/src/Composer/Installers/Plugin.php',
+ 'Composer\\Installers\\PortoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PortoInstaller.php',
+ 'Composer\\Installers\\PrestashopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
+ 'Composer\\Installers\\ProcessWireInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ProcessWireInstaller.php',
+ 'Composer\\Installers\\PuppetInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
+ 'Composer\\Installers\\PxcmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PxcmsInstaller.php',
+ 'Composer\\Installers\\RadPHPInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php',
+ 'Composer\\Installers\\ReIndexInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ReIndexInstaller.php',
+ 'Composer\\Installers\\Redaxo5Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Redaxo5Installer.php',
+ 'Composer\\Installers\\RedaxoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RedaxoInstaller.php',
+ 'Composer\\Installers\\RoundcubeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RoundcubeInstaller.php',
+ 'Composer\\Installers\\SMFInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
+ 'Composer\\Installers\\ShopwareInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
+ 'Composer\\Installers\\SilverStripeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
+ 'Composer\\Installers\\SiteDirectInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SiteDirectInstaller.php',
+ 'Composer\\Installers\\StarbugInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/StarbugInstaller.php',
+ 'Composer\\Installers\\SyDESInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
+ 'Composer\\Installers\\SyliusInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SyliusInstaller.php',
+ 'Composer\\Installers\\Symfony1Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
+ 'Composer\\Installers\\TYPO3CmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
+ 'Composer\\Installers\\TYPO3FlowInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
+ 'Composer\\Installers\\TaoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TaoInstaller.php',
+ 'Composer\\Installers\\TastyIgniterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php',
+ 'Composer\\Installers\\TheliaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
+ 'Composer\\Installers\\TuskInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TuskInstaller.php',
+ 'Composer\\Installers\\UserFrostingInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/UserFrostingInstaller.php',
+ 'Composer\\Installers\\VanillaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/VanillaInstaller.php',
+ 'Composer\\Installers\\VgmcpInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/VgmcpInstaller.php',
+ 'Composer\\Installers\\WHMCSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php',
+ 'Composer\\Installers\\WinterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WinterInstaller.php',
+ 'Composer\\Installers\\WolfCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php',
+ 'Composer\\Installers\\WordPressInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WordPressInstaller.php',
+ 'Composer\\Installers\\YawikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/YawikInstaller.php',
+ 'Composer\\Installers\\ZendInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZendInstaller.php',
+ 'Composer\\Installers\\ZikulaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
+ 'Firebase\\JWT\\BeforeValidException' => $vendorDir . '/firebase/php-jwt/src/BeforeValidException.php',
+ 'Firebase\\JWT\\CachedKeySet' => $vendorDir . '/firebase/php-jwt/src/CachedKeySet.php',
+ 'Firebase\\JWT\\ExpiredException' => $vendorDir . '/firebase/php-jwt/src/ExpiredException.php',
+ 'Firebase\\JWT\\JWK' => $vendorDir . '/firebase/php-jwt/src/JWK.php',
+ 'Firebase\\JWT\\JWT' => $vendorDir . '/firebase/php-jwt/src/JWT.php',
+ 'Firebase\\JWT\\Key' => $vendorDir . '/firebase/php-jwt/src/Key.php',
+ 'Firebase\\JWT\\SignatureInvalidException' => $vendorDir . '/firebase/php-jwt/src/SignatureInvalidException.php',
);
diff --git a/includes/vendor/composer/autoload_namespaces.php b/includes/vendor/composer/autoload_namespaces.php
index 4a9c20be..f1ae7a0f 100644
--- a/includes/vendor/composer/autoload_namespaces.php
+++ b/includes/vendor/composer/autoload_namespaces.php
@@ -2,7 +2,7 @@
// autoload_namespaces.php @generated by Composer
-$vendorDir = dirname(dirname(__FILE__));
+$vendorDir = dirname(__DIR__);
$baseDir = dirname(dirname($vendorDir));
return array(
diff --git a/includes/vendor/composer/autoload_psr4.php b/includes/vendor/composer/autoload_psr4.php
index 91d582ba..f8ff6f8b 100644
--- a/includes/vendor/composer/autoload_psr4.php
+++ b/includes/vendor/composer/autoload_psr4.php
@@ -2,9 +2,10 @@
// autoload_psr4.php @generated by Composer
-$vendorDir = dirname(dirname(__FILE__));
+$vendorDir = dirname(__DIR__);
$baseDir = dirname(dirname($vendorDir));
return array(
'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'),
+ 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
);
diff --git a/includes/vendor/composer/autoload_real.php b/includes/vendor/composer/autoload_real.php
index c50148da..3617d4b0 100644
--- a/includes/vendor/composer/autoload_real.php
+++ b/includes/vendor/composer/autoload_real.php
@@ -13,38 +13,26 @@ public static function loadClassLoader($class)
}
}
+ /**
+ * @return \Composer\Autoload\ClassLoader
+ */
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
+ require __DIR__ . '/platform_check.php';
+
spl_autoload_register(array('ComposerAutoloaderInit6ba6ee55693d165c056f65e51c5383a5', 'loadClassLoader'), true, true);
- self::$loader = $loader = new \Composer\Autoload\ClassLoader();
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit6ba6ee55693d165c056f65e51c5383a5', 'loadClassLoader'));
- $map = require __DIR__ . '/autoload_namespaces.php';
- foreach ($map as $namespace => $path) {
- $loader->set($namespace, $path);
- }
-
- $map = require __DIR__ . '/autoload_psr4.php';
- foreach ($map as $namespace => $path) {
- $loader->setPsr4($namespace, $path);
- }
-
- $classMap = require __DIR__ . '/autoload_classmap.php';
- if ($classMap) {
- $loader->addClassMap($classMap);
- }
+ require __DIR__ . '/autoload_static.php';
+ call_user_func(\Composer\Autoload\ComposerStaticInit6ba6ee55693d165c056f65e51c5383a5::getInitializer($loader));
$loader->register(true);
return $loader;
}
}
-
-function composerRequire6ba6ee55693d165c056f65e51c5383a5($file)
-{
- require $file;
-}
diff --git a/includes/vendor/composer/autoload_static.php b/includes/vendor/composer/autoload_static.php
new file mode 100644
index 00000000..fe631270
--- /dev/null
+++ b/includes/vendor/composer/autoload_static.php
@@ -0,0 +1,153 @@
+
+ array (
+ 'Firebase\\JWT\\' => 13,
+ ),
+ 'C' =>
+ array (
+ 'Composer\\Installers\\' => 20,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'Firebase\\JWT\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
+ ),
+ 'Composer\\Installers\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
+ ),
+ );
+
+ public static $classMap = array (
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+ 'Composer\\Installers\\AglInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AglInstaller.php',
+ 'Composer\\Installers\\AimeosInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AimeosInstaller.php',
+ 'Composer\\Installers\\AnnotateCmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
+ 'Composer\\Installers\\AsgardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
+ 'Composer\\Installers\\AttogramInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AttogramInstaller.php',
+ 'Composer\\Installers\\BaseInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/BaseInstaller.php',
+ 'Composer\\Installers\\BitrixInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/BitrixInstaller.php',
+ 'Composer\\Installers\\BonefishInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/BonefishInstaller.php',
+ 'Composer\\Installers\\CakePHPInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CakePHPInstaller.php',
+ 'Composer\\Installers\\ChefInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ChefInstaller.php',
+ 'Composer\\Installers\\CiviCrmInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CiviCrmInstaller.php',
+ 'Composer\\Installers\\ClanCatsFrameworkInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php',
+ 'Composer\\Installers\\CockpitInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CockpitInstaller.php',
+ 'Composer\\Installers\\CodeIgniterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
+ 'Composer\\Installers\\Concrete5Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
+ 'Composer\\Installers\\CraftInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CraftInstaller.php',
+ 'Composer\\Installers\\CroogoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
+ 'Composer\\Installers\\DecibelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DecibelInstaller.php',
+ 'Composer\\Installers\\DframeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DframeInstaller.php',
+ 'Composer\\Installers\\DokuWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DokuWikiInstaller.php',
+ 'Composer\\Installers\\DolibarrInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DolibarrInstaller.php',
+ 'Composer\\Installers\\DrupalInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DrupalInstaller.php',
+ 'Composer\\Installers\\ElggInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ElggInstaller.php',
+ 'Composer\\Installers\\EliasisInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/EliasisInstaller.php',
+ 'Composer\\Installers\\ExpressionEngineInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php',
+ 'Composer\\Installers\\EzPlatformInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/EzPlatformInstaller.php',
+ 'Composer\\Installers\\FuelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
+ 'Composer\\Installers\\FuelphpInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
+ 'Composer\\Installers\\GravInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/GravInstaller.php',
+ 'Composer\\Installers\\HuradInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
+ 'Composer\\Installers\\ImageCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
+ 'Composer\\Installers\\Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Installer.php',
+ 'Composer\\Installers\\ItopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
+ 'Composer\\Installers\\JoomlaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
+ 'Composer\\Installers\\KanboardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
+ 'Composer\\Installers\\KirbyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
+ 'Composer\\Installers\\KnownInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KnownInstaller.php',
+ 'Composer\\Installers\\KodiCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
+ 'Composer\\Installers\\KohanaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
+ 'Composer\\Installers\\LanManagementSystemInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php',
+ 'Composer\\Installers\\LaravelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
+ 'Composer\\Installers\\LavaLiteInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LavaLiteInstaller.php',
+ 'Composer\\Installers\\LithiumInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
+ 'Composer\\Installers\\MODULEWorkInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
+ 'Composer\\Installers\\MODXEvoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
+ 'Composer\\Installers\\MagentoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
+ 'Composer\\Installers\\MajimaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MajimaInstaller.php',
+ 'Composer\\Installers\\MakoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
+ 'Composer\\Installers\\MantisBTInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MantisBTInstaller.php',
+ 'Composer\\Installers\\MauticInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
+ 'Composer\\Installers\\MayaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
+ 'Composer\\Installers\\MediaWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
+ 'Composer\\Installers\\MiaoxingInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MiaoxingInstaller.php',
+ 'Composer\\Installers\\MicroweberInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
+ 'Composer\\Installers\\ModxInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ModxInstaller.php',
+ 'Composer\\Installers\\MoodleInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
+ 'Composer\\Installers\\OctoberInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
+ 'Composer\\Installers\\OntoWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OntoWikiInstaller.php',
+ 'Composer\\Installers\\OsclassInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OsclassInstaller.php',
+ 'Composer\\Installers\\OxidInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
+ 'Composer\\Installers\\PPIInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
+ 'Composer\\Installers\\PantheonInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PantheonInstaller.php',
+ 'Composer\\Installers\\PhiftyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
+ 'Composer\\Installers\\PhpBBInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
+ 'Composer\\Installers\\PimcoreInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PimcoreInstaller.php',
+ 'Composer\\Installers\\PiwikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
+ 'Composer\\Installers\\PlentymarketsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
+ 'Composer\\Installers\\Plugin' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Plugin.php',
+ 'Composer\\Installers\\PortoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PortoInstaller.php',
+ 'Composer\\Installers\\PrestashopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
+ 'Composer\\Installers\\ProcessWireInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ProcessWireInstaller.php',
+ 'Composer\\Installers\\PuppetInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
+ 'Composer\\Installers\\PxcmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PxcmsInstaller.php',
+ 'Composer\\Installers\\RadPHPInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php',
+ 'Composer\\Installers\\ReIndexInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ReIndexInstaller.php',
+ 'Composer\\Installers\\Redaxo5Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Redaxo5Installer.php',
+ 'Composer\\Installers\\RedaxoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RedaxoInstaller.php',
+ 'Composer\\Installers\\RoundcubeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RoundcubeInstaller.php',
+ 'Composer\\Installers\\SMFInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
+ 'Composer\\Installers\\ShopwareInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
+ 'Composer\\Installers\\SilverStripeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
+ 'Composer\\Installers\\SiteDirectInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SiteDirectInstaller.php',
+ 'Composer\\Installers\\StarbugInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/StarbugInstaller.php',
+ 'Composer\\Installers\\SyDESInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
+ 'Composer\\Installers\\SyliusInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SyliusInstaller.php',
+ 'Composer\\Installers\\Symfony1Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
+ 'Composer\\Installers\\TYPO3CmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
+ 'Composer\\Installers\\TYPO3FlowInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
+ 'Composer\\Installers\\TaoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TaoInstaller.php',
+ 'Composer\\Installers\\TastyIgniterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php',
+ 'Composer\\Installers\\TheliaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
+ 'Composer\\Installers\\TuskInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TuskInstaller.php',
+ 'Composer\\Installers\\UserFrostingInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/UserFrostingInstaller.php',
+ 'Composer\\Installers\\VanillaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/VanillaInstaller.php',
+ 'Composer\\Installers\\VgmcpInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/VgmcpInstaller.php',
+ 'Composer\\Installers\\WHMCSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php',
+ 'Composer\\Installers\\WinterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WinterInstaller.php',
+ 'Composer\\Installers\\WolfCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php',
+ 'Composer\\Installers\\WordPressInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WordPressInstaller.php',
+ 'Composer\\Installers\\YawikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/YawikInstaller.php',
+ 'Composer\\Installers\\ZendInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ZendInstaller.php',
+ 'Composer\\Installers\\ZikulaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
+ 'Firebase\\JWT\\BeforeValidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/BeforeValidException.php',
+ 'Firebase\\JWT\\CachedKeySet' => __DIR__ . '/..' . '/firebase/php-jwt/src/CachedKeySet.php',
+ 'Firebase\\JWT\\ExpiredException' => __DIR__ . '/..' . '/firebase/php-jwt/src/ExpiredException.php',
+ 'Firebase\\JWT\\JWK' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWK.php',
+ 'Firebase\\JWT\\JWT' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWT.php',
+ 'Firebase\\JWT\\Key' => __DIR__ . '/..' . '/firebase/php-jwt/src/Key.php',
+ 'Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/SignatureInvalidException.php',
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInit6ba6ee55693d165c056f65e51c5383a5::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit6ba6ee55693d165c056f65e51c5383a5::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInit6ba6ee55693d165c056f65e51c5383a5::$classMap;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/includes/vendor/composer/installed.json b/includes/vendor/composer/installed.json
index cc955f47..5312805b 100644
--- a/includes/vendor/composer/installed.json
+++ b/includes/vendor/composer/installed.json
@@ -1,47 +1,226 @@
-[
- {
- "name": "firebase/php-jwt",
- "version": "v3.0.0",
- "version_normalized": "3.0.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/firebase/php-jwt.git",
- "reference": "fa8a06e96526eb7c0eeaa47e4f39be59d21f16e1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/firebase/php-jwt/zipball/fa8a06e96526eb7c0eeaa47e4f39be59d21f16e1",
- "reference": "fa8a06e96526eb7c0eeaa47e4f39be59d21f16e1",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "time": "2015-07-22 18:31:08",
- "type": "library",
- "installation-source": "dist",
- "autoload": {
- "psr-4": {
- "Firebase\\JWT\\": "src"
- }
+{
+ "packages": [
+ {
+ "name": "composer/installers",
+ "version": "v1.12.0",
+ "version_normalized": "1.12.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/installers.git",
+ "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/installers/zipball/d20a64ed3c94748397ff5973488761b22f6d3f19",
+ "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0 || ^2.0"
+ },
+ "replace": {
+ "roundcube/plugin-installer": "*",
+ "shama/baton": "*"
+ },
+ "require-dev": {
+ "composer/composer": "1.6.* || ^2.0",
+ "composer/semver": "^1 || ^3",
+ "phpstan/phpstan": "^0.12.55",
+ "phpstan/phpstan-phpunit": "^0.12.16",
+ "symfony/phpunit-bridge": "^4.2 || ^5",
+ "symfony/process": "^2.3"
+ },
+ "time": "2021-09-13T08:19:44+00:00",
+ "type": "composer-plugin",
+ "extra": {
+ "class": "Composer\\Installers\\Plugin",
+ "branch-alias": {
+ "dev-main": "1.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Composer\\Installers\\": "src/Composer/Installers"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kyle Robinson Young",
+ "email": "kyle@dontkry.com",
+ "homepage": "https://github.com/shama"
+ }
+ ],
+ "description": "A multi-framework Composer library installer",
+ "homepage": "https://composer.github.io/installers/",
+ "keywords": [
+ "Craft",
+ "Dolibarr",
+ "Eliasis",
+ "Hurad",
+ "ImageCMS",
+ "Kanboard",
+ "Lan Management System",
+ "MODX Evo",
+ "MantisBT",
+ "Mautic",
+ "Maya",
+ "OXID",
+ "Plentymarkets",
+ "Porto",
+ "RadPHP",
+ "SMF",
+ "Starbug",
+ "Thelia",
+ "Whmcs",
+ "WolfCMS",
+ "agl",
+ "aimeos",
+ "annotatecms",
+ "attogram",
+ "bitrix",
+ "cakephp",
+ "chef",
+ "cockpit",
+ "codeigniter",
+ "concrete5",
+ "croogo",
+ "dokuwiki",
+ "drupal",
+ "eZ Platform",
+ "elgg",
+ "expressionengine",
+ "fuelphp",
+ "grav",
+ "installer",
+ "itop",
+ "joomla",
+ "known",
+ "kohana",
+ "laravel",
+ "lavalite",
+ "lithium",
+ "magento",
+ "majima",
+ "mako",
+ "mediawiki",
+ "miaoxing",
+ "modulework",
+ "modx",
+ "moodle",
+ "osclass",
+ "pantheon",
+ "phpbb",
+ "piwik",
+ "ppi",
+ "processwire",
+ "puppet",
+ "pxcms",
+ "reindex",
+ "roundcube",
+ "shopware",
+ "silverstripe",
+ "sydes",
+ "sylius",
+ "symfony",
+ "tastyigniter",
+ "typo3",
+ "wordpress",
+ "yawik",
+ "zend",
+ "zikula"
+ ],
+ "support": {
+ "issues": "https://github.com/composer/installers/issues",
+ "source": "https://github.com/composer/installers/tree/v1.12.0"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com/",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "install-path": "./installers"
},
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Neuman Vong",
- "email": "neuman+pear@twilio.com",
- "role": "Developer"
- },
- {
- "name": "Anant Narayanan",
- "email": "anant@php.net",
- "role": "Developer"
- }
- ],
- "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
- "homepage": "https://github.com/firebase/php-jwt"
- }
-]
+ {
+ "name": "firebase/php-jwt",
+ "version": "v6.4.0",
+ "version_normalized": "6.4.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/firebase/php-jwt.git",
+ "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/firebase/php-jwt/zipball/4dd1e007f22a927ac77da5a3fbb067b42d3bc224",
+ "reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1||^8.0"
+ },
+ "require-dev": {
+ "guzzlehttp/guzzle": "^6.5||^7.4",
+ "phpspec/prophecy-phpunit": "^1.1",
+ "phpunit/phpunit": "^7.5||^9.5",
+ "psr/cache": "^1.0||^2.0",
+ "psr/http-client": "^1.0",
+ "psr/http-factory": "^1.0"
+ },
+ "suggest": {
+ "ext-sodium": "Support EdDSA (Ed25519) signatures",
+ "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
+ },
+ "time": "2023-02-09T21:01:23+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Firebase\\JWT\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Neuman Vong",
+ "email": "neuman+pear@twilio.com",
+ "role": "Developer"
+ },
+ {
+ "name": "Anant Narayanan",
+ "email": "anant@php.net",
+ "role": "Developer"
+ }
+ ],
+ "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
+ "homepage": "https://github.com/firebase/php-jwt",
+ "keywords": [
+ "jwt",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/firebase/php-jwt/issues",
+ "source": "https://github.com/firebase/php-jwt/tree/v6.4.0"
+ },
+ "install-path": "../firebase/php-jwt"
+ }
+ ],
+ "dev": false,
+ "dev-package-names": []
+}
diff --git a/includes/vendor/composer/installed.php b/includes/vendor/composer/installed.php
new file mode 100644
index 00000000..cd9d36ae
--- /dev/null
+++ b/includes/vendor/composer/installed.php
@@ -0,0 +1,53 @@
+ array(
+ 'name' => 'tmeister/wp-api-jwt-auth',
+ 'pretty_version' => 'dev-develop',
+ 'version' => 'dev-develop',
+ 'reference' => 'd91b9b6412fcd1e09102f5c9254481c13ed07f9c',
+ 'type' => 'wordpress-plugin',
+ 'install_path' => __DIR__ . '/../../../',
+ 'aliases' => array(),
+ 'dev' => false,
+ ),
+ 'versions' => array(
+ 'composer/installers' => array(
+ 'pretty_version' => 'v1.12.0',
+ 'version' => '1.12.0.0',
+ 'reference' => 'd20a64ed3c94748397ff5973488761b22f6d3f19',
+ 'type' => 'composer-plugin',
+ 'install_path' => __DIR__ . '/./installers',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
+ 'firebase/php-jwt' => array(
+ 'pretty_version' => 'v6.4.0',
+ 'version' => '6.4.0.0',
+ 'reference' => '4dd1e007f22a927ac77da5a3fbb067b42d3bc224',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../firebase/php-jwt',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
+ 'roundcube/plugin-installer' => array(
+ 'dev_requirement' => false,
+ 'replaced' => array(
+ 0 => '*',
+ ),
+ ),
+ 'shama/baton' => array(
+ 'dev_requirement' => false,
+ 'replaced' => array(
+ 0 => '*',
+ ),
+ ),
+ 'tmeister/wp-api-jwt-auth' => array(
+ 'pretty_version' => 'dev-develop',
+ 'version' => 'dev-develop',
+ 'reference' => 'd91b9b6412fcd1e09102f5c9254481c13ed07f9c',
+ 'type' => 'wordpress-plugin',
+ 'install_path' => __DIR__ . '/../../../',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
+ ),
+);
diff --git a/includes/vendor/composer/installers/.github/workflows/continuous-integration.yml b/includes/vendor/composer/installers/.github/workflows/continuous-integration.yml
new file mode 100644
index 00000000..34b8f91f
--- /dev/null
+++ b/includes/vendor/composer/installers/.github/workflows/continuous-integration.yml
@@ -0,0 +1,76 @@
+name: "Continuous Integration"
+
+on:
+ - push
+ - pull_request
+
+env:
+ COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --prefer-dist"
+ SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT: "1"
+
+jobs:
+ tests:
+ name: "CI"
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ php-version:
+ - "5.3"
+ - "5.4"
+ - "5.5"
+ - "5.6"
+ - "7.0"
+ - "7.1"
+ - "7.2"
+ - "7.3"
+ - "7.4"
+ - "8.0"
+ - "8.1"
+ dependencies: [locked]
+ include:
+ - php-version: "5.3"
+ dependencies: lowest
+ - php-version: "8.1"
+ dependencies: lowest
+
+ steps:
+ - name: "Checkout"
+ uses: "actions/checkout@v2"
+
+ - name: "Install PHP"
+ uses: "shivammathur/setup-php@v2"
+ with:
+ coverage: "none"
+ php-version: "${{ matrix.php-version }}"
+ tools: composer:snapshot
+
+ - name: Get composer cache directory
+ id: composercache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache dependencies
+ uses: actions/cache@v2
+ with:
+ path: ${{ steps.composercache.outputs.dir }}
+ key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
+ restore-keys: ${{ runner.os }}-composer-
+
+ - name: "Handle lowest dependencies update"
+ if: "contains(matrix.dependencies, 'lowest')"
+ run: "echo \"COMPOSER_FLAGS=$COMPOSER_FLAGS --prefer-lowest\" >> $GITHUB_ENV"
+
+ - name: "Upgrade phpunit-bridge if needed for php 8 lowest build"
+ if: "contains(matrix.php-version, '8.')"
+ run: |
+ composer require symfony/phpunit-bridge:^5.3.3 --dev --no-update
+
+ - name: "Install latest dependencies"
+ run: |
+ # Remove PHPStan as it requires a newer PHP
+ composer remove phpstan/phpstan phpstan/phpstan-phpunit --dev --no-update
+ composer update ${{ env.COMPOSER_FLAGS }}
+
+ - name: "Run tests"
+ run: "vendor/bin/simple-phpunit --verbose"
diff --git a/includes/vendor/composer/installers/.github/workflows/lint.yml b/includes/vendor/composer/installers/.github/workflows/lint.yml
new file mode 100644
index 00000000..81a1ac4d
--- /dev/null
+++ b/includes/vendor/composer/installers/.github/workflows/lint.yml
@@ -0,0 +1,30 @@
+name: "PHP Lint"
+
+on:
+ - push
+ - pull_request
+
+jobs:
+ tests:
+ name: "Lint"
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ php-version:
+ - "5.3"
+ - "8.0"
+
+ steps:
+ - name: "Checkout"
+ uses: "actions/checkout@v2"
+
+ - name: "Install PHP"
+ uses: "shivammathur/setup-php@v2"
+ with:
+ coverage: "none"
+ php-version: "${{ matrix.php-version }}"
+
+ - name: "Lint PHP files"
+ run: "find src/ -type f -name '*.php' -print0 | xargs -0 -L1 -P4 -- php -l -f"
diff --git a/includes/vendor/composer/installers/.github/workflows/phpstan.yml b/includes/vendor/composer/installers/.github/workflows/phpstan.yml
new file mode 100644
index 00000000..ac4c4a92
--- /dev/null
+++ b/includes/vendor/composer/installers/.github/workflows/phpstan.yml
@@ -0,0 +1,51 @@
+name: "PHPStan"
+
+on:
+ - push
+ - pull_request
+
+env:
+ COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --prefer-dist"
+ SYMFONY_PHPUNIT_VERSION: ""
+
+jobs:
+ tests:
+ name: "PHPStan"
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ php-version:
+ # pinned to 7.4 because we need PHPUnit 7.5 which does not support PHP 8
+ - "7.4"
+
+ steps:
+ - name: "Checkout"
+ uses: "actions/checkout@v2"
+
+ - name: "Install PHP"
+ uses: "shivammathur/setup-php@v2"
+ with:
+ coverage: "none"
+ php-version: "${{ matrix.php-version }}"
+
+ - name: Get composer cache directory
+ id: composercache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache dependencies
+ uses: actions/cache@v2
+ with:
+ path: ${{ steps.composercache.outputs.dir }}
+ key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
+ restore-keys: ${{ runner.os }}-composer-
+
+ - name: "Install latest dependencies"
+ run: "composer update ${{ env.COMPOSER_FLAGS }}"
+
+ - name: Run PHPStan
+ # Locked to phpunit 7.5 here as newer ones have void return types which break inheritance
+ run: |
+ composer require --dev phpunit/phpunit:^7.5.20 --with-all-dependencies ${{ env.COMPOSER_FLAGS }}
+ vendor/bin/phpstan analyse
diff --git a/includes/vendor/composer/installers/LICENSE b/includes/vendor/composer/installers/LICENSE
new file mode 100644
index 00000000..85f97fc7
--- /dev/null
+++ b/includes/vendor/composer/installers/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Kyle Robinson Young
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/includes/vendor/composer/installers/composer.json b/includes/vendor/composer/installers/composer.json
new file mode 100644
index 00000000..4a7fd3c3
--- /dev/null
+++ b/includes/vendor/composer/installers/composer.json
@@ -0,0 +1,122 @@
+{
+ "name": "composer/installers",
+ "type": "composer-plugin",
+ "license": "MIT",
+ "description": "A multi-framework Composer library installer",
+ "keywords": [
+ "installer",
+ "Aimeos",
+ "AGL",
+ "AnnotateCms",
+ "Attogram",
+ "Bitrix",
+ "CakePHP",
+ "Chef",
+ "Cockpit",
+ "CodeIgniter",
+ "concrete5",
+ "Craft",
+ "Croogo",
+ "DokuWiki",
+ "Dolibarr",
+ "Drupal",
+ "Elgg",
+ "Eliasis",
+ "ExpressionEngine",
+ "eZ Platform",
+ "FuelPHP",
+ "Grav",
+ "Hurad",
+ "ImageCMS",
+ "iTop",
+ "Joomla",
+ "Kanboard",
+ "Known",
+ "Kohana",
+ "Lan Management System",
+ "Laravel",
+ "Lavalite",
+ "Lithium",
+ "Magento",
+ "majima",
+ "Mako",
+ "MantisBT",
+ "Mautic",
+ "Maya",
+ "MODX",
+ "MODX Evo",
+ "MediaWiki",
+ "Miaoxing",
+ "OXID",
+ "osclass",
+ "MODULEWork",
+ "Moodle",
+ "Pantheon",
+ "Piwik",
+ "pxcms",
+ "phpBB",
+ "Plentymarkets",
+ "PPI",
+ "Puppet",
+ "Porto",
+ "ProcessWire",
+ "RadPHP",
+ "ReIndex",
+ "Roundcube",
+ "shopware",
+ "SilverStripe",
+ "SMF",
+ "Starbug",
+ "SyDES",
+ "Sylius",
+ "symfony",
+ "TastyIgniter",
+ "Thelia",
+ "TYPO3",
+ "WHMCS",
+ "WolfCMS",
+ "WordPress",
+ "YAWIK",
+ "Zend",
+ "Zikula"
+ ],
+ "homepage": "https://composer.github.io/installers/",
+ "authors": [
+ {
+ "name": "Kyle Robinson Young",
+ "email": "kyle@dontkry.com",
+ "homepage": "https://github.com/shama"
+ }
+ ],
+ "autoload": {
+ "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" }
+ },
+ "autoload-dev": {
+ "psr-4": { "Composer\\Installers\\Test\\": "tests/Composer/Installers/Test" }
+ },
+ "extra": {
+ "class": "Composer\\Installers\\Plugin",
+ "branch-alias": {
+ "dev-main": "1.x-dev"
+ }
+ },
+ "replace": {
+ "shama/baton": "*",
+ "roundcube/plugin-installer": "*"
+ },
+ "require": {
+ "composer-plugin-api": "^1.0 || ^2.0"
+ },
+ "require-dev": {
+ "composer/composer": "1.6.* || ^2.0",
+ "composer/semver": "^1 || ^3",
+ "symfony/phpunit-bridge": "^4.2 || ^5",
+ "phpstan/phpstan": "^0.12.55",
+ "symfony/process": "^2.3",
+ "phpstan/phpstan-phpunit": "^0.12.16"
+ },
+ "scripts": {
+ "test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit",
+ "phpstan": "vendor/bin/phpstan analyse"
+ }
+}
diff --git a/includes/vendor/composer/installers/phpstan.neon.dist b/includes/vendor/composer/installers/phpstan.neon.dist
new file mode 100644
index 00000000..8e3d81e9
--- /dev/null
+++ b/includes/vendor/composer/installers/phpstan.neon.dist
@@ -0,0 +1,10 @@
+parameters:
+ level: 5
+ paths:
+ - src
+ - tests
+ excludes_analyse:
+ - tests/Composer/Installers/Test/PolyfillTestCase.php
+
+includes:
+ - vendor/phpstan/phpstan-phpunit/extension.neon
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/AglInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/AglInstaller.php
new file mode 100644
index 00000000..01b8a416
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/AglInstaller.php
@@ -0,0 +1,21 @@
+ 'More/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
+ return strtoupper($matches[1]);
+ }, $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php
new file mode 100644
index 00000000..79a0e958
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php
@@ -0,0 +1,9 @@
+ 'ext/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php
new file mode 100644
index 00000000..89d7ad90
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php
@@ -0,0 +1,11 @@
+ 'addons/modules/{$name}/',
+ 'component' => 'addons/components/{$name}/',
+ 'service' => 'addons/services/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php
new file mode 100644
index 00000000..22dad1b9
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php
@@ -0,0 +1,49 @@
+ 'Modules/{$name}/',
+ 'theme' => 'Themes/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type asgard-module, cut off a trailing '-plugin' if present.
+ *
+ * For package type asgard-theme, cut off a trailing '-theme' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'asgard-module') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'asgard-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php
new file mode 100644
index 00000000..d62fd8fd
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php
new file mode 100644
index 00000000..70dde907
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php
@@ -0,0 +1,137 @@
+composer = $composer;
+ $this->package = $package;
+ $this->io = $io;
+ }
+
+ /**
+ * Return the install path based on package type.
+ *
+ * @param PackageInterface $package
+ * @param string $frameworkType
+ * @return string
+ */
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+ $type = $this->package->getType();
+
+ $prettyName = $this->package->getPrettyName();
+ if (strpos($prettyName, '/') !== false) {
+ list($vendor, $name) = explode('/', $prettyName);
+ } else {
+ $vendor = '';
+ $name = $prettyName;
+ }
+
+ $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
+
+ $extra = $package->getExtra();
+ if (!empty($extra['installer-name'])) {
+ $availableVars['name'] = $extra['installer-name'];
+ }
+
+ if ($this->composer->getPackage()) {
+ $extra = $this->composer->getPackage()->getExtra();
+ if (!empty($extra['installer-paths'])) {
+ $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
+ if ($customPath !== false) {
+ return $this->templatePath($customPath, $availableVars);
+ }
+ }
+ }
+
+ $packageType = substr($type, strlen($frameworkType) + 1);
+ $locations = $this->getLocations();
+ if (!isset($locations[$packageType])) {
+ throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
+ }
+
+ return $this->templatePath($locations[$packageType], $availableVars);
+ }
+
+ /**
+ * For an installer to override to modify the vars per installer.
+ *
+ * @param array $vars This will normally receive array{name: string, vendor: string, type: string}
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ return $vars;
+ }
+
+ /**
+ * Gets the installer's locations
+ *
+ * @return array map of package types => install path
+ */
+ public function getLocations()
+ {
+ return $this->locations;
+ }
+
+ /**
+ * Replace vars in a path
+ *
+ * @param string $path
+ * @param array $vars
+ * @return string
+ */
+ protected function templatePath($path, array $vars = array())
+ {
+ if (strpos($path, '{') !== false) {
+ extract($vars);
+ preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
+ if (!empty($matches[1])) {
+ foreach ($matches[1] as $var) {
+ $path = str_replace('{$' . $var . '}', $$var, $path);
+ }
+ }
+ }
+
+ return $path;
+ }
+
+ /**
+ * Search through a passed paths array for a custom install path.
+ *
+ * @param array $paths
+ * @param string $name
+ * @param string $type
+ * @param string $vendor = NULL
+ * @return string|false
+ */
+ protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL)
+ {
+ foreach ($paths as $path => $names) {
+ $names = (array) $names;
+ if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) {
+ return $path;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php
new file mode 100644
index 00000000..e80cd1e1
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php
@@ -0,0 +1,126 @@
+.`.
+ * - `bitrix-d7-component` — copy the component to directory `bitrix/components//`.
+ * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/_`.
+ *
+ * You can set custom path to directory with Bitrix kernel in `composer.json`:
+ *
+ * ```json
+ * {
+ * "extra": {
+ * "bitrix-dir": "s1/bitrix"
+ * }
+ * }
+ * ```
+ *
+ * @author Nik Samokhvalov
+ * @author Denis Kulichkin
+ */
+class BitrixInstaller extends BaseInstaller
+{
+ protected $locations = array(
+ 'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
+ 'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
+ 'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
+ 'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/',
+ 'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/',
+ 'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/',
+ );
+
+ /**
+ * @var array Storage for informations about duplicates at all the time of installation packages.
+ */
+ private static $checkedDuplicates = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($this->composer->getPackage()) {
+ $extra = $this->composer->getPackage()->getExtra();
+
+ if (isset($extra['bitrix-dir'])) {
+ $vars['bitrix_dir'] = $extra['bitrix-dir'];
+ }
+ }
+
+ if (!isset($vars['bitrix_dir'])) {
+ $vars['bitrix_dir'] = 'bitrix';
+ }
+
+ return parent::inflectPackageVars($vars);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function templatePath($path, array $vars = array())
+ {
+ $templatePath = parent::templatePath($path, $vars);
+ $this->checkDuplicates($templatePath, $vars);
+
+ return $templatePath;
+ }
+
+ /**
+ * Duplicates search packages.
+ *
+ * @param string $path
+ * @param array $vars
+ */
+ protected function checkDuplicates($path, array $vars = array())
+ {
+ $packageType = substr($vars['type'], strlen('bitrix') + 1);
+ $localDir = explode('/', $vars['bitrix_dir']);
+ array_pop($localDir);
+ $localDir[] = 'local';
+ $localDir = implode('/', $localDir);
+
+ $oldPath = str_replace(
+ array('{$bitrix_dir}', '{$name}'),
+ array($localDir, $vars['name']),
+ $this->locations[$packageType]
+ );
+
+ if (in_array($oldPath, static::$checkedDuplicates)) {
+ return;
+ }
+
+ if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) {
+
+ $this->io->writeError(' Duplication of packages:');
+ $this->io->writeError(' Package ' . $oldPath . ' will be called instead package ' . $path . '');
+
+ while (true) {
+ switch ($this->io->ask(' Delete ' . $oldPath . ' [y,n,?]? ', '?')) {
+ case 'y':
+ $fs = new Filesystem();
+ $fs->removeDirectory($oldPath);
+ break 2;
+
+ case 'n':
+ break 2;
+
+ case '?':
+ default:
+ $this->io->writeError(array(
+ ' y - delete package ' . $oldPath . ' and to continue with the installation',
+ ' n - don\'t delete and to continue with the installation',
+ ));
+ $this->io->writeError(' ? - print help');
+ break;
+ }
+ }
+ }
+
+ static::$checkedDuplicates[] = $oldPath;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php
new file mode 100644
index 00000000..da3aad2a
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php
@@ -0,0 +1,9 @@
+ 'Packages/{$vendor}/{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php
new file mode 100644
index 00000000..1e2ddd02
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php
@@ -0,0 +1,66 @@
+ 'Plugin/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
+ return $vars;
+ }
+
+ $nameParts = explode('/', $vars['name']);
+ foreach ($nameParts as &$value) {
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
+ $value = str_replace(array('-', '_'), ' ', $value);
+ $value = str_replace(' ', '', ucwords($value));
+ }
+ $vars['name'] = implode('/', $nameParts);
+
+ return $vars;
+ }
+
+ /**
+ * Change the default plugin location when cakephp >= 3.0
+ */
+ public function getLocations()
+ {
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
+ $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
+ }
+ return $this->locations;
+ }
+
+ /**
+ * Check if CakePHP version matches against a version
+ *
+ * @param string $matcher
+ * @param string $version
+ * @return bool
+ * @phpstan-param Constraint::STR_OP_* $matcher
+ */
+ protected function matchesCakeVersion($matcher, $version)
+ {
+ $repositoryManager = $this->composer->getRepositoryManager();
+ if (! $repositoryManager) {
+ return false;
+ }
+
+ $repos = $repositoryManager->getLocalRepository();
+ if (!$repos) {
+ return false;
+ }
+
+ return $repos->findPackage('cakephp/cakephp', new Constraint($matcher, $version)) !== null;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php
new file mode 100644
index 00000000..ab2f9aad
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php
@@ -0,0 +1,11 @@
+ 'Chef/{$vendor}/{$name}/',
+ 'role' => 'Chef/roles/{$name}/',
+ );
+}
+
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php
new file mode 100644
index 00000000..6673aea9
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php
@@ -0,0 +1,9 @@
+ 'ext/{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php
new file mode 100644
index 00000000..c887815c
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php
@@ -0,0 +1,10 @@
+ 'CCF/orbit/{$name}/',
+ 'theme' => 'CCF/app/themes/{$name}/',
+ );
+}
\ No newline at end of file
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php
new file mode 100644
index 00000000..053f3ffd
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php
@@ -0,0 +1,32 @@
+ 'cockpit/modules/addons/{$name}/',
+ );
+
+ /**
+ * Format module name.
+ *
+ * Strip `module-` prefix from package name.
+ *
+ * {@inheritDoc}
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] == 'cockpit-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ return $vars;
+ }
+
+ public function inflectModuleVars($vars)
+ {
+ $vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php
new file mode 100644
index 00000000..3b4a4ece
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php
@@ -0,0 +1,11 @@
+ 'application/libraries/{$name}/',
+ 'third-party' => 'application/third_party/{$name}/',
+ 'module' => 'application/modules/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php b/includes/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php
new file mode 100644
index 00000000..5c01bafd
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php
@@ -0,0 +1,13 @@
+ 'concrete/',
+ 'block' => 'application/blocks/{$name}/',
+ 'package' => 'packages/{$name}/',
+ 'theme' => 'application/themes/{$name}/',
+ 'update' => 'updates/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php
new file mode 100644
index 00000000..d37a77ae
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php
@@ -0,0 +1,35 @@
+ 'craft/plugins/{$name}/',
+ );
+
+ /**
+ * Strip `craft-` prefix and/or `-plugin` suffix from package names
+ *
+ * @param array $vars
+ *
+ * @return array
+ */
+ final public function inflectPackageVars($vars)
+ {
+ return $this->inflectPluginVars($vars);
+ }
+
+ private function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']);
+ $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php
new file mode 100644
index 00000000..d94219d3
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php
@@ -0,0 +1,21 @@
+ 'Plugin/{$name}/',
+ 'theme' => 'View/Themed/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php
new file mode 100644
index 00000000..f4837a6c
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php
@@ -0,0 +1,10 @@
+ 'app/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php
new file mode 100644
index 00000000..70788163
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php
@@ -0,0 +1,10 @@
+ 'modules/{$vendor}/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php
new file mode 100644
index 00000000..cfd638d5
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php
@@ -0,0 +1,50 @@
+ 'lib/plugins/{$name}/',
+ 'template' => 'lib/tpl/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type dokuwiki-plugin, cut off a trailing '-plugin',
+ * or leading dokuwiki_ if present.
+ *
+ * For package type dokuwiki-template, cut off a trailing '-template' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+
+ if ($vars['type'] === 'dokuwiki-plugin') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'dokuwiki-template') {
+ return $this->inflectTemplateVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectTemplateVars($vars)
+ {
+ $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
+
+ return $vars;
+ }
+
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php
new file mode 100644
index 00000000..21f7e8e8
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php
@@ -0,0 +1,16 @@
+
+ */
+class DolibarrInstaller extends BaseInstaller
+{
+ //TODO: Add support for scripts and themes
+ protected $locations = array(
+ 'module' => 'htdocs/custom/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php
new file mode 100644
index 00000000..73282392
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php
@@ -0,0 +1,22 @@
+ 'core/',
+ 'module' => 'modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ 'library' => 'libraries/{$name}/',
+ 'profile' => 'profiles/{$name}/',
+ 'database-driver' => 'drivers/lib/Drupal/Driver/Database/{$name}/',
+ 'drush' => 'drush/{$name}/',
+ 'custom-theme' => 'themes/custom/{$name}/',
+ 'custom-module' => 'modules/custom/{$name}/',
+ 'custom-profile' => 'profiles/custom/{$name}/',
+ 'drupal-multisite' => 'sites/{$name}/',
+ 'console' => 'console/{$name}/',
+ 'console-language' => 'console/language/{$name}/',
+ 'config' => 'config/sync/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php
new file mode 100644
index 00000000..c0bb609f
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php
@@ -0,0 +1,9 @@
+ 'mod/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php
new file mode 100644
index 00000000..6f3dc97b
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php
@@ -0,0 +1,12 @@
+ 'components/{$name}/',
+ 'module' => 'modules/{$name}/',
+ 'plugin' => 'plugins/{$name}/',
+ 'template' => 'templates/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php
new file mode 100644
index 00000000..d5321a8c
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php
@@ -0,0 +1,29 @@
+ 'system/expressionengine/third_party/{$name}/',
+ 'theme' => 'themes/third_party/{$name}/',
+ );
+
+ private $ee3Locations = array(
+ 'addon' => 'system/user/addons/{$name}/',
+ 'theme' => 'themes/user/{$name}/',
+ );
+
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+
+ $version = "{$frameworkType}Locations";
+ $this->locations = $this->$version;
+
+ return parent::getInstallPath($package, $frameworkType);
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php
new file mode 100644
index 00000000..f30ebcc7
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php
@@ -0,0 +1,10 @@
+ 'web/assets/ezplatform/',
+ 'assets' => 'web/assets/ezplatform/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php
new file mode 100644
index 00000000..6eba2e34
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php
@@ -0,0 +1,11 @@
+ 'fuel/app/modules/{$name}/',
+ 'package' => 'fuel/packages/{$name}/',
+ 'theme' => 'fuel/app/themes/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php
new file mode 100644
index 00000000..29d980b3
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php
@@ -0,0 +1,9 @@
+ 'components/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/GravInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/GravInstaller.php
new file mode 100644
index 00000000..dbe63e07
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/GravInstaller.php
@@ -0,0 +1,30 @@
+ 'user/plugins/{$name}/',
+ 'theme' => 'user/themes/{$name}/',
+ );
+
+ /**
+ * Format package name
+ *
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $restrictedWords = implode('|', array_keys($this->locations));
+
+ $vars['name'] = strtolower($vars['name']);
+ $vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui',
+ '$1',
+ $vars['name']
+ );
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php
new file mode 100644
index 00000000..8fe017f0
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php
@@ -0,0 +1,25 @@
+ 'plugins/{$name}/',
+ 'theme' => 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $nameParts = explode('/', $vars['name']);
+ foreach ($nameParts as &$value) {
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
+ $value = str_replace(array('-', '_'), ' ', $value);
+ $value = str_replace(' ', '', ucwords($value));
+ }
+ $vars['name'] = implode('/', $nameParts);
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php
new file mode 100644
index 00000000..5e2142ea
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php
@@ -0,0 +1,11 @@
+ 'templates/{$name}/',
+ 'module' => 'application/modules/{$name}/',
+ 'library' => 'application/libraries/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/Installer.php b/includes/vendor/composer/installers/src/Composer/Installers/Installer.php
new file mode 100644
index 00000000..9c9c24f7
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/Installer.php
@@ -0,0 +1,298 @@
+ 'AimeosInstaller',
+ 'asgard' => 'AsgardInstaller',
+ 'attogram' => 'AttogramInstaller',
+ 'agl' => 'AglInstaller',
+ 'annotatecms' => 'AnnotateCmsInstaller',
+ 'bitrix' => 'BitrixInstaller',
+ 'bonefish' => 'BonefishInstaller',
+ 'cakephp' => 'CakePHPInstaller',
+ 'chef' => 'ChefInstaller',
+ 'civicrm' => 'CiviCrmInstaller',
+ 'ccframework' => 'ClanCatsFrameworkInstaller',
+ 'cockpit' => 'CockpitInstaller',
+ 'codeigniter' => 'CodeIgniterInstaller',
+ 'concrete5' => 'Concrete5Installer',
+ 'craft' => 'CraftInstaller',
+ 'croogo' => 'CroogoInstaller',
+ 'dframe' => 'DframeInstaller',
+ 'dokuwiki' => 'DokuWikiInstaller',
+ 'dolibarr' => 'DolibarrInstaller',
+ 'decibel' => 'DecibelInstaller',
+ 'drupal' => 'DrupalInstaller',
+ 'elgg' => 'ElggInstaller',
+ 'eliasis' => 'EliasisInstaller',
+ 'ee3' => 'ExpressionEngineInstaller',
+ 'ee2' => 'ExpressionEngineInstaller',
+ 'ezplatform' => 'EzPlatformInstaller',
+ 'fuel' => 'FuelInstaller',
+ 'fuelphp' => 'FuelphpInstaller',
+ 'grav' => 'GravInstaller',
+ 'hurad' => 'HuradInstaller',
+ 'tastyigniter' => 'TastyIgniterInstaller',
+ 'imagecms' => 'ImageCMSInstaller',
+ 'itop' => 'ItopInstaller',
+ 'joomla' => 'JoomlaInstaller',
+ 'kanboard' => 'KanboardInstaller',
+ 'kirby' => 'KirbyInstaller',
+ 'known' => 'KnownInstaller',
+ 'kodicms' => 'KodiCMSInstaller',
+ 'kohana' => 'KohanaInstaller',
+ 'lms' => 'LanManagementSystemInstaller',
+ 'laravel' => 'LaravelInstaller',
+ 'lavalite' => 'LavaLiteInstaller',
+ 'lithium' => 'LithiumInstaller',
+ 'magento' => 'MagentoInstaller',
+ 'majima' => 'MajimaInstaller',
+ 'mantisbt' => 'MantisBTInstaller',
+ 'mako' => 'MakoInstaller',
+ 'maya' => 'MayaInstaller',
+ 'mautic' => 'MauticInstaller',
+ 'mediawiki' => 'MediaWikiInstaller',
+ 'miaoxing' => 'MiaoxingInstaller',
+ 'microweber' => 'MicroweberInstaller',
+ 'modulework' => 'MODULEWorkInstaller',
+ 'modx' => 'ModxInstaller',
+ 'modxevo' => 'MODXEvoInstaller',
+ 'moodle' => 'MoodleInstaller',
+ 'october' => 'OctoberInstaller',
+ 'ontowiki' => 'OntoWikiInstaller',
+ 'oxid' => 'OxidInstaller',
+ 'osclass' => 'OsclassInstaller',
+ 'pxcms' => 'PxcmsInstaller',
+ 'phpbb' => 'PhpBBInstaller',
+ 'pimcore' => 'PimcoreInstaller',
+ 'piwik' => 'PiwikInstaller',
+ 'plentymarkets'=> 'PlentymarketsInstaller',
+ 'ppi' => 'PPIInstaller',
+ 'puppet' => 'PuppetInstaller',
+ 'radphp' => 'RadPHPInstaller',
+ 'phifty' => 'PhiftyInstaller',
+ 'porto' => 'PortoInstaller',
+ 'processwire' => 'ProcessWireInstaller',
+ 'quicksilver' => 'PantheonInstaller',
+ 'redaxo' => 'RedaxoInstaller',
+ 'redaxo5' => 'Redaxo5Installer',
+ 'reindex' => 'ReIndexInstaller',
+ 'roundcube' => 'RoundcubeInstaller',
+ 'shopware' => 'ShopwareInstaller',
+ 'sitedirect' => 'SiteDirectInstaller',
+ 'silverstripe' => 'SilverStripeInstaller',
+ 'smf' => 'SMFInstaller',
+ 'starbug' => 'StarbugInstaller',
+ 'sydes' => 'SyDESInstaller',
+ 'sylius' => 'SyliusInstaller',
+ 'symfony1' => 'Symfony1Installer',
+ 'tao' => 'TaoInstaller',
+ 'thelia' => 'TheliaInstaller',
+ 'tusk' => 'TuskInstaller',
+ 'typo3-cms' => 'TYPO3CmsInstaller',
+ 'typo3-flow' => 'TYPO3FlowInstaller',
+ 'userfrosting' => 'UserFrostingInstaller',
+ 'vanilla' => 'VanillaInstaller',
+ 'whmcs' => 'WHMCSInstaller',
+ 'winter' => 'WinterInstaller',
+ 'wolfcms' => 'WolfCMSInstaller',
+ 'wordpress' => 'WordPressInstaller',
+ 'yawik' => 'YawikInstaller',
+ 'zend' => 'ZendInstaller',
+ 'zikula' => 'ZikulaInstaller',
+ 'prestashop' => 'PrestashopInstaller'
+ );
+
+ /**
+ * Installer constructor.
+ *
+ * Disables installers specified in main composer extra installer-disable
+ * list
+ *
+ * @param IOInterface $io
+ * @param Composer $composer
+ * @param string $type
+ * @param Filesystem|null $filesystem
+ * @param BinaryInstaller|null $binaryInstaller
+ */
+ public function __construct(
+ IOInterface $io,
+ Composer $composer,
+ $type = 'library',
+ Filesystem $filesystem = null,
+ BinaryInstaller $binaryInstaller = null
+ ) {
+ parent::__construct($io, $composer, $type, $filesystem,
+ $binaryInstaller);
+ $this->removeDisabledInstallers();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getInstallPath(PackageInterface $package)
+ {
+ $type = $package->getType();
+ $frameworkType = $this->findFrameworkType($type);
+
+ if ($frameworkType === false) {
+ throw new \InvalidArgumentException(
+ 'Sorry the package type of this package is not yet supported.'
+ );
+ }
+
+ $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
+ $installer = new $class($package, $this->composer, $this->getIO());
+
+ return $installer->getInstallPath($package, $frameworkType);
+ }
+
+ public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
+ {
+ $installPath = $this->getPackageBasePath($package);
+ $io = $this->io;
+ $outputStatus = function () use ($io, $installPath) {
+ $io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? 'deleted' : 'not deleted'));
+ };
+
+ $promise = parent::uninstall($repo, $package);
+
+ // Composer v2 might return a promise here
+ if ($promise instanceof PromiseInterface) {
+ return $promise->then($outputStatus);
+ }
+
+ // If not, execute the code right away as parent::uninstall executed synchronously (composer v1, or v2 without async)
+ $outputStatus();
+
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supports($packageType)
+ {
+ $frameworkType = $this->findFrameworkType($packageType);
+
+ if ($frameworkType === false) {
+ return false;
+ }
+
+ $locationPattern = $this->getLocationPattern($frameworkType);
+
+ return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
+ }
+
+ /**
+ * Finds a supported framework type if it exists and returns it
+ *
+ * @param string $type
+ * @return string|false
+ */
+ protected function findFrameworkType($type)
+ {
+ krsort($this->supportedTypes);
+
+ foreach ($this->supportedTypes as $key => $val) {
+ if ($key === substr($type, 0, strlen($key))) {
+ return substr($type, 0, strlen($key));
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the second part of the regular expression to check for support of a
+ * package type
+ *
+ * @param string $frameworkType
+ * @return string
+ */
+ protected function getLocationPattern($frameworkType)
+ {
+ $pattern = false;
+ if (!empty($this->supportedTypes[$frameworkType])) {
+ $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
+ /** @var BaseInstaller $framework */
+ $framework = new $frameworkClass(null, $this->composer, $this->getIO());
+ $locations = array_keys($framework->getLocations());
+ $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
+ }
+
+ return $pattern ? : '(\w+)';
+ }
+
+ /**
+ * Get I/O object
+ *
+ * @return IOInterface
+ */
+ private function getIO()
+ {
+ return $this->io;
+ }
+
+ /**
+ * Look for installers set to be disabled in composer's extra config and
+ * remove them from the list of supported installers.
+ *
+ * Globals:
+ * - true, "all", and "*" - disable all installers.
+ * - false - enable all installers (useful with
+ * wikimedia/composer-merge-plugin or similar)
+ *
+ * @return void
+ */
+ protected function removeDisabledInstallers()
+ {
+ $extra = $this->composer->getPackage()->getExtra();
+
+ if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) {
+ // No installers are disabled
+ return;
+ }
+
+ // Get installers to disable
+ $disable = $extra['installer-disable'];
+
+ // Ensure $disabled is an array
+ if (!is_array($disable)) {
+ $disable = array($disable);
+ }
+
+ // Check which installers should be disabled
+ $all = array(true, "all", "*");
+ $intersect = array_intersect($all, $disable);
+ if (!empty($intersect)) {
+ // Disable all installers
+ $this->supportedTypes = array();
+ } else {
+ // Disable specified installers
+ foreach ($disable as $key => $installer) {
+ if (is_string($installer) && key_exists($installer, $this->supportedTypes)) {
+ unset($this->supportedTypes[$installer]);
+ }
+ }
+ }
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php
new file mode 100644
index 00000000..c6c1b337
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php
@@ -0,0 +1,9 @@
+ 'extensions/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php
new file mode 100644
index 00000000..9ee77596
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php
@@ -0,0 +1,15 @@
+ 'components/{$name}/',
+ 'module' => 'modules/{$name}/',
+ 'template' => 'templates/{$name}/',
+ 'plugin' => 'plugins/{$name}/',
+ 'library' => 'libraries/{$name}/',
+ );
+
+ // TODO: Add inflector for mod_ and com_ names
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php
new file mode 100644
index 00000000..9cb7b8cd
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php
@@ -0,0 +1,18 @@
+ 'plugins/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php
new file mode 100644
index 00000000..36b2f84a
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php
@@ -0,0 +1,11 @@
+ 'site/plugins/{$name}/',
+ 'field' => 'site/fields/{$name}/',
+ 'tag' => 'site/tags/{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php
new file mode 100644
index 00000000..c5d08c5f
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php
@@ -0,0 +1,11 @@
+ 'IdnoPlugins/{$name}/',
+ 'theme' => 'Themes/{$name}/',
+ 'console' => 'ConsolePlugins/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php
new file mode 100644
index 00000000..7143e232
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php
@@ -0,0 +1,10 @@
+ 'cms/plugins/{$name}/',
+ 'media' => 'cms/media/vendor/{$name}/'
+ );
+}
\ No newline at end of file
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php
new file mode 100644
index 00000000..dcd6d263
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php
new file mode 100644
index 00000000..903143a5
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php
@@ -0,0 +1,27 @@
+ 'plugins/{$name}/',
+ 'template' => 'templates/{$name}/',
+ 'document-template' => 'documents/templates/{$name}/',
+ 'userpanel-module' => 'userpanel/modules/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php
new file mode 100644
index 00000000..be4d53a7
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php
@@ -0,0 +1,9 @@
+ 'libraries/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php
new file mode 100644
index 00000000..412c0b5c
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php
@@ -0,0 +1,10 @@
+ 'packages/{$vendor}/{$name}/',
+ 'theme' => 'public/themes/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php
new file mode 100644
index 00000000..47bbd4ca
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php
@@ -0,0 +1,10 @@
+ 'libraries/{$name}/',
+ 'source' => 'libraries/_source/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php
new file mode 100644
index 00000000..9c2e9fb4
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php
new file mode 100644
index 00000000..5a664608
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php
@@ -0,0 +1,16 @@
+ 'assets/snippets/{$name}/',
+ 'plugin' => 'assets/plugins/{$name}/',
+ 'module' => 'assets/modules/{$name}/',
+ 'template' => 'assets/templates/{$name}/',
+ 'lib' => 'assets/lib/{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php
new file mode 100644
index 00000000..cf18e947
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php
@@ -0,0 +1,11 @@
+ 'app/design/frontend/{$name}/',
+ 'skin' => 'skin/frontend/default/{$name}/',
+ 'library' => 'lib/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php
new file mode 100644
index 00000000..e463756f
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php
@@ -0,0 +1,37 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Transforms the names
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ return $this->correctPluginName($vars);
+ }
+
+ /**
+ * Change hyphenated names to camelcase
+ * @param array $vars
+ * @return array
+ */
+ private function correctPluginName($vars)
+ {
+ $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, $vars['name']);
+ $vars['name'] = ucfirst($camelCasedName);
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php
new file mode 100644
index 00000000..ca3cfacb
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php
@@ -0,0 +1,9 @@
+ 'app/packages/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php
new file mode 100644
index 00000000..dadb1dbb
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php
@@ -0,0 +1,23 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php
new file mode 100644
index 00000000..c3dd2b6f
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php
@@ -0,0 +1,48 @@
+ 'plugins/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ 'core' => 'app/',
+ );
+
+ private function getDirectoryName()
+ {
+ $extra = $this->package->getExtra();
+ if (!empty($extra['install-directory-name'])) {
+ return $extra['install-directory-name'];
+ }
+
+ return $this->toCamelCase($this->package->getPrettyName());
+ }
+
+ /**
+ * @param string $packageName
+ *
+ * @return string
+ */
+ private function toCamelCase($packageName)
+ {
+ return str_replace(' ', '', ucwords(str_replace('-', ' ', basename($packageName))));
+ }
+
+ /**
+ * Format package name of mautic-plugins to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+
+ if ($vars['type'] == 'mautic-plugin' || $vars['type'] == 'mautic-theme') {
+ $directoryName = $this->getDirectoryName();
+ $vars['name'] = $directoryName;
+ }
+
+ return $vars;
+ }
+
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php
new file mode 100644
index 00000000..30a91676
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php
@@ -0,0 +1,33 @@
+ 'modules/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type maya-module, cut off a trailing '-module' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'maya-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectModuleVars($vars)
+ {
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php
new file mode 100644
index 00000000..f5a8957e
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php
@@ -0,0 +1,51 @@
+ 'core/',
+ 'extension' => 'extensions/{$name}/',
+ 'skin' => 'skins/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type mediawiki-extension, cut off a trailing '-extension' if present and transform
+ * to CamelCase keeping existing uppercase chars.
+ *
+ * For package type mediawiki-skin, cut off a trailing '-skin' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+
+ if ($vars['type'] === 'mediawiki-extension') {
+ return $this->inflectExtensionVars($vars);
+ }
+
+ if ($vars['type'] === 'mediawiki-skin') {
+ return $this->inflectSkinVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectExtensionVars($vars)
+ {
+ $vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
+ $vars['name'] = str_replace('-', ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectSkinVars($vars)
+ {
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php
new file mode 100644
index 00000000..66d8369c
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php
@@ -0,0 +1,10 @@
+ 'plugins/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php
new file mode 100644
index 00000000..b7d97039
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php
@@ -0,0 +1,119 @@
+ 'userfiles/modules/{$install_item_dir}/',
+ 'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/',
+ 'template' => 'userfiles/templates/{$install_item_dir}/',
+ 'element' => 'userfiles/elements/{$install_item_dir}/',
+ 'vendor' => 'vendor/{$install_item_dir}/',
+ 'components' => 'components/{$install_item_dir}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type microweber-module, cut off a trailing '-module' if present
+ *
+ * For package type microweber-template, cut off a trailing '-template' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+
+
+ if ($this->package->getTargetDir()) {
+ $vars['install_item_dir'] = $this->package->getTargetDir();
+ } else {
+ $vars['install_item_dir'] = $vars['name'];
+ if ($vars['type'] === 'microweber-template') {
+ return $this->inflectTemplateVars($vars);
+ }
+ if ($vars['type'] === 'microweber-templates') {
+ return $this->inflectTemplatesVars($vars);
+ }
+ if ($vars['type'] === 'microweber-core') {
+ return $this->inflectCoreVars($vars);
+ }
+ if ($vars['type'] === 'microweber-adapter') {
+ return $this->inflectCoreVars($vars);
+ }
+ if ($vars['type'] === 'microweber-module') {
+ return $this->inflectModuleVars($vars);
+ }
+ if ($vars['type'] === 'microweber-modules') {
+ return $this->inflectModulesVars($vars);
+ }
+ if ($vars['type'] === 'microweber-skin') {
+ return $this->inflectSkinVars($vars);
+ }
+ if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') {
+ return $this->inflectElementVars($vars);
+ }
+ }
+
+
+ return $vars;
+ }
+
+ protected function inflectTemplateVars($vars)
+ {
+ $vars['install_item_dir'] = preg_replace('/-template$/', '', $vars['install_item_dir']);
+ $vars['install_item_dir'] = preg_replace('/template-$/', '', $vars['install_item_dir']);
+
+ return $vars;
+ }
+
+ protected function inflectTemplatesVars($vars)
+ {
+ $vars['install_item_dir'] = preg_replace('/-templates$/', '', $vars['install_item_dir']);
+ $vars['install_item_dir'] = preg_replace('/templates-$/', '', $vars['install_item_dir']);
+
+ return $vars;
+ }
+
+ protected function inflectCoreVars($vars)
+ {
+ $vars['install_item_dir'] = preg_replace('/-providers$/', '', $vars['install_item_dir']);
+ $vars['install_item_dir'] = preg_replace('/-provider$/', '', $vars['install_item_dir']);
+ $vars['install_item_dir'] = preg_replace('/-adapter$/', '', $vars['install_item_dir']);
+
+ return $vars;
+ }
+
+ protected function inflectModuleVars($vars)
+ {
+ $vars['install_item_dir'] = preg_replace('/-module$/', '', $vars['install_item_dir']);
+ $vars['install_item_dir'] = preg_replace('/module-$/', '', $vars['install_item_dir']);
+
+ return $vars;
+ }
+
+ protected function inflectModulesVars($vars)
+ {
+ $vars['install_item_dir'] = preg_replace('/-modules$/', '', $vars['install_item_dir']);
+ $vars['install_item_dir'] = preg_replace('/modules-$/', '', $vars['install_item_dir']);
+
+ return $vars;
+ }
+
+ protected function inflectSkinVars($vars)
+ {
+ $vars['install_item_dir'] = preg_replace('/-skin$/', '', $vars['install_item_dir']);
+ $vars['install_item_dir'] = preg_replace('/skin-$/', '', $vars['install_item_dir']);
+
+ return $vars;
+ }
+
+ protected function inflectElementVars($vars)
+ {
+ $vars['install_item_dir'] = preg_replace('/-elements$/', '', $vars['install_item_dir']);
+ $vars['install_item_dir'] = preg_replace('/elements-$/', '', $vars['install_item_dir']);
+ $vars['install_item_dir'] = preg_replace('/-element$/', '', $vars['install_item_dir']);
+ $vars['install_item_dir'] = preg_replace('/element-$/', '', $vars['install_item_dir']);
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php
new file mode 100644
index 00000000..0ee140ab
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php
@@ -0,0 +1,12 @@
+ 'core/packages/{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php
new file mode 100644
index 00000000..05317995
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php
@@ -0,0 +1,59 @@
+ 'mod/{$name}/',
+ 'admin_report' => 'admin/report/{$name}/',
+ 'atto' => 'lib/editor/atto/plugins/{$name}/',
+ 'tool' => 'admin/tool/{$name}/',
+ 'assignment' => 'mod/assignment/type/{$name}/',
+ 'assignsubmission' => 'mod/assign/submission/{$name}/',
+ 'assignfeedback' => 'mod/assign/feedback/{$name}/',
+ 'auth' => 'auth/{$name}/',
+ 'availability' => 'availability/condition/{$name}/',
+ 'block' => 'blocks/{$name}/',
+ 'booktool' => 'mod/book/tool/{$name}/',
+ 'cachestore' => 'cache/stores/{$name}/',
+ 'cachelock' => 'cache/locks/{$name}/',
+ 'calendartype' => 'calendar/type/{$name}/',
+ 'fileconverter' => 'files/converter/{$name}/',
+ 'format' => 'course/format/{$name}/',
+ 'coursereport' => 'course/report/{$name}/',
+ 'customcertelement' => 'mod/customcert/element/{$name}/',
+ 'datafield' => 'mod/data/field/{$name}/',
+ 'datapreset' => 'mod/data/preset/{$name}/',
+ 'editor' => 'lib/editor/{$name}/',
+ 'enrol' => 'enrol/{$name}/',
+ 'filter' => 'filter/{$name}/',
+ 'gradeexport' => 'grade/export/{$name}/',
+ 'gradeimport' => 'grade/import/{$name}/',
+ 'gradereport' => 'grade/report/{$name}/',
+ 'gradingform' => 'grade/grading/form/{$name}/',
+ 'local' => 'local/{$name}/',
+ 'logstore' => 'admin/tool/log/store/{$name}/',
+ 'ltisource' => 'mod/lti/source/{$name}/',
+ 'ltiservice' => 'mod/lti/service/{$name}/',
+ 'message' => 'message/output/{$name}/',
+ 'mnetservice' => 'mnet/service/{$name}/',
+ 'plagiarism' => 'plagiarism/{$name}/',
+ 'portfolio' => 'portfolio/{$name}/',
+ 'qbehaviour' => 'question/behaviour/{$name}/',
+ 'qformat' => 'question/format/{$name}/',
+ 'qtype' => 'question/type/{$name}/',
+ 'quizaccess' => 'mod/quiz/accessrule/{$name}/',
+ 'quiz' => 'mod/quiz/report/{$name}/',
+ 'report' => 'report/{$name}/',
+ 'repository' => 'repository/{$name}/',
+ 'scormreport' => 'mod/scorm/report/{$name}/',
+ 'search' => 'search/engine/{$name}/',
+ 'theme' => 'theme/{$name}/',
+ 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
+ 'profilefield' => 'user/profile/field/{$name}/',
+ 'webservice' => 'webservice/{$name}/',
+ 'workshopallocation' => 'mod/workshop/allocation/{$name}/',
+ 'workshopeval' => 'mod/workshop/eval/{$name}/',
+ 'workshopform' => 'mod/workshop/form/{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php
new file mode 100644
index 00000000..489ef02a
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php
@@ -0,0 +1,48 @@
+ 'modules/{$name}/',
+ 'plugin' => 'plugins/{$vendor}/{$name}/',
+ 'theme' => 'themes/{$vendor}-{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type october-plugin, cut off a trailing '-plugin' if present.
+ *
+ * For package type october-theme, cut off a trailing '-theme' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'october-plugin') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'october-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']);
+ $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']);
+ $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php
new file mode 100644
index 00000000..5dd3438d
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php
@@ -0,0 +1,24 @@
+ 'extensions/{$name}/',
+ 'theme' => 'extensions/themes/{$name}/',
+ 'translation' => 'extensions/translations/{$name}/',
+ );
+
+ /**
+ * Format package name to lower case and remove ".ontowiki" suffix
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower($vars['name']);
+ $vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-translation$/', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php
new file mode 100644
index 00000000..3ca7954c
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php
@@ -0,0 +1,14 @@
+ 'oc-content/plugins/{$name}/',
+ 'theme' => 'oc-content/themes/{$name}/',
+ 'language' => 'oc-content/languages/{$name}/',
+ );
+
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php
new file mode 100644
index 00000000..1797a22c
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php
@@ -0,0 +1,59 @@
+.+)\/.+/';
+
+ protected $locations = array(
+ 'module' => 'modules/{$name}/',
+ 'theme' => 'application/views/{$name}/',
+ 'out' => 'out/{$name}/',
+ );
+
+ /**
+ * getInstallPath
+ *
+ * @param PackageInterface $package
+ * @param string $frameworkType
+ * @return string
+ */
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+ $installPath = parent::getInstallPath($package, $frameworkType);
+ $type = $this->package->getType();
+ if ($type === 'oxid-module') {
+ $this->prepareVendorDirectory($installPath);
+ }
+ return $installPath;
+ }
+
+ /**
+ * prepareVendorDirectory
+ *
+ * Makes sure there is a vendormetadata.php file inside
+ * the vendor folder if there is a vendor folder.
+ *
+ * @param string $installPath
+ * @return void
+ */
+ protected function prepareVendorDirectory($installPath)
+ {
+ $matches = '';
+ $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches);
+ if (!$hasVendorDirectory) {
+ return;
+ }
+
+ $vendorDirectory = $matches['vendor'];
+ $vendorPath = getcwd() . '/modules/' . $vendorDirectory;
+ if (!file_exists($vendorPath)) {
+ mkdir($vendorPath, 0755, true);
+ }
+
+ $vendorMetaDataPath = $vendorPath . '/vendormetadata.php';
+ touch($vendorMetaDataPath);
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php
new file mode 100644
index 00000000..170136f9
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PantheonInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PantheonInstaller.php
new file mode 100644
index 00000000..439f61a0
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PantheonInstaller.php
@@ -0,0 +1,12 @@
+ */
+ protected $locations = array(
+ 'script' => 'web/private/scripts/quicksilver/{$name}',
+ 'module' => 'web/private/scripts/quicksilver/{$name}',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php
new file mode 100644
index 00000000..4e59a8a7
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php
@@ -0,0 +1,11 @@
+ 'bundles/{$name}/',
+ 'library' => 'libraries/{$name}/',
+ 'framework' => 'frameworks/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php
new file mode 100644
index 00000000..deb2b77a
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php
@@ -0,0 +1,11 @@
+ 'ext/{$vendor}/{$name}/',
+ 'language' => 'language/{$name}/',
+ 'style' => 'styles/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php
new file mode 100644
index 00000000..4781fa6d
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php
@@ -0,0 +1,21 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php
new file mode 100644
index 00000000..c17f4572
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php
@@ -0,0 +1,32 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php
new file mode 100644
index 00000000..903e55f6
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php
@@ -0,0 +1,29 @@
+ '{$name}/'
+ );
+
+ /**
+ * Remove hyphen, "plugin" and format to camelcase
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = explode("-", $vars['name']);
+ foreach ($vars['name'] as $key => $name) {
+ $vars['name'][$key] = ucfirst($vars['name'][$key]);
+ if (strcasecmp($name, "Plugin") == 0) {
+ unset($vars['name'][$key]);
+ }
+ }
+ $vars['name'] = implode("",$vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/Plugin.php b/includes/vendor/composer/installers/src/Composer/Installers/Plugin.php
new file mode 100644
index 00000000..e60da0e7
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/Plugin.php
@@ -0,0 +1,27 @@
+installer = new Installer($io, $composer);
+ $composer->getInstallationManager()->addInstaller($this->installer);
+ }
+
+ public function deactivate(Composer $composer, IOInterface $io)
+ {
+ $composer->getInstallationManager()->removeInstaller($this->installer);
+ }
+
+ public function uninstall(Composer $composer, IOInterface $io)
+ {
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php
new file mode 100644
index 00000000..dbf85e63
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php
@@ -0,0 +1,9 @@
+ 'app/Containers/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php
new file mode 100644
index 00000000..4c8421e3
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php
@@ -0,0 +1,10 @@
+ 'modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php
new file mode 100644
index 00000000..e6834a0c
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php
@@ -0,0 +1,22 @@
+ 'site/modules/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php
new file mode 100644
index 00000000..77cc3dd8
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php
@@ -0,0 +1,11 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php
new file mode 100644
index 00000000..65510580
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php
@@ -0,0 +1,63 @@
+ 'app/Modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'pxcms-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ if ($vars['type'] === 'pxcms-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ /**
+ * For package type pxcms-module, cut off a trailing '-plugin' if present.
+ *
+ * return string
+ */
+ protected function inflectModuleVars($vars)
+ {
+ $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
+ $vars['name'] = str_replace('module-', '', $vars['name']); // strip out module-
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']); // strip out -module
+ $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
+ $vars['name'] = ucwords($vars['name']); // make module name camelcased
+
+ return $vars;
+ }
+
+
+ /**
+ * For package type pxcms-module, cut off a trailing '-plugin' if present.
+ *
+ * return string
+ */
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
+ $vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme-
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); // strip out -theme
+ $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
+ $vars['name'] = ucwords($vars['name']); // make module name camelcased
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php
new file mode 100644
index 00000000..0f78b5ca
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php
@@ -0,0 +1,24 @@
+ 'src/{$name}/'
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $nameParts = explode('/', $vars['name']);
+ foreach ($nameParts as &$value) {
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
+ $value = str_replace(array('-', '_'), ' ', $value);
+ $value = str_replace(' ', '', ucwords($value));
+ }
+ $vars['name'] = implode('/', $nameParts);
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php
new file mode 100644
index 00000000..252c7339
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php
@@ -0,0 +1,10 @@
+ 'themes/{$name}/',
+ 'plugin' => 'plugins/{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php b/includes/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php
new file mode 100644
index 00000000..23a20347
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php
@@ -0,0 +1,10 @@
+ 'redaxo/src/addons/{$name}/',
+ 'bestyle-plugin' => 'redaxo/src/addons/be_style/plugins/{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php
new file mode 100644
index 00000000..09544576
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php
@@ -0,0 +1,10 @@
+ 'redaxo/include/addons/{$name}/',
+ 'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php
new file mode 100644
index 00000000..d8d795be
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php
@@ -0,0 +1,22 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Lowercase name and changes the name to a underscores
+ *
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(str_replace('-', '_', $vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php
new file mode 100644
index 00000000..1acd3b14
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php
@@ -0,0 +1,10 @@
+ 'Sources/{$name}/',
+ 'theme' => 'Themes/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php
new file mode 100644
index 00000000..7d20d27a
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php
@@ -0,0 +1,60 @@
+ 'engine/Shopware/Plugins/Local/Backend/{$name}/',
+ 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/',
+ 'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/',
+ 'theme' => 'templates/{$name}/',
+ 'plugin' => 'custom/plugins/{$name}/',
+ 'frontend-theme' => 'themes/Frontend/{$name}/',
+ );
+
+ /**
+ * Transforms the names
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'shopware-theme') {
+ return $this->correctThemeName($vars);
+ }
+
+ return $this->correctPluginName($vars);
+ }
+
+ /**
+ * Changes the name to a camelcased combination of vendor and name
+ * @param array $vars
+ * @return array
+ */
+ private function correctPluginName($vars)
+ {
+ $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, $vars['name']);
+
+ $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName);
+
+ return $vars;
+ }
+
+ /**
+ * Changes the name to a underscore separated name
+ * @param array $vars
+ * @return array
+ */
+ private function correctThemeName($vars)
+ {
+ $vars['name'] = str_replace('-', '_', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php
new file mode 100644
index 00000000..81910e9f
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php
@@ -0,0 +1,35 @@
+ '{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Return the install path based on package type.
+ *
+ * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework
+ * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0
+ *
+ * @param PackageInterface $package
+ * @param string $frameworkType
+ * @return string
+ */
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+ if (
+ $package->getName() == 'silverstripe/framework'
+ && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion())
+ && version_compare($package->getVersion(), '2.999.999') < 0
+ ) {
+ return $this->templatePath($this->locations['module'], array('name' => 'sapphire'));
+ }
+
+ return parent::getInstallPath($package, $frameworkType);
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php
new file mode 100644
index 00000000..762d94c6
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php
@@ -0,0 +1,25 @@
+ 'modules/{$vendor}/{$name}/',
+ 'plugin' => 'plugins/{$vendor}/{$name}/'
+ );
+
+ public function inflectPackageVars($vars)
+ {
+ return $this->parseVars($vars);
+ }
+
+ protected function parseVars($vars)
+ {
+ $vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor'];
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php
new file mode 100644
index 00000000..a31c9fda
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php
@@ -0,0 +1,12 @@
+ 'modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ 'custom-module' => 'app/modules/{$name}/',
+ 'custom-theme' => 'app/themes/{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php
new file mode 100644
index 00000000..8626a9bc
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php
@@ -0,0 +1,47 @@
+ 'app/modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Format module name.
+ *
+ * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present.
+ *
+ * {@inerhitDoc}
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] == 'sydes-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ if ($vars['type'] === 'sydes-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ public function inflectModuleVars($vars)
+ {
+ $vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']);
+ $vars['name'] = strtolower($vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php
new file mode 100644
index 00000000..4357a35b
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php
@@ -0,0 +1,9 @@
+ 'themes/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php b/includes/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php
new file mode 100644
index 00000000..1675c4f2
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php
@@ -0,0 +1,26 @@
+
+ */
+class Symfony1Installer extends BaseInstaller
+{
+ protected $locations = array(
+ 'plugin' => 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php
new file mode 100644
index 00000000..b1663e84
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php
@@ -0,0 +1,16 @@
+
+ */
+class TYPO3CmsInstaller extends BaseInstaller
+{
+ protected $locations = array(
+ 'extension' => 'typo3conf/ext/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php
new file mode 100644
index 00000000..42572f44
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php
@@ -0,0 +1,38 @@
+ 'Packages/Application/{$name}/',
+ 'framework' => 'Packages/Framework/{$name}/',
+ 'plugin' => 'Packages/Plugins/{$name}/',
+ 'site' => 'Packages/Sites/{$name}/',
+ 'boilerplate' => 'Packages/Boilerplates/{$name}/',
+ 'build' => 'Build/{$name}/',
+ );
+
+ /**
+ * Modify the package name to be a TYPO3 Flow style key.
+ *
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $autoload = $this->package->getAutoload();
+ if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) {
+ $namespace = key($autoload['psr-0']);
+ $vars['name'] = str_replace('\\', '.', $namespace);
+ }
+ if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) {
+ $namespace = key($autoload['psr-4']);
+ $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.');
+ }
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php
new file mode 100644
index 00000000..4f79a45f
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php
@@ -0,0 +1,30 @@
+ '{$name}'
+ );
+
+ public function inflectPackageVars($vars)
+ {
+ $extra = $this->package->getExtra();
+
+ if (array_key_exists(self::EXTRA_TAO_EXTENSION_NAME, $extra)) {
+ $vars['name'] = $extra[self::EXTRA_TAO_EXTENSION_NAME];
+ return $vars;
+ }
+
+ $vars['name'] = str_replace('extension-', '', $vars['name']);
+ $vars['name'] = str_replace('-', ' ', $vars['name']);
+ $vars['name'] = lcfirst(str_replace(' ', '', ucwords($vars['name'])));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php
new file mode 100644
index 00000000..e20e65b8
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php
@@ -0,0 +1,32 @@
+ 'extensions/{$vendor}/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * Cut off leading 'ti-ext-' or 'ti-theme-' if present.
+ * Strip vendor name of characters that is not alphanumeric or an underscore
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'tastyigniter-extension') {
+ $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
+ $vars['name'] = preg_replace('/^ti-ext-/', '', $vars['name']);
+ }
+
+ if ($vars['type'] === 'tastyigniter-theme') {
+ $vars['name'] = preg_replace('/^ti-theme-/', '', $vars['name']);
+ }
+
+ return $vars;
+ }
+}
\ No newline at end of file
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php
new file mode 100644
index 00000000..158af526
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php
@@ -0,0 +1,12 @@
+ 'local/modules/{$name}/',
+ 'frontoffice-template' => 'templates/frontOffice/{$name}/',
+ 'backoffice-template' => 'templates/backOffice/{$name}/',
+ 'email-template' => 'templates/email/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php
new file mode 100644
index 00000000..7c0113b8
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php
@@ -0,0 +1,14 @@
+
+ */
+ class TuskInstaller extends BaseInstaller
+ {
+ protected $locations = array(
+ 'task' => '.tusk/tasks/{$name}/',
+ 'command' => '.tusk/commands/{$name}/',
+ 'asset' => 'assets/tusk/{$name}/',
+ );
+ }
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php
new file mode 100644
index 00000000..fcb414ab
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php
@@ -0,0 +1,9 @@
+ 'app/sprinkles/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php
new file mode 100644
index 00000000..24ca6451
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php
@@ -0,0 +1,10 @@
+ 'plugins/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php
new file mode 100644
index 00000000..7d90c5e6
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php
@@ -0,0 +1,49 @@
+ 'src/{$vendor}/{$name}/',
+ 'theme' => 'themes/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type vgmcp-bundle, cut off a trailing '-bundle' if present.
+ *
+ * For package type vgmcp-theme, cut off a trailing '-theme' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'vgmcp-bundle') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'vgmcp-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-bundle$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php
new file mode 100644
index 00000000..b65dbbaf
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php
@@ -0,0 +1,21 @@
+ 'modules/addons/{$vendor}_{$name}/',
+ 'fraud' => 'modules/fraud/{$vendor}_{$name}/',
+ 'gateways' => 'modules/gateways/{$vendor}_{$name}/',
+ 'notifications' => 'modules/notifications/{$vendor}_{$name}/',
+ 'registrars' => 'modules/registrars/{$vendor}_{$name}/',
+ 'reports' => 'modules/reports/{$vendor}_{$name}/',
+ 'security' => 'modules/security/{$vendor}_{$name}/',
+ 'servers' => 'modules/servers/{$vendor}_{$name}/',
+ 'social' => 'modules/social/{$vendor}_{$name}/',
+ 'support' => 'modules/support/{$vendor}_{$name}/',
+ 'templates' => 'templates/{$vendor}_{$name}/',
+ 'includes' => 'includes/{$vendor}_{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php
new file mode 100644
index 00000000..cff1bf19
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php
@@ -0,0 +1,58 @@
+ 'modules/{$name}/',
+ 'plugin' => 'plugins/{$vendor}/{$name}/',
+ 'theme' => 'themes/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type winter-plugin, cut off a trailing '-plugin' if present.
+ *
+ * For package type winter-theme, cut off a trailing '-theme' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'winter-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ if ($vars['type'] === 'winter-plugin') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'winter-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectModuleVars($vars)
+ {
+ $vars['name'] = preg_replace('/^wn-|-module$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/^wn-|-plugin$/', '', $vars['name']);
+ $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/^wn-|-theme$/', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php
new file mode 100644
index 00000000..cb387881
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php
@@ -0,0 +1,9 @@
+ 'wolf/plugins/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php
new file mode 100644
index 00000000..91c46ad9
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php
@@ -0,0 +1,12 @@
+ 'wp-content/plugins/{$name}/',
+ 'theme' => 'wp-content/themes/{$name}/',
+ 'muplugin' => 'wp-content/mu-plugins/{$name}/',
+ 'dropin' => 'wp-content/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php
new file mode 100644
index 00000000..27f429ff
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php
@@ -0,0 +1,32 @@
+ 'module/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
\ No newline at end of file
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php
new file mode 100644
index 00000000..bde9bc8c
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php
@@ -0,0 +1,11 @@
+ 'library/{$name}/',
+ 'extra' => 'extras/library/{$name}/',
+ 'module' => 'module/{$name}/',
+ );
+}
diff --git a/includes/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php b/includes/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php
new file mode 100644
index 00000000..56cdf5da
--- /dev/null
+++ b/includes/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php
@@ -0,0 +1,10 @@
+ 'modules/{$vendor}-{$name}/',
+ 'theme' => 'themes/{$vendor}-{$name}/'
+ );
+}
diff --git a/includes/vendor/composer/installers/src/bootstrap.php b/includes/vendor/composer/installers/src/bootstrap.php
new file mode 100644
index 00000000..0de276ee
--- /dev/null
+++ b/includes/vendor/composer/installers/src/bootstrap.php
@@ -0,0 +1,13 @@
+= 70400)) {
+ $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.';
+}
+
+if ($issues) {
+ if (!headers_sent()) {
+ header('HTTP/1.1 500 Internal Server Error');
+ }
+ if (!ini_get('display_errors')) {
+ if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+ fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
+ } elseif (!headers_sent()) {
+ echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
+ }
+ }
+ trigger_error(
+ 'Composer detected issues in your platform: ' . implode(' ', $issues),
+ E_USER_ERROR
+ );
+}
diff --git a/includes/vendor/firebase/php-jwt/.gitignore b/includes/vendor/firebase/php-jwt/.gitignore
deleted file mode 100644
index 7c29c87b..00000000
--- a/includes/vendor/firebase/php-jwt/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-vendor
-phpunit.phar
-phpunit.phar.asc
-composer.phar
diff --git a/includes/vendor/firebase/php-jwt/.travis.yml b/includes/vendor/firebase/php-jwt/.travis.yml
deleted file mode 100644
index 0bd12c5a..00000000
--- a/includes/vendor/firebase/php-jwt/.travis.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-language: php
-
-php:
- - 5.3
- - 5.4
- - 5.5
- - hhvm
-
-before_script:
- - wget -nc http://getcomposer.org/composer.phar
- - php composer.phar install
-
-script: phpunit --configuration phpunit.xml.dist
diff --git a/includes/vendor/firebase/php-jwt/CHANGELOG.md b/includes/vendor/firebase/php-jwt/CHANGELOG.md
new file mode 100644
index 00000000..9242bd30
--- /dev/null
+++ b/includes/vendor/firebase/php-jwt/CHANGELOG.md
@@ -0,0 +1,105 @@
+# Changelog
+
+## [6.4.0](https://github.com/firebase/php-jwt/compare/v6.3.2...v6.4.0) (2023-02-08)
+
+
+### Features
+
+* add support for W3C ES256K ([#462](https://github.com/firebase/php-jwt/issues/462)) ([213924f](https://github.com/firebase/php-jwt/commit/213924f51936291fbbca99158b11bd4ae56c2c95))
+* improve caching by only decoding jwks when necessary ([#486](https://github.com/firebase/php-jwt/issues/486)) ([78d3ed1](https://github.com/firebase/php-jwt/commit/78d3ed1073553f7d0bbffa6c2010009a0d483d5c))
+
+## [6.3.2](https://github.com/firebase/php-jwt/compare/v6.3.1...v6.3.2) (2022-11-01)
+
+
+### Bug Fixes
+
+* check kid before using as array index ([bad1b04](https://github.com/firebase/php-jwt/commit/bad1b040d0c736bbf86814c6b5ae614f517cf7bd))
+
+## [6.3.1](https://github.com/firebase/php-jwt/compare/v6.3.0...v6.3.1) (2022-11-01)
+
+
+### Bug Fixes
+
+* casing of GET for PSR compat ([#451](https://github.com/firebase/php-jwt/issues/451)) ([60b52b7](https://github.com/firebase/php-jwt/commit/60b52b71978790eafcf3b95cfbd83db0439e8d22))
+* string interpolation format for php 8.2 ([#446](https://github.com/firebase/php-jwt/issues/446)) ([2e07d8a](https://github.com/firebase/php-jwt/commit/2e07d8a1524d12b69b110ad649f17461d068b8f2))
+
+## 6.3.0 / 2022-07-15
+
+ - Added ES256 support to JWK parsing ([#399](https://github.com/firebase/php-jwt/pull/399))
+ - Fixed potential caching error in `CachedKeySet` by caching jwks as strings ([#435](https://github.com/firebase/php-jwt/pull/435))
+
+## 6.2.0 / 2022-05-14
+
+ - Added `CachedKeySet` ([#397](https://github.com/firebase/php-jwt/pull/397))
+ - Added `$defaultAlg` parameter to `JWT::parseKey` and `JWT::parseKeySet` ([#426](https://github.com/firebase/php-jwt/pull/426)).
+
+## 6.1.0 / 2022-03-23
+
+ - Drop support for PHP 5.3, 5.4, 5.5, 5.6, and 7.0
+ - Add parameter typing and return types where possible
+
+## 6.0.0 / 2022-01-24
+
+ - **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v6.0.0) for more information.
+ - New Key object to prevent key/algorithm type confusion (#365)
+ - Add JWK support (#273)
+ - Add ES256 support (#256)
+ - Add ES384 support (#324)
+ - Add Ed25519 support (#343)
+
+## 5.0.0 / 2017-06-26
+- Support RS384 and RS512.
+ See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)!
+- Add an example for RS256 openssl.
+ See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)!
+- Detect invalid Base64 encoding in signature.
+ See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)!
+- Update `JWT::verify` to handle OpenSSL errors.
+ See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)!
+- Add `array` type hinting to `decode` method
+ See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)!
+- Add all JSON error types.
+ See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)!
+- Bugfix 'kid' not in given key list.
+ See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)!
+- Miscellaneous cleanup, documentation and test fixes.
+ See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115),
+ [#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and
+ [#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman),
+ [@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)!
+
+## 4.0.0 / 2016-07-17
+- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)!
+- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)!
+- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)!
+- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)!
+
+## 3.0.0 / 2015-07-22
+- Minimum PHP version updated from `5.2.0` to `5.3.0`.
+- Add `\Firebase\JWT` namespace. See
+[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to
+[@Dashron](https://github.com/Dashron)!
+- Require a non-empty key to decode and verify a JWT. See
+[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to
+[@sjones608](https://github.com/sjones608)!
+- Cleaner documentation blocks in the code. See
+[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to
+[@johanderuijter](https://github.com/johanderuijter)!
+
+## 2.2.0 / 2015-06-22
+- Add support for adding custom, optional JWT headers to `JWT::encode()`. See
+[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to
+[@mcocaro](https://github.com/mcocaro)!
+
+## 2.1.0 / 2015-05-20
+- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew
+between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)!
+- Add support for passing an object implementing the `ArrayAccess` interface for
+`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)!
+
+## 2.0.0 / 2015-04-01
+- **Note**: It is strongly recommended that you update to > v2.0.0 to address
+ known security vulnerabilities in prior versions when both symmetric and
+ asymmetric keys are used together.
+- Update signature for `JWT::decode(...)` to require an array of supported
+ algorithms to use when verifying token signatures.
diff --git a/includes/vendor/firebase/php-jwt/LICENSE b/includes/vendor/firebase/php-jwt/LICENSE
index cb0c49b3..11c01466 100644
--- a/includes/vendor/firebase/php-jwt/LICENSE
+++ b/includes/vendor/firebase/php-jwt/LICENSE
@@ -13,7 +13,7 @@ modification, are permitted provided that the following conditions are met:
disclaimer in the documentation and/or other materials provided
with the distribution.
- * Neither the name of Neuman Vong nor the names of other
+ * Neither the name of the copyright holder nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
diff --git a/includes/vendor/firebase/php-jwt/README.md b/includes/vendor/firebase/php-jwt/README.md
index 7f1b026b..ae2b3895 100644
--- a/includes/vendor/firebase/php-jwt/README.md
+++ b/includes/vendor/firebase/php-jwt/README.md
@@ -1,12 +1,11 @@
-[](https://travis-ci.org/firebase/php-jwt)
+
[](https://packagist.org/packages/firebase/php-jwt)
[](https://packagist.org/packages/firebase/php-jwt)
[](https://packagist.org/packages/firebase/php-jwt)
PHP-JWT
=======
-A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should
-conform to the [current spec](http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06)
+A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to [RFC 7519](https://tools.ietf.org/html/rfc7519).
Installation
------------
@@ -17,19 +16,26 @@ Use composer to manage your dependencies and download PHP-JWT:
composer require firebase/php-jwt
```
+Optionally, install the `paragonie/sodium_compat` package from composer if your
+php is < 7.2 or does not have libsodium installed:
+
+```bash
+composer require paragonie/sodium_compat
+```
+
Example
-------
```php
- "http://example.org/",
- "aud" => "http://example.com/",
- "iat" => 1356999524,
- "nbf" => 1357000000
-);
+use Firebase\JWT\JWT;
+use Firebase\JWT\Key;
+
+$key = 'example_key';
+$payload = [
+ 'iss' => 'http://example.org/',
+ 'aud' => 'http://example.com/',
+ 'iat' => 1356999524,
+ 'nbf' => 1357000000
+];
/**
* IMPORTANT:
@@ -37,8 +43,8 @@ $token = array(
* https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40
* for a list of spec-compliant algorithms.
*/
-$jwt = JWT::encode($token, $key);
-$decoded = JWT::decode($jwt, $key, array('HS256'));
+$jwt = JWT::encode($payload, $key, 'HS256');
+$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
print_r($decoded);
@@ -57,44 +63,250 @@ $decoded_array = (array) $decoded;
* Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef
*/
JWT::$leeway = 60; // $leeway in seconds
-$decoded = JWT::decode($jwt, $key, array('HS256'));
+$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
+```
+Example with RS256 (openssl)
+----------------------------
+```php
+use Firebase\JWT\JWT;
+use Firebase\JWT\Key;
+
+$privateKey = <<
+$payload = [
+ 'iss' => 'example.org',
+ 'aud' => 'example.com',
+ 'iat' => 1356999524,
+ 'nbf' => 1357000000
+];
+
+$jwt = JWT::encode($payload, $privateKey, 'RS256');
+echo "Encode:\n" . print_r($jwt, true) . "\n";
+
+$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256'));
+
+/*
+ NOTE: This will now be an object instead of an associative array. To get
+ an associative array, you will need to cast it as such:
+*/
+
+$decoded_array = (array) $decoded;
+echo "Decode:\n" . print_r($decoded_array, true) . "\n";
```
-Changelog
----------
-
-#### 3.0.0 / 2015-07-22
-- Minimum PHP version updated from `5.2.0` to `5.3.0`.
-- Add `\Firebase\JWT` namespace. See
-[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to
-[@Dashron](https://github.com/Dashron)!
-- Require a non-empty key to decode and verify a JWT. See
-[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to
-[@sjones608](https://github.com/sjones608)!
-- Cleaner documentation blocks in the code. See
-[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to
-[@johanderuijter](https://github.com/johanderuijter)!
-
-#### 2.2.0 / 2015-06-22
-- Add support for adding custom, optional JWT headers to `JWT::encode()`. See
-[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to
-[@mcocaro](https://github.com/mcocaro)!
-
-#### 2.1.0 / 2015-05-20
-- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew
-between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)!
-- Add support for passing an object implementing the `ArrayAccess` interface for
-`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)!
-
-#### 2.0.0 / 2015-04-01
-- **Note**: It is strongly recommended that you update to > v2.0.0 to address
- known security vulnerabilities in prior versions when both symmetric and
- asymmetric keys are used together.
-- Update signature for `JWT::decode(...)` to require an array of supported
- algorithms to use when verifying token signatures.
+Example with a passphrase
+-------------------------
+
+```php
+use Firebase\JWT\JWT;
+use Firebase\JWT\Key;
+
+// Your passphrase
+$passphrase = '[YOUR_PASSPHRASE]';
+
+// Your private key file with passphrase
+// Can be generated with "ssh-keygen -t rsa -m pem"
+$privateKeyFile = '/path/to/key-with-passphrase.pem';
+
+// Create a private key of type "resource"
+$privateKey = openssl_pkey_get_private(
+ file_get_contents($privateKeyFile),
+ $passphrase
+);
+
+$payload = [
+ 'iss' => 'example.org',
+ 'aud' => 'example.com',
+ 'iat' => 1356999524,
+ 'nbf' => 1357000000
+];
+
+$jwt = JWT::encode($payload, $privateKey, 'RS256');
+echo "Encode:\n" . print_r($jwt, true) . "\n";
+
+// Get public key from the private key, or pull from from a file.
+$publicKey = openssl_pkey_get_details($privateKey)['key'];
+
+$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256'));
+echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
+```
+
+Example with EdDSA (libsodium and Ed25519 signature)
+----------------------------
+```php
+use Firebase\JWT\JWT;
+use Firebase\JWT\Key;
+
+// Public and private keys are expected to be Base64 encoded. The last
+// non-empty line is used so that keys can be generated with
+// sodium_crypto_sign_keypair(). The secret keys generated by other tools may
+// need to be adjusted to match the input expected by libsodium.
+
+$keyPair = sodium_crypto_sign_keypair();
+
+$privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair));
+
+$publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair));
+
+$payload = [
+ 'iss' => 'example.org',
+ 'aud' => 'example.com',
+ 'iat' => 1356999524,
+ 'nbf' => 1357000000
+];
+
+$jwt = JWT::encode($payload, $privateKey, 'EdDSA');
+echo "Encode:\n" . print_r($jwt, true) . "\n";
+
+$decoded = JWT::decode($jwt, new Key($publicKey, 'EdDSA'));
+echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
+````
+Using JWKs
+----------
+
+```php
+use Firebase\JWT\JWK;
+use Firebase\JWT\JWT;
+
+// Set of keys. The "keys" key is required. For example, the JSON response to
+// this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk
+$jwks = ['keys' => []];
+
+// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key
+// objects. Pass this as the second parameter to JWT::decode.
+JWT::decode($payload, JWK::parseKeySet($jwks));
+```
+
+Using Cached Key Sets
+---------------------
+
+The `CachedKeySet` class can be used to fetch and cache JWKS (JSON Web Key Sets) from a public URI.
+This has the following advantages:
+
+1. The results are cached for performance.
+2. If an unrecognized key is requested, the cache is refreshed, to accomodate for key rotation.
+3. If rate limiting is enabled, the JWKS URI will not make more than 10 requests a second.
+
+```php
+use Firebase\JWT\CachedKeySet;
+use Firebase\JWT\JWT;
+
+// The URI for the JWKS you wish to cache the results from
+$jwksUri = 'https://www.gstatic.com/iap/verify/public_key-jwk';
+
+// Create an HTTP client (can be any PSR-7 compatible HTTP client)
+$httpClient = new GuzzleHttp\Client();
+
+// Create an HTTP request factory (can be any PSR-17 compatible HTTP request factory)
+$httpFactory = new GuzzleHttp\Psr\HttpFactory();
+
+// Create a cache item pool (can be any PSR-6 compatible cache item pool)
+$cacheItemPool = Phpfastcache\CacheManager::getInstance('files');
+
+$keySet = new CachedKeySet(
+ $jwksUri,
+ $httpClient,
+ $httpFactory,
+ $cacheItemPool,
+ null, // $expiresAfter int seconds to set the JWKS to expire
+ true // $rateLimit true to enable rate limit of 10 RPS on lookup of invalid keys
+);
+
+$jwt = 'eyJhbGci...'; // Some JWT signed by a key from the $jwkUri above
+$decoded = JWT::decode($jwt, $keySet);
+```
+
+Miscellaneous
+-------------
+
+#### Exception Handling
+
+When a call to `JWT::decode` is invalid, it will throw one of the following exceptions:
+
+```php
+use Firebase\JWT\JWT;
+use Firebase\JWT\SignatureInvalidException;
+use Firebase\JWT\BeforeValidException;
+use Firebase\JWT\ExpiredException;
+use DomainException;
+use InvalidArgumentException;
+use UnexpectedValueException;
+
+try {
+ $decoded = JWT::decode($payload, $keys);
+} catch (InvalidArgumentException $e) {
+ // provided key/key-array is empty or malformed.
+} catch (DomainException $e) {
+ // provided algorithm is unsupported OR
+ // provided key is invalid OR
+ // unknown error thrown in openSSL or libsodium OR
+ // libsodium is required but not available.
+} catch (SignatureInvalidException $e) {
+ // provided JWT signature verification failed.
+} catch (BeforeValidException $e) {
+ // provided JWT is trying to be used before "nbf" claim OR
+ // provided JWT is trying to be used before "iat" claim.
+} catch (ExpiredException $e) {
+ // provided JWT is trying to be used after "exp" claim.
+} catch (UnexpectedValueException $e) {
+ // provided JWT is malformed OR
+ // provided JWT is missing an algorithm / using an unsupported algorithm OR
+ // provided JWT algorithm does not match provided key OR
+ // provided key ID in key/key-array is empty or invalid.
+}
+```
+
+All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException`, and can be simplified
+like this:
+
+```php
+try {
+ $decoded = JWT::decode($payload, $keys);
+} catch (LogicException $e) {
+ // errors having to do with environmental setup or malformed JWT Keys
+} catch (UnexpectedValueException $e) {
+ // errors having to do with JWT signature and claims
+}
+```
+
+#### Casting to array
+
+The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays
+instead, you can do the following:
+
+```php
+// return type is stdClass
+$decoded = JWT::decode($payload, $keys);
+
+// cast to array
+$decoded = json_decode(json_encode($decoded), true);
+```
Tests
-----
@@ -109,6 +321,12 @@ Time: 0 seconds, Memory: 2.50Mb
OK (5 tests, 5 assertions)
```
+New Lines in private keys
+-----
+
+If your private key contains `\n` characters, be sure to wrap it in double quotes `""`
+and not single quotes `''` in order to properly interpret the escaped characters.
+
License
-------
[3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause).
diff --git a/includes/vendor/firebase/php-jwt/composer.json b/includes/vendor/firebase/php-jwt/composer.json
index 1a5e93b5..c9aa3dbb 100644
--- a/includes/vendor/firebase/php-jwt/composer.json
+++ b/includes/vendor/firebase/php-jwt/composer.json
@@ -2,6 +2,10 @@
"name": "firebase/php-jwt",
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
+ "keywords": [
+ "php",
+ "jwt"
+ ],
"authors": [
{
"name": "Neuman Vong",
@@ -16,12 +20,23 @@
],
"license": "BSD-3-Clause",
"require": {
- "php": ">=5.3.0"
+ "php": "^7.1||^8.0"
+ },
+ "suggest": {
+ "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present",
+ "ext-sodium": "Support EdDSA (Ed25519) signatures"
},
"autoload": {
"psr-4": {
"Firebase\\JWT\\": "src"
}
},
- "minimum-stability": "dev"
+ "require-dev": {
+ "guzzlehttp/guzzle": "^6.5||^7.4",
+ "phpspec/prophecy-phpunit": "^1.1",
+ "phpunit/phpunit": "^7.5||^9.5",
+ "psr/cache": "^1.0||^2.0",
+ "psr/http-client": "^1.0",
+ "psr/http-factory": "^1.0"
+ }
}
diff --git a/includes/vendor/firebase/php-jwt/composer.lock b/includes/vendor/firebase/php-jwt/composer.lock
deleted file mode 100644
index 5518ae41..00000000
--- a/includes/vendor/firebase/php-jwt/composer.lock
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "_readme": [
- "This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
- "This file is @generated automatically"
- ],
- "hash": "60a5df5d283a7ae9000173248eba8909",
- "packages": [],
- "packages-dev": [],
- "aliases": [],
- "minimum-stability": "dev",
- "stability-flags": [],
- "prefer-stable": false,
- "prefer-lowest": false,
- "platform": {
- "php": ">=5.2.0"
- },
- "platform-dev": []
-}
diff --git a/includes/vendor/firebase/php-jwt/package.xml b/includes/vendor/firebase/php-jwt/package.xml
deleted file mode 100644
index a95b056f..00000000
--- a/includes/vendor/firebase/php-jwt/package.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
- JWT
- pear.php.net
- A JWT encoder/decoder.
- A JWT encoder/decoder library for PHP.
-
- Neuman Vong
- lcfrs
- neuman+pear@twilio.com
- yes
-
-
- Firebase Operations
- firebase
- operations@firebase.com
- yes
-
- 2015-07-22
-
- 3.0.0
- 3.0.0
-
-
- beta
- beta
-
- BSD 3-Clause License
-
-Initial release with basic support for JWT encoding, decoding and signature verification.
-
-
-
-
-
-
-
-
-
-
-
-
- 5.1
-
-
- 1.7.0
-
-
- json
-
-
- hash
-
-
-
-
-
-
-
- 0.1.0
- 0.1.0
-
-
- beta
- beta
-
- 2015-04-01
- BSD 3-Clause License
-
-Initial release with basic support for JWT encoding, decoding and signature verification.
-
-
-
-
diff --git a/includes/vendor/firebase/php-jwt/phpunit.xml.dist b/includes/vendor/firebase/php-jwt/phpunit.xml.dist
deleted file mode 100644
index 9f85f5ba..00000000
--- a/includes/vendor/firebase/php-jwt/phpunit.xml.dist
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
- ./tests
-
-
-
diff --git a/includes/vendor/firebase/php-jwt/run-tests.sh b/includes/vendor/firebase/php-jwt/run-tests.sh
deleted file mode 100755
index d37c30fd..00000000
--- a/includes/vendor/firebase/php-jwt/run-tests.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#!/usr/bin/env bash
-gpg --fingerprint D8406D0D82947747293778314AA394086372C20A
-if [ $? -ne 0 ]; then
- echo -e "\033[33mDownloading PGP Public Key...\033[0m"
- gpg --recv-keys D8406D0D82947747293778314AA394086372C20A
- # Sebastian Bergmann
- gpg --fingerprint D8406D0D82947747293778314AA394086372C20A
- if [ $? -ne 0 ]; then
- echo -e "\033[31mCould not download PGP public key for verification\033[0m"
- exit
- fi
-fi
-
-# Let's grab the latest release and its signature
-if [ ! -f phpunit.phar ]; then
- wget https://phar.phpunit.de/phpunit.phar
-fi
-if [ ! -f phpunit.phar.asc ]; then
- wget https://phar.phpunit.de/phpunit.phar.asc
-fi
-
-# Verify before running
-gpg --verify phpunit.phar.asc phpunit.phar
-if [ $? -eq 0 ]; then
- echo
- echo -e "\033[33mBegin Unit Testing\033[0m"
- # Run the testing suite
- php --version
- php phpunit.phar --configuration phpunit.xml.dist
-else
- echo
- chmod -x phpunit.phar
- mv phpunit.phar /tmp/bad-phpunit.phar
- mv phpunit.phar.asc /tmp/bad-phpunit.phar.asc
- echo -e "\033[31mSignature did not match! PHPUnit has been moved to /tmp/bad-phpunit.phar\033[0m"
- exit 1
-fi
diff --git a/includes/vendor/firebase/php-jwt/src/BeforeValidException.php b/includes/vendor/firebase/php-jwt/src/BeforeValidException.php
index a6ee2f7c..c147852b 100644
--- a/includes/vendor/firebase/php-jwt/src/BeforeValidException.php
+++ b/includes/vendor/firebase/php-jwt/src/BeforeValidException.php
@@ -1,7 +1,7 @@
+ */
+class CachedKeySet implements ArrayAccess
+{
+ /**
+ * @var string
+ */
+ private $jwksUri;
+ /**
+ * @var ClientInterface
+ */
+ private $httpClient;
+ /**
+ * @var RequestFactoryInterface
+ */
+ private $httpFactory;
+ /**
+ * @var CacheItemPoolInterface
+ */
+ private $cache;
+ /**
+ * @var ?int
+ */
+ private $expiresAfter;
+ /**
+ * @var ?CacheItemInterface
+ */
+ private $cacheItem;
+ /**
+ * @var array>
+ */
+ private $keySet;
+ /**
+ * @var string
+ */
+ private $cacheKey;
+ /**
+ * @var string
+ */
+ private $cacheKeyPrefix = 'jwks';
+ /**
+ * @var int
+ */
+ private $maxKeyLength = 64;
+ /**
+ * @var bool
+ */
+ private $rateLimit;
+ /**
+ * @var string
+ */
+ private $rateLimitCacheKey;
+ /**
+ * @var int
+ */
+ private $maxCallsPerMinute = 10;
+ /**
+ * @var string|null
+ */
+ private $defaultAlg;
+
+ public function __construct(
+ string $jwksUri,
+ ClientInterface $httpClient,
+ RequestFactoryInterface $httpFactory,
+ CacheItemPoolInterface $cache,
+ int $expiresAfter = null,
+ bool $rateLimit = false,
+ string $defaultAlg = null
+ ) {
+ $this->jwksUri = $jwksUri;
+ $this->httpClient = $httpClient;
+ $this->httpFactory = $httpFactory;
+ $this->cache = $cache;
+ $this->expiresAfter = $expiresAfter;
+ $this->rateLimit = $rateLimit;
+ $this->defaultAlg = $defaultAlg;
+ $this->setCacheKeys();
+ }
+
+ /**
+ * @param string $keyId
+ * @return Key
+ */
+ public function offsetGet($keyId): Key
+ {
+ if (!$this->keyIdExists($keyId)) {
+ throw new OutOfBoundsException('Key ID not found');
+ }
+ return JWK::parseKey($this->keySet[$keyId], $this->defaultAlg);
+ }
+
+ /**
+ * @param string $keyId
+ * @return bool
+ */
+ public function offsetExists($keyId): bool
+ {
+ return $this->keyIdExists($keyId);
+ }
+
+ /**
+ * @param string $offset
+ * @param Key $value
+ */
+ public function offsetSet($offset, $value): void
+ {
+ throw new LogicException('Method not implemented');
+ }
+
+ /**
+ * @param string $offset
+ */
+ public function offsetUnset($offset): void
+ {
+ throw new LogicException('Method not implemented');
+ }
+
+ /**
+ * @return array
+ */
+ private function formatJwksForCache(string $jwks): array
+ {
+ $jwks = json_decode($jwks, true);
+
+ if (!isset($jwks['keys'])) {
+ throw new UnexpectedValueException('"keys" member must exist in the JWK Set');
+ }
+
+ if (empty($jwks['keys'])) {
+ throw new InvalidArgumentException('JWK Set did not contain any keys');
+ }
+
+ $keys = [];
+ foreach ($jwks['keys'] as $k => $v) {
+ $kid = isset($v['kid']) ? $v['kid'] : $k;
+ $keys[(string) $kid] = $v;
+ }
+
+ return $keys;
+ }
+
+ private function keyIdExists(string $keyId): bool
+ {
+ if (null === $this->keySet) {
+ $item = $this->getCacheItem();
+ // Try to load keys from cache
+ if ($item->isHit()) {
+ // item found! retrieve it
+ $this->keySet = $item->get();
+ // If the cached item is a string, the JWKS response was cached (previous behavior).
+ // Parse this into expected format array instead.
+ if (\is_string($this->keySet)) {
+ $this->keySet = $this->formatJwksForCache($this->keySet);
+ }
+ }
+ }
+
+ if (!isset($this->keySet[$keyId])) {
+ if ($this->rateLimitExceeded()) {
+ return false;
+ }
+ $request = $this->httpFactory->createRequest('GET', $this->jwksUri);
+ $jwksResponse = $this->httpClient->sendRequest($request);
+ $this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody());
+
+ if (!isset($this->keySet[$keyId])) {
+ return false;
+ }
+
+ $item = $this->getCacheItem();
+ $item->set($this->keySet);
+ if ($this->expiresAfter) {
+ $item->expiresAfter($this->expiresAfter);
+ }
+ $this->cache->save($item);
+ }
+
+ return true;
+ }
+
+ private function rateLimitExceeded(): bool
+ {
+ if (!$this->rateLimit) {
+ return false;
+ }
+
+ $cacheItem = $this->cache->getItem($this->rateLimitCacheKey);
+ if (!$cacheItem->isHit()) {
+ $cacheItem->expiresAfter(1); // # of calls are cached each minute
+ }
+
+ $callsPerMinute = (int) $cacheItem->get();
+ if (++$callsPerMinute > $this->maxCallsPerMinute) {
+ return true;
+ }
+ $cacheItem->set($callsPerMinute);
+ $this->cache->save($cacheItem);
+ return false;
+ }
+
+ private function getCacheItem(): CacheItemInterface
+ {
+ if (\is_null($this->cacheItem)) {
+ $this->cacheItem = $this->cache->getItem($this->cacheKey);
+ }
+
+ return $this->cacheItem;
+ }
+
+ private function setCacheKeys(): void
+ {
+ if (empty($this->jwksUri)) {
+ throw new RuntimeException('JWKS URI is empty');
+ }
+
+ // ensure we do not have illegal characters
+ $key = preg_replace('|[^a-zA-Z0-9_\.!]|', '', $this->jwksUri);
+
+ // add prefix
+ $key = $this->cacheKeyPrefix . $key;
+
+ // Hash keys if they exceed $maxKeyLength of 64
+ if (\strlen($key) > $this->maxKeyLength) {
+ $key = substr(hash('sha256', $key), 0, $this->maxKeyLength);
+ }
+
+ $this->cacheKey = $key;
+
+ if ($this->rateLimit) {
+ // add prefix
+ $rateLimitKey = $this->cacheKeyPrefix . 'ratelimit' . $key;
+
+ // Hash keys if they exceed $maxKeyLength of 64
+ if (\strlen($rateLimitKey) > $this->maxKeyLength) {
+ $rateLimitKey = substr(hash('sha256', $rateLimitKey), 0, $this->maxKeyLength);
+ }
+
+ $this->rateLimitCacheKey = $rateLimitKey;
+ }
+ }
+}
diff --git a/includes/vendor/firebase/php-jwt/src/ExpiredException.php b/includes/vendor/firebase/php-jwt/src/ExpiredException.php
index 3597370a..81ba52d4 100644
--- a/includes/vendor/firebase/php-jwt/src/ExpiredException.php
+++ b/includes/vendor/firebase/php-jwt/src/ExpiredException.php
@@ -1,7 +1,7 @@
+ * @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
+ * @link https://github.com/firebase/php-jwt
+ */
+class JWK
+{
+ private const OID = '1.2.840.10045.2.1';
+ private const ASN1_OBJECT_IDENTIFIER = 0x06;
+ private const ASN1_SEQUENCE = 0x10; // also defined in JWT
+ private const ASN1_BIT_STRING = 0x03;
+ private const EC_CURVES = [
+ 'P-256' => '1.2.840.10045.3.1.7', // Len: 64
+ 'secp256k1' => '1.3.132.0.10', // Len: 64
+ // 'P-384' => '1.3.132.0.34', // Len: 96 (not yet supported)
+ // 'P-521' => '1.3.132.0.35', // Len: 132 (not supported)
+ ];
+
+ /**
+ * Parse a set of JWK keys
+ *
+ * @param array $jwks The JSON Web Key Set as an associative array
+ * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the
+ * JSON Web Key Set
+ *
+ * @return array An associative array of key IDs (kid) to Key objects
+ *
+ * @throws InvalidArgumentException Provided JWK Set is empty
+ * @throws UnexpectedValueException Provided JWK Set was invalid
+ * @throws DomainException OpenSSL failure
+ *
+ * @uses parseKey
+ */
+ public static function parseKeySet(array $jwks, string $defaultAlg = null): array
+ {
+ $keys = [];
+
+ if (!isset($jwks['keys'])) {
+ throw new UnexpectedValueException('"keys" member must exist in the JWK Set');
+ }
+
+ if (empty($jwks['keys'])) {
+ throw new InvalidArgumentException('JWK Set did not contain any keys');
+ }
+
+ foreach ($jwks['keys'] as $k => $v) {
+ $kid = isset($v['kid']) ? $v['kid'] : $k;
+ if ($key = self::parseKey($v, $defaultAlg)) {
+ $keys[(string) $kid] = $key;
+ }
+ }
+
+ if (0 === \count($keys)) {
+ throw new UnexpectedValueException('No supported algorithms found in JWK Set');
+ }
+
+ return $keys;
+ }
+
+ /**
+ * Parse a JWK key
+ *
+ * @param array $jwk An individual JWK
+ * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the
+ * JSON Web Key Set
+ *
+ * @return Key The key object for the JWK
+ *
+ * @throws InvalidArgumentException Provided JWK is empty
+ * @throws UnexpectedValueException Provided JWK was invalid
+ * @throws DomainException OpenSSL failure
+ *
+ * @uses createPemFromModulusAndExponent
+ */
+ public static function parseKey(array $jwk, string $defaultAlg = null): ?Key
+ {
+ if (empty($jwk)) {
+ throw new InvalidArgumentException('JWK must not be empty');
+ }
+
+ if (!isset($jwk['kty'])) {
+ throw new UnexpectedValueException('JWK must contain a "kty" parameter');
+ }
+
+ if (!isset($jwk['alg'])) {
+ if (\is_null($defaultAlg)) {
+ // The "alg" parameter is optional in a KTY, but an algorithm is required
+ // for parsing in this library. Use the $defaultAlg parameter when parsing the
+ // key set in order to prevent this error.
+ // @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4
+ throw new UnexpectedValueException('JWK must contain an "alg" parameter');
+ }
+ $jwk['alg'] = $defaultAlg;
+ }
+
+ switch ($jwk['kty']) {
+ case 'RSA':
+ if (!empty($jwk['d'])) {
+ throw new UnexpectedValueException('RSA private keys are not supported');
+ }
+ if (!isset($jwk['n']) || !isset($jwk['e'])) {
+ throw new UnexpectedValueException('RSA keys must contain values for both "n" and "e"');
+ }
+
+ $pem = self::createPemFromModulusAndExponent($jwk['n'], $jwk['e']);
+ $publicKey = \openssl_pkey_get_public($pem);
+ if (false === $publicKey) {
+ throw new DomainException(
+ 'OpenSSL error: ' . \openssl_error_string()
+ );
+ }
+ return new Key($publicKey, $jwk['alg']);
+ case 'EC':
+ if (isset($jwk['d'])) {
+ // The key is actually a private key
+ throw new UnexpectedValueException('Key data must be for a public key');
+ }
+
+ if (empty($jwk['crv'])) {
+ throw new UnexpectedValueException('crv not set');
+ }
+
+ if (!isset(self::EC_CURVES[$jwk['crv']])) {
+ throw new DomainException('Unrecognised or unsupported EC curve');
+ }
+
+ if (empty($jwk['x']) || empty($jwk['y'])) {
+ throw new UnexpectedValueException('x and y not set');
+ }
+
+ $publicKey = self::createPemFromCrvAndXYCoordinates($jwk['crv'], $jwk['x'], $jwk['y']);
+ return new Key($publicKey, $jwk['alg']);
+ default:
+ // Currently only RSA is supported
+ break;
+ }
+
+ return null;
+ }
+
+ /**
+ * Converts the EC JWK values to pem format.
+ *
+ * @param string $crv The EC curve (only P-256 is supported)
+ * @param string $x The EC x-coordinate
+ * @param string $y The EC y-coordinate
+ *
+ * @return string
+ */
+ private static function createPemFromCrvAndXYCoordinates(string $crv, string $x, string $y): string
+ {
+ $pem =
+ self::encodeDER(
+ self::ASN1_SEQUENCE,
+ self::encodeDER(
+ self::ASN1_SEQUENCE,
+ self::encodeDER(
+ self::ASN1_OBJECT_IDENTIFIER,
+ self::encodeOID(self::OID)
+ )
+ . self::encodeDER(
+ self::ASN1_OBJECT_IDENTIFIER,
+ self::encodeOID(self::EC_CURVES[$crv])
+ )
+ ) .
+ self::encodeDER(
+ self::ASN1_BIT_STRING,
+ \chr(0x00) . \chr(0x04)
+ . JWT::urlsafeB64Decode($x)
+ . JWT::urlsafeB64Decode($y)
+ )
+ );
+
+ return sprintf(
+ "-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n",
+ wordwrap(base64_encode($pem), 64, "\n", true)
+ );
+ }
+
+ /**
+ * Create a public key represented in PEM format from RSA modulus and exponent information
+ *
+ * @param string $n The RSA modulus encoded in Base64
+ * @param string $e The RSA exponent encoded in Base64
+ *
+ * @return string The RSA public key represented in PEM format
+ *
+ * @uses encodeLength
+ */
+ private static function createPemFromModulusAndExponent(
+ string $n,
+ string $e
+ ): string {
+ $mod = JWT::urlsafeB64Decode($n);
+ $exp = JWT::urlsafeB64Decode($e);
+
+ $modulus = \pack('Ca*a*', 2, self::encodeLength(\strlen($mod)), $mod);
+ $publicExponent = \pack('Ca*a*', 2, self::encodeLength(\strlen($exp)), $exp);
+
+ $rsaPublicKey = \pack(
+ 'Ca*a*a*',
+ 48,
+ self::encodeLength(\strlen($modulus) + \strlen($publicExponent)),
+ $modulus,
+ $publicExponent
+ );
+
+ // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
+ $rsaOID = \pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
+ $rsaPublicKey = \chr(0) . $rsaPublicKey;
+ $rsaPublicKey = \chr(3) . self::encodeLength(\strlen($rsaPublicKey)) . $rsaPublicKey;
+
+ $rsaPublicKey = \pack(
+ 'Ca*a*',
+ 48,
+ self::encodeLength(\strlen($rsaOID . $rsaPublicKey)),
+ $rsaOID . $rsaPublicKey
+ );
+
+ return "-----BEGIN PUBLIC KEY-----\r\n" .
+ \chunk_split(\base64_encode($rsaPublicKey), 64) .
+ '-----END PUBLIC KEY-----';
+ }
+
+ /**
+ * DER-encode the length
+ *
+ * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
+ * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
+ *
+ * @param int $length
+ * @return string
+ */
+ private static function encodeLength(int $length): string
+ {
+ if ($length <= 0x7F) {
+ return \chr($length);
+ }
+
+ $temp = \ltrim(\pack('N', $length), \chr(0));
+
+ return \pack('Ca*', 0x80 | \strlen($temp), $temp);
+ }
+
+ /**
+ * Encodes a value into a DER object.
+ * Also defined in Firebase\JWT\JWT
+ *
+ * @param int $type DER tag
+ * @param string $value the value to encode
+ * @return string the encoded object
+ */
+ private static function encodeDER(int $type, string $value): string
+ {
+ $tag_header = 0;
+ if ($type === self::ASN1_SEQUENCE) {
+ $tag_header |= 0x20;
+ }
+
+ // Type
+ $der = \chr($tag_header | $type);
+
+ // Length
+ $der .= \chr(\strlen($value));
+
+ return $der . $value;
+ }
+
+ /**
+ * Encodes a string into a DER-encoded OID.
+ *
+ * @param string $oid the OID string
+ * @return string the binary DER-encoded OID
+ */
+ private static function encodeOID(string $oid): string
+ {
+ $octets = explode('.', $oid);
+
+ // Get the first octet
+ $first = (int) array_shift($octets);
+ $second = (int) array_shift($octets);
+ $oid = \chr($first * 40 + $second);
+
+ // Iterate over subsequent octets
+ foreach ($octets as $octet) {
+ if ($octet == 0) {
+ $oid .= \chr(0x00);
+ continue;
+ }
+ $bin = '';
+
+ while ($octet) {
+ $bin .= \chr(0x80 | ($octet & 0x7f));
+ $octet >>= 7;
+ }
+ $bin[0] = $bin[0] & \chr(0x7f);
+
+ // Convert to big endian if necessary
+ if (pack('V', 65534) == pack('L', 65534)) {
+ $oid .= strrev($bin);
+ } else {
+ $oid .= $bin;
+ }
+ }
+
+ return $oid;
+ }
+}
diff --git a/includes/vendor/firebase/php-jwt/src/JWT.php b/includes/vendor/firebase/php-jwt/src/JWT.php
index b3532df7..269e8caf 100644
--- a/includes/vendor/firebase/php-jwt/src/JWT.php
+++ b/includes/vendor/firebase/php-jwt/src/JWT.php
@@ -1,14 +1,20 @@
array('hash_hmac', 'SHA256'),
- 'HS512' => array('hash_hmac', 'SHA512'),
- 'HS384' => array('hash_hmac', 'SHA384'),
- 'RS256' => array('openssl', 'SHA256'),
- );
+ /**
+ * Allow the current timestamp to be specified.
+ * Useful for fixing a value within unit testing.
+ * Will default to PHP time() value if null.
+ *
+ * @var ?int
+ */
+ public static $timestamp = null;
+
+ /**
+ * @var array
+ */
+ public static $supported_algs = [
+ 'ES384' => ['openssl', 'SHA384'],
+ 'ES256' => ['openssl', 'SHA256'],
+ 'ES256K' => ['openssl', 'SHA256'],
+ 'HS256' => ['hash_hmac', 'SHA256'],
+ 'HS384' => ['hash_hmac', 'SHA384'],
+ 'HS512' => ['hash_hmac', 'SHA512'],
+ 'RS256' => ['openssl', 'SHA256'],
+ 'RS384' => ['openssl', 'SHA384'],
+ 'RS512' => ['openssl', 'SHA512'],
+ 'EdDSA' => ['sodium_crypto', 'EdDSA'],
+ ];
/**
* Decodes a JWT string into a PHP object.
*
- * @param string $jwt The JWT
- * @param string|array|null $key The key, or map of keys.
- * If the algorithm used is asymmetric, this is the public key
- * @param array $allowed_algs List of supported verification algorithms
- * Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
+ * @param string $jwt The JWT
+ * @param Key|array $keyOrKeyArray The Key or associative array of key IDs (kid) to Key objects.
+ * If the algorithm used is asymmetric, this is the public key
+ * Each Key object contains an algorithm and matching key.
+ * Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
+ * 'HS512', 'RS256', 'RS384', and 'RS512'
*
- * @return object The JWT's payload as a PHP object
+ * @return stdClass The JWT's payload as a PHP object
*
- * @throws DomainException Algorithm was not provided
+ * @throws InvalidArgumentException Provided key/key-array was empty or malformed
+ * @throws DomainException Provided JWT is malformed
* @throws UnexpectedValueException Provided JWT was invalid
* @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed
* @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf'
@@ -57,65 +88,78 @@ class JWT
* @uses jsonDecode
* @uses urlsafeB64Decode
*/
- public static function decode($jwt, $key, $allowed_algs = array())
- {
- if (empty($key)) {
+ public static function decode(
+ string $jwt,
+ $keyOrKeyArray
+ ): stdClass {
+ // Validate JWT
+ $timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp;
+
+ if (empty($keyOrKeyArray)) {
throw new InvalidArgumentException('Key may not be empty');
}
- $tks = explode('.', $jwt);
- if (count($tks) != 3) {
+ $tks = \explode('.', $jwt);
+ if (\count($tks) !== 3) {
throw new UnexpectedValueException('Wrong number of segments');
}
list($headb64, $bodyb64, $cryptob64) = $tks;
- if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) {
+ $headerRaw = static::urlsafeB64Decode($headb64);
+ if (null === ($header = static::jsonDecode($headerRaw))) {
throw new UnexpectedValueException('Invalid header encoding');
}
- if (null === $payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64))) {
+ $payloadRaw = static::urlsafeB64Decode($bodyb64);
+ if (null === ($payload = static::jsonDecode($payloadRaw))) {
throw new UnexpectedValueException('Invalid claims encoding');
}
- $sig = JWT::urlsafeB64Decode($cryptob64);
-
- if (empty($header->alg)) {
- throw new DomainException('Empty algorithm');
+ if (\is_array($payload)) {
+ // prevent PHP Fatal Error in edge-cases when payload is empty array
+ $payload = (object) $payload;
}
- if (empty(self::$supported_algs[$header->alg])) {
- throw new DomainException('Algorithm not supported');
+ if (!$payload instanceof stdClass) {
+ throw new UnexpectedValueException('Payload must be a JSON object');
}
- if (!is_array($allowed_algs) || !in_array($header->alg, $allowed_algs)) {
- throw new DomainException('Algorithm not allowed');
+ $sig = static::urlsafeB64Decode($cryptob64);
+ if (empty($header->alg)) {
+ throw new UnexpectedValueException('Empty algorithm');
}
- if (is_array($key) || $key instanceof \ArrayAccess) {
- if (isset($header->kid)) {
- $key = $key[$header->kid];
- } else {
- throw new DomainException('"kid" empty, unable to lookup correct key');
- }
+ if (empty(static::$supported_algs[$header->alg])) {
+ throw new UnexpectedValueException('Algorithm not supported');
}
- // Check the signature
- if (!JWT::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
+ $key = self::getKey($keyOrKeyArray, property_exists($header, 'kid') ? $header->kid : null);
+
+ // Check the algorithm
+ if (!self::constantTimeEquals($key->getAlgorithm(), $header->alg)) {
+ // See issue #351
+ throw new UnexpectedValueException('Incorrect key for this algorithm');
+ }
+ if (\in_array($header->alg, ['ES256', 'ES256K', 'ES384'], true)) {
+ // OpenSSL expects an ASN.1 DER sequence for ES256/ES256K/ES384 signatures
+ $sig = self::signatureToDER($sig);
+ }
+ if (!self::verify("{$headb64}.{$bodyb64}", $sig, $key->getKeyMaterial(), $header->alg)) {
throw new SignatureInvalidException('Signature verification failed');
}
- // Check if the nbf if it is defined. This is the time that the
+ // Check the nbf if it is defined. This is the time that the
// token can actually be used. If it's not yet that time, abort.
- if (isset($payload->nbf) && $payload->nbf > (time() + self::$leeway)) {
+ if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) {
throw new BeforeValidException(
- 'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
+ 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->nbf)
);
}
// Check that this token has been created before 'now'. This prevents
// using tokens that have been created for later use (and haven't
// correctly used the nbf claim).
- if (isset($payload->iat) && $payload->iat > (time() + self::$leeway)) {
+ if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) {
throw new BeforeValidException(
- 'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
+ 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->iat)
);
}
// Check if this token has expired.
- if (isset($payload->exp) && (time() - self::$leeway) >= $payload->exp) {
+ if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
throw new ExpiredException('Expired token');
}
@@ -123,115 +167,172 @@ public static function decode($jwt, $key, $allowed_algs = array())
}
/**
- * Converts and signs a PHP object or array into a JWT string.
+ * Converts and signs a PHP array into a JWT string.
*
- * @param object|array $payload PHP object or array
- * @param string $key The secret key.
- * If the algorithm used is asymmetric, this is the private key
- * @param string $alg The signing algorithm.
- * Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
- * @param array $head An array with header elements to attach
+ * @param array $payload PHP array
+ * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
+ * @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256',
+ * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512'
+ * @param string $keyId
+ * @param array $head An array with header elements to attach
*
* @return string A signed JWT
*
* @uses jsonEncode
* @uses urlsafeB64Encode
*/
- public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null)
- {
- $header = array('typ' => 'JWT', 'alg' => $alg);
+ public static function encode(
+ array $payload,
+ $key,
+ string $alg,
+ string $keyId = null,
+ array $head = null
+ ): string {
+ $header = ['typ' => 'JWT', 'alg' => $alg];
if ($keyId !== null) {
$header['kid'] = $keyId;
}
- if ( isset($head) && is_array($head) ) {
- $header = array_merge($head, $header);
+ if (isset($head) && \is_array($head)) {
+ $header = \array_merge($head, $header);
}
- $segments = array();
- $segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($header));
- $segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($payload));
- $signing_input = implode('.', $segments);
+ $segments = [];
+ $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header));
+ $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload));
+ $signing_input = \implode('.', $segments);
- $signature = JWT::sign($signing_input, $key, $alg);
- $segments[] = JWT::urlsafeB64Encode($signature);
+ $signature = static::sign($signing_input, $key, $alg);
+ $segments[] = static::urlsafeB64Encode($signature);
- return implode('.', $segments);
+ return \implode('.', $segments);
}
/**
* Sign a string with a given key and algorithm.
*
- * @param string $msg The message to sign
- * @param string|resource $key The secret key
- * @param string $alg The signing algorithm.
- * Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
+ * @param string $msg The message to sign
+ * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
+ * @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256',
+ * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512'
*
* @return string An encrypted message
*
- * @throws DomainException Unsupported algorithm was specified
+ * @throws DomainException Unsupported algorithm or bad key was specified
*/
- public static function sign($msg, $key, $alg = 'HS256')
- {
- if (empty(self::$supported_algs[$alg])) {
+ public static function sign(
+ string $msg,
+ $key,
+ string $alg
+ ): string {
+ if (empty(static::$supported_algs[$alg])) {
throw new DomainException('Algorithm not supported');
}
- list($function, $algorithm) = self::$supported_algs[$alg];
- switch($function) {
+ list($function, $algorithm) = static::$supported_algs[$alg];
+ switch ($function) {
case 'hash_hmac':
- return hash_hmac($algorithm, $msg, $key, true);
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException('key must be a string when using hmac');
+ }
+ return \hash_hmac($algorithm, $msg, $key, true);
case 'openssl':
$signature = '';
- $success = openssl_sign($msg, $signature, $key, $algorithm);
+ $success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line
if (!$success) {
- throw new DomainException("OpenSSL unable to sign data");
- } else {
- return $signature;
+ throw new DomainException('OpenSSL unable to sign data');
+ }
+ if ($alg === 'ES256' || $alg === 'ES256K') {
+ $signature = self::signatureFromDER($signature, 256);
+ } elseif ($alg === 'ES384') {
+ $signature = self::signatureFromDER($signature, 384);
+ }
+ return $signature;
+ case 'sodium_crypto':
+ if (!\function_exists('sodium_crypto_sign_detached')) {
+ throw new DomainException('libsodium is not available');
+ }
+ if (!\is_string($key)) {
+ throw new InvalidArgumentException('key must be a string when using EdDSA');
+ }
+ try {
+ // The last non-empty line is used as the key.
+ $lines = array_filter(explode("\n", $key));
+ $key = base64_decode((string) end($lines));
+ if (\strlen($key) === 0) {
+ throw new DomainException('Key cannot be empty string');
+ }
+ return sodium_crypto_sign_detached($msg, $key);
+ } catch (Exception $e) {
+ throw new DomainException($e->getMessage(), 0, $e);
}
}
+
+ throw new DomainException('Algorithm not supported');
}
/**
* Verify a signature with the message, key and method. Not all methods
* are symmetric, so we must have a separate verify and sign method.
*
- * @param string $msg The original message (header and body)
- * @param string $signature The original signature
- * @param string|resource $key For HS*, a string key works. for RS*, must be a resource of an openssl public key
- * @param string $alg The algorithm
+ * @param string $msg The original message (header and body)
+ * @param string $signature The original signature
+ * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey
+ * @param string $alg The algorithm
*
* @return bool
*
- * @throws DomainException Invalid Algorithm or OpenSSL failure
+ * @throws DomainException Invalid Algorithm, bad key, or OpenSSL failure
*/
- private static function verify($msg, $signature, $key, $alg)
- {
- if (empty(self::$supported_algs[$alg])) {
+ private static function verify(
+ string $msg,
+ string $signature,
+ $keyMaterial,
+ string $alg
+ ): bool {
+ if (empty(static::$supported_algs[$alg])) {
throw new DomainException('Algorithm not supported');
}
- list($function, $algorithm) = self::$supported_algs[$alg];
- switch($function) {
+ list($function, $algorithm) = static::$supported_algs[$alg];
+ switch ($function) {
case 'openssl':
- $success = openssl_verify($msg, $signature, $key, $algorithm);
- if (!$success) {
- throw new DomainException("OpenSSL unable to verify data: " . openssl_error_string());
- } else {
- return $signature;
+ $success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm); // @phpstan-ignore-line
+ if ($success === 1) {
+ return true;
+ }
+ if ($success === 0) {
+ return false;
+ }
+ // returns 1 on success, 0 on failure, -1 on error.
+ throw new DomainException(
+ 'OpenSSL error: ' . \openssl_error_string()
+ );
+ case 'sodium_crypto':
+ if (!\function_exists('sodium_crypto_sign_verify_detached')) {
+ throw new DomainException('libsodium is not available');
+ }
+ if (!\is_string($keyMaterial)) {
+ throw new InvalidArgumentException('key must be a string when using EdDSA');
+ }
+ try {
+ // The last non-empty line is used as the key.
+ $lines = array_filter(explode("\n", $keyMaterial));
+ $key = base64_decode((string) end($lines));
+ if (\strlen($key) === 0) {
+ throw new DomainException('Key cannot be empty string');
+ }
+ if (\strlen($signature) === 0) {
+ throw new DomainException('Signature cannot be empty string');
+ }
+ return sodium_crypto_sign_verify_detached($signature, $msg, $key);
+ } catch (Exception $e) {
+ throw new DomainException($e->getMessage(), 0, $e);
}
case 'hash_hmac':
default:
- $hash = hash_hmac($algorithm, $msg, $key, true);
- if (function_exists('hash_equals')) {
- return hash_equals($signature, $hash);
- }
- $len = min(self::safeStrlen($signature), self::safeStrlen($hash));
-
- $status = 0;
- for ($i = 0; $i < $len; $i++) {
- $status |= (ord($signature[$i]) ^ ord($hash[$i]));
+ if (!\is_string($keyMaterial)) {
+ throw new InvalidArgumentException('key must be a string when using hmac');
}
- $status |= (self::safeStrlen($signature) ^ self::safeStrlen($hash));
-
- return ($status === 0);
+ $hash = \hash_hmac($algorithm, $msg, $keyMaterial, true);
+ return self::constantTimeEquals($hash, $signature);
}
}
@@ -240,30 +341,16 @@ private static function verify($msg, $signature, $key, $alg)
*
* @param string $input JSON string
*
- * @return object Object representation of JSON string
+ * @return mixed The decoded JSON string
*
* @throws DomainException Provided string was invalid JSON
*/
- public static function jsonDecode($input)
+ public static function jsonDecode(string $input)
{
- if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) {
- /** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you
- * to specify that large ints (like Steam Transaction IDs) should be treated as
- * strings, rather than the PHP default behaviour of converting them to floats.
- */
- $obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
- } else {
- /** Not all servers will support that, however, so for older versions we must
- * manually detect large ints in the JSON string and quote them (thus converting
- *them to strings) before decoding, hence the preg_replace() call.
- */
- $max_int_length = strlen((string) PHP_INT_MAX) - 1;
- $json_without_bigints = preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input);
- $obj = json_decode($json_without_bigints);
- }
+ $obj = \json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
- if (function_exists('json_last_error') && $errno = json_last_error()) {
- JWT::handleJsonError($errno);
+ if ($errno = \json_last_error()) {
+ self::handleJsonError($errno);
} elseif ($obj === null && $input !== 'null') {
throw new DomainException('Null result with non-null input');
}
@@ -271,22 +358,30 @@ public static function jsonDecode($input)
}
/**
- * Encode a PHP object into a JSON string.
+ * Encode a PHP array into a JSON string.
*
- * @param object|array $input A PHP object or array
+ * @param array $input A PHP array
*
- * @return string JSON representation of the PHP object or array
+ * @return string JSON representation of the PHP array
*
* @throws DomainException Provided object could not be encoded to valid JSON
*/
- public static function jsonEncode($input)
+ public static function jsonEncode(array $input): string
{
- $json = json_encode($input);
- if (function_exists('json_last_error') && $errno = json_last_error()) {
- JWT::handleJsonError($errno);
+ if (PHP_VERSION_ID >= 50400) {
+ $json = \json_encode($input, \JSON_UNESCAPED_SLASHES);
+ } else {
+ // PHP 5.3 only
+ $json = \json_encode($input);
+ }
+ if ($errno = \json_last_error()) {
+ self::handleJsonError($errno);
} elseif ($json === 'null' && $input !== null) {
throw new DomainException('Null result with non-null input');
}
+ if ($json === false) {
+ throw new DomainException('Provided object could not be encoded to valid JSON');
+ }
return $json;
}
@@ -296,15 +391,17 @@ public static function jsonEncode($input)
* @param string $input A Base64 encoded string
*
* @return string A decoded string
+ *
+ * @throws InvalidArgumentException invalid base64 characters
*/
- public static function urlsafeB64Decode($input)
+ public static function urlsafeB64Decode(string $input): string
{
- $remainder = strlen($input) % 4;
+ $remainder = \strlen($input) % 4;
if ($remainder) {
$padlen = 4 - $remainder;
- $input .= str_repeat('=', $padlen);
+ $input .= \str_repeat('=', $padlen);
}
- return base64_decode(strtr($input, '-_', '+/'));
+ return \base64_decode(\strtr($input, '-_', '+/'));
}
/**
@@ -314,9 +411,65 @@ public static function urlsafeB64Decode($input)
*
* @return string The base64 encode of what you passed in
*/
- public static function urlsafeB64Encode($input)
+ public static function urlsafeB64Encode(string $input): string
{
- return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
+ return \str_replace('=', '', \strtr(\base64_encode($input), '+/', '-_'));
+ }
+
+
+ /**
+ * Determine if an algorithm has been provided for each Key
+ *
+ * @param Key|ArrayAccess|array $keyOrKeyArray
+ * @param string|null $kid
+ *
+ * @throws UnexpectedValueException
+ *
+ * @return Key
+ */
+ private static function getKey(
+ $keyOrKeyArray,
+ ?string $kid
+ ): Key {
+ if ($keyOrKeyArray instanceof Key) {
+ return $keyOrKeyArray;
+ }
+
+ if (empty($kid)) {
+ throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
+ }
+
+ if ($keyOrKeyArray instanceof CachedKeySet) {
+ // Skip "isset" check, as this will automatically refresh if not set
+ return $keyOrKeyArray[$kid];
+ }
+
+ if (!isset($keyOrKeyArray[$kid])) {
+ throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key');
+ }
+
+ return $keyOrKeyArray[$kid];
+ }
+
+ /**
+ * @param string $left The string of known length to compare against
+ * @param string $right The user-supplied string
+ * @return bool
+ */
+ public static function constantTimeEquals(string $left, string $right): bool
+ {
+ if (\function_exists('hash_equals')) {
+ return \hash_equals($left, $right);
+ }
+ $len = \min(self::safeStrlen($left), self::safeStrlen($right));
+
+ $status = 0;
+ for ($i = 0; $i < $len; $i++) {
+ $status |= (\ord($left[$i]) ^ \ord($right[$i]));
+ }
+ $status |= (self::safeStrlen($left) ^ self::safeStrlen($right));
+
+ return ($status === 0);
}
/**
@@ -324,15 +477,19 @@ public static function urlsafeB64Encode($input)
*
* @param int $errno An error number from json_last_error()
*
+ * @throws DomainException
+ *
* @return void
*/
- private static function handleJsonError($errno)
+ private static function handleJsonError(int $errno): void
{
- $messages = array(
+ $messages = [
JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
+ JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
- JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON'
- );
+ JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
+ JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3
+ ];
throw new DomainException(
isset($messages[$errno])
? $messages[$errno]
@@ -343,15 +500,139 @@ private static function handleJsonError($errno)
/**
* Get the number of bytes in cryptographic strings.
*
- * @param string
+ * @param string $str
*
* @return int
*/
- private static function safeStrlen($str)
+ private static function safeStrlen(string $str): int
{
- if (function_exists('mb_strlen')) {
- return mb_strlen($str, '8bit');
+ if (\function_exists('mb_strlen')) {
+ return \mb_strlen($str, '8bit');
}
- return strlen($str);
+ return \strlen($str);
+ }
+
+ /**
+ * Convert an ECDSA signature to an ASN.1 DER sequence
+ *
+ * @param string $sig The ECDSA signature to convert
+ * @return string The encoded DER object
+ */
+ private static function signatureToDER(string $sig): string
+ {
+ // Separate the signature into r-value and s-value
+ $length = max(1, (int) (\strlen($sig) / 2));
+ list($r, $s) = \str_split($sig, $length);
+
+ // Trim leading zeros
+ $r = \ltrim($r, "\x00");
+ $s = \ltrim($s, "\x00");
+
+ // Convert r-value and s-value from unsigned big-endian integers to
+ // signed two's complement
+ if (\ord($r[0]) > 0x7f) {
+ $r = "\x00" . $r;
+ }
+ if (\ord($s[0]) > 0x7f) {
+ $s = "\x00" . $s;
+ }
+
+ return self::encodeDER(
+ self::ASN1_SEQUENCE,
+ self::encodeDER(self::ASN1_INTEGER, $r) .
+ self::encodeDER(self::ASN1_INTEGER, $s)
+ );
+ }
+
+ /**
+ * Encodes a value into a DER object.
+ *
+ * @param int $type DER tag
+ * @param string $value the value to encode
+ *
+ * @return string the encoded object
+ */
+ private static function encodeDER(int $type, string $value): string
+ {
+ $tag_header = 0;
+ if ($type === self::ASN1_SEQUENCE) {
+ $tag_header |= 0x20;
+ }
+
+ // Type
+ $der = \chr($tag_header | $type);
+
+ // Length
+ $der .= \chr(\strlen($value));
+
+ return $der . $value;
+ }
+
+ /**
+ * Encodes signature from a DER object.
+ *
+ * @param string $der binary signature in DER format
+ * @param int $keySize the number of bits in the key
+ *
+ * @return string the signature
+ */
+ private static function signatureFromDER(string $der, int $keySize): string
+ {
+ // OpenSSL returns the ECDSA signatures as a binary ASN.1 DER SEQUENCE
+ list($offset, $_) = self::readDER($der);
+ list($offset, $r) = self::readDER($der, $offset);
+ list($offset, $s) = self::readDER($der, $offset);
+
+ // Convert r-value and s-value from signed two's compliment to unsigned
+ // big-endian integers
+ $r = \ltrim($r, "\x00");
+ $s = \ltrim($s, "\x00");
+
+ // Pad out r and s so that they are $keySize bits long
+ $r = \str_pad($r, $keySize / 8, "\x00", STR_PAD_LEFT);
+ $s = \str_pad($s, $keySize / 8, "\x00", STR_PAD_LEFT);
+
+ return $r . $s;
+ }
+
+ /**
+ * Reads binary DER-encoded data and decodes into a single object
+ *
+ * @param string $der the binary data in DER format
+ * @param int $offset the offset of the data stream containing the object
+ * to decode
+ *
+ * @return array{int, string|null} the new offset and the decoded object
+ */
+ private static function readDER(string $der, int $offset = 0): array
+ {
+ $pos = $offset;
+ $size = \strlen($der);
+ $constructed = (\ord($der[$pos]) >> 5) & 0x01;
+ $type = \ord($der[$pos++]) & 0x1f;
+
+ // Length
+ $len = \ord($der[$pos++]);
+ if ($len & 0x80) {
+ $n = $len & 0x1f;
+ $len = 0;
+ while ($n-- && $pos < $size) {
+ $len = ($len << 8) | \ord($der[$pos++]);
+ }
+ }
+
+ // Value
+ if ($type === self::ASN1_BIT_STRING) {
+ $pos++; // Skip the first contents octet (padding indicator)
+ $data = \substr($der, $pos, $len - 1);
+ $pos += $len - 1;
+ } elseif (!$constructed) {
+ $data = \substr($der, $pos, $len);
+ $pos += $len;
+ } else {
+ $data = null;
+ }
+
+ return [$pos, $data];
}
}
diff --git a/includes/vendor/firebase/php-jwt/src/Key.php b/includes/vendor/firebase/php-jwt/src/Key.php
new file mode 100644
index 00000000..00cf7f2e
--- /dev/null
+++ b/includes/vendor/firebase/php-jwt/src/Key.php
@@ -0,0 +1,64 @@
+keyMaterial = $keyMaterial;
+ $this->algorithm = $algorithm;
+ }
+
+ /**
+ * Return the algorithm valid for this key
+ *
+ * @return string
+ */
+ public function getAlgorithm(): string
+ {
+ return $this->algorithm;
+ }
+
+ /**
+ * @return string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate
+ */
+ public function getKeyMaterial()
+ {
+ return $this->keyMaterial;
+ }
+}
diff --git a/includes/vendor/firebase/php-jwt/src/SignatureInvalidException.php b/includes/vendor/firebase/php-jwt/src/SignatureInvalidException.php
index 27332b21..d35dee9f 100644
--- a/includes/vendor/firebase/php-jwt/src/SignatureInvalidException.php
+++ b/includes/vendor/firebase/php-jwt/src/SignatureInvalidException.php
@@ -1,7 +1,7 @@
assertEquals(JWT::decode($msg, 'my_key', array('HS256')), 'abc');
- }
-
- public function testDecodeFromPython()
- {
- $msg = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.Iio6aHR0cDovL2FwcGxpY2F0aW9uL2NsaWNreT9ibGFoPTEuMjMmZi5vbz00NTYgQUMwMDAgMTIzIg.E_U8X2YpMT5K1cEiT_3-IvBYfrdIFIeVYeOqre_Z5Cg';
- $this->assertEquals(
- JWT::decode($msg, 'my_key', array('HS256')),
- '*:http://application/clicky?blah=1.23&f.oo=456 AC000 123'
- );
- }
-
- public function testUrlSafeCharacters()
- {
- $encoded = JWT::encode('f?', 'a');
- $this->assertEquals('f?', JWT::decode($encoded, 'a', array('HS256')));
- }
-
- public function testMalformedUtf8StringsFail()
- {
- $this->setExpectedException('DomainException');
- JWT::encode(pack('c', 128), 'a');
- }
-
- public function testMalformedJsonThrowsException()
- {
- $this->setExpectedException('DomainException');
- JWT::jsonDecode('this is not valid JSON string');
- }
-
- public function testExpiredToken()
- {
- $this->setExpectedException('Firebase\JWT\ExpiredException');
- $payload = array(
- "message" => "abc",
- "exp" => time() - 20); // time in the past
- $encoded = JWT::encode($payload, 'my_key');
- JWT::decode($encoded, 'my_key', array('HS256'));
- }
-
- public function testBeforeValidTokenWithNbf()
- {
- $this->setExpectedException('Firebase\JWT\BeforeValidException');
- $payload = array(
- "message" => "abc",
- "nbf" => time() + 20); // time in the future
- $encoded = JWT::encode($payload, 'my_key');
- JWT::decode($encoded, 'my_key', array('HS256'));
- }
-
- public function testBeforeValidTokenWithIat()
- {
- $this->setExpectedException('Firebase\JWT\BeforeValidException');
- $payload = array(
- "message" => "abc",
- "iat" => time() + 20); // time in the future
- $encoded = JWT::encode($payload, 'my_key');
- JWT::decode($encoded, 'my_key', array('HS256'));
- }
-
- public function testValidToken()
- {
- $payload = array(
- "message" => "abc",
- "exp" => time() + JWT::$leeway + 20); // time in the future
- $encoded = JWT::encode($payload, 'my_key');
- $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
- $this->assertEquals($decoded->message, 'abc');
- }
-
- public function testValidTokenWithLeeway()
- {
- JWT::$leeway = 60;
- $payload = array(
- "message" => "abc",
- "exp" => time() - 20); // time in the past
- $encoded = JWT::encode($payload, 'my_key');
- $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
- $this->assertEquals($decoded->message, 'abc');
- JWT::$leeway = 0;
- }
-
- public function testExpiredTokenWithLeeway()
- {
- JWT::$leeway = 60;
- $payload = array(
- "message" => "abc",
- "exp" => time() - 70); // time far in the past
- $this->setExpectedException('Firebase\JWT\ExpiredException');
- $encoded = JWT::encode($payload, 'my_key');
- $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
- $this->assertEquals($decoded->message, 'abc');
- JWT::$leeway = 0;
- }
-
- public function testValidTokenWithList()
- {
- $payload = array(
- "message" => "abc",
- "exp" => time() + 20); // time in the future
- $encoded = JWT::encode($payload, 'my_key');
- $decoded = JWT::decode($encoded, 'my_key', array('HS256', 'HS512'));
- $this->assertEquals($decoded->message, 'abc');
- }
-
- public function testValidTokenWithNbf()
- {
- $payload = array(
- "message" => "abc",
- "iat" => time(),
- "exp" => time() + 20, // time in the future
- "nbf" => time() - 20);
- $encoded = JWT::encode($payload, 'my_key');
- $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
- $this->assertEquals($decoded->message, 'abc');
- }
-
- public function testValidTokenWithNbfLeeway()
- {
- JWT::$leeway = 60;
- $payload = array(
- "message" => "abc",
- "nbf" => time() + 20); // not before in near (leeway) future
- $encoded = JWT::encode($payload, 'my_key');
- $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
- $this->assertEquals($decoded->message, 'abc');
- JWT::$leeway = 0;
- }
-
- public function testInvalidTokenWithNbfLeeway()
- {
- JWT::$leeway = 60;
- $payload = array(
- "message" => "abc",
- "nbf" => time() + 65); // not before too far in future
- $encoded = JWT::encode($payload, 'my_key');
- $this->setExpectedException('Firebase\JWT\BeforeValidException');
- $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
- JWT::$leeway = 0;
- }
-
- public function testValidTokenWithIatLeeway()
- {
- JWT::$leeway = 60;
- $payload = array(
- "message" => "abc",
- "iat" => time() + 20); // issued in near (leeway) future
- $encoded = JWT::encode($payload, 'my_key');
- $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
- $this->assertEquals($decoded->message, 'abc');
- JWT::$leeway = 0;
- }
-
- public function testInvalidTokenWithIatLeeway()
- {
- JWT::$leeway = 60;
- $payload = array(
- "message" => "abc",
- "iat" => time() + 65); // issued too far in future
- $encoded = JWT::encode($payload, 'my_key');
- $this->setExpectedException('Firebase\JWT\BeforeValidException');
- $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
- JWT::$leeway = 0;
- }
-
- public function testInvalidToken()
- {
- $payload = array(
- "message" => "abc",
- "exp" => time() + 20); // time in the future
- $encoded = JWT::encode($payload, 'my_key');
- $this->setExpectedException('Firebase\JWT\SignatureInvalidException');
- $decoded = JWT::decode($encoded, 'my_key2', array('HS256'));
- }
-
- public function testNullKeyFails()
- {
- $payload = array(
- "message" => "abc",
- "exp" => time() + JWT::$leeway + 20); // time in the future
- $encoded = JWT::encode($payload, 'my_key');
- $this->setExpectedException('InvalidArgumentException');
- $decoded = JWT::decode($encoded, null, array('HS256'));
- }
-
- public function testEmptyKeyFails()
- {
- $payload = array(
- "message" => "abc",
- "exp" => time() + JWT::$leeway + 20); // time in the future
- $encoded = JWT::encode($payload, 'my_key');
- $this->setExpectedException('InvalidArgumentException');
- $decoded = JWT::decode($encoded, '', array('HS256'));
- }
-
- public function testRSEncodeDecode()
- {
- $privKey = openssl_pkey_new(array('digest_alg' => 'sha256',
- 'private_key_bits' => 1024,
- 'private_key_type' => OPENSSL_KEYTYPE_RSA));
- $msg = JWT::encode('abc', $privKey, 'RS256');
- $pubKey = openssl_pkey_get_details($privKey);
- $pubKey = $pubKey['key'];
- $decoded = JWT::decode($msg, $pubKey, array('RS256'));
- $this->assertEquals($decoded, 'abc');
- }
-
- public function testKIDChooser()
- {
- $keys = array('1' => 'my_key', '2' => 'my_key2');
- $msg = JWT::encode('abc', $keys['1'], 'HS256', '1');
- $decoded = JWT::decode($msg, $keys, array('HS256'));
- $this->assertEquals($decoded, 'abc');
- }
-
- public function testArrayAccessKIDChooser()
- {
- $keys = new ArrayObject(array('1' => 'my_key', '2' => 'my_key2'));
- $msg = JWT::encode('abc', $keys['1'], 'HS256', '1');
- $decoded = JWT::decode($msg, $keys, array('HS256'));
- $this->assertEquals($decoded, 'abc');
- }
-
- public function testNoneAlgorithm()
- {
- $msg = JWT::encode('abc', 'my_key');
- $this->setExpectedException('DomainException');
- JWT::decode($msg, 'my_key', array('none'));
- }
-
- public function testIncorrectAlgorithm()
- {
- $msg = JWT::encode('abc', 'my_key');
- $this->setExpectedException('DomainException');
- JWT::decode($msg, 'my_key', array('RS256'));
- }
-
- public function testMissingAlgorithm()
- {
- $msg = JWT::encode('abc', 'my_key');
- $this->setExpectedException('DomainException');
- JWT::decode($msg, 'my_key');
- }
-
- public function testAdditionalHeaders()
- {
- $msg = JWT::encode('abc', 'my_key', 'HS256', null, array('cty' => 'test-eit;v=1'));
- $this->assertEquals(JWT::decode($msg, 'my_key', array('HS256')), 'abc');
- }
-
- public function testInvalidSegmentCount()
- {
- $this->setExpectedException('UnexpectedValueException');
- JWT::decode('brokenheader.brokenbody', 'my_key', array('HS256'));
- }
-}
diff --git a/includes/vendor/firebase/php-jwt/tests/autoload.php.dist b/includes/vendor/firebase/php-jwt/tests/autoload.php.dist
deleted file mode 100644
index 2e4310a0..00000000
--- a/includes/vendor/firebase/php-jwt/tests/autoload.php.dist
+++ /dev/null
@@ -1,17 +0,0 @@
-run();
+function run_jwt_auth() {
+ $plugin = new Jwt_Auth();
+ $plugin->run();
}
+
run_jwt_auth();
diff --git a/public/class-jwt-auth-public.php b/public/class-jwt-auth-public.php
old mode 100755
new mode 100644
index 20a5504b..ba820160
--- a/public/class-jwt-auth-public.php
+++ b/public/class-jwt-auth-public.php
@@ -1,14 +1,8 @@
+ * @since 1.0.0
*/
-class Jwt_Auth_Public
-{
- /**
- * The ID of this plugin.
- *
- * @since 1.0.0
- *
- * @var string The ID of this plugin.
- */
- private $plugin_name;
-
- /**
- * The version of this plugin.
- *
- * @since 1.0.0
- *
- * @var string The current version of this plugin.
- */
- private $version;
-
- /**
- * The namespace to add to the api calls.
- *
- * @var string The namespace to add to the api call
- */
- private $namespace;
-
- /**
- * Store errors to display if the JWT is wrong
- *
- * @var WP_Error
- */
- private $jwt_error = null;
-
- /**
- * Initialize the class and set its properties.
- *
- * @since 1.0.0
- *
- * @param string $plugin_name The name of the plugin.
- * @param string $version The version of this plugin.
- */
- public function __construct($plugin_name, $version)
- {
- $this->plugin_name = $plugin_name;
- $this->version = $version;
- $this->namespace = $this->plugin_name.'/v'.intval($this->version);
- }
-
- /**
- * Add the endpoints to the API
- */
- public function add_api_routes()
- {
- register_rest_route($this->namespace, 'token', [
- 'methods' => 'POST',
- 'callback' => array($this, 'generate_token'),
- ]);
-
- register_rest_route($this->namespace, 'token/validate', array(
- 'methods' => 'POST',
- 'callback' => array($this, 'validate_token'),
- ));
- }
-
- /**
- * Add CORs suppot to the request.
- */
- public function add_cors_support()
- {
- $enable_cors = defined('JWT_AUTH_CORS_ENABLE') ? JWT_AUTH_CORS_ENABLE : false;
- if ($enable_cors) {
- $headers = apply_filters('jwt_auth_cors_allow_headers', 'Access-Control-Allow-Headers, Content-Type, Authorization');
- header(sprintf('Access-Control-Allow-Headers: %s', $headers));
- }
- }
-
- /**
- * Get the user and password in the request body and generate a JWT
- *
- * @param [type] $request [description]
- *
- * @return [type] [description]
- */
- public function generate_token($request)
- {
- $secret_key = defined('JWT_AUTH_SECRET_KEY') ? JWT_AUTH_SECRET_KEY : false;
- $username = $request->get_param('username');
- $password = $request->get_param('password');
-
- /** First thing, check the secret key if not exist return a error*/
- if (!$secret_key) {
- return new WP_Error(
- 'jwt_auth_bad_config',
- __('JWT is not configurated properly, please contact the admin', 'wp-api-jwt-auth'),
- array(
- 'status' => 403,
- )
- );
- }
- /** Try to authenticate the user with the passed credentials*/
- $user = wp_authenticate($username, $password);
-
- /** If the authentication fails return a error*/
- if (is_wp_error($user)) {
- return new WP_Error(
- 'jwt_auth_failed',
- __('Invalid Credentials.', 'wp-api-jwt-auth'),
- array(
- 'status' => 403,
- )
- );
- }
-
- /** Valid credentials, the user exists create the according Token */
- $issuedAt = time();
- $notBefore = apply_filters('jwt_auth_not_before', $issuedAt, $issuedAt);
- $expire = apply_filters('jwt_auth_expire', $issuedAt + (DAY_IN_SECONDS * 7), $issuedAt);
-
- $token = array(
- 'iss' => get_bloginfo('url'),
- 'iat' => $issuedAt,
- 'nbf' => $notBefore,
- 'exp' => $expire,
- 'data' => array(
- 'user' => array(
- 'id' => $user->data->ID,
- ),
- ),
- );
-
- /** Let the user modify the token data before the sign. */
- $token = JWT::encode(apply_filters('jwt_auth_token_before_sign', $token), $secret_key);
-
- /** The token is signed, now create the object with no sensible user data to the client*/
- $data = array(
- 'token' => $token,
- 'user_email' => $user->data->user_email,
- 'user_nicename' => $user->data->user_nicename,
- 'user_display_name' => $user->data->display_name,
- );
-
- /** Let the user modify the data before send it back */
- return apply_filters('jwt_auth_token_before_dispatch', $data, $user);
- }
-
- /**
- * This is our Middleware to try to authenticate the user according to the
- * token send.
- *
- * @param (int|bool) $user Logged User ID
- *
- * @return (int|bool)
- */
- public function determine_current_user($user)
- {
- /*
- * if the request URI is for validate the token don't do anything,
- * this avoid double calls to the validate_token function.
- */
- $validate_uri = strpos($_SERVER['REQUEST_URI'], 'token/validate');
- if ($validate_uri > 0) {
- return $user;
- }
-
- $token = $this->validate_token(false);
-
- if (is_wp_error($token)) {
- if ($token->get_error_code() != 'jwt_auth_no_auth_header') {
- /** If there is a error, store it to show it after see rest_pre_dispatch */
- $this->jwt_error = $token;
- return $user;
- } else {
- return $user;
- }
- }
- /** Everything is ok, return the user ID stored in the token*/
- return $token->data->user->id;
- }
-
- /**
- * Main validation function, this function try to get the Autentication
- * headers and decoded.
- *
- * @param bool $output
- *
- * @return WP_Error | Object
- */
- public function validate_token($output = true)
- {
- /*
- * Looking for the HTTP_AUTHORIZATION header, if not present just
- * return the user.
- */
- $auth = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : false;
- if (!$auth) {
- return new WP_Error(
- 'jwt_auth_no_auth_header',
- __('Authorization header not found.', 'wp-api-jwt-auth'),
- array(
- 'status' => 403,
- )
- );
- }
-
- /*
- * The HTTP_AUTHORIZATION is present verify the format
- * if the format is wrong return the user.
- */
- list($token) = sscanf($auth, 'Bearer %s');
- if (!$token) {
- return new WP_Error(
- 'jwt_auth_bad_auth_header',
- __('Authorization header malformed.', 'wp-api-jwt-auth'),
- array(
- 'status' => 403,
- )
- );
- }
-
- /** Get the Secret Key */
- $secret_key = defined('JWT_AUTH_SECRET_KEY') ? JWT_AUTH_SECRET_KEY : false;
- if (!$secret_key) {
- return new WP_Error(
- 'jwt_auth_bad_config',
- __('JWT is not configurated properly, please contact the admin', 'wp-api-jwt-auth'),
- array(
- 'status' => 403,
- )
- );
- }
-
- /** Try to decode the token */
- try {
- $token = JWT::decode($token, $secret_key, array('HS256'));
- /** The Token is decoded now validate the iss */
- if ($token->iss != get_bloginfo('url')) {
- /** The iss do not match, return error */
- return new WP_Error(
- 'jwt_auth_bad_iss',
- __('The iss do not match with this server', 'wp-api-jwt-auth'),
- array(
- 'status' => 403,
- )
- );
- }
- /** So far so good, validate the user id in the token */
- if (!isset($token->data->user->id)) {
- /** No user id in the token, abort!! */
- return new WP_Error(
- 'jwt_auth_bad_request',
- __('User ID not found in the token', 'wp-api-jwt-auth'),
- array(
- 'status' => 403,
- )
- );
- }
- /** Everything looks good return the decoded token if the $output is false */
- if (!$output) {
- return $token;
- }
- /** If the output is true return an answer to the request to show it */
- return array(
- 'code' => 'jwt_auth_valid_token',
- 'data' => array(
- 'status' => 200,
- ),
- );
- } catch (Exception $e) {
- /** Something is wrong trying to decode the token, send back the error */
- return new WP_Error(
- 'jwt_auth_invalid_token',
- $e->getMessage(),
- array(
- 'status' => 403,
- )
- );
- }
- }
-
- /**
- * Filter to hook the rest_pre_dispatch, if the is an error in the request
- * send it, if there is no error just continue with the current request.
- *
- * @param $request
- */
- public function rest_pre_dispatch($request)
- {
- if (is_wp_error($this->jwt_error)) {
- return $this->jwt_error;
- }
- return $request;
- }
+class Jwt_Auth_Public {
+ /**
+ * The ID of this plugin.
+ *
+ * @since 1.0.0
+ *
+ * @var string The ID of this plugin.
+ */
+ private string $plugin_name;
+
+ /**
+ * The version of this plugin.
+ *
+ * @since 1.0.0
+ *
+ * @var string The current version of this plugin.
+ */
+ private string $version;
+
+ /**
+ * The namespace to add to the api calls.
+ *
+ * @var string The namespace to add to the api call
+ */
+ private string $namespace;
+
+ /**
+ * Store errors to display if the JWT is wrong
+ *
+ * @var WP_Error|null
+ */
+ private ?WP_Error $jwt_error = null;
+
+ /**
+ * Supported algorithms to sign the token.
+ *
+ * @var array|string[]
+ * @since 1.3.1
+ * @see https://www.rfc-editor.org/rfc/rfc7518#section-3
+ */
+ private array $supported_algorithms = [ 'HS256', 'HS384', 'HS512', 'RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512', 'PS256', 'PS384', 'PS512' ];
+
+ /**
+ * Initialize the class and set its properties.
+ *
+ * @param string $plugin_name The name of the plugin.
+ * @param string $version The version of this plugin.
+ *
+ * @since 1.0.0
+ *
+ */
+ public function __construct( string $plugin_name, string $version ) {
+ $this->plugin_name = $plugin_name;
+ $this->version = $version;
+ $this->namespace = $this->plugin_name . '/v' . intval( $this->version );
+ }
+
+ /**
+ * Add the endpoints to the API
+ */
+ public function add_api_routes() {
+ register_rest_route( $this->namespace, 'token', [
+ 'methods' => 'POST',
+ 'callback' => [ $this, 'generate_token' ],
+ 'permission_callback' => '__return_true',
+ ] );
+
+ register_rest_route( $this->namespace, 'token/validate', [
+ 'methods' => 'POST',
+ 'callback' => [ $this, 'validate_token' ],
+ 'permission_callback' => '__return_true',
+ ] );
+ }
+
+ /**
+ * Add CORs support to the request.
+ */
+ public function add_cors_support() {
+ $enable_cors = defined( 'JWT_AUTH_CORS_ENABLE' ) && JWT_AUTH_CORS_ENABLE;
+ if ( $enable_cors ) {
+ $headers = apply_filters( 'jwt_auth_cors_allow_headers', 'Access-Control-Allow-Headers, Content-Type, Authorization' );
+ header( sprintf( 'Access-Control-Allow-Headers: %s', $headers ) );
+ }
+ }
+
+ /**
+ * Get the user and password in the request body and generate a JWT
+ *
+ * @param WP_REST_Request $request
+ *
+ * @return mixed|WP_Error|null
+ */
+ public function generate_token( WP_REST_Request $request ) {
+ $secret_key = defined( 'JWT_AUTH_SECRET_KEY' ) ? JWT_AUTH_SECRET_KEY : false;
+ $username = $request->get_param( 'username' );
+ $password = $request->get_param( 'password' );
+
+ /** First thing, check the secret key if not exist return an error*/
+ if ( ! $secret_key ) {
+ return new WP_Error(
+ 'jwt_auth_bad_config',
+ __( 'JWT is not configured properly, please contact the admin', 'wp-api-jwt-auth' ),
+ [
+ 'status' => 403,
+ ]
+ );
+ }
+ /** Try to authenticate the user with the passed credentials*/
+ $user = wp_authenticate( $username, $password );
+
+ /** If the authentication fails return an error*/
+ if ( is_wp_error( $user ) ) {
+ $error_code = $user->get_error_code();
+
+ return new WP_Error(
+ '[jwt_auth] ' . $error_code,
+ $user->get_error_message( $error_code ),
+ [
+ 'status' => 403,
+ ]
+ );
+ }
+
+ /** Valid credentials, the user exists create the according Token */
+ $issuedAt = time();
+ $notBefore = apply_filters( 'jwt_auth_not_before', $issuedAt, $issuedAt );
+ $expire = apply_filters( 'jwt_auth_expire', $issuedAt + ( DAY_IN_SECONDS * 7 ), $issuedAt );
+
+ $token = [
+ 'iss' => get_bloginfo( 'url' ),
+ 'iat' => $issuedAt,
+ 'nbf' => $notBefore,
+ 'exp' => $expire,
+ 'data' => [
+ 'user' => [
+ 'id' => $user->data->ID,
+ ],
+ ],
+ ];
+
+ /** Let the user modify the token data before the sign. */
+ $algorithm = $this->get_algorithm();
+
+ if ( $algorithm === false ) {
+ return new WP_Error(
+ 'jwt_auth_unsupported_algorithm',
+ __( 'Algorithm not supported, see https://www.rfc-editor.org/rfc/rfc7518#section-3', 'wp-api-jwt-auth' ),
+ [
+ 'status' => 403,
+ ]
+ );
+ }
+
+ $token = JWT::encode(
+ apply_filters( 'jwt_auth_token_before_sign', $token, $user ),
+ $secret_key,
+ $algorithm
+ );
+
+ /** The token is signed, now create the object with no sensible user data to the client*/
+ $data = [
+ 'token' => $token,
+ 'user_email' => $user->data->user_email,
+ 'user_nicename' => $user->data->user_nicename,
+ 'user_display_name' => $user->data->display_name,
+ ];
+
+ /** Let the user modify the data before send it back */
+ return apply_filters( 'jwt_auth_token_before_dispatch', $data, $user );
+ }
+
+ /**
+ * This is our Middleware to try to authenticate the user according to the
+ * token send.
+ *
+ * @param (int|bool) $user Logged User ID
+ *
+ * @return (int|bool)
+ */
+ public function determine_current_user( $user ) {
+ /**
+ * This hook only should run on the REST API requests to determine
+ * if the user in the Token (if any) is valid, for any other
+ * normal call ex. wp-admin/.* return the user.
+ *
+ * @since 1.2.3
+ **/
+ $rest_api_slug = rest_get_url_prefix();
+ $requested_url = sanitize_url(http://github.com/$_SERVER['REQUEST_URI']);
+ // if we already have a valid user, or we have an invalid url, don't attempt to validate token
+ $is_rest_request_constant_defined = defined( 'REST_REQUEST' ) && REST_REQUEST;
+ $is_rest_request = $is_rest_request_constant_defined || strpos( $requested_url, $rest_api_slug );
+ if ( $is_rest_request && $user ) {
+ return $user;
+ }
+
+ /*
+ * if the request URI is for validate the token don't do anything,
+ * this avoids double calls.
+ */
+ $validate_uri = strpos( $requested_url, 'token/validate' );
+ if ( $validate_uri > 0 ) {
+ return $user;
+ }
+
+ /**
+ * We still need to get the Authorization header and check for the token.
+ */
+ $auth_header = ! empty( $_SERVER['HTTP_AUTHORIZATION'] ) ? sanitize_text_field( $_SERVER['HTTP_AUTHORIZATION'] ) : false;
+ /* Double check for different auth header string (server dependent) */
+ if ( ! $auth_header ) {
+ $auth_header = ! empty( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) ? sanitize_text_field( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) : false;
+ }
+
+ if ( ! $auth_header ) {
+ return $user;
+ }
+
+ /*
+ * Check the token from the headers.
+ */
+ $token = $this->validate_token( new WP_REST_Request(), $auth_header );
+
+ if ( is_wp_error( $token ) ) {
+ if ( $token->get_error_code() != 'jwt_auth_no_auth_header' ) {
+ /** If there is an error, store it to show it after see rest_pre_dispatch */
+ $this->jwt_error = $token;
+ }
+
+ return $user;
+ }
+
+ /** Everything is ok, return the user ID stored in the token*/
+ return $token->data->user->id;
+ }
+
+ /**
+ * Main validation function
+ *
+ * This function is used by the /token/validate endpoint and
+ * by our middleware.
+ *
+ * The function take the token and try to decode it and validated it.
+ *
+ * @param WP_REST_Request $request
+ * @param bool|string $custom_token
+ *
+ * @return WP_Error | Object | Array
+ */
+ public function validate_token( WP_REST_Request $request, $custom_token = false ) {
+ /*
+ * Looking for the Authorization header
+ *
+ * There is two ways to get the authorization token
+ * 1. via WP_REST_Request
+ * 2. via custom_token, we get this for all the other API requests
+ *
+ * The get_header( 'Authorization' ) checks for the header in the following order:
+ * 1. HTTP_AUTHORIZATION
+ * 2. REDIRECT_HTTP_AUTHORIZATION
+ *
+ * @see https://core.trac.wordpress.org/ticket/47077
+ */
+
+ $auth_header = $custom_token ?: $request->get_header( 'Authorization' );
+
+ if ( ! $auth_header ) {
+ return new WP_Error(
+ 'jwt_auth_no_auth_header',
+ 'Authorization header not found.',
+ [
+ 'status' => 403,
+ ]
+ );
+ }
+
+ /*
+ * Extract the authorization header
+ */
+ [ $token ] = sscanf( $auth_header, 'Bearer %s' );
+
+ /**
+ * if the format is not valid return an error.
+ */
+ if ( ! $token ) {
+ return new WP_Error(
+ 'jwt_auth_bad_auth_header',
+ 'Authorization header malformed.',
+ [
+ 'status' => 403,
+ ]
+ );
+ }
+
+ /** Get the Secret Key */
+ $secret_key = defined( 'JWT_AUTH_SECRET_KEY' ) ? JWT_AUTH_SECRET_KEY : false;
+ if ( ! $secret_key ) {
+ return new WP_Error(
+ 'jwt_auth_bad_config',
+ 'JWT is not configured properly, please contact the admin',
+ [
+ 'status' => 403,
+ ]
+ );
+ }
+
+ /** Try to decode the token */
+ try {
+ $algorithm = $this->get_algorithm();
+ if ( $algorithm === false ) {
+ return new WP_Error(
+ 'jwt_auth_unsupported_algorithm',
+ __( 'Algorithm not supported, see https://www.rfc-editor.org/rfc/rfc7518#section-3', 'wp-api-jwt-auth' ),
+ [
+ 'status' => 403,
+ ]
+ );
+ }
+
+ $token = JWT::decode( $token, new Key( $secret_key, $algorithm ) );
+
+ /** The Token is decoded now validate the iss */
+ if ( $token->iss !== get_bloginfo( 'url' ) ) {
+ /** The iss do not match, return error */
+ return new WP_Error(
+ 'jwt_auth_bad_iss',
+ 'The iss do not match with this server',
+ [
+ 'status' => 403,
+ ]
+ );
+ }
+
+ /** So far so good, validate the user id in the token */
+ if ( ! isset( $token->data->user->id ) ) {
+ /** No user id in the token, abort!! */
+ return new WP_Error(
+ 'jwt_auth_bad_request',
+ 'User ID not found in the token',
+ [
+ 'status' => 403,
+ ]
+ );
+ }
+
+ /** Everything looks good return the decoded token if we are using the custom_token */
+ if ( $custom_token ) {
+ return $token;
+ }
+
+ /** This is for the /toke/validate endpoint*/
+ return [
+ 'code' => 'jwt_auth_valid_token',
+ 'data' => [
+ 'status' => 200,
+ ],
+ ];
+ } catch ( Exception $e ) {
+ /** Something were wrong trying to decode the token, send back the error */
+ return new WP_Error(
+ 'jwt_auth_invalid_token',
+ $e->getMessage(),
+ [
+ 'status' => 403,
+ ]
+ );
+ }
+ }
+
+ /**
+ * Filter to hook the rest_pre_dispatch, if the is an error in the request
+ * send it, if there is no error just continue with the current request.
+ *
+ * @param $request
+ *
+ * @return mixed|WP_Error|null
+ */
+ public function rest_pre_dispatch( $request ) {
+ if ( is_wp_error( $this->jwt_error ) ) {
+ return $this->jwt_error;
+ }
+
+ return $request;
+ }
+
+ /**
+ * Get the algorithm used to sign the token via the filter jwt_auth_algorithm.
+ * and validate that the algorithm is in the supported list.
+ *
+ * @return false|mixed|null
+ */
+ private function get_algorithm() {
+ $algorithm = apply_filters( 'jwt_auth_algorithm', 'HS256' );
+ if ( ! in_array( $algorithm, $this->supported_algorithms ) ) {
+ return false;
+ }
+
+ return $algorithm;
+ }
}
diff --git a/readme.txt b/readme.txt
index 5fdb0115..85e31ffe 100755
--- a/readme.txt
+++ b/readme.txt
@@ -1,11 +1,12 @@
=== JWT Authentication for WP REST API ===
Contributors: tmeister
-Donate link: https://enriquechavez.co
+Donate link: https://www.paypal.me/wpchavez
Tags: wp-json, jwt, json web authentication, wp-api
Requires at least: 4.2
-Tested up to: 4.3
-Stable tag: 1.0
+Tested up to: 6.3.1
+Requires PHP: 7.4.0
+Stable tag: 1.3.3
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -61,7 +62,7 @@ The JWT needs a **secret key** to sign the token this **secret key** must be uni
To add the **secret key** edit your wp-config.php file and add a new constant called **JWT_AUTH_SECRET_KEY**
`
-define('JWT_AUTH_SECRET_KEY', 'your-top-secrect-key');
+define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key');
`
You can use a string from here https://api.wordpress.org/secret-key/1.1/salt/
@@ -320,6 +321,30 @@ $data = array(
);
`
+### jwt_auth_algorithm
+The **jwt_auth_algorithm** allows you to modify the signing algorithm.
+
+Default value:
+
+`
+