From 63146eb697567628a2645f7489b07fd3893a1ba9 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Fri, 22 Jul 2022 18:07:24 +0100
Subject: [PATCH 01/21] wip: cipher upgrade
---
README.md | 11 +-
composer.json | 8 +-
composer.lock | 979 +++++++++++-------
src/Authenticator.php | 74 +-
src/InitVector.php | 18 -
.../{AdminUri.php => AdminUriBase.php} | 4 +-
...actProviderUri.php => BaseProviderUri.php} | 8 +-
.../{LoginUri.php => LoginUriBase.php} | 4 +-
.../{LogoutUri.php => LogoutUriBase.php} | 6 +-
.../{ProfileUri.php => ProfileUriBase.php} | 4 +-
src/ResponseData/UserData.php | 4 +-
src/Token.php | 51 +-
test/phpunit/AuthenticatorTest.php | 332 +++---
.../phpunit/MalformedReponseDataException.php | 6 -
.../ProviderUri/AbstractProviderUriTest.php | 16 +-
test/phpunit/ProviderUri/AdminUriTest.php | 6 +-
test/phpunit/ProviderUri/LoginUriTest.php | 12 +-
test/phpunit/TokenTest.php | 64 +-
18 files changed, 932 insertions(+), 675 deletions(-)
delete mode 100644 src/InitVector.php
rename src/ProviderUri/{AdminUri.php => AdminUriBase.php} (82%)
rename src/ProviderUri/{AbstractProviderUri.php => BaseProviderUri.php} (86%)
rename src/ProviderUri/{LoginUri.php => LoginUriBase.php} (95%)
rename src/ProviderUri/{LogoutUri.php => LogoutUriBase.php} (84%)
rename src/ProviderUri/{ProfileUri.php => ProfileUriBase.php} (87%)
delete mode 100644 test/phpunit/MalformedReponseDataException.php
diff --git a/README.md b/README.md
index 539097a..5970f8b 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ To use this repository, your application must be registered to obtain a client k
Basic usage
-----------
-With the following PHP code below, you can display a log in button that, when clicked, changes to a log out button and displays a greeting to the logged in user.
+With the following PHP code below, you can display a login button that, when clicked, changes to a logout button and displays a greeting to the logged-in user.
```php
isLoggedIn()) {
+// Available methods:
+// $auth->getId(); // a unique string in ULID format - use this to store in your database
+// $auth->getEmail(); // the current email of the user (could change)
+// $auth->getField($name); // any extra field your application is configured to take upon user signup
+
echo <<You are logged in as {$auth->getEmail()}
Log out
@@ -52,4 +57,4 @@ else {
Log in
HTML;
}
-```
\ No newline at end of file
+```
diff --git a/composer.json b/composer.json
index b360806..78b30fa 100644
--- a/composer.json
+++ b/composer.json
@@ -3,13 +3,15 @@
"description": "PHP client library to implement Authwave in your application",
"require": {
- "php": ">=7.4",
+ "php": ">=8.1",
"ext-openssl": "*",
+ "phpgt/cipher": "dev-master",
"phpgt/http": "1.*",
"phpgt/session": ">=1.1"
},
"require-dev": {
- "phpunit/phpunit": "8.*"
+ "phpunit/phpunit": "8.*",
+ "ext-sodium": "*"
},
"autoload": {
"psr-4": {
@@ -21,4 +23,4 @@
"Authwave\\Test\\": "./test/phpunit"
}
}
-}
\ No newline at end of file
+}
diff --git a/composer.lock b/composer.lock
index 396bbef..bf392a9 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,73 +1,86 @@
{
"_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"
],
- "content-hash": "f740eced9a0ec10945d216e31b732e26",
+ "content-hash": "33cc3f246595defd43ac4a235110f89a",
"packages": [
{
- "name": "phpgt/cookie",
- "version": "v1.0.2",
+ "name": "phpgt/cipher",
+ "version": "dev-master",
"source": {
"type": "git",
- "url": "https://github.com/PhpGt/Cookie.git",
- "reference": "dd811b6f04becc7c1f8524d84ad02e4635f4a94e"
+ "url": "https://github.com/PhpGt/Cipher.git",
+ "reference": "5cef809acd0d77d24ea11ece9ba0e1ed4c8736fd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PhpGt/Cookie/zipball/dd811b6f04becc7c1f8524d84ad02e4635f4a94e",
- "reference": "dd811b6f04becc7c1f8524d84ad02e4635f4a94e",
+ "url": "https://api.github.com/repos/PhpGt/Cipher/zipball/5cef809acd0d77d24ea11ece9ba0e1ed4c8736fd",
+ "reference": "5cef809acd0d77d24ea11ece9ba0e1ed4c8736fd",
"shasum": ""
},
"require": {
- "php": ">=7.2"
+ "ext-sodium": "*",
+ "php": ">=8.0",
+ "phpgt/http": "v1.*"
},
"require-dev": {
- "phpunit/phpunit": "8.*"
+ "phpstan/phpstan": "v1.8.0",
+ "phpunit/phpunit": "v9.5.21"
},
+ "default-branch": true,
"type": "library",
"autoload": {
"psr-4": {
- "Gt\\Cookie\\": "./src"
+ "Gt\\Cipher\\": "./src"
}
},
"notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
"authors": [
{
"name": "Greg Bowler",
- "email": "greg.bowler@g105b.com"
+ "email": "greg.bowler@g105b.com",
+ "homepage": "https://www.g105b.com",
+ "role": "Developer"
}
],
- "description": "Object oriented cookie handler.",
- "time": "2019-07-17T20:11:11+00:00"
+ "description": "Two-way encryption of messages for secure plain text transmission.",
+ "support": {
+ "issues": "https://github.com/PhpGt/Cipher/issues",
+ "source": "https://github.com/PhpGt/Cipher/tree/master"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/PhpGt",
+ "type": "github"
+ }
+ ],
+ "time": "2022-07-20T11:29:08+00:00"
},
{
"name": "phpgt/http",
- "version": "v1.0.3",
+ "version": "v1.1.4",
"source": {
"type": "git",
"url": "https://github.com/PhpGt/Http.git",
- "reference": "394ecdd2a2e2686a467cdf2f837c72105d68398f"
+ "reference": "80ed7269050bc0f2de2402c5461711dd2418f55f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PhpGt/Http/zipball/394ecdd2a2e2686a467cdf2f837c72105d68398f",
- "reference": "394ecdd2a2e2686a467cdf2f837c72105d68398f",
+ "url": "https://api.github.com/repos/PhpGt/Http/zipball/80ed7269050bc0f2de2402c5461711dd2418f55f",
+ "reference": "80ed7269050bc0f2de2402c5461711dd2418f55f",
"shasum": ""
},
"require": {
- "php": ">=7.2",
- "phpgt/cookie": "*",
- "phpgt/input": "*",
- "psr/http-message": "^1.0.1",
- "willdurand/negotiation": "^2.3"
+ "php": ">=8.0",
+ "phpgt/input": "^v1",
+ "psr/http-message": "^v1.0.1",
+ "willdurand/negotiation": "v3.0.*"
},
"require-dev": {
- "phpunit/phpunit": "8.*"
+ "phpstan/phpstan": ">=0.12.64",
+ "phpunit/phpunit": "9.*"
},
"type": "library",
"autoload": {
@@ -80,27 +93,39 @@
"MIT"
],
"description": "PSR-7 HTTP message implementation.",
- "time": "2019-11-28T12:05:15+00:00"
+ "support": {
+ "issues": "https://github.com/PhpGt/Http/issues",
+ "source": "https://github.com/PhpGt/Http/tree/v1.1.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/PhpGt",
+ "type": "github"
+ }
+ ],
+ "time": "2021-06-23T15:45:09+00:00"
},
{
"name": "phpgt/input",
- "version": "v1.1.2",
+ "version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/PhpGt/Input.git",
- "reference": "ae78931ffd5c4800f362db61bd86f8e545733e86"
+ "reference": "95136bcbe1c50c3d8db90eb3b1944d049ec2b2a0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PhpGt/Input/zipball/ae78931ffd5c4800f362db61bd86f8e545733e86",
- "reference": "ae78931ffd5c4800f362db61bd86f8e545733e86",
+ "url": "https://api.github.com/repos/PhpGt/Input/zipball/95136bcbe1c50c3d8db90eb3b1944d049ec2b2a0",
+ "reference": "95136bcbe1c50c3d8db90eb3b1944d049ec2b2a0",
"shasum": ""
},
"require": {
- "phpgt/http": "*"
+ "php": ">=8.0",
+ "phpgt/http": "^v1.1"
},
"require-dev": {
- "phpunit/phpunit": "8.*"
+ "phpstan/phpstan": "^v1.4",
+ "phpunit/phpunit": "^v9.5"
},
"type": "library",
"autoload": {
@@ -113,27 +138,39 @@
"MIT"
],
"description": "Encapsulated user input.",
- "time": "2019-11-29T11:22:35+00:00"
+ "support": {
+ "issues": "https://github.com/PhpGt/Input/issues",
+ "source": "https://github.com/PhpGt/Input/tree/v1.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/PhpGt",
+ "type": "github"
+ }
+ ],
+ "time": "2022-03-18T19:03:02+00:00"
},
{
"name": "phpgt/session",
- "version": "v1.1.0",
+ "version": "v1.1.5",
"source": {
"type": "git",
"url": "https://github.com/PhpGt/Session.git",
- "reference": "97b793244a6cde7858f5bf07ecfad67ce4d6002b"
+ "reference": "4ec55d2e38117b095d525b3e8507bdb5efac5c8a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PhpGt/Session/zipball/97b793244a6cde7858f5bf07ecfad67ce4d6002b",
- "reference": "97b793244a6cde7858f5bf07ecfad67ce4d6002b",
+ "url": "https://api.github.com/repos/PhpGt/Session/zipball/4ec55d2e38117b095d525b3e8507bdb5efac5c8a",
+ "reference": "4ec55d2e38117b095d525b3e8507bdb5efac5c8a",
"shasum": ""
},
"require": {
- "php": ">=7.2"
+ "php": ">=8.0",
+ "phpgt/typesafegetter": "^v1.2"
},
"require-dev": {
- "phpunit/phpunit": "^8.0"
+ "phpstan/phpstan": "^v1.4",
+ "phpunit/phpunit": "^9.5"
},
"type": "library",
"autoload": {
@@ -146,7 +183,67 @@
"MIT"
],
"description": "Encapsulated user sessions.",
- "time": "2020-02-27T16:06:07+00:00"
+ "support": {
+ "issues": "https://github.com/PhpGt/Session/issues",
+ "source": "https://github.com/PhpGt/Session/tree/v1.1.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/PhpGt",
+ "type": "github"
+ }
+ ],
+ "time": "2022-03-08T15:40:23+00:00"
+ },
+ {
+ "name": "phpgt/typesafegetter",
+ "version": "v1.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PhpGt/TypeSafeGetter.git",
+ "reference": "ebffd758e69b8a0eebcad30f3daf408915b9ddf3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PhpGt/TypeSafeGetter/zipball/ebffd758e69b8a0eebcad30f3daf408915b9ddf3",
+ "reference": "ebffd758e69b8a0eebcad30f3daf408915b9ddf3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "v1.8.0",
+ "phpunit/phpunit": "v9.5.21"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Gt\\TypeSafeGetter\\": "./src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Greg Bowler",
+ "email": "greg.bowler@g105b.com"
+ }
+ ],
+ "description": "An interface for objects that expose type-safe getter methods.",
+ "support": {
+ "issues": "https://github.com/PhpGt/TypeSafeGetter/issues",
+ "source": "https://github.com/PhpGt/TypeSafeGetter/tree/v1.2.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/PhpGt",
+ "type": "github"
+ }
+ ],
+ "time": "2022-07-08T17:17:42+00:00"
},
{
"name": "psr/http-message",
@@ -196,32 +293,35 @@
"request",
"response"
],
+ "support": {
+ "source": "https://github.com/php-fig/http-message/tree/master"
+ },
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "willdurand/negotiation",
- "version": "v2.3.1",
+ "version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/willdurand/Negotiation.git",
- "reference": "03436ededa67c6e83b9b12defac15384cb399dc9"
+ "reference": "04e14f38d4edfcc974114a07d2777d90c98f3d9c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/03436ededa67c6e83b9b12defac15384cb399dc9",
- "reference": "03436ededa67c6e83b9b12defac15384cb399dc9",
+ "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/04e14f38d4edfcc974114a07d2777d90c98f3d9c",
+ "reference": "04e14f38d4edfcc974114a07d2777d90c98f3d9c",
"shasum": ""
},
"require": {
- "php": ">=5.4.0"
+ "php": ">=7.1.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.5"
+ "symfony/phpunit-bridge": "^5.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.3-dev"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
@@ -248,42 +348,42 @@
"header",
"negotiation"
],
- "time": "2017-05-14T17:21:12+00:00"
+ "support": {
+ "issues": "https://github.com/willdurand/Negotiation/issues",
+ "source": "https://github.com/willdurand/Negotiation/tree/3.0.0"
+ },
+ "time": "2020-09-25T08:01:41+00:00"
}
],
"packages-dev": [
{
"name": "doctrine/instantiator",
- "version": "1.3.0",
+ "version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
- "reference": "ae466f726242e637cebdd526a7d991b9433bacf1"
+ "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1",
- "reference": "ae466f726242e637cebdd526a7d991b9433bacf1",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc",
+ "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": "^7.1 || ^8.0"
},
"require-dev": {
- "doctrine/coding-standard": "^6.0",
+ "doctrine/coding-standard": "^9",
"ext-pdo": "*",
"ext-phar": "*",
- "phpbench/phpbench": "^0.13",
- "phpstan/phpstan-phpunit": "^0.11",
- "phpstan/phpstan-shim": "^0.11",
- "phpunit/phpunit": "^7.0"
+ "phpbench/phpbench": "^0.16 || ^1",
+ "phpstan/phpstan": "^1.4",
+ "phpstan/phpstan-phpunit": "^1",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "vimeo/psalm": "^4.22"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.2.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
@@ -297,7 +397,7 @@
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
- "homepage": "http://ocramius.github.com/"
+ "homepage": "https://ocramius.github.io/"
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
@@ -306,41 +406,60 @@
"constructor",
"instantiate"
],
- "time": "2019-10-21T16:45:58+00:00"
+ "support": {
+ "issues": "https://github.com/doctrine/instantiator/issues",
+ "source": "https://github.com/doctrine/instantiator/tree/1.4.1"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-03-03T08:28:38+00:00"
},
{
"name": "myclabs/deep-copy",
- "version": "1.9.5",
+ "version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef"
+ "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef",
- "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
+ "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": "^7.1 || ^8.0"
},
- "replace": {
- "myclabs/deep-copy": "self.version"
+ "conflict": {
+ "doctrine/collections": "<1.6.8",
+ "doctrine/common": "<2.13.3 || >=3,<3.2.2"
},
"require-dev": {
- "doctrine/collections": "^1.0",
- "doctrine/common": "^2.6",
- "phpunit/phpunit": "^7.1"
+ "doctrine/collections": "^1.6.8",
+ "doctrine/common": "^2.13.3 || ^3.2.2",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
},
"type": "library",
"autoload": {
- "psr-4": {
- "DeepCopy\\": "src/DeepCopy/"
- },
"files": [
"src/DeepCopy/deep_copy.php"
- ]
+ ],
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -354,32 +473,43 @@
"object",
"object graph"
],
- "time": "2020-01-17T21:11:47+00:00"
+ "support": {
+ "issues": "https://github.com/myclabs/DeepCopy/issues",
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
+ },
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-03-03T13:19:32+00:00"
},
{
"name": "phar-io/manifest",
- "version": "1.0.3",
+ "version": "2.0.3",
"source": {
"type": "git",
"url": "https://github.com/phar-io/manifest.git",
- "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
+ "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
- "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
+ "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-phar": "*",
- "phar-io/version": "^2.0",
- "php": "^5.6 || ^7.0"
+ "ext-xmlwriter": "*",
+ "phar-io/version": "^3.0.1",
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
@@ -409,24 +539,28 @@
}
],
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
- "time": "2018-07-08T19:23:20+00:00"
+ "support": {
+ "issues": "https://github.com/phar-io/manifest/issues",
+ "source": "https://github.com/phar-io/manifest/tree/2.0.3"
+ },
+ "time": "2021-07-20T11:28:43+00:00"
},
{
"name": "phar-io/version",
- "version": "2.0.1",
+ "version": "3.2.1",
"source": {
"type": "git",
"url": "https://github.com/phar-io/version.git",
- "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
- "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
"shasum": ""
},
"require": {
- "php": "^5.6 || ^7.0"
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"autoload": {
@@ -456,32 +590,33 @@
}
],
"description": "Library for handling version information and constraints",
- "time": "2018-07-08T19:19:57+00:00"
+ "support": {
+ "issues": "https://github.com/phar-io/version/issues",
+ "source": "https://github.com/phar-io/version/tree/3.2.1"
+ },
+ "time": "2022-02-21T01:04:05+00:00"
},
{
"name": "phpdocumentor/reflection-common",
- "version": "2.0.0",
+ "version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a"
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a",
- "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"shasum": ""
},
"require": {
- "php": ">=7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "~6"
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.x-dev"
+ "dev-2.x": "2.x-dev"
}
},
"autoload": {
@@ -508,32 +643,36 @@
"reflection",
"static analysis"
],
- "time": "2018-08-07T13:53:10+00:00"
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
+ },
+ "time": "2020-06-27T09:03:43+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
- "version": "5.1.0",
+ "version": "5.3.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e"
+ "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e",
- "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
+ "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
"shasum": ""
},
"require": {
- "ext-filter": "^7.1",
- "php": "^7.2",
- "phpdocumentor/reflection-common": "^2.0",
- "phpdocumentor/type-resolver": "^1.0",
- "webmozart/assert": "^1"
+ "ext-filter": "*",
+ "php": "^7.2 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.2",
+ "phpdocumentor/type-resolver": "^1.3",
+ "webmozart/assert": "^1.9.1"
},
"require-dev": {
- "doctrine/instantiator": "^1",
- "mockery/mockery": "^1"
+ "mockery/mockery": "~1.3.2",
+ "psalm/phar": "^4.8"
},
"type": "library",
"extra": {
@@ -561,34 +700,38 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "time": "2020-02-22T12:28:44+00:00"
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
+ },
+ "time": "2021-10-19T17:43:47+00:00"
},
{
"name": "phpdocumentor/type-resolver",
- "version": "1.1.0",
+ "version": "1.6.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "7462d5f123dfc080dfdf26897032a6513644fc95"
+ "reference": "77a32518733312af16a44300404e945338981de3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/7462d5f123dfc080dfdf26897032a6513644fc95",
- "reference": "7462d5f123dfc080dfdf26897032a6513644fc95",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3",
+ "reference": "77a32518733312af16a44300404e945338981de3",
"shasum": ""
},
"require": {
- "php": "^7.2",
+ "php": "^7.2 || ^8.0",
"phpdocumentor/reflection-common": "^2.0"
},
"require-dev": {
- "ext-tokenizer": "^7.2",
- "mockery/mockery": "~1"
+ "ext-tokenizer": "*",
+ "psalm/phar": "^4.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.x-dev"
+ "dev-1.x": "1.x-dev"
}
},
"autoload": {
@@ -607,37 +750,41 @@
}
],
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
- "time": "2020-02-18T18:59:58+00:00"
+ "support": {
+ "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1"
+ },
+ "time": "2022-03-15T21:29:03+00:00"
},
{
"name": "phpspec/prophecy",
- "version": "v1.10.2",
+ "version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
- "reference": "b4400efc9d206e83138e2bb97ed7f5b14b831cd9"
+ "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b4400efc9d206e83138e2bb97ed7f5b14b831cd9",
- "reference": "b4400efc9d206e83138e2bb97ed7f5b14b831cd9",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
+ "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.0.2",
- "php": "^5.3|^7.0",
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
- "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0",
- "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0"
+ "doctrine/instantiator": "^1.2",
+ "php": "^7.2 || ~8.0, <8.2",
+ "phpdocumentor/reflection-docblock": "^5.2",
+ "sebastian/comparator": "^3.0 || ^4.0",
+ "sebastian/recursion-context": "^3.0 || ^4.0"
},
"require-dev": {
- "phpspec/phpspec": "^2.5 || ^3.2",
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+ "phpspec/phpspec": "^6.0 || ^7.0",
+ "phpunit/phpunit": "^8.0 || ^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.10.x-dev"
+ "dev-master": "1.x-dev"
}
},
"autoload": {
@@ -670,29 +817,33 @@
"spy",
"stub"
],
- "time": "2020-01-20T15:57:02+00:00"
+ "support": {
+ "issues": "https://github.com/phpspec/prophecy/issues",
+ "source": "https://github.com/phpspec/prophecy/tree/v1.15.0"
+ },
+ "time": "2021-12-08T12:19:24+00:00"
},
{
"name": "phpunit/php-code-coverage",
- "version": "7.0.10",
+ "version": "7.0.15",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf"
+ "reference": "819f92bba8b001d4363065928088de22f25a3a48"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf",
- "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/819f92bba8b001d4363065928088de22f25a3a48",
+ "reference": "819f92bba8b001d4363065928088de22f25a3a48",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-xmlwriter": "*",
- "php": "^7.2",
+ "php": ">=7.2",
"phpunit/php-file-iterator": "^2.0.2",
"phpunit/php-text-template": "^1.2.1",
- "phpunit/php-token-stream": "^3.1.1",
+ "phpunit/php-token-stream": "^3.1.3 || ^4.0",
"sebastian/code-unit-reverse-lookup": "^1.0.1",
"sebastian/environment": "^4.2.2",
"sebastian/version": "^2.0.1",
@@ -733,27 +884,37 @@
"testing",
"xunit"
],
- "time": "2019-11-20T13:55:58+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.15"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-07-26T12:20:09+00:00"
},
{
"name": "phpunit/php-file-iterator",
- "version": "2.0.2",
+ "version": "2.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "050bedf145a257b1ff02746c31894800e5122946"
+ "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
- "reference": "050bedf145a257b1ff02746c31894800e5122946",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
+ "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "^7.1"
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
@@ -783,7 +944,17 @@
"filesystem",
"iterator"
],
- "time": "2018-09-13T20:33:42+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-12-02T12:42:26+00:00"
},
{
"name": "phpunit/php-text-template",
@@ -824,27 +995,31 @@
"keywords": [
"template"
],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
+ },
"time": "2015-06-21T13:50:34+00:00"
},
{
"name": "phpunit/php-timer",
- "version": "2.1.2",
+ "version": "2.1.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "1038454804406b0b5f5f520358e78c1c2f71501e"
+ "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e",
- "reference": "1038454804406b0b5f5f520358e78c1c2f71501e",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
+ "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "^7.0"
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
@@ -873,33 +1048,43 @@
"keywords": [
"timer"
],
- "time": "2019-06-07T04:22:29+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-timer/issues",
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T08:20:02+00:00"
},
{
"name": "phpunit/php-token-stream",
- "version": "3.1.1",
+ "version": "4.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff"
+ "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff",
- "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3",
+ "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
- "php": "^7.1"
+ "php": "^7.3 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "^7.0"
+ "phpunit/phpunit": "^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.1-dev"
+ "dev-master": "4.0-dev"
}
},
"autoload": {
@@ -922,52 +1107,60 @@
"keywords": [
"tokenizer"
],
- "time": "2019-09-17T06:23:10+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
+ "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "abandoned": true,
+ "time": "2020-08-04T08:28:15+00:00"
},
{
"name": "phpunit/phpunit",
- "version": "8.5.2",
+ "version": "8.5.27",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "018b6ac3c8ab20916db85fa91bf6465acb64d1e0"
+ "reference": "df70070f2711b8fe8dcca0797c1239ede8c94be6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/018b6ac3c8ab20916db85fa91bf6465acb64d1e0",
- "reference": "018b6ac3c8ab20916db85fa91bf6465acb64d1e0",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/df70070f2711b8fe8dcca0797c1239ede8c94be6",
+ "reference": "df70070f2711b8fe8dcca0797c1239ede8c94be6",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.2.0",
+ "doctrine/instantiator": "^1.3.1",
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
- "myclabs/deep-copy": "^1.9.1",
- "phar-io/manifest": "^1.0.3",
- "phar-io/version": "^2.0.1",
- "php": "^7.2",
- "phpspec/prophecy": "^1.8.1",
- "phpunit/php-code-coverage": "^7.0.7",
- "phpunit/php-file-iterator": "^2.0.2",
+ "myclabs/deep-copy": "^1.10.0",
+ "phar-io/manifest": "^2.0.3",
+ "phar-io/version": "^3.0.2",
+ "php": ">=7.2",
+ "phpspec/prophecy": "^1.10.3",
+ "phpunit/php-code-coverage": "^7.0.12",
+ "phpunit/php-file-iterator": "^2.0.4",
"phpunit/php-text-template": "^1.2.1",
"phpunit/php-timer": "^2.1.2",
"sebastian/comparator": "^3.0.2",
"sebastian/diff": "^3.0.2",
- "sebastian/environment": "^4.2.2",
- "sebastian/exporter": "^3.1.1",
+ "sebastian/environment": "^4.2.3",
+ "sebastian/exporter": "^3.1.2",
"sebastian/global-state": "^3.0.0",
"sebastian/object-enumerator": "^3.0.3",
"sebastian/resource-operations": "^2.0.1",
"sebastian/type": "^1.1.3",
"sebastian/version": "^2.0.1"
},
- "require-dev": {
- "ext-pdo": "*"
- },
"suggest": {
"ext-soap": "*",
"ext-xdebug": "*",
@@ -1005,27 +1198,41 @@
"testing",
"xunit"
],
- "time": "2020-01-08T08:49:49+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.27"
+ },
+ "funding": [
+ {
+ "url": "https://phpunit.de/sponsors.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-06-19T12:11:16+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
- "version": "1.0.1",
+ "version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
- "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
+ "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
- "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
+ "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
"shasum": ""
},
"require": {
- "php": "^5.6 || ^7.0"
+ "php": ">=5.6"
},
"require-dev": {
- "phpunit/phpunit": "^5.7 || ^6.0"
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
@@ -1050,29 +1257,39 @@
],
"description": "Looks up which function or method a line of code belongs to",
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
- "time": "2017-03-04T06:30:41+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T08:15:22+00:00"
},
{
"name": "sebastian/comparator",
- "version": "3.0.2",
+ "version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da"
+ "reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
- "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
+ "reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
"shasum": ""
},
"require": {
- "php": "^7.1",
+ "php": ">=7.1",
"sebastian/diff": "^3.0",
"sebastian/exporter": "^3.1"
},
"require-dev": {
- "phpunit/phpunit": "^7.1"
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
@@ -1090,6 +1307,10 @@
"BSD-3-Clause"
],
"authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
@@ -1101,10 +1322,6 @@
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
}
],
"description": "Provides the functionality to compare PHP values for equality",
@@ -1114,24 +1331,34 @@
"compare",
"equality"
],
- "time": "2018-07-12T15:12:46+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/comparator/issues",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T08:04:30+00:00"
},
{
"name": "sebastian/diff",
- "version": "3.0.2",
+ "version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29"
+ "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
- "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
+ "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=7.1"
},
"require-dev": {
"phpunit/phpunit": "^7.5 || ^8.0",
@@ -1153,13 +1380,13 @@
"BSD-3-Clause"
],
"authors": [
- {
- "name": "Kore Nordmann",
- "email": "mail@kore-nordmann.de"
- },
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
}
],
"description": "Diff implementation",
@@ -1170,24 +1397,34 @@
"unidiff",
"unified diff"
],
- "time": "2019-02-04T06:01:07+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/diff/issues",
+ "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:59:04+00:00"
},
{
"name": "sebastian/environment",
- "version": "4.2.3",
+ "version": "4.2.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368"
+ "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
- "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
+ "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=7.1"
},
"require-dev": {
"phpunit/phpunit": "^7.5"
@@ -1223,29 +1460,39 @@
"environment",
"hhvm"
],
- "time": "2019-11-20T08:46:58+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:53:42+00:00"
},
{
"name": "sebastian/exporter",
- "version": "3.1.2",
+ "version": "3.1.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e"
+ "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e",
- "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
+ "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
"shasum": ""
},
"require": {
- "php": "^7.0",
+ "php": ">=7.0",
"sebastian/recursion-context": "^3.0"
},
"require-dev": {
"ext-mbstring": "*",
- "phpunit/phpunit": "^6.0"
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
@@ -1290,24 +1537,34 @@
"export",
"exporter"
],
- "time": "2019-09-14T09:02:43+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/exporter/issues",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-11-11T13:51:24+00:00"
},
{
"name": "sebastian/global-state",
- "version": "3.0.0",
+ "version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4"
+ "reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4",
- "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/de036ec91d55d2a9e0db2ba975b512cdb1c23921",
+ "reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921",
"shasum": ""
},
"require": {
- "php": "^7.2",
+ "php": ">=7.2",
"sebastian/object-reflector": "^1.1.1",
"sebastian/recursion-context": "^3.0"
},
@@ -1344,24 +1601,34 @@
"keywords": [
"global state"
],
- "time": "2019-02-01T05:30:01+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-02-10T06:55:38+00:00"
},
{
"name": "sebastian/object-enumerator",
- "version": "3.0.3",
+ "version": "3.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
- "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5"
+ "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5",
- "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
+ "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
"shasum": ""
},
"require": {
- "php": "^7.0",
+ "php": ">=7.0",
"sebastian/object-reflector": "^1.1.1",
"sebastian/recursion-context": "^3.0"
},
@@ -1391,24 +1658,34 @@
],
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
- "time": "2017-08-03T12:35:26+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
+ "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:40:27+00:00"
},
{
"name": "sebastian/object-reflector",
- "version": "1.1.1",
+ "version": "1.1.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-reflector.git",
- "reference": "773f97c67f28de00d397be301821b06708fca0be"
+ "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be",
- "reference": "773f97c67f28de00d397be301821b06708fca0be",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
+ "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
"shasum": ""
},
"require": {
- "php": "^7.0"
+ "php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
@@ -1436,24 +1713,34 @@
],
"description": "Allows reflection of object attributes, including inherited and non-public ones",
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
- "time": "2017-03-29T09:07:27+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:37:18+00:00"
},
{
"name": "sebastian/recursion-context",
- "version": "3.0.0",
+ "version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
+ "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
- "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
+ "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
"shasum": ""
},
"require": {
- "php": "^7.0"
+ "php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
@@ -1474,14 +1761,14 @@
"BSD-3-Clause"
],
"authors": [
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
@@ -1489,24 +1776,34 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2017-03-03T06:23:57+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:34:24+00:00"
},
{
"name": "sebastian/resource-operations",
- "version": "2.0.1",
+ "version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/resource-operations.git",
- "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9"
+ "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
- "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
+ "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=7.1"
},
"type": "library",
"extra": {
@@ -1531,24 +1828,34 @@
],
"description": "Provides a list of PHP built-in functions that operate on resources",
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
- "time": "2018-10-04T04:07:39+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:30:19+00:00"
},
{
"name": "sebastian/type",
- "version": "1.1.3",
+ "version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/type.git",
- "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3"
+ "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3",
- "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4",
+ "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4",
"shasum": ""
},
"require": {
- "php": "^7.2"
+ "php": ">=7.2"
},
"require-dev": {
"phpunit/phpunit": "^8.2"
@@ -1577,7 +1884,17 @@
],
"description": "Collection of value objects that represent the types of the PHP type system",
"homepage": "https://github.com/sebastianbergmann/type",
- "time": "2019-07-02T08:10:15+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/type/issues",
+ "source": "https://github.com/sebastianbergmann/type/tree/1.1.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:25:11+00:00"
},
{
"name": "sebastian/version",
@@ -1620,85 +1937,31 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
- "time": "2016-10-03T07:35:21+00:00"
- },
- {
- "name": "symfony/polyfill-ctype",
- "version": "v1.14.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues",
+ "source": "https://github.com/sebastianbergmann/version/tree/master"
},
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/fbdeaec0df06cf3d51c93de80c7eb76e271f5a38",
- "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "suggest": {
- "ext-ctype": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.14-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for ctype functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
- ],
- "time": "2020-01-13T11:15:53+00:00"
+ "time": "2016-10-03T07:35:21+00:00"
},
{
"name": "theseer/tokenizer",
- "version": "1.1.3",
+ "version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
- "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9"
+ "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
- "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
+ "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-tokenizer": "*",
"ext-xmlwriter": "*",
- "php": "^7.0"
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"autoload": {
@@ -1718,33 +1981,49 @@
}
],
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
- "time": "2019-06-13T22:48:21+00:00"
+ "support": {
+ "issues": "https://github.com/theseer/tokenizer/issues",
+ "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2021-07-28T10:34:58+00:00"
},
{
"name": "webmozart/assert",
- "version": "1.7.0",
+ "version": "1.11.0",
"source": {
"type": "git",
- "url": "https://github.com/webmozart/assert.git",
- "reference": "aed98a490f9a8f78468232db345ab9cf606cf598"
+ "url": "https://github.com/webmozarts/assert.git",
+ "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/aed98a490f9a8f78468232db345ab9cf606cf598",
- "reference": "aed98a490f9a8f78468232db345ab9cf606cf598",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
+ "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0",
- "symfony/polyfill-ctype": "^1.8"
+ "ext-ctype": "*",
+ "php": "^7.2 || ^8.0"
},
"conflict": {
- "vimeo/psalm": "<3.6.0"
+ "phpstan/phpstan": "<0.12.20",
+ "vimeo/psalm": "<4.6.1 || 4.6.2"
},
"require-dev": {
- "phpunit/phpunit": "^4.8.36 || ^7.5.13"
+ "phpunit/phpunit": "^8.5.13"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.10-dev"
+ }
+ },
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
@@ -1766,18 +2045,24 @@
"check",
"validate"
],
- "time": "2020-02-14T12:15:55+00:00"
+ "support": {
+ "issues": "https://github.com/webmozarts/assert/issues",
+ "source": "https://github.com/webmozarts/assert/tree/1.11.0"
+ },
+ "time": "2022-06-03T18:03:27+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
- "stability-flags": [],
+ "stability-flags": {
+ "phpgt/cipher": 20
+ },
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": ">=7.4",
- "ext-openssl": "*",
- "ext-json": "*"
+ "php": ">=8.1",
+ "ext-openssl": "*"
},
- "platform-dev": []
+ "platform-dev": [],
+ "plugin-api-version": "2.2.0"
}
diff --git a/src/Authenticator.php b/src/Authenticator.php
index ab1f471..48c9158 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -1,11 +1,11 @@
session = $this->session ?? new GlobalSessionContainer();
- if(!$session->contains(self::SESSION_KEY)) {
+ if(!$this->session->contains(self::SESSION_KEY)) {
// TODO: If there is no Token or UserData in the SessionData, do we even
// need to store it to the current session at all?
- $session->set(self::SESSION_KEY, new SessionData());
+ $this->session->set(self::SESSION_KEY, new SessionData());
}
/** @var SessionData $sessionData*/
- $sessionData = $session->get(self::SESSION_KEY);
+ $sessionData = $this->session->get(self::SESSION_KEY);
- $this->clientKey = $clientKey;
- $this->currentUriPath = $currentUriPath;
- $this->authwaveHost = $authwaveHost;
- $this->session = $session;
$this->sessionData = $sessionData;
$this->redirectHandler = $redirectHandler ?? new RedirectHandler();
@@ -53,16 +42,14 @@ public function __construct(
}
public function isLoggedIn():bool {
- $userData = null;
-
try {
- $userData = $this->sessionData->getData();
+ $this->sessionData->getData();
}
catch(NotLoggedInException $exception) {
return false;
}
- return isset($userData);
+ return true;
}
public function login(Token $token = null):void {
@@ -91,9 +78,9 @@ public function logout(Token $token = null):void {
$this->redirectHandler->redirect($this->getLogoutUri($token));
}
- public function getUuid():string {
+ public function getId():string {
$userData = $this->sessionData->getData();
- return $userData->getUuid();
+ return $userData->getId();
}
public function getEmail():string {
@@ -106,16 +93,16 @@ public function getField(string $name):?string {
return $userData->getField($name);
}
- public function getLoginUri(Token $token):AbstractProviderUri {
- return new LoginUri(
+ public function getLoginUri(Token $token):BaseProviderUri {
+ return new LoginUriBase(
$token,
$this->currentUriPath,
$this->authwaveHost
);
}
- private function getLogoutUri(Token $token):AbstractProviderUri {
- return new LogoutUri(
+ private function getLogoutUri(Token $token):BaseProviderUri {
+ return new LogoutUriBase(
$token,
$this->currentUriPath,
$this->authwaveHost
@@ -123,7 +110,7 @@ private function getLogoutUri(Token $token):AbstractProviderUri {
}
public function getAdminUri():UriInterface {
- return new AdminUri($this->authwaveHost);
+ return new AdminUriBase($this->authwaveHost);
}
public function getProfileUri(Token $token = null):UriInterface {
@@ -131,23 +118,24 @@ public function getProfileUri(Token $token = null):UriInterface {
$token = new Token($this->clientKey);
}
- return new ProfileUri(
+ return new ProfileUriBase(
$token,
- $this->getUuid(),
+ $this->getId(),
$this->currentUriPath,
$this->authwaveHost
);
}
private function completeAuth():void {
- $responseCipher = $this->getResponseCipher();
+ return;
+ $queryData = $this->getQueryData();
- if(!$responseCipher) {
+ if(!$queryData) {
return;
}
$token = $this->sessionData->getToken();
- $userData = $token->decryptResponseCipher($responseCipher);
+ $userData = $token->decode($queryData);
$this->session->set(
self::SESSION_KEY,
new SessionData($token, $userData)
@@ -159,7 +147,7 @@ private function completeAuth():void {
);
}
- private function getResponseCipher():?string {
+ private function getQueryData():?string {
$queryString = parse_url(
$this->currentUriPath,
PHP_URL_QUERY
@@ -176,4 +164,4 @@ private function getResponseCipher():?string {
return $queryParts[self::RESPONSE_QUERY_PARAMETER];
}
-}
\ No newline at end of file
+}
diff --git a/src/InitVector.php b/src/InitVector.php
deleted file mode 100644
index 7978666..0000000
--- a/src/InitVector.php
+++ /dev/null
@@ -1,18 +0,0 @@
-bytes = random_bytes($length);
- }
-
- public function getBytes():string {
- return $this->bytes;
- }
-
- public function __toString():string {
- return bin2hex($this->bytes);
- }
-}
\ No newline at end of file
diff --git a/src/ProviderUri/AdminUri.php b/src/ProviderUri/AdminUriBase.php
similarity index 82%
rename from src/ProviderUri/AdminUri.php
rename to src/ProviderUri/AdminUriBase.php
index f8b1ae3..3c932b6 100644
--- a/src/ProviderUri/AdminUri.php
+++ b/src/ProviderUri/AdminUriBase.php
@@ -1,7 +1,7 @@
path = "/admin";
}
-}
\ No newline at end of file
+}
diff --git a/src/ProviderUri/AbstractProviderUri.php b/src/ProviderUri/BaseProviderUri.php
similarity index 86%
rename from src/ProviderUri/AbstractProviderUri.php
rename to src/ProviderUri/BaseProviderUri.php
index bdd63f4..404daf3 100644
--- a/src/ProviderUri/AbstractProviderUri.php
+++ b/src/ProviderUri/BaseProviderUri.php
@@ -5,7 +5,7 @@
use Authwave\Token;
use Gt\Http\Uri;
-abstract class AbstractProviderUri extends Uri {
+abstract class BaseProviderUri extends Uri {
const DEFAULT_BASE_REMOTE_URI = "login.authwave.com";
const QUERY_STRING_CIPHER = "c";
const QUERY_STRING_INIT_VECTOR = "i";
@@ -35,12 +35,12 @@ protected function normaliseBaseUri(string $baseUri):Uri {
protected function buildQuery(
Token $token,
string $currentPath,
- string $message = null
+ string $message = ""
):string {
return http_build_query([
- self::QUERY_STRING_CIPHER => (string)$token->generateRequestCipher($message),
+ self::QUERY_STRING_CIPHER => $token->generateRequestCipher($message),
self::QUERY_STRING_INIT_VECTOR => (string)$token->getIv(),
self::QUERY_STRING_CURRENT_PATH => bin2hex($currentPath),
]);
}
-}
\ No newline at end of file
+}
diff --git a/src/ProviderUri/LoginUri.php b/src/ProviderUri/LoginUriBase.php
similarity index 95%
rename from src/ProviderUri/LoginUri.php
rename to src/ProviderUri/LoginUriBase.php
index a24a6ba..a36fdbe 100644
--- a/src/ProviderUri/LoginUri.php
+++ b/src/ProviderUri/LoginUriBase.php
@@ -10,7 +10,7 @@
* pass the secret IV to the provider, encrypted with the API key. The secret
* IV is only ever stored in the client's session, and is unique to the session.
*/
-class LoginUri extends AbstractProviderUri {
+class LoginUriBase extends BaseProviderUri {
/**
* @param Token $token This must be the same instance of the Token when
* creating Authenticator for the first time as it is when checking the
@@ -29,4 +29,4 @@ public function __construct(
parent::__construct($baseRemoteUri);
$this->query = $this->buildQuery($token, $currentPath);
}
-}
\ No newline at end of file
+}
diff --git a/src/ProviderUri/LogoutUri.php b/src/ProviderUri/LogoutUriBase.php
similarity index 84%
rename from src/ProviderUri/LogoutUri.php
rename to src/ProviderUri/LogoutUriBase.php
index c2ed192..f6c440c 100644
--- a/src/ProviderUri/LogoutUri.php
+++ b/src/ProviderUri/LogoutUriBase.php
@@ -3,7 +3,7 @@
use Authwave\Token;
-class LogoutUri extends AbstractProviderUri {
+class LogoutUriBase extends BaseProviderUri {
public function __construct(
Token $token,
string $currentPath = "/",
@@ -15,7 +15,7 @@ public function __construct(
$this->query = $this->buildQuery(
$token,
$currentPath,
- "action=logout"
+ "action=logout",
);
}
-}
\ No newline at end of file
+}
diff --git a/src/ProviderUri/ProfileUri.php b/src/ProviderUri/ProfileUriBase.php
similarity index 87%
rename from src/ProviderUri/ProfileUri.php
rename to src/ProviderUri/ProfileUriBase.php
index 6ca73f7..8b217b9 100644
--- a/src/ProviderUri/ProfileUri.php
+++ b/src/ProviderUri/ProfileUriBase.php
@@ -3,7 +3,7 @@
use Authwave\Token;
-class ProfileUri extends AbstractProviderUri {
+class ProfileUriBase extends BaseProviderUri {
public function __construct(
Token $token,
string $uuid,
@@ -15,4 +15,4 @@ public function __construct(
$this->path = "/profile";
$this->query = $this->buildQuery($token, $uuid);
}
-}
\ No newline at end of file
+}
diff --git a/src/ResponseData/UserData.php b/src/ResponseData/UserData.php
index 01ebd49..2ea4e77 100644
--- a/src/ResponseData/UserData.php
+++ b/src/ResponseData/UserData.php
@@ -19,7 +19,7 @@ public function __construct(
parent::__construct($message);
}
- public function getUuid():string {
+ public function getId():string {
return $this->uuid;
}
@@ -30,4 +30,4 @@ public function getEmail():string {
public function getField(string $name):?string {
return $this->fields->{$name} ?? null;
}
-}
\ No newline at end of file
+}
diff --git a/src/Token.php b/src/Token.php
index 223008a..6307a29 100644
--- a/src/Token.php
+++ b/src/Token.php
@@ -3,22 +3,25 @@
use Authwave\ResponseData\AbstractResponseData;
use Authwave\ResponseData\UserData;
+use Gt\Cipher\CipherText;
+use Gt\Cipher\InitVector;
+use Gt\Cipher\Key;
+use Gt\Cipher\Message\EncryptedMessage;
+use Gt\Cipher\Message\PlainTextMessage;
use StdClass;
class Token {
- const ENCRYPTION_METHOD = "aes128";
-
- private string $key;
+ private Key $key;
private InitVector $secretIv;
private InitVector $iv;
public function __construct(
- string $key,
- InitVector $secretIv = null,
- InitVector $iv = null
+ string $keyString,
+ InitVector $sessionIv = null,
+ InitVector $iv = null,
) {
- $this->key = $key;
- $this->secretIv = $secretIv ?? new InitVector();
+ $this->key = new Key($keyString);
+ $this->secretIv = $sessionIv ?? new InitVector();
$this->iv = $iv ?? new InitVector();
}
@@ -34,35 +37,21 @@ public function getIv():InitVector {
* response cipher, which will be sent back to the client application in the
* querystring.
*/
- public function generateRequestCipher(string $message = null):string {
- $data = $this->secretIv;
- if($message) {
- $data .= "|" . $message;
- }
-
- $rawCipher = openssl_encrypt(
- $data,
- self::ENCRYPTION_METHOD,
- $this->key,
- 0,
- $this->iv->getBytes()
- );
-
- return base64_encode($rawCipher);
+ public function generateRequestCipher(string $message = ""):CipherText {
+ $plainTextMessage = new PlainTextMessage($message, $this->getIv());
+ return $plainTextMessage->encrypt($this->key);
}
// The response cipher is send from the remote provider back to the client
// application after a successful authentication and includes a serialised
// UserData object, encrypted using the secret IV, which was created when
// encrypting the original request cipher.
- public function decryptResponseCipher(string $cipher):AbstractResponseData {
- $decrypted = openssl_decrypt(
- base64_decode($cipher),
- self::ENCRYPTION_METHOD,
- $this->key,
- 0,
- $this->secretIv->getBytes()
+ public function decode(string $base64cipher):AbstractResponseData {
+ $encryptedMessage = new EncryptedMessage(
+ $base64cipher,
+ $this->iv,
);
+ $decrypted = $encryptedMessage->decrypt($this->key);
if(!$decrypted) {
throw new ResponseCipherDecryptionException();
@@ -81,4 +70,4 @@ public function decryptResponseCipher(string $cipher):AbstractResponseData {
$data->{"fields"} ?? new StdClass()
);
}
-}
\ No newline at end of file
+}
diff --git a/test/phpunit/AuthenticatorTest.php b/test/phpunit/AuthenticatorTest.php
index 5fba507..07678a2 100644
--- a/test/phpunit/AuthenticatorTest.php
+++ b/test/phpunit/AuthenticatorTest.php
@@ -2,17 +2,16 @@
namespace Authwave\Test;
use Authwave\Authenticator;
-use Authwave\InitVector;
use Authwave\NotLoggedInException;
-use Authwave\ProviderUri\AdminUri;
-use Authwave\ProviderUri\LoginUri;
-use Authwave\ProviderUri\LogoutUri;
+use Authwave\ProviderUri\BaseProviderUri;
+use Authwave\ProviderUri\LoginUriBase;
use Authwave\RedirectHandler;
use Authwave\ResponseData\AbstractResponseData;
use Authwave\SessionData;
use Authwave\SessionNotStartedException;
use Authwave\Token;
use Authwave\ResponseData\UserData;
+use Gt\Http\Uri;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\UriInterface;
@@ -53,6 +52,7 @@ public function testIsLoggedInTrueWhenSessionDataSet() {
->method("getData")
->willReturn($userData);
+ /** @noinspection PhpArrayWriteIsNotUsedInspection */
$_SESSION = [
Authenticator::SESSION_KEY => $sessionData
];
@@ -64,111 +64,6 @@ public function testIsLoggedInTrueWhenSessionDataSet() {
self::assertTrue($sut->isLoggedIn());
}
- public function testLogoutCallsLogoutUri() {
- $sessionData = self::createMock(SessionData::class);
- $_SESSION = [
- Authenticator::SESSION_KEY => $sessionData
- ];
-
- $redirectHandler = self::createMock(RedirectHandler::class);
- $redirectHandler->expects(self::once())
- ->method("redirect")
- ->with(self::callback(fn(UriInterface $uri) =>
- $uri->getHost() === "login.authwave.com"
- && $uri->getPath() === "/logout"
- ));
-
- $sut = new Authenticator(
- "test-key",
- "/",
- LoginUri::DEFAULT_BASE_REMOTE_URI,
- null,
- $redirectHandler
- );
- $sut->logout();
- self::assertNotEmpty($_SESSION);
- }
-
- public function testCompleteAuthFromLogoutClearsSession() {
- $token = self::createMock(Token::class);
-
- $sessionData = self::createMock(SessionData::class);
- $sessionData->method("getToken")
- ->willReturn($token);
-
- $_SESSION = [
- Authenticator::SESSION_KEY => $sessionData,
- ];
-
- $responseCipher = "abcdef";
-
- $currentUri = "/example-page-" . uniqid();
- $currentUri .= "?";
- $currentUri .= http_build_query([
- Authenticator::RESPONSE_QUERY_PARAMETER => $responseCipher,
- ]);
-
- $redirectHandler = self::createMock(RedirectHandler::class);
- $redirectHandler->expects(self::once())
- ->method("redirect")
- ->with(self::callback(fn(UriInterface $uri) =>
- $uri->getHost() == ""
- && $uri->getPath() == $currentUri
- ));
-
- new Authenticator(
- "test-key",
- "/",
- LoginUri::DEFAULT_BASE_REMOTE_URI,
- null,
- $redirectHandler
- );
-
- self::assertEmpty($_SESSION);
- }
-
- public function testLoginRedirects() {
- $_SESSION = [];
-
- $redirectHandler = self::createMock(RedirectHandler::class);
- $redirectHandler->expects(self::once())
- ->method("redirect")
- ->with(self::callback(fn(UriInterface $uri) =>
- $uri->getHost() === LoginUri::DEFAULT_BASE_REMOTE_URI
- ));
-
- $sut = new Authenticator(
- "test-key",
- "/",
- LoginUri::DEFAULT_BASE_REMOTE_URI,
- null,
- $redirectHandler
- );
- $sut->login();
- }
-
- public function testLoginRedirectsLocalhost() {
- $_SESSION = [];
-
- $redirectHandler = self::createMock(RedirectHandler::class);
- $redirectHandler->expects(self::once())
- ->method("redirect")
- ->with(self::callback(fn(UriInterface $uri) =>
- $uri->getScheme() === "http"
- && $uri->getHost() === "localhost"
- && $uri->getPort() === 8081
- ));
-
- $sut = new Authenticator(
- "test-key",
- "/",
- "http://localhost:8081",
- null,
- $redirectHandler
- );
- $sut->login();
- }
-
public function testLoginRedirectsWithCorrectQueryString() {
$_SESSION = [];
@@ -189,9 +84,9 @@ public function testLoginRedirectsWithCorrectQueryString() {
->willReturn($iv);
$expectedQueryParts = [
- LoginUri::QUERY_STRING_CIPHER => $cipher,
- LoginUri::QUERY_STRING_INIT_VECTOR => $ivString,
- LoginUri::QUERY_STRING_CURRENT_PATH => bin2hex($currentPath),
+ LoginUriBase::QUERY_STRING_CIPHER => $cipher,
+ LoginUriBase::QUERY_STRING_INIT_VECTOR => $ivString,
+ LoginUriBase::QUERY_STRING_CURRENT_PATH => bin2hex($currentPath),
];
$expectedQuery = http_build_query($expectedQueryParts);
@@ -205,50 +100,19 @@ public function testLoginRedirectsWithCorrectQueryString() {
$sut = new Authenticator(
$key,
$currentPath,
- LoginUri::DEFAULT_BASE_REMOTE_URI,
+ LoginUriBase::DEFAULT_BASE_REMOTE_URI,
null,
$redirectHandler
);
$sut->login($token);
}
- public function testLoginDoesNothingWhenAlreadyLoggedIn() {
- $sessionData = self::createMock(SessionData::class);
- $_SESSION = [
- Authenticator::SESSION_KEY => $sessionData,
- ];
-
- $redirectHandler = self::createMock(RedirectHandler::class);
- $redirectHandler->expects(self::never())
- ->method("redirect");
-
- $sut = new Authenticator(
- "test-key",
- "/",
- LoginUri::DEFAULT_BASE_REMOTE_URI,
- null,
- $redirectHandler
- );
-
- $sut->login();
- }
-
- public function testGetUuidThrowsExceptionWhenNotLoggedIn() {
- $_SESSION = [];
- $sut = new Authenticator(
- "test-key",
- "/"
- );
- self::expectException(NotLoggedInException::class);
- $sut->getUuid();
- }
-
public function testGetUuid() {
- $expectedUuid = uniqid("example-uuid-");
+ $exampleId = uniqid("example-id-");
$userData = self::createMock(UserData::class);
- $userData->method("getUuid")
- ->willReturn($expectedUuid);
+ $userData->method("getId")
+ ->willReturn($exampleId);
$sessionData = self::createMock(SessionData::class);
$sessionData->method("getData")
->willReturn($userData);
@@ -260,7 +124,7 @@ public function testGetUuid() {
"test-key",
"/"
);
- self::assertEquals($expectedUuid, $sut->getUuid());
+ self::assertEquals($exampleId, $sut->getId());
}
public function testGetEmailThrowsExceptionWhenNotLoggedIn() {
@@ -293,6 +157,35 @@ public function testGetEmail() {
self::assertEquals($expectedEmail, $sut->getEmail());
}
+ public function testCompleteAuthNotAffectedByQueryString() {
+ $redirectHandler = self::createMock(RedirectHandler::class);
+ $redirectHandler->expects(self::never())
+ ->method("redirect");
+ $_SESSION = [];
+
+ new Authenticator(
+ "test-key",
+ "/example-path/?filter=something",
+ LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ null,
+ $redirectHandler
+ );
+ }
+
+ public function testGetAdminUri() {
+ $_SESSION = [];
+ $auth = new Authenticator(
+ "test-key",
+ "/example-path",
+ BaseProviderUri::DEFAULT_BASE_REMOTE_URI
+ );
+ $sut = $auth->getAdminUri();
+ self::assertEquals(
+ "/admin",
+ $sut->getPath()
+ );
+ }
+
public function testCompleteAuthNotLoggedIn() {
$currentUri = "/?"
. Authenticator::RESPONSE_QUERY_PARAMETER
@@ -335,7 +228,7 @@ public function testCompleteAuth() {
new Authenticator(
"test-key",
$currentUri,
- LoginUri::DEFAULT_BASE_REMOTE_URI,
+ LoginUriBase::DEFAULT_BASE_REMOTE_URI,
null,
$redirectHandler
);
@@ -353,32 +246,149 @@ public function testCompleteAuth() {
);
}
- public function testCompleteAuthNotAffectedByQueryString() {
+ public function testLoginDoesNothingWhenAlreadyLoggedIn() {
+ $sessionData = self::createMock(SessionData::class);
+ $_SESSION = [
+ Authenticator::SESSION_KEY => $sessionData,
+ ];
+
$redirectHandler = self::createMock(RedirectHandler::class);
$redirectHandler->expects(self::never())
->method("redirect");
+
+ $sut = new Authenticator(
+ "test-key",
+ "/",
+ LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ null,
+ $redirectHandler
+ );
+
+ $sut->login();
+ }
+
+ public function testGetUuidThrowsExceptionWhenNotLoggedIn() {
$_SESSION = [];
+ $sut = new Authenticator(
+ "test-key",
+ "/"
+ );
+ self::expectException(NotLoggedInException::class);
+ $sut->getId();
+ }
+
+ public function testLogoutCallsLogoutUri() {
+ $sessionData = self::createMock(SessionData::class);
+ $_SESSION = [
+ Authenticator::SESSION_KEY => $sessionData
+ ];
+
+ $redirectHandler = self::createMock(RedirectHandler::class);
+ $redirectHandler->expects(self::once())
+ ->method("redirect")
+ ->with(self::callback(function(UriInterface $uri):bool {
+ if($uri->getHost() !== "login.authwave.com") {
+ return false;
+ }
+
+ parse_str($uri->getQuery(), $queryParts);
+ /** @var SessionData $session */
+ $session = $_SESSION[Authenticator::SESSION_KEY];
+ $token = $session->getToken();
+ $decrypted = $token->decode(
+ $queryParts[BaseProviderUri::QUERY_STRING_CIPHER]
+ );
+ var_dump($decrypted);die();
+ }));
+
+ $sut = new Authenticator(
+ "test-key",
+ "/",
+ LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ null,
+ $redirectHandler
+ );
+ $sut->logout();
+ self::assertNotEmpty($_SESSION);
+ }
+
+ public function testCompleteAuthFromLogoutClearsSession() {
+ $token = self::createMock(Token::class);
+
+ $sessionData = self::createMock(SessionData::class);
+ $sessionData->method("getToken")
+ ->willReturn($token);
+
+ $_SESSION = [
+ Authenticator::SESSION_KEY => $sessionData,
+ ];
+
+ $responseCipher = "abcdef";
+
+ $currentUri = "/example-page-" . uniqid();
+ $currentUri .= "?";
+ $currentUri .= http_build_query([
+ Authenticator::RESPONSE_QUERY_PARAMETER => $responseCipher,
+ ]);
+
+ $redirectHandler = self::createMock(RedirectHandler::class);
+ $redirectHandler->expects(self::once())
+ ->method("redirect")
+ ->with(self::callback(fn(UriInterface $uri) =>
+ $uri->getHost() == ""
+ && $uri->getPath() == $currentUri
+ ));
new Authenticator(
"test-key",
- "/example-path?filter=something",
- LoginUri::DEFAULT_BASE_REMOTE_URI,
+ "/",
+ LoginUriBase::DEFAULT_BASE_REMOTE_URI,
null,
$redirectHandler
);
+
+ self::assertEmpty($_SESSION);
}
- public function testGetAdminUri() {
+ public function testLoginRedirects() {
$_SESSION = [];
- $auth = new Authenticator(
+
+ $redirectHandler = self::createMock(RedirectHandler::class);
+ $redirectHandler->expects(self::once())
+ ->method("redirect")
+ ->with(self::callback(fn(UriInterface $uri) =>
+ $uri->getHost() === LoginUriBase::DEFAULT_BASE_REMOTE_URI
+ ));
+
+ $sut = new Authenticator(
"test-key",
- "/example-path",
- LoginUri::DEFAULT_BASE_REMOTE_URI
+ "/",
+ LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ null,
+ $redirectHandler
);
- $sut = $auth->getAdminUri();
- self::assertEquals(
- "/admin",
- $sut->getPath()
+ $sut->login();
+ }
+
+ public function testLoginRedirectsLocalhost() {
+ $_SESSION = [];
+
+ $redirectHandler = self::createMock(RedirectHandler::class);
+ $redirectHandler->expects(self::once())
+ ->method("redirect")
+ ->with(self::callback(fn(UriInterface $uri) =>
+ $uri->getScheme() === "http"
+ && $uri->getHost() === "localhost"
+ && $uri->getPort() === 8081
+ ));
+
+ $sut = new Authenticator(
+ "test-key",
+ "/",
+ "http://localhost:8081",
+ null,
+ $redirectHandler
);
+ $sut->login();
}
-}
\ No newline at end of file
+}
diff --git a/test/phpunit/MalformedReponseDataException.php b/test/phpunit/MalformedReponseDataException.php
deleted file mode 100644
index a8660bb..0000000
--- a/test/phpunit/MalformedReponseDataException.php
+++ /dev/null
@@ -1,6 +0,0 @@
-willReturn("https://example.com");
$token = self::createMock(Token::class);
- $sut = new LoginUri(
+ $sut = new LoginUriBase(
$token,
"",
$baseUri
@@ -35,7 +35,7 @@ public function testAuthUriWithNonStandardPort() {
->willReturn("http://localhost:8081");
$token = self::createMock(Token::class);
- $sut = new LoginUri(
+ $sut = new LoginUriBase(
$token,
"",
$baseUri
@@ -54,7 +54,7 @@ public function testAuthUriWithNonStandardPort() {
// But it should still default to HTTPS on localhost.
public function testGetAuthUriHostnameLocalhostHttpsByDefault() {
$token = self::createMock(Token::class);
- $sut = new LoginUri(
+ $sut = new LoginUriBase(
$token,
"/",
"localhost"
@@ -69,7 +69,7 @@ public function testGetAuthUriHostnameLocalhostHttpsByDefault() {
// We should be able to set the scheme to HTTP for localhost hostname only.
public function testGetAuthUriHostnameLocalhostHttpAllowed() {
$token = self::createMock(Token::class);
- $sut = new LoginUri(
+ $sut = new LoginUriBase(
$token,
"/",
"http://localhost"
@@ -84,7 +84,7 @@ public function testGetAuthUriHostnameLocalhostHttpAllowed() {
public function testGetAuthUriHostnameNotLocalhostHttpNotAllowed() {
$token = self::createMock(Token::class);
self::expectException(InsecureProtocolException::class);
- new LoginUri(
+ new LoginUriBase(
$token,
"/",
"http://localhost.com"
@@ -98,7 +98,7 @@ public function testAuthUriHttpsInferred() {
// Note on the line above, no scheme is passed in - we must assume https.
$token = self::createMock(Token::class);
- $sut = new LoginUri(
+ $sut = new LoginUriBase(
$token,
"/",
$baseUri);
@@ -108,4 +108,4 @@ public function testAuthUriHttpsInferred() {
$sut->getScheme()
);
}
-}
\ No newline at end of file
+}
diff --git a/test/phpunit/ProviderUri/AdminUriTest.php b/test/phpunit/ProviderUri/AdminUriTest.php
index e2e5db7..fed1311 100644
--- a/test/phpunit/ProviderUri/AdminUriTest.php
+++ b/test/phpunit/ProviderUri/AdminUriTest.php
@@ -1,15 +1,15 @@
getPath()
);
}
-}
\ No newline at end of file
+}
diff --git a/test/phpunit/ProviderUri/LoginUriTest.php b/test/phpunit/ProviderUri/LoginUriTest.php
index 794c754..c97f22d 100644
--- a/test/phpunit/ProviderUri/LoginUriTest.php
+++ b/test/phpunit/ProviderUri/LoginUriTest.php
@@ -2,7 +2,7 @@
namespace Authwave\Test\ProviderUri;
use Authwave\InitVector;
-use Authwave\ProviderUri\LoginUri;
+use Authwave\ProviderUri\LoginUriBase;
use Authwave\Token;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\UriInterface;
@@ -23,7 +23,7 @@ public function testQueryString() {
->willReturn($iv);
$returnPath = "/examplePage";
- $sut = new LoginUri(
+ $sut = new LoginUriBase(
$token,
$returnPath,
$baseUri
@@ -32,17 +32,17 @@ public function testQueryString() {
self::assertEquals(
$mockCipherValue,
- $queryParts[LoginUri::QUERY_STRING_CIPHER],
+ $queryParts[LoginUriBase::QUERY_STRING_CIPHER],
);
self::assertEquals(
$mockIvValue,
- $queryParts[LoginUri::QUERY_STRING_INIT_VECTOR]
+ $queryParts[LoginUriBase::QUERY_STRING_INIT_VECTOR]
);
self::assertEquals(
bin2hex($returnPath),
- $queryParts[LoginUri::QUERY_STRING_CURRENT_PATH]
+ $queryParts[LoginUriBase::QUERY_STRING_CURRENT_PATH]
);
}
-}
\ No newline at end of file
+}
diff --git a/test/phpunit/TokenTest.php b/test/phpunit/TokenTest.php
index d001a7b..b178bd5 100644
--- a/test/phpunit/TokenTest.php
+++ b/test/phpunit/TokenTest.php
@@ -1,67 +1,69 @@
generateRequestCipher();
$cipher2 = $token->generateRequestCipher();
- self::assertSame($cipher1, $cipher2);
+ self::assertEquals($cipher1, $cipher2);
}
- public function testGenerateRequestCipherDifferentForDifferentTokenSameDetails() {
- $key = "test-key";
+ public function testGenerateRequestCipher_differentForDifferentTokenSameDetails():void {
+ $key = str_repeat("0", 32);
$token1 = new Token($key);
$token2 = new Token($key);
$cipher1 = $token1->generateRequestCipher();
$cipher2 = $token2->generateRequestCipher();
- self::assertNotSame($cipher1, $cipher2);
+ self::assertNotEquals($cipher1, $cipher2);
}
- public function testGetIv() {
+ public function testGetIv():void {
$iv = self::createMock(InitVector::class);
$sut = new Token("", null, $iv);
self::assertSame($iv, $sut->getIv());
}
- public function testDecryptResponseCipherInvalid() {
- $cipher = "0123456789abcdef";
- $sut = new Token("test-key");
- self::expectException(ResponseCipherDecryptionException::class);
- $sut->decryptResponseCipher($cipher);
+ public function testDecrypt_responseCipherInvalid() {
+ $key = str_repeat("0", 32);
+ $sut = new Token($key);
+ self::expectException(DecryptionFailureException::class);
+ $sut->decode("not a real cipher");
}
public function testDecryptResponseCipherBadJson() {
- $key = uniqid("test-key-");
- $secretIv = self::createMock(InitVector::class);
- $secretIv->method("getBytes")
- ->willReturn(str_repeat("0", 16));
+ $keyString = str_repeat("0", SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
+ $sessionIv = self::createMock(InitVector::class);
+ $sessionIv->method("getBytes")
+ ->willReturn(str_repeat("a", SODIUM_CRYPTO_SECRETBOX_NONCEBYTES));
$iv = self::createMock(InitVector::class);
$iv->method("getBytes")
- ->willReturn(str_repeat("f", 16));
- $cipher = openssl_encrypt(
+ ->willReturn(str_repeat("f", SODIUM_CRYPTO_SECRETBOX_NONCEBYTES));
+
+ $nonce = $iv->getBytes();
+ $manualCipherString = sodium_crypto_secretbox(
"{badly-formed: json]",
- Token::ENCRYPTION_METHOD,
- implode("|", [$key, $secretIv->getBytes()]),
- 0,
- $iv->getBytes()
+ $nonce,
+ $keyString,
);
- $cipher = base64_encode($cipher);
- $sut = new Token($key, $secretIv, $iv);
+ $decryptedCipherString = sodium_crypto_secretbox_open($manualCipherString, $nonce, $keyString);
+
+ $base64Cipher = base64_encode($manualCipherString);
+ $sut = new Token($keyString, $sessionIv, $iv);
self::expectException(InvalidUserDataSerializationException::class);
- $sut->decryptResponseCipher($cipher);
+ $sut->decode($base64Cipher);
}
public function testDecryptResponseCipher() {
@@ -93,9 +95,9 @@ public function testDecryptResponseCipher() {
);
$cipher = base64_encode($cipher);
$sut = new Token($clientKey, $secretIv, $iv);
- $userData = $sut->decryptResponseCipher($cipher);
+ $userData = $sut->decode($cipher);
self::assertInstanceOf(UserData::class, $userData);
- self::assertEquals($uuid, $userData->getUuid());
+ self::assertEquals($uuid, $userData->getId());
self::assertEquals($email, $userData->getEmail());
}
-}
\ No newline at end of file
+}
From f63836f9773fbb408645eea3041056fb4fed12ad Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Mon, 25 Jul 2022 17:55:19 +0100
Subject: [PATCH 02/21] build: upgrade to stable cipher
---
composer.json | 2 +-
composer.lock | 45 ++++++++++++++++++++++-----------------------
2 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/composer.json b/composer.json
index 78b30fa..c78e634 100644
--- a/composer.json
+++ b/composer.json
@@ -5,7 +5,7 @@
"require": {
"php": ">=8.1",
"ext-openssl": "*",
- "phpgt/cipher": "dev-master",
+ "phpgt/cipher": "^1.0",
"phpgt/http": "1.*",
"phpgt/session": ">=1.1"
},
diff --git a/composer.lock b/composer.lock
index bf392a9..11f3d54 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,11 +4,11 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "33cc3f246595defd43ac4a235110f89a",
+ "content-hash": "4573800f16257b1e039dd85fe4abe2a9",
"packages": [
{
"name": "phpgt/cipher",
- "version": "dev-master",
+ "version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/PhpGt/Cipher.git",
@@ -29,7 +29,6 @@
"phpstan/phpstan": "v1.8.0",
"phpunit/phpunit": "v9.5.21"
},
- "default-branch": true,
"type": "library",
"autoload": {
"psr-4": {
@@ -48,7 +47,7 @@
"description": "Two-way encryption of messages for secure plain text transmission.",
"support": {
"issues": "https://github.com/PhpGt/Cipher/issues",
- "source": "https://github.com/PhpGt/Cipher/tree/master"
+ "source": "https://github.com/PhpGt/Cipher/tree/v1.0.0"
},
"funding": [
{
@@ -60,27 +59,27 @@
},
{
"name": "phpgt/http",
- "version": "v1.1.4",
+ "version": "v1.1.5",
"source": {
"type": "git",
"url": "https://github.com/PhpGt/Http.git",
- "reference": "80ed7269050bc0f2de2402c5461711dd2418f55f"
+ "reference": "1b93fa9489100d649f29f59226cc52cd7c0812cb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PhpGt/Http/zipball/80ed7269050bc0f2de2402c5461711dd2418f55f",
- "reference": "80ed7269050bc0f2de2402c5461711dd2418f55f",
+ "url": "https://api.github.com/repos/PhpGt/Http/zipball/1b93fa9489100d649f29f59226cc52cd7c0812cb",
+ "reference": "1b93fa9489100d649f29f59226cc52cd7c0812cb",
"shasum": ""
},
"require": {
"php": ">=8.0",
"phpgt/input": "^v1",
"psr/http-message": "^v1.0.1",
- "willdurand/negotiation": "v3.0.*"
+ "willdurand/negotiation": "v3.1.0"
},
"require-dev": {
- "phpstan/phpstan": ">=0.12.64",
- "phpunit/phpunit": "9.*"
+ "phpstan/phpstan": "v1.8.1",
+ "phpunit/phpunit": "v9.5.21"
},
"type": "library",
"autoload": {
@@ -95,7 +94,7 @@
"description": "PSR-7 HTTP message implementation.",
"support": {
"issues": "https://github.com/PhpGt/Http/issues",
- "source": "https://github.com/PhpGt/Http/tree/v1.1.4"
+ "source": "https://github.com/PhpGt/Http/tree/v1.1.5"
},
"funding": [
{
@@ -103,7 +102,7 @@
"type": "github"
}
],
- "time": "2021-06-23T15:45:09+00:00"
+ "time": "2022-07-25T14:31:55+00:00"
},
{
"name": "phpgt/input",
@@ -300,16 +299,16 @@
},
{
"name": "willdurand/negotiation",
- "version": "3.0.0",
+ "version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/willdurand/Negotiation.git",
- "reference": "04e14f38d4edfcc974114a07d2777d90c98f3d9c"
+ "reference": "68e9ea0553ef6e2ee8db5c1d98829f111e623ec2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/04e14f38d4edfcc974114a07d2777d90c98f3d9c",
- "reference": "04e14f38d4edfcc974114a07d2777d90c98f3d9c",
+ "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/68e9ea0553ef6e2ee8db5c1d98829f111e623ec2",
+ "reference": "68e9ea0553ef6e2ee8db5c1d98829f111e623ec2",
"shasum": ""
},
"require": {
@@ -350,9 +349,9 @@
],
"support": {
"issues": "https://github.com/willdurand/Negotiation/issues",
- "source": "https://github.com/willdurand/Negotiation/tree/3.0.0"
+ "source": "https://github.com/willdurand/Negotiation/tree/3.1.0"
},
- "time": "2020-09-25T08:01:41+00:00"
+ "time": "2022-01-30T20:08:53+00:00"
}
],
"packages-dev": [
@@ -2054,15 +2053,15 @@
],
"aliases": [],
"minimum-stability": "stable",
- "stability-flags": {
- "phpgt/cipher": 20
- },
+ "stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=8.1",
"ext-openssl": "*"
},
- "platform-dev": [],
+ "platform-dev": {
+ "ext-sodium": "*"
+ },
"plugin-api-version": "2.2.0"
}
From 1a6cbf38a61cf8ddd32ff7d8e4f9925cd77b6d6b Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Wed, 10 Aug 2022 08:36:37 +0100
Subject: [PATCH 03/21] feature: upgrade for 2022 provider
---
src/Authenticator.php | 112 +++++++++---------
.../{AdminUriBase.php => AdminUri.php} | 4 +-
src/ProviderUri/BaseProviderUri.php | 13 +-
.../{LoginUriBase.php => LoginUri.php} | 10 +-
.../{LogoutUriBase.php => LogoutUri.php} | 2 +-
.../{ProfileUriBase.php => ProfileUri.php} | 4 +-
src/ResponseData/AbstractResponseData.php | 14 ---
src/ResponseData/UserData.php | 33 ------
src/SessionData.php | 17 +--
src/Token.php | 39 +++---
test/phpunit/AuthenticatorTest.php | 36 +++---
.../ProviderUri/AbstractProviderUriTest.php | 14 +--
test/phpunit/ProviderUri/AdminUriTest.php | 4 +-
test/phpunit/ProviderUri/LoginUriTest.php | 10 +-
test/phpunit/SessionDataTest.php | 6 +-
test/phpunit/TokenTest.php | 4 +-
16 files changed, 141 insertions(+), 181 deletions(-)
rename src/ProviderUri/{AdminUriBase.php => AdminUri.php} (73%)
rename src/ProviderUri/{LoginUriBase.php => LoginUri.php} (87%)
rename src/ProviderUri/{LogoutUriBase.php => LogoutUri.php} (89%)
rename src/ProviderUri/{ProfileUriBase.php => ProfileUri.php} (81%)
delete mode 100644 src/ResponseData/AbstractResponseData.php
delete mode 100644 src/ResponseData/UserData.php
diff --git a/src/Authenticator.php b/src/Authenticator.php
index 48c9158..8782c97 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -2,54 +2,53 @@
namespace Authwave;
use Authwave\ProviderUri\BaseProviderUri;
-use Authwave\ProviderUri\AdminUriBase;
-use Authwave\ProviderUri\LoginUriBase;
-use Authwave\ProviderUri\LogoutUriBase;
-use Authwave\ProviderUri\ProfileUriBase;
+use Authwave\ProviderUri\AdminUri;
+use Authwave\ProviderUri\LoginUri;
+use Authwave\ProviderUri\LogoutUri;
+use Authwave\ProviderUri\ProfileUri;
+use Authwave\ResponseData\UserResponseData;
+use Gt\Cipher\Key;
+use Gt\Cipher\Message\EncryptedMessage;
use Gt\Http\Uri;
use Gt\Session\SessionContainer;
use Psr\Http\Message\UriInterface;
class Authenticator {
- const SESSION_KEY = "AUTHWAVE_SESSION";
const RESPONSE_QUERY_PARAMETER = "AUTHWAVE_RESPONSE_DATA";
- const LOGIN_TYPE_DEFAULT = "login-default";
- const LOGIN_TYPE_ADMIN = "login-admin";
private SessionData $sessionData;
+ private User $user;
public function __construct(
private readonly string $clientKey,
- private readonly string $currentUriPath,
+ private readonly Uri $currentUri,
private readonly string $authwaveHost = "login.authwave.com",
private ?SessionContainer $session = null,
- private ?RedirectHandler $redirectHandler = null
+ private ?RedirectHandler $redirectHandler = null,
) {
$this->session = $this->session ?? new GlobalSessionContainer();
-
- if(!$this->session->contains(self::SESSION_KEY)) {
-// TODO: If there is no Token or UserData in the SessionData, do we even
-// need to store it to the current session at all?
- $this->session->set(self::SESSION_KEY, new SessionData());
- }
- /** @var SessionData $sessionData*/
- $sessionData = $this->session->get(self::SESSION_KEY);
-
- $this->sessionData = $sessionData;
$this->redirectHandler = $redirectHandler ?? new RedirectHandler();
+ if($data = $this->session->get(SessionData::class)) {
+ $this->sessionData = $data;
+
+ try {
+ $responseData = $this->sessionData->getData();
+ if($responseData instanceof UserResponseData) {
+ $this->user = new User(
+ $responseData->getId(),
+ $responseData->getEmail(),
+ $responseData->getAllFields(),
+ );
+ }
+ }
+ catch(NotLoggedInException) {}
+ }
$this->completeAuth();
}
public function isLoggedIn():bool {
- try {
- $this->sessionData->getData();
- }
- catch(NotLoggedInException $exception) {
- return false;
- }
-
- return true;
+ return isset($this->user);
}
public function login(Token $token = null):void {
@@ -62,8 +61,7 @@ public function login(Token $token = null):void {
}
$this->sessionData = new SessionData($token);
- $this->session->set(self::SESSION_KEY, $this->sessionData);
-
+ $this->session->set(SessionData::class, $this->sessionData);
$this->redirectHandler->redirect($this->getLoginUri($token));
}
@@ -73,44 +71,36 @@ public function logout(Token $token = null):void {
}
$this->sessionData = new SessionData($token);
- $this->session->set(self::SESSION_KEY, $this->sessionData);
-
+ $this->session->set(SessionData::class, $this->sessionData);
$this->redirectHandler->redirect($this->getLogoutUri($token));
}
- public function getId():string {
- $userData = $this->sessionData->getData();
- return $userData->getId();
- }
-
- public function getEmail():string {
- $userData = $this->sessionData->getData();
- return $userData->getEmail();
- }
+ public function getUser():User {
+ if(!isset($this->user)) {
+ throw new NotLoggedInException();
+ }
- public function getField(string $name):?string {
- $userData = $this->sessionData->getData();
- return $userData->getField($name);
+ return $this->user;
}
public function getLoginUri(Token $token):BaseProviderUri {
- return new LoginUriBase(
+ return new LoginUri(
$token,
- $this->currentUriPath,
+ $this->currentUri,
$this->authwaveHost
);
}
private function getLogoutUri(Token $token):BaseProviderUri {
- return new LogoutUriBase(
+ return new LogoutUri(
$token,
- $this->currentUriPath,
+ $this->currentUri,
$this->authwaveHost
);
}
public function getAdminUri():UriInterface {
- return new AdminUriBase($this->authwaveHost);
+ return new AdminUri($this->authwaveHost);
}
public function getProfileUri(Token $token = null):UriInterface {
@@ -118,38 +108,48 @@ public function getProfileUri(Token $token = null):UriInterface {
$token = new Token($this->clientKey);
}
- return new ProfileUriBase(
+ return new ProfileUri(
$token,
- $this->getId(),
- $this->currentUriPath,
+ $this->user->id,
+ $this->currentUri,
$this->authwaveHost
);
}
private function completeAuth():void {
- return;
$queryData = $this->getQueryData();
if(!$queryData) {
return;
}
+
$token = $this->sessionData->getToken();
- $userData = $token->decode($queryData);
+ $secretSessionIv = $token->getSecretIv();
+ $encrypted = new EncryptedMessage($queryData, $secretSessionIv);
+ $key = new Key($this->clientKey);
+ $decrypt = $encrypted->decrypt($key);
+ parse_str($decrypt, $data);
+ $userData = new UserResponseData(
+ $data["id"],
+ $data["email"],
+ $data["kvp"] ?? [],
+ );
+
$this->session->set(
- self::SESSION_KEY,
+ SessionData::class,
new SessionData($token, $userData)
);
$this->redirectHandler->redirect(
- (new Uri($this->currentUriPath))
+ (new Uri($this->currentUri))
->withoutQueryValue(self::RESPONSE_QUERY_PARAMETER)
);
}
private function getQueryData():?string {
$queryString = parse_url(
- $this->currentUriPath,
+ $this->currentUri,
PHP_URL_QUERY
);
if(!$queryString) {
diff --git a/src/ProviderUri/AdminUriBase.php b/src/ProviderUri/AdminUri.php
similarity index 73%
rename from src/ProviderUri/AdminUriBase.php
rename to src/ProviderUri/AdminUri.php
index 3c932b6..8e0cd6f 100644
--- a/src/ProviderUri/AdminUriBase.php
+++ b/src/ProviderUri/AdminUri.php
@@ -1,12 +1,12 @@
normaliseBaseUri($baseRemoteUri);
parent::__construct($baseRemoteUri);
- $this->path = "/admin";
+ $this->path = "/admin/";
}
}
diff --git a/src/ProviderUri/BaseProviderUri.php b/src/ProviderUri/BaseProviderUri.php
index 404daf3..3f8fcb4 100644
--- a/src/ProviderUri/BaseProviderUri.php
+++ b/src/ProviderUri/BaseProviderUri.php
@@ -7,9 +7,9 @@
abstract class BaseProviderUri extends Uri {
const DEFAULT_BASE_REMOTE_URI = "login.authwave.com";
- const QUERY_STRING_CIPHER = "c";
- const QUERY_STRING_INIT_VECTOR = "i";
- const QUERY_STRING_CURRENT_PATH = "p";
+ const QUERY_STRING_CIPHER = "cipher";
+ const QUERY_STRING_INIT_VECTOR = "iv";
+ const QUERY_STRING_CURRENT_PATH = "path";
protected function normaliseBaseUri(string $baseUri):Uri {
$scheme = parse_url($baseUri, PHP_URL_SCHEME)
@@ -25,7 +25,8 @@ protected function normaliseBaseUri(string $baseUri):Uri {
->withPort($port);
if($uri->getHost() !== "localhost"
- && $uri->getScheme() !== "https") {
+ && $uri->getHost() !== "127.0.0.127"
+ && $uri->getScheme() !== "https") {
throw new InsecureProtocolException($uri->getScheme());
}
@@ -35,10 +36,10 @@ protected function normaliseBaseUri(string $baseUri):Uri {
protected function buildQuery(
Token $token,
string $currentPath,
- string $message = ""
+ string $message = "",
):string {
return http_build_query([
- self::QUERY_STRING_CIPHER => $token->generateRequestCipher($message),
+ self::QUERY_STRING_CIPHER => (string)$token->generateRequestCipher($message),
self::QUERY_STRING_INIT_VECTOR => (string)$token->getIv(),
self::QUERY_STRING_CURRENT_PATH => bin2hex($currentPath),
]);
diff --git a/src/ProviderUri/LoginUriBase.php b/src/ProviderUri/LoginUri.php
similarity index 87%
rename from src/ProviderUri/LoginUriBase.php
rename to src/ProviderUri/LoginUri.php
index a36fdbe..0e6eae5 100644
--- a/src/ProviderUri/LoginUriBase.php
+++ b/src/ProviderUri/LoginUri.php
@@ -10,7 +10,7 @@
* pass the secret IV to the provider, encrypted with the API key. The secret
* IV is only ever stored in the client's session, and is unique to the session.
*/
-class LoginUriBase extends BaseProviderUri {
+class LoginUri extends BaseProviderUri {
/**
* @param Token $token This must be the same instance of the Token when
* creating Authenticator for the first time as it is when checking the
@@ -22,11 +22,15 @@ class LoginUriBase extends BaseProviderUri {
*/
public function __construct(
Token $token,
- string $currentPath = "/",
+ string $currentPath,
string $baseRemoteUri = self::DEFAULT_BASE_REMOTE_URI
) {
$baseRemoteUri = $this->normaliseBaseUri($baseRemoteUri);
parent::__construct($baseRemoteUri);
- $this->query = $this->buildQuery($token, $currentPath);
+ $this->query = $this->buildQuery(
+ $token,
+ $currentPath,
+ "action=login"
+ );
}
}
diff --git a/src/ProviderUri/LogoutUriBase.php b/src/ProviderUri/LogoutUri.php
similarity index 89%
rename from src/ProviderUri/LogoutUriBase.php
rename to src/ProviderUri/LogoutUri.php
index f6c440c..9f7922c 100644
--- a/src/ProviderUri/LogoutUriBase.php
+++ b/src/ProviderUri/LogoutUri.php
@@ -3,7 +3,7 @@
use Authwave\Token;
-class LogoutUriBase extends BaseProviderUri {
+class LogoutUri extends BaseProviderUri {
public function __construct(
Token $token,
string $currentPath = "/",
diff --git a/src/ProviderUri/ProfileUriBase.php b/src/ProviderUri/ProfileUri.php
similarity index 81%
rename from src/ProviderUri/ProfileUriBase.php
rename to src/ProviderUri/ProfileUri.php
index 8b217b9..6e743e9 100644
--- a/src/ProviderUri/ProfileUriBase.php
+++ b/src/ProviderUri/ProfileUri.php
@@ -3,7 +3,7 @@
use Authwave\Token;
-class ProfileUriBase extends BaseProviderUri {
+class ProfileUri extends BaseProviderUri {
public function __construct(
Token $token,
string $uuid,
@@ -12,7 +12,7 @@ public function __construct(
) {
$baseRemoteUri = $this->normaliseBaseUri($baseRemoteUri);
parent::__construct($baseRemoteUri);
- $this->path = "/profile";
+ $this->path = "/profile/";
$this->query = $this->buildQuery($token, $uuid);
}
}
diff --git a/src/ResponseData/AbstractResponseData.php b/src/ResponseData/AbstractResponseData.php
deleted file mode 100644
index a3e4df6..0000000
--- a/src/ResponseData/AbstractResponseData.php
+++ /dev/null
@@ -1,14 +0,0 @@
-message = $message;
- }
-
- public function getMessage():?string {
- return $this->message;
- }
-}
\ No newline at end of file
diff --git a/src/ResponseData/UserData.php b/src/ResponseData/UserData.php
deleted file mode 100644
index 2ea4e77..0000000
--- a/src/ResponseData/UserData.php
+++ /dev/null
@@ -1,33 +0,0 @@
-uuid = $uuid;
- $this->email = $email;
- $this->fields = $fields;
-
- parent::__construct($message);
- }
-
- public function getId():string {
- return $this->uuid;
- }
-
- public function getEmail():string {
- return $this->email;
- }
-
- public function getField(string $name):?string {
- return $this->fields->{$name} ?? null;
- }
-}
diff --git a/src/SessionData.php b/src/SessionData.php
index dee8c41..43ef6ba 100644
--- a/src/SessionData.php
+++ b/src/SessionData.php
@@ -1,19 +1,14 @@
token = $token;
- $this->data = $data;
}
public function getToken():Token {
@@ -24,11 +19,11 @@ public function getToken():Token {
return $this->token;
}
- public function getData():AbstractResponseData {
+ public function getData():BaseResponseData {
if(!isset($this->data)) {
throw new NotLoggedInException();
}
return $this->data;
}
-}
\ No newline at end of file
+}
diff --git a/src/Token.php b/src/Token.php
index 6307a29..7c93fc8 100644
--- a/src/Token.php
+++ b/src/Token.php
@@ -1,18 +1,19 @@
key = new Key($keyString);
- $this->secretIv = $sessionIv ?? new InitVector();
+ $this->secretSessionIv = $sessionIv ?? new InitVector();
$this->iv = $iv ?? new InitVector();
+ Log::debug("Created login information:\n\tsecretSessionIV\t$this->secretSessionIv\n\t\tiv\t$this->iv");
}
public function getIv():InitVector {
return $this->iv;
}
-/**
- * The request cipher is sent to the remote provider in the querystring. It
- * consists of the token's secret IV, encrypted with the client key, along with
- * an optional message. The secret IV is required for two-way encryption. The
- * remote provider will decrypt the secret and use it as the key if encrypting a
- * response cipher, which will be sent back to the client application in the
- * querystring.
- */
+ public function getSecretIv():InitVector {
+ return $this->secretSessionIv;
+ }
+
+ /**
+ * The request cipher is sent to the remote provider in the querystring.
+ * It consists of the token's secret IV, encrypted with the client key,
+ * along with an optional message. The secret IV is required for two-way
+ * encryption. The remote provider will decrypt the secret and use it as
+ * the key if encrypting a response cipher, which will be sent back to
+ * the client application in the querystring.
+ */
public function generateRequestCipher(string $message = ""):CipherText {
- $plainTextMessage = new PlainTextMessage($message, $this->getIv());
+// TODO: $message should probably always be a KVP, so we can build up the querystring message here without concatenating.
+ $plainTextMessage = new PlainTextMessage($message . "&secretIv=" . $this->getSecretIv(), $this->getIv());
return $plainTextMessage->encrypt($this->key);
}
-
// The response cipher is send from the remote provider back to the client
// application after a successful authentication and includes a serialised
// UserData object, encrypted using the secret IV, which was created when
// encrypting the original request cipher.
- public function decode(string $base64cipher):AbstractResponseData {
+
+ public function decode(string $base64cipher):BaseResponseData {
$encryptedMessage = new EncryptedMessage(
$base64cipher,
$this->iv,
@@ -64,7 +71,7 @@ public function decode(string $base64cipher):AbstractResponseData {
throw new InvalidUserDataSerializationException();
}
- return new UserData(
+ return new UserResponseData(
$data->{"uuid"},
$data->{"email"},
$data->{"fields"} ?? new StdClass()
diff --git a/test/phpunit/AuthenticatorTest.php b/test/phpunit/AuthenticatorTest.php
index 07678a2..e89ff73 100644
--- a/test/phpunit/AuthenticatorTest.php
+++ b/test/phpunit/AuthenticatorTest.php
@@ -4,13 +4,13 @@
use Authwave\Authenticator;
use Authwave\NotLoggedInException;
use Authwave\ProviderUri\BaseProviderUri;
-use Authwave\ProviderUri\LoginUriBase;
+use Authwave\ProviderUri\LoginUri;
use Authwave\RedirectHandler;
-use Authwave\ResponseData\AbstractResponseData;
+use Authwave\ResponseData\BaseResponseData;
use Authwave\SessionData;
use Authwave\SessionNotStartedException;
use Authwave\Token;
-use Authwave\ResponseData\UserData;
+use Authwave\ResponseData\UserResponseData;
use Gt\Http\Uri;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\UriInterface;
@@ -46,7 +46,7 @@ public function testIsLoggedInFalseByDefault() {
}
public function testIsLoggedInTrueWhenSessionDataSet() {
- $userData = self::createMock(UserData::class);
+ $userData = self::createMock(UserResponseData::class);
$sessionData = self::createMock(SessionData::class);
$sessionData->expects(self::once())
->method("getData")
@@ -84,9 +84,9 @@ public function testLoginRedirectsWithCorrectQueryString() {
->willReturn($iv);
$expectedQueryParts = [
- LoginUriBase::QUERY_STRING_CIPHER => $cipher,
- LoginUriBase::QUERY_STRING_INIT_VECTOR => $ivString,
- LoginUriBase::QUERY_STRING_CURRENT_PATH => bin2hex($currentPath),
+ LoginUri::QUERY_STRING_CIPHER => $cipher,
+ LoginUri::QUERY_STRING_INIT_VECTOR => $ivString,
+ LoginUri::QUERY_STRING_CURRENT_PATH => bin2hex($currentPath),
];
$expectedQuery = http_build_query($expectedQueryParts);
@@ -100,7 +100,7 @@ public function testLoginRedirectsWithCorrectQueryString() {
$sut = new Authenticator(
$key,
$currentPath,
- LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ LoginUri::DEFAULT_BASE_REMOTE_URI,
null,
$redirectHandler
);
@@ -110,7 +110,7 @@ public function testLoginRedirectsWithCorrectQueryString() {
public function testGetUuid() {
$exampleId = uniqid("example-id-");
- $userData = self::createMock(UserData::class);
+ $userData = self::createMock(UserResponseData::class);
$userData->method("getId")
->willReturn($exampleId);
$sessionData = self::createMock(SessionData::class);
@@ -140,7 +140,7 @@ public function testGetEmailThrowsExceptionWhenNotLoggedIn() {
public function testGetEmail() {
$expectedEmail = "example@example.com";
- $userData = self::createMock(UserData::class);
+ $userData = self::createMock(UserResponseData::class);
$userData->method("getEmail")
->willReturn($expectedEmail);
$sessionData = self::createMock(SessionData::class);
@@ -166,7 +166,7 @@ public function testCompleteAuthNotAffectedByQueryString() {
new Authenticator(
"test-key",
"/example-path/?filter=something",
- LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ LoginUri::DEFAULT_BASE_REMOTE_URI,
null,
$redirectHandler
);
@@ -228,7 +228,7 @@ public function testCompleteAuth() {
new Authenticator(
"test-key",
$currentUri,
- LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ LoginUri::DEFAULT_BASE_REMOTE_URI,
null,
$redirectHandler
);
@@ -241,7 +241,7 @@ public function testCompleteAuth() {
$newSessionData
);
self::assertInstanceOf(
- AbstractResponseData::class,
+ BaseResponseData::class,
$newSessionData->getData()
);
}
@@ -259,7 +259,7 @@ public function testLoginDoesNothingWhenAlreadyLoggedIn() {
$sut = new Authenticator(
"test-key",
"/",
- LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ LoginUri::DEFAULT_BASE_REMOTE_URI,
null,
$redirectHandler
);
@@ -304,7 +304,7 @@ public function testLogoutCallsLogoutUri() {
$sut = new Authenticator(
"test-key",
"/",
- LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ LoginUri::DEFAULT_BASE_REMOTE_URI,
null,
$redirectHandler
);
@@ -342,7 +342,7 @@ public function testCompleteAuthFromLogoutClearsSession() {
new Authenticator(
"test-key",
"/",
- LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ LoginUri::DEFAULT_BASE_REMOTE_URI,
null,
$redirectHandler
);
@@ -357,13 +357,13 @@ public function testLoginRedirects() {
$redirectHandler->expects(self::once())
->method("redirect")
->with(self::callback(fn(UriInterface $uri) =>
- $uri->getHost() === LoginUriBase::DEFAULT_BASE_REMOTE_URI
+ $uri->getHost() === LoginUri::DEFAULT_BASE_REMOTE_URI
));
$sut = new Authenticator(
"test-key",
"/",
- LoginUriBase::DEFAULT_BASE_REMOTE_URI,
+ LoginUri::DEFAULT_BASE_REMOTE_URI,
null,
$redirectHandler
);
diff --git a/test/phpunit/ProviderUri/AbstractProviderUriTest.php b/test/phpunit/ProviderUri/AbstractProviderUriTest.php
index c264fd6..99a39b2 100644
--- a/test/phpunit/ProviderUri/AbstractProviderUriTest.php
+++ b/test/phpunit/ProviderUri/AbstractProviderUriTest.php
@@ -3,7 +3,7 @@
use Authwave\InitVector;
use Authwave\InsecureProtocolException;
-use Authwave\ProviderUri\LoginUriBase;
+use Authwave\ProviderUri\LoginUri;
use Authwave\Token;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\UriInterface;
@@ -15,7 +15,7 @@ public function testAuthUriHttps() {
->willReturn("https://example.com");
$token = self::createMock(Token::class);
- $sut = new LoginUriBase(
+ $sut = new LoginUri(
$token,
"",
$baseUri
@@ -35,7 +35,7 @@ public function testAuthUriWithNonStandardPort() {
->willReturn("http://localhost:8081");
$token = self::createMock(Token::class);
- $sut = new LoginUriBase(
+ $sut = new LoginUri(
$token,
"",
$baseUri
@@ -54,7 +54,7 @@ public function testAuthUriWithNonStandardPort() {
// But it should still default to HTTPS on localhost.
public function testGetAuthUriHostnameLocalhostHttpsByDefault() {
$token = self::createMock(Token::class);
- $sut = new LoginUriBase(
+ $sut = new LoginUri(
$token,
"/",
"localhost"
@@ -69,7 +69,7 @@ public function testGetAuthUriHostnameLocalhostHttpsByDefault() {
// We should be able to set the scheme to HTTP for localhost hostname only.
public function testGetAuthUriHostnameLocalhostHttpAllowed() {
$token = self::createMock(Token::class);
- $sut = new LoginUriBase(
+ $sut = new LoginUri(
$token,
"/",
"http://localhost"
@@ -84,7 +84,7 @@ public function testGetAuthUriHostnameLocalhostHttpAllowed() {
public function testGetAuthUriHostnameNotLocalhostHttpNotAllowed() {
$token = self::createMock(Token::class);
self::expectException(InsecureProtocolException::class);
- new LoginUriBase(
+ new LoginUri(
$token,
"/",
"http://localhost.com"
@@ -98,7 +98,7 @@ public function testAuthUriHttpsInferred() {
// Note on the line above, no scheme is passed in - we must assume https.
$token = self::createMock(Token::class);
- $sut = new LoginUriBase(
+ $sut = new LoginUri(
$token,
"/",
$baseUri);
diff --git a/test/phpunit/ProviderUri/AdminUriTest.php b/test/phpunit/ProviderUri/AdminUriTest.php
index fed1311..3d32da5 100644
--- a/test/phpunit/ProviderUri/AdminUriTest.php
+++ b/test/phpunit/ProviderUri/AdminUriTest.php
@@ -1,12 +1,12 @@
getPath()
diff --git a/test/phpunit/ProviderUri/LoginUriTest.php b/test/phpunit/ProviderUri/LoginUriTest.php
index c97f22d..d7d819a 100644
--- a/test/phpunit/ProviderUri/LoginUriTest.php
+++ b/test/phpunit/ProviderUri/LoginUriTest.php
@@ -2,7 +2,7 @@
namespace Authwave\Test\ProviderUri;
use Authwave\InitVector;
-use Authwave\ProviderUri\LoginUriBase;
+use Authwave\ProviderUri\LoginUri;
use Authwave\Token;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\UriInterface;
@@ -23,7 +23,7 @@ public function testQueryString() {
->willReturn($iv);
$returnPath = "/examplePage";
- $sut = new LoginUriBase(
+ $sut = new LoginUri(
$token,
$returnPath,
$baseUri
@@ -32,17 +32,17 @@ public function testQueryString() {
self::assertEquals(
$mockCipherValue,
- $queryParts[LoginUriBase::QUERY_STRING_CIPHER],
+ $queryParts[LoginUri::QUERY_STRING_CIPHER],
);
self::assertEquals(
$mockIvValue,
- $queryParts[LoginUriBase::QUERY_STRING_INIT_VECTOR]
+ $queryParts[LoginUri::QUERY_STRING_INIT_VECTOR]
);
self::assertEquals(
bin2hex($returnPath),
- $queryParts[LoginUriBase::QUERY_STRING_CURRENT_PATH]
+ $queryParts[LoginUri::QUERY_STRING_CURRENT_PATH]
);
}
}
diff --git a/test/phpunit/SessionDataTest.php b/test/phpunit/SessionDataTest.php
index 8b8d07b..160776c 100644
--- a/test/phpunit/SessionDataTest.php
+++ b/test/phpunit/SessionDataTest.php
@@ -4,7 +4,7 @@
use Authwave\NotLoggedInException;
use Authwave\SessionData;
use Authwave\Token;
-use Authwave\ResponseData\UserData;
+use Authwave\ResponseData\UserResponseData;
use PHPUnit\Framework\TestCase;
class SessionDataTest extends TestCase {
@@ -28,8 +28,8 @@ public function testGetUserDataNull() {
public function testGetUserData() {
$token = self::createMock(Token::class);
- $userData = self::createMock(UserData::class);
+ $userData = self::createMock(UserResponseData::class);
$sut = new SessionData($token, $userData);
self::assertSame($userData, $sut->getData());
}
-}
\ No newline at end of file
+}
diff --git a/test/phpunit/TokenTest.php b/test/phpunit/TokenTest.php
index b178bd5..3e5ddf8 100644
--- a/test/phpunit/TokenTest.php
+++ b/test/phpunit/TokenTest.php
@@ -4,7 +4,7 @@
use Authwave\InvalidUserDataSerializationException;
use Authwave\ResponseCipherDecryptionException;
use Authwave\Token;
-use Authwave\ResponseData\UserData;
+use Authwave\ResponseData\UserResponseData;
use Gt\Cipher\InitVector;
use Gt\Cipher\Key;
use Gt\Cipher\Message\DecryptionFailureException;
@@ -96,7 +96,7 @@ public function testDecryptResponseCipher() {
$cipher = base64_encode($cipher);
$sut = new Token($clientKey, $secretIv, $iv);
$userData = $sut->decode($cipher);
- self::assertInstanceOf(UserData::class, $userData);
+ self::assertInstanceOf(UserResponseData::class, $userData);
self::assertEquals($uuid, $userData->getId());
self::assertEquals($email, $userData->getEmail());
}
From 36842ed9d243e63374be42632c06a8019514394c Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Thu, 11 Aug 2022 13:27:38 +0100
Subject: [PATCH 04/21] feature: response data classes
---
composer.lock | 12 +++++------
src/ResponseData/BaseResponseData.php | 14 +++++++++++++
src/ResponseData/UserResponseData.php | 30 +++++++++++++++++++++++++++
3 files changed, 50 insertions(+), 6 deletions(-)
create mode 100644 src/ResponseData/BaseResponseData.php
create mode 100644 src/ResponseData/UserResponseData.php
diff --git a/composer.lock b/composer.lock
index 11f3d54..16d2673 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1121,16 +1121,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "8.5.27",
+ "version": "8.5.28",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "df70070f2711b8fe8dcca0797c1239ede8c94be6"
+ "reference": "8f2d1c9c7b30382459c871467853da1a6e44fbd4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/df70070f2711b8fe8dcca0797c1239ede8c94be6",
- "reference": "df70070f2711b8fe8dcca0797c1239ede8c94be6",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8f2d1c9c7b30382459c871467853da1a6e44fbd4",
+ "reference": "8f2d1c9c7b30382459c871467853da1a6e44fbd4",
"shasum": ""
},
"require": {
@@ -1199,7 +1199,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.27"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.28"
},
"funding": [
{
@@ -1211,7 +1211,7 @@
"type": "github"
}
],
- "time": "2022-06-19T12:11:16+00:00"
+ "time": "2022-07-29T09:20:50+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
diff --git a/src/ResponseData/BaseResponseData.php b/src/ResponseData/BaseResponseData.php
new file mode 100644
index 0000000..eea9406
--- /dev/null
+++ b/src/ResponseData/BaseResponseData.php
@@ -0,0 +1,14 @@
+message = $message;
+ }
+
+ public function getMessage():?string {
+ return $this->message;
+ }
+}
diff --git a/src/ResponseData/UserResponseData.php b/src/ResponseData/UserResponseData.php
new file mode 100644
index 0000000..abcbc1b
--- /dev/null
+++ b/src/ResponseData/UserResponseData.php
@@ -0,0 +1,30 @@
+uuid;
+ }
+
+ public function getEmail():string {
+ return $this->email;
+ }
+
+ public function getField(string $name):?string {
+ return $this->kvp[$name] ?? null;
+ }
+
+ /** @return array */
+ public function getAllFields():array {
+ return $this->kvp;
+ }
+}
From b0e50336f40919be29ced5ece26ae0abf9c3246e Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Thu, 11 Aug 2022 13:28:20 +0100
Subject: [PATCH 05/21] feature: user class
---
src/User.php | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 src/User.php
diff --git a/src/User.php b/src/User.php
new file mode 100644
index 0000000..1c5784b
--- /dev/null
+++ b/src/User.php
@@ -0,0 +1,14 @@
+kvp[$key] ?? null;
+ }
+}
From 9111729200e303b5970d0850862fa6eeb9a9f08d Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Fri, 12 Aug 2022 10:26:06 +0100
Subject: [PATCH 06/21] test: fix tests
---
src/Authenticator.php | 11 +-
src/Token.php | 5 +-
test/phpunit/AuthenticatorTest.php | 129 ++++++++++------------
test/phpunit/ProviderUri/AdminUriTest.php | 2 +-
test/phpunit/TokenTest.php | 41 +++----
5 files changed, 89 insertions(+), 99 deletions(-)
diff --git a/src/Authenticator.php b/src/Authenticator.php
index 8782c97..704ed91 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -18,10 +18,11 @@ class Authenticator {
private SessionData $sessionData;
private User $user;
+ private Uri $currentUri;
public function __construct(
private readonly string $clientKey,
- private readonly Uri $currentUri,
+ string|Uri $currentUri,
private readonly string $authwaveHost = "login.authwave.com",
private ?SessionContainer $session = null,
private ?RedirectHandler $redirectHandler = null,
@@ -44,6 +45,11 @@ public function __construct(
catch(NotLoggedInException) {}
}
+ if(is_string($currentUri)) {
+ $currentUri = new Uri($currentUri);
+ }
+ $this->currentUri = $currentUri;
+
$this->completeAuth();
}
@@ -123,6 +129,9 @@ private function completeAuth():void {
return;
}
+ if(!isset($this->sessionData)) {
+ return;
+ }
$token = $this->sessionData->getToken();
$secretSessionIv = $token->getSecretIv();
diff --git a/src/Token.php b/src/Token.php
index 7c93fc8..bcee8a8 100644
--- a/src/Token.php
+++ b/src/Token.php
@@ -24,7 +24,6 @@ public function __construct(
$this->key = new Key($keyString);
$this->secretSessionIv = $sessionIv ?? new InitVector();
$this->iv = $iv ?? new InitVector();
- Log::debug("Created login information:\n\tsecretSessionIV\t$this->secretSessionIv\n\t\tiv\t$this->iv");
}
public function getIv():InitVector {
@@ -72,9 +71,9 @@ public function decode(string $base64cipher):BaseResponseData {
}
return new UserResponseData(
- $data->{"uuid"},
+ $data->{"uuid"} ?? $data->{"id"},
$data->{"email"},
- $data->{"fields"} ?? new StdClass()
+ $data->{"fields"} ?? []
);
}
}
diff --git a/test/phpunit/AuthenticatorTest.php b/test/phpunit/AuthenticatorTest.php
index e89ff73..7d6503e 100644
--- a/test/phpunit/AuthenticatorTest.php
+++ b/test/phpunit/AuthenticatorTest.php
@@ -11,6 +11,7 @@
use Authwave\SessionNotStartedException;
use Authwave\Token;
use Authwave\ResponseData\UserResponseData;
+use Gt\Cipher\InitVector;
use Gt\Http\Uri;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\UriInterface;
@@ -24,18 +25,6 @@ public function testConstructWithDefaultSessionNotStarted() {
);
}
- public function testConstructWithDefaultSession() {
- $_SESSION = [];
- new Authenticator(
- "test-key",
- "/"
- );
- self::assertArrayHasKey(
- Authenticator::SESSION_KEY,
- $_SESSION
- );
- }
-
public function testIsLoggedInFalseByDefault() {
$_SESSION = [];
$sut = new Authenticator(
@@ -54,7 +43,7 @@ public function testIsLoggedInTrueWhenSessionDataSet() {
/** @noinspection PhpArrayWriteIsNotUsedInspection */
$_SESSION = [
- Authenticator::SESSION_KEY => $sessionData
+ SessionData::class => $sessionData
];
$sut = new Authenticator(
@@ -118,13 +107,13 @@ public function testGetUuid() {
->willReturn($userData);
$_SESSION = [
- Authenticator::SESSION_KEY => $sessionData,
+ SessionData::class => $sessionData,
];
$sut = new Authenticator(
"test-key",
"/"
);
- self::assertEquals($exampleId, $sut->getId());
+ self::assertEquals($exampleId, $sut->getUser()->id);
}
public function testGetEmailThrowsExceptionWhenNotLoggedIn() {
@@ -134,7 +123,7 @@ public function testGetEmailThrowsExceptionWhenNotLoggedIn() {
"/"
);
self::expectException(NotLoggedInException::class);
- $sut->getEmail();
+ $sut->getUser()->email;
}
public function testGetEmail() {
@@ -148,13 +137,13 @@ public function testGetEmail() {
->willReturn($userData);
$_SESSION = [
- Authenticator::SESSION_KEY => $sessionData,
+ SessionData::class => $sessionData,
];
$sut = new Authenticator(
"test-key",
"/"
);
- self::assertEquals($expectedEmail, $sut->getEmail());
+ self::assertEquals($expectedEmail, $sut->getUser()->email);
}
public function testCompleteAuthNotAffectedByQueryString() {
@@ -181,7 +170,7 @@ public function testGetAdminUri() {
);
$sut = $auth->getAdminUri();
self::assertEquals(
- "/admin",
+ "/admin/",
$sut->getPath()
);
}
@@ -193,10 +182,11 @@ public function testCompleteAuthNotLoggedIn() {
$_SESSION = [];
self::expectException(NotLoggedInException::class);
- new Authenticator(
+ $sut = new Authenticator(
"test-key",
$currentUri
);
+ $sut->getUser();
}
// When the remote provider redirects back to the client application, a query
@@ -205,9 +195,22 @@ public function testCompleteAuthNotLoggedIn() {
// decrypt properly, and should throw an exception to prevent unauthorised
// access.
public function testCompleteAuth() {
+ $keyBytes = str_repeat("0", SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
+ $ivBytes = str_repeat("1", SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
+ $plainTextMessage = http_build_query([
+ "id" => 123,
+ "email" => "person@example.com",
+ ]);
+ $encryptedMessage = sodium_crypto_secretbox(
+ $plainTextMessage,
+ $ivBytes,
+ $keyBytes,
+ );
+
$currentUri = "/my-page?filter=example&"
. Authenticator::RESPONSE_QUERY_PARAMETER
- . "=0123456789abcdef";
+ . "="
+ . base64_encode($encryptedMessage);
$redirectHandler = self::createMock(RedirectHandler::class);
$redirectHandler->expects(self::once())
@@ -216,17 +219,22 @@ public function testCompleteAuth() {
$uri->getQuery() === "filter=example"
&& $uri->getPath() === "/my-page"
));
+ $iv = self::createMock(InitVector::class);
+ $iv->method("getBytes")->willReturn($ivBytes);
$token = self::createMock(Token::class);
+ $token->method("getSecretIv")
+ ->willReturn($iv);
$sessionData = self::createMock(SessionData::class);
$sessionData->method("getToken")
->willReturn($token);
$_SESSION = [
- Authenticator::SESSION_KEY => $sessionData,
+ SessionData::class => $sessionData,
];
+
new Authenticator(
- "test-key",
+ $keyBytes,
$currentUri,
LoginUri::DEFAULT_BASE_REMOTE_URI,
null,
@@ -234,7 +242,7 @@ public function testCompleteAuth() {
);
/** @var SessionData $newSessionData */
- $newSessionData = $_SESSION[Authenticator::SESSION_KEY];
+ $newSessionData = $_SESSION[SessionData::class];
self::assertNotSame($sessionData, $newSessionData);
self::assertInstanceOf(
SessionData::class,
@@ -249,7 +257,7 @@ public function testCompleteAuth() {
public function testLoginDoesNothingWhenAlreadyLoggedIn() {
$sessionData = self::createMock(SessionData::class);
$_SESSION = [
- Authenticator::SESSION_KEY => $sessionData,
+ SessionData::class => $sessionData,
];
$redirectHandler = self::createMock(RedirectHandler::class);
@@ -264,7 +272,12 @@ public function testLoginDoesNothingWhenAlreadyLoggedIn() {
$redirectHandler
);
- $sut->login();
+ $token = self::createMock(Token::class);
+ $token->method("generateRequestCipher")
+ ->willReturn("example-request-cipher");
+ $token->method("getIv")
+ ->willReturn("0123456789");
+ $sut->login($token);
}
public function testGetUuidThrowsExceptionWhenNotLoggedIn() {
@@ -274,13 +287,13 @@ public function testGetUuidThrowsExceptionWhenNotLoggedIn() {
"/"
);
self::expectException(NotLoggedInException::class);
- $sut->getId();
+ $sut->getUser()->id;
}
public function testLogoutCallsLogoutUri() {
$sessionData = self::createMock(SessionData::class);
$_SESSION = [
- Authenticator::SESSION_KEY => $sessionData
+ SessionData::class => $sessionData
];
$redirectHandler = self::createMock(RedirectHandler::class);
@@ -308,46 +321,13 @@ public function testLogoutCallsLogoutUri() {
null,
$redirectHandler
);
- $sut->logout();
- self::assertNotEmpty($_SESSION);
- }
-
- public function testCompleteAuthFromLogoutClearsSession() {
$token = self::createMock(Token::class);
-
- $sessionData = self::createMock(SessionData::class);
- $sessionData->method("getToken")
- ->willReturn($token);
-
- $_SESSION = [
- Authenticator::SESSION_KEY => $sessionData,
- ];
-
- $responseCipher = "abcdef";
-
- $currentUri = "/example-page-" . uniqid();
- $currentUri .= "?";
- $currentUri .= http_build_query([
- Authenticator::RESPONSE_QUERY_PARAMETER => $responseCipher,
- ]);
-
- $redirectHandler = self::createMock(RedirectHandler::class);
- $redirectHandler->expects(self::once())
- ->method("redirect")
- ->with(self::callback(fn(UriInterface $uri) =>
- $uri->getHost() == ""
- && $uri->getPath() == $currentUri
- ));
-
- new Authenticator(
- "test-key",
- "/",
- LoginUri::DEFAULT_BASE_REMOTE_URI,
- null,
- $redirectHandler
- );
-
- self::assertEmpty($_SESSION);
+ $token->method("generateRequestCipher")
+ ->willReturn("example-request-cipher");
+ $token->method("getIv")
+ ->willReturn("01234567890");
+ $sut->logout($token);
+ self::assertNotEmpty($_SESSION);
}
public function testLoginRedirects() {
@@ -367,7 +347,13 @@ public function testLoginRedirects() {
null,
$redirectHandler
);
- $sut->login();
+
+ $token = self::createMock(Token::class);
+ $token->method("generateRequestCipher")
+ ->willReturn("example-request-cipher");
+ $token->method("getIv")
+ ->willReturn("01234567890");
+ $sut->login($token);
}
public function testLoginRedirectsLocalhost() {
@@ -389,6 +375,11 @@ public function testLoginRedirectsLocalhost() {
null,
$redirectHandler
);
- $sut->login();
+ $token = self::createMock(Token::class);
+ $token->method("generateRequestCipher")
+ ->willReturn("example-request-cipher");
+ $token->method("getIv")
+ ->willReturn("01234567890");
+ $sut->login($token);
}
}
diff --git a/test/phpunit/ProviderUri/AdminUriTest.php b/test/phpunit/ProviderUri/AdminUriTest.php
index 3d32da5..da82940 100644
--- a/test/phpunit/ProviderUri/AdminUriTest.php
+++ b/test/phpunit/ProviderUri/AdminUriTest.php
@@ -8,7 +8,7 @@ class AdminUriTest extends TestCase {
public function testPathAccount() {
$sut = new AdminUri("example.com");
self::assertEquals(
- "/admin",
+ "/admin/",
$sut->getPath()
);
}
diff --git a/test/phpunit/TokenTest.php b/test/phpunit/TokenTest.php
index 3e5ddf8..d8751c3 100644
--- a/test/phpunit/TokenTest.php
+++ b/test/phpunit/TokenTest.php
@@ -67,35 +67,26 @@ public function testDecryptResponseCipherBadJson() {
}
public function testDecryptResponseCipher() {
- $clientKey = uniqid("test-key-");
-// SecretIv is stored in the client application's session only.
+ $clientKeyBytes = str_repeat("0", SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
+ $ivBytes = str_repeat("1", SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
+ $uuid = "abcdef";
+ $email = "person@example.com";
+ $cipher = sodium_crypto_secretbox(
+ serialize((object)[
+ "id" => $uuid,
+ "email" => $email,
+ ]),
+ $ivBytes,
+ $clientKeyBytes,
+ );
+
$secretIv = self::createMock(InitVector::class);
- $secretIv->method("getBytes")
- ->willReturn(str_repeat("0", 16));
$iv = self::createMock(InitVector::class);
$iv->method("getBytes")
- ->willReturn(str_repeat("f", 16));
+ ->willReturn($ivBytes);
- $uuid = "aabb-ccdd-eeff";
- $email = "user@example.com";
- $serialized = serialize((object)[
- "uuid" => $uuid,
- "email" => $email,
- "fields" => (object)[
- "example1" => "value1",
- ]
- ]);
-
- $cipher = openssl_encrypt(
- $serialized,
- Token::ENCRYPTION_METHOD,
- $clientKey,
- 0,
- $secretIv->getBytes()
- );
- $cipher = base64_encode($cipher);
- $sut = new Token($clientKey, $secretIv, $iv);
- $userData = $sut->decode($cipher);
+ $sut = new Token($clientKeyBytes, $secretIv, $iv);
+ $userData = $sut->decode(base64_encode($cipher));
self::assertInstanceOf(UserResponseData::class, $userData);
self::assertEquals($uuid, $userData->getId());
self::assertEquals($email, $userData->getEmail());
From 3cebe9ce026e4bda73f72a278676a16caaac2707 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Fri, 12 Aug 2022 10:29:42 +0100
Subject: [PATCH 07/21] docs: explain unit tests
---
README.md | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/README.md b/README.md
index 5970f8b..f8709fb 100644
--- a/README.md
+++ b/README.md
@@ -58,3 +58,12 @@ else {
HTML;
}
```
+
+Running unit tests
+------------------
+
+From the root directory, unit tests can be ran with the following command:
+
+```bash
+vendor/bin/phpunit test/phpunit --coverage-clover test/phpunit/_coverage --whitelist src
+```
From 8c8c08aacac19b22afbbfb528e76ef09e23749ef Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Wed, 17 Aug 2022 12:26:02 +0100
Subject: [PATCH 08/21] ci: update step versions
---
.github/workflows/ci.yml | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 66b6de3..d90bc29 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,18 +7,18 @@ jobs:
runs-on: [ubuntu-latest]
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v3
- name: Cache PHP dependencies
- uses: actions/cache@v1
+ uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.OS }}-build-${{ hashFiles('**/composer.lock') }}
- - uses: php-actions/composer@v1
+ - uses: php-actions/composer@v6
- name: Upload build for test runner
- uses: actions/upload-artifact@v1
+ uses: actions/upload-artifact@v3
with:
name: build-artifact
path: ./
@@ -28,9 +28,9 @@ jobs:
needs: [build]
steps:
- - uses: actions/download-artifact@v1
+ - uses: actions/download-artifact@v3
with:
name: build-artifact
path: ./
- - uses: php-actions/phpunit@v1
\ No newline at end of file
+ - uses: php-actions/phpunit@v3
From 00a8b9135fc125e53368e08acd6880f6ae5aa524 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Wed, 17 Aug 2022 12:30:41 +0100
Subject: [PATCH 09/21] ci: upgrade workflow
---
.github/workflows/ci.yml | 49 ++++++++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 17 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d90bc29..50a433e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -3,34 +3,49 @@ name: CI
on: [push]
jobs:
- build:
- runs-on: [ubuntu-latest]
+ composer:
+ runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v2
- - name: Cache PHP dependencies
- uses: actions/cache@v3
+ - name: Cache Composer dependencies
+ uses: actions/cache@v2
with:
- path: vendor
- key: ${{ runner.OS }}-build-${{ hashFiles('**/composer.lock') }}
+ path: /tmp/composer-cache
+ key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }}
- - uses: php-actions/composer@v6
+ - name: Composer
+ uses: php-actions/composer@v6
+ with:
+ php_version: '8.1'
+
+ - name: Archive build
+ run: mkdir /tmp/github-actions/ && tar -cvf /tmp/github-actions/build.tar ./
- - name: Upload build for test runner
- uses: actions/upload-artifact@v3
+ - name: Upload build archive for test runners
+ uses: actions/upload-artifact@v2
with:
name: build-artifact
- path: ./
+ path: /tmp/github-actions
- test:
- runs-on: [ubuntu-latest]
- needs: [build]
+ phpunit:
+ runs-on: ubuntu-latest
+ needs: [ composer ]
steps:
- - uses: actions/download-artifact@v3
+ - uses: actions/download-artifact@v2
with:
name: build-artifact
- path: ./
+ path: /tmp/github-actions
- - uses: php-actions/phpunit@v3
+ - name: Extract build archive
+ run: tar -xvf /tmp/github-actions/build.tar ./
+
+ - name: PHP Unit tests
+ uses: php-actions/phpunit@v3
+ with:
+ php_version: '8.1'
+ php_extensions: xdebug
+ configuration: test/phpunit/phpunit.xml
+ bootstrap: vendor/autoload.php
From 798705a92f4c590002d3fdfffdccba1a98fb4f22 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Wed, 17 Aug 2022 12:31:06 +0100
Subject: [PATCH 10/21] ci: bump step versions
---
.github/workflows/ci.yml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 50a433e..ceebd0b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,10 +7,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Cache Composer dependencies
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: /tmp/composer-cache
key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }}
@@ -24,7 +24,7 @@ jobs:
run: mkdir /tmp/github-actions/ && tar -cvf /tmp/github-actions/build.tar ./
- name: Upload build archive for test runners
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: build-artifact
path: /tmp/github-actions
@@ -34,7 +34,7 @@ jobs:
needs: [ composer ]
steps:
- - uses: actions/download-artifact@v2
+ - uses: actions/download-artifact@v3
with:
name: build-artifact
path: /tmp/github-actions
From ea05c76b93b2c44f7bda0c4f4db490702269bb37 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Wed, 17 Aug 2022 13:05:26 +0100
Subject: [PATCH 11/21] test: fix test warnings caused by mocks
---
test/phpunit/AuthenticatorTest.php | 54 ++++++++++++++++++-----
test/phpunit/ProviderUri/LoginUriTest.php | 11 +++--
2 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/test/phpunit/AuthenticatorTest.php b/test/phpunit/AuthenticatorTest.php
index 7d6503e..c1f0fce 100644
--- a/test/phpunit/AuthenticatorTest.php
+++ b/test/phpunit/AuthenticatorTest.php
@@ -11,6 +11,7 @@
use Authwave\SessionNotStartedException;
use Authwave\Token;
use Authwave\ResponseData\UserResponseData;
+use Gt\Cipher\CipherText;
use Gt\Cipher\InitVector;
use Gt\Http\Uri;
use PHPUnit\Framework\TestCase;
@@ -59,7 +60,9 @@ public function testLoginRedirectsWithCorrectQueryString() {
$key = uniqid("key-");
$currentPath = uniqid("/path/");
- $cipher = "example-cipher";
+ $cipherString = "example-cipher";
+ $cipher = self::createMock(CipherText::class);
+ $cipher->method("__toString")->willReturn($cipherString);
$ivString = "example-iv";
$iv = self::createMock(InitVector::class);
@@ -73,7 +76,7 @@ public function testLoginRedirectsWithCorrectQueryString() {
->willReturn($iv);
$expectedQueryParts = [
- LoginUri::QUERY_STRING_CIPHER => $cipher,
+ LoginUri::QUERY_STRING_CIPHER => (string)$cipher,
LoginUri::QUERY_STRING_INIT_VECTOR => $ivString,
LoginUri::QUERY_STRING_CURRENT_PATH => bin2hex($currentPath),
];
@@ -256,6 +259,8 @@ public function testCompleteAuth() {
public function testLoginDoesNothingWhenAlreadyLoggedIn() {
$sessionData = self::createMock(SessionData::class);
+ $sessionData->method("getData")
+ ->willReturn(self::createMock(UserResponseData::class));
$_SESSION = [
SessionData::class => $sessionData,
];
@@ -273,10 +278,17 @@ public function testLoginDoesNothingWhenAlreadyLoggedIn() {
);
$token = self::createMock(Token::class);
+ $requestCipherString = "example-request-cipher";
+ $requestCipher = self::createMock(CipherText::class);
+ $requestCipher->method("__toString")->willReturn($requestCipherString);
+ $ivBytes = "0123456789";
+ $iv = self::createMock(InitVector::class);
+ $iv->method("__toString")->willReturn($ivBytes);
+
$token->method("generateRequestCipher")
- ->willReturn("example-request-cipher");
+ ->willReturn($requestCipher);
$token->method("getIv")
- ->willReturn("0123456789");
+ ->willReturn($iv);
$sut->login($token);
}
@@ -306,12 +318,12 @@ public function testLogoutCallsLogoutUri() {
parse_str($uri->getQuery(), $queryParts);
/** @var SessionData $session */
- $session = $_SESSION[Authenticator::SESSION_KEY];
+ $session = $_SESSION[SessionData::class];
$token = $session->getToken();
$decrypted = $token->decode(
$queryParts[BaseProviderUri::QUERY_STRING_CIPHER]
);
- var_dump($decrypted);die();
+ return (bool)$decrypted;
}));
$sut = new Authenticator(
@@ -322,10 +334,16 @@ public function testLogoutCallsLogoutUri() {
$redirectHandler
);
$token = self::createMock(Token::class);
+ $cipherString = "example-request-cipher";
+ $cipher = self::createMock(CipherText::class);
+ $cipher->method("__toString")->willReturn($cipherString);
$token->method("generateRequestCipher")
- ->willReturn("example-request-cipher");
+ ->willReturn($cipher);
+ $ivBytes = "01234567890";
+ $iv = self::createMock(InitVector::class);
+ $iv->method("__toString")->willReturn($ivBytes);
$token->method("getIv")
- ->willReturn("01234567890");
+ ->willReturn($iv);
$sut->logout($token);
self::assertNotEmpty($_SESSION);
}
@@ -349,10 +367,16 @@ public function testLoginRedirects() {
);
$token = self::createMock(Token::class);
+ $cipherString = "example-request-cipher";
+ $cipher = self::createMock(CipherText::class);
+ $cipher->method("__toString")->willReturn($cipherString);
$token->method("generateRequestCipher")
- ->willReturn("example-request-cipher");
+ ->willReturn($cipher);
+ $ivBytes = "01234567890";
+ $iv = self::createMock(InitVector::class);
+ $iv->method("__toString")->willReturn($ivBytes);
$token->method("getIv")
- ->willReturn("01234567890");
+ ->willReturn($iv);
$sut->login($token);
}
@@ -376,10 +400,16 @@ public function testLoginRedirectsLocalhost() {
$redirectHandler
);
$token = self::createMock(Token::class);
+ $cipherString = "example-request-cipher";
+ $cipher = self::createMock(CipherText::class);
+ $cipher->method("__toString")->willReturn($cipherString);
$token->method("generateRequestCipher")
- ->willReturn("example-request-cipher");
+ ->willReturn($cipher);
+ $ivBytes = "01234567890";
+ $iv = self::createMock(InitVector::class);
+ $iv->method("__toString")->willReturn($ivBytes);
$token->method("getIv")
- ->willReturn("01234567890");
+ ->willReturn($iv);
$sut->login($token);
}
}
diff --git a/test/phpunit/ProviderUri/LoginUriTest.php b/test/phpunit/ProviderUri/LoginUriTest.php
index d7d819a..7af25d2 100644
--- a/test/phpunit/ProviderUri/LoginUriTest.php
+++ b/test/phpunit/ProviderUri/LoginUriTest.php
@@ -1,15 +1,18 @@
method("__toString")->willReturn($cipherString);
$mockIvValue = str_repeat("0", 16);
$iv = self::createMock(InitVector::class);
$iv->method("__toString")
@@ -18,7 +21,7 @@ public function testQueryString() {
$baseUri = self::createMock(UriInterface::class);
$token = self::createMock(Token::class);
$token->method("generateRequestCipher")
- ->willReturn($mockCipherValue);
+ ->willReturn($cipher);
$token->method("getIv")
->willReturn($iv);
@@ -31,7 +34,7 @@ public function testQueryString() {
parse_str($sut->getQuery(), $queryParts);
self::assertEquals(
- $mockCipherValue,
+ $cipher,
$queryParts[LoginUri::QUERY_STRING_CIPHER],
);
From a19260d177f00c2dc5fc24182837e7b10e7c6f0c Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Wed, 17 Aug 2022 13:17:27 +0100
Subject: [PATCH 12/21] feature: switch to json serialisation for language
interoperability
---
src/Token.php | 6 ++----
test/phpunit/TokenTest.php | 2 +-
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/Token.php b/src/Token.php
index bcee8a8..0cbcebc 100644
--- a/src/Token.php
+++ b/src/Token.php
@@ -63,10 +63,8 @@ public function decode(string $base64cipher):BaseResponseData {
throw new ResponseCipherDecryptionException();
}
- $data = @unserialize(
- $decrypted
- );
- if($data === false) {
+ $data = json_decode($decrypted);
+ if($data === null) {
throw new InvalidUserDataSerializationException();
}
diff --git a/test/phpunit/TokenTest.php b/test/phpunit/TokenTest.php
index d8751c3..b792063 100644
--- a/test/phpunit/TokenTest.php
+++ b/test/phpunit/TokenTest.php
@@ -72,7 +72,7 @@ public function testDecryptResponseCipher() {
$uuid = "abcdef";
$email = "person@example.com";
$cipher = sodium_crypto_secretbox(
- serialize((object)[
+ json_encode((object)[
"id" => $uuid,
"email" => $email,
]),
From 62ec6fbd2627b19cd65396919e0130e95a91958b Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Wed, 17 Aug 2022 13:38:35 +0100
Subject: [PATCH 13/21] feature: switch to json serialisation for language
interoperability
---
src/Authenticator.php | 10 +++++-----
test/phpunit/AuthenticatorTest.php | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/Authenticator.php b/src/Authenticator.php
index 704ed91..8891ea3 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -137,12 +137,12 @@ private function completeAuth():void {
$secretSessionIv = $token->getSecretIv();
$encrypted = new EncryptedMessage($queryData, $secretSessionIv);
$key = new Key($this->clientKey);
- $decrypt = $encrypted->decrypt($key);
- parse_str($decrypt, $data);
+ $decrypted = $encrypted->decrypt($key);
+ $data = json_decode($decrypted);
$userData = new UserResponseData(
- $data["id"],
- $data["email"],
- $data["kvp"] ?? [],
+ $data->{"id"},
+ $data->{"email"},
+ $data->{"kvp"} ?? [],
);
$this->session->set(
diff --git a/test/phpunit/AuthenticatorTest.php b/test/phpunit/AuthenticatorTest.php
index c1f0fce..afcf817 100644
--- a/test/phpunit/AuthenticatorTest.php
+++ b/test/phpunit/AuthenticatorTest.php
@@ -200,7 +200,7 @@ public function testCompleteAuthNotLoggedIn() {
public function testCompleteAuth() {
$keyBytes = str_repeat("0", SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
$ivBytes = str_repeat("1", SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
- $plainTextMessage = http_build_query([
+ $plainTextMessage = json_encode([
"id" => 123,
"email" => "person@example.com",
]);
From 1f60dfe03f643e1e1afc1b64c90b5e1948a391f3 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Mon, 30 Oct 2023 17:46:16 +0000
Subject: [PATCH 14/21] feature: logout uri
---
composer.json | 3 +-
composer.lock | 900 ++++++++++++----------
src/Authenticator.php | 36 +-
src/ProviderUri/BaseProviderUri.php | 11 +-
src/ProviderUri/LoginUri.php | 6 +-
src/ProviderUri/LogoutUri.php | 5 +-
src/Token.php | 6 +-
test/phpunit/AuthenticatorTest.php | 2 +-
test/phpunit/ProviderUri/LoginUriTest.php | 2 +-
9 files changed, 553 insertions(+), 418 deletions(-)
diff --git a/composer.json b/composer.json
index c78e634..f9b4734 100644
--- a/composer.json
+++ b/composer.json
@@ -7,7 +7,8 @@
"ext-openssl": "*",
"phpgt/cipher": "^1.0",
"phpgt/http": "1.*",
- "phpgt/session": ">=1.1"
+ "phpgt/session": ">=1.1",
+ "phpgt/logger": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "8.*",
diff --git a/composer.lock b/composer.lock
index 16d2673..825b0d5 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,20 +4,66 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "4573800f16257b1e039dd85fe4abe2a9",
+ "content-hash": "f1ed6a0c38c839b72dfec0981f5aa820",
"packages": [
{
- "name": "phpgt/cipher",
+ "name": "phpgt/async",
"version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PhpGt/Async.git",
+ "reference": "3d2bdeca8cafc8573b416da3ac591d5d88f6dea9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PhpGt/Async/zipball/3d2bdeca8cafc8573b416da3ac591d5d88f6dea9",
+ "reference": "3d2bdeca8cafc8573b416da3ac591d5d88f6dea9",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "php": ">=7.4",
+ "phpgt/promise": "^2.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^v1.8",
+ "phpunit/phpunit": "^v9.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Gt\\Async\\": "./src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Promise-based non-blocking operations.",
+ "support": {
+ "issues": "https://github.com/PhpGt/Async/issues",
+ "source": "https://github.com/PhpGt/Async/tree/v1.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/phpgt",
+ "type": "github"
+ }
+ ],
+ "time": "2023-01-19T11:11:58+00:00"
+ },
+ {
+ "name": "phpgt/cipher",
+ "version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/PhpGt/Cipher.git",
- "reference": "5cef809acd0d77d24ea11ece9ba0e1ed4c8736fd"
+ "reference": "611ff35dbcb73b65d31e902fa15d76b49ba11d46"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PhpGt/Cipher/zipball/5cef809acd0d77d24ea11ece9ba0e1ed4c8736fd",
- "reference": "5cef809acd0d77d24ea11ece9ba0e1ed4c8736fd",
+ "url": "https://api.github.com/repos/PhpGt/Cipher/zipball/611ff35dbcb73b65d31e902fa15d76b49ba11d46",
+ "reference": "611ff35dbcb73b65d31e902fa15d76b49ba11d46",
"shasum": ""
},
"require": {
@@ -26,8 +72,8 @@
"phpgt/http": "v1.*"
},
"require-dev": {
- "phpstan/phpstan": "v1.8.0",
- "phpunit/phpunit": "v9.5.21"
+ "phpstan/phpstan": "^v1.8",
+ "phpunit/phpunit": "^v9.5"
},
"type": "library",
"autoload": {
@@ -47,7 +93,7 @@
"description": "Two-way encryption of messages for secure plain text transmission.",
"support": {
"issues": "https://github.com/PhpGt/Cipher/issues",
- "source": "https://github.com/PhpGt/Cipher/tree/v1.0.0"
+ "source": "https://github.com/PhpGt/Cipher/tree/v1.0.1"
},
"funding": [
{
@@ -55,33 +101,165 @@
"type": "github"
}
],
- "time": "2022-07-20T11:29:08+00:00"
+ "time": "2023-05-12T11:14:40+00:00"
+ },
+ {
+ "name": "phpgt/curl",
+ "version": "v3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PhpGt/Curl.git",
+ "reference": "a7e0856d3735f8f69d6d5fbf2f6f26664e55e3b7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PhpGt/Curl/zipball/a7e0856d3735f8f69d6d5fbf2f6f26664e55e3b7",
+ "reference": "a7e0856d3735f8f69d6d5fbf2f6f26664e55e3b7",
+ "shasum": ""
+ },
+ "require": {
+ "ext-curl": "*",
+ "ext-json": "*",
+ "php": ">=8.1",
+ "phpgt/json": "^1.2"
+ },
+ "require-dev": {
+ "phpmd/phpmd": "^2.13",
+ "phpstan/phpstan": "^1.9",
+ "phpunit/phpunit": "^10.0",
+ "squizlabs/php_codesniffer": "^3.7"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Gt\\Curl\\": "./src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Greg Bowler",
+ "email": "greg.bowler@g105b.com"
+ }
+ ],
+ "description": "cURL object wrapper.",
+ "keywords": [
+ "curl",
+ "curl_multi",
+ "http",
+ "interface"
+ ],
+ "support": {
+ "issues": "https://github.com/PhpGt/Curl/issues",
+ "source": "https://github.com/PhpGt/Curl/tree/v3.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/PhpGt",
+ "type": "github"
+ }
+ ],
+ "time": "2023-04-29T17:28:12+00:00"
+ },
+ {
+ "name": "phpgt/dataobject",
+ "version": "v1.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PhpGt/DataObject.git",
+ "reference": "3b05cc3b64a0f2b763c8e550bc6c03b71474cd1a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PhpGt/DataObject/zipball/3b05cc3b64a0f2b763c8e550bc6c03b71474cd1a",
+ "reference": "3b05cc3b64a0f2b763c8e550bc6c03b71474cd1a",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "php": ">=8.0",
+ "phpgt/typesafegetter": "^1.3"
+ },
+ "require-dev": {
+ "phpmd/phpmd": "^2.13",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^10.1",
+ "squizlabs/php_codesniffer": "^3.7"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Gt\\DataObject\\": "./src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Greg Bowler",
+ "email": "greg.bowler@g105b.com"
+ }
+ ],
+ "description": " Structured, type-safe, immutable data transfer.",
+ "support": {
+ "issues": "https://github.com/PhpGt/DataObject/issues",
+ "source": "https://github.com/PhpGt/DataObject/tree/v1.0.7"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/phpgt",
+ "type": "github"
+ }
+ ],
+ "time": "2023-07-13T09:45:07+00:00"
},
{
"name": "phpgt/http",
- "version": "v1.1.5",
+ "version": "v1.2.2",
"source": {
"type": "git",
"url": "https://github.com/PhpGt/Http.git",
- "reference": "1b93fa9489100d649f29f59226cc52cd7c0812cb"
+ "reference": "de03587d63d5a582140a3e9e9b06e506ffbc8ca3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PhpGt/Http/zipball/1b93fa9489100d649f29f59226cc52cd7c0812cb",
- "reference": "1b93fa9489100d649f29f59226cc52cd7c0812cb",
+ "url": "https://api.github.com/repos/PhpGt/Http/zipball/de03587d63d5a582140a3e9e9b06e506ffbc8ca3",
+ "reference": "de03587d63d5a582140a3e9e9b06e506ffbc8ca3",
"shasum": ""
},
"require": {
- "php": ">=8.0",
- "phpgt/input": "^v1",
- "psr/http-message": "^v1.0.1",
- "willdurand/negotiation": "v3.1.0"
+ "ext-curl": "*",
+ "ext-dom": "*",
+ "ext-fileinfo": "*",
+ "php": ">=8.1",
+ "phpgt/async": "^1.0",
+ "phpgt/curl": "^3.1",
+ "phpgt/input": "^1.2",
+ "phpgt/json": "^1.2",
+ "phpgt/promise": "^2.2",
+ "phpgt/propfunc": "^1.0",
+ "phpgt/typesafegetter": "^1.3",
+ "psr/http-message": "^2.0",
+ "willdurand/negotiation": "3.1.0"
},
"require-dev": {
- "phpstan/phpstan": "v1.8.1",
- "phpunit/phpunit": "v9.5.21"
+ "phpmd/phpmd": "^2.13",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^10.1",
+ "squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.3-dev",
+ "dev-ci": "1.2.3-dev"
+ }
+ },
"autoload": {
"psr-4": {
"Gt\\Http\\": "./src"
@@ -94,7 +272,7 @@
"description": "PSR-7 HTTP message implementation.",
"support": {
"issues": "https://github.com/PhpGt/Http/issues",
- "source": "https://github.com/PhpGt/Http/tree/v1.1.5"
+ "source": "https://github.com/PhpGt/Http/tree/v1.2.2"
},
"funding": [
{
@@ -102,29 +280,31 @@
"type": "github"
}
],
- "time": "2022-07-25T14:31:55+00:00"
+ "time": "2023-07-20T15:04:03+00:00"
},
{
"name": "phpgt/input",
- "version": "v1.2.0",
+ "version": "v1.2.3",
"source": {
"type": "git",
"url": "https://github.com/PhpGt/Input.git",
- "reference": "95136bcbe1c50c3d8db90eb3b1944d049ec2b2a0"
+ "reference": "7e82009922c42531e57e45641072b7c416d726c3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PhpGt/Input/zipball/95136bcbe1c50c3d8db90eb3b1944d049ec2b2a0",
- "reference": "95136bcbe1c50c3d8db90eb3b1944d049ec2b2a0",
+ "url": "https://api.github.com/repos/PhpGt/Input/zipball/7e82009922c42531e57e45641072b7c416d726c3",
+ "reference": "7e82009922c42531e57e45641072b7c416d726c3",
"shasum": ""
},
"require": {
- "php": ">=8.0",
+ "php": ">=8.1",
"phpgt/http": "^v1.1"
},
"require-dev": {
- "phpstan/phpstan": "^v1.4",
- "phpunit/phpunit": "^v9.5"
+ "phpmd/phpmd": "^2.13",
+ "phpstan/phpstan": "^v1.10",
+ "phpunit/phpunit": "^10.1",
+ "squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
@@ -139,7 +319,168 @@
"description": "Encapsulated user input.",
"support": {
"issues": "https://github.com/PhpGt/Input/issues",
- "source": "https://github.com/PhpGt/Input/tree/v1.2.0"
+ "source": "https://github.com/PhpGt/Input/tree/v1.2.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/PhpGt",
+ "type": "github"
+ }
+ ],
+ "time": "2023-05-02T17:16:00+00:00"
+ },
+ {
+ "name": "phpgt/json",
+ "version": "v1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PhpGt/Json.git",
+ "reference": "8938b374d550bc6114bf1d4e5c1cbe3283868e58"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PhpGt/Json/zipball/8938b374d550bc6114bf1d4e5c1cbe3283868e58",
+ "reference": "8938b374d550bc6114bf1d4e5c1cbe3283868e58",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "php": ">=8.1",
+ "phpgt/dataobject": "^1.0.7"
+ },
+ "require-dev": {
+ "phpmd/phpmd": "^2.13",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^10.1",
+ "squizlabs/php_codesniffer": "^3.7"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Gt\\Json\\": "./src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Greg Bowler",
+ "email": "greg.bowler@g105b.com"
+ }
+ ],
+ "description": " Structured, type-safe, immutable JSON objects.",
+ "support": {
+ "issues": "https://github.com/PhpGt/Json/issues",
+ "source": "https://github.com/PhpGt/Json/tree/v1.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/PhpGt",
+ "type": "github"
+ }
+ ],
+ "time": "2023-07-13T13:20:08+00:00"
+ },
+ {
+ "name": "phpgt/logger",
+ "version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PhpGt/Logger.git",
+ "reference": "9cbb7c986941bff513aedf80dfa256497aff8dd2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PhpGt/Logger/zipball/9cbb7c986941bff513aedf80dfa256497aff8dd2",
+ "reference": "9cbb7c986941bff513aedf80dfa256497aff8dd2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.4"
+ },
+ "require-dev": {
+ "phpstan/phpstan": ">=0.12.64",
+ "phpunit/phpunit": "9.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Gt\\Logger\\": "./src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Greg Bowler",
+ "email": "greg.bowler@g105b.com"
+ }
+ ],
+ "description": "PSR-3 logger and implementation.",
+ "support": {
+ "issues": "https://github.com/PhpGt/Logger/issues",
+ "source": "https://github.com/PhpGt/Logger/tree/v1.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/PhpGt",
+ "type": "github"
+ }
+ ],
+ "time": "2021-09-21T14:18:11+00:00"
+ },
+ {
+ "name": "phpgt/promise",
+ "version": "v2.2.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PhpGt/Promise.git",
+ "reference": "907b3a450f3252077f80b50289f73ab930ca2cdc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PhpGt/Promise/zipball/907b3a450f3252077f80b50289f73ab930ca2cdc",
+ "reference": "907b3a450f3252077f80b50289f73ab930ca2cdc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "phpmd/phpmd": "^2.13",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^10.1",
+ "squizlabs/php_codesniffer": "^3.7"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Gt\\Promise\\": "./src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Pleasantly work with asynchronous code.",
+ "keywords": [
+ "W3C",
+ "async",
+ "asynchronous",
+ "callback",
+ "concurrency",
+ "concurrent",
+ "deferred",
+ "promise",
+ "then"
+ ],
+ "support": {
+ "issues": "https://github.com/PhpGt/Promise/issues",
+ "source": "https://github.com/PhpGt/Promise/tree/v2.2.3"
},
"funding": [
{
@@ -147,29 +488,83 @@
"type": "github"
}
],
- "time": "2022-03-18T19:03:02+00:00"
+ "time": "2023-07-01T10:59:01+00:00"
+ },
+ {
+ "name": "phpgt/propfunc",
+ "version": "v1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PhpGt/PropFunc.git",
+ "reference": "091213649e89ff22d1ef640b46fbee5215c65520"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PhpGt/PropFunc/zipball/091213649e89ff22d1ef640b46fbee5215c65520",
+ "reference": "091213649e89ff22d1ef640b46fbee5215c65520",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": ">=0.12",
+ "phpunit/phpunit": ">=9.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Gt\\PropFunc\\": "./src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Greg Bowler",
+ "email": "greg.bowler@g105b.com",
+ "homepage": "https://www.g105b.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "Property accessor and mutator functions.",
+ "support": {
+ "issues": "https://github.com/PhpGt/PropFunc/issues",
+ "source": "https://github.com/PhpGt/PropFunc/tree/v1.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/PhpGt",
+ "type": "github"
+ }
+ ],
+ "time": "2021-03-23T12:46:44+00:00"
},
{
"name": "phpgt/session",
- "version": "v1.1.5",
+ "version": "v1.2.1",
"source": {
"type": "git",
"url": "https://github.com/PhpGt/Session.git",
- "reference": "4ec55d2e38117b095d525b3e8507bdb5efac5c8a"
+ "reference": "b2e21a3147f135aee9dc16b04e352c28898d78fa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PhpGt/Session/zipball/4ec55d2e38117b095d525b3e8507bdb5efac5c8a",
- "reference": "4ec55d2e38117b095d525b3e8507bdb5efac5c8a",
+ "url": "https://api.github.com/repos/PhpGt/Session/zipball/b2e21a3147f135aee9dc16b04e352c28898d78fa",
+ "reference": "b2e21a3147f135aee9dc16b04e352c28898d78fa",
"shasum": ""
},
"require": {
"php": ">=8.0",
- "phpgt/typesafegetter": "^v1.2"
+ "phpgt/typesafegetter": "^1.3"
},
"require-dev": {
- "phpstan/phpstan": "^v1.4",
- "phpunit/phpunit": "^9.5"
+ "phpmd/phpmd": "^2.13",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^10.1",
+ "squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
@@ -184,7 +579,7 @@
"description": "Encapsulated user sessions.",
"support": {
"issues": "https://github.com/PhpGt/Session/issues",
- "source": "https://github.com/PhpGt/Session/tree/v1.1.5"
+ "source": "https://github.com/PhpGt/Session/tree/v1.2.1"
},
"funding": [
{
@@ -192,28 +587,30 @@
"type": "github"
}
],
- "time": "2022-03-08T15:40:23+00:00"
+ "time": "2023-05-25T13:15:56+00:00"
},
{
"name": "phpgt/typesafegetter",
- "version": "v1.2.4",
+ "version": "v1.3.2",
"source": {
"type": "git",
"url": "https://github.com/PhpGt/TypeSafeGetter.git",
- "reference": "ebffd758e69b8a0eebcad30f3daf408915b9ddf3"
+ "reference": "f760c05a37b1cc188dcbf800c5fdfab8a926b4b0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PhpGt/TypeSafeGetter/zipball/ebffd758e69b8a0eebcad30f3daf408915b9ddf3",
- "reference": "ebffd758e69b8a0eebcad30f3daf408915b9ddf3",
+ "url": "https://api.github.com/repos/PhpGt/TypeSafeGetter/zipball/f760c05a37b1cc188dcbf800c5fdfab8a926b4b0",
+ "reference": "f760c05a37b1cc188dcbf800c5fdfab8a926b4b0",
"shasum": ""
},
"require": {
"php": ">=8.0"
},
"require-dev": {
- "phpstan/phpstan": "v1.8.0",
- "phpunit/phpunit": "v9.5.21"
+ "phpmd/phpmd": "^2.13",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^10.1",
+ "squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
@@ -234,7 +631,7 @@
"description": "An interface for objects that expose type-safe getter methods.",
"support": {
"issues": "https://github.com/PhpGt/TypeSafeGetter/issues",
- "source": "https://github.com/PhpGt/TypeSafeGetter/tree/v1.2.4"
+ "source": "https://github.com/PhpGt/TypeSafeGetter/tree/v1.3.2"
},
"funding": [
{
@@ -242,29 +639,29 @@
"type": "github"
}
],
- "time": "2022-07-08T17:17:42+00:00"
+ "time": "2023-04-28T14:42:27+00:00"
},
{
"name": "psr/http-message",
- "version": "1.0.1",
+ "version": "2.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
+ "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
@@ -279,7 +676,7 @@
"authors": [
{
"name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
@@ -293,9 +690,9 @@
"response"
],
"support": {
- "source": "https://github.com/php-fig/http-message/tree/master"
+ "source": "https://github.com/php-fig/http-message/tree/2.0"
},
- "time": "2016-08-06T14:39:51+00:00"
+ "time": "2023-04-04T09:54:51+00:00"
},
{
"name": "willdurand/negotiation",
@@ -357,30 +754,30 @@
"packages-dev": [
{
"name": "doctrine/instantiator",
- "version": "1.4.1",
+ "version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
- "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc"
+ "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc",
- "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b",
+ "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
- "doctrine/coding-standard": "^9",
+ "doctrine/coding-standard": "^9 || ^11",
"ext-pdo": "*",
"ext-phar": "*",
"phpbench/phpbench": "^0.16 || ^1",
"phpstan/phpstan": "^1.4",
"phpstan/phpstan-phpunit": "^1",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
- "vimeo/psalm": "^4.22"
+ "vimeo/psalm": "^4.30 || ^5.4"
},
"type": "library",
"autoload": {
@@ -407,7 +804,7 @@
],
"support": {
"issues": "https://github.com/doctrine/instantiator/issues",
- "source": "https://github.com/doctrine/instantiator/tree/1.4.1"
+ "source": "https://github.com/doctrine/instantiator/tree/1.5.0"
},
"funding": [
{
@@ -423,20 +820,20 @@
"type": "tidelift"
}
],
- "time": "2022-03-03T08:28:38+00:00"
+ "time": "2022-12-30T00:15:36+00:00"
},
{
"name": "myclabs/deep-copy",
- "version": "1.11.0",
+ "version": "1.11.1",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
+ "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
- "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+ "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
"shasum": ""
},
"require": {
@@ -474,7 +871,7 @@
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
- "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
},
"funding": [
{
@@ -482,7 +879,7 @@
"type": "tidelift"
}
],
- "time": "2022-03-03T13:19:32+00:00"
+ "time": "2023-03-08T13:26:56+00:00"
},
{
"name": "phar-io/manifest",
@@ -595,233 +992,6 @@
},
"time": "2022-02-21T01:04:05+00:00"
},
- {
- "name": "phpdocumentor/reflection-common",
- "version": "2.2.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-2.x": "2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jaap van Otterdijk",
- "email": "opensource@ijaap.nl"
- }
- ],
- "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
- "homepage": "http://www.phpdoc.org",
- "keywords": [
- "FQSEN",
- "phpDocumentor",
- "phpdoc",
- "reflection",
- "static analysis"
- ],
- "support": {
- "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
- "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
- },
- "time": "2020-06-27T09:03:43+00:00"
- },
- {
- "name": "phpdocumentor/reflection-docblock",
- "version": "5.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
- "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
- "shasum": ""
- },
- "require": {
- "ext-filter": "*",
- "php": "^7.2 || ^8.0",
- "phpdocumentor/reflection-common": "^2.2",
- "phpdocumentor/type-resolver": "^1.3",
- "webmozart/assert": "^1.9.1"
- },
- "require-dev": {
- "mockery/mockery": "~1.3.2",
- "psalm/phar": "^4.8"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- },
- {
- "name": "Jaap van Otterdijk",
- "email": "account@ijaap.nl"
- }
- ],
- "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "support": {
- "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
- "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
- },
- "time": "2021-10-19T17:43:47+00:00"
- },
- {
- "name": "phpdocumentor/type-resolver",
- "version": "1.6.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "77a32518733312af16a44300404e945338981de3"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3",
- "reference": "77a32518733312af16a44300404e945338981de3",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0",
- "phpdocumentor/reflection-common": "^2.0"
- },
- "require-dev": {
- "ext-tokenizer": "*",
- "psalm/phar": "^4.8"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-1.x": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- }
- ],
- "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
- "support": {
- "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
- "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1"
- },
- "time": "2022-03-15T21:29:03+00:00"
- },
- {
- "name": "phpspec/prophecy",
- "version": "v1.15.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpspec/prophecy.git",
- "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
- "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
- "shasum": ""
- },
- "require": {
- "doctrine/instantiator": "^1.2",
- "php": "^7.2 || ~8.0, <8.2",
- "phpdocumentor/reflection-docblock": "^5.2",
- "sebastian/comparator": "^3.0 || ^4.0",
- "sebastian/recursion-context": "^3.0 || ^4.0"
- },
- "require-dev": {
- "phpspec/phpspec": "^6.0 || ^7.0",
- "phpunit/phpunit": "^8.0 || ^9.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Prophecy\\": "src/Prophecy"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com",
- "homepage": "http://everzet.com"
- },
- {
- "name": "Marcello Duarte",
- "email": "marcello.duarte@gmail.com"
- }
- ],
- "description": "Highly opinionated mocking framework for PHP 5.3+",
- "homepage": "https://github.com/phpspec/prophecy",
- "keywords": [
- "Double",
- "Dummy",
- "fake",
- "mock",
- "spy",
- "stub"
- ],
- "support": {
- "issues": "https://github.com/phpspec/prophecy/issues",
- "source": "https://github.com/phpspec/prophecy/tree/v1.15.0"
- },
- "time": "2021-12-08T12:19:24+00:00"
- },
{
"name": "phpunit/php-code-coverage",
"version": "7.0.15",
@@ -1121,16 +1291,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "8.5.28",
+ "version": "8.5.34",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "8f2d1c9c7b30382459c871467853da1a6e44fbd4"
+ "reference": "622d0186707f39a4ae71df3bcf42d759bb868854"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8f2d1c9c7b30382459c871467853da1a6e44fbd4",
- "reference": "8f2d1c9c7b30382459c871467853da1a6e44fbd4",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/622d0186707f39a4ae71df3bcf42d759bb868854",
+ "reference": "622d0186707f39a4ae71df3bcf42d759bb868854",
"shasum": ""
},
"require": {
@@ -1145,15 +1315,14 @@
"phar-io/manifest": "^2.0.3",
"phar-io/version": "^3.0.2",
"php": ">=7.2",
- "phpspec/prophecy": "^1.10.3",
"phpunit/php-code-coverage": "^7.0.12",
"phpunit/php-file-iterator": "^2.0.4",
"phpunit/php-text-template": "^1.2.1",
"phpunit/php-timer": "^2.1.2",
- "sebastian/comparator": "^3.0.2",
+ "sebastian/comparator": "^3.0.5",
"sebastian/diff": "^3.0.2",
"sebastian/environment": "^4.2.3",
- "sebastian/exporter": "^3.1.2",
+ "sebastian/exporter": "^3.1.5",
"sebastian/global-state": "^3.0.0",
"sebastian/object-enumerator": "^3.0.3",
"sebastian/resource-operations": "^2.0.1",
@@ -1161,9 +1330,9 @@
"sebastian/version": "^2.0.1"
},
"suggest": {
- "ext-soap": "*",
- "ext-xdebug": "*",
- "phpunit/php-invoker": "^2.0.0"
+ "ext-soap": "To be able to generate mocks based on WSDL files",
+ "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage",
+ "phpunit/php-invoker": "To allow enforcing time limits"
},
"bin": [
"phpunit"
@@ -1199,7 +1368,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.28"
+ "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.34"
},
"funding": [
{
@@ -1209,9 +1379,13 @@
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
+ "type": "tidelift"
}
],
- "time": "2022-07-29T09:20:50+00:00"
+ "time": "2023-09-19T05:20:51+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
@@ -1270,16 +1444,16 @@
},
{
"name": "sebastian/comparator",
- "version": "3.0.3",
+ "version": "3.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
+ "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
- "reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
+ "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
"shasum": ""
},
"require": {
@@ -1332,7 +1506,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
- "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3"
+ "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.5"
},
"funding": [
{
@@ -1340,20 +1514,20 @@
"type": "github"
}
],
- "time": "2020-11-30T08:04:30+00:00"
+ "time": "2022-09-14T12:31:48+00:00"
},
{
"name": "sebastian/diff",
- "version": "3.0.3",
+ "version": "3.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
+ "reference": "6296a0c086dd0117c1b78b059374d7fcbe7545ae"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
- "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/6296a0c086dd0117c1b78b059374d7fcbe7545ae",
+ "reference": "6296a0c086dd0117c1b78b059374d7fcbe7545ae",
"shasum": ""
},
"require": {
@@ -1398,7 +1572,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
- "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3"
+ "source": "https://github.com/sebastianbergmann/diff/tree/3.0.4"
},
"funding": [
{
@@ -1406,7 +1580,7 @@
"type": "github"
}
],
- "time": "2020-11-30T07:59:04+00:00"
+ "time": "2023-05-07T05:30:20+00:00"
},
{
"name": "sebastian/environment",
@@ -1473,16 +1647,16 @@
},
{
"name": "sebastian/exporter",
- "version": "3.1.4",
+ "version": "3.1.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db"
+ "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
- "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/73a9676f2833b9a7c36968f9d882589cd75511e6",
+ "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6",
"shasum": ""
},
"require": {
@@ -1538,7 +1712,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
- "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4"
+ "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.5"
},
"funding": [
{
@@ -1546,20 +1720,20 @@
"type": "github"
}
],
- "time": "2021-11-11T13:51:24+00:00"
+ "time": "2022-09-14T06:00:17+00:00"
},
{
"name": "sebastian/global-state",
- "version": "3.0.2",
+ "version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921"
+ "reference": "66783ce213de415b451b904bfef9dda0cf9aeae0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/de036ec91d55d2a9e0db2ba975b512cdb1c23921",
- "reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/66783ce213de415b451b904bfef9dda0cf9aeae0",
+ "reference": "66783ce213de415b451b904bfef9dda0cf9aeae0",
"shasum": ""
},
"require": {
@@ -1602,7 +1776,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
- "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.2"
+ "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.3"
},
"funding": [
{
@@ -1610,7 +1784,7 @@
"type": "github"
}
],
- "time": "2022-02-10T06:55:38+00:00"
+ "time": "2023-08-02T09:23:32+00:00"
},
{
"name": "sebastian/object-enumerator",
@@ -1991,64 +2165,6 @@
}
],
"time": "2021-07-28T10:34:58+00:00"
- },
- {
- "name": "webmozart/assert",
- "version": "1.11.0",
- "source": {
- "type": "git",
- "url": "https://github.com/webmozarts/assert.git",
- "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
- "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
- "shasum": ""
- },
- "require": {
- "ext-ctype": "*",
- "php": "^7.2 || ^8.0"
- },
- "conflict": {
- "phpstan/phpstan": "<0.12.20",
- "vimeo/psalm": "<4.6.1 || 4.6.2"
- },
- "require-dev": {
- "phpunit/phpunit": "^8.5.13"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.10-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Webmozart\\Assert\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@gmail.com"
- }
- ],
- "description": "Assertions to validate method input/output with nice error messages.",
- "keywords": [
- "assert",
- "check",
- "validate"
- ],
- "support": {
- "issues": "https://github.com/webmozarts/assert/issues",
- "source": "https://github.com/webmozarts/assert/tree/1.11.0"
- },
- "time": "2022-06-03T18:03:27+00:00"
}
],
"aliases": [],
@@ -2063,5 +2179,5 @@
"platform-dev": {
"ext-sodium": "*"
},
- "plugin-api-version": "2.2.0"
+ "plugin-api-version": "2.3.0"
}
diff --git a/src/Authenticator.php b/src/Authenticator.php
index 8891ea3..deb6777 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -10,27 +10,33 @@
use Gt\Cipher\Key;
use Gt\Cipher\Message\EncryptedMessage;
use Gt\Http\Uri;
+use Gt\Logger\Log;
use Gt\Session\SessionContainer;
use Psr\Http\Message\UriInterface;
class Authenticator {
+ const SESSION_STORE_KEY = "AUTHWAVE_CONSUMER_SESSION";
const RESPONSE_QUERY_PARAMETER = "AUTHWAVE_RESPONSE_DATA";
private SessionData $sessionData;
private User $user;
private Uri $currentUri;
+ private readonly string $deploymentId;
+ private readonly string $secret;
public function __construct(
- private readonly string $clientKey,
+ string $clientKey,
string|Uri $currentUri,
private readonly string $authwaveHost = "login.authwave.com",
private ?SessionContainer $session = null,
private ?RedirectHandler $redirectHandler = null,
) {
+ [$this->deploymentId, $this->secret] = explode("_", $clientKey);
+
$this->session = $this->session ?? new GlobalSessionContainer();
$this->redirectHandler = $redirectHandler ?? new RedirectHandler();
- if($data = $this->session->get(SessionData::class)) {
- $this->sessionData = $data;
+ if($sessionData = $this->session->get(SessionData::class)) {
+ $this->sessionData = $sessionData;
try {
$responseData = $this->sessionData->getData();
@@ -63,7 +69,8 @@ public function login(Token $token = null):void {
}
if(is_null($token)) {
- $token = new Token($this->clientKey);
+ Log::debug("Created new CONSUMER token");
+ $token = new Token($this->secret);
}
$this->sessionData = new SessionData($token);
@@ -72,8 +79,9 @@ public function login(Token $token = null):void {
}
public function logout(Token $token = null):void {
+// TODO: Log out needs implementing - ApplicationDeploymentNotFoundException throws!
if(is_null($token)) {
- $token = new Token($this->clientKey);
+ $token = new Token($this->secret);
}
$this->sessionData = new SessionData($token);
@@ -93,7 +101,8 @@ public function getLoginUri(Token $token):BaseProviderUri {
return new LoginUri(
$token,
$this->currentUri,
- $this->authwaveHost
+ $this->deploymentId,
+ $this->authwaveHost,
);
}
@@ -101,7 +110,8 @@ private function getLogoutUri(Token $token):BaseProviderUri {
return new LogoutUri(
$token,
$this->currentUri,
- $this->authwaveHost
+ $this->deploymentId,
+ $this->authwaveHost,
);
}
@@ -111,7 +121,7 @@ public function getAdminUri():UriInterface {
public function getProfileUri(Token $token = null):UriInterface {
if(is_null($token)) {
- $token = new Token($this->clientKey);
+ $token = new Token($this->secret);
}
return new ProfileUri(
@@ -130,13 +140,15 @@ private function completeAuth():void {
}
if(!isset($this->sessionData)) {
+ die("No session data");
+ $this->tidyResponseData();
return;
}
$token = $this->sessionData->getToken();
$secretSessionIv = $token->getSecretIv();
$encrypted = new EncryptedMessage($queryData, $secretSessionIv);
- $key = new Key($this->clientKey);
+ $key = new Key($this->secret);
$decrypted = $encrypted->decrypt($key);
$data = json_decode($decrypted);
$userData = new UserResponseData(
@@ -150,9 +162,13 @@ private function completeAuth():void {
new SessionData($token, $userData)
);
+ $this->tidyResponseData();
+ }
+
+ private function tidyResponseData():void {
$this->redirectHandler->redirect(
(new Uri($this->currentUri))
- ->withoutQueryValue(self::RESPONSE_QUERY_PARAMETER)
+ ->withoutQueryValue(self::RESPONSE_QUERY_PARAMETER)
);
}
diff --git a/src/ProviderUri/BaseProviderUri.php b/src/ProviderUri/BaseProviderUri.php
index 3f8fcb4..a3b1cb3 100644
--- a/src/ProviderUri/BaseProviderUri.php
+++ b/src/ProviderUri/BaseProviderUri.php
@@ -7,9 +7,10 @@
abstract class BaseProviderUri extends Uri {
const DEFAULT_BASE_REMOTE_URI = "login.authwave.com";
- const QUERY_STRING_CIPHER = "cipher";
- const QUERY_STRING_INIT_VECTOR = "iv";
- const QUERY_STRING_CURRENT_PATH = "path";
+ const QUERY_STRING_CIPHER = "c";
+ const QUERY_STRING_INIT_VECTOR = "i";
+ const QUERY_STRING_CURRENT_URI = "u";
+ const QUERY_STRING_DEPLOYMENT_ID = "d";
protected function normaliseBaseUri(string $baseUri):Uri {
$scheme = parse_url($baseUri, PHP_URL_SCHEME)
@@ -35,13 +36,15 @@ protected function normaliseBaseUri(string $baseUri):Uri {
protected function buildQuery(
Token $token,
+ string $deploymentId,
string $currentPath,
string $message = "",
):string {
return http_build_query([
self::QUERY_STRING_CIPHER => (string)$token->generateRequestCipher($message),
+ self::QUERY_STRING_DEPLOYMENT_ID => $deploymentId,
self::QUERY_STRING_INIT_VECTOR => (string)$token->getIv(),
- self::QUERY_STRING_CURRENT_PATH => bin2hex($currentPath),
+ self::QUERY_STRING_CURRENT_URI => bin2hex($currentPath),
]);
}
}
diff --git a/src/ProviderUri/LoginUri.php b/src/ProviderUri/LoginUri.php
index 0e6eae5..5df9a81 100644
--- a/src/ProviderUri/LoginUri.php
+++ b/src/ProviderUri/LoginUri.php
@@ -15,22 +15,22 @@ class LoginUri extends BaseProviderUri {
* @param Token $token This must be the same instance of the Token when
* creating Authenticator for the first time as it is when checking the
* response from the Authwave provider (store in a session).
- * @param string $clientId
- * @param string $currentPath
* @param string $baseRemoteUri The base URI of the application. This is the
* URI authority with optional scheme, as localhost allows http://
*/
public function __construct(
Token $token,
string $currentPath,
+ string $deploymentId,
string $baseRemoteUri = self::DEFAULT_BASE_REMOTE_URI
) {
$baseRemoteUri = $this->normaliseBaseUri($baseRemoteUri);
parent::__construct($baseRemoteUri);
$this->query = $this->buildQuery(
$token,
+ $deploymentId,
$currentPath,
- "action=login"
+ "action=login",
);
}
}
diff --git a/src/ProviderUri/LogoutUri.php b/src/ProviderUri/LogoutUri.php
index 9f7922c..c05e9fd 100644
--- a/src/ProviderUri/LogoutUri.php
+++ b/src/ProviderUri/LogoutUri.php
@@ -6,14 +6,15 @@
class LogoutUri extends BaseProviderUri {
public function __construct(
Token $token,
- string $currentPath = "/",
+ string $currentPath,
+ string $deploymentId,
string $baseRemoteUri = self::DEFAULT_BASE_REMOTE_URI
) {
$baseRemoteUri = $this->normaliseBaseUri($baseRemoteUri);
-
parent::__construct($baseRemoteUri);
$this->query = $this->buildQuery(
$token,
+ $deploymentId,
$currentPath,
"action=logout",
);
diff --git a/src/Token.php b/src/Token.php
index 0cbcebc..61aa5e5 100644
--- a/src/Token.php
+++ b/src/Token.php
@@ -8,8 +8,6 @@
use Gt\Cipher\Key;
use Gt\Cipher\Message\EncryptedMessage;
use Gt\Cipher\Message\PlainTextMessage;
-use Gt\Logger\Log;
-use StdClass;
class Token {
private Key $key;
@@ -17,11 +15,11 @@ class Token {
private InitVector $iv;
public function __construct(
- string $keyString,
+ string $secret,
InitVector $sessionIv = null,
InitVector $iv = null,
) {
- $this->key = new Key($keyString);
+ $this->key = new Key($secret);
$this->secretSessionIv = $sessionIv ?? new InitVector();
$this->iv = $iv ?? new InitVector();
}
diff --git a/test/phpunit/AuthenticatorTest.php b/test/phpunit/AuthenticatorTest.php
index afcf817..31b5653 100644
--- a/test/phpunit/AuthenticatorTest.php
+++ b/test/phpunit/AuthenticatorTest.php
@@ -78,7 +78,7 @@ public function testLoginRedirectsWithCorrectQueryString() {
$expectedQueryParts = [
LoginUri::QUERY_STRING_CIPHER => (string)$cipher,
LoginUri::QUERY_STRING_INIT_VECTOR => $ivString,
- LoginUri::QUERY_STRING_CURRENT_PATH => bin2hex($currentPath),
+ LoginUri::QUERY_STRING_CURRENT_URI => bin2hex($currentPath),
];
$expectedQuery = http_build_query($expectedQueryParts);
diff --git a/test/phpunit/ProviderUri/LoginUriTest.php b/test/phpunit/ProviderUri/LoginUriTest.php
index 7af25d2..3b56f50 100644
--- a/test/phpunit/ProviderUri/LoginUriTest.php
+++ b/test/phpunit/ProviderUri/LoginUriTest.php
@@ -45,7 +45,7 @@ public function testQueryString() {
self::assertEquals(
bin2hex($returnPath),
- $queryParts[LoginUri::QUERY_STRING_CURRENT_PATH]
+ $queryParts[LoginUri::QUERY_STRING_CURRENT_URI]
);
}
}
From 7478bda54a8ff735cdab4b5991f828ee6a850e41 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Mon, 20 Nov 2023 18:06:33 +0000
Subject: [PATCH 15/21] feature: fake login for #14
---
src/Authenticator.php | 48 +++++++++++++++++++++++++++++++++++++++----
1 file changed, 44 insertions(+), 4 deletions(-)
diff --git a/src/Authenticator.php b/src/Authenticator.php
index deb6777..25f009d 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -7,8 +7,10 @@
use Authwave\ProviderUri\LogoutUri;
use Authwave\ProviderUri\ProfileUri;
use Authwave\ResponseData\UserResponseData;
+use Gt\Cipher\InitVector;
use Gt\Cipher\Key;
use Gt\Cipher\Message\EncryptedMessage;
+use Gt\Cipher\Message\PlainTextMessage;
use Gt\Http\Uri;
use Gt\Logger\Log;
use Gt\Session\SessionContainer;
@@ -17,6 +19,7 @@
class Authenticator {
const SESSION_STORE_KEY = "AUTHWAVE_CONSUMER_SESSION";
const RESPONSE_QUERY_PARAMETER = "AUTHWAVE_RESPONSE_DATA";
+ const FAKE_EMAIL = "fakelogin@authwave.com";
private SessionData $sessionData;
private User $user;
@@ -84,9 +87,47 @@ public function logout(Token $token = null):void {
$token = new Token($this->secret);
}
- $this->sessionData = new SessionData($token);
- $this->session->set(SessionData::class, $this->sessionData);
- $this->redirectHandler->redirect($this->getLogoutUri($token));
+ if($this->user->email === self::FAKE_EMAIL) {
+ $this->session->remove(SessionData::class);
+ unset($this->user);
+ }
+ else {
+ $this->redirectHandler->redirect($this->getLogoutUri($token));
+ $this->sessionData = new SessionData($token);
+ $this->session->set(SessionData::class, $this->sessionData);
+ }
+ }
+
+ public function fakeLogin(string $userId, string $redirectTo = "/"):void {
+ $secretIv = new InitVector();
+ $token = new Token($this->secret, $secretIv);
+ $sessionData = new SessionData($token);
+ $this->session->set(SessionData::class, $sessionData);
+
+ $userData = new UserResponseData(
+ $userId,
+ self::FAKE_EMAIL,
+ );
+
+ $this->session->set(
+ SessionData::class,
+ new SessionData($token, $userData)
+ );
+
+ $message = new PlainTextMessage(
+ json_encode([
+ "id" => $userData->getId(),
+ "email" => $userData->getEmail(),
+ ]),
+ $secretIv,
+ );
+
+ $cipherText = $message->encrypt(new Key($this->secret));
+ $queryString = http_build_query([
+ "AUTHWAVE_RESPONSE_DATA" => (string)$cipherText,
+ ]);
+ $uri = new Uri("$redirectTo?$queryString");
+ $this->redirectHandler->redirect($uri);
}
public function getUser():User {
@@ -140,7 +181,6 @@ private function completeAuth():void {
}
if(!isset($this->sessionData)) {
- die("No session data");
$this->tidyResponseData();
return;
}
From d3bf341521ed68fe6a14e03f9719a9b5ec1b9d02 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Mon, 20 Nov 2023 21:21:18 +0000
Subject: [PATCH 16/21] tweak: check property is set before access
---
src/Authenticator.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Authenticator.php b/src/Authenticator.php
index 25f009d..9633494 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -87,7 +87,7 @@ public function logout(Token $token = null):void {
$token = new Token($this->secret);
}
- if($this->user->email === self::FAKE_EMAIL) {
+ if(isset($this->user) && $this->user->email === self::FAKE_EMAIL) {
$this->session->remove(SessionData::class);
unset($this->user);
}
From a6cc9402ab282347a910f1d5159fce690bbe40ac Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Sun, 4 Feb 2024 20:19:43 +0000
Subject: [PATCH 17/21] tweak: get all kvp
---
src/User.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/User.php b/src/User.php
index 1c5784b..06fe970 100644
--- a/src/User.php
+++ b/src/User.php
@@ -11,4 +11,8 @@ public function __construct(
public function getData(string $key):?string {
return $this->kvp[$key] ?? null;
}
+
+ public function getKvp():array {
+ return $this->kvp;
+ }
}
From 7d840530c256a9fa466849f0a6a0527c6f1d775d Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Sun, 4 Feb 2024 21:28:27 +0000
Subject: [PATCH 18/21] tweak: override and remove session data on logout
---
src/Authenticator.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/Authenticator.php b/src/Authenticator.php
index 9633494..52ed98f 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -92,9 +92,10 @@ public function logout(Token $token = null):void {
unset($this->user);
}
else {
- $this->redirectHandler->redirect($this->getLogoutUri($token));
$this->sessionData = new SessionData($token);
$this->session->set(SessionData::class, $this->sessionData);
+ $this->session->remove(SessionData::class);
+ $this->redirectHandler->redirect($this->getLogoutUri($token));
}
}
From 3fca12086ffdbeecb65fa08c9730d3f05c643454 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Fri, 10 May 2024 15:14:05 +0100
Subject: [PATCH 19/21] feature: append existing query string
---
src/Authenticator.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/Authenticator.php b/src/Authenticator.php
index 52ed98f..cac120b 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -127,6 +127,10 @@ public function fakeLogin(string $userId, string $redirectTo = "/"):void {
$queryString = http_build_query([
"AUTHWAVE_RESPONSE_DATA" => (string)$cipherText,
]);
+ if($currentQuery = $this->currentUri->getQuery()) {
+ $queryString .= "&";
+ $queryString .= $currentQuery;
+ }
$uri = new Uri("$redirectTo?$queryString");
$this->redirectHandler->redirect($uri);
}
From 9c8d79c78a48e719d6ed548410badb446cba2952 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Thu, 8 Aug 2024 10:16:12 +0100
Subject: [PATCH 20/21] tweak: pass in email you would like
---
src/Authenticator.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Authenticator.php b/src/Authenticator.php
index cac120b..2c00e76 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -99,7 +99,7 @@ public function logout(Token $token = null):void {
}
}
- public function fakeLogin(string $userId, string $redirectTo = "/"):void {
+ public function fakeLogin(string $userId, ?string $email = null, string $redirectTo = "/"):void {
$secretIv = new InitVector();
$token = new Token($this->secret, $secretIv);
$sessionData = new SessionData($token);
@@ -107,7 +107,7 @@ public function fakeLogin(string $userId, string $redirectTo = "/"):void {
$userData = new UserResponseData(
$userId,
- self::FAKE_EMAIL,
+ $email ?? self::FAKE_EMAIL,
);
$this->session->set(
From 8d3cfe6e0f147f5383dc675d6c75473a71351a36 Mon Sep 17 00:00:00 2001
From: Greg Bowler
Date: Tue, 5 Aug 2025 17:23:39 +0100
Subject: [PATCH 21/21] tweak: allow multiple underscores
---
src/Authenticator.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/Authenticator.php b/src/Authenticator.php
index 2c00e76..3af6259 100644
--- a/src/Authenticator.php
+++ b/src/Authenticator.php
@@ -34,7 +34,8 @@ public function __construct(
private ?SessionContainer $session = null,
private ?RedirectHandler $redirectHandler = null,
) {
- [$this->deploymentId, $this->secret] = explode("_", $clientKey);
+ $this->deploymentId = substr($clientKey, 0, strrpos($clientKey, "_"));
+ $this->secret = substr(strrchr($clientKey, "_"), 1);
$this->session = $this->session ?? new GlobalSessionContainer();
$this->redirectHandler = $redirectHandler ?? new RedirectHandler();