diff --git a/src/Controller/Component/JsonRpcRequestClientComponent.php b/src/Controller/Component/JsonRpcRequestClientComponent.php
new file mode 100644
index 000000000..d5ca72808
--- /dev/null
+++ b/src/Controller/Component/JsonRpcRequestClientComponent.php
@@ -0,0 +1,71 @@
+rpcClient = new JsonRpcClient();
+ }
+
+ // @param id: if id = 0 call rand for it
+ public function request($method, $params = [], $id = 0)
+ {
+
+ if(0 == $id) {
+ $id = random_int(1, 12000);
+ }
+ $this->rpcClient->query($id, $method, $params);
+
+ $message = $this->rpcClient->encode();
+ return $this->sendRequest($message);
+ // message: {"jsonrpc":"2.0","method":"add","params":[1,2],"id":1}
+ }
+
+ public function sendRequest($message) {
+ $http = new Client();
+
+ $response = $http->post($this->getGradidoNodeUrl(), $message, ['type' => 'json']);
+ $responseStatus = $response->getStatusCode();
+ if($responseStatus != 200) {
+ return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response status code isn\'t 200', 'details' => $responseStatus];
+ }
+ //$responseType = $response->getType();
+ //if($responseType != 'application/json') {
+// return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response isn\'t json', 'details' => $responseType];
+// }
+ $json = $response->getJson();
+ if($json == null) {
+ //$responseType = $response->getType();
+ return ['state' => 'error', 'type' => 'request error', 'msg' => 'server response isn\'t valid json'];
+ }
+ return $json;
+ //return ['state' => 'success', 'data' => $json];
+ }
+
+ static public function getGradidoNodeUrl()
+ {
+ $gradidoNode = Configure::read('GradidoNode');
+ return $gradidoNode['host'] . ':' . $gradidoNode['port'];
+ }
+
+
+}
+
+
diff --git a/src/Form/DecodeTransaction.php b/src/Form/DecodeTransaction.php
new file mode 100644
index 000000000..3ac00faa6
--- /dev/null
+++ b/src/Form/DecodeTransaction.php
@@ -0,0 +1,8 @@
+controller = $controller;
+ $this->action = $action;
+ $this->param = $param;
+ $this->iconClass = $iconClass;
+ if($active != null) {
+ $this->active = $active;
+ } else {
+ $this->active = ($GLOBALS["side"] == $controller &&
+ $GLOBALS["subside"] == $action &&
+ $GLOBALS["passed"] == $param);
+ }
+ $this->title = $title;
+ $this->subtitle = $subtitle;
+ return $this;
+ }
+
+ public function setIconColor($iconColorClass) {
+ $this->iconColor = $iconColorClass;
+ return $this;
+ }
+ public function setBGColor($bgColorClass) {
+ $this->bgColorClass = $bgColorClass;
+ return $this;
+ }
+ private function isActive() {
+ return $this->active;
+ }
+
+
+
+ private function link() {
+ //global $self;
+ //echo "self: "; var_dump($GLOBALS("self"));
+ $self = $GLOBALS["self"];
+ if($this->hasChilds()) {
+ return $self->Html->link($this->title.'', ['controller' => $this->controller, "action" => $this->action, $this->param], ['escape' => false]);
+ } else {
+ //return $self->Html->link($this->title, ['controller' => $this->controller, "action" => $this->action, $this->param]);
+ return $self->Html->Link(
+ ''
+ .'' . $this->title . ''
+ .''
+ //.'' . $this->subtitle . ''
+ ,
+ ['controller' => $this->controller, 'action' => $this->action, $this->param],
+ ['class' => $this->bgColorClass, 'escape' => false]);
+ }
+ }
+
+ public function __toString() {
+ $str = "";
+ $str .= "
hasChilds()) { $class .= "dropdown";}
+ if($this->isActive()) { $class .= " active"; }
+ if(strlen($class) > 0 ) $str .= " class='$class'";
+ $str .= ">";
+
+ $str .= ''. $this->subtitle .'';
+ $str .= $this->link();
+
+ if($this->hasChilds()) {
+ $str .= "";
+ foreach($this->childs as $child) {
+ $str .= $child;
+ }
+ $str .= "
";
+ }
+ $str .= "";
+ return $str;
+ }
+}
\ No newline at end of file
diff --git a/src/Model/Transactions/SignatureMap.php b/src/Model/Transactions/SignatureMap.php
new file mode 100644
index 000000000..0606182d3
--- /dev/null
+++ b/src/Model/Transactions/SignatureMap.php
@@ -0,0 +1,48 @@
+mProtoSigMap = $protoSigMap;
+ }
+
+ public function getProto() {
+ return $this->mProtoSigMap;
+ }
+
+ static public function fromEntity($transactionSignatures)
+ {
+
+ $protoSigMap = new \Model\Messages\Gradido\SignatureMap();
+ $sigPairs = $protoSigMap->getSigPair();
+ //echo "sigPairs: "; var_dump($sigPairs); echo "
";
+ //return null;
+ foreach($transactionSignatures as $signature) {
+ $sigPair = new \Model\Messages\Gradido\SignaturePair();
+ $sigPair->setPubKey(stream_get_contents($signature->pubkey));
+ $sigPair->setEd25519(stream_get_contents($signature->signature));
+
+ $sigPairs[] = $sigPair;
+ //array_push($sigPairs, $sigPair);
+ }
+ return new SignatureMap($protoSigMap);
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/Template/Email/text/notification_creation.ctp b/src/Template/Email/text/notification_creation.ctp
new file mode 100644
index 000000000..65b91708d
--- /dev/null
+++ b/src/Template/Email/text/notification_creation.ctp
@@ -0,0 +1,19 @@
+assign('title', __('Gradido Schöpfung'));
+?>= __('Hallo') ?> = $user->first_name ?> = $user->last_name ?>,
+
+= __('Für dich wurden soeben {0} geschöpft.', $this->element('printGradido', ['number' => $gdd_cent, 'raw' => true])) ?>
+Gradido Akademie schreibt:
+
+= $memo ?>
+
+= __('Bitte antworte nicht auf diese E-Mail!'); ?>
+
+= __('Mit freundlichen Grüßen'); ?>
+Gradido Community Server
\ No newline at end of file
diff --git a/src/Template/Email/text/notification_transfer.ctp b/src/Template/Email/text/notification_transfer.ctp
new file mode 100644
index 000000000..2cc692e02
--- /dev/null
+++ b/src/Template/Email/text/notification_transfer.ctp
@@ -0,0 +1,21 @@
+assign('title', __('Gradido Überweisung'));
+$receiverNames = $receiverUser->first_name . ' ' . $receiverUser->last_name;
+$senderNames = $senderUser->first_name . ' ' . $senderUser->last_name;
+?>= __('Hallo') ?> = $receiverNames ?>,
+
+= __('Du hast soeben {0} von {1} erhalten.', $this->element('printGradido', ['number' => $gdd_cent, 'raw' => true]), $senderNames) ?>
+= __('{0} schreibt:', $senderNames) ?>
+
+= $memo ?>
+
+= __('Du kannst {0} eine Nachricht schreiben, indem du auf diese E-Mail antwortest', $senderNames); ?>
+
+= __('Mit freundlichen Grüßen'); ?>
+Gradido Community Server
\ No newline at end of file
diff --git a/src/Template/StateUsers/list_ident_hashes.ctp b/src/Template/StateUsers/list_ident_hashes.ctp
new file mode 100644
index 000000000..7f50910b1
--- /dev/null
+++ b/src/Template/StateUsers/list_ident_hashes.ctp
@@ -0,0 +1,29 @@
+
+
+
+
+
+ | first name | last name | email | identHash | Public key hex
+ |
+
+
+
+
+
+ | = $user->first_name ?> |
+ = $user->last_name ?> |
+ = $user->email ?> |
+ = $user->identHash ?> |
+ = bin2hex(stream_get_contents($user->public_key)) ?> |
+
+
+
+
+
diff --git a/src/Template/Transactions/decode.ctp b/src/Template/Transactions/decode.ctp
new file mode 100644
index 000000000..b9f840d2b
--- /dev/null
+++ b/src/Template/Transactions/decode.ctp
@@ -0,0 +1,36 @@
+
+ 0) : ?>
+
+
+
+ -
+ = var_dump($error); ?>
+
+
+
+
+
+
+= $this->Form->create() ?>
+= $this->Form->control('base64', ['type'=> 'textarea', 'rows' => '5', 'cols' => 40]) ?>
+= $this->Form->submit(); ?>
+= $this->Form->end() ?>
+
+
+getTransactionBody();
+?>
+
+ | Type | = $body->getTransactionTypeName() ?> |
+ | Memo | getMemo() ?> |
+
+= var_dump($transaction); ?>
+
diff --git a/src/Template/Transactions/send_to_node.ctp b/src/Template/Transactions/send_to_node.ctp
new file mode 100644
index 000000000..de6e82c76
--- /dev/null
+++ b/src/Template/Transactions/send_to_node.ctp
@@ -0,0 +1,91 @@
+assign('title', __('Transaktionen an Gradido-Node senden'));
+?>
+
+
+
+
+Bisher keine Transaktionen eingereicht
+
+Letzte eingereichte Transaktion = gTransactionIds[0] - 1 ?>
+
+
+
+ $id) : ?>
+ -
+ = $id ?>:
+
+
+ Wird verarbeitet
+
+ in Warteschlange
+
+
+
+
+
+= $this->Html->script(['core']); ?>
+
diff --git a/tests/Fixture/AdminErrorsFixture.php b/tests/Fixture/AdminErrorsFixture.php
new file mode 100644
index 000000000..0fbc3a067
--- /dev/null
+++ b/tests/Fixture/AdminErrorsFixture.php
@@ -0,0 +1,56 @@
+ ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null],
+ 'state_user_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
+ 'controller' => ['type' => 'string', 'length' => 255, 'null' => false, 'default' => null, 'collate' => 'utf8mb4_general_ci', 'comment' => '', 'precision' => null, 'fixed' => null],
+ 'action' => ['type' => 'string', 'length' => 255, 'null' => false, 'default' => null, 'collate' => 'utf8mb4_general_ci', 'comment' => '', 'precision' => null, 'fixed' => null],
+ 'state' => ['type' => 'string', 'length' => 255, 'null' => false, 'default' => null, 'collate' => 'utf8mb4_general_ci', 'comment' => '', 'precision' => null, 'fixed' => null],
+ 'msg' => ['type' => 'string', 'length' => 255, 'null' => false, 'default' => null, 'collate' => 'utf8mb4_general_ci', 'comment' => '', 'precision' => null, 'fixed' => null],
+ 'details' => ['type' => 'string', 'length' => 255, 'null' => false, 'default' => null, 'collate' => 'utf8mb4_general_ci', 'comment' => '', 'precision' => null, 'fixed' => null],
+ 'created' => ['type' => 'datetime', 'length' => null, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null],
+ '_constraints' => [
+ 'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []],
+ ],
+ '_options' => [
+ 'engine' => 'InnoDB',
+ 'collation' => 'utf8mb4_general_ci'
+ ],
+ ];
+ // @codingStandardsIgnoreEnd
+ /**
+ * Init method
+ *
+ * @return void
+ */
+ public function init()
+ {
+ $this->records = [
+ [
+ 'id' => 1,
+ 'state_user_id' => 1,
+ 'controller' => 'Lorem ipsum dolor sit amet',
+ 'action' => 'Lorem ipsum dolor sit amet',
+ 'state' => 'Lorem ipsum dolor sit amet',
+ 'msg' => 'Lorem ipsum dolor sit amet',
+ 'details' => 'Lorem ipsum dolor sit amet',
+ 'created' => '2019-12-16 15:08:19'
+ ],
+ ];
+ parent::init();
+ }
+}
diff --git a/tests/Fixture/StateErrorsFixture.php b/tests/Fixture/StateErrorsFixture.php
new file mode 100644
index 000000000..6f0d95e26
--- /dev/null
+++ b/tests/Fixture/StateErrorsFixture.php
@@ -0,0 +1,50 @@
+ ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null],
+ 'state_user_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
+ 'transaction_type_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
+ 'created' => ['type' => 'datetime', 'length' => null, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null],
+ 'message_json' => ['type' => 'text', 'length' => null, 'null' => false, 'default' => null, 'collate' => 'utf8mb4_general_ci', 'comment' => '', 'precision' => null],
+ '_constraints' => [
+ 'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []],
+ ],
+ '_options' => [
+ 'engine' => 'InnoDB',
+ 'collation' => 'utf8mb4_general_ci'
+ ],
+ ];
+ // @codingStandardsIgnoreEnd
+ /**
+ * Init method
+ *
+ * @return void
+ */
+ public function init()
+ {
+ $this->records = [
+ [
+ 'id' => 1,
+ 'state_user_id' => 1,
+ 'transaction_type_id' => 1,
+ 'created' => '2019-11-07 13:13:12',
+ 'message_json' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida, phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit, feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.'
+ ],
+ ];
+ parent::init();
+ }
+}
diff --git a/tests/TestCase/Controller/AdminErrorsControllerTest.php b/tests/TestCase/Controller/AdminErrorsControllerTest.php
new file mode 100644
index 000000000..a9044b4ae
--- /dev/null
+++ b/tests/TestCase/Controller/AdminErrorsControllerTest.php
@@ -0,0 +1,76 @@
+markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test view method
+ *
+ * @return void
+ */
+ public function testView()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test add method
+ *
+ * @return void
+ */
+ public function testAdd()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test edit method
+ *
+ * @return void
+ */
+ public function testEdit()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test delete method
+ *
+ * @return void
+ */
+ public function testDelete()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+}
diff --git a/tests/TestCase/Controller/AppControllerTest.php b/tests/TestCase/Controller/AppControllerTest.php
new file mode 100644
index 000000000..79294cbe0
--- /dev/null
+++ b/tests/TestCase/Controller/AppControllerTest.php
@@ -0,0 +1,46 @@
+session(['StateUser.id' => 1]);
+ $this->get('/');
+ $this->assertSession(1200, 'StateUser.balance');
+ //$this->markTestIncomplete('Not implemented yet.');
+ }
+
+
+}
diff --git a/tests/TestCase/Controller/Component/JsonRequestClientComponentTest.php b/tests/TestCase/Controller/Component/JsonRequestClientComponentTest.php
new file mode 100644
index 000000000..fb882478a
--- /dev/null
+++ b/tests/TestCase/Controller/Component/JsonRequestClientComponentTest.php
@@ -0,0 +1,84 @@
+JsonRequestClientComponent = new JsonRequestClientComponent($registry);
+ }
+
+ /**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown()
+ {
+ unset($this->JsonRequestClientComponent);
+
+ parent::tearDown();
+ }
+
+ /**
+ * Test sendTransaction method
+ *
+ * @return void
+ */
+ public function testSendTransaction()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test getLoginServerUrl method
+ *
+ * @return void
+ */
+ public function testGetLoginServerUrl()
+ {
+ //$this->markTestIncomplete('Not implemented yet.');
+ $serverUrl = $this->JsonRequestClientComponent->getLoginServerUrl();
+ $this->assertEquals($serverUrl, 'http://***REMOVED***');
+ }
+
+ /**
+ * Test is_base64 method
+ *
+ * @return void
+ */
+ public function testIsBase64Valid()
+ {
+ $result = $this->JsonRequestClientComponent->is_base64('CgpIYWxsbyBXZWx0EgYIr6fe7wVKLwonCiDWDyYU4+zldTQdQMIzGpsL20W+vV44JuNVA5hwczIELRDgg5sBELmhkoIE');
+
+ $this->assertEquals($result, true);
+ }
+
+ public function testIsBase64Invalid()
+ {
+ $result = $this->JsonRequestClientComponent->is_base64('CgpIYWxsbyBXZWx0EgYIr6fe7wVKLwonCiDWDyYU4-zldTQdQMIzGpsL20W+vV44JuNVA5hwczIELRDgg5sBELmhkoIE');
+
+ $this->assertEquals($result, false);
+ }
+}
diff --git a/tests/TestCase/Controller/StateErrorsControllerTest.php b/tests/TestCase/Controller/StateErrorsControllerTest.php
new file mode 100644
index 000000000..452af54fc
--- /dev/null
+++ b/tests/TestCase/Controller/StateErrorsControllerTest.php
@@ -0,0 +1,77 @@
+markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test view method
+ *
+ * @return void
+ */
+ public function testView()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test add method
+ *
+ * @return void
+ */
+ public function testAdd()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test edit method
+ *
+ * @return void
+ */
+ public function testEdit()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test delete method
+ *
+ * @return void
+ */
+ public function testDelete()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+}