update conflicted files

This commit is contained in:
Dario Rekowski on RockPI 2019-11-29 14:49:12 +00:00
commit e36f3297c5
73 changed files with 2343 additions and 405 deletions

2
.gitmodules vendored
View File

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

View File

@ -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": {

377
composer.lock generated
View File

@ -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",

View File

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

View File

@ -2,6 +2,7 @@
namespace App\Controller;
use App\Controller\AppController;
use Cake\I18n\Number;
/**
* AddressTypes Controller

View File

@ -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'] . "; <br>";
$session->destroy();
foreach($json['user'] as $key => $value) {
$session->write('StateUser.' . $key, $value );
}
$transactionPendings = $json['Transaction.pending'];
//echo "read transaction pending: $transactionPendings<br>";
$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');

View File

@ -0,0 +1,33 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
namespace App\Controller\Component;
use Cake\Controller\Component;
class GradidoNumberComponent extends Component
{
// input can be from 0,01 or 0.01 up to big number be anything
public function parseInputNumberToCentNumber($inputNumber)
{
//$filteredInputNumber = preg_replace('/,/', '.', $inputNumber);
$parts = preg_split('/(,|\.)/', (string)$inputNumber);
$result = intval($parts[0]) * 10000;
if(count($parts) == 2) {
$result += intval($parts[1]) * 100;
}
return $result;
}
public function centToPrint($centAmount)
{
}
}

View File

@ -2,10 +2,8 @@
namespace App\Controller;
use App\Controller\AppController;
use Cake\Http\Client;
use Cake\Routing\Router;
use Cake\ORM\TableRegistry;
use Cake\Core\Configure;
//use Cake\Routing\Router;
//use Cake\ORM\TableRegistry;
/**
* StateUsers Controller
@ -21,7 +19,7 @@ class DashboardController extends AppController
{
parent::initialize();
//$this->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<br>";
//echo $session_id; echo "<br>";
//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'] . "; <br>";
$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);
}

View File

@ -1,6 +1,7 @@
<?php
namespace App\Controller;
use Cake\ORM\TableRegistry;
use App\Controller\AppController;
/**
@ -12,6 +13,13 @@ use App\Controller\AppController;
*/
class StateBalancesController extends AppController
{
public function initialize()
{
parent::initialize();
//$this->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

View File

@ -0,0 +1,164 @@
<?php
namespace App\Controller;
use App\Controller\AppController;
/**
* StateErrors Controller
*
* @property \App\Model\Table\StateErrorsTable $StateErrors
*
* @method \App\Model\Entity\StateError[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
*/
class StateErrorsController extends AppController
{
public function initialize()
{
parent::initialize();
$this->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']);
}
}

View File

@ -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'] . '<br>';
$floatAmount = floatval(Number::format($requestData['amount'], ['places' => 4, 'locale' => 'en_GB']));
//echo 'set for receiver: ' . round($floatAmount * 10000) . '<br>';
$receiver->setAmount(round($floatAmount * 10000));
//echo 'after receiver amount set<br>';
$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']);

View File

@ -0,0 +1,87 @@
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\ORM\TableRegistry;
use Model\Transactions\Transaction;
/*!
* @author: Dario Rekowski#
*
* @date: 03.11.2019
*
* @desc: Handle requests from other server put or request transaction
*/
class TransactionJsonRequestHandlerController extends AppController {
public function initialize()
{
parent::initialize();
//$this->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);
}
}

View File

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

View File

@ -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',

View File

@ -0,0 +1,37 @@
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;
/**
* StateError Entity
*
* @property int $id
* @property int $state_user_id
* @property int $transaction_type_id
* @property \Cake\I18n\FrozenTime $created
* @property string $message_json
*
* @property \App\Model\Entity\StateUser $state_user
* @property \App\Model\Entity\TransactionType $transaction_type
*/
class StateError extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array
*/
protected $_accessible = [
'state_user_id' => true,
'transaction_type_id' => true,
'created' => true,
'message_json' => true,
'state_user' => true,
'transaction_type' => true
];
}

View File

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

View File

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

View File

@ -19,6 +19,10 @@ class TransactionBody extends \Google\Protobuf\Internal\Message
* Generated from protobuf field <code>string memo = 1;</code>
*/
private $memo = '';
/**
* Generated from protobuf field <code>.model.messages.gradido.TimestampSeconds created = 2;</code>
*/
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 <code>.model.messages.gradido.StateCreateGroup createGroup = 2;</code>
* Generated from protobuf field <code>.model.messages.gradido.TimestampSeconds created = 2;</code>
* @return \Model\Messages\Gradido\TimestampSeconds
*/
public function getCreated()
{
return $this->created;
}
/**
* Generated from protobuf field <code>.model.messages.gradido.TimestampSeconds created = 2;</code>
* @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 <code>.model.messages.gradido.StateCreateGroup createGroup = 6;</code>
* @return \Model\Messages\Gradido\StateCreateGroup
*/
public function getCreateGroup()
{
return $this->readOneof(2);
return $this->readOneof(6);
}
/**
* Generated from protobuf field <code>.model.messages.gradido.StateCreateGroup createGroup = 2;</code>
* Generated from protobuf field <code>.model.messages.gradido.StateCreateGroup createGroup = 6;</code>
* @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 <code>.model.messages.gradido.StateGroupChangeParent groupChangeParent = 3;</code>
* Generated from protobuf field <code>.model.messages.gradido.StateGroupChangeParent groupChangeParent = 7;</code>
* @return \Model\Messages\Gradido\StateGroupChangeParent
*/
public function getGroupChangeParent()
{
return $this->readOneof(3);
return $this->readOneof(7);
}
/**
* Generated from protobuf field <code>.model.messages.gradido.StateGroupChangeParent groupChangeParent = 3;</code>
* Generated from protobuf field <code>.model.messages.gradido.StateGroupChangeParent groupChangeParent = 7;</code>
* @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 <code>.model.messages.gradido.Transfer transfer = 4;</code>
* Generated from protobuf field <code>.model.messages.gradido.Transfer transfer = 8;</code>
* @return \Model\Messages\Gradido\Transfer
*/
public function getTransfer()
{
return $this->readOneof(4);
return $this->readOneof(8);
}
/**
* Generated from protobuf field <code>.model.messages.gradido.Transfer transfer = 4;</code>
* Generated from protobuf field <code>.model.messages.gradido.Transfer transfer = 8;</code>
* @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 <code>.model.messages.gradido.TransactionCreation creation = 5;</code>
* Generated from protobuf field <code>.model.messages.gradido.TransactionCreation creation = 9;</code>
* @return \Model\Messages\Gradido\TransactionCreation
*/
public function getCreation()
{
return $this->readOneof(5);
return $this->readOneof(9);
}
/**
* Generated from protobuf field <code>.model.messages.gradido.TransactionCreation creation = 5;</code>
* Generated from protobuf field <code>.model.messages.gradido.TransactionCreation creation = 9;</code>
* @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;
}

View File

@ -0,0 +1,88 @@
<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* StateErrors Model
*
* @property \App\Model\Table\StateUsersTable&\Cake\ORM\Association\BelongsTo $StateUsers
* @property \App\Model\Table\TransactionTypesTable&\Cake\ORM\Association\BelongsTo $TransactionTypes
*
* @method \App\Model\Entity\StateError get($primaryKey, $options = [])
* @method \App\Model\Entity\StateError newEntity($data = null, array $options = [])
* @method \App\Model\Entity\StateError[] newEntities(array $data, array $options = [])
* @method \App\Model\Entity\StateError|false save(\Cake\Datasource\EntityInterface $entity, $options = [])
* @method \App\Model\Entity\StateError saveOrFail(\Cake\Datasource\EntityInterface $entity, $options = [])
* @method \App\Model\Entity\StateError patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
* @method \App\Model\Entity\StateError[] patchEntities($entities, array $data, array $options = [])
* @method \App\Model\Entity\StateError findOrCreate($search, callable $callback = null, $options = [])
*
* @mixin \Cake\ORM\Behavior\TimestampBehavior
*/
class StateErrorsTable extends Table
{
/**
* Initialize method
*
* @param array $config The configuration for the Table.
* @return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->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;
}
}

View File

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

View File

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

View File

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

View File

@ -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: <br>';
//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 "<br>";
$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);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,14 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
$this->assign('title', __('Error, Please try again'));
?>
<div class="grd_container_small">
<button class="grd_clickable grd-form-bn" onclick="history.back()"><?= __('Back'); ?></button>
</div>

View File

@ -11,15 +11,22 @@ if(isset($user)) {
}
$this->assign('title', __('Willkommen') . '&nbsp;' . $user['first_name'] . '&nbsp;' . $user['last_name']);
?>
<?php if(isset($requestTime)) : ?>
<span class='grd-second-timer'><?= round($requestTime * 1000.0) ?> ms</span>
<?php endif; ?>
<div class="grd_container_small">
<fieldset>
<h3>Gradido ...</h3>
<?= $this->Html->link(
__('schöpfen'),
['controller' => 'TransactionCreations', 'action' => 'create'],
__('übersicht'),
['controller' => 'StateBalances', 'action' => 'overview'],
['class' => 'grd-nav-bn grd-nav-bn-large']
);?>
<?= $this->Html->link(
__('überweisen'),
['controller' => 'TransactionSendCoins', 'action' => 'create'],
['class' => 'grd-nav-bn grd-nav-bn-large']
); ?>
<a class="grd-nav-bn grd-nav-bn-large">überweisen</a>
</fieldset>
<fieldset class="grd-margin-top-10">
<h3>Account ...</h3>

View File

@ -1,5 +1,5 @@
<?php
$class = 'message';
$class = 'alert-primary';
if (!empty($params['class'])) {
$class .= ' ' . $params['class'];
}
@ -7,4 +7,7 @@ if (!isset($params['escape']) || $params['escape'] !== false) {
$message = h($message);
}
?>
<div class="<?= h($class) ?>" onclick="this.classList.add('hidden');"><?= $message ?></div>
<!--<div class="<?= h($class) ?>" onclick="this.classList.add('hidden');"><?= $message ?></div>-->
<div class="alert <?= h($class) ?>" onclick="this.classList.add('hidden')" role="alert">
<?= $message ?>
</div>

View File

@ -3,4 +3,7 @@ if (!isset($params['escape']) || $params['escape'] !== false) {
$message = h($message);
}
?>
<div class="message error" onclick="this.classList.add('hidden');"><?= $message ?></div>
<!--<div class="message error" onclick="this.classList.add('hidden');"><?= $message ?></div>-->
<div class="alert alert-danger" role="alert" onclick="this.classList.add('hidden');">
<i class="mdi mdi-alert-outline grd-alert-color mdi-2x"></i> <?= $message ?>
</div>

View File

@ -3,4 +3,8 @@ if (!isset($params['escape']) || $params['escape'] !== false) {
$message = h($message);
}
?>
<div class="message success" onclick="this.classList.add('hidden')"><?= $message ?></div>
<!--<div class="message success" onclick="this.classList.add('hidden')"><?= $message ?></div>-->
<div class="alert alert-success" onclick="this.classList.add('hidden')" role="alert">
<b><?= __('Info:') ?></b> <?= $message ?>
</div>

View File

@ -52,8 +52,10 @@ $cakeDescription = 'Gradido';
<div class="container clearfix">
<?= $this->fetch('content') ?>
</div>
<div class="grd-time-used dev-info">
<?= round($timeUsed * 1000.0, 4) ?> ms
</div>
<?php if(isset($timeUsed)) : ?>
<div class="grd-time-used dev-info">
<?= round($timeUsed * 1000.0, 4) ?> ms
</div>
<?php endif;?>
</body>
</html>

View File

@ -1,5 +1,6 @@
<?php
use Cake\Routing\Router;
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
@ -14,9 +15,18 @@ use Cake\Routing\Router;
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
$cakeDescription = 'Gradido';
$session = $this->getRequest()->getSession();
$transactionPendings = $session->read('Transactions.pending');
$errorCount = intval($session->read('StateUser.errorCount'));
$balance = $session->read('StateUser.balance');
//echo "balance: $balance<br>";
if(!isset($balance)) {
$balance = 0;
}
//echo "balance: $balance<br>";
//echo "transactions pending: " . $transactionPendings;
?>
<!DOCTYPE html>
@ -40,21 +50,32 @@ $transactionPendings = $session->read('Transactions.pending');
<body>
<div class="versionstring dev-info">
<p class="grd_small">Community Server in Entwicklung</p>
<p class="grd_small">Alpha 0.4.4</p>
<p class="grd_small">Alpha 0.6.0</p>
</div>
<nav class="grd-left-bar expanded" data-topbar role="navigation">
<div class="grd-left-bar-section">
<ul class="grd-no-style">
<li><?= $this->Html->link(__('Startseite'), ['controller' => 'dashboard'], ['class' => 'grd-nav-bn'])?>
<?php if($errorCount > 0) : ?>
<li>
<?= $this->Html->Link(__('Fehler '). "($errorCount)", ['controller' => 'StateErrors', 'action' => 'showForUser'], ['class' => 'grd-nav-bn grd-nav-bn-discard']) ?>
</li>
<?php endif; ?>
<?php if(isset($balance)) : ?>
<li><?= $this->Html->link($this->element('printGradido', ['number' => $balance]),
['controller' => 'StateBalances', 'action' => 'overview'], ['class' => 'grd-nav-bn grd-nav-without-border', 'escape' => false])
?>
</li>
<?php endif; ?>
<li><?= $this->Html->link(__('Startseite'), ['controller' => 'Dashboard'], ['class' => 'grd-nav-bn'])?>
<!--<li><?= $this->Html->link(__('Kontostand'), ['controller' => 'StateBalances', 'action' => 'overview'], ['class' => 'grd-nav-bn']) ?>-->
<?php if(intval($transactionPendings) > 0) : ?>
<li>
<a href="<?= Router::url('', true) ?>account/checkTransactions" class="grd-nav-bn">
<a href="<?= Router::url('./', true) ?>account/checkTransactions" class="grd-nav-bn">
<?= __("Transaktionen unterzeichnen") . '&nbsp;(' . intval($transactionPendings) . ')'?>
</a>
</li>
<?php else: ?>
<li><a href="<?= Router::url('', true) ?>account/logout" class="grd-nav-bn"><?= __("Logout"); ?></a></li>
<li><a href="<?= Router::url('./', true) ?>account/logout" class="grd-nav-bn"><?= __("Logout"); ?></a></li>
<?php endif; ?>
</ul>
</div>
@ -64,8 +85,10 @@ $transactionPendings = $session->read('Transactions.pending');
<div class="flash-messages"><?= $this->Flash->render() ?></div>
<?= $this->fetch('content') ?>
</div>
<div class="grd-time-used dev-info">
<?= round($timeUsed * 1000.0, 4) ?> ms
</div>
<?php if(isset($timeUsed)) : ?>
<div class="grd-time-used dev-info">
<?= round($timeUsed * 1000.0, 4) ?> ms
</div>
<?php endif; ?>
</body>
</html>

View File

@ -0,0 +1,132 @@
<?php
use Cake\Routing\Router;
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 0.10.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
$cakeDescription = 'Gradido';
$GLOBALS["self"] = $this;
//echo "balance: $balance<br>";
//echo "transactions pending: " . $transactionPendings;
?>
<!DOCTYPE html>
<html>
<head>
<?= $this->Html->charset() ?>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
<?= $cakeDescription ?>:
<?= $this->fetch('title') ?>
</title>
<?= $this->Html->meta('icon') ?>
<?= $this->Html->css(['rippleUI/style.css', 'materialdesignicons.min.css']) ?>
<?= $this->Html->script(['basic']) ?>
<?= $this->fetch('meta') ?>
<?= $this->fetch('css') ?>
<?= $this->fetch('script') ?>
</head>
<body class="header-fixed">
<div class="versionstring dev-info">
<p class="grd_small"><?= __("Community Server in Entwicklung") ?></p>
<p class="grd_small">Alpha 0.8.0</p>
</div>
<nav class="t-header">
<div class="t-header-brand-wrapper">
<a href="/">
<?= $this->Html->image('logo_schrift_half.webp', ['alt' => 'Logo', 'class' => 'logo']) ?>
<?= $this->Html->image('logo_half.webp', ['alt' => 'Logo', 'class' => 'logo-mini']) ?>
</a>
<button class="t-header-toggler t-header-desk-toggler d-none d-lg-block">
<svg class="logo" viewBox="0 0 200 200">
<path class="top" d="
M 40, 80
C 40, 80 120, 80 140, 80
C180, 80 180, 20 90, 80
C 60,100 30,120 30,120
"></path>
<path class="middle" d="
M 40,100
L140,100
"></path>
<path class="bottom" d="
M 40,120
C 40,120 120,120 140,120
C180,120 180,180 90,120
C 60,100 30, 80 30, 80
"></path>
</svg>
</button>
</div>
<div class="t-header-content-wrapper">
<div class="t-header-content">
<button class="t-header-toggler t-header-mobile-toggler d-block d-lg-none">
<i class="mdi mdi-menu"></i>
</button>
<div class="flash-messages" style="margin-left:20px; margin-top:30px;">
<?= $this->Flash->render() ?>
</div>
<?= $this->element('navi_header'); ?>
</div>
</div>
</nav>
<div class="page-body">
<!-- partial:partials/_sidebar.html -->
<div class="sidebar">
<?= $this->element('navi'); ?>
</div>
<div class="page-content-wrapper">
<div class="page-content-wrapper-inner">
<div class="viewport-header">
<nav aria-label="breadcrumb">
<ol class="breadcrumb has-arrow">
<li class="breadcrumb-item">
<?= $this->Html->link(__('Startseite'), ['controller' => 'Dashboard']); ?>
</li>
<li class="breadcrumb-item active" aria-current="page"><?= $this->fetch('title') ?></li>
</ol>
</nav>
</div>
<div class="content-viewport">
<?= $this->fetch('content') ?>
</div>
</div>
<!-- content viewport ends -->
<!-- partial:partials/_footer.html -->
<footer class="footer">
<div class="row">
<div class="col-sm-6 text-center text-sm-right order-sm-1">
<ul class="text-gray">
<li><a href="#">Terms of use</a></li>
<li><a href="#">Privacy Policy</a></li>
</ul>
</div>
<div class="col-sm-6 text-center text-sm-left mt-3 mt-sm-0">
<small class="text-muted d-block">Copyright © 2019 Gradido</small>
</div>
</div>
</footer>
<!-- partial -->
</div>
<!-- page content ends -->
</div>
<?php if(isset($timeUsed)) : ?>
<div class="grd-time-used dev-info">
<?= round($timeUsed * 1000.0, 4) ?> ms
</div>
<?php endif; ?>
</body>
</html>

View File

@ -0,0 +1,74 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
$this->assign('title', __('Kontoübersicht'));
//var_dump($transactions);
?>
<div class="row">
<div class="col-md-8 equel-grid">
<div class="grid">
<div class="grid-body py-3">
<h3><?= __('Aktueller Kontostand: ') ?></h3>
<h2><?= $this->element('printGradido', ['number' => $balance]) ?></h2>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-10 equel-grid">
<div class="grid">
<div class="grid-body py-3">
<p class="card-title ml-n1">Überweisungen</p>
</div>
<div class="table-responsive">
<table class="table table-hover table-sm">
<thead>
<tr class="solid-header">
<th colspan="2" class="pl-4"><?= __('Absender') . ' / ' . ('Empfänger') ?></th>
<th><?= __('Transaktions Nr.') ?></th>
<th><?= __('Datum') ?></th>
<th><?= __('Betrag') ?></th>
</tr>
</thead>
<tbody>
<?php foreach($transactions as $transaction): ?>
<tr>
<td class="pr-0 pl-4">
<?= $this->Html->image('50x50.png', ['class' => 'profile-img img-sm', 'alt' => 'profile image']) ?>
</td>
<td class="pl-md-0">
<?php if(isset($transaction['email']) && $transaction['email'] != ''): ?>
<a href="mailto:<?= $transaction['email'] ?>" title="<?= $transaction['email'] ?>">
<small class="text-black font-weight-medium d-block"><?= $transaction['name'] ?></small>
</a>
<?php else : ?>
<small class="text-black font-weight-medium d-block"><?= $transaction['name'] ?></small>
<?php endif; ?>
<span>
<?php if($transaction['type'] == 'creation') : ?>
<i class="mdi mdi-creation grd-orange-color"></i>&nbsp;<?= __('Geschöpft')?>
<?php elseif($transaction['type'] == 'send') : ?>
<i class="mdi mdi-arrow-right-bold"></i>&nbsp;<?= __('Gesendet') ?>
<?php elseif($transaction['type'] == 'receive') : ?>
<i class="mdi mdi-arrow-left-bold"></i>&nbsp;<?= __('Empfangen') ?>
<?php endif; ?>
</span>
</td>
<td>
<small><?= $transaction['transaction_id'] ?></small>
</td>
<td> <?= $transaction['date']->nice() ?> </td>
<td><?= $this->element('printGradido', ['number' => $transaction['balance']]) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<!--<a class="border-top px-3 py-2 d-block text-gray" href="#"><small class="font-weight-medium"><i class="mdi mdi-chevron-down mr-2"></i>View All Order History</small></a>-->
</div>
</div>
</div>

View File

@ -0,0 +1,29 @@
<?php
/**
* @var \App\View\AppView $this
* @var \App\Model\Entity\StateError $stateError
*/
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
<li><?= $this->Html->link(__('List State Errors'), ['action' => 'index']) ?></li>
<li><?= $this->Html->link(__('List State Users'), ['controller' => 'StateUsers', 'action' => 'index']) ?></li>
<li><?= $this->Html->link(__('New State User'), ['controller' => 'StateUsers', 'action' => 'add']) ?></li>
<li><?= $this->Html->link(__('List Transaction Types'), ['controller' => 'TransactionTypes', 'action' => 'index']) ?></li>
<li><?= $this->Html->link(__('New Transaction Type'), ['controller' => 'TransactionTypes', 'action' => 'add']) ?></li>
</ul>
</nav>
<div class="stateErrors form large-9 medium-8 columns content">
<?= $this->Form->create($stateError) ?>
<fieldset>
<legend><?= __('Add State Error') ?></legend>
<?php
echo $this->Form->control('state_user_id', ['options' => $stateUsers]);
echo $this->Form->control('transaction_type_id', ['options' => $transactionTypes]);
echo $this->Form->control('message_json');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>

View File

@ -0,0 +1,35 @@
<?php
/**
* @var \App\View\AppView $this
* @var \App\Model\Entity\StateError $stateError
*/
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
<li><?= $this->Form->postLink(
__('Delete'),
['action' => 'delete', $stateError->id],
['confirm' => __('Are you sure you want to delete # {0}?', $stateError->id)]
)
?></li>
<li><?= $this->Html->link(__('List State Errors'), ['action' => 'index']) ?></li>
<li><?= $this->Html->link(__('List State Users'), ['controller' => 'StateUsers', 'action' => 'index']) ?></li>
<li><?= $this->Html->link(__('New State User'), ['controller' => 'StateUsers', 'action' => 'add']) ?></li>
<li><?= $this->Html->link(__('List Transaction Types'), ['controller' => 'TransactionTypes', 'action' => 'index']) ?></li>
<li><?= $this->Html->link(__('New Transaction Type'), ['controller' => 'TransactionTypes', 'action' => 'add']) ?></li>
</ul>
</nav>
<div class="stateErrors form large-9 medium-8 columns content">
<?= $this->Form->create($stateError) ?>
<fieldset>
<legend><?= __('Edit State Error') ?></legend>
<?php
echo $this->Form->control('state_user_id', ['options' => $stateUsers]);
echo $this->Form->control('transaction_type_id', ['options' => $transactionTypes]);
echo $this->Form->control('message_json');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>

View File

@ -0,0 +1,55 @@
<?php
/**
* @var \App\View\AppView $this
* @var \App\Model\Entity\StateError[]|\Cake\Collection\CollectionInterface $stateErrors
*/
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
<li><?= $this->Html->link(__('New State Error'), ['action' => 'add']) ?></li>
<li><?= $this->Html->link(__('List State Users'), ['controller' => 'StateUsers', 'action' => 'index']) ?></li>
<li><?= $this->Html->link(__('New State User'), ['controller' => 'StateUsers', 'action' => 'add']) ?></li>
<li><?= $this->Html->link(__('List Transaction Types'), ['controller' => 'TransactionTypes', 'action' => 'index']) ?></li>
<li><?= $this->Html->link(__('New Transaction Type'), ['controller' => 'TransactionTypes', 'action' => 'add']) ?></li>
</ul>
</nav>
<div class="stateErrors index large-9 medium-8 columns content">
<h3><?= __('State Errors') ?></h3>
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th scope="col"><?= $this->Paginator->sort('id') ?></th>
<th scope="col"><?= $this->Paginator->sort('state_user_id') ?></th>
<th scope="col"><?= $this->Paginator->sort('transaction_type_id') ?></th>
<th scope="col"><?= $this->Paginator->sort('created') ?></th>
<th scope="col" class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($stateErrors as $stateError): ?>
<tr>
<td><?= $this->Number->format($stateError->id) ?></td>
<td><?= $stateError->has('state_user') ? $this->Html->link($stateError->state_user->id, ['controller' => 'StateUsers', 'action' => 'view', $stateError->state_user->id]) : '' ?></td>
<td><?= $stateError->has('transaction_type') ? $this->Html->link($stateError->transaction_type->name, ['controller' => 'TransactionTypes', 'action' => 'view', $stateError->transaction_type->id]) : '' ?></td>
<td><?= h($stateError->created) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $stateError->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $stateError->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $stateError->id], ['confirm' => __('Are you sure you want to delete # {0}?', $stateError->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(['format' => __('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')]) ?></p>
</div>
</div>

View File

@ -0,0 +1,34 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
$this->assign('title', __('Fehlermeldungen'));
//var_dump($transactionTypes);
/*foreach($transactionTypes as $i => $t) {
echo "$i => ";
var_dump($t);
echo "<br>";
}*/
?>
<div class="grd_container_small">
<table>
<thead>
<tr><th>Transaktion Typ</th><th>Datum</th><th>Fehler</th><th>Aktionen</th></tr>
</thead>
<tbody>
<?php foreach($errors as $error) :
$type = $transactionTypes[$error->transaction_type_id]; ?>
<tr>
<td title="<?= $type->text ?>"><?= $type->name ?></td>
<td><?= $error->created ?></td>
<td><?= $error->message_json ?></td>
<td><?= $this->Html->link(__('Delete'), ['action' => 'deleteForUser', $error->id], ['class' => 'grd-form-bn grd-form-bn-discard']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>

View File

@ -0,0 +1,44 @@
<?php
/**
* @var \App\View\AppView $this
* @var \App\Model\Entity\StateError $stateError
*/
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
<li><?= $this->Html->link(__('Edit State Error'), ['action' => 'edit', $stateError->id]) ?> </li>
<li><?= $this->Form->postLink(__('Delete State Error'), ['action' => 'delete', $stateError->id], ['confirm' => __('Are you sure you want to delete # {0}?', $stateError->id)]) ?> </li>
<li><?= $this->Html->link(__('List State Errors'), ['action' => 'index']) ?> </li>
<li><?= $this->Html->link(__('New State Error'), ['action' => 'add']) ?> </li>
<li><?= $this->Html->link(__('List State Users'), ['controller' => 'StateUsers', 'action' => 'index']) ?> </li>
<li><?= $this->Html->link(__('New State User'), ['controller' => 'StateUsers', 'action' => 'add']) ?> </li>
<li><?= $this->Html->link(__('List Transaction Types'), ['controller' => 'TransactionTypes', 'action' => 'index']) ?> </li>
<li><?= $this->Html->link(__('New Transaction Type'), ['controller' => 'TransactionTypes', 'action' => 'add']) ?> </li>
</ul>
</nav>
<div class="stateErrors view large-9 medium-8 columns content">
<h3><?= h($stateError->id) ?></h3>
<table class="vertical-table">
<tr>
<th scope="row"><?= __('State User') ?></th>
<td><?= $stateError->has('state_user') ? $this->Html->link($stateError->state_user->id, ['controller' => 'StateUsers', 'action' => 'view', $stateError->state_user->id]) : '' ?></td>
</tr>
<tr>
<th scope="row"><?= __('Transaction Type') ?></th>
<td><?= $stateError->has('transaction_type') ? $this->Html->link($stateError->transaction_type->name, ['controller' => 'TransactionTypes', 'action' => 'view', $stateError->transaction_type->id]) : '' ?></td>
</tr>
<tr>
<th scope="row"><?= __('Id') ?></th>
<td><?= $this->Number->format($stateError->id) ?></td>
</tr>
<tr>
<th scope="row"><?= __('Created') ?></th>
<td><?= h($stateError->created) ?></td>
</tr>
</table>
<div class="row">
<h4><?= __('Message Json') ?></h4>
<?= $this->Text->autoParagraph(h($stateError->message_json)); ?>
</div>
</div>

View File

@ -39,8 +39,8 @@ class StateBalancesFixture extends TestFixture
[
'id' => 1,
'state_user_id' => 1,
'modified' => '2019-09-12 11:14:50',
'amount' => 1
'modified' => '2019-11-05 18:02:28',
'amount' => 1200
],
];
parent::init();

View File

@ -15,12 +15,16 @@ class StateUsersFixture extends TestFixture
*/
// @codingStandardsIgnoreStart
public $fields = [
'id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
'id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null],
'index_id' => ['type' => 'smallinteger', 'length' => 6, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null],
'state_group_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
'group_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
'public_key' => ['type' => 'binary', 'length' => 32, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null],
'email' => ['type' => 'string', 'length' => 255, 'null' => true, 'default' => null, 'collate' => 'utf8_bin', 'comment' => '', 'precision' => null, 'fixed' => null],
'first_name' => ['type' => 'string', 'length' => 255, 'null' => true, 'default' => null, 'collate' => 'utf8_bin', 'comment' => '', 'precision' => null, 'fixed' => null],
'last_name' => ['type' => 'string', 'length' => 255, 'null' => true, 'default' => null, 'collate' => 'utf8_bin', 'comment' => '', 'precision' => null, 'fixed' => null],
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []],
'public_key' => ['type' => 'unique', 'columns' => ['public_key'], 'length' => []],
],
'_options' => [
'engine' => 'InnoDB',
@ -38,9 +42,21 @@ class StateUsersFixture extends TestFixture
$this->records = [
[
'id' => 1,
'index_id' => 1,
'state_group_id' => 1,
'public_key' => 'Lorem ipsum dolor sit amet'
'index_id' => 0,
'group_id' => 0,
'public_key' => '0x94ae135b93cd9f33752b4e55c41903a3faa13a75bb90bfd411ea1d4a1a5e711f',
'email' => NULL,
'first_name' => 'Dario',
'last_name' => 'Rekowski'
],
[
'id' => 11,
'index_id' => 0,
'group_id' => 0,
'public_key' => '0x61b923c218cb63a64a8c62f3860121283b9577f374d0a31590ba02cdc2912999',
'email' => NULL,
'first_name' => 'Dario',
'last_name' => 'Rekowski'
],
];
parent::init();

View File

@ -15,7 +15,11 @@ class TransactionCreationsFixture extends TestFixture
*/
// @codingStandardsIgnoreStart
public $fields = [
<<<<<<< HEAD
'id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
=======
'id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null],
>>>>>>> cd32fbe27a5e24b63a58d9b0b47c11917d31bcbc
'transaction_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
'state_user_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
'amount' => ['type' => 'biginteger', 'length' => 20, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
@ -36,13 +40,23 @@ class TransactionCreationsFixture extends TestFixture
*/
public function init()
{
//(8, 17, 11, 1210000, 0x2d31333636313339343833000000000000000000000000000000000000000000)
$this->records = [
[
'id' => 1,
'transaction_id' => 1,
'state_user_id' => 1,
'amount' => 1,
'ident_hash' => 'Lorem ipsum dolor sit amet'
'state_user_id' => 11,
'amount' => 10000000,
'ident_hash' => hex2bin('2d31333636313339343833000000000000000000000000000000000000000000')
],
[
'id' => 8,
'transaction_id' => 17,
'state_user_id' => 11,
'amount' => 1210000,
'ident_hash' => hex2bin('2d31333636313339343833000000000000000000000000000000000000000000')
],
];
parent::init();

View File

@ -37,9 +37,14 @@ class TransactionTypesFixture extends TestFixture
$this->records = [
[
'id' => 1,
'name' => 'Lorem ipsum dolor sit ',
'text' => 'Lorem ipsum dolor sit amet'
'name' => 'creation',
'text' => 'Aktives oder Bedingsungsloses Grundeinkommen'
],
[
'id' => 2,
'name' => 'transfer',
'text' => 'Einfache Überweisung'
]
];
parent::init();
}

View File

@ -36,13 +36,23 @@ class TransactionsFixture extends TestFixture
*/
public function init()
{
//(17, 0, 1, 0x0000000000000000000000000000000000000000000000000000000000000000, '', '2019-11-05 15:13:27');
$this->records = [
[
'id' => 1,
'state_group_id' => 1,
'group_id' => 0,
'transaction_type_id' => 1,
'tx_hash' => 'Lorem ipsum dolor sit amet',
'received' => 1568286900
'tx_hash' => '0x0000000000000000000000000000000000000000000000000000000000000000',
'memo' => '',
'received' => 1571314633
],
[
'id' => 17,
'group_id' => 0,
'transaction_type_id' => 1,
'tx_hash' => '0x0000000000000000000000000000000000000000000000000000000000000000',
'memo' => '',
'received' => 1572966807
],
];
parent::init();

View File

@ -0,0 +1,95 @@
<?php
namespace App\Test\TestCase\Controller\Component;
use App\Controller\Component\GradidoNumberComponent;
use Cake\Controller\ComponentRegistry;
use Cake\TestSuite\TestCase;
/**
* App\Controller\Component\NumberComponent Test Case
*/
class GradidoNumberComponentTest extends TestCase
{
/**
* Test subject
*
* @var \App\Controller\Component\NumberComponent
*/
public $GradidoNumberComponent;
/**
* setUp method
*
* @return void
*/
public function setUp()
{
parent::setUp();
$registry = new ComponentRegistry();
$this->GradidoNumberComponent = new GradidoNumberComponent($registry);
}
/**
* tearDown method
*
* @return void
*/
public function tearDown()
{
unset($this->GradidoNumberComponent);
parent::tearDown();
}
/**
* Test parseInputNumberToCentNumber method
*
* @return void
*/
/* public function testParseInputNumberToCentNumber()
{
$this->markTestIncomplete('Not implemented yet.');
}*/
public function test100()
{
$result = $this->GradidoNumberComponent->parseInputNumberToCentNumber(100);
$this->assertEquals(1000000, $result);
}
public function test1000()
{
$result = $this->GradidoNumberComponent->parseInputNumberToCentNumber(1000);
$this->assertEquals(10000000, $result);
}
public function test100Comma()
{
$result = $this->GradidoNumberComponent->parseInputNumberToCentNumber('100,12');
$this->assertEquals(1001200, $result);
}
public function test100Point()
{
$result = $this->GradidoNumberComponent->parseInputNumberToCentNumber('100.12');
$this->assertEquals(1001200, $result);
}
public function test100Decimal()
{
$result = $this->GradidoNumberComponent->parseInputNumberToCentNumber(100.12);
$this->assertEquals(1001200, $result);
}
public function test1000Point()
{
$result = $this->GradidoNumberComponent->parseInputNumberToCentNumber('1000.12');
$this->assertEquals(10001200, $result);
}
public function test1000Comma()
{
$result = $this->GradidoNumberComponent->parseInputNumberToCentNumber('1000,12');
$this->assertEquals(10001200, $result);
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace App\Test\TestCase\Controller;
use App\Controller\DashboardController;
use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase;
/**
* App\Controller\DashboardController Test Case
*
* @uses \App\Controller\DashboardController
*/
class DashboardControllerTest extends TestCase
{
use IntegrationTestTrait;
/**
* Fixtures
*
* @var array
*/
public $fixtures = [
];
/**
* Test initialize method
*
* @return void
*/
public function testInitialize()
{
$this->markTestIncomplete('Not implemented yet.');
}
/**
* Test index method
*
* @return void
*/
public function testIndex()
{
$this->markTestIncomplete('Not implemented yet.');
}
}

View File

@ -35,9 +35,9 @@ class PagesControllerTest extends IntegrationTestCase
public function testMultipleGet()
{
$this->get('/');
$this->assertResponseOk();
$this->assertRedirect('account/');
$this->get('/');
$this->assertResponseOk();
$this->assertRedirect('account/');
}
/**

View File

@ -25,6 +25,16 @@ class TransactionCreationsControllerTest extends TestCase
'app.StateUsers'
];
/**
* Test initialize method
*
* @return void
*/
public function testInitialize()
{
$this->markTestIncomplete('Not implemented yet.');
}
/**
* Test index method
*
@ -45,6 +55,16 @@ class TransactionCreationsControllerTest extends TestCase
$this->markTestIncomplete('Not implemented yet.');
}
/**
* Test create method
*
* @return void
*/
public function testCreate()
{
$this->markTestIncomplete('Not implemented yet.');
}
/**
* Test add method
*

View File

@ -0,0 +1,163 @@
<?php
namespace App\Test\TestCase\Controller;
use App\Controller\TransactionJsonRequestHandlerController;
use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase;
/**
* App\Controller\TransactionJsonRequestHandlerController Test Case
*
* @uses \App\Controller\TransactionJsonRequestHandlerController
*/
class TransactionJsonRequestHandlerControllerTest extends TestCase
{
use IntegrationTestTrait;
/**
* Fixtures
*
* @var array
*/
public $fixtures = [
'app.TransactionCreations',
'app.Transactions',
'app.StateUsers',
'app.TransactionSignatures',
'app.TransactionSendCoins',
'app.StateBalances',
'app.TransactionTypes'
];
public $transactions = [
'validCreation' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQJ8wF12eZo3hcMAlAKKJ9WLT-zuSkNmGh7D98UEqH4KoIysnCkXqEya9EBZl9o11_nJ8xmm_nOevuVjR-GfLMQ8qSQoOSGFsbG8gV2VsdCAxMjMSBgiZm4ruBUovCicKIJSuE1uTzZ8zdStOVcQZA6P6oTp1u5C_1BHqHUoaXnEfEKDakwEQtYntlgo',
'validCreation900' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQNVZ8Ae3Zbg3G0wZ840fzKan6N4KtTcSe0KYi17kQwFmsl18oFxXv8_s6j1xXFrIKjy1_1Olq0a7xYLErDMkjwYqORIGCNb5iu4FSi8KJwoglK4TW5PNnzN1K05VxBkDo_qhOnW7kL_UEeodShpecR8QgNHKCBC1ie2WCg',
'validCreation1200' => 'GmYKZAogYbkjwhjLY6ZKjGLzhgEhKDuVd_N00KMVkLoCzcKRKZkSQEEey5QMAdldoOTP_jTETHgOQriGsixEY0cziQeRfT_J5YtbI_A6AizEYD-JcxmRmXzv1xjjTgsV39Y32ta2CQkqORIGCIeGi-4FSi8KJwoglK4TW5PNnzN1K05VxBkDo_qhOnW7kL_UEeodShpecR8QgOy4CxC1ie2WCg',
'notBase64' => 'CgpIYWxsbyBXZW-0EgYIyfSG7gV_LwonCiCboKikqwjZfes9xuqgthFH3'
];
/*public function setUp() {
parent::setUp();
}
*/
public function testWrongMethod()
{
$this->configRequest([
'headers' => ['Accept' => 'application/json']
]);
$this->get('/TransactionJsonRequestHandler');
$this->assertResponseOk();
$expected = json_encode(['state' => 'error', 'msg' => 'no post']);
$this->assertEquals($expected, (string)$this->_response->getBody());
}
public function testInvalidJson()
{
$this->configRequest([
'headers' => ['Accept' => 'application/json']
]);
$this->post('/TransactionJsonRequestHandler', '{This isn\'t valid json}');
$this->assertResponseOk();
$expected = json_encode(['state' => 'error', 'msg' => 'parameter error']);
$this->assertEquals($expected, (string)$this->_response->getBody());
}
public function testNotSetTransaction()
{
$this->postAndParse(
['method' => 'putTransaction'],
['state' => 'error', 'msg' => 'parameter error']
);
}
public function testNotSetMethod()
{
$this->postAndParse(
['transaction' => $this->transactions['validCreation']],
['state' => 'error', 'msg' => 'parameter error']
);
}
public function testUnknownMethod()
{
//$this->post('/TransactionJsonRequestHandler', ['method' => 'putTransaction', 'transaction' => 'CgpIYWxsbyBXZWx0EgYIyfSG7gVKLwonCiCboKikqwjZfes9xuqgthFH3/cHHaWchkUhWiGhQjB23xCg2pMBELWJ7ZYK']);
$this->postAndParse(
['method' => 'foobar', 'transaction' => $this->transactions['validCreation']],
['state' => 'error', 'msg' => 'unknown method', 'details' => 'foobar']
);
}
public function testInvalidEncodedTransaction() {
//"msg":"error parsing transaction","details":[{"Transaction":"base64 decode error"}]
$this->postAndParse(
['method' => 'putTransaction', 'transaction' => $this->transactions['notBase64']],
['state' => 'error', 'msg' => 'error parsing transaction', 'details' => [
['Transaction' => 'invalid base64 string']
]]
);
}
public function testInvalidTransaction() {
$this->postAndParse(
['method' => 'putTransaction', 'transaction' => base64_encode('Hallo Miau Welt')],
['state' => 'error', 'msg' => 'error parsing transaction', 'details' => [
['Transaction' => 'Error occurred during parsing: Unexpected wire type.']
]]
);
}
public function testToLargeCreationSum()
{
$this->postAndParse(
['method' => 'putTransaction', 'transaction' => $this->transactions['validCreation900']],
'{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1000 gr per Month not allowed"}]}'
);
}
public function testToLargeCreation()
{
$this->postAndParse(
['method' => 'putTransaction', 'transaction' => $this->transactions['validCreation1200']],
'{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1000 gr per Month not allowed"}]}'
);
}
/*public function testMissingPreviousTransaction()
{
}*/
public function testValidTransaction()
{
$this->postAndParse(
['method' => 'putTransaction', 'transaction' => $this->transactions['validCreation']],
['state' => 'success']
);
}
private function postAndParse($params, $expected)
{
$this->configRequest([
'headers' => ['Accept' => 'application/json']
]);
$this->disableErrorHandlerMiddleware();
$this->post('/TransactionJsonRequestHandler', json_encode($params));
// Check that the response was a 200
$this->assertResponseOk();
$responseBodyString = (string)$this->_response->getBody();
$json = json_decode($responseBodyString);
$this->assertNotFalse($json);
if(is_array($expected)) {
$expected = json_encode($expected);
}
$this->assertEquals($expected, $responseBodyString);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
webroot/img/50x50.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

BIN
webroot/img/logo_half.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

75
webroot/js/basic.js Normal file
View File

@ -0,0 +1,75 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
// cross browser dom is ready module from:
// https://www.competa.com/blog/cross-browser-document-ready-with-vanilla-javascript/
var domIsReady = (function(domIsReady) {
var isBrowserIeOrNot = function() {
return (!document.attachEvent || typeof document.attachEvent === "undefined" ? 'not-ie' : 'ie');
}
domIsReady = function(callback) {
if(callback && typeof callback === 'function'){
if(isBrowserIeOrNot() !== 'ie') {
document.addEventListener("DOMContentLoaded", function() {
return callback();
});
} else {
document.attachEvent("onreadystatechange", function() {
if(document.readyState === "complete") {
return callback();
}
});
}
} else {
console.error('The callback is not a function!');
}
}
return domIsReady;
})(domIsReady || {});
/*
* var el = document.querySelector('.toggle-me');
el.onclick = function() {
el.classList.toggle('active');
}
*/
// cross browser dom is ready
(function(document, window, domIsReady, undefined) {
domIsReady(function() {
//console.log('My DOM is ready peeps!');
//document.querySelector('#page').style.background = 'blue';
//var Body = $("body");
var DesktopToggler = document.querySelector('.t-header-desk-toggler');
var MobileToggler = document.querySelector('.t-header-mobile-toggler');
var HeaderToggle = document.querySelector('.t-header-toggler');
// SIDEBAR TOGGLE FUNCTION FOR LARGE SCREENS (SCREEN "LG" AND UP)
if(DesktopToggler) {
DesktopToggler.addEventListener('click', function ()
{
//$(Body).toggleClass("sidebar-minimized");
document.body.classList.toggle('sidebar-minimized');
});
}
// SIDEBAR TOGGLE FUNCTION FOR MOBILE (SCREEN "MD" AND DOWN)
if(MobileToggler) {
MobileToggler.addEventListener('click', function () {
document.querySelector('.page-body').classList.toggle('sidebar-collpased');
});
}
if(HeaderToggle) {
HeaderToggle.addEventListener('click', function () {
HeaderToggle.classList.toggle('arrow');
});
}
});
})(document, window, domIsReady);

View File