diff --git a/.gitmodules b/.gitmodules
index 54e471399..16b05784f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -3,4 +3,4 @@
url = ssh://git@***REMOVED***/~/_mithril/gradido_mithrilJS_client
[submodule "src/protobuf"]
path = src/protobuf
- url = git@***REMOVED***:~/_protobuf/gradido_protobuf
+ url = ssh://git@***REMOVED***/~/_protobuf/gradido_protobuf
diff --git a/composer.json b/composer.json
index 0f6ba320a..3c5ff0d58 100644
--- a/composer.json
+++ b/composer.json
@@ -18,7 +18,7 @@
"cakephp/cakephp-codesniffer": "^3.0",
"cakephp/debug_kit": "^3.17.0",
"josegonzalez/dotenv": "3.*",
- "phpunit/phpunit": "^5|^6",
+ "phpunit/phpunit": "^5.7|^6.0",
"psy/psysh": "@stable"
},
"suggest": {
diff --git a/composer.lock b/composer.lock
index 8f7349d0c..20505546a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "content-hash": "2944d37824c58c80f9759fff3074fa2d",
+ "content-hash": "de9b091bfb2ef9e30a63a154a97b5d9f",
"packages": [
{
"name": "aura/intl",
@@ -54,16 +54,16 @@
},
{
"name": "cakephp/cakephp",
- "version": "3.8.5",
+ "version": "3.8.6",
"source": {
"type": "git",
"url": "https://github.com/cakephp/cakephp.git",
- "reference": "ea64434740f0d2a53438f95a3de414de63a11101"
+ "reference": "34833a0c02fc1fc21e27ceb69cf7b4f7c131a3cc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/cakephp/cakephp/zipball/ea64434740f0d2a53438f95a3de414de63a11101",
- "reference": "ea64434740f0d2a53438f95a3de414de63a11101",
+ "url": "https://api.github.com/repos/cakephp/cakephp/zipball/34833a0c02fc1fc21e27ceb69cf7b4f7c131a3cc",
+ "reference": "34833a0c02fc1fc21e27ceb69cf7b4f7c131a3cc",
"shasum": ""
},
"require": {
@@ -139,7 +139,7 @@
"rapid-development",
"validation"
],
- "time": "2019-10-07T00:51:50+00:00"
+ "time": "2019-11-07T01:11:43+00:00"
},
{
"name": "cakephp/chronos",
@@ -200,16 +200,16 @@
},
{
"name": "cakephp/migrations",
- "version": "2.3.0",
+ "version": "2.4.0",
"source": {
"type": "git",
"url": "https://github.com/cakephp/migrations.git",
- "reference": "3d1750bb218958b4c48fea1365c619bedea62d69"
+ "reference": "643e54e627e876c10b5ffa1c706a6819aa6a70b9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/cakephp/migrations/zipball/3d1750bb218958b4c48fea1365c619bedea62d69",
- "reference": "3d1750bb218958b4c48fea1365c619bedea62d69",
+ "url": "https://api.github.com/repos/cakephp/migrations/zipball/643e54e627e876c10b5ffa1c706a6819aa6a70b9",
+ "reference": "643e54e627e876c10b5ffa1c706a6819aa6a70b9",
"shasum": ""
},
"require": {
@@ -249,7 +249,7 @@
"cakephp",
"migrations"
],
- "time": "2019-10-07T22:04:21+00:00"
+ "time": "2019-11-10T15:12:59+00:00"
},
{
"name": "cakephp/plugin-installer",
@@ -432,16 +432,16 @@
},
{
"name": "paragonie/sodium_compat",
- "version": "v1.12.0",
+ "version": "v1.12.1",
"source": {
"type": "git",
"url": "https://github.com/paragonie/sodium_compat.git",
- "reference": "8228b286d6b8fe24825f42ce02403f72656ac826"
+ "reference": "063cae9b3a7323579063e7037720f5b52b56c178"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/8228b286d6b8fe24825f42ce02403f72656ac826",
- "reference": "8228b286d6b8fe24825f42ce02403f72656ac826",
+ "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/063cae9b3a7323579063e7037720f5b52b56c178",
+ "reference": "063cae9b3a7323579063e7037720f5b52b56c178",
"shasum": ""
},
"require": {
@@ -510,7 +510,7 @@
"secret-key cryptography",
"side-channel resistant"
],
- "time": "2019-10-19T15:30:42+00:00"
+ "time": "2019-11-07T17:07:24+00:00"
},
{
"name": "psr/container",
@@ -785,32 +785,32 @@
},
{
"name": "symfony/config",
- "version": "v4.3.6",
+ "version": "v4.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "f4ee0ebb91b16ca1ac105aa39f9284f3cac19a15"
+ "reference": "f08e1c48e1f05d07c32f2d8599ed539e62105beb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/f4ee0ebb91b16ca1ac105aa39f9284f3cac19a15",
- "reference": "f4ee0ebb91b16ca1ac105aa39f9284f3cac19a15",
+ "url": "https://api.github.com/repos/symfony/config/zipball/f08e1c48e1f05d07c32f2d8599ed539e62105beb",
+ "reference": "f08e1c48e1f05d07c32f2d8599ed539e62105beb",
"shasum": ""
},
"require": {
"php": "^7.1.3",
- "symfony/filesystem": "~3.4|~4.0",
+ "symfony/filesystem": "^3.4|^4.0|^5.0",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
"symfony/finder": "<3.4"
},
"require-dev": {
- "symfony/dependency-injection": "~3.4|~4.0",
- "symfony/event-dispatcher": "~3.4|~4.0",
- "symfony/finder": "~3.4|~4.0",
- "symfony/messenger": "~4.1",
- "symfony/yaml": "~3.4|~4.0"
+ "symfony/event-dispatcher": "^3.4|^4.0|^5.0",
+ "symfony/finder": "^3.4|^4.0|^5.0",
+ "symfony/messenger": "^4.1|^5.0",
+ "symfony/service-contracts": "^1.1|^2",
+ "symfony/yaml": "^3.4|^4.0|^5.0"
},
"suggest": {
"symfony/yaml": "To use the yaml reference dumper"
@@ -818,7 +818,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.3-dev"
+ "dev-master": "4.4-dev"
}
},
"autoload": {
@@ -845,31 +845,32 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
- "time": "2019-10-30T13:18:51+00:00"
+ "time": "2019-11-16T15:22:42+00:00"
},
{
"name": "symfony/console",
- "version": "v4.3.6",
+ "version": "v4.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "136c4bd62ea871d00843d1bc0316de4c4a84bb78"
+ "reference": "35d9077f495c6d184d9930f7a7ecbd1ad13c7ab8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/136c4bd62ea871d00843d1bc0316de4c4a84bb78",
- "reference": "136c4bd62ea871d00843d1bc0316de4c4a84bb78",
+ "url": "https://api.github.com/repos/symfony/console/zipball/35d9077f495c6d184d9930f7a7ecbd1ad13c7ab8",
+ "reference": "35d9077f495c6d184d9930f7a7ecbd1ad13c7ab8",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8",
- "symfony/service-contracts": "^1.1"
+ "symfony/service-contracts": "^1.1|^2"
},
"conflict": {
"symfony/dependency-injection": "<3.4",
- "symfony/event-dispatcher": "<4.3",
+ "symfony/event-dispatcher": "<4.3|>=5",
+ "symfony/lock": "<4.4",
"symfony/process": "<3.3"
},
"provide": {
@@ -877,12 +878,12 @@
},
"require-dev": {
"psr/log": "~1.0",
- "symfony/config": "~3.4|~4.0",
- "symfony/dependency-injection": "~3.4|~4.0",
+ "symfony/config": "^3.4|^4.0|^5.0",
+ "symfony/dependency-injection": "^3.4|^4.0|^5.0",
"symfony/event-dispatcher": "^4.3",
- "symfony/lock": "~3.4|~4.0",
- "symfony/process": "~3.4|~4.0",
- "symfony/var-dumper": "^4.3"
+ "symfony/lock": "^4.4|^5.0",
+ "symfony/process": "^3.4|^4.0|^5.0",
+ "symfony/var-dumper": "^4.3|^5.0"
},
"suggest": {
"psr/log": "For using the console logger",
@@ -893,7 +894,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.3-dev"
+ "dev-master": "4.4-dev"
}
},
"autoload": {
@@ -920,20 +921,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2019-10-30T12:58:49+00:00"
+ "time": "2019-11-13T07:39:40+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v4.3.6",
+ "version": "v4.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263"
+ "reference": "d12b01cba60be77b583c9af660007211e3909854"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/9abbb7ef96a51f4d7e69627bc6f63307994e4263",
- "reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/d12b01cba60be77b583c9af660007211e3909854",
+ "reference": "d12b01cba60be77b583c9af660007211e3909854",
"shasum": ""
},
"require": {
@@ -943,7 +944,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.3-dev"
+ "dev-master": "4.4-dev"
}
},
"autoload": {
@@ -970,20 +971,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2019-08-20T14:07:54+00:00"
+ "time": "2019-11-12T14:51:11+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.12.0",
+ "version": "v1.13.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "550ebaac289296ce228a706d0867afc34687e3f4"
+ "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4",
- "reference": "550ebaac289296ce228a706d0867afc34687e3f4",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
+ "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
"shasum": ""
},
"require": {
@@ -995,7 +996,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.12-dev"
+ "dev-master": "1.13-dev"
}
},
"autoload": {
@@ -1028,20 +1029,20 @@
"polyfill",
"portable"
],
- "time": "2019-08-06T08:03:45+00:00"
+ "time": "2019-11-27T13:56:44+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.12.0",
+ "version": "v1.13.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17"
+ "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17",
- "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f",
+ "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f",
"shasum": ""
},
"require": {
@@ -1053,7 +1054,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.12-dev"
+ "dev-master": "1.13-dev"
}
},
"autoload": {
@@ -1087,20 +1088,20 @@
"portable",
"shim"
],
- "time": "2019-08-06T08:03:45+00:00"
+ "time": "2019-11-27T14:18:11+00:00"
},
{
"name": "symfony/polyfill-php73",
- "version": "v1.12.0",
+ "version": "v1.13.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
- "reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188"
+ "reference": "4b0e2222c55a25b4541305a053013d5647d3a25f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/2ceb49eaccb9352bff54d22570276bb75ba4a188",
- "reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/4b0e2222c55a25b4541305a053013d5647d3a25f",
+ "reference": "4b0e2222c55a25b4541305a053013d5647d3a25f",
"shasum": ""
},
"require": {
@@ -1109,7 +1110,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.12-dev"
+ "dev-master": "1.13-dev"
}
},
"autoload": {
@@ -1145,24 +1146,24 @@
"portable",
"shim"
],
- "time": "2019-08-06T08:03:45+00:00"
+ "time": "2019-11-27T16:25:15+00:00"
},
{
"name": "symfony/service-contracts",
- "version": "v1.1.7",
+ "version": "v2.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0"
+ "reference": "9d99e1556417bf227a62e14856d630672bf10eaf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ffcde9615dc5bb4825b9f6aed07716f1f57faae0",
- "reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/9d99e1556417bf227a62e14856d630672bf10eaf",
+ "reference": "9d99e1556417bf227a62e14856d630672bf10eaf",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
+ "php": "^7.2.9",
"psr/container": "^1.0"
},
"suggest": {
@@ -1171,7 +1172,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.1-dev"
+ "dev-master": "2.0-dev"
}
},
"autoload": {
@@ -1203,20 +1204,20 @@
"interoperability",
"standards"
],
- "time": "2019-09-17T11:12:18+00:00"
+ "time": "2019-11-09T09:18:34+00:00"
},
{
"name": "symfony/yaml",
- "version": "v4.3.6",
+ "version": "v4.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "324cf4b19c345465fad14f3602050519e09e361d"
+ "reference": "76de473358fe802578a415d5bb43c296cf09d211"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/324cf4b19c345465fad14f3602050519e09e361d",
- "reference": "324cf4b19c345465fad14f3602050519e09e361d",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/76de473358fe802578a415d5bb43c296cf09d211",
+ "reference": "76de473358fe802578a415d5bb43c296cf09d211",
"shasum": ""
},
"require": {
@@ -1227,7 +1228,7 @@
"symfony/console": "<3.4"
},
"require-dev": {
- "symfony/console": "~3.4|~4.0"
+ "symfony/console": "^3.4|^4.0|^5.0"
},
"suggest": {
"symfony/console": "For validating YAML files using the lint command"
@@ -1235,7 +1236,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.3-dev"
+ "dev-master": "4.4-dev"
}
},
"autoload": {
@@ -1262,7 +1263,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2019-10-30T12:58:49+00:00"
+ "time": "2019-11-12T14:51:11+00:00"
},
{
"name": "zendframework/zend-diactoros",
@@ -1549,16 +1550,16 @@
},
{
"name": "cakephp/cakephp-codesniffer",
- "version": "3.1.2",
+ "version": "3.2.1",
"source": {
"type": "git",
"url": "https://github.com/cakephp/cakephp-codesniffer.git",
- "reference": "45a1dcc2e83598362b8c323df3e67510676457fe"
+ "reference": "65ce18f4959d89f0bcbd8d1517734c68606a8186"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/cakephp/cakephp-codesniffer/zipball/45a1dcc2e83598362b8c323df3e67510676457fe",
- "reference": "45a1dcc2e83598362b8c323df3e67510676457fe",
+ "url": "https://api.github.com/repos/cakephp/cakephp-codesniffer/zipball/65ce18f4959d89f0bcbd8d1517734c68606a8186",
+ "reference": "65ce18f4959d89f0bcbd8d1517734c68606a8186",
"shasum": ""
},
"require": {
@@ -1571,7 +1572,7 @@
"type": "phpcodesniffer-standard",
"autoload": {
"psr-4": {
- "CakePHP\\": "CakePHP"
+ "CakePHP\\": "CakePHP/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1585,25 +1586,25 @@
}
],
"description": "CakePHP CodeSniffer Standards",
- "homepage": "http://cakephp.org",
+ "homepage": "https://cakephp.org",
"keywords": [
"codesniffer",
"framework"
],
- "time": "2019-08-30T01:55:00+00:00"
+ "time": "2019-11-20T03:45:19+00:00"
},
{
"name": "cakephp/debug_kit",
- "version": "3.20.5",
+ "version": "3.21.0",
"source": {
"type": "git",
"url": "https://github.com/cakephp/debug_kit.git",
- "reference": "7c399398fc31db2cfad93400c0986a160ddc3834"
+ "reference": "74c289cbd9ee07a531ce813dec744c9f2f472e14"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/cakephp/debug_kit/zipball/7c399398fc31db2cfad93400c0986a160ddc3834",
- "reference": "7c399398fc31db2cfad93400c0986a160ddc3834",
+ "url": "https://api.github.com/repos/cakephp/debug_kit/zipball/74c289cbd9ee07a531ce813dec744c9f2f472e14",
+ "reference": "74c289cbd9ee07a531ce813dec744c9f2f472e14",
"shasum": ""
},
"require": {
@@ -1624,8 +1625,8 @@
"type": "cakephp-plugin",
"autoload": {
"psr-4": {
- "DebugKit\\": "src",
- "DebugKit\\Test\\Fixture\\": "tests\\Fixture"
+ "DebugKit\\": "src/",
+ "DebugKit\\Test\\Fixture\\": "tests/Fixture/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1635,7 +1636,7 @@
"authors": [
{
"name": "Mark Story",
- "homepage": "http://mark-story.com",
+ "homepage": "https://mark-story.com",
"role": "Author"
},
{
@@ -1650,7 +1651,7 @@
"debug",
"kit"
],
- "time": "2019-11-01T01:21:14+00:00"
+ "time": "2019-11-10T02:41:02+00:00"
},
{
"name": "composer/ca-bundle",
@@ -1912,24 +1913,24 @@
},
{
"name": "composer/xdebug-handler",
- "version": "1.3.3",
+ "version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/composer/xdebug-handler.git",
- "reference": "46867cbf8ca9fb8d60c506895449eb799db1184f"
+ "reference": "cbe23383749496fe0f373345208b79568e4bc248"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/46867cbf8ca9fb8d60c506895449eb799db1184f",
- "reference": "46867cbf8ca9fb8d60c506895449eb799db1184f",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/cbe23383749496fe0f373345208b79568e4bc248",
+ "reference": "cbe23383749496fe0f373345208b79568e4bc248",
"shasum": ""
},
"require": {
- "php": "^5.3.2 || ^7.0",
+ "php": "^5.3.2 || ^7.0 || ^8.0",
"psr/log": "^1.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5"
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8"
},
"type": "library",
"autoload": {
@@ -1947,12 +1948,12 @@
"email": "john-stevenson@blueyonder.co.uk"
}
],
- "description": "Restarts a process without xdebug.",
+ "description": "Restarts a process without Xdebug.",
"keywords": [
"Xdebug",
"performance"
],
- "time": "2019-05-27T17:52:04+00:00"
+ "time": "2019-11-06T16:40:04+00:00"
},
{
"name": "dnoegel/php-xdg-base-dir",
@@ -1989,16 +1990,16 @@
},
{
"name": "doctrine/instantiator",
- "version": "1.2.0",
+ "version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
- "reference": "a2c590166b2133a4633738648b6b064edae0814a"
+ "reference": "ae466f726242e637cebdd526a7d991b9433bacf1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a",
- "reference": "a2c590166b2133a4633738648b6b064edae0814a",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1",
+ "reference": "ae466f726242e637cebdd526a7d991b9433bacf1",
"shasum": ""
},
"require": {
@@ -2041,7 +2042,7 @@
"constructor",
"instantiate"
],
- "time": "2019-03-17T17:37:11+00:00"
+ "time": "2019-10-21T16:45:58+00:00"
},
{
"name": "jakub-onderka/php-console-color",
@@ -2468,16 +2469,16 @@
},
{
"name": "nikic/php-parser",
- "version": "v4.2.5",
+ "version": "v4.3.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2"
+ "reference": "9a9981c347c5c49d6dfe5cf826bb882b824080dc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/b76bbc3c51f22c570648de48e8c2d941ed5e2cf2",
- "reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/9a9981c347c5c49d6dfe5cf826bb882b824080dc",
+ "reference": "9a9981c347c5c49d6dfe5cf826bb882b824080dc",
"shasum": ""
},
"require": {
@@ -2485,7 +2486,7 @@
"php": ">=7.0"
},
"require-dev": {
- "ircmaxell/php-yacc": "0.0.4",
+ "ircmaxell/php-yacc": "0.0.5",
"phpunit/phpunit": "^6.5 || ^7.0 || ^8.0"
},
"bin": [
@@ -2494,7 +2495,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
},
"autoload": {
@@ -2516,7 +2517,7 @@
"parser",
"php"
],
- "time": "2019-10-25T18:33:07+00:00"
+ "time": "2019-11-08T13:50:10+00:00"
},
{
"name": "phar-io/manifest",
@@ -3228,16 +3229,16 @@
},
{
"name": "psy/psysh",
- "version": "v0.9.9",
+ "version": "v0.9.11",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
- "reference": "9aaf29575bb8293206bb0420c1e1c87ff2ffa94e"
+ "reference": "75d9ac1c16db676de27ab554a4152b594be4748e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/bobthecow/psysh/zipball/9aaf29575bb8293206bb0420c1e1c87ff2ffa94e",
- "reference": "9aaf29575bb8293206bb0420c1e1c87ff2ffa94e",
+ "url": "https://api.github.com/repos/bobthecow/psysh/zipball/75d9ac1c16db676de27ab554a4152b594be4748e",
+ "reference": "75d9ac1c16db676de27ab554a4152b594be4748e",
"shasum": ""
},
"require": {
@@ -3247,8 +3248,8 @@
"jakub-onderka/php-console-highlighter": "0.3.*|0.4.*",
"nikic/php-parser": "~1.3|~2.0|~3.0|~4.0",
"php": ">=5.4.0",
- "symfony/console": "~2.3.10|^2.4.2|~3.0|~4.0",
- "symfony/var-dumper": "~2.7|~3.0|~4.0"
+ "symfony/console": "~2.3.10|^2.4.2|~3.0|~4.0|~5.0",
+ "symfony/var-dumper": "~2.7|~3.0|~4.0|~5.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.2",
@@ -3298,7 +3299,7 @@
"interactive",
"shell"
],
- "time": "2018-10-13T15:16:03+00:00"
+ "time": "2019-11-27T22:44:29+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
@@ -4005,16 +4006,16 @@
},
{
"name": "symfony/finder",
- "version": "v4.3.6",
+ "version": "v4.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "72a068f77e317ae77c0a0495236ad292cfb5ce6f"
+ "reference": "ce8743441da64c41e2a667b8eb66070444ed911e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/72a068f77e317ae77c0a0495236ad292cfb5ce6f",
- "reference": "72a068f77e317ae77c0a0495236ad292cfb5ce6f",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/ce8743441da64c41e2a667b8eb66070444ed911e",
+ "reference": "ce8743441da64c41e2a667b8eb66070444ed911e",
"shasum": ""
},
"require": {
@@ -4023,7 +4024,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.3-dev"
+ "dev-master": "4.4-dev"
}
},
"autoload": {
@@ -4050,75 +4051,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2019-10-30T12:53:54+00:00"
- },
- {
- "name": "symfony/polyfill-php72",
- "version": "v1.12.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php72.git",
- "reference": "04ce3335667451138df4307d6a9b61565560199e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/04ce3335667451138df4307d6a9b61565560199e",
- "reference": "04ce3335667451138df4307d6a9b61565560199e",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.12-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Php72\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "time": "2019-08-06T08:03:45+00:00"
+ "time": "2019-11-17T21:56:56+00:00"
},
{
"name": "symfony/process",
- "version": "v4.3.6",
+ "version": "v4.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "3b2e0cb029afbb0395034509291f21191d1a4db0"
+ "reference": "75ad33d9b6f25325ebc396d68ad86fd74bcfbb06"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/3b2e0cb029afbb0395034509291f21191d1a4db0",
- "reference": "3b2e0cb029afbb0395034509291f21191d1a4db0",
+ "url": "https://api.github.com/repos/symfony/process/zipball/75ad33d9b6f25325ebc396d68ad86fd74bcfbb06",
+ "reference": "75ad33d9b6f25325ebc396d68ad86fd74bcfbb06",
"shasum": ""
},
"require": {
@@ -4127,7 +4073,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.3-dev"
+ "dev-master": "4.4-dev"
}
},
"autoload": {
@@ -4154,36 +4100,35 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2019-10-28T17:07:32+00:00"
+ "time": "2019-10-28T20:30:34+00:00"
},
{
"name": "symfony/var-dumper",
- "version": "v4.3.6",
+ "version": "v5.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "ea4940845535c85ff5c505e13b3205b0076d07bf"
+ "reference": "956b8b6e4c52186695f592286414601abfcec284"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ea4940845535c85ff5c505e13b3205b0076d07bf",
- "reference": "ea4940845535c85ff5c505e13b3205b0076d07bf",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/956b8b6e4c52186695f592286414601abfcec284",
+ "reference": "956b8b6e4c52186695f592286414601abfcec284",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/polyfill-mbstring": "~1.0",
- "symfony/polyfill-php72": "~1.5"
+ "php": "^7.2.5",
+ "symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
- "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
- "symfony/console": "<3.4"
+ "phpunit/phpunit": "<5.4.3",
+ "symfony/console": "<4.4"
},
"require-dev": {
"ext-iconv": "*",
- "symfony/console": "~3.4|~4.0",
- "symfony/process": "~3.4|~4.0",
- "twig/twig": "~1.34|~2.4"
+ "symfony/console": "^4.4|^5.0",
+ "symfony/process": "^4.4|^5.0",
+ "twig/twig": "^2.4|^3.0"
},
"suggest": {
"ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
@@ -4196,7 +4141,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.3-dev"
+ "dev-master": "5.0-dev"
}
},
"autoload": {
@@ -4230,7 +4175,7 @@
"debug",
"dump"
],
- "time": "2019-10-13T12:02:04+00:00"
+ "time": "2019-11-18T17:27:11+00:00"
},
{
"name": "theseer/tokenizer",
@@ -4274,16 +4219,16 @@
},
{
"name": "twig/twig",
- "version": "v1.42.3",
+ "version": "v1.42.4",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "201baee843e0ffe8b0b956f336dd42b2a92fae4e"
+ "reference": "e587180584c3d2d6cb864a0454e777bb6dcb6152"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/201baee843e0ffe8b0b956f336dd42b2a92fae4e",
- "reference": "201baee843e0ffe8b0b956f336dd42b2a92fae4e",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/e587180584c3d2d6cb864a0454e777bb6dcb6152",
+ "reference": "e587180584c3d2d6cb864a0454e777bb6dcb6152",
"shasum": ""
},
"require": {
@@ -4336,7 +4281,7 @@
"keywords": [
"templating"
],
- "time": "2019-08-24T12:51:03+00:00"
+ "time": "2019-11-11T16:49:32+00:00"
},
{
"name": "umpirsky/twig-php-function",
@@ -4381,31 +4326,29 @@
},
{
"name": "webmozart/assert",
- "version": "1.5.0",
+ "version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
- "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4"
+ "reference": "573381c0a64f155a0d9a23f4b0c797194805b925"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4",
- "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925",
+ "reference": "573381c0a64f155a0d9a23f4b0c797194805b925",
"shasum": ""
},
"require": {
"php": "^5.3.3 || ^7.0",
"symfony/polyfill-ctype": "^1.8"
},
+ "conflict": {
+ "vimeo/psalm": "<3.6.0"
+ },
"require-dev": {
"phpunit/phpunit": "^4.8.36 || ^7.5.13"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.3-dev"
- }
- },
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
@@ -4427,7 +4370,7 @@
"check",
"validate"
],
- "time": "2019-08-24T08:43:50+00:00"
+ "time": "2019-11-24T13:36:37+00:00"
},
{
"name": "wyrihaximus/twig-view",
diff --git a/config/bootstrap.php b/config/bootstrap.php
index 1c266a499..c57f81374 100644
--- a/config/bootstrap.php
+++ b/config/bootstrap.php
@@ -114,7 +114,9 @@ ini_set('intl.default_locale', Configure::read('App.defaultLocale'));
/*
* Register application error and exception handlers.
*/
+
$isCli = PHP_SAPI === 'cli';
+
if ($isCli) {
(new ConsoleErrorHandler(Configure::read('Error')))->register();
} else {
diff --git a/src/Controller/AddressTypesController.php b/src/Controller/AddressTypesController.php
index 92bfad6c8..348a8e9e6 100644
--- a/src/Controller/AddressTypesController.php
+++ b/src/Controller/AddressTypesController.php
@@ -2,6 +2,7 @@
namespace App\Controller;
use App\Controller\AppController;
+use Cake\I18n\Number;
/**
* AddressTypes Controller
diff --git a/src/Controller/AppController.php b/src/Controller/AppController.php
index 9c43e6d69..04762e14f 100644
--- a/src/Controller/AppController.php
+++ b/src/Controller/AppController.php
@@ -15,7 +15,11 @@
namespace App\Controller;
use Cake\Controller\Controller;
-use Cake\Event\Event;
+//use Cake\Event\Event;
+use Cake\Http\Client;
+use Cake\Routing\Router;
+use Cake\ORM\TableRegistry;
+use Cake\Core\Configure;
/**
* Application Controller
@@ -75,7 +79,151 @@ class AppController extends Controller
* see https://book.cakephp.org/3.0/en/controllers/components/security.html
*/
//$this->loadComponent('Security');
+
+
+ // load current balance
+ $session = $this->getRequest()->getSession();
+ $state_user_id = $session->read('StateUser.id');
+ if($state_user_id) {
+ $stateBalancesTable = TableRegistry::getTableLocator()->get('stateBalances');
+ $stateBalanceQuery = $stateBalancesTable
+ ->find('all')
+ ->select('amount')
+ ->contain(false)
+ ->where(['state_user_id' => $state_user_id]);
+ if($stateBalanceQuery->count() == 1) {
+ //var_dump($stateBalanceEntry->first());
+ $session->write('StateUser.balance', $stateBalanceQuery->first()->amount);
+ //echo "stateUser.balance: " . $session->read('StateUser.balance');
+ }
+ }
+
+ // load error count
+ if($state_user_id) {
+ $stateErrorsTable = TableRegistry::getTableLocator()->get('stateErrors');
+ $stateErrorQuery = $stateErrorsTable
+ ->find('all')
+ ->select('id')
+ ->contain(false)
+ ->where(['state_user_id' => $state_user_id]);
+ $session->write('StateUser.errorCount', $stateErrorQuery->count());
+ }
+ //echo "initialize";
+
+
+ // put current page into global for navi
+ $GLOBALS["passed"] = null;
+ $side = $this->request->getParam('controller');
+ $GLOBALS["side"] = $side;
+ $subside = $this->request->getParam('action');
+ $passedArguments = $this->request->getParam('pass');
+ if($passedArguments) {
+ $GLOBALS["passed"] = $passedArguments[0];
+ }
+ $GLOBALS["subside"] = $subside;
+
+
}
+
+ protected function requestLogin()
+ {
+ $session = $this->getRequest()->getSession();
+ // check login
+ // disable encryption for cookies
+ //$this->Cookie->configKey('User', 'encryption', false);
+ $session_id = intval($this->request->getCookie('GRADIDO_LOGIN', ''));
+ $ip = $this->request->clientIp();
+ if(!$session->check('client_ip')) {
+ $session->write('client_ip', $ip);
+ }
+ // login server cannot detect host ip
+ // TODO: update login server, recognize nginx real ip header
+
+ if($session_id != 0) {
+ $userStored = $session->read('StateUser');
+ $transactionPendings = $session->read('Transactions.pending');
+ if($session->read('session_id') != $session_id ||
+ ( $userStored && !isset($userStored['id'])) ||
+ intval($transactionPendings) > 0) {
+ $http = new Client();
+ try {
+ $loginServer = Configure::read('LoginServer');
+ $url = $loginServer['host'] . ':' . $loginServer['port'];
+
+ $response = $http->get($url . '/login', ['session_id' => $session_id]);
+ $json = $response->getJson();
+
+ if(isset($json) && count($json) > 0) {
+
+ if($json['state'] === 'success' && intval($json['user']['email_checked']) === 1) {
+ //echo "email checked: " . $json['user']['email_checked'] . ";
";
+ $session->destroy();
+ foreach($json['user'] as $key => $value) {
+ $session->write('StateUser.' . $key, $value );
+ }
+
+ $transactionPendings = $json['Transaction.pending'];
+ //echo "read transaction pending: $transactionPendings
";
+ $session->write('Transactions.pending', $transactionPendings);
+ $session->write('session_id', $session_id);
+ $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
+ if($json['user']['public_hex'] != '') {
+ $public_key_bin = hex2bin($json['user']['public_hex']);
+ $stateUserQuery = $stateUserTable
+ ->find('all')
+ ->where(['public_key' => $public_key_bin])
+ ->contain(['StateBalances']);
+ if($stateUserQuery->count() == 1) {
+ $stateUser = $stateUserQuery->first();
+ if($stateUser->first_name != $json['user']['first_name'] ||
+ $stateUser->last_name != $json['user']['last_name'] ||
+ $stateUser->email != $json['user']['email']) {
+ $stateUser->first_name = $json['user']['first_name'];
+ $stateUser->last_name = $json['user']['last_name'];
+ $stateUser->email = $json['user']['email'];
+ if(!$stateUserTable->save($stateUser)) {
+ $this->Flash->error(__('error updating state user ' . json_encode($stateUser->errors())));
+ }
+ }
+ //var_dump($stateUser);
+ if(count($stateUser->state_balances) > 0) {
+ $session->write('StateUser.balance', $stateUser->state_balances[0]->amount);
+ }
+ $session->write('StateUser.id', $stateUser->id);
+ //echo $stateUser['id'];
+ } else {
+ $newStateUser = $stateUserTable->newEntity();
+ $newStateUser->public_key = $public_key_bin;
+ $newStateUser->first_name = $json['user']['first_name'];
+ $newStateUser->last_name = $json['user']['last_name'];
+ if(!$stateUserTable->save($newStateUser)) {
+ $this->Flash->error(__('error saving state user ' . json_encode($newStateUser->errors())));
+ }
+ $session->write('StateUser.id', $newStateUser->id);
+ //echo $newStateUser->id;
+ }
+ }
+ } else {
+ if($json['state'] === 'not found' ) {
+ $this->Flash->error(__('invalid session'));
+ return $this->redirect(Router::url('/', true) . 'account/', 303);
+ }
+ }
+ }
+ } catch(\Exception $e) {
+ $msg = $e->getMessage();
+ $this->Flash->error(__('error http request: ') . $msg);
+ return $this->redirect(['controller' => 'Dashboard', 'action' => 'errorHttpRequest']);
+ //continue;
+ }
+ }
+ } else {
+ // no login
+ return $this->redirect(Router::url('/', true) . 'account/', 303);
+ }
+ return true;
+ }
+
/*
public function beforeFilter(Event $event)
{
@@ -83,6 +231,12 @@ class AppController extends Controller
}
*/
+ public function returnJsonEncoded($json) {
+ $this->autoRender = false;
+ $response = $this->response->withType('application/json');
+ return $response->withStringBody($json);
+ }
+
public function returnJson($array) {
$this->autoRender = false;
$response = $this->response->withType('application/json');
diff --git a/src/Controller/Component/GradidoNumberComponent.php b/src/Controller/Component/GradidoNumberComponent.php
new file mode 100644
index 000000000..5db208c3a
--- /dev/null
+++ b/src/Controller/Component/GradidoNumberComponent.php
@@ -0,0 +1,33 @@
+Auth->allow(['add', 'edit']);
- $this->Auth->allow('index');
+ $this->Auth->allow(['index', 'errorHttpRequest']);
}
/**
* Index method
@@ -33,101 +31,25 @@ class DashboardController extends AppController
$startTime = microtime(true);
$this->viewBuilder()->setLayout('frontend');
$session = $this->getRequest()->getSession();
- // check login
- // disable encryption for cookies
- //$this->Cookie->configKey('User', 'encryption', false);
- //$this->Cookie->read('GRADIDO_LOGIN');
- $session_id = intval($this->request->getCookie('GRADIDO_LOGIN', ''));
- $ip = $this->request->clientIp();
- if(!$session->check('client_ip')) {
- $session->write('client_ip', $ip);
- }
- // login server cannot detect host ip
- //echo "client ip: $ip
";
- //echo $session_id; echo "
";
- //echo $session->read('session_id');
- if($session_id != 0) {
- $userStored = $session->read('StateUser');
- $transactionPendings = $session->read('Transactions.pending');
- if($session->read('session_id') != $session_id ||
- ( $userStored && !isset($userStored['id'])) ||
- intval($transactionPendings) > 0) {
- $http = new Client();
- try {
- $loginServer = Configure::read('LoginServer');
- $url = $loginServer['host'] . ':' . $loginServer['port'];
- //$url = 'http://***REMOVED***';
- $response = $http->get($url . '/login', ['session_id' => $session_id]);
- $json = $response->getJson();
-
- if(isset($json) && count($json) > 0) {
-
- if($json['state'] === 'success' && intval($json['user']['email_checked']) === 1) {
- //echo "email checked: " . $json['user']['email_checked'] . ";
";
- $session->destroy();
- foreach($json['user'] as $key => $value) {
- if($key === 'state') { continue; }
- $session->write('StateUser.' . $key, $value );
- }
- $transactionPendings = $json['Transaction.pending'];
- $session->write('Transaction.pending', $transactionPendings);
- $session->write('session_id', $session_id);
- $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
- if($json['user']['public_hex'] != '') {
- $public_key_bin = hex2bin($json['user']['public_hex']);
- $stateUserQuery = $stateUserTable->find('all')->where(['public_key' => $public_key_bin]);
- if($stateUserQuery->count() == 1) {
- $stateUser = $stateUserQuery->first();
- $session->write('StateUser.id', $stateUser['id']);
- //echo $stateUser['id'];
- } else {
- $newStateUser = $stateUserTable->newEntity();
- $newStateUser->public_key = $public_key_bin;
- $newStateUser->first_name = $json['user']['first_name'];
- $newStateUser->last_name = $json['user']['last_name'];
- $stateUserTable->save($newStateUser);
- $session->write('StateUser.id', $newStateUser->id);
- //echo $newStateUser->id;
- }
- }
-
-
-
- // for debugging
-
- $this->set('user', $json['user']);
- //$this->set('json', $json);
- $this->set('timeUsed', microtime(true) - $startTime);
-
- } else {
- if($json['state'] === 'not found' ) {
- $this->Flash->error(__('invalid session'));
- //echo $json['user']['email_checked'];
- //var_dump($json);
- //
- return $this->redirect(Router::url('/', true) . 'account/', 303);
- }
- }
- }
-
- } catch(\Exception $e) {
- $msg = $e->getMessage();
- $this->Flash->error(__('error http request: ') . $msg);
-
- //continue;
- }
- } else {
- // login already in session
- $user = $session->read('StateUser');
- $this->set('user', $user);
- $this->set('timeUsed', microtime(true) - $startTime);
- }
-
- } else {
- // no login
- return $this->redirect(Router::url('/', true) . 'account/', 303);
+
+ //return $this->redirect(Router::url('/', true) . 'account/', 303);
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $result;
}
+ $user = $session->read('StateUser');
+
+ $this->set('user', $user);
+ $this->set('timeUsed', microtime(true) - $startTime);
+
+ }
+
+ public function errorHttpRequest()
+ {
+ $startTime = microtime(true);
+ $this->viewBuilder()->setLayout('frontend');
+ $this->set('timeUsed', microtime(true) - $startTime);
}
diff --git a/src/Controller/StateBalancesController.php b/src/Controller/StateBalancesController.php
index 20580fcf4..78478c45c 100644
--- a/src/Controller/StateBalancesController.php
+++ b/src/Controller/StateBalancesController.php
@@ -1,6 +1,7 @@
Auth->allow(['add', 'edit']);
+ $this->Auth->allow(['overview']);
+ }
/**
* Index method
*
@@ -26,6 +34,100 @@ class StateBalancesController extends AppController
$this->set(compact('stateBalances'));
}
+
+ public function overview()
+ {
+ $startTime = microtime(true);
+ $this->viewBuilder()->setLayout('frontend_ripple');
+ $session = $this->getRequest()->getSession();
+ $user = $session->read('StateUser');
+// var_dump($user);
+ if(!$user) {
+ //return $this->redirect(Router::url('/', true) . 'account/', 303);
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $result;
+ }
+ $user = $session->read('StateUser');
+ }
+
+ $creationsTable = TableRegistry::getTableLocator()->get('TransactionCreations');
+ $creationTransactions = $creationsTable
+ ->find('all')
+ ->where(['state_user_id' => $user['id']])
+ ->contain(['Transactions']);
+
+ $transferTable = TableRegistry::getTableLocator()->get('TransactionSendCoins');
+ $transferTransactions = $transferTable
+ ->find('all')
+ ->where(['OR' => ['state_user_id' => $user['id'], 'receiver_user_id' => $user['id']]])
+ ->contain(['Transactions']);
+
+ $involvedUserIds = [];
+ foreach($transferTransactions as $sendCoins) {
+ if($sendCoins->state_user_id != $user['id']) {
+ array_push($involvedUserIds, intval($sendCoins->state_user_id));
+ } else if($sendCoins->receiver_user_id != $user['id']) {
+ array_push($involvedUserIds, intval($sendCoins->receiver_user_id));
+ }
+ }
+ // exchange key with values and drop duplicates
+ $involvedUser_temp = array_flip($involvedUserIds);
+ // exchange back
+ $involvedUserIds = array_flip($involvedUser_temp);
+ $userTable = TableRegistry::getTableLocator()->get('StateUsers');
+ $involvedUser = $userTable->find('all', [
+ 'contain' => false,
+ 'where' => ['id IN' => $involvedUserIds],
+ 'fields' => ['id', 'first_name', 'last_name', 'email']
+ ]);
+ $involvedUserIndices = [];
+ foreach($involvedUser as $involvedUser) {
+ $involvedUserIndices[$involvedUser->id] = $involvedUser;
+ }
+
+ // sender or receiver when user has sended money
+ // group name if creation
+ // type: gesendet / empfangen / geschöpft
+ // transaktion nr / id
+ // date
+ // balance
+
+ $transactions = [];
+ foreach($creationTransactions as $creation) {
+ //var_dump($creation);
+ array_push($transactions, [
+ 'name' => 'Gradido Akademie',
+ 'type' => 'creation',
+ 'transaction_id' => $creation->transaction_id,
+ 'date' => $creation->transaction->received,
+ 'balance' => $creation->amount
+ ]);
+ }
+
+ foreach($transferTransactions as $sendCoins) {
+ $type = '';
+ $otherUser = null;
+ if($sendCoins->state_user_id == $user['id']) {
+ $type = 'send';
+ $otherUser = $involvedUserIndices[$sendCoins->receiver_user_id];
+ } else if($sendCoins->receiver_user_id == $user['id']) {
+ $type = 'receive';
+ $otherUser = $involvedUserIndices[$sendCoins->state_user_id];
+ }
+ array_push($transactions, [
+ 'name' => $otherUser->first_name . ' ' . $otherUser->last_name,
+ 'email' => $otherUser->email,
+ 'type' => $type,
+ 'transaction_id' => $sendCoins->transaction_id,
+ 'date' => $sendCoins->transaction->received,
+ 'balance' => $sendCoins->amount
+ ]);
+ }
+ $this->set('transactions', $transactions);
+ $this->set('balance', $session->read('StateUser.balance'));
+ $this->set('timeUsed', microtime(true) - $startTime);
+ }
/**
* View method
diff --git a/src/Controller/StateErrorsController.php b/src/Controller/StateErrorsController.php
new file mode 100644
index 000000000..2932b80e6
--- /dev/null
+++ b/src/Controller/StateErrorsController.php
@@ -0,0 +1,164 @@
+Auth->allow(['showForUser', 'deleteForUser']);
+ }
+
+ /**
+ * Index method
+ *
+ * @return \Cake\Http\Response|null
+ */
+ public function index()
+ {
+ $this->paginate = [
+ 'contain' => ['StateUsers', 'TransactionTypes']
+ ];
+ $stateErrors = $this->paginate($this->StateErrors);
+
+ $this->set(compact('stateErrors'));
+ }
+
+ public function showForUser()
+ {
+ $startTime = microtime(true);
+ $this->viewBuilder()->setLayout('frontend');
+ $session = $this->getRequest()->getSession();
+ $user = $session->read('StateUser');
+ if(!$user) {
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $result;
+ }
+ $user = $session->read('StateUser');
+ }
+
+ $errors = $this->StateErrors->find('all')->where(['state_user_id' => $user['id']])->contain(false);
+ $transactionTypes = $this->StateErrors->TransactionTypes->find('all')->select(['id', 'name', 'text']);
+
+ $this->set('errors', $errors);
+ $this->set('transactionTypes', $transactionTypes->toList());
+ $this->set('timeUsed', microtime(true) - $startTime);
+ }
+
+ public function deleteForUser($id = null)
+ {
+ $this->request->allowMethod(['post', 'delete', 'get']);
+ $stateError = $this->StateErrors->get($id);
+ $session = $this->getRequest()->getSession();
+ $user = $session->read('StateUser');
+ if($user['id'] != $stateError->state_user_id) {
+ $this->Flash->error(__('Error belongs to another User, cannot delete'));
+ }
+ else if ($this->StateErrors->delete($stateError)) {
+ $this->Flash->success(__('The state error has been deleted.'));
+ } else {
+ $this->Flash->error(__('The state error could not be deleted. Please, try again.'));
+ }
+ $errors = $this->StateErrors->find('all')->where(['state_user_id' => $user['id']])->contain(false);
+ if($errors->count() == 0) {
+ return $this->redirect(['controller' => 'Dashboard']);
+ }
+ return $this->redirect(['action' => 'showForUser']);
+ }
+
+
+ /**
+ * View method
+ *
+ * @param string|null $id State Error id.
+ * @return \Cake\Http\Response|null
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function view($id = null)
+ {
+ $stateError = $this->StateErrors->get($id, [
+ 'contain' => ['StateUsers', 'TransactionTypes']
+ ]);
+
+ $this->set('stateError', $stateError);
+ }
+
+ /**
+ * Add method
+ *
+ * @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
+ */
+ public function add()
+ {
+ $stateError = $this->StateErrors->newEntity();
+ if ($this->request->is('post')) {
+ $stateError = $this->StateErrors->patchEntity($stateError, $this->request->getData());
+ if ($this->StateErrors->save($stateError)) {
+ $this->Flash->success(__('The state error has been saved.'));
+
+ return $this->redirect(['action' => 'index']);
+ }
+ $this->Flash->error(__('The state error could not be saved. Please, try again.'));
+ }
+ $stateUsers = $this->StateErrors->StateUsers->find('list', ['limit' => 200]);
+ $transactionTypes = $this->StateErrors->TransactionTypes->find('list', ['limit' => 200]);
+ $this->set(compact('stateError', 'stateUsers', 'transactionTypes'));
+ }
+
+ /**
+ * Edit method
+ *
+ * @param string|null $id State Error id.
+ * @return \Cake\Http\Response|null Redirects on successful edit, renders view otherwise.
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function edit($id = null)
+ {
+ $stateError = $this->StateErrors->get($id, [
+ 'contain' => []
+ ]);
+ if ($this->request->is(['patch', 'post', 'put'])) {
+ $stateError = $this->StateErrors->patchEntity($stateError, $this->request->getData());
+ if ($this->StateErrors->save($stateError)) {
+ $this->Flash->success(__('The state error has been saved.'));
+
+ return $this->redirect(['action' => 'index']);
+ }
+ $this->Flash->error(__('The state error could not be saved. Please, try again.'));
+ }
+ $stateUsers = $this->StateErrors->StateUsers->find('list', ['limit' => 200]);
+ $transactionTypes = $this->StateErrors->TransactionTypes->find('list', ['limit' => 200]);
+ $this->set(compact('stateError', 'stateUsers', 'transactionTypes'));
+ }
+
+ /**
+ * Delete method
+ *
+ * @param string|null $id State Error id.
+ * @return \Cake\Http\Response|null Redirects to index.
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function delete($id = null)
+ {
+ $this->request->allowMethod(['post', 'delete']);
+ $stateError = $this->StateErrors->get($id);
+ if ($this->StateErrors->delete($stateError)) {
+ $this->Flash->success(__('The state error has been deleted.'));
+ } else {
+ $this->Flash->error(__('The state error could not be deleted. Please, try again.'));
+ }
+
+ return $this->redirect(['action' => 'index']);
+ }
+}
diff --git a/src/Controller/TransactionCreationsController.php b/src/Controller/TransactionCreationsController.php
index 5e312b4e7..8921493cd 100644
--- a/src/Controller/TransactionCreationsController.php
+++ b/src/Controller/TransactionCreationsController.php
@@ -4,7 +4,7 @@ namespace App\Controller;
use App\Controller\AppController;
use Cake\ORM\TableRegistry;
use Cake\Routing\Router;
-use Cake\I18n\Number;
+//use Cake\I18n\Number;
use Cake\Http\Client;
use Cake\Core\Configure;
@@ -13,6 +13,7 @@ use App\Form\CreationForm;
use Model\Messages\Gradido\TransactionCreation;
use Model\Messages\Gradido\TransactionBody;
use Model\Messages\Gradido\ReceiverAmount;
+use Model\Messages\Gradido\TimestampSeconds;
/**
* TransactionCreations Controller
*
@@ -26,8 +27,9 @@ class TransactionCreationsController extends AppController
public function initialize()
{
parent::initialize();
+ $this->loadComponent('GradidoNumber');
//$this->Auth->allow(['add', 'edit']);
- $this->Auth->allow('create');
+ //$this->Auth->allow('create');
}
/**
* Index method
@@ -68,7 +70,12 @@ class TransactionCreationsController extends AppController
$user = $session->read('StateUser');
// var_dump($user);
if(!$user) {
- return $this->redirect(Router::url('/', true) . 'account/', 303);
+ //return $this->redirect(Router::url('/', true) . 'account/', 303);
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $result;
+ }
+ $user = $session->read('StateUser');
}
$creationForm = new CreationForm();
$transactionCreation = $this->TransactionCreations->newEntity();
@@ -98,12 +105,9 @@ class TransactionCreationsController extends AppController
$pubKeyHex = '';
$receiver = new ReceiverAmount();
- //echo 'amount: ' . $requestData['amount'] . '
';
- $floatAmount = floatval(Number::format($requestData['amount'], ['places' => 4, 'locale' => 'en_GB']));
- //echo 'set for receiver: ' . round($floatAmount * 10000) . '
';
- $receiver->setAmount(round($floatAmount * 10000));
- //echo 'after receiver amount set
';
-
+
+ $receiver->setAmount($this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']));
+
if(intval($requestData['receiver']) == 0) {
if(strlen($requestData['receiver_pubkey_hex']) != 64) {
$this->Flash->error(__('Invalid public Key, must contain 64 Character'));
@@ -118,11 +122,18 @@ class TransactionCreationsController extends AppController
}
}
if($pubKeyHex != '') {
- $receiver->setEd25519ReceiverPubkey(hex2bin($pubKeyHex));
+ $pubKeyBin = hex2bin($pubKeyHex);
+
+ $receiver->setEd25519ReceiverPubkey($pubKeyBin);
//var_dump($requestData);
+
+ $creationDate = new TimestampSeconds();
+ $creationDate->setSeconds(time());
+
$transactionBody = new TransactionBody();
$transactionBody->setMemo($requestData['memo']);
-
+ $transactionBody->setCreated($creationDate);
+
$transaction = new TransactionCreation();
$transaction->setReceiverAmount($receiver);
$transaction->setIdentHash($user['ident_hash']);
diff --git a/src/Controller/TransactionJsonRequestHandlerController.php b/src/Controller/TransactionJsonRequestHandlerController.php
new file mode 100644
index 000000000..78b7662b3
--- /dev/null
+++ b/src/Controller/TransactionJsonRequestHandlerController.php
@@ -0,0 +1,87 @@
+Auth->allow(['add', 'edit']);
+ $this->Auth->allow('index');
+ }
+
+
+ public function index()
+ {
+ if($this->request->is('post')) {
+ $jsonData = $this->request->input('json_decode');
+ //var_dump($jsonData);
+ if($jsonData == NULL || !isset($jsonData->method) || !isset($jsonData->transaction)) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'parameter error']);
+ }
+ $method = $jsonData->method;
+ switch($method) {
+ case 'putTransaction': return $this->putTransaction($jsonData->transaction);
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'unknown method', 'details' => $method]);
+ }
+ return $this->returnJson(['state' => 'error', 'msg' => 'no post']);
+ }
+
+ private function putTransaction($transactionBase64) {
+ $transaction = new Transaction($transactionBase64);
+ if($transaction->hasErrors()) {
+ return $this->returnJson(['state' => 'error', 'msg' => 'error parsing transaction', 'details' => $transaction->getErrors()]);
+ }
+ if(!$transaction->validate()) {
+ return $this->returnJsonSaveError($transaction, ['state' => 'error', 'msg' => 'error validate transaction', 'details' => $transaction->getErrors()]);
+ }
+
+ if ($transaction->save()) {
+ // success
+ return $this->returnJson(['state' => 'success']);
+ } else {
+ return $this->returnJsonSaveError($transaction, [
+ 'state' => 'error',
+ 'msg' => 'error saving transaction in db',
+ 'details' => json_encode($transaction->getErrors())
+ ]);
+ }
+
+ return $this->returnJson(['state' => 'success']);
+ }
+
+
+ private function returnJsonSaveError($transaction, $errorArray) {
+ $json = json_encode($errorArray);
+ $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
+ $pub = $transaction->getFirstPublic();
+ $stateUserQuery = $stateUserTable
+ ->find('all')
+ ->where(['public_key' => $pub])
+ ->contain(false);
+ if($stateUserQuery->count() == 1) {
+ $stateErrorsTable = TableRegistry::getTableLocator()->get('StateErrors');
+ $stateErrorEntity = $stateErrorsTable->newEntity();
+ $stateErrorEntity->state_user_id = $stateUserQuery->first()->id;
+ $stateErrorEntity->transaction_type_id = $transaction->getTransactionBody()->getTransactionTypeId();
+ $stateErrorEntity->message_json = $json;
+ $stateErrorsTable->save($stateErrorEntity);
+ }
+ return $this->returnJsonEncoded($json);
+ }
+
+}
\ No newline at end of file
diff --git a/src/Controller/TransactionSendCoinsController.php b/src/Controller/TransactionSendCoinsController.php
index 491f6ddb5..085b34f59 100644
--- a/src/Controller/TransactionSendCoinsController.php
+++ b/src/Controller/TransactionSendCoinsController.php
@@ -2,6 +2,7 @@
namespace App\Controller;
use App\Controller\AppController;
+use App\Form\CreationForm;
/**
* TransactionSendCoins Controller
@@ -12,6 +13,15 @@ use App\Controller\AppController;
*/
class TransactionSendCoinsController extends AppController
{
+
+ public function initialize()
+ {
+ parent::initialize();
+ $this->loadComponent('GradidoNumber');
+ //$this->Auth->allow(['add', 'edit']);
+ $this->Auth->allow('create');
+ }
+
/**
* Index method
*
@@ -92,6 +102,30 @@ class TransactionSendCoinsController extends AppController
$receiverUsers = $this->TransactionSendCoins->ReceiverUsers->find('list', ['limit' => 200]);
$this->set(compact('transactionSendCoin', 'transactions', 'stateUsers', 'receiverUsers'));
}
+
+ public function create()
+ {
+ $startTime = microtime(true);
+ $this->viewBuilder()->setLayout('frontend_ripple');
+ $session = $this->getRequest()->getSession();
+ $user = $session->read('StateUser');
+// var_dump($user);
+ if(!$user) {
+ //return $this->redirect(Router::url('/', true) . 'account/', 303);
+ $result = $this->requestLogin();
+ if($result !== true) {
+ return $result;
+ }
+ $user = $session->read('StateUser');
+ }
+ if ($this->request->is('post')) {
+ $this->Flash->error(__('Wird zurzeit noch entwickelt!'));
+ }
+
+ $creationForm = new CreationForm();
+ $this->set('creationForm', $creationForm);
+ $this->set('timeUsed', microtime(true) - $startTime);
+ }
/**
* Delete method
diff --git a/src/Form/CreationForm.php b/src/Form/CreationForm.php
index 1e59088ea..46363de27 100644
--- a/src/Form/CreationForm.php
+++ b/src/Form/CreationForm.php
@@ -35,7 +35,12 @@ class CreationForm extends Form
'rule' => ['maxLength', 150],
'message' => 'max 150 character'
])
- ->ascii('memo', __('Only Ascii Character allowed'))
+ //->alphaNumeric('memo', __('Only Alpha Numeric Character allowed'))
+ ->add('memo', 'custom', [
+ 'rule' => 'alphaNumeric',
+ 'provider' => 'custom',
+ 'message' => __('Only Alpha Numeric Character allowed')
+ ])
->allowEmptyString('memo', null, 'create')
/*->add('receiver_pubkey_hex', 'custom', [
'rule' => 'hexKey64',
diff --git a/src/Model/Entity/StateError.php b/src/Model/Entity/StateError.php
new file mode 100644
index 000000000..448e9ccb3
--- /dev/null
+++ b/src/Model/Entity/StateError.php
@@ -0,0 +1,37 @@
+ true,
+ 'transaction_type_id' => true,
+ 'created' => true,
+ 'message_json' => true,
+ 'state_user' => true,
+ 'transaction_type' => true
+ ];
+}
diff --git a/src/Model/Entity/StateUser.php b/src/Model/Entity/StateUser.php
index 59bd19e9a..a6e8c40da 100644
--- a/src/Model/Entity/StateUser.php
+++ b/src/Model/Entity/StateUser.php
@@ -33,6 +33,9 @@ class StateUser extends Entity
'index_id' => true,
'state_group_id' => true,
'public_key' => true,
+ 'email' => true,
+ 'first_name' => true,
+ 'last_name' => true,
'index' => true,
'state_group' => true,
'state_balances' => true,
diff --git a/src/Model/Entity/Transaction.php b/src/Model/Entity/Transaction.php
index 98948adae..d4ebf68c4 100644
--- a/src/Model/Entity/Transaction.php
+++ b/src/Model/Entity/Transaction.php
@@ -37,6 +37,7 @@ class Transaction extends Entity
'state_group_id' => true,
'transaction_type_id' => true,
'tx_hash' => true,
+ 'memo' => true,
'received' => true,
'state_group' => true,
'transaction_type' => true,
diff --git a/src/Model/Messages/Gradido/TransactionBody.php b/src/Model/Messages/Gradido/TransactionBody.php
index 0b8b05005..3452d4251 100644
--- a/src/Model/Messages/Gradido/TransactionBody.php
+++ b/src/Model/Messages/Gradido/TransactionBody.php
@@ -19,6 +19,10 @@ class TransactionBody extends \Google\Protobuf\Internal\Message
* Generated from protobuf field string memo = 1;
*/
private $memo = '';
+ /**
+ * Generated from protobuf field .model.messages.gradido.TimestampSeconds created = 2;
+ */
+ private $created = null;
protected $data;
/**
@@ -29,6 +33,7 @@ class TransactionBody extends \Google\Protobuf\Internal\Message
*
* @type string $memo
* max 150 chars
+ * @type \Model\Messages\Gradido\TimestampSeconds $created
* @type \Model\Messages\Gradido\StateCreateGroup $createGroup
* @type \Model\Messages\Gradido\StateGroupChangeParent $groupChangeParent
* @type \Model\Messages\Gradido\Transfer $transfer
@@ -67,89 +72,111 @@ class TransactionBody extends \Google\Protobuf\Internal\Message
}
/**
- * Generated from protobuf field .model.messages.gradido.StateCreateGroup createGroup = 2;
+ * Generated from protobuf field .model.messages.gradido.TimestampSeconds created = 2;
+ * @return \Model\Messages\Gradido\TimestampSeconds
+ */
+ public function getCreated()
+ {
+ return $this->created;
+ }
+
+ /**
+ * Generated from protobuf field .model.messages.gradido.TimestampSeconds created = 2;
+ * @param \Model\Messages\Gradido\TimestampSeconds $var
+ * @return $this
+ */
+ public function setCreated($var)
+ {
+ GPBUtil::checkMessage($var, \Model\Messages\Gradido\TimestampSeconds::class);
+ $this->created = $var;
+
+ return $this;
+ }
+
+ /**
+ * Generated from protobuf field .model.messages.gradido.StateCreateGroup createGroup = 6;
* @return \Model\Messages\Gradido\StateCreateGroup
*/
public function getCreateGroup()
{
- return $this->readOneof(2);
+ return $this->readOneof(6);
}
/**
- * Generated from protobuf field .model.messages.gradido.StateCreateGroup createGroup = 2;
+ * Generated from protobuf field .model.messages.gradido.StateCreateGroup createGroup = 6;
* @param \Model\Messages\Gradido\StateCreateGroup $var
* @return $this
*/
public function setCreateGroup($var)
{
GPBUtil::checkMessage($var, \Model\Messages\Gradido\StateCreateGroup::class);
- $this->writeOneof(2, $var);
+ $this->writeOneof(6, $var);
return $this;
}
/**
- * Generated from protobuf field .model.messages.gradido.StateGroupChangeParent groupChangeParent = 3;
+ * Generated from protobuf field .model.messages.gradido.StateGroupChangeParent groupChangeParent = 7;
* @return \Model\Messages\Gradido\StateGroupChangeParent
*/
public function getGroupChangeParent()
{
- return $this->readOneof(3);
+ return $this->readOneof(7);
}
/**
- * Generated from protobuf field .model.messages.gradido.StateGroupChangeParent groupChangeParent = 3;
+ * Generated from protobuf field .model.messages.gradido.StateGroupChangeParent groupChangeParent = 7;
* @param \Model\Messages\Gradido\StateGroupChangeParent $var
* @return $this
*/
public function setGroupChangeParent($var)
{
GPBUtil::checkMessage($var, \Model\Messages\Gradido\StateGroupChangeParent::class);
- $this->writeOneof(3, $var);
+ $this->writeOneof(7, $var);
return $this;
}
/**
- * Generated from protobuf field .model.messages.gradido.Transfer transfer = 4;
+ * Generated from protobuf field .model.messages.gradido.Transfer transfer = 8;
* @return \Model\Messages\Gradido\Transfer
*/
public function getTransfer()
{
- return $this->readOneof(4);
+ return $this->readOneof(8);
}
/**
- * Generated from protobuf field .model.messages.gradido.Transfer transfer = 4;
+ * Generated from protobuf field .model.messages.gradido.Transfer transfer = 8;
* @param \Model\Messages\Gradido\Transfer $var
* @return $this
*/
public function setTransfer($var)
{
GPBUtil::checkMessage($var, \Model\Messages\Gradido\Transfer::class);
- $this->writeOneof(4, $var);
+ $this->writeOneof(8, $var);
return $this;
}
/**
- * Generated from protobuf field .model.messages.gradido.TransactionCreation creation = 5;
+ * Generated from protobuf field .model.messages.gradido.TransactionCreation creation = 9;
* @return \Model\Messages\Gradido\TransactionCreation
*/
public function getCreation()
{
- return $this->readOneof(5);
+ return $this->readOneof(9);
}
/**
- * Generated from protobuf field .model.messages.gradido.TransactionCreation creation = 5;
+ * Generated from protobuf field .model.messages.gradido.TransactionCreation creation = 9;
* @param \Model\Messages\Gradido\TransactionCreation $var
* @return $this
*/
public function setCreation($var)
{
GPBUtil::checkMessage($var, \Model\Messages\Gradido\TransactionCreation::class);
- $this->writeOneof(5, $var);
+ $this->writeOneof(9, $var);
return $this;
}
diff --git a/src/Model/Table/StateErrorsTable.php b/src/Model/Table/StateErrorsTable.php
new file mode 100644
index 000000000..62893b7bf
--- /dev/null
+++ b/src/Model/Table/StateErrorsTable.php
@@ -0,0 +1,88 @@
+setTable('state_errors');
+ $this->setDisplayField('id');
+ $this->setPrimaryKey('id');
+
+ $this->addBehavior('Timestamp');
+
+ $this->belongsTo('StateUsers', [
+ 'foreignKey' => 'state_user_id',
+ 'joinType' => 'INNER'
+ ]);
+ $this->belongsTo('TransactionTypes', [
+ 'foreignKey' => 'transaction_type_id',
+ 'joinType' => 'INNER'
+ ]);
+ }
+
+ /**
+ * Default validation rules.
+ *
+ * @param \Cake\Validation\Validator $validator Validator instance.
+ * @return \Cake\Validation\Validator
+ */
+ public function validationDefault(Validator $validator)
+ {
+ $validator
+ ->integer('id')
+ ->allowEmptyString('id', null, 'create');
+
+ $validator
+ ->scalar('message_json')
+ ->requirePresence('message_json', 'create')
+ ->notEmptyString('message_json');
+
+ return $validator;
+ }
+
+ /**
+ * Returns a rules checker object that will be used for validating
+ * application integrity.
+ *
+ * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
+ * @return \Cake\ORM\RulesChecker
+ */
+ public function buildRules(RulesChecker $rules)
+ {
+ $rules->add($rules->existsIn(['state_user_id'], 'StateUsers'));
+ $rules->add($rules->existsIn(['transaction_type_id'], 'TransactionTypes'));
+
+ return $rules;
+ }
+}
diff --git a/src/Model/Table/StateUsersTable.php b/src/Model/Table/StateUsersTable.php
index fe18766e9..a28162d6a 100644
--- a/src/Model/Table/StateUsersTable.php
+++ b/src/Model/Table/StateUsersTable.php
@@ -61,6 +61,10 @@ class StateUsersTable extends Table
$this->hasMany('TransactionSendCoins', [
'foreignKey' => 'state_user_id'
]);
+ $this->hasMany('TransactionReceiveCoins', [
+ 'className' => 'TransactionSendCoins',
+ 'foreignKey' => 'receiver_user_id'
+ ]);
}
/**
@@ -96,4 +100,19 @@ class StateUsersTable extends Table
return $rules;
}
+
+ public function getReceiverProposal() {
+ $stateUsers = $this->find('all');
+ $receiverProposal = [];
+ foreach($stateUsers as $stateUser) {
+ $name = $stateUser->email;
+ $keyHex = bin2hex(stream_get_contents($stateUser->public_key));
+ if($name === NULL) {
+ $name = $stateUser->first_name . ' ' . $stateUser->last_name;
+ }
+ array_push($receiverProposal, ['name' => $name, 'key' => $keyHex]);
+ //$stateUser->public_key
+ }
+ return $receiverProposal;
+ }
}
diff --git a/src/Model/Table/TransactionCreationsTable.php b/src/Model/Table/TransactionCreationsTable.php
index 8f0afc158..70ab54071 100644
--- a/src/Model/Table/TransactionCreationsTable.php
+++ b/src/Model/Table/TransactionCreationsTable.php
@@ -45,6 +45,10 @@ class TransactionCreationsTable extends Table
'foreignKey' => 'state_user_id',
'joinType' => 'INNER'
]);
+ $this->belongsTo('StateUsers', [
+ 'foreignKey' => 'receiver_user_id',
+ 'joinType' => 'INNER'
+ ]);
}
/**
@@ -82,6 +86,7 @@ class TransactionCreationsTable extends Table
{
$rules->add($rules->existsIn(['transaction_id'], 'Transactions'));
$rules->add($rules->existsIn(['state_user_id'], 'StateUsers'));
+ $rules->add($rules->existsIn(['receiver_user_id'], 'StateUsers'));
return $rules;
}
diff --git a/src/Model/Table/TransactionsTable.php b/src/Model/Table/TransactionsTable.php
index 99c2473b8..75659a5b2 100644
--- a/src/Model/Table/TransactionsTable.php
+++ b/src/Model/Table/TransactionsTable.php
@@ -87,8 +87,11 @@ class TransactionsTable extends Table
->allowEmptyString('id', null, 'create');
$validator
- ->requirePresence('tx_hash', 'create')
- ->notEmptyString('tx_hash');
+ //->requirePresence('tx_hash', 'create')
+ ->allowEmptyString('tx_hash', null, 'create');
+
+ $validator
+ ->allowEmptyString('memo', null, 'create');
$validator
->dateTime('received')
diff --git a/src/Model/Transactions/Transaction.php b/src/Model/Transactions/Transaction.php
index 3c55f804c..393ca899c 100644
--- a/src/Model/Transactions/Transaction.php
+++ b/src/Model/Transactions/Transaction.php
@@ -10,57 +10,140 @@ namespace Model\Transactions;
//use Model\Messages\Gradido\Transaction;
//use Model\Messages\Gradido\TransactionBody;
+use Cake\ORM\TableRegistry;
+use Cake\Datasource\ConnectionManager;
class Transaction extends TransactionBase {
private $mProtoTransaction = null;
- private $mProtoTransactionBody = null;
- private $errors = [];
+ private $mTransactionBody = null;
public function __construct($base64Data) {
- $transactionBin = base64_decode($base64Data);
- if($transactionBin == FALSE) {
+ //$transactionBin = base64_decode($base64Data, true);
+ //if($transactionBin == false)
+ //sodium_base64_VARIANT_URLSAFE_NO_PADDING
+ try {
+ $transactionBin = sodium_base642bin($base64Data, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING);
+ } catch(\SodiumException $e) {
+ $this->addError('Transaction', $e->getMessage());// . ' ' . $base64Data);
+ return;
+ }
+ //*/
+ if($transactionBin == false) {
//$this->addError('base64 decode failed');
- $this->addError(['data' => $base64Data, 'bin' => $transactionBin, 'msg' => 'base64 decode error']);
+ $this->addError('Transaction', 'base64 decode error: ' . $base64Data);
} else {
$this->mProtoTransaction = new \Model\Messages\Gradido\Transaction();
- $this->mProtoTransaction->mergeFromString($transactionBin);
+ try {
+ $this->mProtoTransaction->mergeFromString($transactionBin);
+ // cannot catch Exception with cakePHP, I don't know why
+ } catch(\Google\Protobuf\Internal\GPBDecodeException $e) {
+ //var_dump($e);
+ $this->addError('Transaction', $e->getMessage());
+ return;
+ }//*/
- $this->mProtoTransactionBody = new \Model\Messages\Gradido\TransactionBody();
- $this->mProtoTransactionBody->mergeFromString($this->mProtoTransaction->getBodyBytes());
+ //echo 'serialize to json:
';
+ //echo $this->mProtoTransaction->serializeToJsonString();
- $data = $this->mProtoTransactionBody->getData();
- var_dump($data);
+ $this->mTransactionBody = new TransactionBody($this->mProtoTransaction->getBodyBytes());
}
}
+ public function getTransactionBody() {
+ return $this->mTransactionBody;
+ }
+
+ public function getFirstPublic() {
+ $sigPairs = $this->mProtoTransaction->getSigMap()->getSigPair();
+ return $sigPairs[0]->getPubKey();
+ }
+
public function validate() {
- $sigPairs = $this->mProtoTransaction->getSigMap()->getSigPair();
+ $sigMap = $this->mProtoTransaction->getSigMap();
+ if(!$sigMap) {
+ $this->addError('Transaction', 'signature map is zero');
+ return false;
+ }
+ //var_dump($sigMap);
+ //die();
+ $sigPairs = $sigMap->getSigPair();
$bodyBytes = $this->mProtoTransaction->getBodyBytes();
+
+ if(!$sigPairs || count($sigPairs) < 1) {
+ $this->addError('Transaction::validate', 'no signature found');
+ return false;
+ }
+
// check signature(s)
foreach($sigPairs as $sigPair) {
+ //echo 'sig Pair: '; var_dump($sigPair); echo "
";
$pubkey = $sigPair->getPubKey();
$signature = $sigPair->getEd25519();
if (!\Sodium\crypto_sign_verify_detached($signature, $bodyBytes, $pubkey)) {
- $this->addError('signature for key ' . bin2hex($pubkey) . ' isn\'t valid ' );
+ $this->addError('Transaction::validate', 'signature for key ' . bin2hex($pubkey) . ' isn\'t valid ' );
return false;
}
}
+ if(!$this->mTransactionBody->validate($sigPairs)) {
+ $this->addErrors($this->mTransactionBody->getErrors());
+ return false;
+ }
+
return true;
}
- public function getErrors() {
- return $this->errors;
+ public function save()
+ {
+ $connection = ConnectionManager::get('default');
+ $connection->begin();
+ //id transaction_id signature pubkey
+
+ if (!$this->mTransactionBody->save($this->getFirstPublic(), $this->mProtoTransaction->getSigMap())) {
+ $this->addErrors($this->mTransactionBody->getErrors());
+ $connection->rollback();
+ return false;
+ }
+
+ // save transaction signatures
+ $transactionsSignaturesTable = TableRegistry::getTableLocator()->get('transaction_signatures');
+ $transactionId = $this->mTransactionBody->getTransactionID();
+ //signature pubkey
+
+ $sigPairs = $this->mProtoTransaction->getSigMap()->getSigPair();
+ //echo "sigPairs: "; var_dump($sigPairs);
+ $signatureEntitys = [];
+ foreach($sigPairs as $sigPair) {
+ $signatureEntity = $transactionsSignaturesTable->newEntity();
+ $signatureEntity->transaction_id = $transactionId;
+ $signatureEntity->signature = $sigPair->getEd25519();
+ $signatureEntity->pubkey = $sigPair->getPubKey();
+ array_push($signatureEntitys, $signatureEntity);
+ }
+ //debug($signatureEntitys);
+ if(!$transactionsSignaturesTable->saveMany($signatureEntitys)) {
+ foreach($signatureEntitys as $entity) {
+ $errors = $entity->getErrors();
+ if(!$errors && count($errors) > 0) {
+ $pubkeyHex = bin2hex($entity->pubkey);
+ $this->addError('Transaction::save', 'error saving signature for pubkey: ' . $pubkeyHex . ', with errors: ' . json_encode($errors) );
+ }
+ }
+ $connection->rollback();
+ return false;
+ }
+
+
+
+ $connection->commit();
+ return true;
}
+
+
+
- public function hasErrors() {
- return count($this->errors) > 0;
- }
-
- private function addError($message) {
- array_push($this->errors, $message);
- }
+
}
\ No newline at end of file
diff --git a/src/Model/Transactions/TransactionBase.php b/src/Model/Transactions/TransactionBase.php
index ddf20798c..50eb72738 100644
--- a/src/Model/Transactions/TransactionBase.php
+++ b/src/Model/Transactions/TransactionBase.php
@@ -2,6 +2,68 @@
namespace Model\Transactions;
+use Cake\ORM\TableRegistry;
+
class TransactionBase {
+ private $errors = [];
+ public function getErrors() {
+ return $this->errors;
+ }
+
+ public function addError($functionName, $errorName) {
+ array_push($this->errors, [$functionName => $errorName]);
+ }
+
+ public function addErrors($errors) {
+ $this->errors = array_merge($this->errors, $errors);
+ }
+
+ public function hasErrors() {
+ return count($this->errors) > 0;
+ }
+
+ protected function getStateUserId($publicKey) {
+ $stateUsersTable = TableRegistry::getTableLocator()->get('state_users');
+ $stateUser = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $publicKey])->first();
+ if($stateUser) {
+ return $stateUser->id;
+ }
+ // create new entry
+ $stateUserEntity = $stateUsersTable->newEntity();
+ $stateUserEntity->public_key = $publicKey;
+ if($stateUsersTable->save($stateUserEntity)) {
+ return $stateUserEntity->id;
+ } else {
+ $this->addError('TransactionBase::getStateUserId', 'error saving new state user with error: ' . json_encode($stateUserEntity->getErrors()));
+ }
+
+ return NULL;
+ }
+
+ protected function updateStateBalance($stateUserId, $newAmountCent) {
+ $stateBalancesTable = TableRegistry::getTableLocator()->get('stateBalances');
+ $stateBalanceQuery = $stateBalancesTable
+ ->find('all')
+ ->select(['amount'])
+ ->contain(false)
+ ->where(['state_user_id' => $stateUserId]);//->first();
+ //debug($stateBalanceQuery);
+
+ if($stateBalanceQuery->count() > 0) {
+ $stateBalanceEntry = $stateBalanceQuery->first();
+ $stateBalanceEntry->amount += $newAmountCent;
+ } else {
+ $stateBalanceEntry = $stateBalancesTable->newEntity();
+ $stateBalanceEntry->state_user_id = $stateUserId;
+ $stateBalanceEntry->amount = $newAmountCent;
+ }
+
+ if(!$stateBalancesTable->save($stateBalanceEntry)) {
+ $errors = $stateBalanceEntry->getErrors();
+ $this->addError('TransactionBase::updateStateBalance', 'error saving state balance with: ' . json_encode($errors));
+ return false;
+ }
+ return true;
+ }
}
\ No newline at end of file
diff --git a/src/Model/Transactions/TransactionBody.php b/src/Model/Transactions/TransactionBody.php
index 175552736..ce66fe1b5 100644
--- a/src/Model/Transactions/TransactionBody.php
+++ b/src/Model/Transactions/TransactionBody.php
@@ -2,6 +2,138 @@
namespace Model\Transactions;
+use Cake\ORM\TableRegistry;
+
class TransactionBody extends TransactionBase {
+ private $mProtoTransactionBody = null;
+ private $mSpecificTransaction = null;
+ private $mTransactionID = 0;
+ private $transactionTypeId = 0;
+
+ public function __construct($bodyBytes) {
+ $this->mProtoTransactionBody = new \Model\Messages\Gradido\TransactionBody();
+ try {
+ $this->mProtoTransactionBody->mergeFromString($bodyBytes);
+ // cannot catch Exception with cakePHP, I don't know why
+ } catch(\Google\Protobuf\Internal\GPBDecodeException $e) {
+ //var_dump($e);
+ $this->addError('TransactionBody', $e->getMessage());
+ return;
+ }
+
+ switch($this->mProtoTransactionBody->getData()) {
+ case 'creation' : $this->mSpecificTransaction = new TransactionCreation($this->mProtoTransactionBody->getCreation()); break;
+ case 'transfer' : $this->mSpecificTransaction = new TransactionTransfer($this->mProtoTransactionBody->getTransfer()); break;
+ }
+ }
+
+ public function validate($sigPairs) {
+
+ // transaction type id
+ $transactionTypesTable = TableRegistry::getTableLocator()->get('transaction_types');
+
+ $typeName = $this->getTransactionTypeName();
+ $transactionType = $transactionTypesTable->find('all')->where(['name' => $typeName])->select(['id'])->first();
+ if($transactionType == NULL) {
+ $this->addError('TransactionBody::validate', 'zero type id for type: ' . $typeName);
+ return false;
+ }
+ $this->transactionTypeId = $transactionType->id;
+
+ // check if creation time is in the past
+ if($this->mProtoTransactionBody->getCreated()->getSeconds() > time()) {
+ $this->addError('TransactionBody::validate', 'Transaction were created in the past!');
+ return false;
+ }
+ if(!$this->mSpecificTransaction->validate($sigPairs)) {
+ $this->addErrors($this->mSpecificTransaction->getErrors());
+ return false;
+ }
+
+
+
+ return true;
+ }
+
+ public function getSpecificTransaction() {
+ return $this->mSpecificTransaction;
+ }
+
+ public function getMemo() {
+ return $this->mProtoTransactionBody->getMemo();
+ }
+
+ public function getTransactionTypeName()
+ {
+ return $this->mProtoTransactionBody->getData();
+ }
+
+ public function save($firstPublic, $sigMap) {
+ $transactionsTable = TableRegistry::getTableLocator()->get('transactions');
+ $transactionEntity = $transactionsTable->newEntity();
+
+
+ $transactionEntity->transaction_type_id = $this->transactionTypeId;
+ $transactionEntity->memo = $this->getMemo();
+
+ if ($transactionsTable->save($transactionEntity)) {
+ // success
+ $this->mTransactionID = $transactionEntity->id;
+ if(!$this->mSpecificTransaction->save($transactionEntity->id, $firstPublic)) {
+ $this->addErrors($this->mSpecificTransaction->getErrors());
+ return false;
+ }
+ } else {
+ $this->addError('TransactionBody::save', 'error saving transaction with: ' . json_encode($transactionEntity->getError()));
+ return false;
+ }
+ $previousTxHash = null;
+ if($this->mTransactionID > 1) {
+ try {
+ $previousTransaction = $transactionsTable->get($this->mTransactionID - 1, [
+ 'contain' => false,
+ 'fields' => ['tx_hash']
+ ]);
+ } catch(Cake\Datasource\Exception\RecordNotFoundException $ex) {
+ $this->addError('TransactionBody::save', 'previous transaction (with id ' . ($this->mTransactionID-1) . ' not found');
+ return false;
+ }
+ if(!$previousTransaction) {
+ // shouldn't occur
+ $this->addError('TransactionBody::save', 'previous transaction (with id ' . ($this->mTransactionID-1) . ' not found');
+ return false;
+ }
+ $previousTxHash = $previousTransaction->tx_hash;
+ }
+ $transactionEntity->received = $transactionsTable->get($transactionEntity->id, ['contain' => false, 'fields' => ['received']])->received;
+
+ // calculate tx hash
+ // previous tx hash + id + received + sigMap as string
+ // Sodium use for the generichash function BLAKE2b today (11.11.2019), mabye change in the future
+ $state = \Sodium\crypto_generichash_init();
+ //echo "prev hash: $previousTxHash\n";
+ if($previousTxHash != null) {
+ \Sodium\crypto_generichash_update($state, stream_get_contents($previousTxHash));
+ }
+ //echo "id: " . $transactionEntity->id . "\n";
+ \Sodium\crypto_generichash_update($state, strval($transactionEntity->id));
+ //echo "received: " . $transactionEntity->received;
+ \Sodium\crypto_generichash_update($state, $transactionEntity->received->i18nFormat('yyyy-MM-dd HH:mm:ss'));
+ \Sodium\crypto_generichash_update($state, $sigMap->serializeToString());
+ $transactionEntity->tx_hash = \Sodium\crypto_generichash_final($state);
+ if ($transactionsTable->save($transactionEntity)) {
+ return true;
+ }
+ $this->addError('TransactionBody::save', 'error saving transaction with: ' . json_encode($transactionEntity->getError()));
+ return false;
+ }
+
+ public function getTransactionID() {
+ return $this->mTransactionID;
+ }
+
+ public function getTransactionTypeId() {
+ return $this->transactionTypeId;
+ }
}
diff --git a/src/Model/Transactions/TransactionCreation.php b/src/Model/Transactions/TransactionCreation.php
index 4f60849f2..073ae2bf7 100644
--- a/src/Model/Transactions/TransactionCreation.php
+++ b/src/Model/Transactions/TransactionCreation.php
@@ -4,6 +4,96 @@ namespace Model\Transactions;
//use App\Model\Transactions\TransactionBase;
+use Cake\ORM\TableRegistry;
+
class TransactionCreation extends TransactionBase {
+ private $protoTransactionCreation;
+ private $transactionCreationsTable;
+
+ public function __construct($protoTransactionCreation) {
+ $this->protoTransactionCreation = $protoTransactionCreation;
+ $this->transactionCreationsTable = TableRegistry::getTableLocator()->get('transaction_creations');
+ }
+
+ public function getAmount() {
+ return $this->protoTransactionCreation->getReceiverAmount()->getAmount();
+ }
+
+ public function getReceiverPublic() {
+ return $this->protoTransactionCreation->getReceiverAmount()->getEd25519ReceiverPubkey();
+ }
+
+ public function getIdentHash() {
+ return $this->protoTransactionCreation->getIdentHash();
+ }
+
+ public function validate($sigPairs) {
+ // check if receiver public is not in signature list
+ $receiverPublic = $this->getReceiverPublic();
+ foreach($sigPairs as $sigPair) {
+ $pubkey = $sigPair->getPubKey();
+ if($pubkey == $receiverPublic) {
+ $this->addError('TransactionCreation::validate', 'receiver aren\'t allowed to sign creation Transaction');
+ return false;
+ }
+ }
+
+ // check if creation threshold for this month isn't reached
+
+ //$identHashBin = sprintf("%0d", $this->getIdentHash());
+ // padding with zero in case hash is smaller than 32 bytes, static length binary field in db
+ $identHashBin = pack('a32', $this->getIdentHash());
+
+ $existingCreations = $this->transactionCreationsTable
+ ->find('all')
+ ->group('ident_hash')
+ ->where(['ident_hash' => $identHashBin]);
+ $existingCreations->select(['amount_sum' => $existingCreations->func()->sum('amount')]);
+ $existingCreations->matching('Transactions', function ($q) {
+ return $q->where(['EXTRACT(YEAR_MONTH FROM Transactions.received) LIKE EXTRACT(YEAR_MONTH FROM NOW())']);
+ });
+ //debug($existingCreations);
+ if($existingCreations->count() > 0) {
+ //var_dump($existingCreations->toArray());
+ //echo "amount sum: " . $existingCreations->first()->amount_sum . "\n";
+ if($this->getAmount() + $existingCreations->first()->amount_sum > 10000000) {
+ $this->addError('TransactionCreation::validate', 'Creation more than 1000 gr per Month not allowed');
+ return false;
+ }
+ }
+ //die("\n");
+ return true;
+ }
+
+ public function save($transaction_id, $firstPublic)
+ {
+
+ $transactionCreationEntity = $this->transactionCreationsTable->newEntity();
+ $transactionCreationEntity->transaction_id = $transaction_id;
+
+ // state user id
+ //$state_user_id = $this->getStateUserId($firstPublic);
+ $receiverUser = $this->getStateUserId($this->getReceiverPublic());
+ if(!$receiverUser) {
+ $this->addError('TransactionCreation::save', 'couldn\'t get state user id');
+ return false;
+ }
+ $transactionCreationEntity->state_user_id = $receiverUser;
+ $transactionCreationEntity->amount = $this->getAmount();
+ $transactionCreationEntity->ident_hash = $this->getIdentHash();
+
+ if(!$this->transactionCreationsTable->save($transactionCreationEntity)) {
+ $this->addError('TransactionCreation::save', 'error saving transactionCreation with errors: ' . json_encode($transactionCreationEntity->getErrors()));
+ return false;
+ }
+
+ // update state balance
+ if(!$this->updateStateBalance($receiverUser, $this->getAmount())) {
+ return false;
+ }
+
+ return true;
+ }
+
}
diff --git a/src/Model/Transactions/TransactionTransfer.php b/src/Model/Transactions/TransactionTransfer.php
index e8357cc79..89eb36bda 100644
--- a/src/Model/Transactions/TransactionTransfer.php
+++ b/src/Model/Transactions/TransactionTransfer.php
@@ -5,6 +5,18 @@ namespace Model\Transactions;
//use App\Model\Transactions\TransactionBase;
class TransactionTransfer extends TransactionBase {
-
+ private $protoTransactionTransfer;
+
+ public function __construct($protoTransactionTransfer) {
+ $this->protoTransactionTransfer = $protoTransactionTransfer;
+ }
+
+ public function validate($sigPairs) {
+ return true;
+ }
+
+ public function save($transaction_id, $firstPublic) {
+ return true;
+ }
}
diff --git a/src/Model/Validation/TransactionValidation.php b/src/Model/Validation/TransactionValidation.php
index aba5828a1..a3463cd5b 100644
--- a/src/Model/Validation/TransactionValidation.php
+++ b/src/Model/Validation/TransactionValidation.php
@@ -30,4 +30,11 @@ class TransactionValidation
}
return false;
}
+
+ public static function alphaNumeric($value, array $context) {
+ if(preg_match('/^[a-zA-Z0-9äöüÄÖÜß _-]*$/', $value)) {
+ return true;
+ }
+ return false;
+ }
}
\ No newline at end of file
diff --git a/src/Template/Dashboard/error_http_request.ctp b/src/Template/Dashboard/error_http_request.ctp
new file mode 100644
index 000000000..cdbbec19b
--- /dev/null
+++ b/src/Template/Dashboard/error_http_request.ctp
@@ -0,0 +1,14 @@
+assign('title', __('Error, Please try again'));
+?>
+
+