mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into login_build_alpine
This commit is contained in:
commit
8574c07e90
20
.github/ISSUE_TEMPLATE/bug_report.md
vendored
20
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -5,21 +5,5 @@ labels: bug
|
||||
title: 🐛 [Bug]
|
||||
---
|
||||
|
||||
## :bug: Bugreport
|
||||
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the bug is.-->
|
||||
|
||||
### Steps to reproduce the behavior
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4. ...
|
||||
5. Profit
|
||||
|
||||
### Expected behavior
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
### Version & Environment
|
||||
<!-- Add context about your environment and used version here. -->
|
||||
|
||||
### Additional context
|
||||
<!-- Add any other context about the problem here. -->
|
||||
## 🐛 Bugreport
|
||||
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the bug is.--
|
||||
|
||||
15
.github/ISSUE_TEMPLATE/devops_ticket.md
vendored
15
.github/ISSUE_TEMPLATE/devops_ticket.md
vendored
@ -7,18 +7,3 @@ title: 💥 [DevOps]
|
||||
|
||||
## 💥 DevOps ticket
|
||||
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the problem is.-->
|
||||
|
||||
### Motive
|
||||
<!-- Why does this task need to be done? What can we benefit from this? -->
|
||||
|
||||
### Related issues
|
||||
<!-- Are there any related issues to link to? Please paste them below for reference. -->
|
||||
|
||||
### Implementation
|
||||
<!-- Please, document any ideas of how the task can be performed. -->
|
||||
|
||||
### Validation
|
||||
<!-- How can we make sure that this task was successful? -->
|
||||
|
||||
### Additional context
|
||||
<!-- Add other context or background about the feature request here.-->
|
||||
|
||||
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -5,20 +5,5 @@ labels: feature
|
||||
title: 🚀 [Feature]
|
||||
---
|
||||
|
||||
## :rocket: Feature
|
||||
## 🚀 Feature
|
||||
<!-- Give a short summary of the Feature. Use Screenshots if you want. -->
|
||||
|
||||
### User Problem
|
||||
<!-- Which problem is this solving? Why do you think this is important? Who will benefit from it and how? -->
|
||||
|
||||
### Implementation
|
||||
<!-- How do you think this feature should be implemented? How will it be used? Where in the network should it be located? Which steps and screens are involved? -->
|
||||
|
||||
### Design & Layout
|
||||
<!-- Attach Screenshots and Sketches to illustrate your idea. -->
|
||||
|
||||
### Validation
|
||||
<!-- How can we make sure that this feature indeed solves the above problem? How do we know if it has been accepted by the users of the network, once released? -->
|
||||
|
||||
### Additional context
|
||||
<!-- Add other context or background about the feature request here.-->
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/question.md
vendored
4
.github/ISSUE_TEMPLATE/question.md
vendored
@ -1,11 +1,11 @@
|
||||
---
|
||||
name: 💬 Question
|
||||
about: If you need help understanding HumanConnection.
|
||||
about: If you need help understanding Gradido.
|
||||
labels: question
|
||||
title: 💬 [Question]
|
||||
---
|
||||
<!-- Chat with Team Gradido -->
|
||||
<!-- If you need an answer right away, visit the Gradido Discord: https://discord.gg/kA3zBAKQDC -->
|
||||
|
||||
## :speech_balloon: Question
|
||||
## 💬 Question
|
||||
<!-- Describe your Question in detail. Include screenshots and drawings if needed. -->
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/refactor_tickets.md
vendored
14
.github/ISSUE_TEMPLATE/refactor_tickets.md
vendored
@ -5,17 +5,5 @@ labels: refactor
|
||||
title: 🔧 [Refactor]
|
||||
---
|
||||
|
||||
## :zap: Refactor ticket
|
||||
## 🔧 Refactor ticket
|
||||
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the problem is.-->
|
||||
|
||||
### Motive
|
||||
<!-- What is the purpose of this refactoring? If it's removing depcrecated code, please link to the deprecation notice. -->
|
||||
|
||||
### Related issues
|
||||
<!-- Are there any related issues to link to? Please paste them below for reference. -->
|
||||
|
||||
### Implementation
|
||||
<!-- Please, document any ideas of how the code should be refactored. -->
|
||||
|
||||
### Additional context
|
||||
<!-- Add other context or background about the feature request here.-->
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -212,7 +212,7 @@ jobs:
|
||||
report_name: Coverage Frontend
|
||||
type: lcov
|
||||
result_path: ./coverage/lcov.info
|
||||
min_coverage: 12
|
||||
min_coverage: 15
|
||||
token: ${{ github.token }}
|
||||
|
||||
#test:
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
CREATE TABLE `address_types` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(25) NOT NULL,
|
||||
`text` VARCHAR(255) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,7 +0,0 @@
|
||||
CREATE TABLE `operators` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT ,
|
||||
`username` VARCHAR(128) NOT NULL ,
|
||||
`data_base64` VARCHAR(255) NOT NULL ,
|
||||
PRIMARY KEY (`id`), UNIQUE (`username`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
|
||||
@ -3,7 +3,7 @@ CREATE TABLE `transaction_creations` (
|
||||
`transaction_id` int(10) unsigned NOT NULL,
|
||||
`state_user_id` int(10) unsigned NOT NULL,
|
||||
`amount` bigint(20) NOT NULL,
|
||||
`ident_hash` binary(32) NOT NULL,
|
||||
`ident_hash` binary(32) NULL,
|
||||
`target_date` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
@ -1,7 +0,0 @@
|
||||
CREATE TABLE `state_balances` (
|
||||
`id` int(11) NOT NULL,
|
||||
`state_user_id` int(11) NOT NULL,
|
||||
`modified` datetime NOT NULL,
|
||||
`amount` bigint(20) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,10 +0,0 @@
|
||||
CREATE TABLE `state_created` (
|
||||
`id` int(11) NOT NULL,
|
||||
`transaction_id` int(11) NOT NULL,
|
||||
`month` tinyint(4) NOT NULL,
|
||||
`year` smallint(6) NOT NULL,
|
||||
`state_user_id` int(11) NOT NULL,
|
||||
`created` datetime NOT NULL,
|
||||
`short_ident_hash` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`), INDEX(`short_ident_hash`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,7 +0,0 @@
|
||||
CREATE TABLE `state_group_addresses` (
|
||||
`id` int(11) NOT NULL,
|
||||
`state_group_id` int(11) NOT NULL,
|
||||
`public_key` binary(32) NOT NULL,
|
||||
`address_type_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,7 +0,0 @@
|
||||
CREATE TABLE `state_group_relationships` (
|
||||
`id` int(11) NOT NULL,
|
||||
`state_group1_id` int(11) NOT NULL,
|
||||
`state_group2_id` int(11) NOT NULL,
|
||||
`state_relationship_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,8 +0,0 @@
|
||||
CREATE TABLE `state_groups` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`index_id` VARBINARY(64) NOT NULL,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
`root_public_key` BINARY(32) NOT NULL,
|
||||
`user_count` SMALLINT NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,6 +0,0 @@
|
||||
CREATE TABLE `state_relationship_types` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` varchar(25) COLLATE utf8_bin NOT NULL,
|
||||
`text` varchar(255) COLLATE utf8_bin DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,7 +0,0 @@
|
||||
CREATE TABLE `state_users` (
|
||||
`id` int(11) NOT NULL,
|
||||
`index_id` smallint(6) NOT NULL,
|
||||
`state_group_id` int(11) NOT NULL,
|
||||
`public_key` binary(32) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,10 +0,0 @@
|
||||
|
||||
CREATE TABLE `transaction_creations` (
|
||||
`id` int(11) NOT NULL,
|
||||
`transaction_id` int(11) NOT NULL,
|
||||
`state_user_id` int(11) NOT NULL,
|
||||
`amount` bigint(20) NOT NULL,
|
||||
`ident_hash` binary(32) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
|
||||
CREATE TABLE `transaction_group_addaddress` (
|
||||
`id` int(11) NOT NULL,
|
||||
`transaction_id` int(11) NOT NULL,
|
||||
`address_type_id` int(11) NOT NULL,
|
||||
`public_key` binary(32) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,8 +0,0 @@
|
||||
|
||||
CREATE TABLE `transaction_group_allowtrades` (
|
||||
`id` int(11) NOT NULL,
|
||||
`transaction_id` int(11) NOT NULL,
|
||||
`group_id` int(11) NOT NULL,
|
||||
`allow` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,9 +0,0 @@
|
||||
|
||||
CREATE TABLE `transaction_group_creates` (
|
||||
`id` int(11) NOT NULL,
|
||||
`transaction_id` int(11) NOT NULL,
|
||||
`group_public_key` binary(32) NOT NULL,
|
||||
`state_group_id` int(11) COLLATE utf8_bin NOT NULL,
|
||||
`name` varchar(64) COLLATE utf8_bin NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,11 +0,0 @@
|
||||
|
||||
CREATE TABLE `transaction_send_coins` (
|
||||
`id` int(11) NOT NULL,
|
||||
`transaction_id` int(11) NOT NULL,
|
||||
`state_user_id` int(11) NOT NULL,
|
||||
`receiver_public_key` binary(32) NOT NULL,
|
||||
`receiver_user_id` varbinary(64) NOT NULL,
|
||||
`amount` bigint(20) NOT NULL,
|
||||
`sender_final_balance` bigint(20) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,7 +0,0 @@
|
||||
CREATE TABLE `transaction_signatures` (
|
||||
`id` int(11) NOT NULL,
|
||||
`transaction_id` int(11) NOT NULL,
|
||||
`signature` binary(64) NOT NULL,
|
||||
`pubkey` binary(32) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,6 +0,0 @@
|
||||
CREATE TABLE `transaction_types` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(24) NOT NULL,
|
||||
`text` VARCHAR(255) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -1,9 +0,0 @@
|
||||
|
||||
CREATE TABLE `transactions` (
|
||||
`id` bigint(20) NOT NULL,
|
||||
`state_group_id` int(11) NOT NULL,
|
||||
`transaction_type_id` int(11) NOT NULL,
|
||||
`tx_hash` binary(32) NOT NULL,
|
||||
`received` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
|
||||
@ -167,13 +167,15 @@ class AppController extends Controller
|
||||
$php_session_id = intval($session->read('session_id'));
|
||||
}
|
||||
$cookie_session_id = intval($this->request->getCookie('GRADIDO_LOGIN', ''));
|
||||
if($php_session_id != 0) {
|
||||
// decide in which order session_ids are tried
|
||||
if($sessionId != 0) {
|
||||
$session_id = $sessionId;
|
||||
} else if($php_session_id != 0) {
|
||||
$session_id = $php_session_id;
|
||||
} else if($cookie_session_id != 0) {
|
||||
$session_id = $cookie_session_id;
|
||||
} else {
|
||||
$session_id = $sessionId;
|
||||
}
|
||||
}
|
||||
|
||||
$ip = $this->request->clientIp();
|
||||
if (!$session->check('client_ip')) {
|
||||
$session->write('client_ip', $ip);
|
||||
|
||||
@ -61,8 +61,8 @@ class AppRequestsController extends AppController
|
||||
if(is_array($field)) {
|
||||
$one_exist = false;
|
||||
foreach($field as $oneField) {
|
||||
if(isset($data[$oneField])) {
|
||||
$param[$oneField] = $data[$oneField];
|
||||
if(isset($data->$oneField)) {
|
||||
$param[$oneField] = $data->$oneField;
|
||||
$one_exist = true;
|
||||
break;
|
||||
}
|
||||
@ -71,10 +71,10 @@ class AppRequestsController extends AppController
|
||||
return ['state' => 'error', 'msg' => 'missing field of set', 'details' => $field];
|
||||
}
|
||||
} else {
|
||||
if(!isset($data[$field])) {
|
||||
if(!isset($data->$field)) {
|
||||
return ['state' => 'error', 'msg' => 'missing field', 'details' => $field . ' not found'];
|
||||
} else {
|
||||
$param[$field] = $data[$field];
|
||||
$param[$field] = $data->$field;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -85,9 +85,9 @@ class AppRequestsController extends AppController
|
||||
{
|
||||
foreach(array_keys($replaceKeys) as $key) {
|
||||
$newKey = $replaceKeys[$key];
|
||||
if(isset($data[$key])) {
|
||||
$data[$newKey] = $data[$key];
|
||||
unset($data[$key]);
|
||||
if(isset($data->$key)) {
|
||||
$data->$newKey = $data->$key;
|
||||
unset($data->$key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,8 +98,8 @@ class AppRequestsController extends AppController
|
||||
$data = $this->request->input('json_decode');
|
||||
}
|
||||
$session_id = 0;
|
||||
if(isset($data['session_id'])) {
|
||||
$session_id = $data['session_id'];
|
||||
if(isset($data->session_id)) {
|
||||
$session_id = $data->session_id;
|
||||
}
|
||||
$login_request_result = $this->requestLogin($session_id, false);
|
||||
if($login_request_result !== true) {
|
||||
@ -119,12 +119,12 @@ class AppRequestsController extends AppController
|
||||
return ['state' => 'error', 'msg' => 'amount is invalid', 'details' => $param['amount']];
|
||||
}
|
||||
|
||||
if(isset($data['memo'])) {
|
||||
$param['memo'] = $data['memo'];
|
||||
if(isset($data->memo)) {
|
||||
$param['memo'] = $data->memo;
|
||||
}
|
||||
|
||||
if(isset($data['auto_sign'])) {
|
||||
$param['auto_sign'] = boolval($data['auto_sign']);
|
||||
if(isset($data->auto_sign)) {
|
||||
$param['auto_sign'] = boolval($data->auto_sign);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -317,7 +317,6 @@ class AppRequestsController extends AppController
|
||||
$gdtSum = intval($gdtEntries['data']['sum']);
|
||||
} else {
|
||||
$this->addAdminError('StateBalancesController', 'overview', $gdtEntries, $user['id'] ? $user['id'] : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -330,11 +329,13 @@ class AppRequestsController extends AppController
|
||||
->page($page)
|
||||
;
|
||||
$decay = true;
|
||||
$transactions = $transactionsTable->listTransactionsHumanReadable($stateUserTransactionsQuery->toArray(), $user, $decay);
|
||||
$transactions = [];
|
||||
if($stateUserTransactionsQuery->count() > 0) {
|
||||
$transactions = $transactionsTable->listTransactionsHumanReadable($stateUserTransactionsQuery->toArray(), $user, $decay);
|
||||
|
||||
|
||||
if($orderDirection == 'DESC') {
|
||||
$transactions = array_reverse($transactions);
|
||||
if($orderDirection == 'DESC') {
|
||||
$transactions = array_reverse($transactions);
|
||||
}
|
||||
}
|
||||
return $this->returnJson([
|
||||
'state' => 'success',
|
||||
|
||||
@ -180,7 +180,7 @@ class StateBalancesTable extends Table
|
||||
|
||||
$transactions = $transactionsTable
|
||||
->find('all')
|
||||
->where(['id IN' => array_keys($transaction_ids)])
|
||||
->where(['Transactions.id IN' => array_keys($transaction_ids)])
|
||||
->contain(['TransactionCreations', 'TransactionSendCoins']);
|
||||
|
||||
$transactions_indiced = [];
|
||||
@ -199,7 +199,7 @@ class StateBalancesTable extends Table
|
||||
$amount = 0;
|
||||
|
||||
if($transaction->transaction_type_id == 1) { // creation
|
||||
$temp = $transaction->transaction_creations[0];
|
||||
$temp = $transaction->transaction_creation;
|
||||
|
||||
/*$balance_temp = $this->newEntity();
|
||||
$balance_temp->amount = $temp->amount;
|
||||
@ -211,7 +211,7 @@ class StateBalancesTable extends Table
|
||||
//$amount_date =
|
||||
} else if($transaction->transaction_type_id == 2) { // transfer
|
||||
|
||||
$temp = $transaction->transaction_send_coins[0];
|
||||
$temp = $transaction->transaction_send_coin;
|
||||
$amount = intval($temp->amount);
|
||||
// reverse if sender
|
||||
if($stateUserId == $temp->state_user_id) {
|
||||
|
||||
@ -427,6 +427,6 @@ return [
|
||||
],
|
||||
'ServerAdminEmail' => 'info@gradido.net',
|
||||
'noReplyEmail' => 'no-reply@gradido.net',
|
||||
'disableEmail' => false
|
||||
'disableEmail' => true
|
||||
|
||||
];
|
||||
|
||||
@ -22,7 +22,7 @@ loginServer.db.user = root
|
||||
loginServer.db.password =
|
||||
loginServer.db.port = 3306
|
||||
|
||||
frontend.checkEmailPath = http://localhost/account/checkEmail
|
||||
frontend.checkEmailPath = http://localhost/reset
|
||||
|
||||
email.disable = true
|
||||
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `host`, `home`, `description`) VALUES
|
||||
(1, 'docker', 'docker gradido group', 'localhost', 'nginx', '/', 'gradido test group for docker and stage2 with blockchain db');
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `home`, `description`) VALUES
|
||||
(1, 'dockerStage2', 'docker stage2 gradido group', 'localhost', '/', 'gradido test group for docker and stage2');
|
||||
|
||||
INSERT INTO `hedera_ids` (`id`, `shardNum`, `realmNum`, `num`) VALUES
|
||||
(1, 0, 0, 3),
|
||||
(2, 0, 0, 3327),
|
||||
(3, 0, 0, 413151);
|
||||
|
||||
INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES
|
||||
(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 1, '2000-01-01 00:00:00');
|
||||
|
||||
INSERT INTO `hedera_accounts` (`id`, `user_id`, `account_hedera_id`, `account_key_id`, `balance`, `network_type`, `updated`) VALUES
|
||||
(1, 1, 2, 1, 1000000000000, 1, '2021-01-07 10:22:52');
|
||||
|
||||
INSERT INTO `hedera_topics` (`id`, `topic_hedera_id`, `name`, `auto_renew_account_hedera_id`, `auto_renew_period`, `group_id`, `admin_key_id`, `submit_key_id`, `current_timeout`, `sequence_number`, `running_hash`, `running_hash_version`, `updated`) VALUES
|
||||
(1, 3, 'dockerStage2', 1, 7890000, 1, 0, 0, '2021-06-08 23:17:19', 0, NULL, 0, '2021-03-09 16:42:34');
|
||||
|
||||
|
||||
|
||||
INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `host`, `home`, `description`) VALUES
|
||||
(2, 'dockerStage2', 'docker stage2 gradido group', 'localhost', 'nginx', '/', 'gradido test group for docker and stage2');
|
||||
|
||||
INSERT INTO `hedera_ids` (`id`, `shardNum`, `realmNum`, `num`) VALUES
|
||||
(1, 0, 0, 3),
|
||||
(2, 0, 0, 3327),
|
||||
(3, 0, 0, 413151);
|
||||
|
||||
INSERT INTO `node_servers` (`id`, `url`, `port`, `group_id`, `server_type`, `node_hedera_id`, `last_live_sign`) VALUES
|
||||
(1, 'http://0.testnet.hedera.com', 50211, 0, 4, 2, '2000-01-01 00:00:00');
|
||||
|
||||
INSERT INTO `hedera_accounts` (`id`, `user_id`, `account_hedera_id`, `account_key_id`, `balance`, `network_type`, `updated`) VALUES
|
||||
(1, 1, 2, 1, 1000000000000, 1, '2021-01-07 10:22:52');
|
||||
|
||||
INSERT INTO `hedera_topics` (`id`, `topic_hedera_id`, `name`, `auto_renew_account_hedera_id`, `auto_renew_period`, `group_id`, `admin_key_id`, `submit_key_id`, `current_timeout`, `sequence_number`, `running_hash`, `running_hash_version`, `updated`) VALUES
|
||||
(1, 3, 'dockerStage2', 1, 7890000, 1, 0, 0, '2021-06-08 23:17:19', 0, NULL, 0, '2021-03-09 16:42:34');
|
||||
|
||||
|
||||
|
||||
@ -8,6 +8,8 @@ services:
|
||||
image: gradido/frontend:development
|
||||
build:
|
||||
target: development
|
||||
networks:
|
||||
- external-net
|
||||
environment:
|
||||
- NODE_ENV="development"
|
||||
# - DEBUG=true
|
||||
|
||||
@ -15,13 +15,13 @@ services:
|
||||
context: ./frontend
|
||||
target: production
|
||||
networks:
|
||||
- external-net
|
||||
- internal-net
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 3000:3000
|
||||
environment:
|
||||
# Envs used in Dockerfile
|
||||
# - DOCKER_WORKDIR="/app"
|
||||
# - PORT="8080"
|
||||
# - PORT=3000
|
||||
- BUILD_DATE
|
||||
- BUILD_VERSION
|
||||
- BUILD_COMMIT
|
||||
|
||||
@ -150,6 +150,7 @@ with
|
||||
- `session_id`: optional, only used if cookie GRADIDO_LOGIN not exist and no sesion_id in php session
|
||||
- `email` or `username` or `pubkey`: used to identify how gets the gradidos (email and username are only aliases for pubkey)
|
||||
- `amount`: gdd amount to transfer in gradido cent (10000000 = 1000,00 GDD)
|
||||
- `target_date`: target date for creation, can be max 3 months before current date, but not after current date, allowed formats do you find here: https://pocoproject.org/docs/Poco.DateTimeFormat.html
|
||||
- `memo`: text for receiver, currently saved as clear text in blockchain
|
||||
- `auto_sign`: if set to true, transaction will be directly signed on login-server and proceed if needed signs are there
|
||||
if set to false, transaction must be signed after on `http://localhost/account/checkTransactions`
|
||||
|
||||
@ -56,6 +56,7 @@ In case of success returns:
|
||||
"first_name": "Max",
|
||||
"group_alias": "gdd1",
|
||||
"ident_hash": 323769895,
|
||||
"language":"de",
|
||||
"last_name": "Mustermann",
|
||||
"public_hex": "131c7f68dd94b2be4c913400ff7ff4cdc03ac2bda99c2d29edcacb3b065c67e6",
|
||||
"role": "none",
|
||||
@ -74,6 +75,7 @@ In case of success returns:
|
||||
- `first_name`: first name of user
|
||||
- `group_alias`: alias of group/community to which user belong
|
||||
- `ident_hash`: currently hash of email, will be later a identification hash to prevent multiple accounts and therefore multiple creations per user
|
||||
- `language`: language of user, currently only "de" or "en"
|
||||
- `last_name`: last name of user
|
||||
- `public_hex`: public key of user in hex format
|
||||
- `role`: role of user currently only "none" or "admin"
|
||||
@ -302,6 +304,7 @@ In case of success returns:
|
||||
"first_name": "Max",
|
||||
"group_alias": "gdd1",
|
||||
"ident_hash": 323769895,
|
||||
"language": "de",
|
||||
"last_name": "Mustermann",
|
||||
"public_hex": "131c7f68dd94b2be4c913400ff7ff4cdc03ac2bda99c2d29edcacb3b065c67e6",
|
||||
"role": "none",
|
||||
@ -326,6 +329,7 @@ In case of success returns:
|
||||
- `first_name`: first name of user
|
||||
- `group_alias`: alias of group/community to which user belong
|
||||
- `ident_hash`: currently hash of email, will be later a identification hash to prevent multiple accounts and therefore multiple creations per user
|
||||
- `language`: language of user, currently only "de" or "en"
|
||||
- `last_name`: last name of user
|
||||
- `public_hex`: public key of user in hex format
|
||||
- `role`: role of user currently only "none" or "admin"
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
LOGIN_API_URL=http://localhost/login_api/
|
||||
COMMUNITY_API_URL=http://localhost/api/
|
||||
VUE_PATH=/vue
|
||||
ALLOW_REGISTER=true
|
||||
@ -15,7 +15,7 @@ ENV BUILD_COMMIT="0000000"
|
||||
## SET NODE_ENV
|
||||
ENV NODE_ENV="production"
|
||||
## App relevant Envs
|
||||
ENV PORT="8080"
|
||||
ENV PORT="3000"
|
||||
|
||||
# Labels
|
||||
LABEL org.label-schema.build-date="${BUILD_DATE}"
|
||||
@ -82,15 +82,14 @@ FROM base as production
|
||||
|
||||
# Copy "binary"-files from build image
|
||||
COPY --from=build ${DOCKER_WORKDIR}/dist ./dist
|
||||
#COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
|
||||
#COPY --from=build ${DOCKER_WORKDIR}/nuxt.config.js ./nuxt.config.js
|
||||
# We also copy the node_modules express and serve-static for the run script
|
||||
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
|
||||
# Copy static files
|
||||
# TODO - this should be one Folder containign all stuff needed to be copied
|
||||
#COPY --from=build ${DOCKER_WORKDIR}/constants ./constants
|
||||
#COPY --from=build ${DOCKER_WORKDIR}/static ./static
|
||||
#COPY --from=build ${DOCKER_WORKDIR}/locales ./locales
|
||||
COPY --from=build ${DOCKER_WORKDIR}/public ./public
|
||||
# Copy package.json for script definitions (lock file should not be needed)
|
||||
COPY --from=build ${DOCKER_WORKDIR}/package.json ./package.json
|
||||
# Copy run scripts run/
|
||||
COPY --from=build ${DOCKER_WORKDIR}/run ./run
|
||||
|
||||
# Run command
|
||||
CMD /bin/sh -c "yarn run start"
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"version": "0.9.4",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"start": "node run/server.js",
|
||||
"serve": "vue-cli-service serve --open",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "eslint --ext .js,.vue .",
|
||||
@ -69,6 +69,7 @@
|
||||
"vue-good-table": "^2.21.3",
|
||||
"vue-i18n": "^8.22.4",
|
||||
"vue-jest": "^3.0.7",
|
||||
"vue-loading-overlay": "^3.4.2",
|
||||
"vue-moment": "^4.1.0",
|
||||
"vue-qrcode": "^0.3.5",
|
||||
"vue-qrcode-reader": "^2.3.16",
|
||||
|
||||
14
frontend/run/server.js
Normal file
14
frontend/run/server.js
Normal file
@ -0,0 +1,14 @@
|
||||
// Imports
|
||||
const express = require('express')
|
||||
const serveStatic = require('serve-static')
|
||||
|
||||
// Port
|
||||
const port = process.env.PORT || 3000
|
||||
|
||||
// Express Server
|
||||
const app = express()
|
||||
app.use(serveStatic(__dirname + '/../dist'))
|
||||
app.listen(port)
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`http://frontend:${port} server started.`)
|
||||
@ -1,7 +0,0 @@
|
||||
var express = require('express')
|
||||
var serveStatic = require('serve-static')
|
||||
var app = express()
|
||||
app.use(serveStatic(__dirname + '/dist'))
|
||||
var port = process.env.PORT || 5000
|
||||
app.listen(port)
|
||||
// console.log('http://localhost:5000 server started.');
|
||||
@ -36,7 +36,7 @@ const communityAPI = {
|
||||
return apiGet(CONFIG.COMMUNITY_API_URL + 'getBalance/' + session_id)
|
||||
},
|
||||
transactions: async (session_id) => {
|
||||
return apiGet(CONFIG.COMMUNITY_API__URL + 'listTransactions/1/25/ASC/' + session_id)
|
||||
return apiGet(CONFIG.COMMUNITY_API_URL + 'listTransactions/1/25/ASC/' + session_id)
|
||||
},
|
||||
/*create: async (session_id, email, amount, memo, target_date = new Date() ) => {
|
||||
const payload = {
|
||||
@ -49,15 +49,16 @@ const communityAPI = {
|
||||
}
|
||||
return apiPost(CONFIG.COMMUNITY_API__URL + 'createCoins/', payload)
|
||||
},*/
|
||||
send: async (session_id, email, amount, memo) => {
|
||||
send: async (session_id, email, amount, memo, target_date) => {
|
||||
const payload = {
|
||||
session_id,
|
||||
email,
|
||||
amount,
|
||||
memo,
|
||||
target_date,
|
||||
auto_sign: true,
|
||||
}
|
||||
return apiPost(CONFIG.COMMUNITY_API__URL + 'sendCoins/', payload)
|
||||
return apiPost(CONFIG.COMMUNITY_API_URL + 'sendCoins/', payload)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -64,7 +64,6 @@ const loginAPI = {
|
||||
return apiPost(CONFIG.LOGIN_API_URL + 'createUser', payload)
|
||||
},
|
||||
sendEmail: async (email, email_text = 7, email_verification_code_type = 'resetPassword') => {
|
||||
//console.log('api email', email)
|
||||
const payload = {
|
||||
email,
|
||||
email_text,
|
||||
@ -72,6 +71,21 @@ const loginAPI = {
|
||||
}
|
||||
return apiPost(CONFIG.LOGIN_API_URL + 'sendEmail', payload)
|
||||
},
|
||||
loginViaEmailVerificationCode: async (optin) => {
|
||||
return apiGet(
|
||||
CONFIG.LOGIN_API_URL + 'loginViaEmailVerificationCode?emailVerificationCode=' + optin,
|
||||
)
|
||||
},
|
||||
changePassword: async (session_id, email, password) => {
|
||||
const payload = {
|
||||
session_id,
|
||||
email,
|
||||
update: {
|
||||
'User.password': password,
|
||||
},
|
||||
}
|
||||
return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
||||
},
|
||||
}
|
||||
|
||||
export default loginAPI
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<img :src="logo" class="navbar-brand-img" alt="..." />
|
||||
</div>
|
||||
<b-row class="text-center">
|
||||
<b-col>{{ $n($store.state.user.balance) }} GDD</b-col>
|
||||
<b-col>{{ $n(balance) }} GDD</b-col>
|
||||
</b-row>
|
||||
<slot name="mobile-right">
|
||||
<ul class="nav align-items-center d-md-none">
|
||||
@ -58,7 +58,7 @@
|
||||
<hr class="my-3" />
|
||||
<ul class="navbar-nav mb-md-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-lg" @click="logout">
|
||||
<a class="nav-link text-lg pointer" @click="logout">
|
||||
{{ $t('logout') }}
|
||||
</a>
|
||||
</li>
|
||||
@ -88,6 +88,10 @@ export default {
|
||||
default: true,
|
||||
description: 'Whether sidebar should autoclose on mobile when clicking an item',
|
||||
},
|
||||
balance: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
@ -107,3 +111,8 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
|
||||
// Load Package Details for some default values
|
||||
// const pkg = require('../../package')
|
||||
|
||||
const environment = {
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
DEBUG: process.env.NODE_ENV !== 'production' || false,
|
||||
PRODUCTION: process.env.NODE_ENV === 'production' || false,
|
||||
ALLOW_REGISTER: process.env.ALLOW_REGISTER !== 'false',
|
||||
}
|
||||
|
||||
const server = {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
"logout":"Abmelden",
|
||||
"login":"Login",
|
||||
"signup": "Registrieren",
|
||||
"reset": "Passwort zurücksetzen",
|
||||
"imprint":"Impressum",
|
||||
"privacy_policy":"Datenschutzerklärung",
|
||||
"members_area": "Mitgliedsbereich",
|
||||
@ -110,5 +111,9 @@
|
||||
"submit":"Einreichen",
|
||||
"hours_report":"Stundenbericht"
|
||||
}
|
||||
},
|
||||
"reset-password": {
|
||||
"title": "Passwort Zurücksetzen",
|
||||
"text": "Jetzt kannst du ein neues Passwort speichern, mit dem du dich zukünfitg in der GRADIDO App anmelden kannst."
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
"logout":"Logout",
|
||||
"login":"Login",
|
||||
"signup": "Sign up",
|
||||
"reset": "Reset password",
|
||||
"imprint":"Legal notice",
|
||||
"privacy_policy":"Privacy policy",
|
||||
"members_area": "Member's area",
|
||||
@ -110,5 +111,9 @@
|
||||
"submit":"submit",
|
||||
"hours_report":"Hourly report"
|
||||
}
|
||||
},
|
||||
"reset-password": {
|
||||
"title": "Reset Password",
|
||||
"text": "Now you can save a new password to login to the GRADIDO App in the future."
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,6 +37,10 @@ import 'vue-good-table/dist/vue-good-table.css'
|
||||
|
||||
import VueMoment from 'vue-moment'
|
||||
|
||||
import Loading from 'vue-loading-overlay'
|
||||
// import the styles
|
||||
import 'vue-loading-overlay/dist/vue-loading.css'
|
||||
|
||||
Object.keys(rules).forEach((rule) => {
|
||||
extend(rule, {
|
||||
...rules[rule], // copies rule configuration
|
||||
@ -56,6 +60,7 @@ export default {
|
||||
Vue.use(VueQrcodeReader)
|
||||
Vue.use(VueQrcode)
|
||||
Vue.use(VueFlatPickr)
|
||||
Vue.use(Loading)
|
||||
configure({
|
||||
classes: {
|
||||
valid: 'is-valid',
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import routes from './routes'
|
||||
import CONFIG from '../config'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
// configure router
|
||||
const router = new VueRouter({
|
||||
base: '/vue',
|
||||
routes, // short for routes: routes
|
||||
linkActiveClass: 'active',
|
||||
mode: 'history',
|
||||
@ -20,4 +22,11 @@ const router = new VueRouter({
|
||||
},
|
||||
})
|
||||
|
||||
if (CONFIG.ALLOW_REGISTER) {
|
||||
router.addRoute({
|
||||
path: '/register',
|
||||
component: () => import('../views/Pages/Register.vue'),
|
||||
})
|
||||
}
|
||||
|
||||
export default router
|
||||
|
||||
@ -21,20 +21,20 @@ const routes = [
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/profileedit',
|
||||
component: () => import('../views/Pages/UserProfileEdit.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/activity',
|
||||
component: () => import('../views/Pages/UserProfileActivity.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
//{
|
||||
// path: '/profileedit',
|
||||
// component: () => import('../views/Pages/UserProfileEdit.vue'),
|
||||
// meta: {
|
||||
// requiresAuth: true,
|
||||
// },
|
||||
//},
|
||||
//{
|
||||
// path: '/activity',
|
||||
// component: () => import('../views/Pages/UserProfileActivity.vue'),
|
||||
// meta: {
|
||||
// requiresAuth: true,
|
||||
// },
|
||||
//},
|
||||
{
|
||||
path: '/transactions',
|
||||
component: () => import('../views/Pages/UserProfileTransactionList.vue'),
|
||||
@ -50,16 +50,12 @@ const routes = [
|
||||
path: '/thx',
|
||||
component: () => import('../views/Pages/thx.vue'),
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
component: () => import('../views/Pages/Register.vue'),
|
||||
},
|
||||
{
|
||||
path: '/password',
|
||||
component: () => import('../views/Pages/ForgotPassword.vue'),
|
||||
},
|
||||
{
|
||||
path: '/reset',
|
||||
path: '/reset/:optin',
|
||||
component: () => import('../views/Pages/ResetPassword.vue'),
|
||||
},
|
||||
{ path: '*', component: NotFound },
|
||||
|
||||
@ -1,9 +1,32 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
Vue.use(Vuex)
|
||||
import communityAPI from '../apis/communityAPI'
|
||||
import createPersistedState from 'vuex-persistedstate'
|
||||
|
||||
export const mutations = {
|
||||
language: (state, language) => {
|
||||
state.language = language
|
||||
},
|
||||
email: (state, email) => {
|
||||
state.email = email
|
||||
},
|
||||
session_id: (state, session_id) => {
|
||||
state.session_id = session_id
|
||||
},
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
login: ({ dispatch, commit }, data) => {
|
||||
commit('session_id', data.session_id)
|
||||
commit('email', data.email)
|
||||
},
|
||||
logout: ({ commit, state }) => {
|
||||
commit('session_id', null)
|
||||
commit('email', null)
|
||||
sessionStorage.clear()
|
||||
},
|
||||
}
|
||||
|
||||
export const store = new Vuex.Store({
|
||||
plugins: [
|
||||
createPersistedState({
|
||||
@ -14,64 +37,10 @@ export const store = new Vuex.Store({
|
||||
session_id: null,
|
||||
email: '',
|
||||
language: 'en',
|
||||
user: {
|
||||
name: '',
|
||||
balance: 0,
|
||||
balance_gdt: 0,
|
||||
},
|
||||
modals: false,
|
||||
optionAxios: {
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Credentials': 'true',
|
||||
},
|
||||
},
|
||||
},
|
||||
getters: {},
|
||||
// Syncronous mutation of the state
|
||||
mutations: {
|
||||
language: (state, language) => {
|
||||
state.language = language
|
||||
},
|
||||
email: (state, email) => {
|
||||
state.email = email
|
||||
},
|
||||
session_id: (state, session_id) => {
|
||||
state.session_id = session_id
|
||||
},
|
||||
user_balance: (state, balance) => {
|
||||
state.user.balance = balance / 10000
|
||||
},
|
||||
user_balance_gdt: (state, balance) => {
|
||||
state.user.balance_gdt = balance / 10000
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
login: ({ dispatch, commit }, data) => {
|
||||
commit('session_id', data.session_id)
|
||||
commit('email', data.email)
|
||||
},
|
||||
passwordReset: (data) => {},
|
||||
schoepfen: (data) => {
|
||||
// http://localhost/transaction-creations/ajaxCreate
|
||||
},
|
||||
createUser: ({ commit, dispatch }, data) => {
|
||||
commit('session_id', data.session_id)
|
||||
commit('email', data.email)
|
||||
},
|
||||
logout: ({ commit, state }) => {
|
||||
commit('session_id', null)
|
||||
commit('email', null)
|
||||
sessionStorage.clear()
|
||||
},
|
||||
accountBalance: async ({ commit, dispatch, state }) => {
|
||||
const result = await communityAPI.balance(state.session_id)
|
||||
if (result.success) {
|
||||
commit('user_balance', result.result.data.balance)
|
||||
} else {
|
||||
//dispatch('logout')
|
||||
}
|
||||
},
|
||||
},
|
||||
mutations,
|
||||
actions,
|
||||
})
|
||||
|
||||
81
frontend/src/store/store.test.js
Normal file
81
frontend/src/store/store.test.js
Normal file
@ -0,0 +1,81 @@
|
||||
import { mutations, actions } from './store'
|
||||
|
||||
const { language, email, session_id } = mutations
|
||||
const { login, logout } = actions
|
||||
|
||||
describe('Vuex store', () => {
|
||||
describe('mutations', () => {
|
||||
describe('language', () => {
|
||||
it('sets the state of language', () => {
|
||||
const state = { language: 'en' }
|
||||
language(state, 'de')
|
||||
expect(state.language).toEqual('de')
|
||||
})
|
||||
})
|
||||
|
||||
describe('email', () => {
|
||||
it('sets the state of email', () => {
|
||||
const state = { email: 'nobody@knows.tv' }
|
||||
email(state, 'someone@there.is')
|
||||
expect(state.email).toEqual('someone@there.is')
|
||||
})
|
||||
})
|
||||
|
||||
describe('session_id', () => {
|
||||
it('sets the state of session_id', () => {
|
||||
const state = { session_id: null }
|
||||
session_id(state, '1234')
|
||||
expect(state.session_id).toEqual('1234')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('actions', () => {
|
||||
describe('login', () => {
|
||||
const commit = jest.fn()
|
||||
const state = {}
|
||||
|
||||
it('calls two commits', () => {
|
||||
login({ commit, state }, { session_id: 1234, email: 'someone@there.is' })
|
||||
expect(commit).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('commits session_id', () => {
|
||||
login({ commit, state }, { session_id: 1234, email: 'someone@there.is' })
|
||||
expect(commit).toHaveBeenNthCalledWith(1, 'session_id', 1234)
|
||||
})
|
||||
|
||||
it('commits email', () => {
|
||||
login({ commit, state }, { session_id: 1234, email: 'someone@there.is' })
|
||||
expect(commit).toHaveBeenNthCalledWith(2, 'email', 'someone@there.is')
|
||||
})
|
||||
})
|
||||
|
||||
describe('logout', () => {
|
||||
const commit = jest.fn()
|
||||
const state = {}
|
||||
|
||||
it('calls two commits', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('commits session_id', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(1, 'session_id', null)
|
||||
})
|
||||
|
||||
it('commits email', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(2, 'email', null)
|
||||
})
|
||||
|
||||
// how can I get this working?
|
||||
it.skip('calls sessionStorage.clear()', () => {
|
||||
logout({ commit, state })
|
||||
const spy = jest.spyOn(sessionStorage, 'clear')
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,23 +1,23 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-row v-show="row_form">
|
||||
<b-row v-show="showTransactionList">
|
||||
<b-col xl="12" md="12">
|
||||
<b-alert variant="warning" show dismissible v-html="$t('form.attention')"></b-alert>
|
||||
<b-alert show dismissible variant="warning" class="text-center">
|
||||
<span class="alert-text" v-html="$t('form.attention')"></span>
|
||||
</b-alert>
|
||||
<b-card class="p-0 p-md-3" style="background-color: #ebebeba3 !important">
|
||||
<b-alert show variant="secondary">
|
||||
<span class="alert-text" v-html="$t('form.scann_code')"></span>
|
||||
<b-col v-show="!scan" lg="12" class="text-right">
|
||||
<img src="/img/icons/gradido/qr-scan-pure.png" height="50" @click="scan = true" />
|
||||
<a @click="toggle" class="nav-link pointer">
|
||||
<img src="img/icons/gradido/qr-scan-pure.png" height="50" />
|
||||
</a>
|
||||
</b-col>
|
||||
<b-alert v-show="scan" show variant="warning">
|
||||
<span class="alert-text" @click="scan = false">
|
||||
<strong>{{ $t('form.cancel') }}</strong>
|
||||
</span>
|
||||
</b-alert>
|
||||
|
||||
<div v-if="scan">
|
||||
<!-- <b-row>
|
||||
<qrcode-capture @detect="onDetect" capture="user" ></qrcode-capture>
|
||||
</b-row> -->
|
||||
<qrcode-capture @detect="onDetect" capture="user" ></qrcode-capture>
|
||||
</b-row> -->
|
||||
|
||||
<qrcode-stream class="mt-3" @decode="onDecode" @detect="onDetect"></qrcode-stream>
|
||||
|
||||
@ -31,6 +31,13 @@
|
||||
</b-row>
|
||||
</b-container>
|
||||
</div>
|
||||
<div @click="toggle">
|
||||
<b-alert v-show="scan" show variant="primary" class="pointer text-center">
|
||||
<span class="alert-text">
|
||||
<strong>{{ $t('form.cancel') }}</strong>
|
||||
</span>
|
||||
</b-alert>
|
||||
</div>
|
||||
</b-alert>
|
||||
|
||||
<validation-observer v-slot="{ handleSubmit }" ref="formValidator">
|
||||
@ -73,7 +80,7 @@
|
||||
<br />
|
||||
<div>
|
||||
<b-col class="text-left p-3 p-sm-1">{{ $t('form.amount') }}</b-col>
|
||||
<b-col v-if="$store.state.user.balance == form.amount" class="text-right">
|
||||
<b-col v-if="balance == form.amount" class="text-right">
|
||||
<b-badge variant="primary">{{ $t('form.max_gdd_info') }}</b-badge>
|
||||
</b-col>
|
||||
<b-input-group
|
||||
@ -93,7 +100,7 @@
|
||||
placeholder="0.01"
|
||||
step="0.01"
|
||||
min="0.01"
|
||||
:max="$store.state.user.balance"
|
||||
:max="balance"
|
||||
style="font-size: xx-large; padding-left: 20px"
|
||||
></b-form-input>
|
||||
</b-input-group>
|
||||
@ -197,9 +204,8 @@ export default {
|
||||
BIcon,
|
||||
},
|
||||
props: {
|
||||
row_form: { type: Boolean, default: true },
|
||||
row_check: { type: Boolean, default: false },
|
||||
row_thx: { type: Boolean, default: false },
|
||||
balance: { type: Number, default: 0 },
|
||||
showTransactionList: { type: Boolean, default: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -219,12 +225,16 @@ export default {
|
||||
auto_sign: true,
|
||||
},
|
||||
send: false,
|
||||
row_check: false,
|
||||
row_thx: false,
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
toggle() {
|
||||
this.scan = !this.scan
|
||||
},
|
||||
async onDecode(decodedString) {
|
||||
//console.log('onDecode JSON.parse(decodedString)', JSON.parse(decodedString))
|
||||
const arr = JSON.parse(decodedString)
|
||||
this.form.email = arr[0].email
|
||||
this.form.amount = arr[0].amount
|
||||
@ -234,30 +244,31 @@ export default {
|
||||
//event.preventDefault()
|
||||
this.ajaxCreateData.email = this.form.email
|
||||
this.ajaxCreateData.amount = this.form.amount
|
||||
this.ajaxCreateData.target_date = Date.now()
|
||||
const now = new Date(Date.now()).toISOString()
|
||||
this.ajaxCreateData.target_date = now
|
||||
this.ajaxCreateData.memo = this.form.memo
|
||||
|
||||
this.$emit('change-rows', { row_form: false, row_check: true, row_thx: false })
|
||||
this.$emit('toggle-show-list', false)
|
||||
this.row_check = true
|
||||
this.row_thx = false
|
||||
},
|
||||
async sendTransaction() {
|
||||
this.ajaxCreateData.amount = this.ajaxCreateData.amount * 10000
|
||||
|
||||
const result = await communityAPI.send(
|
||||
this.$store.state.session_id,
|
||||
this.ajaxCreateData.email,
|
||||
this.ajaxCreateData.amount,
|
||||
this.ajaxCreateData.amount * 10000,
|
||||
this.ajaxCreateData.memo,
|
||||
this.ajaxCreateData.target_date,
|
||||
)
|
||||
// console.log(result)
|
||||
|
||||
if (result.success) {
|
||||
// console.log('send success')
|
||||
|
||||
this.$emit('change-rows', { row_form: false, row_check: false, row_thx: true })
|
||||
this.$emit('toggle-show-list', false)
|
||||
this.row_check = false
|
||||
this.row_thx = true
|
||||
this.$emit('update-balance', { ammount: this.ajaxCreateData.amount })
|
||||
} else {
|
||||
// console.log('send error')
|
||||
alert('error')
|
||||
this.$emit('change-rows', { row_form: true, row_check: false, row_thx: false })
|
||||
this.$emit('toggle-show-list', true)
|
||||
this.row_check = false
|
||||
this.row_thx = false
|
||||
}
|
||||
},
|
||||
onReset(event) {
|
||||
@ -265,15 +276,20 @@ export default {
|
||||
this.form.email = ''
|
||||
this.form.amount = ''
|
||||
this.show = false
|
||||
this.$emit('toggle-show-list', true)
|
||||
this.row_check = false
|
||||
this.row_thx = false
|
||||
this.$nextTick(() => {
|
||||
this.show = true
|
||||
})
|
||||
this.$emit('change-rows', { row_form: true, row_check: false, row_thx: false })
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
video {
|
||||
max-height: 665px;
|
||||
max-width: 665px;
|
||||
|
||||
@ -1,29 +1,22 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import GddStatus from './GddStatus'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
describe('GddStatus', () => {
|
||||
let wrapper
|
||||
|
||||
let state = {
|
||||
user: {
|
||||
balance: 1234,
|
||||
balance_gdt: 9876,
|
||||
},
|
||||
}
|
||||
|
||||
let store = new Vuex.Store({
|
||||
state,
|
||||
})
|
||||
|
||||
let mocks = {
|
||||
$n: jest.fn((n) => n),
|
||||
}
|
||||
|
||||
let propsData = {
|
||||
balance: 1234,
|
||||
GdtBalance: 9876,
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(GddStatus, { localVue, store, mocks })
|
||||
return mount(GddStatus, { localVue, mocks, propsData })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-row v-show="this.row_form">
|
||||
<b-row v-show="showTransactionList">
|
||||
<b-col xl="6" md="6">
|
||||
<stats-card
|
||||
type="gradient-red"
|
||||
@ -8,7 +8,7 @@
|
||||
class="mb-4 h1"
|
||||
style="background-color: #ebebeba3 !important"
|
||||
>
|
||||
{{ $n($store.state.user.balance) }} GDD
|
||||
{{ $n(balance) }} GDD
|
||||
</stats-card>
|
||||
</b-col>
|
||||
<b-col xl="6" md="6">
|
||||
@ -18,7 +18,7 @@
|
||||
class="mb-4 h1"
|
||||
style="background-color: #ebebeba3 !important"
|
||||
>
|
||||
{{ $n($store.state.user.balance_gdt) }} GDT
|
||||
{{ $n(GdtBalance) }} GDT
|
||||
</stats-card>
|
||||
</b-col>
|
||||
</b-row>
|
||||
@ -29,7 +29,9 @@
|
||||
export default {
|
||||
name: 'GddStatus',
|
||||
props: {
|
||||
row_form: { type: Boolean, default: true },
|
||||
showTransactionList: { type: Boolean, default: true },
|
||||
balance: { type: Number, default: 0 },
|
||||
GdtBalance: { type: Number, default: 0 },
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-list-group v-show="this.row_form">
|
||||
<b-list-group v-show="showTransactionList">
|
||||
<b-list-group-item
|
||||
v-for="item in filteredItems"
|
||||
:key="item.id"
|
||||
@ -73,14 +73,11 @@
|
||||
</b-collapse>
|
||||
</b-list-group-item>
|
||||
<b-list-group-item v-show="this.$route.path == '/overview'">
|
||||
<b-alert
|
||||
v-if="count < 5"
|
||||
show
|
||||
variant="secondary"
|
||||
v-html="$t('transaction.show_part', { count: count })"
|
||||
></b-alert>
|
||||
<b-alert v-if="count < 5" show variant="secondary">
|
||||
<span class="alert-text" v-html="$t('transaction.show_part', { count: count })"></span>
|
||||
</b-alert>
|
||||
<router-link
|
||||
else
|
||||
v-else
|
||||
to="/transactions"
|
||||
v-html="$t('transaction.show_all', { count: count })"
|
||||
></router-link>
|
||||
@ -96,7 +93,7 @@ import communityAPI from '../../apis/communityAPI'
|
||||
export default {
|
||||
name: 'GddTable',
|
||||
props: {
|
||||
row_form: { type: Boolean, default: true },
|
||||
showTransactionList: { type: Boolean, default: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -111,7 +108,6 @@ export default {
|
||||
const result = await communityAPI.transactions(this.$store.state.session_id)
|
||||
|
||||
if (result.success) {
|
||||
this.$store.state.user.balance_gdt = result.result.data.gdtSum
|
||||
this.items = result.result.data.transactions
|
||||
this.count = result.result.data.count
|
||||
} else {
|
||||
|
||||
@ -79,7 +79,7 @@ describe('DashboardLayoutGdd', () => {
|
||||
})
|
||||
|
||||
it('has five items in the navbar', () => {
|
||||
expect(navbar.findAll('ul > li')).toHaveLength(5)
|
||||
expect(navbar.findAll('ul > li')).toHaveLength(3)
|
||||
})
|
||||
|
||||
it('has first item "send" in navbar', () => {
|
||||
@ -116,29 +116,29 @@ describe('DashboardLayoutGdd', () => {
|
||||
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/profile')
|
||||
})
|
||||
|
||||
it('has fourth item "Settigs" in navbar', () => {
|
||||
expect(navbar.findAll('ul > li').at(3).text()).toEqual('site.navbar.settings')
|
||||
})
|
||||
//it('has fourth item "Settigs" in navbar', () => {
|
||||
// expect(navbar.findAll('ul > li').at(3).text()).toEqual('site.navbar.settings')
|
||||
//})
|
||||
//
|
||||
//it.skip('has fourth item "Settings" linked to profileedit in navbar', async () => {
|
||||
// navbar.findAll('ul > li > a').at(3).trigger('click')
|
||||
// await flushPromises()
|
||||
// await jest.runAllTimers()
|
||||
// await flushPromises()
|
||||
// expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/profileedit')
|
||||
//})
|
||||
|
||||
it.skip('has fourth item "Settings" linked to profileedit in navbar', async () => {
|
||||
navbar.findAll('ul > li > a').at(3).trigger('click')
|
||||
await flushPromises()
|
||||
await jest.runAllTimers()
|
||||
await flushPromises()
|
||||
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/profileedit')
|
||||
})
|
||||
|
||||
it('has fifth item "Activity" in navbar', () => {
|
||||
expect(navbar.findAll('ul > li').at(4).text()).toEqual('site.navbar.activity')
|
||||
})
|
||||
|
||||
it.skip('has fourth item "Activity" linked to activity in navbar', async () => {
|
||||
navbar.findAll('ul > li > a').at(4).trigger('click')
|
||||
await flushPromises()
|
||||
await jest.runAllTimers()
|
||||
await flushPromises()
|
||||
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/activity')
|
||||
})
|
||||
//it('has fifth item "Activity" in navbar', () => {
|
||||
// expect(navbar.findAll('ul > li').at(4).text()).toEqual('site.navbar.activity')
|
||||
//})
|
||||
//
|
||||
//it.skip('has fourth item "Activity" linked to activity in navbar', async () => {
|
||||
// navbar.findAll('ul > li > a').at(4).trigger('click')
|
||||
// await flushPromises()
|
||||
// await jest.runAllTimers()
|
||||
// await flushPromises()
|
||||
// expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/activity')
|
||||
//})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<notifications></notifications>
|
||||
<side-bar @logout="logout">
|
||||
<side-bar @logout="logout" :balance="balance">
|
||||
<template slot="links">
|
||||
<b-nav-item href="#!" to="/overview">
|
||||
<b-nav-text class="p-0 text-lg text-muted">{{ $t('send') }}</b-nav-text>
|
||||
@ -12,12 +12,14 @@
|
||||
<b-nav-item href="#!" to="/profile">
|
||||
<b-nav-text class="p-0 text-lg text-muted">{{ $t('site.navbar.my-profil') }}</b-nav-text>
|
||||
</b-nav-item>
|
||||
<!--
|
||||
<b-nav-item href="#!" to="/profileedit">
|
||||
<b-nav-text class="p-0 text-lg text-muted">{{ $t('site.navbar.settings') }}</b-nav-text>
|
||||
</b-nav-item>
|
||||
<b-nav-item href="#!" to="/activity">
|
||||
<b-nav-text class="p-0 text-lg text-muted">{{ $t('site.navbar.activity') }}</b-nav-text>
|
||||
</b-nav-item>
|
||||
-->
|
||||
</template>
|
||||
</side-bar>
|
||||
<div class="main-content">
|
||||
@ -26,7 +28,11 @@
|
||||
<div @click="$sidebar.displaySidebar(false)">
|
||||
<fade-transition :duration="200" origin="center top" mode="out-in">
|
||||
<!-- your content here -->
|
||||
<router-view></router-view>
|
||||
<router-view
|
||||
:balance="balance"
|
||||
:gdt-balance="GdtBalance"
|
||||
@update-balance="updateBalance"
|
||||
></router-view>
|
||||
</fade-transition>
|
||||
</div>
|
||||
<content-footer v-if="!$route.meta.hideFooter"></content-footer>
|
||||
@ -57,6 +63,7 @@ import DashboardNavbar from './DashboardNavbar.vue'
|
||||
import ContentFooter from './ContentFooter.vue'
|
||||
// import DashboardContent from './Content.vue';
|
||||
import { FadeTransition } from 'vue2-transitions'
|
||||
import communityAPI from '../../apis/communityAPI'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -65,6 +72,12 @@ export default {
|
||||
// DashboardContent,
|
||||
FadeTransition,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
balance: 0,
|
||||
GdtBalance: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initScrollbar() {
|
||||
let isWindows = navigator.platform.startsWith('Win')
|
||||
@ -78,10 +91,33 @@ export default {
|
||||
this.$store.dispatch('logout')
|
||||
this.$router.push('/login')
|
||||
},
|
||||
async loadBalance() {
|
||||
const result = await communityAPI.balance(this.$store.state.session_id)
|
||||
if (result.success) {
|
||||
this.balance = result.result.data.balance / 10000
|
||||
} else {
|
||||
// what to do when loading balance fails?
|
||||
}
|
||||
},
|
||||
async loadGDTBalance() {
|
||||
const result = await communityAPI.transactions(this.$store.state.session_id)
|
||||
if (result.success) {
|
||||
this.GdtBalance = result.result.data.gdtSum / 10000
|
||||
} else {
|
||||
// what to do when loading balance fails?
|
||||
}
|
||||
},
|
||||
updateBalance(ammount) {
|
||||
this.balance -= ammount
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.initScrollbar()
|
||||
},
|
||||
created() {
|
||||
this.loadBalance()
|
||||
this.loadGDTBalance()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss"></style>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<li class="nav-item d-sm-none"></li>
|
||||
</b-navbar-nav>
|
||||
<b-navbar-nav class="align-items-center ml-auto ml-md-0">
|
||||
<a class="pr-1" slot="title-container">
|
||||
<a class="pr-1 nav-link" slot="title-container pointer">
|
||||
<b-media no-body class="align-items-center">
|
||||
<span class="pb-2 text-lg font-weight-bold">
|
||||
{{ $store.state.email }}
|
||||
@ -41,3 +41,8 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,26 +1,17 @@
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import KontoOverview from './KontoOverview'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
describe('KontoOverview', () => {
|
||||
let wrapper
|
||||
|
||||
let actions = {
|
||||
accountBalance: jest.fn(),
|
||||
}
|
||||
|
||||
let store = new Vuex.Store({
|
||||
actions,
|
||||
})
|
||||
|
||||
let mocks = {
|
||||
$t: jest.fn((t) => t),
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return shallowMount(KontoOverview, { localVue, store, mocks })
|
||||
return shallowMount(KontoOverview, { localVue, mocks })
|
||||
}
|
||||
|
||||
describe('shallow Mount', () => {
|
||||
@ -44,37 +35,34 @@ describe('KontoOverview', () => {
|
||||
expect(wrapper.find('gdd-table-stub').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('calls "accountBalance" action from store on creation', () => {
|
||||
const spy = jest.spyOn(actions, 'accountBalance')
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('updates transctions data when change-transactions is emitted', async () => {
|
||||
wrapper.find('gdd-table-stub').vm.$emit('change-transactions', [0, 1])
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(wrapper.vm.transactions).toEqual(expect.arrayContaining([0, 1]))
|
||||
})
|
||||
|
||||
describe('setRows method', () => {
|
||||
describe('updateBalance method', () => {
|
||||
beforeEach(async () => {
|
||||
wrapper.find('gdd-send-stub').vm.$emit('change-rows', {
|
||||
row_form: false,
|
||||
row_check: true,
|
||||
row_thx: true,
|
||||
wrapper.find('gdd-send-stub').vm.$emit('update-balance', {
|
||||
ammount: 42,
|
||||
})
|
||||
await wrapper.vm.$nextTick()
|
||||
})
|
||||
|
||||
it('updates row_form data when change-rows is emitted', () => {
|
||||
expect(wrapper.vm.row_form).toBeFalsy()
|
||||
it('emmits updateBalance with correct value', () => {
|
||||
expect(wrapper.emitted('update-balance')).toEqual([[42]])
|
||||
})
|
||||
})
|
||||
|
||||
describe('toggleShowList method', () => {
|
||||
beforeEach(async () => {
|
||||
wrapper.setProps({ showTransactionList: false })
|
||||
wrapper.find('gdd-send-stub').vm.$emit('toggle-show-list', true)
|
||||
await wrapper.vm.$nextTick()
|
||||
})
|
||||
|
||||
it('updates row_check data when change-rows is emitted', () => {
|
||||
expect(wrapper.vm.row_check).toBeTruthy()
|
||||
})
|
||||
|
||||
it('updates row_thx data when change-rows is emitted', () => {
|
||||
expect(wrapper.vm.row_thx).toBeTruthy()
|
||||
it('changes the value of property showTransactionList', () => {
|
||||
expect(wrapper.vm.showTransactionList).toBeTruthy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -2,17 +2,21 @@
|
||||
<div>
|
||||
<base-header class="pb-6 pb-8 pt-5 pt-md-8 bg-transparent"></base-header>
|
||||
<b-container fluid class="mt--7">
|
||||
<gdd-status :row_form="row_form" />
|
||||
<gdd-status
|
||||
:balance="balance"
|
||||
:gdt-balance="GdtBalance"
|
||||
:show-transaction-list="showTransactionList"
|
||||
/>
|
||||
<br />
|
||||
<gdd-send
|
||||
:row_form="row_form"
|
||||
:row_check="row_check"
|
||||
:row_thx="row_thx"
|
||||
@change-rows="setRows"
|
||||
:balance="balance"
|
||||
:show-transaction-list="showTransactionList"
|
||||
@update-balance="updateBalance"
|
||||
@toggle-show-list="toggleShowList"
|
||||
/>
|
||||
<hr />
|
||||
<gdd-table
|
||||
:row_form="row_form"
|
||||
:show-transaction-list="showTransactionList"
|
||||
:transactions="transactions"
|
||||
@change-transactions="setTransactions"
|
||||
/>
|
||||
@ -28,25 +32,25 @@ export default {
|
||||
name: 'Overview',
|
||||
data() {
|
||||
return {
|
||||
row_form: true,
|
||||
row_check: false,
|
||||
row_thx: false,
|
||||
transactions: [],
|
||||
showTransactionList: true,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
balance: { type: Number, default: 0 },
|
||||
GdtBalance: { type: Number, default: 0 },
|
||||
},
|
||||
components: {
|
||||
GddStatus,
|
||||
GddSend,
|
||||
GddTable,
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch('accountBalance', this.$store.state.session_id)
|
||||
},
|
||||
methods: {
|
||||
setRows(rows) {
|
||||
this.row_form = rows.row_form
|
||||
this.row_check = rows.row_check
|
||||
this.row_thx = rows.row_thx
|
||||
toggleShowList(bool) {
|
||||
this.showTransactionList = bool
|
||||
},
|
||||
updateBalance(data) {
|
||||
this.$emit('update-balance', data.ammount)
|
||||
},
|
||||
setTransactions(transactions) {
|
||||
this.transactions = transactions
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
</strong>
|
||||
</b-col>
|
||||
<b-col class="text-right">
|
||||
<a href="#!" @click="closeAlert">
|
||||
<a @click="closeAlert">
|
||||
<div>
|
||||
<b-icon-exclamation-triangle-fill
|
||||
class="h2 mb-0"
|
||||
@ -67,7 +67,7 @@
|
||||
</b-alert>
|
||||
|
||||
<!-- <b-form-checkbox v-model="model.rememberMe">{{ $t('site.login.remember')}}</b-form-checkbox> -->
|
||||
<div class="text-center">
|
||||
<div class="text-center" ref="submitButton">
|
||||
<base-button type="secondary" native-type="submit" class="my-4">
|
||||
{{ $t('site.login.signin') }}
|
||||
</base-button>
|
||||
@ -82,15 +82,12 @@
|
||||
{{ $t('site.login.forgot_pwd') }}
|
||||
</router-link>
|
||||
</b-col>
|
||||
<b-col cols="6" class="text-right">
|
||||
<b-col cols="6" class="text-right" v-show="allowRegister">
|
||||
<router-link to="/register">
|
||||
{{ $t('site.login.new_wallet') }}
|
||||
</router-link>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col><router-link to="/reset">reset</router-link></b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
@ -98,6 +95,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import loginAPI from '../../apis/loginAPI'
|
||||
import CONFIG from '../../config'
|
||||
|
||||
export default {
|
||||
name: 'login',
|
||||
@ -109,10 +107,14 @@ export default {
|
||||
// rememberMe: false
|
||||
},
|
||||
loginfail: false,
|
||||
allowRegister: CONFIG.ALLOW_REGISTER,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
let loader = this.$loading.show({
|
||||
container: this.$refs.submitButton,
|
||||
})
|
||||
const result = await loginAPI.login(this.model.email, this.model.password)
|
||||
if (result.success) {
|
||||
this.$store.dispatch('login', {
|
||||
@ -120,11 +122,14 @@ export default {
|
||||
email: this.model.email,
|
||||
})
|
||||
this.$router.push('/overview')
|
||||
loader.hide()
|
||||
} else {
|
||||
loader.hide()
|
||||
this.loginfail = true
|
||||
}
|
||||
},
|
||||
closeAlert() {
|
||||
loader.hide()
|
||||
this.loginfail = false
|
||||
},
|
||||
},
|
||||
|
||||
@ -65,11 +65,8 @@
|
||||
></b-form-input>
|
||||
|
||||
<b-input-group-append>
|
||||
<b-button variant="outline-primary">
|
||||
<b-icon
|
||||
:icon="passwordVisible ? 'eye' : 'eye-slash'"
|
||||
@click="togglePasswordVisibility"
|
||||
/>
|
||||
<b-button variant="outline-primary" @click="togglePasswordVisibility">
|
||||
<b-icon :icon="passwordVisible ? 'eye' : 'eye-slash'" />
|
||||
</b-button>
|
||||
</b-input-group-append>
|
||||
</b-input-group>
|
||||
@ -177,7 +174,7 @@ export default {
|
||||
this.password,
|
||||
)
|
||||
if (result.success) {
|
||||
this.$store.dispatch('createUser', {
|
||||
this.$store.dispatch('login', {
|
||||
session_id: result.result.data.session_id,
|
||||
email: this.model.email,
|
||||
})
|
||||
|
||||
@ -1,35 +1,30 @@
|
||||
import { mount, RouterLinkStub } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import flushPromises from 'flush-promises'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import VueRouter from 'vue-router'
|
||||
import routes from '../../routes/routes'
|
||||
|
||||
import ResetPassword from './ResetPassword'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
const router = new VueRouter({ routes })
|
||||
|
||||
describe('ResetPassword', () => {
|
||||
let wrapper
|
||||
|
||||
let emailVerification = jest.fn()
|
||||
|
||||
let mocks = {
|
||||
$i18n: {
|
||||
locale: 'en',
|
||||
},
|
||||
$t: jest.fn((t) => t),
|
||||
}
|
||||
|
||||
let state = {
|
||||
// loginfail: false,
|
||||
}
|
||||
|
||||
let store = new Vuex.Store({
|
||||
state,
|
||||
})
|
||||
|
||||
let stubs = {
|
||||
RouterLink: RouterLinkStub,
|
||||
loginAPI: {
|
||||
loginViaEmailVerificationCode: emailVerification,
|
||||
},
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(ResetPassword, { localVue, mocks, store, stubs })
|
||||
return mount(ResetPassword, { localVue, mocks, router })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
@ -37,7 +32,20 @@ describe('ResetPassword', () => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('renders the Reset Password form', () => {
|
||||
/*
|
||||
it('calls the email verification when created', () => {
|
||||
const spy = jest.spyOn(wrapper.vm, 'authenticate')
|
||||
expect(spy).toBeCalled()
|
||||
})
|
||||
*/
|
||||
|
||||
it('does not render the Reset Password form when not authenticated', async () => {
|
||||
expect(wrapper.find('div.resetpwd-form').exists()).toBeFalsy()
|
||||
})
|
||||
|
||||
it('renders the Reset Password form', async () => {
|
||||
wrapper.setData({ authenticated: true })
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(wrapper.find('div.resetpwd-form').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
|
||||
@ -1,16 +1,13 @@
|
||||
<template>
|
||||
<div class="resetpwd-form">
|
||||
<div class="resetpwd-form" v-if="authenticated">
|
||||
<!-- Header -->
|
||||
<div class="header p-4">
|
||||
<b-container class="container">
|
||||
<div class="header-body text-center mb-7">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col xl="5" lg="6" md="8" class="px-2">
|
||||
<h1>Reset Password</h1>
|
||||
<div class="pb-4">
|
||||
Jetzt kannst du ein neues Passwort speichern, mit welchem du dich zukünfitg in der
|
||||
GRADIDO App anmelden kannst.
|
||||
</div>
|
||||
<h1>{{ $t('reset-password.title') }}</h1>
|
||||
<div class="pb-4">{{ $t('reset-password.text') }}</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
@ -78,7 +75,7 @@
|
||||
v-if="passwordsFilled && samePasswords && passwordValidation.valid"
|
||||
>
|
||||
<b-button type="submit" variant="secondary" class="mt-4">
|
||||
{{ $t('signup') }}
|
||||
{{ $t('reset') }}
|
||||
</b-button>
|
||||
</div>
|
||||
</b-form>
|
||||
@ -91,6 +88,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import loginAPI from '../../apis/loginAPI'
|
||||
export default {
|
||||
name: 'reset',
|
||||
data() {
|
||||
@ -105,18 +103,34 @@ export default {
|
||||
checkPassword: '',
|
||||
passwordVisible: false,
|
||||
submitted: false,
|
||||
authenticated: false,
|
||||
session_id: null,
|
||||
email: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
togglePasswordVisibility() {
|
||||
this.passwordVisible = !this.passwordVisible
|
||||
},
|
||||
onSubmit() {
|
||||
this.$store.dispatch('createUser', {
|
||||
password: this.model.password,
|
||||
})
|
||||
this.model.password = ''
|
||||
this.$router.push('/thx')
|
||||
async onSubmit() {
|
||||
const result = await loginAPI.changePassword(this.session_id, this.email, this.password)
|
||||
if (result.success) {
|
||||
this.password = ''
|
||||
this.$router.push('/thx')
|
||||
} else {
|
||||
alert(result.result.message)
|
||||
}
|
||||
},
|
||||
async authenticate() {
|
||||
const optin = this.$route.params.optin
|
||||
const result = await loginAPI.loginViaEmailVerificationCode(optin)
|
||||
if (result.success) {
|
||||
this.authenticated = true
|
||||
this.session_id = result.result.data.session_id
|
||||
this.email = result.result.data.user.email
|
||||
} else {
|
||||
alert(result.result.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
@ -139,8 +153,8 @@ export default {
|
||||
return { valid: false, errors }
|
||||
},
|
||||
},
|
||||
created() {
|
||||
//console.log('resetpage', this.$route)
|
||||
async created() {
|
||||
this.authenticate()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,17 +1,11 @@
|
||||
const path = require('path')
|
||||
const dotenv = require('dotenv-webpack')
|
||||
|
||||
function resolveSrc(_path) {
|
||||
return path.join(__dirname, _path)
|
||||
}
|
||||
|
||||
let vue_path = process.env.VUE_PATH
|
||||
if (vue_path == undefined) {
|
||||
vue_path = '/vue'
|
||||
}
|
||||
|
||||
// vue.config.js
|
||||
module.exports = {
|
||||
devServer: {
|
||||
port: process.env.PORT || 3000,
|
||||
},
|
||||
pluginOptions: {
|
||||
i18n: {
|
||||
locale: 'de',
|
||||
@ -21,12 +15,12 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
lintOnSave: true,
|
||||
publicPath: vue_path + '/',
|
||||
publicPath: '/vue',
|
||||
configureWebpack: {
|
||||
// Set up all the aliases we use in our app.
|
||||
resolve: {
|
||||
alias: {
|
||||
assets: resolveSrc('src/assets'),
|
||||
assets: path.join(__dirname, 'src/assets'),
|
||||
},
|
||||
},
|
||||
plugins: [new dotenv()],
|
||||
@ -35,5 +29,5 @@ module.exports = {
|
||||
// Enable CSS source maps.
|
||||
sourceMap: process.env.NODE_ENV !== 'production',
|
||||
},
|
||||
outputDir: path.resolve(__dirname, './dist' + vue_path),
|
||||
outputDir: path.resolve(__dirname, './dist'),
|
||||
}
|
||||
|
||||
@ -13348,6 +13348,11 @@ vue-loader@^15.7.0:
|
||||
vue-hot-reload-api "^2.3.0"
|
||||
vue-style-loader "^4.1.0"
|
||||
|
||||
vue-loading-overlay@^3.4.2:
|
||||
version "3.4.2"
|
||||
resolved "https://registry.yarnpkg.com/vue-loading-overlay/-/vue-loading-overlay-3.4.2.tgz#34792a83218df1d35dff50121ce9fac2114f1c38"
|
||||
integrity sha512-xcB+NPjl76eA0uggm707x3ZFgrNosZXpynHipyS3K+rrK1NztOV49R1LY+/4ij5W1KYANp7eRI2EIHrxCpmWAw==
|
||||
|
||||
vue-moment@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vue-moment/-/vue-moment-4.1.0.tgz#092a8ff723a96c6f85a0a8e23ad30f0bf320f3b0"
|
||||
|
||||
2
login_server/.gitignore
vendored
2
login_server/.gitignore
vendored
@ -6,3 +6,5 @@ src/cpsp/*.cpp
|
||||
src/cpp/proto/
|
||||
build*/
|
||||
/skeema/gradido_login/insert/crypto_key.sql
|
||||
|
||||
src/LOCALE/messages.pot
|
||||
|
||||
@ -16,34 +16,45 @@ RUN git clone https://github.com/Kitware/CMake.git --branch=v3.19.8 \
|
||||
&& make install
|
||||
|
||||
#########################################################################################################
|
||||
# debug build preparation
|
||||
# Build debug
|
||||
#########################################################################################################
|
||||
FROM cmake-gcc-9 as build_debug_preparation
|
||||
|
||||
USER root
|
||||
From gradido/login_dependencies:stage2 as debug
|
||||
|
||||
ENV DOCKER_WORKDIR="/code"
|
||||
|
||||
RUN mkdir -p ${DOCKER_WORKDIR}
|
||||
WORKDIR ${DOCKER_WORKDIR}
|
||||
USER root
|
||||
|
||||
WORKDIR ${DOCKER_WORKDIR}
|
||||
COPY . .
|
||||
|
||||
RUN cd scripts \
|
||||
&& chmod +x ./prepare_build.sh \
|
||||
&& ./prepare_build.sh
|
||||
|
||||
RUN ./compile_pot.sh
|
||||
RUN ./unix_parse_proto.sh
|
||||
|
||||
|
||||
#########################################################################################################
|
||||
# run debug
|
||||
#########################################################################################################
|
||||
FROM build_debug_preparation as login_server_debug
|
||||
FROM debug as login_server_debug
|
||||
|
||||
ENV DOCKER_WORKDIR="/code"
|
||||
#RUN apt-get update && \
|
||||
# apt-get install -y --no-install-recommends gdb && \
|
||||
# apt-get autoclean && \
|
||||
# apt-get autoremove && \
|
||||
# apt-get clean && \
|
||||
# rm -rf /var/lib/apt/lists/*
|
||||
|
||||
VOLUME /var/log/grd_login
|
||||
VOLUME /code/src
|
||||
|
||||
EXPOSE 1200
|
||||
EXPOSE 1201
|
||||
WORKDIR ${DOCKER_WORKDIR}
|
||||
RUN chmod +x ./scripts/build_and_run.sh
|
||||
|
||||
CMD ./scripts/build_and_run.sh; ./build/bin/Gradido_LoginServer
|
||||
CMD ./Dockerfiles/build_and_run.sh; ./build_vol/bin/Gradido_LoginServer
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit b95393dcc3640807838e8323b4e600e54d2e8116
|
||||
Subproject commit 3fc3e5f5b8462f7666952b43381383a79b8b5d92
|
||||
@ -3,6 +3,7 @@ CREATE TABLE `groups` (
|
||||
`alias` varchar(190) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`url` varchar(255) NOT NULL,
|
||||
`host` varchar(255) DEFAULT "/",
|
||||
`home` varchar(255) DEFAULT "/",
|
||||
`description` text,
|
||||
PRIMARY KEY (`id`),
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `home`, `description`) VALUES
|
||||
(2, 'docker', 'docker gradido group', 'localhost', '/', 'gradido test group for docker and stage2 with blockchain db');
|
||||
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user