mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into 1216-SEO-Vorschau-Links
This commit is contained in:
commit
68caec953c
48
.github/workflows/publish.yml
vendored
48
.github/workflows/publish.yml
vendored
@ -106,43 +106,6 @@ jobs:
|
||||
name: docker-database-production_up
|
||||
path: /tmp/database_up.tar
|
||||
|
||||
##############################################################################
|
||||
# JOB: DOCKER BUILD PRODUCTION COMMUNITY SERVER ##############################
|
||||
##############################################################################
|
||||
build_production_community_server:
|
||||
name: Docker Build Production - Community Server
|
||||
runs-on: ubuntu-latest
|
||||
#needs: [nothing]
|
||||
steps:
|
||||
##########################################################################
|
||||
# CHECKOUT CODE ##########################################################
|
||||
##########################################################################
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
##########################################################################
|
||||
# SET ENVS ###############################################################
|
||||
##########################################################################
|
||||
- name: ENV - VERSION
|
||||
run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
|
||||
- name: ENV - BUILD_DATE
|
||||
run: echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
|
||||
- name: ENV - BUILD_VERSION
|
||||
run: echo "BUILD_VERSION=${VERSION}.${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
|
||||
- name: ENV - BUILD_COMMIT
|
||||
run: echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
|
||||
##########################################################################
|
||||
# COMMUNITY SERVER #######################################################
|
||||
##########################################################################
|
||||
- name: Community Server | Build `production` image
|
||||
run: |
|
||||
docker build -t "gradido/community_server:latest" -t "gradido/community_server:production" -t "gradido/community_server:${VERSION}" -t "gradido/community_server:${BUILD_VERSION}" -f ./community_server/Dockerfile ./
|
||||
docker save "gradido/community_server" > /tmp/community_server.tar
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: docker-community-server-production
|
||||
path: /tmp/community_server.tar
|
||||
|
||||
##############################################################################
|
||||
# JOB: DOCKER BUILD PRODUCTION MARIADB #######################################
|
||||
##############################################################################
|
||||
@ -223,7 +186,7 @@ jobs:
|
||||
upload_to_dockerhub:
|
||||
name: Upload to Dockerhub
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build_production_frontend, build_production_backend, build_production_database_up, build_production_community_server, build_production_mariadb, build_production_nginx]
|
||||
needs: [build_production_frontend, build_production_backend, build_production_database_up, build_production_mariadb, build_production_nginx]
|
||||
env:
|
||||
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@ -257,13 +220,6 @@ jobs:
|
||||
path: /tmp
|
||||
- name: Load Docker Image
|
||||
run: docker load < /tmp/database_up.tar
|
||||
- name: Download Docker Image (Community Server)
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: docker-community-server-production
|
||||
path: /tmp
|
||||
- name: Load Docker Image
|
||||
run: docker load < /tmp/community_server.tar
|
||||
- name: Download Docker Image (MariaDB)
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
@ -289,8 +245,6 @@ jobs:
|
||||
run: docker push --all-tags gradido/backend
|
||||
- name: Push database
|
||||
run: docker push --all-tags gradido/database
|
||||
- name: Push community_server
|
||||
run: docker push --all-tags gradido/community_server
|
||||
- name: Push MariaDB
|
||||
run: docker push --all-tags gradido/mariadb
|
||||
- name: Push Nginx
|
||||
|
||||
95
.github/workflows/test.yml
vendored
95
.github/workflows/test.yml
vendored
@ -107,32 +107,6 @@ jobs:
|
||||
name: docker-database-test_up
|
||||
path: /tmp/database_up.tar
|
||||
|
||||
##############################################################################
|
||||
# JOB: DOCKER BUILD TEST COMMUNITY SERVER ####################################
|
||||
##############################################################################
|
||||
build_test_community_server:
|
||||
name: Docker Build Test - Community Server
|
||||
runs-on: ubuntu-latest
|
||||
#needs: [nothing]
|
||||
steps:
|
||||
##########################################################################
|
||||
# CHECKOUT CODE ##########################################################
|
||||
##########################################################################
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
##########################################################################
|
||||
# BUILD COMMUNITY SERVER DOCKER IMAGE ####################################
|
||||
##########################################################################
|
||||
- name: community server | Build `test` image
|
||||
run: |
|
||||
docker build -t "gradido/community_server:test" -f ./community_server/Dockerfile ./
|
||||
docker save "gradido/community_server:test" > /tmp/community_server.tar
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: docker-community-server-test
|
||||
path: /tmp/community_server.tar
|
||||
|
||||
##############################################################################
|
||||
# JOB: DOCKER BUILD TEST MARIADB #############################################
|
||||
##############################################################################
|
||||
@ -448,7 +422,7 @@ jobs:
|
||||
report_name: Coverage Admin Interface
|
||||
type: lcov
|
||||
result_path: ./coverage/lcov.info
|
||||
min_coverage: 93
|
||||
min_coverage: 94
|
||||
token: ${{ github.token }}
|
||||
|
||||
##############################################################################
|
||||
@ -509,73 +483,6 @@ jobs:
|
||||
min_coverage: 38
|
||||
token: ${{ github.token }}
|
||||
|
||||
##############################################################################
|
||||
# JOB: UNIT TEST COMMUNITY-SERVER ###########################################
|
||||
##############################################################################
|
||||
unit_test_community_server:
|
||||
name: Unit tests - Community Server
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build_test_community_server]
|
||||
services:
|
||||
mariadb:
|
||||
image: gradido/mariadb:test
|
||||
env:
|
||||
MARIADB_ALLOW_EMPTY_PASSWORD: 1
|
||||
MARIADB_USER: root
|
||||
options: --health-cmd="mysqladmin ping"
|
||||
--health-interval=5s
|
||||
--health-timeout=5s
|
||||
--health-retries=3
|
||||
steps:
|
||||
- name: get mariadb container id
|
||||
run: echo "::set-output name=id::$(docker container ls | grep mariadb | awk '{ print $1 }')"
|
||||
id: mariadb_container
|
||||
- name: get automatic created network
|
||||
run: echo "::set-output name=id::$(docker network ls | grep github_network | awk '{ print $1 }')"
|
||||
id: network
|
||||
- name: Start database migration
|
||||
run: docker run --network ${{ steps.network.outputs.id }} --name=database --env NODE_ENV=production --env DB_HOST=mariadb --env DB_DATABASE=gradido_community_test -d gradido/database:production_up
|
||||
- name: get database migration container id
|
||||
run: echo "::set-output name=id::$(docker container ls | grep database | awk '{ print $1 }')"
|
||||
id: database_container
|
||||
##########################################################################
|
||||
# CHECKOUT CODE ##########################################################
|
||||
##########################################################################
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
##########################################################################
|
||||
# DOWNLOAD DOCKER IMAGE ##################################################
|
||||
##########################################################################
|
||||
- name: Download Docker Image (Community-Server)
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: docker-community-server-test
|
||||
path: /tmp
|
||||
- name: Load Docker Image
|
||||
run: docker load < /tmp/community_server.tar
|
||||
- name: check mariadb
|
||||
run: docker logs ${{ steps.mariadb_container.outputs.id }}
|
||||
- name: check migration
|
||||
run: docker logs ${{ steps.database_container.outputs.id }}
|
||||
##########################################################################
|
||||
# UNIT TESTS BACKEND COMMUNITY-SERVER #######################################
|
||||
##########################################################################
|
||||
- name: community server | Unit tests
|
||||
run: |
|
||||
docker run --network ${{ steps.network.outputs.id }} -v ~/coverage:/var/www/cakephp/webroot/coverage gradido/community_server:test
|
||||
cp -r ~/coverage ./coverage
|
||||
#########################################################################
|
||||
# COVERAGE CHECK BACKEND COMMUNITY-SERVER ####################################
|
||||
##########################################################################
|
||||
- name: backend community | Coverage check
|
||||
uses: einhornimmond/coverage-check-action@master
|
||||
with:
|
||||
report_name: Coverage Backend Community
|
||||
type: phpunit
|
||||
result_path: ./coverage/coverage.info
|
||||
min_coverage: 10
|
||||
token: ${{ github.token }}
|
||||
|
||||
##########################################################################
|
||||
# DATABASE MIGRATION TEST UP + RESET #####################################
|
||||
##########################################################################
|
||||
|
||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -1,3 +1 @@
|
||||
[submodule "community_server/src/protobuf"]
|
||||
path = community_server/src/protobuf
|
||||
url = https://github.com/gradido/gradido_protocol.git
|
||||
|
||||
|
||||
68
CHANGELOG.md
68
CHANGELOG.md
@ -4,8 +4,76 @@ All notable changes to this project will be documented in this file. Dates are d
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [1.6.4](https://github.com/gradido/gradido/compare/1.6.3...1.6.4)
|
||||
|
||||
- fix: Admin Email Confirmation Date and Time [`#1448`](https://github.com/gradido/gradido/pull/1448)
|
||||
- Fix: Do not log password or token to the console [`#1477`](https://github.com/gradido/gradido/pull/1477)
|
||||
- Fix: Elopage Hook Crash [`#1474`](https://github.com/gradido/gradido/pull/1474)
|
||||
- 538 unify all buttons [`#1455`](https://github.com/gradido/gradido/pull/1455)
|
||||
- 833 old error is shown for a second even if transaction is successful [`#1460`](https://github.com/gradido/gradido/pull/1460)
|
||||
- fix: Wrong Email Spelling in German [`#1446`](https://github.com/gradido/gradido/pull/1446)
|
||||
- fix: Redirect to Login after Register [`#1445`](https://github.com/gradido/gradido/pull/1445)
|
||||
- refactor: Split User Table Component in Admin Interface [`#1443`](https://github.com/gradido/gradido/pull/1443)
|
||||
- remove user table [`c6a469e`](https://github.com/gradido/gradido/commit/c6a469e08f16101c8fb78958eda69b163b815ed3)
|
||||
- open creations table [`9ef575d`](https://github.com/gradido/gradido/commit/9ef575d6b140a4c768e4330a18eaa3b04346b483)
|
||||
- User Search Table [`ae2d535`](https://github.com/gradido/gradido/commit/ae2d5355d62f525187dd1cdb1448aec63fb05d3f)
|
||||
|
||||
#### [1.6.3](https://github.com/gradido/gradido/compare/1.6.2...1.6.3)
|
||||
|
||||
> 9 February 2022
|
||||
|
||||
- v1.6.3 [`#1447`](https://github.com/gradido/gradido/pull/1447)
|
||||
- add .btn-outline-secondary in scss [`#1442`](https://github.com/gradido/gradido/pull/1442)
|
||||
- Profil settings and footer refactor [`#1440`](https://github.com/gradido/gradido/pull/1440)
|
||||
- profil settings header info refactor style [`cbaa016`](https://github.com/gradido/gradido/commit/cbaa0162b9366e5de722235aeb633908c59bb3e1)
|
||||
- margin footer refactor, more margin to top [`81b3dc0`](https://github.com/gradido/gradido/commit/81b3dc08ae6f60049feba690132dba37c84ad5c5)
|
||||
|
||||
#### [1.6.2](https://github.com/gradido/gradido/compare/1.6.1...1.6.2)
|
||||
|
||||
> 8 February 2022
|
||||
|
||||
- v1.6.2 [`#1438`](https://github.com/gradido/gradido/pull/1438)
|
||||
- updated_changelog_library [`#1437`](https://github.com/gradido/gradido/pull/1437)
|
||||
- admin interface does user have member area [`#1416`](https://github.com/gradido/gradido/pull/1416)
|
||||
- Refactor - Remove community_server [`#1408`](https://github.com/gradido/gradido/pull/1408)
|
||||
- 1389 transactions tabs are not well designed [`#1425`](https://github.com/gradido/gradido/pull/1425)
|
||||
- fix_community_name_description [`#1429`](https://github.com/gradido/gradido/pull/1429)
|
||||
- remove_unnecessary_repositories [`#1406`](https://github.com/gradido/gradido/pull/1406)
|
||||
- clean_database_users [`#1427`](https://github.com/gradido/gradido/pull/1427)
|
||||
- remove_gradido_node [`#1431`](https://github.com/gradido/gradido/pull/1431)
|
||||
- add updateTransactions function for GDD balance if reload page [`#1423`](https://github.com/gradido/gradido/pull/1423)
|
||||
- 1390 display error when navigating to send form without any gdd [`#1424`](https://github.com/gradido/gradido/pull/1424)
|
||||
- have an delete button for the search input [`#1413`](https://github.com/gradido/gradido/pull/1413)
|
||||
- reset all selected users in mass creation [`#1422`](https://github.com/gradido/gradido/pull/1422)
|
||||
- combine_user_tables [`#1411`](https://github.com/gradido/gradido/pull/1411)
|
||||
- feat: Test Table Row Details Toggling [`#1420`](https://github.com/gradido/gradido/pull/1420)
|
||||
- feat: Improved Tests for Mass Creation [`#1419`](https://github.com/gradido/gradido/pull/1419)
|
||||
- refactor: Mixin for Creation Labels [`#1409`](https://github.com/gradido/gradido/pull/1409)
|
||||
- Marque community_server as to be removed. [`#1407`](https://github.com/gradido/gradido/pull/1407)
|
||||
- database_transaction_signatures [`#1368`](https://github.com/gradido/gradido/pull/1368)
|
||||
- database_pending_creations [`#1367`](https://github.com/gradido/gradido/pull/1367)
|
||||
- fix_seed [`#1410`](https://github.com/gradido/gradido/pull/1410)
|
||||
- clean_database [`#1362`](https://github.com/gradido/gradido/pull/1362)
|
||||
- multiple creation already selected users remain saved [`#1376`](https://github.com/gradido/gradido/pull/1376)
|
||||
- fix: Localize Datetime in Admin Interface [`#1327`](https://github.com/gradido/gradido/pull/1327)
|
||||
- feat: Remove Login Server [`#1383`](https://github.com/gradido/gradido/pull/1383)
|
||||
- refactor: Tag Last Version with Login Server [`#1391`](https://github.com/gradido/gradido/pull/1391)
|
||||
- if an email is not confirmed, a user cannot be added to any multiple … [`#1374`](https://github.com/gradido/gradido/pull/1374)
|
||||
- cleanups_refactors [`#1404`](https://github.com/gradido/gradido/pull/1404)
|
||||
- 1365 clear bootstrap version for vue2, preparation for new template [`#1366`](https://github.com/gradido/gradido/pull/1366)
|
||||
- upgrade vue version from ^2.6.11 to 2.6.12 [`#1382`](https://github.com/gradido/gradido/pull/1382)
|
||||
- remove vue-qrcode from dashboard-plugin [`#1364`](https://github.com/gradido/gradido/pull/1364)
|
||||
- remove unused package from frontend [`#1360`](https://github.com/gradido/gradido/pull/1360)
|
||||
- Removed community_server folder, removed reference to community_server. [`e5c3c3c`](https://github.com/gradido/gradido/commit/e5c3c3c57a2343e1c4d7b8fbc658edcd78f1a292)
|
||||
- migration 20 [`c0156d4`](https://github.com/gradido/gradido/commit/c0156d4a298ac11f0d1ccabb859fdcbd56d391ee)
|
||||
- fix frontend tests [`3f0aa00`](https://github.com/gradido/gradido/commit/3f0aa00dc36499b13878eda469312e00100074f4)
|
||||
|
||||
#### [1.6.1](https://github.com/gradido/gradido/compare/1.6.0...1.6.1)
|
||||
|
||||
> 28 January 2022
|
||||
|
||||
- Hotfix elopage [`#1358`](https://github.com/gradido/gradido/pull/1358)
|
||||
- change standard text für creation [`#1343`](https://github.com/gradido/gradido/pull/1343)
|
||||
- Check if user email is activated to make a creation. [`#1356`](https://github.com/gradido/gradido/pull/1356)
|
||||
- fix: Creation Confirmation User Ids [`#1345`](https://github.com/gradido/gradido/pull/1345)
|
||||
- fix and improve test [`1c833d3`](https://github.com/gradido/gradido/commit/1c833d394f502a7aed2b5a648c0171a2fe4ee1e6)
|
||||
|
||||
@ -60,7 +60,6 @@ docker-compose -f docker-compose.yml up
|
||||
- [frontend](./frontend) Wallet frontend
|
||||
- [backend](./backend) GraphQL & Business logic backend
|
||||
- [mariadb](./mariadb) Database backend
|
||||
- [community_server](./community_server/) Business logic backend (will be removed)
|
||||
|
||||
We are currently restructuring the service to reduce dependencies and unify business logic into one place. Furthermore the databases defined for each service will be unified into one.
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"description": "Administraion Interface for Gradido",
|
||||
"main": "index.js",
|
||||
"author": "Moriz Wahl",
|
||||
"version": "1.6.1",
|
||||
"version": "1.6.4",
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="component-confirm-register-mail">
|
||||
<div class="shadow p-3 mb-5 bg-white rounded">
|
||||
<div v-if="checked">{{ $t('unregister_mail.text_true', { date: dateLastSend }) }}</div>
|
||||
<div v-if="checked">{{ $t('unregister_mail.text_true') }}</div>
|
||||
<div v-else>
|
||||
{{ $t('unregister_mail.text_false', { date: dateLastSend, mail: email }) }}
|
||||
|
||||
|
||||
86
admin/src/components/Tables/OpenCreationsTable.vue
Normal file
86
admin/src/components/Tables/OpenCreationsTable.vue
Normal file
@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div class="component-open-creations-table">
|
||||
<b-table-lite :items="items" :fields="fields" caption-top striped hover stacked="md">
|
||||
<template #cell(bookmark)="row">
|
||||
<b-button
|
||||
variant="danger"
|
||||
size="md"
|
||||
@click="$emit('remove-creation', row.item)"
|
||||
class="mr-2"
|
||||
>
|
||||
<b-icon icon="x" variant="light"></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
<template #cell(edit_creation)="row">
|
||||
<b-button variant="info" size="md" @click="rowToogleDetails(row, 0)" class="mr-2">
|
||||
<b-icon :icon="row.detailsShowing ? 'x' : 'pencil-square'" aria-label="Help"></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
<template #cell(confirm)="row">
|
||||
<b-button variant="success" size="md" @click="$emit('show-overlay', row.item)" class="mr-2">
|
||||
<b-icon icon="check" scale="2" variant=""></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
<template #row-details="row">
|
||||
<row-details
|
||||
:row="row"
|
||||
type="show-creation"
|
||||
slotName="show-creation"
|
||||
:index="0"
|
||||
@row-toogle-details="rowToogleDetails"
|
||||
>
|
||||
<template #show-creation>
|
||||
<div>
|
||||
<edit-creation-formular
|
||||
type="singleCreation"
|
||||
:creation="row.item.creation"
|
||||
:item="row.item"
|
||||
:row="row"
|
||||
:creationUserData="creationUserData"
|
||||
@update-creation-data="updateCreationData"
|
||||
@update-user-data="updateUserData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</row-details>
|
||||
</template>
|
||||
</b-table-lite>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { toggleRowDetails } from '../../mixins/toggleRowDetails'
|
||||
import RowDetails from '../RowDetails.vue'
|
||||
import EditCreationFormular from '../EditCreationFormular.vue'
|
||||
|
||||
export default {
|
||||
name: 'OpenCreationsTable',
|
||||
mixins: [toggleRowDetails],
|
||||
components: {
|
||||
EditCreationFormular,
|
||||
RowDetails,
|
||||
},
|
||||
props: {
|
||||
items: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
fields: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
updateCreationData(data) {
|
||||
this.creationUserData.amount = data.amount
|
||||
this.creationUserData.date = data.date
|
||||
this.creationUserData.memo = data.memo
|
||||
this.creationUserData.moderator = data.moderator
|
||||
data.row.toggleDetails()
|
||||
},
|
||||
updateUserData(rowItem, newCreation) {
|
||||
rowItem.creation = newCreation
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
125
admin/src/components/Tables/SearchUserTable.vue
Normal file
125
admin/src/components/Tables/SearchUserTable.vue
Normal file
@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div class="search-user-table">
|
||||
<b-table-lite :items="items" :fields="fields" caption-top striped hover stacked="md">
|
||||
<template #cell(creation)="data">
|
||||
<div v-html="data.value"></div>
|
||||
</template>
|
||||
<template #cell(show_details)="row">
|
||||
<b-button
|
||||
variant="info"
|
||||
size="md"
|
||||
v-if="row.item.emailChecked"
|
||||
@click="rowToogleDetails(row, 0)"
|
||||
class="mr-2"
|
||||
>
|
||||
<b-icon :icon="row.detailsShowing ? 'eye-slash-fill' : 'eye-fill'"></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
<template #cell(confirm_mail)="row">
|
||||
<b-button
|
||||
:variant="row.item.emailChecked ? 'success' : 'danger'"
|
||||
size="md"
|
||||
@click="rowToogleDetails(row, 1)"
|
||||
class="mr-2"
|
||||
>
|
||||
<b-icon
|
||||
:icon="row.item.emailChecked ? 'envelope-open' : 'envelope'"
|
||||
aria-label="Help"
|
||||
></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
<template #cell(has_elopage)="row">
|
||||
<b-icon
|
||||
:variant="row.item.hasElopage ? 'success' : 'danger'"
|
||||
:icon="row.item.hasElopage ? 'check-circle' : 'x-circle'"
|
||||
></b-icon>
|
||||
</template>
|
||||
<template #cell(transactions_list)="row">
|
||||
<b-button variant="warning" size="md" @click="rowToogleDetails(row, 2)" class="mr-2">
|
||||
<b-icon icon="list"></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
<template #row-details="row">
|
||||
<row-details
|
||||
:row="row"
|
||||
type="singleCreation"
|
||||
:slotName="slotName"
|
||||
:index="slotIndex"
|
||||
@row-toogle-details="rowToogleDetails"
|
||||
>
|
||||
<template #show-creation>
|
||||
<div>
|
||||
<creation-formular
|
||||
type="singleCreation"
|
||||
pagetype="singleCreation"
|
||||
:creation="row.item.creation"
|
||||
:item="row.item"
|
||||
:creationUserData="creationUserData"
|
||||
@update-user-data="updateUserData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #show-register-mail>
|
||||
<confirm-register-mail-formular
|
||||
:checked="row.item.emailChecked"
|
||||
:email="row.item.email"
|
||||
:dateLastSend="
|
||||
row.item.emailConfirmationSend
|
||||
? $d(new Date(row.item.emailConfirmationSend), 'long')
|
||||
: ''
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
<template #show-transaction-list>
|
||||
<creation-transaction-list-formular :userId="row.item.userId" />
|
||||
</template>
|
||||
</row-details>
|
||||
</template>
|
||||
</b-table-lite>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import CreationFormular from '../CreationFormular.vue'
|
||||
import ConfirmRegisterMailFormular from '../ConfirmRegisterMailFormular.vue'
|
||||
import RowDetails from '../RowDetails.vue'
|
||||
import CreationTransactionListFormular from '../CreationTransactionListFormular.vue'
|
||||
import { toggleRowDetails } from '../../mixins/toggleRowDetails'
|
||||
|
||||
const slotNames = ['show-creation', 'show-register-mail', 'show-transaction-list']
|
||||
|
||||
export default {
|
||||
name: 'SearchUserTable',
|
||||
mixins: [toggleRowDetails],
|
||||
components: {
|
||||
CreationFormular,
|
||||
ConfirmRegisterMailFormular,
|
||||
CreationTransactionListFormular,
|
||||
RowDetails,
|
||||
},
|
||||
props: {
|
||||
items: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
fields: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
creationUserData: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateUserData(rowItem, newCreation) {
|
||||
rowItem.creation = newCreation
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
slotName() {
|
||||
return slotNames[this.slotIndex]
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
35
admin/src/components/Tables/SelectUsersTable.vue
Normal file
35
admin/src/components/Tables/SelectUsersTable.vue
Normal file
@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div class="component-select-users-table">
|
||||
<b-table-lite :items="items" :fields="fields" caption-top striped hover stacked="md">
|
||||
<template #cell(bookmark)="row">
|
||||
<div>
|
||||
<b-button
|
||||
v-if="row.item.emailChecked"
|
||||
variant="warning"
|
||||
size="md"
|
||||
@click="$emit('push-item', row.item)"
|
||||
class="mr-2"
|
||||
>
|
||||
<b-icon icon="plus" variant="success"></b-icon>
|
||||
</b-button>
|
||||
<div v-else>{{ $t('e_mail') }}!</div>
|
||||
</div>
|
||||
</template>
|
||||
</b-table-lite>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'SelectUsersTable',
|
||||
props: {
|
||||
items: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
fields: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
26
admin/src/components/Tables/SelectedUsersTable.vue
Normal file
26
admin/src/components/Tables/SelectedUsersTable.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<div class="component-selected-users-table">
|
||||
<b-table-lite :items="items" :fields="fields" caption-top striped hover stacked="md">
|
||||
<template #cell(bookmark)="row">
|
||||
<b-button variant="danger" size="md" @click="$emit('remove-item', row.item)" class="mr-2">
|
||||
<b-icon icon="x" variant="light"></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
</b-table-lite>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'SelectedUsersTable',
|
||||
props: {
|
||||
items: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
fields: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -1,343 +0,0 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import UserTable from './UserTable.vue'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
const apolloQueryMock = jest.fn()
|
||||
apolloQueryMock.mockResolvedValue()
|
||||
|
||||
describe('UserTable', () => {
|
||||
let wrapper
|
||||
|
||||
const defaultItemsUser = [
|
||||
{
|
||||
userId: 1,
|
||||
firstName: 'Bibi',
|
||||
lastName: 'Bloxberg',
|
||||
email: 'bibi@bloxberg.de',
|
||||
creation: [200, 400, 600],
|
||||
emailChecked: true,
|
||||
},
|
||||
{
|
||||
userId: 2,
|
||||
firstName: 'Benjamin',
|
||||
lastName: 'Blümchen',
|
||||
email: 'benjamin@bluemchen.de',
|
||||
creation: [1000, 1000, 1000],
|
||||
emailChecked: true,
|
||||
},
|
||||
{
|
||||
userId: 3,
|
||||
firstName: 'Peter',
|
||||
lastName: 'Lustig',
|
||||
email: 'peter@lustig.de',
|
||||
creation: [0, 0, 0],
|
||||
emailChecked: true,
|
||||
},
|
||||
{
|
||||
userId: 4,
|
||||
firstName: 'New',
|
||||
lastName: 'User',
|
||||
email: 'new@user.ch',
|
||||
creation: [1000, 1000, 1000],
|
||||
emailChecked: false,
|
||||
},
|
||||
]
|
||||
|
||||
const confirmationItemsUser = [
|
||||
{
|
||||
email: 'bibi@bloxberg.de',
|
||||
firstName: 'Bibi',
|
||||
lastName: 'Bloxberg',
|
||||
amount: 10,
|
||||
memo: 'Test 1',
|
||||
date: '11-09-2001',
|
||||
moderator: 1,
|
||||
},
|
||||
{
|
||||
email: 'bibi@bloxberg.de',
|
||||
firstName: 'Bibi',
|
||||
lastName: 'Bloxberg',
|
||||
amount: 10,
|
||||
memo: 'Test 2',
|
||||
date: '21-09-2001',
|
||||
moderator: 1,
|
||||
},
|
||||
{
|
||||
email: 'bibi@bloxberg.de',
|
||||
firstName: 'Bibi',
|
||||
lastName: 'Bloxberg',
|
||||
amount: 10,
|
||||
memo: 'Test 3',
|
||||
date: '30-09-2001',
|
||||
moderator: 1,
|
||||
},
|
||||
]
|
||||
|
||||
const propsDataPageUserSearch = {
|
||||
type: 'PageUserSearch',
|
||||
itemsUser: defaultItemsUser,
|
||||
fieldsTable: [
|
||||
'email',
|
||||
'firstName',
|
||||
'lastName',
|
||||
'creation',
|
||||
'show_details',
|
||||
'confirm_mail',
|
||||
'transactions_list',
|
||||
],
|
||||
}
|
||||
|
||||
const propsDataUserListSearch = {
|
||||
type: 'UserListSearch',
|
||||
itemsUser: defaultItemsUser,
|
||||
fieldsTable: ['bookmark', 'email', 'firstName', 'lastName', 'creation'],
|
||||
creation: [1000, 1000, 1000],
|
||||
}
|
||||
|
||||
const propsDataUserListMassCreation = {
|
||||
type: 'UserListMassCreation',
|
||||
itemsUser: defaultItemsUser,
|
||||
fieldsTable: ['email', 'firstName', 'lastName', 'creation', 'bookmark'],
|
||||
creation: [1000, 1000, 1000],
|
||||
}
|
||||
|
||||
const propsDataPageCreationConfirm = {
|
||||
type: 'PageCreationConfirm',
|
||||
itemsUser: confirmationItemsUser,
|
||||
fieldsTable: [
|
||||
'bookmark',
|
||||
'email',
|
||||
'firstName',
|
||||
'lastName',
|
||||
'amount',
|
||||
'memo',
|
||||
'date',
|
||||
'moderator',
|
||||
'edit_creation',
|
||||
'confirm',
|
||||
],
|
||||
}
|
||||
|
||||
const mocks = {
|
||||
$t: jest.fn((t) => t),
|
||||
$d: jest.fn((d) => String(d)),
|
||||
$apollo: {
|
||||
query: apolloQueryMock,
|
||||
},
|
||||
$store: {
|
||||
commit: jest.fn(),
|
||||
},
|
||||
}
|
||||
|
||||
const Wrapper = (propsData) => {
|
||||
return mount(UserTable, { localVue, propsData, mocks })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
describe('type PageUserSearch', () => {
|
||||
beforeEach(async () => {
|
||||
wrapper = Wrapper(propsDataPageUserSearch)
|
||||
})
|
||||
|
||||
it('has a DIV element with the class.component-user-table', () => {
|
||||
expect(wrapper.find('.component-user-table').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('has a DIV element with the id overlay that is not displayed', () => {
|
||||
expect(wrapper.find('#overlay').exists()).toBeTruthy()
|
||||
expect(wrapper.find('#overlay').attributes('style')).toBe('display: none;')
|
||||
})
|
||||
|
||||
describe('table', () => {
|
||||
it('has a table', () => {
|
||||
expect(wrapper.find('table').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
describe('header definition', () => {
|
||||
it('has 4 column', () => {
|
||||
expect(wrapper.findAll('th').length).toBe(7)
|
||||
})
|
||||
|
||||
it('has Email as first column', () => {
|
||||
expect(wrapper.find('th[aria-colindex="1"] div').text()).toBe('Email')
|
||||
})
|
||||
|
||||
it('has First Name as second column', () => {
|
||||
expect(wrapper.find('th[aria-colindex="2"] div').text()).toBe('First Name')
|
||||
})
|
||||
|
||||
it('has Last Name as third column', () => {
|
||||
expect(wrapper.find('th[aria-colindex="3"] div').text()).toBe('Last Name')
|
||||
})
|
||||
|
||||
it('has Creation as fourth column', () => {
|
||||
expect(wrapper.find('th[aria-colindex="4"] div').text()).toBe('Creation')
|
||||
})
|
||||
|
||||
it('has Creation as fifth column', () => {
|
||||
expect(wrapper.find('th[aria-colindex="5"] div').text()).toBe('Show Details')
|
||||
})
|
||||
|
||||
it('has Creation as sixth column', () => {
|
||||
expect(wrapper.find('th[aria-colindex="6"] div').text()).toBe('Confirm Mail')
|
||||
})
|
||||
|
||||
it('has Creation as seventh column', () => {
|
||||
expect(wrapper.find('th[aria-colindex="7"] div').text()).toBe('Transactions List')
|
||||
})
|
||||
})
|
||||
|
||||
describe('content', () => {
|
||||
it('has 4 rows', () => {
|
||||
expect(wrapper.findAll('tbody tr')).toHaveLength(4)
|
||||
})
|
||||
|
||||
it('has 7 columns', () => {
|
||||
expect(wrapper.findAll('tr:nth-child(1) > td')).toHaveLength(7)
|
||||
})
|
||||
|
||||
it('find button on fifth column', () => {
|
||||
expect(
|
||||
wrapper.findAll('tr:nth-child(1) > td').at(5).find('button').isVisible(),
|
||||
).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('row toggling', () => {
|
||||
describe('user with email not activated', () => {
|
||||
it('has no details button', () => {
|
||||
expect(
|
||||
wrapper.findAll('tbody > tr').at(3).findAll('td').at(4).find('button').exists(),
|
||||
).toBeFalsy()
|
||||
})
|
||||
|
||||
it('has a red confirmed button with envelope item', () => {
|
||||
const row = wrapper.findAll('tbody > tr').at(3)
|
||||
expect(row.findAll('td').at(5).find('button').exists()).toBeTruthy()
|
||||
expect(row.findAll('td').at(5).find('button').classes('btn-danger')).toBeTruthy()
|
||||
expect(row.findAll('td').at(5).find('svg').classes('bi-envelope')).toBeTruthy()
|
||||
})
|
||||
|
||||
describe('click on envelope', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper
|
||||
.findAll('tbody > tr')
|
||||
.at(3)
|
||||
.findAll('td')
|
||||
.at(5)
|
||||
.find('button')
|
||||
.trigger('click')
|
||||
})
|
||||
|
||||
it('opens the details', async () => {
|
||||
expect(wrapper.findAll('tbody > tr')).toHaveLength(6)
|
||||
expect(wrapper.findAll('tbody > tr').at(5).find('input').element.value).toBe(
|
||||
'new@user.ch',
|
||||
)
|
||||
expect(wrapper.findAll('tbody > tr').at(5).text()).toContain(
|
||||
'unregister_mail.text_false',
|
||||
)
|
||||
// HACK: for some reason we need to close the row details after this test
|
||||
await wrapper
|
||||
.findAll('tbody > tr')
|
||||
.at(3)
|
||||
.findAll('td')
|
||||
.at(5)
|
||||
.find('button')
|
||||
.trigger('click')
|
||||
})
|
||||
|
||||
describe('click on envelope again', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper
|
||||
.findAll('tbody > tr')
|
||||
.at(3)
|
||||
.findAll('td')
|
||||
.at(5)
|
||||
.find('button')
|
||||
.trigger('click')
|
||||
})
|
||||
|
||||
it('closes the details', () => {
|
||||
expect(wrapper.findAll('tbody > tr')).toHaveLength(4)
|
||||
})
|
||||
})
|
||||
|
||||
describe('click on close details', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper.findAll('tbody > tr').at(5).findAll('button').at(1).trigger('click')
|
||||
})
|
||||
|
||||
it('closes the details', () => {
|
||||
expect(wrapper.findAll('tbody > tr')).toHaveLength(4)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('different details', () => {
|
||||
it.skip('shows the creation formular for second user', async () => {
|
||||
await wrapper
|
||||
.findAll('tbody > tr')
|
||||
.at(1)
|
||||
.findAll('td')
|
||||
.at(4)
|
||||
.find('button')
|
||||
.trigger('click')
|
||||
expect(wrapper.findAll('tbody > tr')).toHaveLength(6)
|
||||
expect(
|
||||
wrapper
|
||||
.findAll('tbody > tr')
|
||||
.at(3)
|
||||
.find('div.component-creation-formular')
|
||||
.exists(),
|
||||
).toBeTruthy()
|
||||
})
|
||||
|
||||
it.skip('shows the transactions for third user', async () => {
|
||||
await wrapper
|
||||
.findAll('tbody > tr')
|
||||
.at(4)
|
||||
.findAll('td')
|
||||
.at(6)
|
||||
.find('button')
|
||||
.trigger('click')
|
||||
expect(wrapper.findAll('tbody > tr')).toHaveLength(6)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('type UserListSearch', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper(propsDataUserListSearch)
|
||||
})
|
||||
|
||||
it('has a DIV element with the class.component-user-table', () => {
|
||||
expect(wrapper.find('.component-user-table').exists()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('type UserListMassCreation', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper(propsDataUserListMassCreation)
|
||||
})
|
||||
|
||||
it('has a DIV element with the class.component-user-table', () => {
|
||||
expect(wrapper.find('.component-user-table').exists()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('type PageCreationConfirm', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper(propsDataPageCreationConfirm)
|
||||
})
|
||||
|
||||
it('has a DIV element with the class.component-user-table', () => {
|
||||
expect(wrapper.find('.component-user-table').exists()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,309 +0,0 @@
|
||||
<template>
|
||||
<div class="component-user-table">
|
||||
<div v-show="overlay" id="overlay" class="">
|
||||
<b-jumbotron class="bg-light p-4">
|
||||
<template #header>{{ overlayText.header }}</template>
|
||||
|
||||
<template #lead>
|
||||
{{ overlayText.text1 }}
|
||||
</template>
|
||||
|
||||
<hr class="my-4" />
|
||||
|
||||
<p>
|
||||
{{ overlayText.text2 }}
|
||||
</p>
|
||||
|
||||
<b-button size="md" variant="danger" class="m-3" @click="overlayCancel">
|
||||
{{ overlayText.button_cancel }}
|
||||
</b-button>
|
||||
<b-button
|
||||
size="md"
|
||||
variant="success"
|
||||
class="m-3 text-right"
|
||||
@click="overlayOK(overlayBookmarkType, overlayItem)"
|
||||
>
|
||||
{{ overlayText.button_ok }}
|
||||
</b-button>
|
||||
</b-jumbotron>
|
||||
</div>
|
||||
<b-table-lite :items="itemsUser" :fields="fieldsTable" caption-top striped hover stacked="md">
|
||||
<template #cell(creation)="data">
|
||||
<div v-html="data.value"></div>
|
||||
</template>
|
||||
|
||||
<template #cell(edit_creation)="row">
|
||||
<b-button variant="info" size="md" @click="rowToogleDetails(row, 0)" class="mr-2">
|
||||
<b-icon :icon="row.detailsShowing ? 'x' : 'pencil-square'" aria-label="Help"></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
|
||||
<template #cell(show_details)="row">
|
||||
<b-button
|
||||
variant="info"
|
||||
size="md"
|
||||
v-if="row.item.emailChecked"
|
||||
@click="rowToogleDetails(row, 0)"
|
||||
class="mr-2"
|
||||
>
|
||||
<b-icon :icon="row.detailsShowing ? 'eye-slash-fill' : 'eye-fill'"></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
|
||||
<template #cell(confirm_mail)="row">
|
||||
<b-button
|
||||
:variant="row.item.emailChecked ? 'success' : 'danger'"
|
||||
size="md"
|
||||
@click="rowToogleDetails(row, 1)"
|
||||
class="mr-2"
|
||||
>
|
||||
<b-icon
|
||||
:icon="row.item.emailChecked ? 'envelope-open' : 'envelope'"
|
||||
aria-label="Help"
|
||||
></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
|
||||
<template #cell(transactions_list)="row">
|
||||
<b-button variant="warning" size="md" @click="rowToogleDetails(row, 2)" class="mr-2">
|
||||
<b-icon icon="list"></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
|
||||
<template #row-details="row">
|
||||
<row-details
|
||||
v-if="type !== 'UserListSearch' && type !== 'UserListMassCreation'"
|
||||
:row="row"
|
||||
:type="type"
|
||||
:slotName="slotName"
|
||||
:index="slotIndex"
|
||||
@row-toogle-details="rowToogleDetails"
|
||||
>
|
||||
<template #show-creation>
|
||||
<div>
|
||||
<creation-formular
|
||||
v-if="type === 'PageUserSearch'"
|
||||
type="singleCreation"
|
||||
:pagetype="type"
|
||||
:creation="row.item.creation"
|
||||
:item="row.item"
|
||||
:creationUserData="creationUserData"
|
||||
@update-creation-data="updateCreationData"
|
||||
@update-user-data="updateUserData"
|
||||
/>
|
||||
<edit-creation-formular
|
||||
v-else
|
||||
type="singleCreation"
|
||||
:pagetype="type"
|
||||
:creation="row.item.creation"
|
||||
:item="row.item"
|
||||
:row="row"
|
||||
:creationUserData="creationUserData"
|
||||
@update-creation-data="updateCreationData"
|
||||
@update-user-data="updateUserData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #show-register-mail>
|
||||
<confirm-register-mail-formular
|
||||
:checked="row.item.emailChecked"
|
||||
:email="row.item.email"
|
||||
:dateLastSend="$d(new Date(), 'long')"
|
||||
/>
|
||||
</template>
|
||||
<template #show-transaction-list>
|
||||
<creation-transaction-list-formular :userId="row.item.userId" />
|
||||
</template>
|
||||
</row-details>
|
||||
</template>
|
||||
<template #cell(bookmark)="row">
|
||||
<div v-if="type === 'UserListSearch'">
|
||||
<b-button
|
||||
v-if="row.item.emailChecked"
|
||||
variant="warning"
|
||||
size="md"
|
||||
@click="bookmarkPush(row.item)"
|
||||
class="mr-2"
|
||||
>
|
||||
<b-icon icon="plus" variant="success"></b-icon>
|
||||
</b-button>
|
||||
<div v-else>{{ $t('e_mail') }}!</div>
|
||||
</div>
|
||||
<b-button
|
||||
variant="danger"
|
||||
v-show="type === 'UserListMassCreation' || type === 'PageCreationConfirm'"
|
||||
size="md"
|
||||
@click="bookmarkRemove(row.item)"
|
||||
class="mr-2"
|
||||
>
|
||||
<b-icon icon="x" variant="light"></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
|
||||
<template #cell(confirm)="row">
|
||||
<b-button
|
||||
variant="success"
|
||||
v-show="type === 'PageCreationConfirm'"
|
||||
size="md"
|
||||
@click="overlayShow('confirm', row.item)"
|
||||
class="mr-2"
|
||||
>
|
||||
<b-icon icon="check" scale="2" variant=""></b-icon>
|
||||
</b-button>
|
||||
</template>
|
||||
</b-table-lite>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CreationFormular from '../components/CreationFormular.vue'
|
||||
import EditCreationFormular from '../components/EditCreationFormular.vue'
|
||||
import ConfirmRegisterMailFormular from '../components/ConfirmRegisterMailFormular.vue'
|
||||
import CreationTransactionListFormular from '../components/CreationTransactionListFormular.vue'
|
||||
import RowDetails from '../components/RowDetails.vue'
|
||||
|
||||
const slotNames = ['show-creation', 'show-register-mail', 'show-transaction-list']
|
||||
|
||||
export default {
|
||||
name: 'UserTable',
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
itemsUser: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
fieldsTable: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
CreationFormular,
|
||||
EditCreationFormular,
|
||||
ConfirmRegisterMailFormular,
|
||||
CreationTransactionListFormular,
|
||||
RowDetails,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showCreationFormular: null,
|
||||
showConfirmRegisterMailFormular: null,
|
||||
showCreationTransactionListFormular: null,
|
||||
creationUserData: {},
|
||||
overlay: false,
|
||||
overlayBookmarkType: '',
|
||||
overlayItem: [],
|
||||
overlayText: [
|
||||
{
|
||||
header: '-',
|
||||
text1: '--',
|
||||
text2: '---',
|
||||
button_ok: 'OK',
|
||||
button_cancel: 'Cancel',
|
||||
},
|
||||
],
|
||||
slotIndex: 0,
|
||||
openRow: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
rowToogleDetails(row, index) {
|
||||
if (this.openRow) {
|
||||
if (this.openRow.index === row.index) {
|
||||
if (index === this.slotIndex) {
|
||||
row.toggleDetails()
|
||||
this.openRow = null
|
||||
} else {
|
||||
this.slotIndex = index
|
||||
}
|
||||
} else {
|
||||
this.openRow.toggleDetails()
|
||||
row.toggleDetails()
|
||||
this.slotIndex = index
|
||||
this.openRow = row
|
||||
if (this.type === 'PageCreationConfirm') {
|
||||
this.creationUserData = row.item
|
||||
}
|
||||
}
|
||||
} else {
|
||||
row.toggleDetails()
|
||||
this.slotIndex = index
|
||||
this.openRow = row
|
||||
if (this.type === 'PageCreationConfirm') {
|
||||
this.creationUserData = row.item
|
||||
}
|
||||
}
|
||||
},
|
||||
overlayShow(bookmarkType, item) {
|
||||
this.overlay = true
|
||||
this.overlayBookmarkType = bookmarkType
|
||||
this.overlayItem = item
|
||||
|
||||
if (bookmarkType === 'confirm') {
|
||||
this.overlayText.header = this.$t('overlay.confirm.title')
|
||||
this.overlayText.text1 = this.$t('overlay.confirm.text')
|
||||
this.overlayText.text2 = this.$t('overlay.confirm.question')
|
||||
this.overlayText.button_ok = this.$t('overlay.confirm.yes')
|
||||
this.overlayText.button_cancel = this.$t('overlay.confirm.no')
|
||||
}
|
||||
},
|
||||
overlayOK(bookmarkType, item) {
|
||||
if (bookmarkType === 'confirm') {
|
||||
this.$emit('confirm-creation', item)
|
||||
}
|
||||
this.overlay = false
|
||||
},
|
||||
overlayCancel() {
|
||||
this.overlay = false
|
||||
},
|
||||
bookmarkPush(item) {
|
||||
this.$emit('push-item', item)
|
||||
},
|
||||
bookmarkRemove(item) {
|
||||
if (this.type === 'UserListMassCreation') {
|
||||
this.$emit('remove-item', item)
|
||||
}
|
||||
|
||||
if (this.type === 'PageCreationConfirm') {
|
||||
this.$emit('remove-creation', item)
|
||||
}
|
||||
},
|
||||
updateCreationData(data) {
|
||||
this.creationUserData.amount = data.amount
|
||||
this.creationUserData.date = data.date
|
||||
this.creationUserData.memo = data.memo
|
||||
this.creationUserData.moderator = data.moderator
|
||||
|
||||
data.row.toggleDetails()
|
||||
},
|
||||
updateUserData(rowItem, newCreation) {
|
||||
rowItem.creation = newCreation
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
slotName() {
|
||||
return slotNames[this.slotIndex]
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
#overlay {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding-left: 5%;
|
||||
background-color: rgba(12, 11, 11, 0.781);
|
||||
z-index: 1000000;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@ -16,6 +16,8 @@ export const searchUsers = gql`
|
||||
email
|
||||
creation
|
||||
emailChecked
|
||||
hasElopage
|
||||
emailConfirmationSend
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,9 +54,9 @@ const dateTimeFormats = {
|
||||
},
|
||||
long: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
weekday: 'short',
|
||||
weekday: 'long',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
},
|
||||
@ -78,9 +78,9 @@ const dateTimeFormats = {
|
||||
},
|
||||
long: {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
weekday: 'short',
|
||||
weekday: 'long',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
},
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
"all_emails": "Alle Nutzer",
|
||||
"bookmark": "bookmark",
|
||||
"confirmed": "bestätigt",
|
||||
"creation": "Schöpfung",
|
||||
"creation_form": {
|
||||
"creation_for": "Aktives Grundeinkommen für",
|
||||
"enter_text": "Text eintragen",
|
||||
@ -19,12 +20,15 @@
|
||||
"update_creation": "Schöpfung aktualisieren"
|
||||
},
|
||||
"date": "Datum",
|
||||
"delete": "Löschen",
|
||||
"details": "Details",
|
||||
"edit": "Bearbeiten",
|
||||
"e_mail": "E-Mail",
|
||||
"firstname": "Vorname",
|
||||
"gradido_admin_footer": "Gradido Akademie Adminkonsole",
|
||||
"hide_details": "Details verbergen von",
|
||||
"lastname": "Nachname",
|
||||
"moderator": "Moderator",
|
||||
"multiple_creation_text": "Bitte wähle ein oder mehrere Mitglieder aus für die du Schöpfen möchtest.",
|
||||
"navbar": {
|
||||
"logout": "Abmelden",
|
||||
@ -55,6 +59,8 @@
|
||||
},
|
||||
"remove": "Entfernen",
|
||||
"remove_all": "alle Nutzer entfernen",
|
||||
"save": "Speichern",
|
||||
"text": "Text",
|
||||
"transaction": "Transaktion",
|
||||
"transactionlist": {
|
||||
"amount": "Betrag",
|
||||
@ -71,7 +77,7 @@
|
||||
"info": "Email bestätigen, wiederholt senden an:",
|
||||
"success": "Erfolgreiches Senden des Bestätigungs-Links an die E-Mail des Nutzers! ({email})",
|
||||
"text_false": " Die letzte Email wurde am {date} Uhr an das Mitglied ({mail}) gesendet.",
|
||||
"text_true": " Die Email wurde am {date} Uhr bestätigt."
|
||||
"text_true": " Die Email wurde bestätigt."
|
||||
},
|
||||
"user_search": "Nutzer-Suche"
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
"all_emails": "All users",
|
||||
"bookmark": "Remember",
|
||||
"confirmed": "confirmed",
|
||||
"creation": "Creation",
|
||||
"creation_form": {
|
||||
"creation_for": "Active Basic Income for",
|
||||
"enter_text": "Enter text",
|
||||
@ -19,12 +20,15 @@
|
||||
"update_creation": "Creation update"
|
||||
},
|
||||
"date": "Date",
|
||||
"delete": "Delete",
|
||||
"details": "Details",
|
||||
"edit": "Edit",
|
||||
"e_mail": "E-mail",
|
||||
"firstname": "Firstname",
|
||||
"gradido_admin_footer": "Gradido Academy Admin Console",
|
||||
"hide_details": "Hide details from",
|
||||
"lastname": "Lastname",
|
||||
"moderator": "Moderator",
|
||||
"multiple_creation_text": "Please select one or more members for which you would like to perform creations.",
|
||||
"navbar": {
|
||||
"logout": "Logout",
|
||||
@ -55,6 +59,8 @@
|
||||
},
|
||||
"remove": "Remove",
|
||||
"remove_all": "Remove all users",
|
||||
"save": "Speichern",
|
||||
"text": "Text",
|
||||
"transaction": "Transaction",
|
||||
"transactionlist": {
|
||||
"amount": "Amount",
|
||||
@ -70,8 +76,8 @@
|
||||
"error": "Error sending the confirmation link to the user: {message}",
|
||||
"info": "Confirm email, send repeatedly to:",
|
||||
"success": "Successfully send the confirmation link to the user's email! ({email})",
|
||||
"text_false": "The last email was sent to the member ({mail}) on {date} clock.",
|
||||
"text_true": "The email was confirmed on {date} clock."
|
||||
"text_false": "The last email was sent to the member ({mail}) on {date}.",
|
||||
"text_true": "The email was confirmed."
|
||||
},
|
||||
"user_search": "User search"
|
||||
}
|
||||
|
||||
34
admin/src/mixins/toggleRowDetails.js
Normal file
34
admin/src/mixins/toggleRowDetails.js
Normal file
@ -0,0 +1,34 @@
|
||||
export const toggleRowDetails = {
|
||||
data() {
|
||||
return {
|
||||
slotIndex: 0,
|
||||
openRow: null,
|
||||
creationUserData: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
rowToogleDetails(row, index) {
|
||||
if (this.openRow) {
|
||||
if (this.openRow.index === row.index) {
|
||||
if (index === this.slotIndex) {
|
||||
row.toggleDetails()
|
||||
this.openRow = null
|
||||
} else {
|
||||
this.slotIndex = index
|
||||
}
|
||||
} else {
|
||||
this.openRow.toggleDetails()
|
||||
row.toggleDetails()
|
||||
this.slotIndex = index
|
||||
this.openRow = row
|
||||
this.creationUserData = row.item
|
||||
}
|
||||
} else {
|
||||
row.toggleDetails()
|
||||
this.slotIndex = index
|
||||
this.openRow = row
|
||||
this.creationUserData = row.item
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
141
admin/src/mixins/toggleRowDetails.test.js
Normal file
141
admin/src/mixins/toggleRowDetails.test.js
Normal file
@ -0,0 +1,141 @@
|
||||
import { toggleRowDetails } from './toggleRowDetails'
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
const Component = {
|
||||
render() {},
|
||||
mixins: [toggleRowDetails],
|
||||
}
|
||||
|
||||
const toggleDetailsMock = jest.fn()
|
||||
const secondToggleDetailsMock = jest.fn()
|
||||
|
||||
const row = {
|
||||
toggleDetails: toggleDetailsMock,
|
||||
index: 0,
|
||||
item: {
|
||||
data: 'item-data',
|
||||
},
|
||||
}
|
||||
|
||||
let wrapper
|
||||
|
||||
describe('toggleRowDetails', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
wrapper = mount(Component, { localVue })
|
||||
})
|
||||
|
||||
it('sets default data', () => {
|
||||
expect(wrapper.vm.slotIndex).toBe(0)
|
||||
expect(wrapper.vm.openRow).toBe(null)
|
||||
expect(wrapper.vm.creationUserData).toEqual({})
|
||||
})
|
||||
|
||||
describe('no open row', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.vm.rowToogleDetails(row, 2)
|
||||
})
|
||||
|
||||
it('calls toggleDetails', () => {
|
||||
expect(toggleDetailsMock).toBeCalled()
|
||||
})
|
||||
|
||||
it('updates slot index', () => {
|
||||
expect(wrapper.vm.slotIndex).toBe(2)
|
||||
})
|
||||
|
||||
it('updates open row', () => {
|
||||
expect(wrapper.vm.openRow).toEqual(
|
||||
expect.objectContaining({
|
||||
index: 0,
|
||||
item: {
|
||||
data: 'item-data',
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('updates creation user data', () => {
|
||||
expect(wrapper.vm.creationUserData).toEqual({ data: 'item-data' })
|
||||
})
|
||||
})
|
||||
|
||||
describe('with open row', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setData({ openRow: row })
|
||||
})
|
||||
|
||||
describe('row index is open row index', () => {
|
||||
describe('index is slot index', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.vm.rowToogleDetails(row, 0)
|
||||
})
|
||||
|
||||
it('calls toggleDetails', () => {
|
||||
expect(toggleDetailsMock).toBeCalled()
|
||||
})
|
||||
|
||||
it('sets open row to null', () => {
|
||||
expect(wrapper.vm.openRow).toBe(null)
|
||||
})
|
||||
})
|
||||
|
||||
describe('index is not slot index', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.vm.rowToogleDetails(row, 2)
|
||||
})
|
||||
|
||||
it('does not call toggleDetails', () => {
|
||||
expect(toggleDetailsMock).not.toBeCalled()
|
||||
})
|
||||
|
||||
it('updates slot index', () => {
|
||||
expect(wrapper.vm.slotIndex).toBe(2)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('row index is not open row index', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.vm.rowToogleDetails(
|
||||
{
|
||||
toggleDetails: secondToggleDetailsMock,
|
||||
index: 2,
|
||||
item: {
|
||||
data: 'new-item-data',
|
||||
},
|
||||
},
|
||||
2,
|
||||
)
|
||||
})
|
||||
|
||||
it('closes the open row', () => {
|
||||
expect(toggleDetailsMock).toBeCalled()
|
||||
})
|
||||
|
||||
it('opens the new row', () => {
|
||||
expect(secondToggleDetailsMock).toBeCalled()
|
||||
})
|
||||
|
||||
it('updates slot index', () => {
|
||||
expect(wrapper.vm.slotIndex).toBe(2)
|
||||
})
|
||||
|
||||
it('updates open row', () => {
|
||||
expect(wrapper.vm.openRow).toEqual({
|
||||
toggleDetails: secondToggleDetailsMock,
|
||||
index: 2,
|
||||
item: {
|
||||
data: 'new-item-data',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('updates creation user data', () => {
|
||||
expect(wrapper.vm.creationUserData).toEqual({ data: 'new-item-data' })
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -17,11 +17,10 @@
|
||||
</b-input-group-text>
|
||||
</b-input-group-append>
|
||||
</b-input-group>
|
||||
<user-table
|
||||
<select-users-table
|
||||
v-if="itemsList.length > 0"
|
||||
type="UserListSearch"
|
||||
:itemsUser="itemsList"
|
||||
:fieldsTable="Searchfields"
|
||||
:items="itemsList"
|
||||
:fields="Searchfields"
|
||||
@push-item="pushItem"
|
||||
/>
|
||||
<b-pagination
|
||||
@ -41,11 +40,10 @@
|
||||
{{ $t('remove_all') }}
|
||||
</b-button>
|
||||
</div>
|
||||
<user-table
|
||||
<selected-users-table
|
||||
class="shadow p-3 mb-5 bg-white rounded"
|
||||
type="UserListMassCreation"
|
||||
:itemsUser="itemsMassCreation"
|
||||
:fieldsTable="fields"
|
||||
:items="itemsMassCreation"
|
||||
:fields="fields"
|
||||
@remove-item="removeItem"
|
||||
/>
|
||||
</div>
|
||||
@ -65,7 +63,8 @@
|
||||
</template>
|
||||
<script>
|
||||
import CreationFormular from '../components/CreationFormular.vue'
|
||||
import UserTable from '../components/UserTable.vue'
|
||||
import SelectUsersTable from '../components/Tables/SelectUsersTable.vue'
|
||||
import SelectedUsersTable from '../components/Tables/SelectedUsersTable.vue'
|
||||
import { searchUsers } from '../graphql/searchUsers'
|
||||
import { creationMonths } from '../mixins/creationMonths'
|
||||
|
||||
@ -74,7 +73,8 @@ export default {
|
||||
mixins: [creationMonths],
|
||||
components: {
|
||||
CreationFormular,
|
||||
UserTable,
|
||||
SelectUsersTable,
|
||||
SelectedUsersTable,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@ -165,19 +165,19 @@ describe('CreationConfirm', () => {
|
||||
expect(wrapper.findAll('tbody > tr')).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('confirm creation with error', () => {
|
||||
beforeEach(async () => {
|
||||
apolloMutateMock.mockRejectedValue({ message: 'Ouchhh!' })
|
||||
await wrapper.findComponent({ name: 'UserTable' }).vm.$emit('confirm-creation', { id: 2 })
|
||||
await wrapper.find('#overlay').findAll('button').at(1).trigger('click')
|
||||
})
|
||||
|
||||
it('toasts an error message', () => {
|
||||
expect(toastedErrorMock).toBeCalledWith('Ouchhh!')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('server response for get pending creations is error', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@ -1,17 +1,30 @@
|
||||
<template>
|
||||
<div class="creation-confirm">
|
||||
<user-table
|
||||
<div v-show="overlay" id="overlay" class="">
|
||||
<b-jumbotron class="bg-light p-4">
|
||||
<template #header>{{ $t('overlay.confirm.title') }}</template>
|
||||
<template #lead>{{ $t('overlay.confirm.text') }}</template>
|
||||
<hr class="my-4" />
|
||||
<p>{{ $t('overlay.confirm.question') }}</p>
|
||||
<b-button size="md" variant="danger" class="m-3" @click="overlay = false">
|
||||
{{ $t('overlay.confirm.no') }}
|
||||
</b-button>
|
||||
<b-button size="md" variant="success" class="m-3 text-right" @click="confirmCreation">
|
||||
{{ $t('overlay.confirm.yes') }}
|
||||
</b-button>
|
||||
</b-jumbotron>
|
||||
</div>
|
||||
<open-creations-table
|
||||
class="mt-4"
|
||||
type="PageCreationConfirm"
|
||||
:itemsUser="pendingCreations"
|
||||
:fieldsTable="fields"
|
||||
:items="pendingCreations"
|
||||
:fields="fields"
|
||||
@remove-creation="removeCreation"
|
||||
@confirm-creation="confirmCreation"
|
||||
@show-overlay="showOverlay"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import UserTable from '../components/UserTable.vue'
|
||||
import OpenCreationsTable from '../components/Tables/OpenCreationsTable.vue'
|
||||
import { getPendingCreations } from '../graphql/getPendingCreations'
|
||||
import { deletePendingCreation } from '../graphql/deletePendingCreation'
|
||||
import { confirmPendingCreation } from '../graphql/confirmPendingCreation'
|
||||
@ -19,11 +32,13 @@ import { confirmPendingCreation } from '../graphql/confirmPendingCreation'
|
||||
export default {
|
||||
name: 'CreationConfirm',
|
||||
components: {
|
||||
UserTable,
|
||||
OpenCreationsTable,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pendingCreations: [],
|
||||
overlay: false,
|
||||
item: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -43,19 +58,21 @@ export default {
|
||||
this.$toasted.error(error.message)
|
||||
})
|
||||
},
|
||||
confirmCreation(item) {
|
||||
confirmCreation() {
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: confirmPendingCreation,
|
||||
variables: {
|
||||
id: item.id,
|
||||
id: this.item.id,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
this.updatePendingCreations(item.id)
|
||||
this.overlay = false
|
||||
this.updatePendingCreations(this.item.id)
|
||||
this.$toasted.success(this.$t('creation_form.toasted_created'))
|
||||
})
|
||||
.catch((error) => {
|
||||
this.overlay = false
|
||||
this.$toasted.error(error.message)
|
||||
})
|
||||
},
|
||||
@ -78,22 +95,26 @@ export default {
|
||||
this.pendingCreations = this.pendingCreations.filter((obj) => obj.id !== id)
|
||||
this.$store.commit('openCreationsMinus', 1)
|
||||
},
|
||||
showOverlay(item) {
|
||||
this.overlay = true
|
||||
this.item = item
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
fields() {
|
||||
return [
|
||||
{ key: 'bookmark', label: 'löschen' },
|
||||
{ key: 'email', label: 'Email' },
|
||||
{ key: 'firstName', label: 'Vorname' },
|
||||
{ key: 'lastName', label: 'Nachname' },
|
||||
{ key: 'bookmark', label: this.$t('delete') },
|
||||
{ key: 'email', label: this.$t('e_mail') },
|
||||
{ key: 'firstName', label: this.$t('firstname') },
|
||||
{ key: 'lastName', label: this.$t('lastname') },
|
||||
{
|
||||
key: 'amount',
|
||||
label: 'Schöpfung',
|
||||
label: this.$t('creation'),
|
||||
formatter: (value) => {
|
||||
return value + ' GDD'
|
||||
},
|
||||
},
|
||||
{ key: 'memo', label: 'Text' },
|
||||
{ key: 'memo', label: this.$t('text') },
|
||||
{
|
||||
key: 'date',
|
||||
label: this.$t('date'),
|
||||
@ -101,9 +122,9 @@ export default {
|
||||
return this.$d(new Date(value), 'short')
|
||||
},
|
||||
},
|
||||
{ key: 'moderator', label: 'Moderator' },
|
||||
{ key: 'edit_creation', label: 'ändern' },
|
||||
{ key: 'confirm', label: 'speichern' },
|
||||
{ key: 'moderator', label: this.$t('moderator') },
|
||||
{ key: 'edit_creation', label: this.$t('edit') },
|
||||
{ key: 'confirm', label: this.$t('save') },
|
||||
]
|
||||
},
|
||||
},
|
||||
@ -112,3 +133,20 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
#overlay {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding-left: 5%;
|
||||
background-color: rgba(12, 11, 11, 0.781);
|
||||
z-index: 1000000;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
</b-input-group-append>
|
||||
</b-input-group>
|
||||
</div>
|
||||
<user-table type="PageUserSearch" :itemsUser="searchResult" :fieldsTable="fields" />
|
||||
<search-user-table type="PageUserSearch" :items="searchResult" :fields="fields" />
|
||||
<b-pagination
|
||||
pills
|
||||
size="lg"
|
||||
@ -35,7 +35,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import UserTable from '../components/UserTable.vue'
|
||||
import SearchUserTable from '../components/Tables/SearchUserTable.vue'
|
||||
import { searchUsers } from '../graphql/searchUsers'
|
||||
import { creationMonths } from '../mixins/creationMonths'
|
||||
|
||||
@ -43,7 +43,7 @@ export default {
|
||||
name: 'UserSearch',
|
||||
mixins: [creationMonths],
|
||||
components: {
|
||||
UserTable,
|
||||
SearchUserTable,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -106,6 +106,7 @@ export default {
|
||||
},
|
||||
{ key: 'show_details', label: this.$t('details') },
|
||||
{ key: 'confirm_mail', label: this.$t('confirmed') },
|
||||
{ key: 'has_elopage', label: 'elopage' },
|
||||
{ key: 'transactions_list', label: this.$t('transaction') },
|
||||
]
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gradido-backend",
|
||||
"version": "1.6.1",
|
||||
"version": "1.6.4",
|
||||
"description": "Gradido unified backend providing an API-Service for Gradido Transactions",
|
||||
"main": "src/index.ts",
|
||||
"repository": "https://github.com/gradido/gradido/backend",
|
||||
@ -18,6 +18,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/lodash.clonedeep": "^4.5.6",
|
||||
"apollo-log": "^1.1.0",
|
||||
"apollo-server-express": "^2.25.2",
|
||||
"apollo-server-testing": "^2.25.2",
|
||||
@ -29,6 +30,7 @@
|
||||
"graphql": "^15.5.1",
|
||||
"jest": "^27.2.4",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"module-alias": "^2.2.2",
|
||||
"moment": "^2.29.1",
|
||||
"mysql2": "^2.3.0",
|
||||
|
||||
@ -4,7 +4,7 @@ import dotenv from 'dotenv'
|
||||
dotenv.config()
|
||||
|
||||
const constants = {
|
||||
DB_VERSION: '0020-rename_and_clean_state_users',
|
||||
DB_VERSION: '0021-elopagebuys_fields_nullable',
|
||||
}
|
||||
|
||||
const server = {
|
||||
|
||||
@ -19,6 +19,12 @@ export class UserAdmin {
|
||||
|
||||
@Field(() => Boolean)
|
||||
emailChecked: boolean
|
||||
|
||||
@Field(() => Boolean)
|
||||
hasElopage: boolean
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
emailConfirmationSend?: string
|
||||
}
|
||||
|
||||
@ObjectType()
|
||||
|
||||
@ -21,7 +21,11 @@ import { UserTransactionRepository } from '../../typeorm/repository/UserTransact
|
||||
import { BalanceRepository } from '../../typeorm/repository/Balance'
|
||||
import { calculateDecay } from '../../util/decay'
|
||||
import { AdminPendingCreation } from '@entity/AdminPendingCreation'
|
||||
import { User as dbUser } from '@entity/User'
|
||||
import { hasElopageBuys } from '../../util/hasElopageBuys'
|
||||
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
|
||||
|
||||
// const EMAIL_OPT_IN_REGISTER = 1
|
||||
// const EMAIL_OPT_UNKNOWN = 3 // elopage?
|
||||
|
||||
@Resolver()
|
||||
export class AdminResolver {
|
||||
@ -40,7 +44,28 @@ export class AdminResolver {
|
||||
adminUser.lastName = user.lastName
|
||||
adminUser.email = user.email
|
||||
adminUser.creation = await getUserCreations(user.id)
|
||||
adminUser.emailChecked = await hasActivatedEmail(user.email)
|
||||
adminUser.emailChecked = user.emailChecked
|
||||
adminUser.hasElopage = await hasElopageBuys(user.email)
|
||||
if (!user.emailChecked) {
|
||||
const emailOptIn = await LoginEmailOptIn.findOne(
|
||||
{
|
||||
userId: user.id,
|
||||
},
|
||||
{
|
||||
order: {
|
||||
updatedAt: 'DESC',
|
||||
createdAt: 'DESC',
|
||||
},
|
||||
},
|
||||
)
|
||||
if (emailOptIn) {
|
||||
if (emailOptIn.updatedAt) {
|
||||
adminUser.emailConfirmationSend = emailOptIn.updatedAt.toISOString()
|
||||
} else {
|
||||
adminUser.emailConfirmationSend = emailOptIn.createdAt.toISOString()
|
||||
}
|
||||
}
|
||||
}
|
||||
return adminUser
|
||||
}),
|
||||
)
|
||||
@ -59,8 +84,7 @@ export class AdminResolver {
|
||||
): Promise<number[]> {
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const user = await userRepository.findByEmail(email)
|
||||
const isActivated = await hasActivatedEmail(user.email)
|
||||
if (!isActivated) {
|
||||
if (!user.emailChecked) {
|
||||
throw new Error('Creation could not be saved, Email is not activated')
|
||||
}
|
||||
const creations = await getUserCreations(user.id)
|
||||
@ -372,8 +396,3 @@ function isCreationValid(creations: number[], amount: number, creationDate: Date
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
async function hasActivatedEmail(email: string): Promise<boolean> {
|
||||
const user = await dbUser.findOne({ email })
|
||||
return user ? user.emailChecked : false
|
||||
}
|
||||
|
||||
@ -373,7 +373,7 @@ export class TransactionResolver {
|
||||
// TODO: the detour over the public key is unnecessary
|
||||
const recipiantPublicKey = await getPublicKey(email)
|
||||
if (!recipiantPublicKey) {
|
||||
throw new Error('recipiant not known')
|
||||
throw new Error('recipient not known')
|
||||
}
|
||||
if (!isHexPublicKey(recipiantPublicKey)) {
|
||||
throw new Error('invalid recipiant public key')
|
||||
|
||||
@ -21,7 +21,7 @@ import { sendAccountActivationEmail } from '../../mailer/sendAccountActivationEm
|
||||
import { klicktippSignIn } from '../../apis/KlicktippController'
|
||||
import { RIGHTS } from '../../auth/RIGHTS'
|
||||
import { ROLE_ADMIN } from '../../auth/ROLES'
|
||||
import { LoginElopageBuys } from '@entity/LoginElopageBuys'
|
||||
import { hasElopageBuys } from '../../util/hasElopageBuys'
|
||||
import { ServerUser } from '@entity/ServerUser'
|
||||
|
||||
const EMAIL_OPT_IN_RESET_PASSWORD = 2
|
||||
@ -661,7 +661,6 @@ export class UserResolver {
|
||||
return false
|
||||
}
|
||||
|
||||
const elopageBuyCount = await LoginElopageBuys.count({ payerEmail: userEntity.email })
|
||||
return elopageBuyCount > 0
|
||||
return hasElopageBuys(userEntity.email)
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ export const accountActivation = {
|
||||
text: (data: { link: string; firstName: string; lastName: string; email: string }): string =>
|
||||
`Hallo ${data.firstName} ${data.lastName},
|
||||
|
||||
Deine EMail wurde soeben bei Gradido registriert.
|
||||
Deine E-Mail-Adresse wurde soeben bei Gradido registriert.
|
||||
|
||||
Klicke bitte auf diesen Link, um die Registrierung abzuschließen und dein Gradido-Konto zu aktivieren:
|
||||
${data.link}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import { ApolloLogPlugin } from 'apollo-log'
|
||||
import { ApolloLogPlugin, LogMutateData } from 'apollo-log'
|
||||
import cloneDeep from 'lodash.clonedeep'
|
||||
|
||||
const plugins = [
|
||||
{
|
||||
@ -21,7 +22,22 @@ const plugins = [
|
||||
}
|
||||
},
|
||||
},
|
||||
ApolloLogPlugin(),
|
||||
ApolloLogPlugin({
|
||||
mutate: (data: LogMutateData) => {
|
||||
// We need to deep clone the object in order to not modify the actual request
|
||||
const dataCopy = cloneDeep(data)
|
||||
|
||||
// mask password if part of the query
|
||||
if (dataCopy.context.request.variables && dataCopy.context.request.variables.password) {
|
||||
dataCopy.context.request.variables.password = '***'
|
||||
}
|
||||
|
||||
// mask token at all times
|
||||
dataCopy.context.context.token = '***'
|
||||
|
||||
return dataCopy
|
||||
},
|
||||
}),
|
||||
]
|
||||
|
||||
export default plugins
|
||||
|
||||
6
backend/src/util/hasElopageBuys.ts
Normal file
6
backend/src/util/hasElopageBuys.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { LoginElopageBuys } from '@entity/LoginElopageBuys'
|
||||
|
||||
export async function hasElopageBuys(email: string): Promise<boolean> {
|
||||
const elopageBuyCount = await LoginElopageBuys.count({ payerEmail: email })
|
||||
return elopageBuyCount > 0
|
||||
}
|
||||
@ -53,12 +53,13 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
membership,
|
||||
} = req.body
|
||||
|
||||
loginElopageBuy.affiliateProgramId = parseInt(product.affiliate_program_id)
|
||||
loginElopageBuy.publisherId = parseInt(publisher.id)
|
||||
loginElopageBuy.orderId = parseInt(order_id)
|
||||
loginElopageBuy.productId = parseInt(product_id)
|
||||
loginElopageBuy.affiliateProgramId = parseInt(product.affiliate_program_id) || null
|
||||
loginElopageBuy.publisherId = parseInt(publisher.id) || null
|
||||
loginElopageBuy.orderId = parseInt(order_id) || null
|
||||
loginElopageBuy.productId = parseInt(product_id) || null
|
||||
// TODO: WHAT THE ACTUAL FUK? Please save this as float in the future directly in the database
|
||||
loginElopageBuy.productPrice = Math.trunc(parseFloat(product.price) * 100)
|
||||
const productPrice = parseFloat(product.price)
|
||||
loginElopageBuy.productPrice = productPrice ? Math.trunc(productPrice * 100) : 0
|
||||
loginElopageBuy.payerEmail = payer.email
|
||||
loginElopageBuy.publisherEmail = publisher.email
|
||||
// eslint-disable-next-line camelcase
|
||||
@ -66,7 +67,7 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
loginElopageBuy.successDate = new Date(success_date)
|
||||
loginElopageBuy.event = event
|
||||
// TODO this was never set on login_server - its unclear if this is the correct value
|
||||
loginElopageBuy.elopageUserId = parseInt(membership.id)
|
||||
loginElopageBuy.elopageUserId = parseInt(membership.id) || null
|
||||
|
||||
const firstName = payer.first_name
|
||||
const lastName = payer.last_name
|
||||
@ -79,7 +80,13 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
}
|
||||
|
||||
// Save the hook data
|
||||
try {
|
||||
await LoginElopageBuys.save(loginElopageBuy)
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Error saving LoginElopageBuy', error)
|
||||
return
|
||||
}
|
||||
|
||||
// create user for certain products
|
||||
/*
|
||||
@ -90,7 +97,10 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
Business-Mitgliedschaft, 43960
|
||||
Förderbeitrag: 49106
|
||||
*/
|
||||
if ([36001, 43741, 43870, 43944, 43960, 49106].includes(loginElopageBuy.productId)) {
|
||||
if (
|
||||
loginElopageBuy.productId &&
|
||||
[36001, 43741, 43870, 43944, 43960, 49106].includes(loginElopageBuy.productId)
|
||||
) {
|
||||
const email = loginElopageBuy.payerEmail
|
||||
|
||||
const VALIDATE_EMAIL = /^[a-zA-Z0-9.!#$%&?*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
|
||||
@ -123,7 +133,7 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
email,
|
||||
firstName,
|
||||
lastName,
|
||||
publisherId: loginElopageBuy.publisherId,
|
||||
publisherId: loginElopageBuy.publisherId || 0, // This seemed to be the default value if not set
|
||||
})
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
|
||||
@ -913,6 +913,18 @@
|
||||
"@types/koa-compose" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/lodash.clonedeep@^4.5.6":
|
||||
version "4.5.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.6.tgz#3b6c40a0affe0799a2ce823b440a6cf33571d32b"
|
||||
integrity sha512-cE1jYr2dEg1wBImvXlNtp0xDoS79rfEdGozQVgliDZj1uERH4k+rmEMTudP9b4VQ8O6nRb5gPqft0QzEQGMQgA==
|
||||
dependencies:
|
||||
"@types/lodash" "*"
|
||||
|
||||
"@types/lodash@*":
|
||||
version "4.14.178"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8"
|
||||
integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==
|
||||
|
||||
"@types/long@^4.0.0":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
|
||||
|
||||
10
community_server/.gitignore
vendored
10
community_server/.gitignore
vendored
@ -1,10 +0,0 @@
|
||||
config/app.php
|
||||
logs/
|
||||
src/GPBMetadata/
|
||||
tmp/
|
||||
vendor/
|
||||
websrc/node_modules/
|
||||
websrc/package-lock.json
|
||||
mithril_client/
|
||||
websrc/src/less-files.css
|
||||
|
||||
3
community_server/.gitmodules
vendored
3
community_server/.gitmodules
vendored
@ -1,3 +0,0 @@
|
||||
[submodule "src/protobuf"]
|
||||
path = src/protobuf
|
||||
url = git@github.com:gradido/gradido_protocol.git
|
||||
@ -1,30 +0,0 @@
|
||||
FROM phpdockerio/php74-fpm as community_server
|
||||
|
||||
# install php fpm
|
||||
RUN apt-get update \
|
||||
&& apt-get -y --no-install-recommends install curl unzip php7.4-curl php7.4-fpm php7.4-mbstring php7.4-intl php7.4-xml php7.4-pdo php7.4-mysql php7.4-xdebug \
|
||||
&& apt-get clean; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
|
||||
|
||||
WORKDIR /var/www/cakephp
|
||||
RUN mkdir logs && mkdir tmp && chmod 777 logs && chmod 777 tmp
|
||||
COPY ./community_server/ .
|
||||
COPY ./configs/community_server/app.php ./config/
|
||||
|
||||
RUN composer update
|
||||
RUN composer dump-autoload
|
||||
|
||||
######### special for code coverage and testing
|
||||
FROM community_server as test
|
||||
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get -y --no-install-recommends install php7.4-xdebug \
|
||||
&& apt-get clean; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
|
||||
|
||||
|
||||
ENV XDEBUG_MODE=coverage
|
||||
#RUN composer require --dev rregeer/phpunit-coverage-check
|
||||
|
||||
#CMD ./vendor/bin/phpunit --coverage-clover=./webroot/coverage/clover.xml
|
||||
CMD ./vendor/bin/phpunit --coverage-text=./webroot/coverage/coverage.info
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
# CakePHP Application Skeleton
|
||||
|
||||
[](https://travis-ci.org/cakephp/app)
|
||||
[](https://packagist.org/packages/cakephp/app)
|
||||
|
||||
A skeleton for creating applications with [CakePHP](https://cakephp.org) 3.x.
|
||||
|
||||
The framework source code can be found here: [cakephp/cakephp](https://github.com/cakephp/cakephp).
|
||||
|
||||
## Installation
|
||||
|
||||
1. Download [Composer](https://getcomposer.org/doc/00-intro.md) or update `composer self-update`.
|
||||
2. Run `php composer.phar create-project --prefer-dist cakephp/app [app_name]`.
|
||||
|
||||
If Composer is installed globally, run
|
||||
|
||||
```bash
|
||||
composer create-project --prefer-dist cakephp/app
|
||||
```
|
||||
|
||||
In case you want to use a custom app dir name (e.g. `/myapp/`):
|
||||
|
||||
```bash
|
||||
composer create-project --prefer-dist cakephp/app myapp
|
||||
```
|
||||
|
||||
You can now either use your machine's webserver to view the default home page, or start
|
||||
up the built-in webserver with:
|
||||
|
||||
```bash
|
||||
bin/cake server -p 8765
|
||||
```
|
||||
|
||||
Then visit `http://localhost:8765` to see the welcome page.
|
||||
|
||||
## Update
|
||||
|
||||
Since this skeleton is a starting point for your application and various files
|
||||
would have been modified as per your needs, there isn't a way to provide
|
||||
automated upgrades, so you have to do any updates manually.
|
||||
|
||||
## Configuration
|
||||
|
||||
Read and edit `config/app.php` and setup the `'Datasources'` and any other
|
||||
configuration relevant for your application.
|
||||
|
||||
## Layout
|
||||
|
||||
The app skeleton uses a subset of [Foundation](http://foundation.zurb.com/) (v5) CSS
|
||||
framework by default. You can, however, replace it with any other library or
|
||||
custom styles.
|
||||
@ -1,75 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
################################################################################
|
||||
#
|
||||
# Cake is a shell script for invoking CakePHP shell commands
|
||||
#
|
||||
# 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 1.2.0
|
||||
# @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# Canonicalize by following every symlink of the given name recursively
|
||||
canonicalize() {
|
||||
NAME="$1"
|
||||
if [ -f "$NAME" ]
|
||||
then
|
||||
DIR=$(dirname -- "$NAME")
|
||||
NAME=$(cd -P "$DIR" > /dev/null && pwd -P)/$(basename -- "$NAME")
|
||||
fi
|
||||
while [ -h "$NAME" ]; do
|
||||
DIR=$(dirname -- "$NAME")
|
||||
SYM=$(readlink "$NAME")
|
||||
NAME=$(cd "$DIR" > /dev/null && cd "$(dirname -- "$SYM")" > /dev/null && pwd)/$(basename -- "$SYM")
|
||||
done
|
||||
echo "$NAME"
|
||||
}
|
||||
|
||||
# Find a CLI version of PHP
|
||||
findCliPhp() {
|
||||
for TESTEXEC in php php-cli /usr/local/bin/php
|
||||
do
|
||||
SAPI=$(echo "<?= PHP_SAPI ?>" | $TESTEXEC 2>/dev/null)
|
||||
if [ "$SAPI" = "cli" ]
|
||||
then
|
||||
echo $TESTEXEC
|
||||
return
|
||||
fi
|
||||
done
|
||||
echo "Failed to find a CLI version of PHP; falling back to system standard php executable" >&2
|
||||
echo "php";
|
||||
}
|
||||
|
||||
# If current path is a symlink, resolve to real path
|
||||
realname="$0"
|
||||
if [ -L "$realname" ]
|
||||
then
|
||||
realname=$(readlink -f "$0")
|
||||
fi
|
||||
|
||||
CONSOLE=$(dirname -- "$(canonicalize "$realname")")
|
||||
APP=$(dirname "$CONSOLE")
|
||||
|
||||
# If your CLI PHP is somewhere that this doesn't find, you can define a PHP environment
|
||||
# variable with the correct path in it.
|
||||
if [ -z "$PHP" ]
|
||||
then
|
||||
PHP=$(findCliPhp)
|
||||
fi
|
||||
|
||||
if [ "$(basename "$realname")" != 'cake' ]
|
||||
then
|
||||
exec "$PHP" "$CONSOLE"/cake.php "$(basename "$realname")" "$@"
|
||||
else
|
||||
exec "$PHP" "$CONSOLE"/cake.php "$@"
|
||||
fi
|
||||
|
||||
exit
|
||||
@ -1,27 +0,0 @@
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: Cake is a Windows batch script for invoking CakePHP shell commands
|
||||
::
|
||||
:: CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
|
||||
:: Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
|
||||
::
|
||||
:: Licensed under The MIT License
|
||||
:: 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 2.0.0
|
||||
:: @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
@echo off
|
||||
|
||||
SET app=%0
|
||||
SET lib=%~dp0
|
||||
|
||||
php "%lib%cake.php" %*
|
||||
|
||||
echo.
|
||||
|
||||
exit /B %ERRORLEVEL%
|
||||
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/php -q
|
||||
<?php
|
||||
// Check platform requirements
|
||||
require dirname(__DIR__) . '/config/requirements.php';
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
use App\Application;
|
||||
use Cake\Console\CommandRunner;
|
||||
|
||||
// Build the runner with an application and root executable name.
|
||||
$runner = new CommandRunner(new Application(dirname(__DIR__) . '/config'), 'cake');
|
||||
exit($runner->run($argv));
|
||||
@ -1,58 +0,0 @@
|
||||
{
|
||||
"name": "cakephp/app",
|
||||
"description": "CakePHP skeleton app",
|
||||
"homepage": "https://cakephp.org",
|
||||
"type": "project",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": ">=5.6",
|
||||
"cakephp/cakephp": "3.9.*",
|
||||
"cakephp/plugin-installer": "^1.0",
|
||||
"datto/json-rpc": "^6.0",
|
||||
"google/protobuf": "v3.10.*",
|
||||
"mobiledetect/mobiledetectlib": "2.*",
|
||||
"paragonie/sodium_compat": "^1.11",
|
||||
"tuupola/base58": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cakephp/bake": "^1.9.0",
|
||||
"cakephp/cakephp-codesniffer": "^3.0",
|
||||
"cakephp/debug_kit": "^3.17.0",
|
||||
"josegonzalez/dotenv": "3.*",
|
||||
"phpunit/phpunit": "^5.7|^6.0",
|
||||
"psy/psysh": "@stable"
|
||||
},
|
||||
"suggest": {
|
||||
"markstory/asset_compress": "An asset compression plugin which provides file concatenation and a flexible filter system for preprocessing and minification.",
|
||||
"dereuromark/cakephp-ide-helper": "After baking your code, this keeps your annotations in sync with the code evolving from there on for maximum IDE and PHPStan compatibility."
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/",
|
||||
"" : "src/",
|
||||
"GPBMetadata\\Gradido\\": "src/Model/Messages/GPBMetadata/Gradido/",
|
||||
"Proto\\Gradido\\" : "src/Model/Messages/Proto/Gradido/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"App\\Test\\": "tests/",
|
||||
"Cake\\Test\\": "vendor/cakephp/cakephp/tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-install-cmd": "App\\Console\\Installer::postInstall",
|
||||
"post-create-project-cmd": "App\\Console\\Installer::postInstall",
|
||||
"check": [
|
||||
"@test",
|
||||
"@cs-check"
|
||||
],
|
||||
"cs-check": "phpcs --colors -p --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/",
|
||||
"cs-fix": "phpcbf --colors --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/",
|
||||
"test": "phpunit --colors=always"
|
||||
},
|
||||
"prefer-stable": true,
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
5577
community_server/composer.lock
generated
5577
community_server/composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,407 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Cake\Cache\Engine\FileEngine;
|
||||
use Cake\Database\Connection;
|
||||
use Cake\Database\Driver\Mysql;
|
||||
use Cake\Error\ExceptionRenderer;
|
||||
use Cake\Log\Engine\FileLog;
|
||||
use Cake\Mailer\Transport\MailTransport;
|
||||
|
||||
return [
|
||||
/**
|
||||
* Debug Level:
|
||||
*
|
||||
* Production Mode:
|
||||
* false: No error messages, errors, or warnings shown.
|
||||
*
|
||||
* Development Mode:
|
||||
* true: Errors and warnings shown.
|
||||
*/
|
||||
'debug' => filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN),
|
||||
|
||||
/**
|
||||
* Configure basic information about the application.
|
||||
*
|
||||
* - namespace - The namespace to find app classes under.
|
||||
* - defaultLocale - The default locale for translation, formatting currencies and numbers, date and time.
|
||||
* - encoding - The encoding used for HTML + database connections.
|
||||
* - base - The base directory the app resides in. If false this
|
||||
* will be auto detected.
|
||||
* - dir - Name of app directory.
|
||||
* - webroot - The webroot directory.
|
||||
* - wwwRoot - The file path to webroot.
|
||||
* - baseUrl - To configure CakePHP to *not* use mod_rewrite and to
|
||||
* use CakePHP pretty URLs, remove these .htaccess
|
||||
* files:
|
||||
* /.htaccess
|
||||
* /webroot/.htaccess
|
||||
* And uncomment the baseUrl key below.
|
||||
* - fullBaseUrl - A base URL to use for absolute links. When set to false (default)
|
||||
* CakePHP generates required value based on `HTTP_HOST` environment variable.
|
||||
* However, you can define it manually to optimize performance or if you
|
||||
* are concerned about people manipulating the `Host` header.
|
||||
* - imageBaseUrl - Web path to the public images directory under webroot.
|
||||
* - cssBaseUrl - Web path to the public css directory under webroot.
|
||||
* - jsBaseUrl - Web path to the public js directory under webroot.
|
||||
* - paths - Configure paths for non class based resources. Supports the
|
||||
* `plugins`, `templates`, `locales` subkeys, which allow the definition of
|
||||
* paths for plugins, view templates and locale files respectively.
|
||||
*/
|
||||
'App' => [
|
||||
'namespace' => 'App',
|
||||
'encoding' => env('APP_ENCODING', 'UTF-8'),
|
||||
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'),
|
||||
'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'UTC'),
|
||||
'base' => false,
|
||||
'dir' => 'src',
|
||||
'webroot' => 'webroot',
|
||||
'wwwRoot' => WWW_ROOT,
|
||||
//'baseUrl' => env('SCRIPT_NAME'),
|
||||
'fullBaseUrl' => false,
|
||||
'imageBaseUrl' => 'img/',
|
||||
'cssBaseUrl' => 'css/',
|
||||
'jsBaseUrl' => 'js/',
|
||||
'paths' => [
|
||||
'plugins' => [ROOT . DS . 'plugins' . DS],
|
||||
'templates' => [APP . 'Template' . DS],
|
||||
'locales' => [APP . 'Locale' . DS],
|
||||
],
|
||||
],
|
||||
|
||||
/**
|
||||
* Security and encryption configuration
|
||||
*
|
||||
* - salt - A random string used in security hashing methods.
|
||||
* The salt value is also used as the encryption key.
|
||||
* You should treat it as extremely sensitive data.
|
||||
*/
|
||||
'Security' => [
|
||||
'salt' => env('SECURITY_SALT', '__SALT__'),
|
||||
],
|
||||
|
||||
/**
|
||||
* Apply timestamps with the last modified time to static assets (js, css, images).
|
||||
* Will append a querystring parameter containing the time the file was modified.
|
||||
* This is useful for busting browser caches.
|
||||
*
|
||||
* Set to true to apply timestamps when debug is true. Set to 'force' to always
|
||||
* enable timestamping regardless of debug value.
|
||||
*/
|
||||
'Asset' => [
|
||||
//'timestamp' => true,
|
||||
// 'cacheTime' => '+1 year'
|
||||
],
|
||||
|
||||
/**
|
||||
* Configure the cache adapters.
|
||||
*/
|
||||
'Cache' => [
|
||||
'default' => [
|
||||
'className' => FileEngine::class,
|
||||
'path' => CACHE,
|
||||
'url' => env('CACHE_DEFAULT_URL', null),
|
||||
],
|
||||
|
||||
/**
|
||||
* Configure the cache used for general framework caching.
|
||||
* Translation cache files are stored with this configuration.
|
||||
* Duration will be set to '+2 minutes' in bootstrap.php when debug = true
|
||||
* If you set 'className' => 'Null' core cache will be disabled.
|
||||
*/
|
||||
'_cake_core_' => [
|
||||
'className' => FileEngine::class,
|
||||
'prefix' => 'myapp_cake_core_',
|
||||
'path' => CACHE . 'persistent/',
|
||||
'serialize' => true,
|
||||
'duration' => '+1 years',
|
||||
'url' => env('CACHE_CAKECORE_URL', null),
|
||||
],
|
||||
|
||||
/**
|
||||
* Configure the cache for model and datasource caches. This cache
|
||||
* configuration is used to store schema descriptions, and table listings
|
||||
* in connections.
|
||||
* Duration will be set to '+2 minutes' in bootstrap.php when debug = true
|
||||
*/
|
||||
'_cake_model_' => [
|
||||
'className' => FileEngine::class,
|
||||
'prefix' => 'myapp_cake_model_',
|
||||
'path' => CACHE . 'models/',
|
||||
'serialize' => true,
|
||||
'duration' => '+1 years',
|
||||
'url' => env('CACHE_CAKEMODEL_URL', null),
|
||||
],
|
||||
|
||||
/**
|
||||
* Configure the cache for routes. The cached routes collection is built the
|
||||
* first time the routes are processed via `config/routes.php`.
|
||||
* Duration will be set to '+2 seconds' in bootstrap.php when debug = true
|
||||
*/
|
||||
'_cake_routes_' => [
|
||||
'className' => FileEngine::class,
|
||||
'prefix' => 'myapp_cake_routes_',
|
||||
'path' => CACHE,
|
||||
'serialize' => true,
|
||||
'duration' => '+1 years',
|
||||
'url' => env('CACHE_CAKEROUTES_URL', null),
|
||||
],
|
||||
],
|
||||
|
||||
/**
|
||||
* Configure the Error and Exception handlers used by your application.
|
||||
*
|
||||
* By default errors are displayed using Debugger, when debug is true and logged
|
||||
* by Cake\Log\Log when debug is false.
|
||||
*
|
||||
* In CLI environments exceptions will be printed to stderr with a backtrace.
|
||||
* In web environments an HTML page will be displayed for the exception.
|
||||
* With debug true, framework errors like Missing Controller will be displayed.
|
||||
* When debug is false, framework errors will be coerced into generic HTTP errors.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `errorLevel` - int - The level of errors you are interested in capturing.
|
||||
* - `trace` - boolean - Whether or not backtraces should be included in
|
||||
* logged errors/exceptions.
|
||||
* - `log` - boolean - Whether or not you want exceptions logged.
|
||||
* - `exceptionRenderer` - string - The class responsible for rendering
|
||||
* uncaught exceptions. If you choose a custom class you should place
|
||||
* the file for that class in src/Error. This class needs to implement a
|
||||
* render method.
|
||||
* - `skipLog` - array - List of exceptions to skip for logging. Exceptions that
|
||||
* extend one of the listed exceptions will also be skipped for logging.
|
||||
* E.g.:
|
||||
* `'skipLog' => ['Cake\Http\Exception\NotFoundException', 'Cake\Http\Exception\UnauthorizedException']`
|
||||
* - `extraFatalErrorMemory` - int - The number of megabytes to increase
|
||||
* the memory limit by when a fatal error is encountered. This allows
|
||||
* breathing room to complete logging or error handling.
|
||||
*/
|
||||
'Error' => [
|
||||
'errorLevel' => E_ALL,
|
||||
'exceptionRenderer' => ExceptionRenderer::class,
|
||||
'skipLog' => [],
|
||||
'log' => true,
|
||||
'trace' => true,
|
||||
],
|
||||
|
||||
/**
|
||||
* Email configuration.
|
||||
*
|
||||
* By defining transports separately from delivery profiles you can easily
|
||||
* re-use transport configuration across multiple profiles.
|
||||
*
|
||||
* You can specify multiple configurations for production, development and
|
||||
* testing.
|
||||
*
|
||||
* Each transport needs a `className`. Valid options are as follows:
|
||||
*
|
||||
* Mail - Send using PHP mail function
|
||||
* Smtp - Send using SMTP
|
||||
* Debug - Do not send the email, just return the result
|
||||
*
|
||||
* You can add custom transports (or override existing transports) by adding the
|
||||
* appropriate file to src/Mailer/Transport. Transports should be named
|
||||
* 'YourTransport.php', where 'Your' is the name of the transport.
|
||||
*/
|
||||
'EmailTransport' => [
|
||||
'default' => [
|
||||
'className' => MailTransport::class,
|
||||
/*
|
||||
* The following keys are used in SMTP transports:
|
||||
*/
|
||||
'host' => 'localhost',
|
||||
'port' => 25,
|
||||
'timeout' => 30,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
'client' => null,
|
||||
'tls' => null,
|
||||
'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
|
||||
],
|
||||
],
|
||||
|
||||
/**
|
||||
* Email delivery profiles
|
||||
*
|
||||
* Delivery profiles allow you to predefine various properties about email
|
||||
* messages from your application and give the settings a name. This saves
|
||||
* duplication across your application and makes maintenance and development
|
||||
* easier. Each profile accepts a number of keys. See `Cake\Mailer\Email`
|
||||
* for more information.
|
||||
*/
|
||||
'Email' => [
|
||||
'default' => [
|
||||
'transport' => 'default',
|
||||
'from' => 'you@localhost',
|
||||
//'charset' => 'utf-8',
|
||||
//'headerCharset' => 'utf-8',
|
||||
],
|
||||
],
|
||||
|
||||
/**
|
||||
* Connection information used by the ORM to connect
|
||||
* to your application's datastores.
|
||||
*
|
||||
* ### Notes
|
||||
* - Drivers include Mysql Postgres Sqlite Sqlserver
|
||||
* See vendor\cakephp\cakephp\src\Database\Driver for complete list
|
||||
* - Do not use periods in database name - it may lead to error.
|
||||
* See https://github.com/cakephp/cakephp/issues/6471 for details.
|
||||
* - 'encoding' is recommended to be set to full UTF-8 4-Byte support.
|
||||
* E.g set it to 'utf8mb4' in MariaDB and MySQL and 'utf8' for any
|
||||
* other RDBMS.
|
||||
*/
|
||||
'Datasources' => [
|
||||
'default' => [
|
||||
'className' => Connection::class,
|
||||
'driver' => Mysql::class,
|
||||
'persistent' => false,
|
||||
'host' => 'localhost',
|
||||
/*
|
||||
* CakePHP will use the default DB port based on the driver selected
|
||||
* MySQL on MAMP uses port 8889, MAMP users will want to uncomment
|
||||
* the following line and set the port accordingly
|
||||
*/
|
||||
//'port' => 'non_standard_port_number',
|
||||
'username' => 'my_app',
|
||||
'password' => 'secret',
|
||||
'database' => 'my_app',
|
||||
/*
|
||||
* You do not need to set this flag to use full utf-8 encoding (internal default since CakePHP 3.6).
|
||||
*/
|
||||
//'encoding' => 'utf8mb4',
|
||||
'timezone' => 'UTC',
|
||||
'flags' => [],
|
||||
'cacheMetadata' => true,
|
||||
'log' => false,
|
||||
|
||||
/**
|
||||
* Set identifier quoting to true if you are using reserved words or
|
||||
* special characters in your table or column names. Enabling this
|
||||
* setting will result in queries built using the Query Builder having
|
||||
* identifiers quoted when creating SQL. It should be noted that this
|
||||
* decreases performance because each query needs to be traversed and
|
||||
* manipulated before being executed.
|
||||
*/
|
||||
'quoteIdentifiers' => false,
|
||||
|
||||
/**
|
||||
* During development, if using MySQL < 5.6, uncommenting the
|
||||
* following line could boost the speed at which schema metadata is
|
||||
* fetched from the database. It can also be set directly with the
|
||||
* mysql configuration directive 'innodb_stats_on_metadata = 0'
|
||||
* which is the recommended value in production environments
|
||||
*/
|
||||
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
|
||||
|
||||
'url' => env('DATABASE_URL', null),
|
||||
],
|
||||
|
||||
/**
|
||||
* The test connection is used during the test suite.
|
||||
*/
|
||||
'test' => [
|
||||
'className' => Connection::class,
|
||||
'driver' => Mysql::class,
|
||||
'persistent' => false,
|
||||
'host' => 'localhost',
|
||||
//'port' => 'non_standard_port_number',
|
||||
'username' => 'my_app',
|
||||
'password' => 'secret',
|
||||
'database' => 'test_myapp',
|
||||
//'encoding' => 'utf8mb4',
|
||||
'timezone' => 'UTC',
|
||||
'cacheMetadata' => true,
|
||||
'quoteIdentifiers' => false,
|
||||
'log' => false,
|
||||
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
|
||||
'url' => env('DATABASE_TEST_URL', null),
|
||||
],
|
||||
],
|
||||
|
||||
/**
|
||||
* Configures logging options
|
||||
*/
|
||||
'Log' => [
|
||||
'debug' => [
|
||||
'className' => FileLog::class,
|
||||
'path' => LOGS,
|
||||
'file' => 'debug',
|
||||
'url' => env('LOG_DEBUG_URL', null),
|
||||
'scopes' => false,
|
||||
'levels' => ['notice', 'info', 'debug'],
|
||||
],
|
||||
'error' => [
|
||||
'className' => FileLog::class,
|
||||
'path' => LOGS,
|
||||
'file' => 'error',
|
||||
'url' => env('LOG_ERROR_URL', null),
|
||||
'scopes' => false,
|
||||
'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'],
|
||||
],
|
||||
// To enable this dedicated query log, you need set your datasource's log flag to true
|
||||
'queries' => [
|
||||
'className' => FileLog::class,
|
||||
'path' => LOGS,
|
||||
'file' => 'queries',
|
||||
'url' => env('LOG_QUERIES_URL', null),
|
||||
'scopes' => ['queriesLog'],
|
||||
],
|
||||
],
|
||||
|
||||
/**
|
||||
* Session configuration.
|
||||
*
|
||||
* Contains an array of settings to use for session configuration. The
|
||||
* `defaults` key is used to define a default preset to use for sessions, any
|
||||
* settings declared here will override the settings of the default config.
|
||||
*
|
||||
* ## Options
|
||||
*
|
||||
* - `cookie` - The name of the cookie to use. Defaults to 'CAKEPHP'. Avoid using `.` in cookie names,
|
||||
* as PHP will drop sessions from cookies with `.` in the name.
|
||||
* - `cookiePath` - The url path for which session cookie is set. Maps to the
|
||||
* `session.cookie_path` php.ini config. Defaults to base path of app.
|
||||
* - `timeout` - The time in minutes the session should be valid for.
|
||||
* Pass 0 to disable checking timeout.
|
||||
* Please note that php.ini's session.gc_maxlifetime must be equal to or greater
|
||||
* than the largest Session['timeout'] in all served websites for it to have the
|
||||
* desired effect.
|
||||
* - `defaults` - The default configuration set to use as a basis for your session.
|
||||
* There are four built-in options: php, cake, cache, database.
|
||||
* - `handler` - Can be used to enable a custom session handler. Expects an
|
||||
* array with at least the `engine` key, being the name of the Session engine
|
||||
* class to use for managing the session. CakePHP bundles the `CacheSession`
|
||||
* and `DatabaseSession` engines.
|
||||
* - `ini` - An associative array of additional ini values to set.
|
||||
*
|
||||
* The built-in `defaults` options are:
|
||||
*
|
||||
* - 'php' - Uses settings defined in your php.ini.
|
||||
* - 'cake' - Saves session files in CakePHP's /tmp directory.
|
||||
* - 'database' - Uses CakePHP's database sessions.
|
||||
* - 'cache' - Use the Cache class to save sessions.
|
||||
*
|
||||
* To define a custom session handler, save it at src/Network/Session/<name>.php.
|
||||
* Make sure the class implements PHP's `SessionHandlerInterface` and set
|
||||
* Session.handler to <name>
|
||||
*
|
||||
* To use database sessions, load the SQL file located at config/schema/sessions.sql
|
||||
*/
|
||||
'Session' => [
|
||||
'defaults' => 'php',
|
||||
],
|
||||
// Gradido specific configuration
|
||||
// Login Server ip and port
|
||||
'LoginServer' => [
|
||||
'host' => 'http://127.0.0.1',
|
||||
'port' => 1201
|
||||
],
|
||||
'API' => [
|
||||
'allowedCaller' => [''] // insert domains or ips from login-server and gdt if they not at localhost
|
||||
],
|
||||
'ServerAdminEmail' => 'info@gradido.net', // email 'from' field for transfer notification emails
|
||||
'noReplyEmail' => 'no-replay@gradido.net', // email sender for creation notification emails to user
|
||||
|
||||
'GroupNode' => false
|
||||
];
|
||||
@ -1,212 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 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.8
|
||||
* @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/*
|
||||
* Configure paths required to find CakePHP + general filepath constants
|
||||
*/
|
||||
require __DIR__ . '/paths.php';
|
||||
|
||||
/*
|
||||
* Bootstrap CakePHP.
|
||||
*
|
||||
* Does the various bits of setup that CakePHP needs to do.
|
||||
* This includes:
|
||||
*
|
||||
* - Registering the CakePHP autoloader.
|
||||
* - Setting the default application paths.
|
||||
*/
|
||||
require CORE_PATH . 'config' . DS . 'bootstrap.php';
|
||||
|
||||
use Cake\Cache\Cache;
|
||||
use Cake\Console\ConsoleErrorHandler;
|
||||
use Cake\Core\Configure;
|
||||
use Cake\Core\Configure\Engine\PhpConfig;
|
||||
use Cake\Core\Plugin;
|
||||
use Cake\Database\Type;
|
||||
use Cake\Datasource\ConnectionManager;
|
||||
use Cake\Error\ErrorHandler;
|
||||
use Cake\Http\ServerRequest;
|
||||
use Cake\Log\Log;
|
||||
use Cake\Mailer\Email;
|
||||
use Cake\Mailer\TransportFactory;
|
||||
use Cake\Utility\Inflector;
|
||||
use Cake\Utility\Security;
|
||||
|
||||
/**
|
||||
* Uncomment block of code below if you want to use `.env` file during development.
|
||||
* You should copy `config/.env.default to `config/.env` and set/modify the
|
||||
* variables as required.
|
||||
*
|
||||
* It is HIGHLY discouraged to use a .env file in production, due to security risks
|
||||
* and decreased performance on each request. The purpose of the .env file is to emulate
|
||||
* the presence of the environment variables like they would be present in production.
|
||||
*/
|
||||
// if (!env('APP_NAME') && file_exists(CONFIG . '.env')) {
|
||||
// $dotenv = new \josegonzalez\Dotenv\Loader([CONFIG . '.env']);
|
||||
// $dotenv->parse()
|
||||
// ->putenv()
|
||||
// ->toEnv()
|
||||
// ->toServer();
|
||||
// }
|
||||
|
||||
/*
|
||||
* Read configuration file and inject configuration into various
|
||||
* CakePHP classes.
|
||||
*
|
||||
* By default there is only one configuration file. It is often a good
|
||||
* idea to create multiple configuration files, and separate the configuration
|
||||
* that changes from configuration that does not. This makes deployment simpler.
|
||||
*/
|
||||
try {
|
||||
Configure::config('default', new PhpConfig());
|
||||
Configure::load('app', 'default', false);
|
||||
} catch (\Exception $e) {
|
||||
exit($e->getMessage() . "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Load an environment local configuration file.
|
||||
* You can use a file like app_local.php to provide local overrides to your
|
||||
* shared configuration.
|
||||
*/
|
||||
//Configure::load('app_local', 'default');
|
||||
|
||||
/*
|
||||
* When debug = true the metadata cache should only last
|
||||
* for a short time.
|
||||
*/
|
||||
if (Configure::read('debug')) {
|
||||
Configure::write('Cache._cake_model_.duration', '+2 minutes');
|
||||
Configure::write('Cache._cake_core_.duration', '+2 minutes');
|
||||
// disable router cache during development
|
||||
Configure::write('Cache._cake_routes_.duration', '+2 seconds');
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the default server timezone. Using UTC makes time calculations / conversions easier.
|
||||
* Check http://php.net/manual/en/timezones.php for list of valid timezone strings.
|
||||
*/
|
||||
date_default_timezone_set(Configure::read('App.defaultTimezone'));
|
||||
|
||||
/*
|
||||
* Configure the mbstring extension to use the correct encoding.
|
||||
*/
|
||||
mb_internal_encoding(Configure::read('App.encoding'));
|
||||
|
||||
/*
|
||||
* Set the default locale. This controls how dates, number and currency is
|
||||
* formatted and sets the default language to use for translations.
|
||||
*/
|
||||
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 {
|
||||
(new ErrorHandler(Configure::read('Error')))->register();
|
||||
}
|
||||
|
||||
/*
|
||||
* Include the CLI bootstrap overrides.
|
||||
*/
|
||||
if ($isCli) {
|
||||
require __DIR__ . '/bootstrap_cli.php';
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the full base URL.
|
||||
* This URL is used as the base of all absolute links.
|
||||
*
|
||||
* If you define fullBaseUrl in your config file you can remove this.
|
||||
*/
|
||||
if (!Configure::read('App.fullBaseUrl')) {
|
||||
$s = null;
|
||||
if (env('HTTPS')) {
|
||||
$s = 's';
|
||||
}
|
||||
|
||||
$httpHost = env('HTTP_HOST');
|
||||
if (isset($httpHost)) {
|
||||
Configure::write('App.fullBaseUrl', 'http' . $s . '://' . $httpHost);
|
||||
}
|
||||
unset($httpHost, $s);
|
||||
}
|
||||
|
||||
Cache::setConfig(Configure::consume('Cache'));
|
||||
ConnectionManager::setConfig(Configure::consume('Datasources'));
|
||||
TransportFactory::setConfig(Configure::consume('EmailTransport'));
|
||||
Email::setConfig(Configure::consume('Email'));
|
||||
Log::setConfig(Configure::consume('Log'));
|
||||
Security::setSalt(Configure::consume('Security.salt'));
|
||||
|
||||
/*
|
||||
* The default crypto extension in 3.0 is OpenSSL.
|
||||
* If you are migrating from 2.x uncomment this code to
|
||||
* use a more compatible Mcrypt based implementation
|
||||
*/
|
||||
//Security::engine(new \Cake\Utility\Crypto\Mcrypt());
|
||||
|
||||
/*
|
||||
* Setup detectors for mobile and tablet.
|
||||
*/
|
||||
ServerRequest::addDetector('mobile', function ($request) {
|
||||
$detector = new \Detection\MobileDetect();
|
||||
|
||||
return $detector->isMobile();
|
||||
});
|
||||
ServerRequest::addDetector('tablet', function ($request) {
|
||||
$detector = new \Detection\MobileDetect();
|
||||
|
||||
return $detector->isTablet();
|
||||
});
|
||||
|
||||
/*
|
||||
* Enable immutable time objects in the ORM.
|
||||
*
|
||||
* You can enable default locale format parsing by adding calls
|
||||
* to `useLocaleParser()`. This enables the automatic conversion of
|
||||
* locale specific date formats. For details see
|
||||
* @link https://book.cakephp.org/3.0/en/core-libraries/internationalization-and-localization.html#parsing-localized-datetime-data
|
||||
*/
|
||||
Type::build('time')
|
||||
->useImmutable();
|
||||
Type::build('date')
|
||||
->useImmutable();
|
||||
Type::build('datetime')
|
||||
->useImmutable();
|
||||
Type::build('timestamp')
|
||||
->useImmutable();
|
||||
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: POST, GET, PUT, PATCH, DELETE, OPTIONS');
|
||||
header('Access-Control-Allow-Headers: *');
|
||||
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom Inflector rules, can be set to correctly pluralize or singularize
|
||||
* table, model, controller names or whatever other string is passed to the
|
||||
* inflection functions.
|
||||
*/
|
||||
//Inflector::rules('plural', ['/^(inflect)or$/i' => '\1ables']);
|
||||
//Inflector::rules('irregular', ['red' => 'redlings']);
|
||||
//Inflector::rules('uninflected', ['dontinflectme']);
|
||||
//Inflector::rules('transliteration', ['/å/' => 'aa']);
|
||||
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 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 3.0.0
|
||||
* @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
use Cake\Core\Configure;
|
||||
|
||||
/**
|
||||
* Additional bootstrapping and configuration for CLI environments should
|
||||
* be put here.
|
||||
*/
|
||||
|
||||
// Set the fullBaseUrl to allow URLs to be generated in shell tasks.
|
||||
// This is useful when sending email from shells.
|
||||
//Configure::write('App.fullBaseUrl', php_uname('n'));
|
||||
|
||||
// Set logs to different files so they don't have permission conflicts.
|
||||
Configure::write('Log.debug.file', 'cli-debug');
|
||||
Configure::write('Log.error.file', 'cli-error');
|
||||
@ -1,46 +0,0 @@
|
||||
<?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.
|
||||
*/
|
||||
|
||||
return [
|
||||
// Container element used by control().
|
||||
'inputContainer' => '{{content}}',
|
||||
// Container element used by control() when a field has an error.
|
||||
'inputContainerError' => '<div class="{{type}}{{required}} is-invalid">{{content}}{{error}}</div>',
|
||||
// Label element when inputs are not nested inside the label.
|
||||
'label' => '<label{{attrs}} class="form-label">{{text}}</label>',
|
||||
// Generic input element.
|
||||
'input' => '<input type="{{type}}" class="form-control" name="{{name}}"{{attrs}}/>',
|
||||
// Textarea input element,
|
||||
'textarea' => '<textarea class="form-control" name="{{name}}"{{attrs}}>{{value}}</textarea>',
|
||||
// Error message wrapper elements.
|
||||
'error' => '<div class="invalid-feedback">'
|
||||
. '{{content}}'
|
||||
. '</div>',
|
||||
// Container for error items.
|
||||
'errorList' => '{{content}}',
|
||||
// Error item wrapper.
|
||||
'errorItem' => '<div>{{text}}</div>'
|
||||
];
|
||||
/*
|
||||
|
||||
<div class="form-group row showcase_row_area">
|
||||
<div class="col-md-3 showcase_text_area">
|
||||
<label for="inputAmount">Betrag in GDD</label>
|
||||
</div>
|
||||
<div class="col-md-9 showcase_content_area">
|
||||
<input type="number" step="0.01" class="form-control" id="inputAmount" name="inputAmount" >
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="input number required">
|
||||
<label for="amount">Amount</label>
|
||||
<input type="number" name="amount" required="required" step="0.01" id="amount">
|
||||
</div>
|
||||
|
||||
*/
|
||||
@ -1,25 +0,0 @@
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
|
||||
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||
fastcgi_param REQUEST_URI $request_uri;
|
||||
fastcgi_param DOCUMENT_URI $document_uri;
|
||||
fastcgi_param DOCUMENT_ROOT $document_root;
|
||||
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||
fastcgi_param REQUEST_SCHEME $scheme;
|
||||
fastcgi_param HTTPS $https if_not_empty;
|
||||
|
||||
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
|
||||
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||
|
||||
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||
fastcgi_param REMOTE_PORT $remote_port;
|
||||
fastcgi_param SERVER_ADDR $server_addr;
|
||||
fastcgi_param SERVER_PORT $server_port;
|
||||
fastcgi_param SERVER_NAME $server_name;
|
||||
|
||||
# PHP only, required if PHP was built with --enable-force-cgi-redirect
|
||||
fastcgi_param REDIRECT_STATUS 200;
|
||||
@ -1,88 +0,0 @@
|
||||
types {
|
||||
text/html html htm shtml;
|
||||
text/css css;
|
||||
text/xml xml;
|
||||
image/gif gif;
|
||||
image/jpeg jpeg jpg;
|
||||
application/javascript js;
|
||||
application/atom+xml atom;
|
||||
application/rss+xml rss;
|
||||
|
||||
text/mathml mml;
|
||||
text/plain txt;
|
||||
text/vnd.sun.j2me.app-descriptor jad;
|
||||
text/vnd.wap.wml wml;
|
||||
text/x-component htc;
|
||||
|
||||
image/png png;
|
||||
image/tiff tif tiff;
|
||||
image/vnd.wap.wbmp wbmp;
|
||||
image/x-icon ico;
|
||||
image/x-jng jng;
|
||||
image/x-ms-bmp bmp;
|
||||
image/svg+xml svg svgz;
|
||||
image/webp webp;
|
||||
|
||||
application/font-woff woff;
|
||||
application/java-archive jar war ear;
|
||||
application/json json;
|
||||
application/mac-binhex40 hqx;
|
||||
application/msword doc;
|
||||
application/pdf pdf;
|
||||
application/postscript ps eps ai;
|
||||
application/rtf rtf;
|
||||
application/vnd.apple.mpegurl m3u8;
|
||||
application/vnd.ms-excel xls;
|
||||
application/vnd.ms-fontobject eot;
|
||||
application/vnd.ms-powerpoint ppt;
|
||||
application/vnd.wap.wmlc wmlc;
|
||||
application/vnd.google-earth.kml+xml kml;
|
||||
application/vnd.google-earth.kmz kmz;
|
||||
application/x-7z-compressed 7z;
|
||||
application/x-cocoa cco;
|
||||
application/x-java-archive-diff jardiff;
|
||||
application/x-java-jnlp-file jnlp;
|
||||
application/x-makeself run;
|
||||
application/x-perl pl pm;
|
||||
application/x-pilot prc pdb;
|
||||
application/x-rar-compressed rar;
|
||||
application/x-redhat-package-manager rpm;
|
||||
application/x-sea sea;
|
||||
application/x-shockwave-flash swf;
|
||||
application/x-stuffit sit;
|
||||
application/x-tcl tcl tk;
|
||||
application/x-x509-ca-cert der pem crt;
|
||||
application/x-xpinstall xpi;
|
||||
application/xhtml+xml xhtml;
|
||||
application/xspf+xml xspf;
|
||||
application/zip zip;
|
||||
|
||||
application/octet-stream bin exe dll;
|
||||
application/octet-stream deb;
|
||||
application/octet-stream dmg;
|
||||
application/octet-stream iso img;
|
||||
application/octet-stream msi msp msm;
|
||||
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
|
||||
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
|
||||
|
||||
audio/midi mid midi kar;
|
||||
audio/mpeg mp3;
|
||||
audio/ogg ogg;
|
||||
audio/x-m4a m4a;
|
||||
audio/x-realaudio ra;
|
||||
|
||||
video/3gpp 3gpp 3gp;
|
||||
video/mp2t ts;
|
||||
video/mp4 mp4;
|
||||
video/mpeg mpeg mpg;
|
||||
video/quicktime mov;
|
||||
video/webm webm;
|
||||
video/x-flv flv;
|
||||
video/x-m4v m4v;
|
||||
video/x-mng mng;
|
||||
video/x-ms-asf asx asf;
|
||||
video/x-ms-wmv wmv;
|
||||
video/x-msvideo avi;
|
||||
}
|
||||
@ -1,86 +0,0 @@
|
||||
|
||||
server {
|
||||
|
||||
listen 80 ;
|
||||
listen [::]:80;
|
||||
server_name 0.0.0.0;
|
||||
|
||||
#include /etc/nginx/common/protect.conf;
|
||||
#include /etc/nginx/common/protect_add_header.conf;
|
||||
#include /etc/nginx/common/ssl.conf;
|
||||
|
||||
|
||||
root /usr/share/nginx/html/webroot;
|
||||
index index.php;
|
||||
|
||||
location ~* \.(png|jpg|ico|webp)\$ {
|
||||
expires 30d;
|
||||
}
|
||||
|
||||
location ~* \.(js|css) {
|
||||
# expires 1d;
|
||||
expires 1d;
|
||||
}
|
||||
|
||||
location ~ \.php\$ {
|
||||
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
|
||||
# Check that the PHP script exists before passing it
|
||||
try_files $fastcgi_script_name =404;
|
||||
|
||||
# Bypass the fact that try_files resets $fastcgi_path_info
|
||||
# see: http://trac.nginx.org/nginx/ticket/321
|
||||
set $path_info $fastcgi_path_info;
|
||||
fastcgi_param PATH_INFO $path_info;
|
||||
|
||||
fastcgi_index index.php;
|
||||
include fastcgi.conf;
|
||||
|
||||
#fastcgi_pass unix:/run/php/php7.3-fpm.sock;
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location /account {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_cache_bypass \$http_upgrade;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$remote_addr;
|
||||
proxy_set_header Host \$host;
|
||||
rewrite /account/(.*) /\$1 break;
|
||||
|
||||
#proxy_next_upstream error timeout invalid_header http_502 non_idempotent;
|
||||
proxy_pass http://login-server:1200;
|
||||
proxy_redirect off;
|
||||
|
||||
|
||||
}
|
||||
|
||||
location /login_api {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_cache_bypass \$http_upgrade;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$remote_addr;
|
||||
proxy_set_header Host \$host;
|
||||
rewrite /login_api/(.*) /\$1 break;
|
||||
|
||||
proxy_pass http://login-server:1201;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files \$uri \$uri/ /index.php?\$args;
|
||||
}
|
||||
|
||||
# access_log /var/log/nginx/access.log main;
|
||||
|
||||
}
|
||||
@ -1,89 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* 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 3.0.0
|
||||
* @license MIT License (https://opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Use the DS to separate the directories in other defines
|
||||
*/
|
||||
if (!defined('DS')) {
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* These defines should only be edited if you have cake installed in
|
||||
* a directory layout other than the way it is distributed.
|
||||
* When using custom settings be sure to use the DS and do not add a trailing DS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The full path to the directory which holds "src", WITHOUT a trailing DS.
|
||||
*/
|
||||
define('ROOT', dirname(__DIR__));
|
||||
|
||||
/**
|
||||
* The actual directory name for the application directory. Normally
|
||||
* named 'src'.
|
||||
*/
|
||||
define('APP_DIR', 'src');
|
||||
|
||||
/**
|
||||
* Path to the application's directory.
|
||||
*/
|
||||
define('APP', ROOT . DS . APP_DIR . DS);
|
||||
|
||||
/**
|
||||
* Path to the config directory.
|
||||
*/
|
||||
define('CONFIG', ROOT . DS . 'config' . DS);
|
||||
|
||||
/**
|
||||
* File path to the webroot directory.
|
||||
*
|
||||
* To derive your webroot from your webserver change this to:
|
||||
*
|
||||
* `define('WWW_ROOT', rtrim($_SERVER['DOCUMENT_ROOT'], DS) . DS);`
|
||||
*/
|
||||
define('WWW_ROOT', ROOT . DS . 'webroot' . DS);
|
||||
|
||||
/**
|
||||
* Path to the tests directory.
|
||||
*/
|
||||
define('TESTS', ROOT . DS . 'tests' . DS);
|
||||
|
||||
/**
|
||||
* Path to the temporary files directory.
|
||||
*/
|
||||
define('TMP', ROOT . DS . 'tmp' . DS);
|
||||
|
||||
/**
|
||||
* Path to the logs directory.
|
||||
*/
|
||||
define('LOGS', ROOT . DS . 'logs' . DS);
|
||||
|
||||
/**
|
||||
* Path to the cache files directory. It can be shared between hosts in a multi-server setup.
|
||||
*/
|
||||
define('CACHE', TMP . 'cache' . DS);
|
||||
|
||||
/**
|
||||
* The absolute path to the "cake" directory, WITHOUT a trailing DS.
|
||||
*
|
||||
* CakePHP should always be installed with composer, so look there.
|
||||
*/
|
||||
define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'vendor' . DS . 'cakephp' . DS . 'cakephp');
|
||||
|
||||
/**
|
||||
* Path to the cake directory.
|
||||
*/
|
||||
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
|
||||
define('CAKE', CORE_PATH . 'src' . DS);
|
||||
@ -1,2 +0,0 @@
|
||||
#upload_max_filesize = 100M
|
||||
#post_max_size = 108M
|
||||
@ -1,39 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 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 3.5.0
|
||||
* @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/*
|
||||
* You can empty out this file, if you are certain that you match all requirements.
|
||||
*/
|
||||
|
||||
/*
|
||||
* You can remove this if you are confident that your PHP version is sufficient.
|
||||
*/
|
||||
if (version_compare(PHP_VERSION, '5.6.0') < 0) {
|
||||
trigger_error('Your PHP version must be equal or higher than 5.6.0 to use CakePHP.' . PHP_EOL, E_USER_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* You can remove this if you are confident you have intl installed.
|
||||
*/
|
||||
if (!extension_loaded('intl')) {
|
||||
trigger_error('You must enable the intl extension to use CakePHP.' . PHP_EOL, E_USER_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* You can remove this if you are confident you have mbstring installed.
|
||||
*/
|
||||
if (!extension_loaded('mbstring')) {
|
||||
trigger_error('You must enable the mbstring extension to use CakePHP.' . PHP_EOL, E_USER_ERROR);
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
<?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.
|
||||
*/
|
||||
|
||||
return [
|
||||
'inputContainer' => '{{content}}',
|
||||
'input' => '<div class="input-group showcase_row_area">'
|
||||
. '<input type="{{type}}" class="form-control" name="{{name}}"{{attrs}}/>'
|
||||
. '</div>',
|
||||
'error' => '<div class="input-group showcase_content_area invalid-feedback">'
|
||||
. '{{content}}'
|
||||
. '</div>',
|
||||
|
||||
// Container for error items.
|
||||
//'errorList' => '<ul>{{content}}</ul>',
|
||||
'errorList' => '{{content}}',
|
||||
|
||||
// Error item wrapper.
|
||||
//'errorItem' => '<li>{{text}}</li>',
|
||||
'errorItem' => '<div>{{text}}</div>'
|
||||
];
|
||||
@ -1,160 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Routes configuration
|
||||
*
|
||||
* In this file, you set up routes to your controllers and their actions.
|
||||
* Routes are very important mechanism that allows you to freely connect
|
||||
* different URLs to chosen controllers and their actions (functions).
|
||||
*
|
||||
* 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
|
||||
* @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
use Cake\Http\Middleware\CsrfProtectionMiddleware;
|
||||
use Cake\Routing\RouteBuilder;
|
||||
use Cake\Routing\Router;
|
||||
use Cake\Routing\Route\DashedRoute;
|
||||
|
||||
use Cake\Core\Configure;
|
||||
|
||||
/**
|
||||
* The default class to use for all routes
|
||||
*
|
||||
* The following route classes are supplied with CakePHP and are appropriate
|
||||
* to set as the default:
|
||||
*
|
||||
* - Route
|
||||
* - InflectedRoute
|
||||
* - DashedRoute
|
||||
*
|
||||
* If no call is made to `Router::defaultRouteClass()`, the class used is
|
||||
* `Route` (`Cake\Routing\Route\Route`)
|
||||
*
|
||||
* Note that `Route` does not do any inflections on URLs which will result in
|
||||
* inconsistently cased URLs when used with `:plugin`, `:controller` and
|
||||
* `:action` markers.
|
||||
*
|
||||
* Cache: Routes are cached to improve performance, check the RoutingMiddleware
|
||||
* constructor in your `src/Application.php` file to change this behavior.
|
||||
*
|
||||
*/
|
||||
Router::defaultRouteClass(DashedRoute::class);
|
||||
|
||||
Router::scope('/', function (RouteBuilder $routes) {
|
||||
|
||||
$csrf = new CsrfProtectionMiddleware([
|
||||
'httpOnly' => true
|
||||
]);
|
||||
|
||||
// Token check will be skipped when callback returns `true`.
|
||||
$csrf->whitelistCallback(function ($request) {
|
||||
// Skip token check for API URLs.
|
||||
//die($request->getParam('controller'));
|
||||
$whitelist = ['JsonRequestHandler', 'ElopageWebhook', 'AppRequests'];
|
||||
$ajaxWhitelist = ['TransactionSendCoins', 'TransactionCreations'];
|
||||
|
||||
$callerIp = $request->clientIp();
|
||||
|
||||
foreach($whitelist as $entry) {
|
||||
if($request->getParam('controller') === $entry) {
|
||||
if($entry == 'ElopageWebhook' || $entry == 'AppRequests') {
|
||||
return true;
|
||||
}
|
||||
$allowedIpLocalhost = ['127.0.0.1', 'localhost', '', '::1'];
|
||||
if(in_array($callerIp, $allowedIpLocalhost)) {
|
||||
return true;
|
||||
}
|
||||
$allowedCaller = Configure::read('API.allowedCaller');
|
||||
$ipPerHost = [];
|
||||
if($allowedCaller && count($allowedCaller) > 0) {
|
||||
|
||||
foreach($allowedCaller as $allowed) {
|
||||
$ip = gethostbyname($allowed);
|
||||
$ipPerHost[$allowed] = $ip;
|
||||
if($ip === $callerIp) return true;
|
||||
}
|
||||
//die("caller ip: $callerIp<br>");
|
||||
}
|
||||
//var_dump(['caller_ip' => $callerIp, 'ips' => $ipPerHost]);
|
||||
die(json_encode(['state' => 'error', 'details' => ['caller_ip' => $callerIp, 'ips' => $ipPerHost]]));
|
||||
}
|
||||
}
|
||||
// disable csfr for all ajax requests in ajax whitelisted controller
|
||||
foreach($ajaxWhitelist as $entry) {
|
||||
if($request->getParam('controller') === $entry) {
|
||||
$action = $request->getParam('action');
|
||||
if(preg_match('/^ajax/', $action)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Register scoped middleware for in scopes.
|
||||
$routes->registerMiddleware('csrf', $csrf);
|
||||
|
||||
/**
|
||||
* Apply a middleware to the current route scope.
|
||||
* Requires middleware to be registered via `Application::routes()` with `registerMiddleware()`
|
||||
*/
|
||||
$routes->applyMiddleware('csrf');
|
||||
|
||||
/**
|
||||
* Here, we are connecting '/' (base path) to a controller called 'Pages',
|
||||
* its action called 'display', and we pass a param to select the view file
|
||||
* to use (in this case, src/Template/Pages/home.ctp)...
|
||||
*/
|
||||
//$routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
|
||||
$routes->connect('/', ['controller' => 'Dashboard', 'action' => 'index']);
|
||||
$routes->connect('/api/:action/*', ['controller' => 'AppRequests'], ['routeClass' => 'DashedRoute']);
|
||||
//$routes->connect('/client', ['controller' => 'Pages', 'action' => 'display', 'js']);
|
||||
$routes->connect('/server', ['controller' => 'Dashboard', 'action' => 'serverIndex']);
|
||||
$routes->connect('/client', ['controller' => 'Pages', 'action' => 'display', 'vue']);
|
||||
$routes->connect('/vue-dev', ['controller' => 'Pages', 'action' => 'display', 'vue-dev']);
|
||||
//$routes->connect('/', 'https://gradido2.dario-rekowski.de/account', array('status' => 303));
|
||||
|
||||
/**
|
||||
* ...and connect the rest of 'Pages' controller's URLs.
|
||||
*/
|
||||
$routes->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']);
|
||||
|
||||
/**
|
||||
* Connect catchall routes for all controllers.
|
||||
*
|
||||
* Using the argument `DashedRoute`, the `fallbacks` method is a shortcut for
|
||||
*
|
||||
* ```
|
||||
* $routes->connect('/:controller', ['action' => 'index'], ['routeClass' => 'DashedRoute']);
|
||||
* $routes->connect('/:controller/:action/*', [], ['routeClass' => 'DashedRoute']);
|
||||
* ```
|
||||
*
|
||||
* Any route class can be used with this method, such as:
|
||||
* - DashedRoute
|
||||
* - InflectedRoute
|
||||
* - Route
|
||||
* - Or your own route class
|
||||
*
|
||||
* You can remove these routes once you've connected the
|
||||
* routes you want in your application.
|
||||
*/
|
||||
$routes->fallbacks(DashedRoute::class);
|
||||
});
|
||||
|
||||
/**
|
||||
* If you need a different set of middleware or none at all,
|
||||
* open new scope and define routes there.
|
||||
*
|
||||
* ```
|
||||
* Router::scope('/api', function (RouteBuilder $routes) {
|
||||
* // No $routes->applyMiddleware() here.
|
||||
* // Connect API actions here.
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
@ -1,18 +0,0 @@
|
||||
# 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.
|
||||
# MIT License (https://opensource.org/licenses/mit-license.php)
|
||||
|
||||
CREATE TABLE i18n (
|
||||
id int NOT NULL auto_increment,
|
||||
locale varchar(6) NOT NULL,
|
||||
model varchar(255) NOT NULL,
|
||||
foreign_key int(10) NOT NULL,
|
||||
field varchar(255) NOT NULL,
|
||||
content text,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field),
|
||||
INDEX I18N_FIELD(model, foreign_key, field)
|
||||
);
|
||||
@ -1,15 +0,0 @@
|
||||
# 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.
|
||||
# MIT License (https://opensource.org/licenses/mit-license.php)
|
||||
|
||||
CREATE TABLE `sessions` (
|
||||
`id` char(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
`created` datetime DEFAULT CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+
|
||||
`modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- optional, requires MySQL 5.6.5+
|
||||
`data` blob DEFAULT NULL, -- for PostgreSQL use bytea instead of blob
|
||||
`expires` int(10) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
@ -1,38 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
[! -z "${FOLDER_NAME}"] && FOLDER_NAME=community_server
|
||||
|
||||
COLOR_GREEN="\033[0;32m"
|
||||
COLOR_YELLOW="\e[33m"
|
||||
COLOR_NONE="\033[0m"
|
||||
|
||||
SCRIPT=`realpath -s $0`
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
#echo -e "script: $SCRIPT, Path: $SCRIPTPATH "
|
||||
|
||||
cd /var/www/html
|
||||
if [ ! -d "$FOLDER_NAME" ] ; then
|
||||
mkdir $FOLDER_NAME
|
||||
else
|
||||
chmod -R 0755 $FOLDER_NAME
|
||||
fi
|
||||
cd $FOLDER_NAME
|
||||
cp -r $SCRIPTPATH/src .
|
||||
cp -r $SCRIPTPATH/config .
|
||||
cp -r $SCRIPTPATH/composer.json .
|
||||
cp -r $SCRIPTPATH/webroot .
|
||||
composer install
|
||||
if [ ! -d "tmp" ] ; then
|
||||
mkdir tmp
|
||||
chown -R www-data:www-data ./tmp
|
||||
fi
|
||||
if [ ! -d "logs" ] ; then
|
||||
mkdir logs
|
||||
chown -R www-data:www-data ./logs
|
||||
fi
|
||||
|
||||
cd ..
|
||||
chown -R www-data:www-data $FOLDER_NAME
|
||||
chmod -R 0755 $FOLDER_NAME/src
|
||||
chmod -R 0755 $FOLDER_NAME/config
|
||||
chmod -R 0755 $FOLDER_NAME/webroot
|
||||
@ -1,132 +0,0 @@
|
||||
|
||||
# community server api
|
||||
|
||||
In this examples I assume that you use gradido with docker-compose build on your local maschine
|
||||
|
||||
## Konto Overview
|
||||
return current account balance
|
||||
|
||||
GET http://localhost/state-balances/ajaxGetBalance/-127182
|
||||
|
||||
If session is valid, return:
|
||||
```json
|
||||
{"state":"success","balance":174500}
|
||||
```
|
||||
- balance: Gradido Cent, 4 Nachkommastellen (2 Reserve), 174500 = 17,45 GDD
|
||||
|
||||
## List Transactions
|
||||
List all transactions from logged in user, currently without paging
|
||||
Ajax:
|
||||
GET http://localhost/state-balances/ajaxListTransactions/-127182/
|
||||
or
|
||||
GET http://localhost/state-balances/ajaxListTransactions/-127182/DESC
|
||||
to get transaction in descending order
|
||||
|
||||
Antwort:
|
||||
Wenn alles okay:
|
||||
```json
|
||||
{"state":"success", "transactions":
|
||||
[
|
||||
{
|
||||
"name": "Max Mustermann",
|
||||
"email": "Maxim Mustermann",
|
||||
"type": "send",
|
||||
"transaction_id": 2,
|
||||
"date": "2021-02-19T13:25:36+00:00",
|
||||
"balance": 1920000,
|
||||
"memo": "a piece of cake :)",
|
||||
"pubkey": "038a6f93270dc57b91d76bf110ad3863fcb7d1b08e7692e793fcdb4467e5b6a7"
|
||||
}
|
||||
],
|
||||
"transactionExecutingCount": 0,
|
||||
"count": 1,
|
||||
"gdtSum": 0,
|
||||
"timeUsed": 0.04562687873840332
|
||||
}
|
||||
```
|
||||
|
||||
- name: name of other involved party or empty if unknown (if other party don't belong to group)
|
||||
- if type is send, name is name of receiver
|
||||
- if type is receive, name is name of sender
|
||||
- if type is creation currently I use a static string ("Gradido Akademie)
|
||||
- email: optional, only if type is send or receive and other user is known
|
||||
- pubkey: optional, only if type is send or receive and other user isn't known
|
||||
- type: type of transaction
|
||||
- creation: user has get gradidos created
|
||||
- send: user has send another user gradidos
|
||||
- receiver: user has received gradidos from another user
|
||||
- transaction_id: id of transaction in db, in stage2 also the hedera sequence number of transaction
|
||||
- date: date of ordering transaction (booking date)
|
||||
- balance: Gradido Cent, 4 Nachkommastellen (2 Reserve), 1920000 = 192,00 GDD
|
||||
- memo: Details about transaction
|
||||
- pubkey: optional, if other party isn't known, hexadecimal representation of 32 Byte public key of user [0-9a-f]
|
||||
|
||||
- transactionExecutingCount: how many transaction for this user currently pending and waiting for signing
|
||||
- count: sum of finished transactions user is involved
|
||||
- gdtSum: sum of gdt of user in cent with 2 places (Nachkommastellen)
|
||||
- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
|
||||
|
||||
## Creation Transaction
|
||||
Make a creation transaction
|
||||
With new Option set in Login-Server:
|
||||
```ini
|
||||
unsecure.allow_auto_sign_transactions = 1
|
||||
```
|
||||
transactions can be auto-signed directly with handing in transaction.
|
||||
Normally a forwarding to login-server check transactions side is neccessary to minimize security risks.
|
||||
|
||||
POST http://localhost/transaction-creations/ajaxCreate
|
||||
```json
|
||||
{
|
||||
"session_id" : -127182,
|
||||
"email": "max.musterman@gmail.de",
|
||||
"amount": 10000000,
|
||||
"target_date":"2021-02-19T13:25:36+00:00",
|
||||
"memo":"AGE",
|
||||
"auto_sign": true
|
||||
}
|
||||
```
|
||||
return if everything is ok:
|
||||
```json
|
||||
{"state":"success", "timeUsed": 0.0122}
|
||||
```
|
||||
- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
|
||||
|
||||
## Send Coins Transaction
|
||||
Make a simple GDD Transaction, send Coins from one user to other.
|
||||
With new Option set in Login-Server:
|
||||
```ini
|
||||
unsecure.allow_auto_sign_transactions = 1
|
||||
```
|
||||
transactions can be auto-signed directly with handing in transaction.
|
||||
Normally a forwarding to login-server check transactions side is neccessary to minimize security risks.
|
||||
|
||||
POST http://localhost/transaction-send-coins/ajaxCreate
|
||||
```json
|
||||
{
|
||||
"session_id" : -127182,
|
||||
"amount": 2000000,
|
||||
"email": "max.musterman@gmail.de",
|
||||
"memo":"Thank you :)",
|
||||
"auto_sign": true
|
||||
}
|
||||
```
|
||||
- amout: amount to transfer, 2000000 = 200,00 GDD
|
||||
- email: receiver email address, must be differ from user email
|
||||
- memo: Details about transaction
|
||||
- auto_sign: set to true to directly sign transaction if unsecure.allow_auto_sign_transactions = 1 is set
|
||||
|
||||
return if everything is ok:
|
||||
```json
|
||||
{"state":"success", "timeUsed": 0.0122}
|
||||
```
|
||||
- timeUsed: time used for getting data from db in seconds, only for analyse backend performance
|
||||
|
||||
Than the transaction was created on community server, send to login-server, signed (if unsecure.allow_auto_sign_transactions = 1 and auto_sign = true)
|
||||
and send back to community server and put into db.
|
||||
After you get this answear you see the new transaction if you list transactions or call for the balance.
|
||||
|
||||
Without auto-sign the transaction is pending on login-server and waits for the user to review it at
|
||||
http://localhost/account/checkTransactions
|
||||
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,20 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2015 gRPC authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# need grpc only for hedera hashgraph
|
||||
#PHP_PLUGIN="$(which grpc_php_plugin)"
|
||||
#protoc --proto_path=./src/protobuf/gradido --php_out=./src/ --grpc_out=./src/ --plugin=protoc-gen-grpc=$PHP_PLUGIN ./src/protobuf/gradido/*.proto
|
||||
|
||||
protoc --proto_path=./src/protobuf --php_out=./src/Model/Messages ./src/protobuf/gradido/*.proto
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
colors="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
>
|
||||
<php>
|
||||
<ini name="memory_limit" value="-1"/>
|
||||
<ini name="apc.enable_cli" value="1"/>
|
||||
</php>
|
||||
|
||||
<!-- Add any additional test suites you want to run here -->
|
||||
<testsuites>
|
||||
<testsuite name="app">
|
||||
<directory>tests/TestCase/</directory>
|
||||
</testsuite>
|
||||
<!-- Add plugin test suites here. -->
|
||||
</testsuites>
|
||||
|
||||
<!-- Setup a listener for fixtures -->
|
||||
<listeners>
|
||||
<listener
|
||||
class="\Cake\TestSuite\Fixture\FixtureInjector">
|
||||
<arguments>
|
||||
<object class="\Cake\TestSuite\Fixture\FixtureManager" />
|
||||
</arguments>
|
||||
</listener>
|
||||
</listeners>
|
||||
|
||||
<!-- Ignore vendor tests in code coverage reports -->
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">src/</directory>
|
||||
<directory suffix=".php">plugins/*/src/</directory>
|
||||
<exclude>
|
||||
<file>src/Console/Installer.php</file>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
@ -1,117 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 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 3.3.0
|
||||
* @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace App;
|
||||
|
||||
use Cake\Core\Configure;
|
||||
use Cake\Core\Exception\MissingPluginException;
|
||||
use Cake\Error\Middleware\ErrorHandlerMiddleware;
|
||||
use Cake\Http\BaseApplication;
|
||||
use Cake\Http\Middleware\CsrfProtectionMiddleware;
|
||||
use Cake\Routing\Middleware\AssetMiddleware;
|
||||
use Cake\Routing\Middleware\RoutingMiddleware;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Application setup class.
|
||||
*
|
||||
* This defines the bootstrapping logic and middleware layers you
|
||||
* want to use in your application.
|
||||
*/
|
||||
class Application extends BaseApplication
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function bootstrap()
|
||||
{
|
||||
// Call parent to load bootstrap from files.
|
||||
parent::bootstrap();
|
||||
|
||||
if (PHP_SAPI === 'cli') {
|
||||
$this->bootstrapCli();
|
||||
}
|
||||
|
||||
/*
|
||||
* Only try to load DebugKit in development mode
|
||||
* Debug Kit should not be installed on a production system
|
||||
*/
|
||||
if (Configure::read('debug')) {
|
||||
$this->addPlugin(\DebugKit\Plugin::class);
|
||||
}
|
||||
|
||||
// Load more plugins here
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Setup the middleware queue your application will use.
|
||||
*
|
||||
* @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup.
|
||||
* @return \Cake\Http\MiddlewareQueue The updated middleware queue.
|
||||
*/
|
||||
public function middleware($middlewareQueue)
|
||||
{
|
||||
//$csrf = new CsrfProtectionMiddleware();
|
||||
|
||||
// Token check will be skipped when callback returns `true`.
|
||||
/*$csrf->whitelistCallback(function ($request) {
|
||||
// Skip token check for API URLs.
|
||||
//if ($request->getParam('prefix') === 'api') {
|
||||
if($request->getAttribute('base') === 'TransactionJsonRequestHandler') {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
*/
|
||||
// Ensure routing middleware is added to the queue before CSRF protection middleware.
|
||||
//$middlewareQueue->;
|
||||
|
||||
$middlewareQueue
|
||||
// ->add($csrf)
|
||||
// Catch any exceptions in the lower layers,
|
||||
// and make an error page/response
|
||||
->add(new ErrorHandlerMiddleware(null, Configure::read('Error')))
|
||||
|
||||
// Handle plugin/theme assets like CakePHP normally does.
|
||||
->add(new AssetMiddleware([
|
||||
'cacheTime' => Configure::read('Asset.cacheTime')
|
||||
]))
|
||||
|
||||
// Add routing middleware.
|
||||
// If you have a large number of routes connected, turning on routes
|
||||
// caching in production could improve performance. For that when
|
||||
// creating the middleware instance specify the cache config name by
|
||||
// using it's second constructor argument:
|
||||
// `new RoutingMiddleware($this, '_cake_routes_')`
|
||||
->add(new RoutingMiddleware($this));
|
||||
|
||||
return $middlewareQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function bootstrapCli()
|
||||
{
|
||||
try {
|
||||
$this->addPlugin('Bake');
|
||||
} catch (MissingPluginException $e) {
|
||||
// Do not halt if the plugin is missing
|
||||
}
|
||||
|
||||
// Load more plugins here
|
||||
}
|
||||
}
|
||||
@ -1,246 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 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 3.0.0
|
||||
* @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace App\Console;
|
||||
|
||||
if (!defined('STDIN')) {
|
||||
define('STDIN', fopen('php://stdin', 'r'));
|
||||
}
|
||||
|
||||
use Cake\Utility\Security;
|
||||
use Composer\Script\Event;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Provides installation hooks for when this application is installed via
|
||||
* composer. Customize this class to suit your needs.
|
||||
*/
|
||||
class Installer
|
||||
{
|
||||
|
||||
/**
|
||||
* An array of directories to be made writable
|
||||
*/
|
||||
const WRITABLE_DIRS = [
|
||||
'logs',
|
||||
'tmp',
|
||||
'tmp/cache',
|
||||
'tmp/cache/models',
|
||||
'tmp/cache/persistent',
|
||||
'tmp/cache/views',
|
||||
'tmp/sessions',
|
||||
'tmp/tests'
|
||||
];
|
||||
|
||||
/**
|
||||
* Does some routine installation tasks so people don't have to.
|
||||
*
|
||||
* @param \Composer\Script\Event $event The composer event object.
|
||||
* @throws \Exception Exception raised by validator.
|
||||
* @return void
|
||||
*/
|
||||
public static function postInstall(Event $event)
|
||||
{
|
||||
$io = $event->getIO();
|
||||
|
||||
$rootDir = dirname(dirname(__DIR__));
|
||||
|
||||
static::createAppConfig($rootDir, $io);
|
||||
static::createWritableDirectories($rootDir, $io);
|
||||
|
||||
// ask if the permissions should be changed
|
||||
if ($io->isInteractive()) {
|
||||
$validator = function ($arg) {
|
||||
if (in_array($arg, ['Y', 'y', 'N', 'n'])) {
|
||||
return $arg;
|
||||
}
|
||||
throw new Exception('This is not a valid answer. Please choose Y or n.');
|
||||
};
|
||||
$setFolderPermissions = $io->askAndValidate(
|
||||
'<info>Set Folder Permissions ? (Default to Y)</info> [<comment>Y,n</comment>]? ',
|
||||
$validator,
|
||||
10,
|
||||
'Y'
|
||||
);
|
||||
|
||||
if (in_array($setFolderPermissions, ['Y', 'y'])) {
|
||||
static::setFolderPermissions($rootDir, $io);
|
||||
}
|
||||
} else {
|
||||
static::setFolderPermissions($rootDir, $io);
|
||||
}
|
||||
|
||||
static::setSecuritySalt($rootDir, $io);
|
||||
|
||||
$class = 'Cake\Codeception\Console\Installer';
|
||||
if (class_exists($class)) {
|
||||
$class::customizeCodeceptionBinary($event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the config/app.php file if it does not exist.
|
||||
*
|
||||
* @param string $dir The application's root directory.
|
||||
* @param \Composer\IO\IOInterface $io IO interface to write to console.
|
||||
* @return void
|
||||
*/
|
||||
public static function createAppConfig($dir, $io)
|
||||
{
|
||||
$appConfig = $dir . '/config/app.php';
|
||||
$defaultConfig = $dir . '/config/app.default.php';
|
||||
if (!file_exists($appConfig)) {
|
||||
copy($defaultConfig, $appConfig);
|
||||
$io->write('Created `config/app.php` file');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `logs` and `tmp` directories.
|
||||
*
|
||||
* @param string $dir The application's root directory.
|
||||
* @param \Composer\IO\IOInterface $io IO interface to write to console.
|
||||
* @return void
|
||||
*/
|
||||
public static function createWritableDirectories($dir, $io)
|
||||
{
|
||||
foreach (static::WRITABLE_DIRS as $path) {
|
||||
$path = $dir . '/' . $path;
|
||||
if (!file_exists($path)) {
|
||||
mkdir($path);
|
||||
$io->write('Created `' . $path . '` directory');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set globally writable permissions on the "tmp" and "logs" directory.
|
||||
*
|
||||
* This is not the most secure default, but it gets people up and running quickly.
|
||||
*
|
||||
* @param string $dir The application's root directory.
|
||||
* @param \Composer\IO\IOInterface $io IO interface to write to console.
|
||||
* @return void
|
||||
*/
|
||||
public static function setFolderPermissions($dir, $io)
|
||||
{
|
||||
// Change the permissions on a path and output the results.
|
||||
$changePerms = function ($path) use ($io) {
|
||||
$currentPerms = fileperms($path) & 0777;
|
||||
$worldWritable = $currentPerms | 0007;
|
||||
if ($worldWritable == $currentPerms) {
|
||||
return;
|
||||
}
|
||||
|
||||
$res = chmod($path, $worldWritable);
|
||||
if ($res) {
|
||||
$io->write('Permissions set on ' . $path);
|
||||
} else {
|
||||
$io->write('Failed to set permissions on ' . $path);
|
||||
}
|
||||
};
|
||||
|
||||
$walker = function ($dir) use (&$walker, $changePerms) {
|
||||
$files = array_diff(scandir($dir), ['.', '..']);
|
||||
foreach ($files as $file) {
|
||||
$path = $dir . '/' . $file;
|
||||
|
||||
if (!is_dir($path)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$changePerms($path);
|
||||
$walker($path);
|
||||
}
|
||||
};
|
||||
|
||||
$walker($dir . '/tmp');
|
||||
$changePerms($dir . '/tmp');
|
||||
$changePerms($dir . '/logs');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the security.salt value in the application's config file.
|
||||
*
|
||||
* @param string $dir The application's root directory.
|
||||
* @param \Composer\IO\IOInterface $io IO interface to write to console.
|
||||
* @return void
|
||||
*/
|
||||
public static function setSecuritySalt($dir, $io)
|
||||
{
|
||||
$newKey = hash('sha256', Security::randomBytes(64));
|
||||
static::setSecuritySaltInFile($dir, $io, $newKey, 'app.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the security.salt value in a given file
|
||||
*
|
||||
* @param string $dir The application's root directory.
|
||||
* @param \Composer\IO\IOInterface $io IO interface to write to console.
|
||||
* @param string $newKey key to set in the file
|
||||
* @param string $file A path to a file relative to the application's root
|
||||
* @return void
|
||||
*/
|
||||
public static function setSecuritySaltInFile($dir, $io, $newKey, $file)
|
||||
{
|
||||
$config = $dir . '/config/' . $file;
|
||||
$content = file_get_contents($config);
|
||||
|
||||
$content = str_replace('__SALT__', $newKey, $content, $count);
|
||||
|
||||
if ($count == 0) {
|
||||
$io->write('No Security.salt placeholder to replace.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$result = file_put_contents($config, $content);
|
||||
if ($result) {
|
||||
$io->write('Updated Security.salt value in config/' . $file);
|
||||
|
||||
return;
|
||||
}
|
||||
$io->write('Unable to update Security.salt value.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the APP_NAME value in a given file
|
||||
*
|
||||
* @param string $dir The application's root directory.
|
||||
* @param \Composer\IO\IOInterface $io IO interface to write to console.
|
||||
* @param string $appName app name to set in the file
|
||||
* @param string $file A path to a file relative to the application's root
|
||||
* @return void
|
||||
*/
|
||||
public static function setAppNameInFile($dir, $io, $appName, $file)
|
||||
{
|
||||
$config = $dir . '/config/' . $file;
|
||||
$content = file_get_contents($config);
|
||||
$content = str_replace('__APP_NAME__', $appName, $content, $count);
|
||||
|
||||
if ($count == 0) {
|
||||
$io->write('No __APP_NAME__ placeholder to replace.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$result = file_put_contents($config, $content);
|
||||
if ($result) {
|
||||
$io->write('Updated __APP_NAME__ value in config/' . $file);
|
||||
|
||||
return;
|
||||
}
|
||||
$io->write('Unable to update __APP_NAME__ value.');
|
||||
}
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* AddressTypes Controller
|
||||
*
|
||||
* @property \App\Model\Table\AddressTypesTable $AddressTypes
|
||||
*
|
||||
* @method \App\Model\Entity\AddressType[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class AddressTypesController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$addressTypes = $this->paginate($this->AddressTypes);
|
||||
|
||||
$this->set(compact('addressTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Address Type id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$addressType = $this->AddressTypes->get($id, [
|
||||
'contain' => ['StateGroupAddresses', 'TransactionGroupAddaddress'],
|
||||
]);
|
||||
|
||||
$this->set('addressType', $addressType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$addressType = $this->AddressTypes->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$addressType = $this->AddressTypes->patchEntity($addressType, $this->request->getData());
|
||||
if ($this->AddressTypes->save($addressType)) {
|
||||
$this->Flash->success(__('The address type has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The address type could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('addressType'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Address Type 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)
|
||||
{
|
||||
$addressType = $this->AddressTypes->get($id, [
|
||||
'contain' => [],
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$addressType = $this->AddressTypes->patchEntity($addressType, $this->request->getData());
|
||||
if ($this->AddressTypes->save($addressType)) {
|
||||
$this->Flash->success(__('The address type has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The address type could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('addressType'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Address Type 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']);
|
||||
$addressType = $this->AddressTypes->get($id);
|
||||
if ($this->AddressTypes->delete($addressType)) {
|
||||
$this->Flash->success(__('The address type has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The address type could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,111 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* AdminErrors Controller
|
||||
*
|
||||
* @property \App\Model\Table\AdminErrorsTable $AdminErrors
|
||||
*
|
||||
* @method \App\Model\Entity\AdminError[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class AdminErrorsController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['StateUsers']
|
||||
];
|
||||
$adminErrors = $this->paginate($this->AdminErrors);
|
||||
|
||||
$this->set(compact('adminErrors'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Admin Error id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$adminError = $this->AdminErrors->get($id, [
|
||||
'contain' => ['StateUsers']
|
||||
]);
|
||||
|
||||
$this->set('adminError', $adminError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$adminError = $this->AdminErrors->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$adminError = $this->AdminErrors->patchEntity($adminError, $this->request->getData());
|
||||
if ($this->AdminErrors->save($adminError)) {
|
||||
$this->Flash->success(__('The admin error has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The admin error could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateUsers = $this->AdminErrors->StateUsers->find('list', ['limit' => 200]);
|
||||
$this->set(compact('adminError', 'stateUsers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Admin 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)
|
||||
{
|
||||
$adminError = $this->AdminErrors->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$adminError = $this->AdminErrors->patchEntity($adminError, $this->request->getData());
|
||||
if ($this->AdminErrors->save($adminError)) {
|
||||
$this->Flash->success(__('The admin error has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The admin error could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateUsers = $this->AdminErrors->StateUsers->find('list', ['limit' => 200]);
|
||||
$this->set(compact('adminError', 'stateUsers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Admin 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']);
|
||||
$adminError = $this->AdminErrors->get($id);
|
||||
if ($this->AdminErrors->delete($adminError)) {
|
||||
$this->Flash->success(__('The admin error has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The admin error could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,386 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 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.2.9
|
||||
* @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace App\Controller;
|
||||
|
||||
use Cake\Controller\Controller;
|
||||
//use Cake\Event\Event;
|
||||
use Cake\Http\Client;
|
||||
use Cake\Routing\Router;
|
||||
use Cake\ORM\TableRegistry;
|
||||
use Cake\Core\Configure;
|
||||
use Cake\I18n\Time;
|
||||
use Cake\I18n\FrozenTime;
|
||||
|
||||
/**
|
||||
* Application Controller
|
||||
*
|
||||
* Add your application-wide methods in the class below, your controllers
|
||||
* will inherit them.
|
||||
*
|
||||
* @link https://book.cakephp.org/3.0/en/controllers.html#the-app-controller
|
||||
*/
|
||||
class AppController extends Controller
|
||||
{
|
||||
|
||||
var $loginServerUrl = '';
|
||||
var $blockchainType = 'mysql';
|
||||
/**
|
||||
* Initialization hook method.
|
||||
*
|
||||
* Use this method to add common initialization code like loading components.
|
||||
*
|
||||
* e.g. `$this->loadComponent('Security');`
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$this->loadComponent('RequestHandler', [
|
||||
'enableBeforeRedirect' => false,
|
||||
]);
|
||||
$this->loadComponent('Flash');
|
||||
|
||||
$this->loadComponent('Auth', [
|
||||
'loginAction' => [
|
||||
'controller' => 'ServerUsers',
|
||||
'action' => 'login'
|
||||
],
|
||||
'loginRedirect' => [
|
||||
'controller' => 'Transactions',
|
||||
'action' => 'index'
|
||||
],
|
||||
'logoutRedirect' => [
|
||||
'controller' => 'Pages',
|
||||
'action' => 'display',
|
||||
'gradido'
|
||||
],
|
||||
'authenticate' => [
|
||||
'all' => ['userModel' => 'ServerUsers'],
|
||||
'Form' => [
|
||||
'userModel' => 'ServerUsers',
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->Auth->deny(['index']);
|
||||
|
||||
/*
|
||||
* Enable the following component for recommended CakePHP security settings.
|
||||
* 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');
|
||||
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
// server login
|
||||
if ($this->Auth->user('id')) {
|
||||
$GLOBALS['ServerUser'] = $this->Auth->user();
|
||||
}
|
||||
|
||||
// login server url
|
||||
$loginServer = Configure::read('LoginServer');
|
||||
if ($loginServer && isset($loginServer['url'])) {
|
||||
$this->loginServerUrl = $loginServer['url'] . '/';
|
||||
} else {
|
||||
$this->loginServerUrl = Router::url('/', true);
|
||||
}
|
||||
/*
|
||||
*
|
||||
* 'GradidoBlockchain' => [
|
||||
* // type:
|
||||
* // - mysql: centralized blockchain in mysql db, no cross group transactions
|
||||
* // - hedera: send transaction over hedera
|
||||
* 'type' => 'hedera',
|
||||
* // gradido nodes with blockchain (if type != mysql)
|
||||
* 'nodes' => [
|
||||
* ['host' => 'http://192.168.178.225', 'port' => 13702]
|
||||
* ]
|
||||
* ],
|
||||
*/
|
||||
$blockchain = Configure::read('GradidoBlockchain');
|
||||
if($blockchain && isset($blockchain['type'])) {
|
||||
$this->blockchainType = $blockchain['type'];
|
||||
}
|
||||
}
|
||||
|
||||
protected function requestLogin($sessionId = 0, $redirect = true)
|
||||
{
|
||||
$stateBalancesTable = TableRegistry::getTableLocator()->get('StateBalances');
|
||||
$session = $this->getRequest()->getSession();
|
||||
// check login
|
||||
// disable encryption for cookies
|
||||
$session_id = 0;
|
||||
$php_session_id = 0;
|
||||
if($session->check('session_id')) {
|
||||
$php_session_id = intval($session->read('session_id'));
|
||||
}
|
||||
$cookie_session_id = intval($this->request->getCookie('GRADIDO_LOGIN', ''));
|
||||
// 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;
|
||||
}
|
||||
|
||||
$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
|
||||
$loginServer = Configure::read('LoginServer');
|
||||
|
||||
if ($session_id != 0) {
|
||||
$userStored = $session->read('StateUser');
|
||||
|
||||
$transactionPendings = $session->read('Transactions.pending');
|
||||
$transactionExecutings = $session->read('Transactions.executing');
|
||||
$transaction_can_signed = $session->read('Transactions.can_signed');
|
||||
|
||||
|
||||
|
||||
if ($session->read('session_id') != $session_id ||
|
||||
( $userStored && (!isset($userStored['id']) || !$userStored['email_checked'])) ||
|
||||
intval($transactionPendings) > 0 ||
|
||||
intval($transactionExecutings) > 0 ||
|
||||
intval($transaction_can_signed > 0))
|
||||
{
|
||||
$http = new Client();
|
||||
|
||||
try {
|
||||
$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') {
|
||||
//echo "email checked: " . $json['user']['email_checked'] . "; <br>";
|
||||
if ($session->read('session_id') != $session_id ||
|
||||
( $userStored && !isset($userStored['id']))) {
|
||||
$session->destroy();
|
||||
}
|
||||
foreach ($json['user'] as $key => $value) {
|
||||
// we don't need the id of user in login server db
|
||||
if($key == 'id') continue;
|
||||
$session->write('StateUser.' . $key, $value);
|
||||
}
|
||||
//var_dump($json);
|
||||
$transactionPendings = $json['Transactions.pending'];
|
||||
$transactionExecuting = $json['Transactions.executing'];
|
||||
$transaction_can_signed = $json['Transactions.can_signed'];
|
||||
//echo "read transaction pending: $transactionPendings<br>";
|
||||
$session->write('Transactions.pending', $transactionPendings);
|
||||
$session->write('Transactions.executing', $transactionExecuting);
|
||||
$session->write('Transactions.can_signed', $transaction_can_signed);
|
||||
$session->write('session_id', $session_id);
|
||||
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
|
||||
|
||||
if (isset($json['user']['public_hex']) && $json['user']['public_hex'] != '') {
|
||||
$public_key_bin = hex2bin($json['user']['public_hex']);
|
||||
$stateUserQuery = $stateUserTable
|
||||
->find('all')
|
||||
->where(['public_key' => $public_key_bin])
|
||||
->contain('StateBalances', function ($q) {
|
||||
return $q->order(['record_date' => 'DESC'])
|
||||
->limit(1);
|
||||
});
|
||||
if ($stateUserQuery->count() == 1) {
|
||||
$stateUser = $stateUserQuery->first();
|
||||
if ($stateUser->first_name != $json['user']['first_name'] ||
|
||||
$stateUser->last_name != $json['user']['last_name'] ||
|
||||
$stateUser->disabled != $json['user']['disabled'] ||
|
||||
//$stateUser->username != $json['user']['username'] ||
|
||||
// -> throws error
|
||||
$stateUser->email != $json['user']['email']
|
||||
) {
|
||||
$stateUser->first_name = $json['user']['first_name'];
|
||||
$stateUser->last_name = $json['user']['last_name'];
|
||||
$stateUser->disabled = intval($json['user']['disabled']);
|
||||
//$stateUser->username = $json['user']['username'];
|
||||
$stateUser->email = $json['user']['email'];
|
||||
if (!$stateUserTable->save($stateUser)) {
|
||||
$this->Flash->error(__('error updating state user ' . json_encode($stateUser->errors())));
|
||||
}
|
||||
}
|
||||
$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'];
|
||||
$newStateUser->disabled = intval($json['user']['disabled']);
|
||||
//$newStateUser->username = $json['user']['username'];
|
||||
$newStateUser->email = $json['user']['email'];
|
||||
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(!$redirect) {
|
||||
return ['state' => 'error', 'msg' => 'no pubkey'];
|
||||
}
|
||||
// we haven't get a pubkey? something seems to gone wrong on the login-server
|
||||
$this->Flash->error(__('no pubkey'));
|
||||
//var_dump($json);
|
||||
return $this->redirect($this->loginServerUrl . 'account/error500/noPubkey', 303);
|
||||
}
|
||||
} else {
|
||||
if(!$redirect) {
|
||||
return ['state' => 'not found', 'msg' => 'invalid session', 'details' => $json];
|
||||
}
|
||||
if ($json['state'] === 'not found') {
|
||||
$this->Flash->error(__('invalid session'));
|
||||
} else {
|
||||
$this->Flash->error(__('Konto ist nicht aktiviert!'));
|
||||
}
|
||||
//die(json_encode($json));
|
||||
if(preg_match('/client ip/', $json['msg'])) {
|
||||
return $this->redirect($this->loginServerUrl . 'account/error500/ipError', 303);
|
||||
}
|
||||
return $this->redirect($this->loginServerUrl . 'account/', 303);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$msg = $e->getMessage();
|
||||
if(!$redirect) {
|
||||
return ['state' => 'error', 'msg' => 'login-server http request error', 'details' => $msg];
|
||||
}
|
||||
$this->Flash->error(__('error http request: ') . $msg);
|
||||
return $this->redirect(['controller' => 'Dashboard', 'action' => 'errorHttpRequest']);
|
||||
//continue;
|
||||
}
|
||||
}
|
||||
$state_balance = $stateBalancesTable->find()->where(['state_user_id' => $session->read('StateUser.id')])->first();
|
||||
if ($state_balance) {
|
||||
$now = new FrozenTime;
|
||||
$session->write('StateUser.balance', $stateBalancesTable->calculateDecay($state_balance->amount, $state_balance->record_date, $now));
|
||||
}
|
||||
} else {
|
||||
// no login
|
||||
//die("no login");
|
||||
if(!$redirect) {
|
||||
return ['state' => 'error', 'msg' => 'not logged in'];
|
||||
}
|
||||
if (isset($loginServer['path'])) {
|
||||
return $this->redirect($loginServer['path'], 303);
|
||||
} else {
|
||||
return $this->redirect($this->loginServerUrl . 'account/', 303);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
public function beforeFilter(Event $event)
|
||||
{
|
||||
//$this->Auth->allow(['display']);
|
||||
}
|
||||
*/
|
||||
|
||||
public function addAdminError($controller, $action, array $returnTable, $state_user_id)
|
||||
{
|
||||
if (!is_array($returnTable)) {
|
||||
$this->addAdminError('AppController', 'addAdminError', ['state' => 'error', 'msg' => 'returnTable isn\'t array', 'details' => gettype($returnTable)], $state_user_id);
|
||||
return false;
|
||||
}
|
||||
$adminErrorTable = TableRegistry::getTableLocator()->get('AdminErrors');
|
||||
$adminErrorEntity = $adminErrorTable->newEntity();
|
||||
$adminErrorEntity->state_user_id = $state_user_id;
|
||||
$adminErrorEntity->controller = $controller;
|
||||
$adminErrorEntity->action = $action;
|
||||
$adminErrorEntity->state = $returnTable['state'];
|
||||
if (isset($returnTable['msg'])) {
|
||||
$adminErrorEntity->msg = $returnTable['msg'];
|
||||
} else {
|
||||
$adminErrorEntity->msg = __('(Leere Message)');
|
||||
}
|
||||
if (isset($returnTable['details'])) {
|
||||
$adminErrorEntity->details = $returnTable['details'];
|
||||
} else {
|
||||
$adminErrorEntity->details = __('(Leere Details)');
|
||||
}
|
||||
if (!$adminErrorTable->save($adminErrorEntity)) {
|
||||
$this->Flash->error(
|
||||
__('Serious error, couldn\'t save to db, please write the admin: ' . $this->getAdminEmailLink()),
|
||||
['escape' => false]
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getAdminEmailLink($text = '')
|
||||
{
|
||||
$serverAdminEmail = Configure::read('ServerAdminEmail');
|
||||
return '<a href="mailto:' . $serverAdminEmail . '">'. $serverAdminEmail . '</a>';
|
||||
}
|
||||
|
||||
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');
|
||||
return $response->withStringBody(json_encode($array));
|
||||
}
|
||||
|
||||
public function getStartEndForMonth($month, $year)
|
||||
{
|
||||
$timeString = $year . '-' . $month . '-01 00:00';
|
||||
$firstDay = new Time($timeString);
|
||||
$lastDay = new Time($timeString);
|
||||
$lastDay = $lastDay->addMonth(1);
|
||||
return [$firstDay, $lastDay];
|
||||
}
|
||||
}
|
||||
@ -1,465 +0,0 @@
|
||||
<?php
|
||||
/*!
|
||||
* @author: Dario Rekowski
|
||||
* @date : 2020-12-01
|
||||
* @brief: Controller for all ajax-json requests caming from mobile app
|
||||
*
|
||||
* Everything is allowed to call them, so caution!
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
use Cake\ORM\TableRegistry;
|
||||
use Cake\Http\Client;
|
||||
use Cake\Core\Configure;
|
||||
|
||||
use Cake\I18n\FrozenTime;
|
||||
|
||||
class AppRequestsController extends AppController
|
||||
{
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->loadComponent('JsonRequestClient');
|
||||
$this->loadComponent('GradidoNumber');
|
||||
//$this->loadComponent('JsonRpcRequestClient');
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->allow([
|
||||
'index', 'sendCoins', 'createCoins', 'getBalance',
|
||||
'listTransactions','listGDTTransactions', 'getDecayStartBlock'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function index()
|
||||
{
|
||||
if($this->request->is('get')) {
|
||||
$method = $this->request->getQuery('method');
|
||||
switch($method) {
|
||||
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'unknown method for get', 'details' => $method]);
|
||||
}
|
||||
else if($this->request->is('post')) {
|
||||
$jsonData = $this->request->input('json_decode');
|
||||
//var_dump($jsonData);
|
||||
if($jsonData == NULL || !isset($jsonData->method)) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'parameter error']);
|
||||
}
|
||||
$method = $jsonData->method;
|
||||
|
||||
switch($method) {
|
||||
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'unknown method for post', 'details' => $method]);
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post or get']);
|
||||
}
|
||||
|
||||
private function checkAndCopyRequiredFields($fields, &$param, $data = null) {
|
||||
if($data == null) {
|
||||
$data = $this->request->input('json_decode');
|
||||
}
|
||||
foreach($fields as $field) {
|
||||
if(is_array($field)) {
|
||||
$one_exist = false;
|
||||
foreach($field as $oneField) {
|
||||
if(isset($data->$oneField)) {
|
||||
$param[$oneField] = $data->$oneField;
|
||||
$one_exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!$one_exist) {
|
||||
return ['state' => 'error', 'msg' => 'missing field of set', 'details' => $field];
|
||||
}
|
||||
} else {
|
||||
if(!isset($data->$field)) {
|
||||
return ['state' => 'error', 'msg' => 'missing field', 'details' => $field . ' not found'];
|
||||
} else {
|
||||
$param[$field] = $data->$field;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function rewriteKeys(&$data, $replaceKeys)
|
||||
{
|
||||
foreach(array_keys($replaceKeys) as $key) {
|
||||
$newKey = $replaceKeys[$key];
|
||||
if(isset($data->$key)) {
|
||||
$data->$newKey = $data->$key;
|
||||
unset($data->$key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function parseParameterForCreateTransaction(&$param, $data = null)
|
||||
{
|
||||
if($data == null) {
|
||||
$data = $this->request->input('json_decode');
|
||||
}
|
||||
$session_id = 0;
|
||||
if(isset($data->session_id)) {
|
||||
$session_id = $data->session_id;
|
||||
}
|
||||
$login_request_result = $this->requestLogin($session_id, false);
|
||||
if($login_request_result !== true) {
|
||||
return $login_request_result;
|
||||
}
|
||||
$session = $this->getRequest()->getSession();
|
||||
$param['session_id'] = $session->read('session_id');
|
||||
$param['blockchain_type'] = $this->blockchainType;
|
||||
|
||||
$this->rewriteKeys($data, ['email' => 'target_email', 'username' => 'target_username', 'pubkey' => 'target_pubkey']);
|
||||
$required_fields = $this->checkAndCopyRequiredFields(['amount', ['target_email', 'target_username', 'target_pubkey']], $param, $data);
|
||||
if($required_fields !== true) {
|
||||
return $required_fields;
|
||||
}
|
||||
|
||||
if(floatval($param['amount']) <= 0.0) {
|
||||
return ['state' => 'error', 'msg' => 'amount is invalid', 'details' => $param['amount']];
|
||||
}
|
||||
$param['amount'] = $this->GradidoNumber->parseInputNumberToCentNumber($param['amount']);
|
||||
|
||||
if(isset($data->memo)) {
|
||||
$param['memo'] = $data->memo;
|
||||
}
|
||||
|
||||
if(isset($data->auto_sign)) {
|
||||
$param['auto_sign'] = boolval($data->auto_sign);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function sendCoins()
|
||||
{
|
||||
/*
|
||||
* {
|
||||
"session_id" : -127182,
|
||||
"amount": 2000000,
|
||||
"email": "max.musterman@gmail.de",
|
||||
"memo":"Thank you :)",
|
||||
"group": "gdd1",
|
||||
"auto_sign": true
|
||||
*/
|
||||
if(!$this->request->is('post')) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post']);
|
||||
}
|
||||
$data = $this->request->input('json_decode');
|
||||
$params = [];
|
||||
$result = $this->parseParameterForCreateTransaction($params, $data);
|
||||
if($result !== true) {
|
||||
return $this->returnJson($result);
|
||||
}
|
||||
|
||||
if(!isset($params['memo']) || strlen($params['memo']) < 5 || strlen($params['memo']) > 150) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'memo is not set or not in expected range [5;150]']);
|
||||
}
|
||||
$params['transaction_type'] = 'transfer';
|
||||
|
||||
$requestAnswear = $this->JsonRequestClient->sendRequest(json_encode($params), '/createTransaction');
|
||||
|
||||
|
||||
if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) {
|
||||
$session = $this->getRequest()->getSession();
|
||||
$pendingTransactionCount = $session->read('Transactions.pending');
|
||||
if($pendingTransactionCount == null) {
|
||||
$pendingTransactionCount = 1;
|
||||
} else {
|
||||
$pendingTransactionCount++;
|
||||
}
|
||||
$session->write('Transactions.pending', $pendingTransactionCount);
|
||||
//echo "pending: " . $pendingTransactionCount;
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
} else {
|
||||
|
||||
/*
|
||||
* if request contain unknown parameter format, shouldn't happen't at all
|
||||
* {"state": "error", "msg": "parameter format unknown"}
|
||||
* if json parsing failed
|
||||
* {"state": "error", "msg": "json exception", "details":"exception text"}
|
||||
* if session_id is zero or not set
|
||||
* {"state": "error", "msg": "session_id invalid"}
|
||||
* if session id wasn't found on login server, if server was restartet or user logged out (also per timeout, default: 15 minutes)
|
||||
* {"state": "error", "msg": "session not found"}
|
||||
* if session hasn't active user, shouldn't happen't at all, login-server should be checked if happen
|
||||
* {"state": "code error", "msg":"user is zero"}
|
||||
* if transaction type not known
|
||||
* {"state": "error", "msg":"transaction_type unknown"}
|
||||
* if receiver wasn't known to Login-Server
|
||||
* {"state": "not found", "msg":"receiver not found"}
|
||||
* if receiver account disabled, and therefor cannto receive any coins
|
||||
* {"state": "disabled", "msg":"receiver is disabled"}
|
||||
* if transaction was okay and will be further proccessed
|
||||
* {"state":"success"}
|
||||
*/
|
||||
$answear_data = $requestAnswear['data'];
|
||||
return $this->returnJson($answear_data);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function createCoins()
|
||||
{
|
||||
/*
|
||||
* "session_id" : -127182,
|
||||
* "email": "max.musterman@gmail.de",
|
||||
* "amount": 10000000,
|
||||
* "target_date":"2021-02-19T13:25:36+00:00",
|
||||
* "memo":"AGE",
|
||||
* "auto_sign": true
|
||||
*/
|
||||
if(!$this->request->is('post')) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post']);
|
||||
}
|
||||
$data = $this->request->input('json_decode');
|
||||
$params = [];
|
||||
$result = $this->parseParameterForCreateTransaction($params, $data);
|
||||
if($result !== true) {
|
||||
return $this->returnJson($result);
|
||||
}
|
||||
$required_fields = $this->checkAndCopyRequiredFields(['target_date'], $params, $data);
|
||||
if($required_fields !== true) {
|
||||
return $this->returnJson($required_fields);
|
||||
}
|
||||
$params['transaction_type'] = 'creation';
|
||||
|
||||
$requestAnswear = $this->JsonRequestClient->sendRequest(json_encode($params), '/createTransaction');
|
||||
|
||||
if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) {
|
||||
$session = $this->getRequest()->getSession();
|
||||
$pendingTransactionCount = $session->read('Transactions.pending');
|
||||
if($pendingTransactionCount == null) {
|
||||
$pendingTransactionCount = 1;
|
||||
} else {
|
||||
$pendingTransactionCount++;
|
||||
}
|
||||
$session->write('Transactions.pending', $pendingTransactionCount);
|
||||
//echo "pending: " . $pendingTransactionCount;
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
} else {
|
||||
|
||||
/*
|
||||
* if request contain unknown parameter format, shouldn't happen't at all
|
||||
* {"state": "error", "msg": "parameter format unknown"}
|
||||
* if json parsing failed
|
||||
* {"state": "error", "msg": "json exception", "details":"exception text"}
|
||||
* if session_id is zero or not set
|
||||
* {"state": "error", "msg": "session_id invalid"}
|
||||
* if session id wasn't found on login server, if server was restartet or user logged out (also per timeout, default: 15 minutes)
|
||||
* {"state": "error", "msg": "session not found"}
|
||||
* if session hasn't active user, shouldn't happen't at all, login-server should be checked if happen
|
||||
* {"state": "code error", "msg":"user is zero"}
|
||||
* if transaction type not known
|
||||
* {"state": "error", "msg":"transaction_type unknown"}
|
||||
* if receiver wasn't known to Login-Server
|
||||
* {"state": "not found", "msg":"receiver not found"}
|
||||
* if receiver account disabled, and therefor cannto receive any coins
|
||||
* {"state": "disabled", "msg":"receiver is disabled"}
|
||||
* if transaction was okay and will be further proccessed
|
||||
* {"state":"success"}
|
||||
*/
|
||||
$answear_data = $requestAnswear['data'];
|
||||
return $this->returnJson($answear_data);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getBalance($session_id = 0)
|
||||
{
|
||||
$this->viewBuilder()->setLayout('ajax');
|
||||
$login_result = $this->requestLogin($session_id, false);
|
||||
if($login_result !== true) {
|
||||
$this->set('body', $login_result);
|
||||
return;
|
||||
}
|
||||
$session = $this->getRequest()->getSession();
|
||||
$user = $session->read('StateUser');
|
||||
$state_balances_table = TableRegistry::getTableLocator()->get('StateBalances');
|
||||
$state_balances_table->updateBalances($user['id']);
|
||||
|
||||
$state_balance = $state_balances_table->find()->where(['state_user_id' => $user['id']])->first();
|
||||
|
||||
|
||||
$now = new FrozenTime();
|
||||
if(!$state_balance) {
|
||||
$body = [
|
||||
'state' => 'success',
|
||||
'balance' => 0,
|
||||
'decay' => 0
|
||||
];
|
||||
} else {
|
||||
|
||||
$body = [
|
||||
'state' => 'success',
|
||||
'balance' => $state_balance->amount,
|
||||
'decay' => $state_balance->partDecay($now),
|
||||
];
|
||||
}
|
||||
|
||||
$body['decay_date'] = $now;
|
||||
$this->set('body', $body);
|
||||
}
|
||||
|
||||
public function listTransactions($page = 1, $count = 25, $orderDirection = 'ASC', $session_id = 0)
|
||||
{
|
||||
$this->viewBuilder()->setLayout('ajax');
|
||||
$startTime = microtime(true);
|
||||
|
||||
$login_result = $this->requestLogin($session_id, false);
|
||||
|
||||
if($login_result !== true) {
|
||||
return $this->returnJson($login_result);
|
||||
}
|
||||
$session = $this->getRequest()->getSession();
|
||||
$user = $session->read('StateUser');
|
||||
|
||||
$stateBalancesTable = TableRegistry::getTableLocator()->get('StateBalances');
|
||||
$stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions');
|
||||
$transactionsTable = TableRegistry::getTableLocator()->get('Transactions');
|
||||
|
||||
$stateBalancesTable->updateBalances($user['id']);
|
||||
|
||||
$gdtSum = 0;
|
||||
|
||||
$gdtEntries = $this->JsonRequestClient->sendRequestGDT(['email' => $user['email']], 'GdtEntries' . DS . 'sumPerEmailApi');
|
||||
|
||||
if('success' == $gdtEntries['state'] && 'success' == $gdtEntries['data']['state']) {
|
||||
$gdtSum = intval($gdtEntries['data']['sum']);
|
||||
} else {
|
||||
$this->addAdminError('StateBalancesController', 'overview', $gdtEntries, $user['id'] ? $user['id'] : 0);
|
||||
}
|
||||
|
||||
//echo "count: $count, page: $page<br>";
|
||||
$limit = $count;
|
||||
$offset = 0;
|
||||
$skip_first_transaction = false;
|
||||
if($page > 1) {
|
||||
$offset = (( $page - 1 ) * $count) - 1;
|
||||
$limit++;
|
||||
}
|
||||
|
||||
if($offset && $orderDirection == 'ASC') {
|
||||
$offset--;
|
||||
}
|
||||
|
||||
//echo "limit: $limit, offset: $offset, skip first transaction: $skip_first_transaction<br>";
|
||||
$stateUserTransactionsQuery = $stateUserTransactionsTable
|
||||
->find()
|
||||
->where(['state_user_id' => $user['id']])
|
||||
->order(['balance_date' => $orderDirection])
|
||||
->contain([])
|
||||
->limit($limit)
|
||||
//->page($page)
|
||||
->offset($offset)
|
||||
;
|
||||
$state_user_transactions_count = $stateUserTransactionsQuery->count();
|
||||
if($state_user_transactions_count > $offset + $limit) {
|
||||
$skip_first_transaction = true;
|
||||
}
|
||||
|
||||
$decay = true;
|
||||
if($page > 1) {
|
||||
$decay = false;
|
||||
}
|
||||
$transactions = [];
|
||||
$transactions_from_db = $stateUserTransactionsQuery->toArray();
|
||||
|
||||
if(count($transactions_from_db)) {
|
||||
if($orderDirection == 'DESC') {
|
||||
$transactions_from_db = array_reverse($transactions_from_db);
|
||||
}
|
||||
|
||||
$transactions = $transactionsTable->listTransactionsHumanReadable($transactions_from_db, $user, $decay, $skip_first_transaction);
|
||||
//echo "transactions count: " . count($transactions) . "<br>";
|
||||
if($orderDirection == 'DESC') {
|
||||
$transactions = array_reverse($transactions);
|
||||
}
|
||||
}
|
||||
|
||||
$state_balance = $stateBalancesTable->find()->where(['state_user_id' => $user['id']])->first();
|
||||
|
||||
$body = [
|
||||
'state' => 'success',
|
||||
'transactions' => $transactions,
|
||||
'transactionExecutingCount' => $session->read('Transactions.executing'),
|
||||
'count' => $state_user_transactions_count,
|
||||
'gdtSum' => $gdtSum,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
];
|
||||
$now = new FrozenTime();
|
||||
$body['decay_date'] = $now;
|
||||
|
||||
if(!$state_balance) {
|
||||
$body['balance'] = 0.0;
|
||||
$body['decay'] = 0.0;
|
||||
} else {
|
||||
$body['balance'] = $state_balance->amount;
|
||||
$body['decay'] = $stateBalancesTable->calculateDecay($state_balance->amount, $state_balance->record_date, $now);
|
||||
}
|
||||
|
||||
$this->set('body', $body);
|
||||
}
|
||||
|
||||
public function listGDTTransactions($page = 1, $count = 25, $orderDirection = 'ASC', $session_id = 0)
|
||||
{
|
||||
$timeBegin = microtime(true);
|
||||
$this->viewBuilder()->setLayout('ajax');
|
||||
|
||||
$login_result = $this->requestLogin($session_id, false);
|
||||
|
||||
if($login_result !== true) {
|
||||
return $this->returnJson($login_result);
|
||||
}
|
||||
$session = $this->getRequest()->getSession();
|
||||
$user = $session->read('StateUser');
|
||||
|
||||
if(!$user) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'exist a valid session cookie?']);
|
||||
}
|
||||
|
||||
$gdtEntries = $this->JsonRequestClient->sendRequestGDT([
|
||||
'email' => $user['email'],
|
||||
'page' => $page,
|
||||
'count' => $count,
|
||||
'orderDirection' => $orderDirection
|
||||
], 'GdtEntries' . DS . 'listPerEmailApi');
|
||||
|
||||
if('success' == $gdtEntries['state']) {
|
||||
$timeEnd = microtime(true);
|
||||
$gdtEntries['data']['timeUsed'] = $timeEnd - $timeBegin;
|
||||
return $this->returnJson($gdtEntries['data']);
|
||||
|
||||
} else {
|
||||
if($user) {
|
||||
$this->addAdminError('StateBalancesController', 'ajaxGdtOverview', $gdtEntries, $user['id']);
|
||||
} else {
|
||||
$this->addAdminError('StateBalancesController', 'ajaxGdtOverview', $gdtEntries, 0);
|
||||
}
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'error by requesting gdt server', 'details' => $gdtEntries]);
|
||||
}
|
||||
|
||||
public function getDecayStartBlock()
|
||||
{
|
||||
$transactionsTable = TableRegistry::getTableLocator()->get('Transactions');
|
||||
$decayStartBlock = $transactionsTable->find()->where(['transaction_type_id' => 9]);
|
||||
if(!$decayStartBlock->count()) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'not found']);
|
||||
}
|
||||
return $this->returnJson(['state' => 'success', 'decay_start' => $decayStartBlock->first()->received]);
|
||||
}
|
||||
|
||||
private function acquireAccessToken($session_id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,106 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* BlockchainTypes Controller
|
||||
*
|
||||
* @property \App\Model\Table\BlockchainTypesTable $BlockchainTypes
|
||||
*
|
||||
* @method \App\Model\Entity\BlockchainType[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class BlockchainTypesController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$blockchainTypes = $this->paginate($this->BlockchainTypes);
|
||||
|
||||
$this->set(compact('blockchainTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Blockchain Type id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$blockchainType = $this->BlockchainTypes->get($id, [
|
||||
'contain' => [],
|
||||
]);
|
||||
|
||||
$this->set('blockchainType', $blockchainType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$blockchainType = $this->BlockchainTypes->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$blockchainType = $this->BlockchainTypes->patchEntity($blockchainType, $this->request->getData());
|
||||
if ($this->BlockchainTypes->save($blockchainType)) {
|
||||
$this->Flash->success(__('The blockchain type has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The blockchain type could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('blockchainType'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Blockchain Type 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)
|
||||
{
|
||||
$blockchainType = $this->BlockchainTypes->get($id, [
|
||||
'contain' => [],
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$blockchainType = $this->BlockchainTypes->patchEntity($blockchainType, $this->request->getData());
|
||||
if ($this->BlockchainTypes->save($blockchainType)) {
|
||||
$this->Flash->success(__('The blockchain type has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The blockchain type could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('blockchainType'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Blockchain Type 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']);
|
||||
$blockchainType = $this->BlockchainTypes->get($id);
|
||||
if ($this->BlockchainTypes->delete($blockchainType)) {
|
||||
$this->Flash->success(__('The blockchain type has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The blockchain type could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* CommunityProfiles Controller
|
||||
*
|
||||
* @property \App\Model\Table\CommunityProfilesTable $CommunityProfiles
|
||||
*
|
||||
* @method \App\Model\Entity\CommunityProfile[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class CommunityProfilesController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$communityProfiles = $this->paginate($this->CommunityProfiles);
|
||||
|
||||
$this->set(compact('communityProfiles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Community Profile id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$communityProfile = $this->CommunityProfiles->get($id, [
|
||||
'contain' => [],
|
||||
]);
|
||||
|
||||
$this->set('communityProfile', $communityProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$communityProfile = $this->CommunityProfiles->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$communityProfile = $this->CommunityProfiles->patchEntity($communityProfile, $this->request->getData());
|
||||
if ($this->CommunityProfiles->save($communityProfile)) {
|
||||
$this->Flash->success(__('The community profile has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The community profile could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('communityProfile'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Community Profile 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)
|
||||
{
|
||||
$communityProfile = $this->CommunityProfiles->get($id, [
|
||||
'contain' => [],
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$communityProfile = $this->CommunityProfiles->patchEntity($communityProfile, $this->request->getData());
|
||||
if ($this->CommunityProfiles->save($communityProfile)) {
|
||||
$this->Flash->success(__('The community profile has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The community profile could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('communityProfile'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Community Profile 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']);
|
||||
$communityProfile = $this->CommunityProfiles->get($id);
|
||||
if ($this->CommunityProfiles->delete($communityProfile)) {
|
||||
$this->Flash->success(__('The community profile has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The community profile could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
<?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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,184 +0,0 @@
|
||||
<?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 App\Model\Validation\GenericValidation;
|
||||
|
||||
use Cake\Controller\Component;
|
||||
use Cake\Http\Client;
|
||||
use Cake\Core\Configure;
|
||||
|
||||
class JsonRequestClientComponent extends Component
|
||||
{
|
||||
public function sendTransaction($session_id, $base64Message, $user_balance = 0, $auto_sign = false, $blockchain_type = 'mysql') {
|
||||
if(!is_numeric($session_id)) {
|
||||
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'session_id isn\'t numeric'];
|
||||
}
|
||||
if(!is_numeric($user_balance) || intval($user_balance) < 0) {
|
||||
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'user_balance invalid'];
|
||||
}
|
||||
if(is_array($base64Message)) {
|
||||
foreach($base64Message as $singleMessage) {
|
||||
if(!$this->is_base64($singleMessage)) {
|
||||
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'at least one base64Message contain invalid base64 characters'];
|
||||
}
|
||||
}
|
||||
} else if(!$this->is_base64($base64Message)) {
|
||||
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'base64Message contain invalid base64 characters'];
|
||||
}
|
||||
|
||||
return $this->sendRequest(json_encode([
|
||||
'session_id' => $session_id,
|
||||
'transaction_base64' => $base64Message,
|
||||
'balance' => $user_balance,
|
||||
'auto_sign' => $auto_sign,
|
||||
'blockchain_type' => $this->blockchainType
|
||||
]), '/checkTransaction');
|
||||
|
||||
}
|
||||
|
||||
public function findePublicKeyForEmailHash($emailHash) {
|
||||
//'ask' = ['account_publickey' => '<email_blake2b_base64>']
|
||||
$results = $this->sendRequestLoginServerNeighbors(json_encode(['ask' => ['account_publickey' => $emailHash]]), 'search');
|
||||
}
|
||||
|
||||
public function getRunningUserTasks($email)
|
||||
{
|
||||
if($email == "") {
|
||||
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'email is empty'];
|
||||
}
|
||||
if(!GenericValidation::email($email, [])) {
|
||||
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'email is invalid'];
|
||||
}
|
||||
|
||||
return $this->sendRequest(json_encode([
|
||||
'email' => $email
|
||||
]), '/getRunningUserTasks');
|
||||
}
|
||||
|
||||
public function getUsers($session_id, $searchString, $accountState)
|
||||
{
|
||||
if($searchString == "") {
|
||||
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'search string is empty'];
|
||||
}
|
||||
if(!is_numeric($session_id)) {
|
||||
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'session_id isn\'t numeric'];
|
||||
}
|
||||
|
||||
return $this->sendRequest(json_encode([
|
||||
'session_id' => $session_id,
|
||||
'search' => $searchString,
|
||||
'account_state' => $accountState,
|
||||
]), '/getUsers');
|
||||
}
|
||||
|
||||
public function sendRequest($transactionBody, $url_last_part) {
|
||||
$http = new Client();
|
||||
|
||||
$response = $http->post($this->getLoginServerUrl() . $url_last_part, $transactionBody, ['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 ['state' => 'success', 'data' => $json];
|
||||
}
|
||||
|
||||
public function sendRequestGDT($transactionBody, $url) {
|
||||
|
||||
$http = new Client();
|
||||
$gdtServerHost = $this->getGDTServerUrl();
|
||||
if(!$gdtServerHost) {
|
||||
return ['state' => 'warning', 'msg' => 'gdt server not configured'];
|
||||
}
|
||||
$fullUrl = $gdtServerHost . DS . $url;
|
||||
$response = $http->post($this->getGDTServerUrl() . DS . $url, $transactionBody, ['type' => 'json']);
|
||||
$responseStatus = $response->getStatusCode();
|
||||
if($responseStatus != 200) {
|
||||
return [
|
||||
'state' => 'error',
|
||||
'type' => 'request error',
|
||||
'msg' => 'server response status code isn\'t 200',
|
||||
'details' => $responseStatus,
|
||||
'fullUrl' => $fullUrl
|
||||
];
|
||||
}
|
||||
//$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 ['state' => 'success', 'data' => $json];
|
||||
}
|
||||
|
||||
public function sendRequestLoginServerNeighbors($transactionBody, $url) {
|
||||
|
||||
$http = new Client();
|
||||
if(!Configure::check('NeighborLoginServers')) {
|
||||
return ['state' => 'warning', 'msg' => 'no neighbor server configured'];
|
||||
}
|
||||
$nServers = Configure::read('NeighborLoginServers');
|
||||
$results = ['errors' => [], 'data' => []];
|
||||
foreach($nServers as $nServer) {
|
||||
$full_url = $nServer['host'] . ':' . $nServer['port'] . '/' . $url;
|
||||
$response = $http->post($full_url, $transactionBody, ['type' => 'json']);
|
||||
$responseStatus = $response->getStatusCode();
|
||||
if($responseStatus != 200) {
|
||||
$results['errors'][] = [
|
||||
'state' => 'error',
|
||||
'type' => 'request error',
|
||||
'msg' => 'server response status code isn\'t 200',
|
||||
'details' => $responseStatus,
|
||||
'fullUrl' => $full_url
|
||||
];
|
||||
continue;
|
||||
}
|
||||
$json = $response->getJson();
|
||||
if($json == null) {
|
||||
//$responseType = $response->getType();
|
||||
$results['errors'][] = ['state' => 'error', 'type' => 'request error', 'msg' => 'server response isn\'t valid json'];
|
||||
continue;
|
||||
}
|
||||
$results['data'][] = $json;
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
static public function getLoginServerUrl()
|
||||
{
|
||||
$loginServer = Configure::read('LoginServer');
|
||||
return $loginServer['host'] . ':' . $loginServer['port'];
|
||||
}
|
||||
|
||||
static public function getGDTServerUrl()
|
||||
{
|
||||
$gdtServer = Configure::read('GDTServer');
|
||||
if(isset($gdtServer['host'])) {
|
||||
return $gdtServer['host'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public function is_base64($s)
|
||||
{
|
||||
return (bool) preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $s);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,83 +0,0 @@
|
||||
<?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;
|
||||
use Cake\Http\Client;
|
||||
use Cake\Core\Configure;
|
||||
|
||||
use Datto\JsonRpc\Client as JsonRpcClient;
|
||||
|
||||
//App\Controller\Component\ComponentRegistry
|
||||
|
||||
class JsonRpcRequestClientComponent extends Component
|
||||
{
|
||||
var $rpcClient = null;
|
||||
public function __construct($registry, array $config = array()) {
|
||||
parent::__construct($registry, $config);
|
||||
|
||||
$this->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();
|
||||
|
||||
try {
|
||||
$url = $this->pickGradidoNodeUrl();
|
||||
if(is_array($url)) {
|
||||
return $url;
|
||||
}
|
||||
$response = $http->post($url, $message, ['type' => 'json']);
|
||||
} catch(Exception $e) {
|
||||
return ['state' => 'error', 'type' => 'http exception', 'details' => $e->getMessage()];
|
||||
}
|
||||
$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['result'];
|
||||
//return ['state' => 'success', 'data' => $json];
|
||||
}
|
||||
|
||||
static public function pickGradidoNodeUrl()
|
||||
{
|
||||
$gradidoNodes = Configure::read('GradidoBlockchain.nodes');
|
||||
if(count($gradidoNodes) == 0) {
|
||||
return ['state' => 'error', 'msg' => 'no gradido nodes in config'];
|
||||
}
|
||||
$i = rand(0, count($gradidoNodes)-1);
|
||||
return $gradidoNodes[$i]['host'] . ':' . $gradidoNodes[$i]['port'];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,78 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
//use Cake\Routing\Router;
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
use Model\Navigation\NaviHierarchy;
|
||||
use Model\Navigation\NaviHierarchyEntry;
|
||||
|
||||
/**
|
||||
* StateUsers Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateUsersTable $StateUsers
|
||||
*
|
||||
* @method \App\Model\Entity\StateUser[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class DashboardController extends AppController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->allow(['index', 'errorHttpRequest']);
|
||||
$this->set(
|
||||
'naviHierarchy',
|
||||
(new NaviHierarchy())->
|
||||
add(new NaviHierarchyEntry(__('Startseite'), 'Dashboard', 'index', true))
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if($result !== true) {
|
||||
return $result;
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
$serverUser = $this->Auth->user('id');
|
||||
if($serverUser) {
|
||||
$adminErrorsTable = TableRegistry::getTableLocator()->get('AdminErrors');
|
||||
$adminErrorCount = $adminErrorsTable->find('all')->count();
|
||||
$this->set('adminErrorCount', $adminErrorCount);
|
||||
}
|
||||
|
||||
$this->set('user', $user);
|
||||
$this->set('serverUser', $serverUser);
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
|
||||
}
|
||||
|
||||
public function serverIndex()
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
$adminErrorsTable = TableRegistry::getTableLocator()->get('AdminErrors');
|
||||
$adminErrorCount = $adminErrorsTable->find('all')->count();
|
||||
|
||||
$this->set('adminErrorCount', $adminErrorCount);
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
}
|
||||
|
||||
public function errorHttpRequest()
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,165 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
use Cake\Datasource\ConnectionManager;
|
||||
use Cake\I18n\Time;
|
||||
//use Cake\I18n\Date;
|
||||
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
/**
|
||||
* ElopageBuys Controller
|
||||
*
|
||||
* @property \App\Model\Table\ElopageBuysTable $ElopageBuys
|
||||
*
|
||||
* @method \App\Model\Entity\ElopageBuy[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class ElopageBuysController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => false,
|
||||
];
|
||||
$elopageBuys = $this->paginate($this->ElopageBuys);
|
||||
|
||||
$this->set(compact('elopageBuys'));
|
||||
}
|
||||
|
||||
public function statistics()
|
||||
{
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
$connection = ConnectionManager::get('loginServer');
|
||||
$dates = $connection->execute('SELECT success_date FROM elopage_buys group by CAST(success_date as DATE)')->fetchAll('assoc');
|
||||
|
||||
$datesTree = [];
|
||||
foreach($dates as $i => $date) {
|
||||
|
||||
$date = new Time($date['success_date']);
|
||||
if(!isset($datesTree[$date->year])) {
|
||||
$datesTree[$date->year] = [];
|
||||
}
|
||||
if(!isset($datesTree[$date->year][$date->month])) {
|
||||
$datesTree[$date->year][$date->month] = true;
|
||||
}
|
||||
}
|
||||
//var_dump($datesTree);
|
||||
|
||||
$now = Time::now();
|
||||
$lastDay = Time::now();
|
||||
$lastDay->day = 1;
|
||||
$now->day = 1;
|
||||
$lastDay->setTime(0,0,0,0);
|
||||
$now->setTime(0,0,0,0);
|
||||
// only for test
|
||||
$now->month = 11;
|
||||
$lastDay->month = 11;
|
||||
$now->year = 2019;
|
||||
$lastDay->year = 2019;
|
||||
// var_dump($now);
|
||||
|
||||
$lastDay = $lastDay->addMonth(1);
|
||||
$sortDate = $this->getStartEndForMonth(11, 2019);
|
||||
$elopageBuys = $this->ElopageBuys
|
||||
->find('all')
|
||||
->where(['success_date >=' => $sortDate[0], 'success_date <' => $sortDate[1]]);
|
||||
$users = [];
|
||||
foreach($elopageBuys as $elopageEntry) {
|
||||
array_push($users, $elopageEntry->payer_email);
|
||||
}
|
||||
$unique_users = array_unique($users);
|
||||
|
||||
$userTable = TableRegistry::getTableLocator()->get('Users');
|
||||
$users = $userTable->find('all')
|
||||
->where(['created >=' => $sortDate[0], 'created <' => $sortDate[1]]);
|
||||
|
||||
$this->set(compact('elopageBuys', 'users'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Elopage Buy id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$elopageBuy = $this->ElopageBuys->get($id, [
|
||||
'contain' => false,
|
||||
]);
|
||||
|
||||
$this->set('elopageBuy', $elopageBuy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$elopageBuy = $this->ElopageBuys->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$elopageBuy = $this->ElopageBuys->patchEntity($elopageBuy, $this->request->getData());
|
||||
if ($this->ElopageBuys->save($elopageBuy)) {
|
||||
$this->Flash->success(__('The elopage buy has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The elopage buy could not be saved. Please, try again.'));
|
||||
}
|
||||
|
||||
$this->set(compact('elopageBuy'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Elopage Buy 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)
|
||||
{
|
||||
$elopageBuy = $this->ElopageBuys->get($id, [
|
||||
'contain' => false,
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$elopageBuy = $this->ElopageBuys->patchEntity($elopageBuy, $this->request->getData());
|
||||
if ($this->ElopageBuys->save($elopageBuy)) {
|
||||
$this->Flash->success(__('The elopage buy has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The elopage buy could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('elopageBuy'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Elopage Buy 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']);
|
||||
$elopageBuy = $this->ElopageBuys->get($id);
|
||||
if ($this->ElopageBuys->delete($elopageBuy)) {
|
||||
$this->Flash->success(__('The elopage buy has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The elopage buy could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
<?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;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
class ElopageWebhookController extends AppController
|
||||
{
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$this->Auth->allow(['put']);
|
||||
|
||||
}
|
||||
|
||||
public function put()
|
||||
{
|
||||
$this->autoRender = false;
|
||||
$data = $this->request->getData();
|
||||
$response = $this->response->withType('text/plain');
|
||||
|
||||
$dataString = http_build_query($data);
|
||||
//$this->recursiveArrayToString($data, $dataString);
|
||||
// %5B => [
|
||||
// %5D => ]
|
||||
$dataString = preg_replace(['/\%5B/', '/\%5D/'], ['[', ']'], $dataString);
|
||||
//var_dump($dataString);
|
||||
|
||||
//2020-02-27T13:52:32+01:00
|
||||
$dateString = date('c');
|
||||
$fh = fopen('/etc/grd_login/php_elopage_requests.txt', 'a');
|
||||
if($fh === FALSE) {
|
||||
return $response->withStringBody('400 ERROR');
|
||||
}
|
||||
fwrite($fh, $dateString);
|
||||
fwrite($fh, "\n");
|
||||
fwrite($fh, $dataString);
|
||||
fwrite($fh, "\n");
|
||||
fclose($fh);
|
||||
|
||||
|
||||
return $response->withStringBody('200 OK');
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 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 3.3.4
|
||||
* @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace App\Controller;
|
||||
|
||||
use Cake\Event\Event;
|
||||
|
||||
/**
|
||||
* Error Handling Controller
|
||||
*
|
||||
* Controller used by ExceptionRenderer to render error responses.
|
||||
*/
|
||||
class ErrorController extends AppController
|
||||
{
|
||||
/**
|
||||
* Initialization hook method.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$this->loadComponent('RequestHandler', [
|
||||
'enableBeforeRedirect' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* beforeFilter callback.
|
||||
*
|
||||
* @param \Cake\Event\Event $event Event.
|
||||
* @return \Cake\Http\Response|null|void
|
||||
*/
|
||||
public function beforeFilter(Event $event)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* beforeRender callback.
|
||||
*
|
||||
* @param \Cake\Event\Event $event Event.
|
||||
* @return \Cake\Http\Response|null|void
|
||||
*/
|
||||
public function beforeRender(Event $event)
|
||||
{
|
||||
parent::beforeRender($event);
|
||||
$this->RequestHandler->renderAs($this, 'json');
|
||||
$this->viewBuilder()->setTemplatePath('Error');
|
||||
}
|
||||
|
||||
/**
|
||||
* afterFilter callback.
|
||||
*
|
||||
* @param \Cake\Event\Event $event Event.
|
||||
* @return \Cake\Http\Response|null|void
|
||||
*/
|
||||
public function afterFilter(Event $event)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -1,559 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
use Cake\ORM\TableRegistry;
|
||||
use Cake\Http\Client;
|
||||
use Cake\Core\Configure;
|
||||
use Cake\Mailer\Email;
|
||||
|
||||
use Model\Transactions\TransactionTransfer;
|
||||
use Model\Transactions\Transaction;
|
||||
use Model\Transactions\Record;
|
||||
/*!
|
||||
* @author: Dario Rekowski#
|
||||
*
|
||||
* @date: 03.11.2019
|
||||
*
|
||||
* @desc: Handle requests from other server put or request transaction
|
||||
*/
|
||||
|
||||
class JsonRequestHandlerController extends AppController {
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->loadComponent('JsonRequestClient');
|
||||
$this->loadComponent('JsonRpcRequestClient');
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->allow('index');
|
||||
}
|
||||
|
||||
|
||||
public function index()
|
||||
{
|
||||
if($this->request->is('get')) {
|
||||
$method = $this->request->getQuery('method');
|
||||
switch($method) {
|
||||
case 'getRunningUserTasks': return $this->getRunningUserTasks();
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'unknown method for get', 'details' => $method]);
|
||||
}
|
||||
else if($this->request->is('post')) {
|
||||
$jsonData = $this->request->input('json_decode');
|
||||
//var_dump($jsonData);
|
||||
if($jsonData == NULL || !isset($jsonData->method)) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'parameter error']);
|
||||
}
|
||||
$method = $jsonData->method;
|
||||
|
||||
switch($method) {
|
||||
case 'putTransaction':
|
||||
if(!isset($jsonData->transaction)) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'parameter error']);
|
||||
} else {
|
||||
return $this->putTransaction($jsonData->transaction);
|
||||
}
|
||||
case 'userDelete': return $this->userDelete($jsonData->user);
|
||||
case 'moveTransaction': return $this->moveTransaction($jsonData->pubkeys, $jsonData->memo, $jsonData->session_id);
|
||||
case 'checkUser': return $this->checkUser($jsonData->email, $jsonData->last_name);
|
||||
case 'getUsers' : return $this->getUsers($jsonData->page, $jsonData->limit);
|
||||
case 'getUserBalance': return $this->getUserBalance($jsonData->email, $jsonData->last_name);
|
||||
case 'errorInTransaction': return $this->errorInTransaction($jsonData);
|
||||
case 'updateReadNode': return $this->updateReadNode();
|
||||
case 'addUser' : return $this->addUser($jsonData->user);
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'unknown method for post', 'details' => $method]);
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post or get']);
|
||||
}
|
||||
|
||||
private function addUser($newUser)
|
||||
{
|
||||
$stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
$entity = $stateUsersTable->newEntity();
|
||||
$required_fields = ['first_name', 'last_name', 'email', 'public_key', 'disabled'];
|
||||
foreach($required_fields as $required_field) {
|
||||
if(!isset($newUser->$required_field)) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'missing required field in addUser', 'details' => $required_field]);
|
||||
}
|
||||
if('public_key' == $required_field) {
|
||||
$entity->$required_field = hex2bin($newUser->public_hex);
|
||||
} else {
|
||||
$entity->$required_field = $newUser->$required_field;
|
||||
}
|
||||
}
|
||||
if($stateUsersTable->save($entity)) {
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
} else {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'error saving state_user', 'details' => $entity->getErrors()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Called from login server like a cron job every 10 minutes or after sending transaction to hedera
|
||||
private function updateReadNode()
|
||||
{
|
||||
$this->autoRender = false;
|
||||
$response = $this->response->withType('application/json');
|
||||
|
||||
$transactionsTable = TableRegistry::getTableLocator()->get('Transactions');
|
||||
$last_transaction_query = $transactionsTable->find('all')->order(['id' => 'DESC']);
|
||||
$last_transaction_id = 0;
|
||||
if(!$last_transaction_query->isEmpty()) {
|
||||
$last_transaction_id = $last_transaction_query->first()->id;
|
||||
}
|
||||
$last_known_sequence_number = $last_transaction_id;
|
||||
|
||||
if($last_transaction_query->count() < $last_transaction_id) {
|
||||
$last_transaction_id = $last_transaction_query->count();
|
||||
}
|
||||
//$last_transaction_id = 0;
|
||||
|
||||
|
||||
$group_alias = Configure::read('GroupAlias');
|
||||
$result = (array)$this->JsonRpcRequestClient->request('getTransactions', ['groupAlias' => $group_alias, 'lastKnownSequenceNumber' => $last_transaction_id]);
|
||||
if(isset($result['state']) && $result['state'] == 'error') {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'jsonrpc error', 'details' => ['return' => $result, 'groupAlias' => $group_alias]]);
|
||||
}
|
||||
/* example
|
||||
$result = json_decode("[
|
||||
{
|
||||
\"record_type\":\"GRADIDO_TRANSACTION\",
|
||||
\"transaction\":{
|
||||
\"version_number\":1,
|
||||
\"signature\":{
|
||||
\"pubkey\":\"2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b\",
|
||||
\"signature\":\"aed6725baacabf903e51f92503d49fa7e6b93c6402d56d9e3784be9a3366a77459213d858af46b579287aba8b1b63d206febce18bc80cec6fa63da6289e56403\"
|
||||
},
|
||||
\"signature_count\":1,
|
||||
\"hedera_transaction\":{
|
||||
\"consensusTimestamp\":{
|
||||
\"seconds\":1604392811,
|
||||
\"nanos\":172812
|
||||
},
|
||||
\"runningHash\":\"f9ccf04137be418c3117a28bb5add6dced9745bcab74b7a2f46c182c8c98eeabf0127c131d15ebea7d0ac376f5d2de45\",
|
||||
\"sequenceNumber\":94,
|
||||
\"runningHashVersion\":3
|
||||
},
|
||||
\"transaction_type\":\"ADD_USER\",
|
||||
\"add_user\":{
|
||||
\"user\":\"2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b\"
|
||||
},
|
||||
\"result\":\"result\",
|
||||
\"parts\":1,
|
||||
\"memo\":\"\"
|
||||
}
|
||||
},
|
||||
{
|
||||
\"record_type\":\"GRADIDO_TRANSACTION\",
|
||||
\"transaction\":{
|
||||
\"version_number\":1,
|
||||
\"signature\":{
|
||||
\"pubkey\":\"8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d\",
|
||||
\"signature\":\"3134adcd6cbccee17c2db398f91b6b6bdd098b6306fb2fa213eb9eb5a322af9078acca4d8b0383d4e906f3139eb3369e7c1ef0f3ac5fec724be0d085ba44af0b\"
|
||||
},
|
||||
\"signature_count\":2,
|
||||
\"hedera_transaction\":{
|
||||
\"consensusTimestamp\":{
|
||||
\"seconds\":1604392886,
|
||||
\"nanos\":1528
|
||||
},
|
||||
\"runningHash\":\"e1df5526331e3def11d6b652b8f248d20c250739b6eb98f1fe7b338901753d9d573a14601ba84f61318a48940b3c237a\",
|
||||
\"sequenceNumber\":95,
|
||||
\"runningHashVersion\":3
|
||||
},
|
||||
\"transaction_type\":\"ADD_USER\",
|
||||
\"add_user\":{
|
||||
\"user\":\"8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d\"
|
||||
},
|
||||
\"result\":\"result\",
|
||||
\"parts\":2,
|
||||
\"memo\":\"\"
|
||||
}
|
||||
},
|
||||
{
|
||||
\"record_type\":\"SIGNATURES\",
|
||||
\"signature\":[
|
||||
{
|
||||
\"pubkey\":\"2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b\",
|
||||
\"signature\":\"401717e768617c0f3311931c34a61e66ab362599a0e2a48ae7c4955645aec6573773985dafb84a11bfaf2bc12140c30b2f8c8ee094bc35d609bc56d15b4e9f04\"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
\"record_type\": \"GRADIDO_TRANSACTION\",
|
||||
\"transaction\":{
|
||||
\"version_number\":1,
|
||||
\"signature\":{
|
||||
\"pubkey\":\"2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b\",
|
||||
\"signature\":\"99665dee9f2b475e426a2f449d0dae61924f6cf025903666ff72f2c7ef1af27523ebcd5fb684d17813fe7906b2f8cfe5ef4bdbb264ebf3ef80363491d9b86807\"
|
||||
},
|
||||
\"signature_count\":1,
|
||||
\"hedera_transaction\":{
|
||||
\"consensusTimestamp\":{
|
||||
\"seconds\":1604392904,
|
||||
\"nanos\":798541
|
||||
},
|
||||
\"runningHash\":\"f1fd03610a9788e9bac01e1efb8b99bafae450f9088cb940db954842e0799235c57d842be83d998e6c21786f77f967a7\",
|
||||
\"sequenceNumber\":96,
|
||||
\"runningHashVersion\":3
|
||||
},
|
||||
\"transaction_type\":\"GRADIDO_CREATION\",
|
||||
\"gradido_creation\":{
|
||||
\"user\":\"8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d\",
|
||||
\"new_balance\":10000000,
|
||||
\"prev_transfer_rec_num\":0,
|
||||
\"amount\":10000000
|
||||
},
|
||||
\"result\":\"result\",
|
||||
\"parts\":1,
|
||||
\"memo\":\"\"
|
||||
}
|
||||
},
|
||||
{
|
||||
\"record_type\": \"GRADIDO_TRANSACTION\",
|
||||
\"transaction\":{
|
||||
\"version_number\":1,
|
||||
\"signature\":{
|
||||
\"pubkey\":\"8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d\",
|
||||
\"signature\":\"90125e0cfce61397d50ed9ba6c5df4cd4e0cf6fee8b10c70fee2898765982570d9a1208c222981429ae3c229e3fd36c2bf2333518cd0a4f0515937822e499d0b\"
|
||||
},
|
||||
\"signature_count\":1,
|
||||
\"hedera_transaction\":{
|
||||
\"consensusTimestamp\":{
|
||||
\"seconds\":1604392929,
|
||||
\"nanos\":52539
|
||||
},
|
||||
\"runningHash\":\"a4be8f54be4f806b61d31f6bd770d7742822f14f03ffe09c07f08bac3031a06d12de5e38fec5c307149c7faf6e9879b8\",
|
||||
\"sequenceNumber\":97,
|
||||
\"runningHashVersion\":3
|
||||
},
|
||||
\"transaction_type\":\"LOCAL_TRANSFER\",
|
||||
\"local_transfer\":{
|
||||
\"sender\":{
|
||||
\"user\":\"8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d\",
|
||||
\"new_balance\":9825500,
|
||||
\"prev_transfer_rec_num\":0
|
||||
},
|
||||
\"receiver\":{
|
||||
\"user\":\"2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b\",
|
||||
\"new_balance\":174500,
|
||||
\"prev_transfer_rec_num\":0
|
||||
},
|
||||
\"amount\":174500
|
||||
},
|
||||
\"result\":\"result\",
|
||||
\"parts\":1,
|
||||
\"memo\":\"\"
|
||||
}
|
||||
}
|
||||
]", true);*/
|
||||
$part_count = -1;
|
||||
$temp_record = new Record;
|
||||
$errors = [];
|
||||
foreach($result['blocks'] as $_record) {
|
||||
if(is_string($_record)) continue;
|
||||
$parse_result = $temp_record->parseRecord($_record);
|
||||
|
||||
if($parse_result == true) {
|
||||
$sequenceNumber = $temp_record->getSequenceNumber();
|
||||
if($part_count == -1) {
|
||||
$part_count = $temp_record->getPartCount();
|
||||
}
|
||||
$part_count--;
|
||||
|
||||
if($part_count == 0) {
|
||||
if($sequenceNumber > $last_known_sequence_number) {
|
||||
$finalize_result = $temp_record->finalize();
|
||||
if($finalize_result !== true) {
|
||||
$errors[] = ['msg' => 'error in finalize', 'record' => $_record, 'details' => $finalize_result, 'sequenceNumber' => $sequenceNumber];
|
||||
}
|
||||
}
|
||||
|
||||
$temp_record = new Record;
|
||||
$part_count = -1;
|
||||
}
|
||||
} else {
|
||||
$temp_record = new Record;
|
||||
$part_count = -1;
|
||||
$errors[] = ['msg' => 'error in parse record', 'record' => $_record, 'details' => $parse_result];
|
||||
}
|
||||
}
|
||||
if(count($errors)) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'error in parsing records', 'details' => $errors]);
|
||||
}
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
}
|
||||
|
||||
/*
|
||||
* payload.set("created", created);
|
||||
* payload.set("id", task_model->getID());
|
||||
* payload.set("type", task_model->getTaskTypeString());
|
||||
* payload.set("public_key", user_model->getPublicKeyHex());
|
||||
* payload.set("error", error);
|
||||
* payload.set("errorMessage", errorDetails);
|
||||
*/
|
||||
//! \param $transactionCreated creation of transaction in timestamp in seconds
|
||||
//! -1 if transaction couldn't decode
|
||||
//! \param $transactionBodyBase64Sha256 generic hash from transaction body serialized and converted to base64
|
||||
//! using sodium_crypto_generichash to calculate
|
||||
// hash also in base64 format
|
||||
//! \param $error short error name in user language
|
||||
//! \param $errorDetails more detailed error message in user language
|
||||
private function errorInTransaction($jsonData) {
|
||||
$stateErrorTable = TableRegistry::getTableLocator()->get('StateErrors');
|
||||
$stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
$transactionTypesTable = TableRegistry::getTableLocator()->get('TransactionTypes');
|
||||
$stateError = $stateErrorTable->newEntity();
|
||||
//
|
||||
$pubkey = hex2bin($jsonData->public_key);
|
||||
$user_query = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $pubkey]);
|
||||
if($user_query->count() != 1) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'user pubkey hex:' . $jsonData->public_key]);
|
||||
}
|
||||
$stateError->state_user_id = $user_query->first()->id;
|
||||
//$stateError->transaction_type_id
|
||||
// TODO:
|
||||
// - show state errors in navi_notify.ctp
|
||||
$transaction_type_query = $transactionTypesTable->find('all')->select(['id'])->where(['name' => $jsonData->type]);
|
||||
if($transaction_type_query->count() != 1) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'transaction type not found', 'details' => 'transaction type name: ' . $jsonData->type]);
|
||||
}
|
||||
$stateError->transaction_type_id = $transaction_type_query->first()->id;
|
||||
$stateError->created = $jsonData->created;
|
||||
$stateError->message_json = json_encode(['task_id' => $jsonData->id, 'error' => $jsonData->error, 'errorMessage' => $jsonData->errorMessage]);
|
||||
if(!$stateErrorTable->save($stateError)) {
|
||||
$this->returnJsonSaveError($stateError, [
|
||||
'state' => 'error',
|
||||
'msg' => 'error saving state_error in db',
|
||||
'details' => json_encode($stateError->getErrors())
|
||||
]);
|
||||
}
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
}
|
||||
|
||||
private function sendEMailTransactionFailed($transaction, $reason_type)
|
||||
{
|
||||
$disable_email = Configure::read('disableEmail', false);
|
||||
if($disable_email) {
|
||||
return;
|
||||
}
|
||||
$transaction_body = $transaction->getTransactionBody();
|
||||
$senderUser = $transaction->getFirstSigningUser();
|
||||
if($transaction_body != null) {
|
||||
$transaction_type_name = $transaction_body->getTransactionTypeName();
|
||||
|
||||
if($transaction_type_name === 'transfer') {
|
||||
$senderUser = $transaction_body->getSpecificTransaction()->getSenderUser();
|
||||
}
|
||||
}
|
||||
// send notification email
|
||||
$noReplyEmail = Configure::read('noReplyEmail');
|
||||
if($senderUser) {
|
||||
try {
|
||||
$email = new Email();
|
||||
$emailViewBuilder = $email->viewBuilder();
|
||||
$emailViewBuilder->setTemplate('notificationTransactionFailed')
|
||||
->setVars(['user' => $senderUser, 'transaction' => $transaction, 'reason' => $reason_type]);
|
||||
$receiverNames = $senderUser->getNames();
|
||||
if($receiverNames == '' || $senderUser->email == '') {
|
||||
$this->addError('TransactionCreation::sendNotificationEmail', 'to email is empty for user: ' . $senderUser->id);
|
||||
return false;
|
||||
}
|
||||
$email->setFrom([$noReplyEmail => 'Gradido (nicht antworten)'])
|
||||
->setTo([$senderUser->email => $senderUser->getNames()])
|
||||
->setSubject(__('Gradido Transaktion fehlgeschlagen!'))
|
||||
->send();
|
||||
} catch(Exception $e) {
|
||||
$this->addAdminError('JsonRequestController', 'sendEMailTransactionFailed', [$e->getMessage(), $reason_type], $senderUser->id);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function putTransaction($transactionBase64) {
|
||||
$transaction = new Transaction($transactionBase64);
|
||||
|
||||
if($transaction->hasErrors()) {
|
||||
$this->sendEMailTransactionFailed($transaction, 'parse');
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'error parsing transaction', 'details' => $transaction->getErrors()]);
|
||||
}
|
||||
|
||||
if(!$transaction->validate()) {
|
||||
//$transaction_details
|
||||
$this->sendEMailTransactionFailed($transaction, 'validate');
|
||||
return $this->returnJsonSaveError($transaction, [
|
||||
'state' => 'error',
|
||||
'msg' => 'error validate transaction',
|
||||
'details' => $transaction->getErrors()
|
||||
]);
|
||||
}
|
||||
|
||||
if ($transaction->save()) {
|
||||
$result = ['state' => 'success'];
|
||||
if($transaction->hasWarnings()) {
|
||||
$result['warnings'] = $transaction->getWarnings();
|
||||
}
|
||||
// success
|
||||
return $this->returnJson($result);
|
||||
} else {
|
||||
|
||||
$this->sendEMailTransactionFailed($transaction, 'save');
|
||||
return $this->returnJsonSaveError($transaction, [
|
||||
'state' => 'error',
|
||||
'msg' => 'error saving transaction in db',
|
||||
'details' => json_encode($transaction->getErrors())
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function moveTransaction($pubkeys, $memo, $session_id) {
|
||||
//$pubkeys->sender
|
||||
//$pubkeys->receiver
|
||||
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
$user = $stateUserTable->find('all')->where(['public_key' => hex2bin($pubkeys->sender)])->contain(['StateBalances']);
|
||||
if(!$user->count()) {
|
||||
return $this->returnJson(['state' => 'not found', 'msg' => 'user not found or empty balance']);
|
||||
}
|
||||
$amountCent = $user->first()->state_balances[0]->amount;
|
||||
//var_dump($user->first());
|
||||
$builderResult = TransactionTransfer::build(
|
||||
$amountCent,
|
||||
$memo,
|
||||
$pubkeys->receiver,
|
||||
$pubkeys->sender
|
||||
);
|
||||
if($builderResult['state'] === 'success') {
|
||||
|
||||
$http = new Client();
|
||||
try {
|
||||
$loginServer = Configure::read('LoginServer');
|
||||
$url = $loginServer['host'] . ':' . $loginServer['port'];
|
||||
|
||||
$response = $http->post($url . '/checkTransaction', json_encode([
|
||||
'session_id' => $session_id,
|
||||
'transaction_base64' => base64_encode($builderResult['transactionBody']->serializeToString()),
|
||||
'balance' => $amountCent
|
||||
]), ['type' => 'json']);
|
||||
$json = $response->getJson();
|
||||
if($json['state'] != 'success') {
|
||||
if($json['msg'] == 'session not found') {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'session not found']);
|
||||
} else {
|
||||
//$this->Flash->error(__('login server return error: ' . json_encode($json)));
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'login server return error', 'details' => $json]);
|
||||
}
|
||||
} else {
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
}
|
||||
|
||||
} catch(\Exception $e) {
|
||||
$msg = $e->getMessage();
|
||||
//$this->Flash->error(__('error http request: ') . $msg);
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'error http request', 'details' => $msg]);
|
||||
}
|
||||
|
||||
} else {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'error building transaction']);
|
||||
}
|
||||
}
|
||||
|
||||
private function userDelete($userPubkeyHex) {
|
||||
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
$user = $stateUserTable->find('all')->where(['public_key' => hex2bin($userPubkeyHex)]);
|
||||
if(!$user || $user->count == 0) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'user not found']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function checkUser($email, $last_name) {
|
||||
$userTable = TableRegistry::getTableLocator()->get('Users');
|
||||
$user = $userTable->find('all')
|
||||
->where(['email' => $email])
|
||||
->contain([])
|
||||
->select(['first_name', 'last_name', 'email']);
|
||||
if(!$user->count()) {
|
||||
return $this->returnJson(['state' => 'not found', 'msg' => 'user not found']);
|
||||
}
|
||||
if($user->count() == 1 && $user->first()->last_name == $last_name) {
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
}
|
||||
return $this->returnJson(['state' => 'not identical', 'user' => $user->toArray()]);
|
||||
}
|
||||
|
||||
private function getUserBalance($email, $last_name) {
|
||||
|
||||
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
$stateUsers = $stateUserTable->find('all')->where(['OR' => ['email' => $email, 'last_name' => $last_name]])->contain(['StateBalances']);
|
||||
$gdds = [];
|
||||
foreach($stateUsers as $stateUser) {
|
||||
foreach($stateUser->state_balances as $stateBalance) {
|
||||
if(!isset($gdds[$stateUser->email])) {
|
||||
$gdds[$stateUser->email] = [];
|
||||
}
|
||||
if(!isset($gdds[$stateUser->email][$stateUser->last_name])) {
|
||||
$gdds[$stateUser->email][$stateUser->last_name] = 0;
|
||||
}
|
||||
$gdds[$stateUser->email][$stateUser->last_name] += $stateBalance->amount;
|
||||
}
|
||||
}
|
||||
return $this->returnJson(['state' => 'success', 'gdds' => $gdds]);
|
||||
}
|
||||
|
||||
private function getUsers($page, $count) {
|
||||
|
||||
$userTable = TableRegistry::getTableLocator()->get('Users');
|
||||
$this->paginate = [
|
||||
'limit' => $count,
|
||||
'page' => $page
|
||||
];
|
||||
$usersQuery = $userTable->find('all')
|
||||
->select(['first_name', 'last_name', 'email'])
|
||||
->order(['id']);
|
||||
try {
|
||||
return $this->returnJson(['state' => 'success', 'users' => $this->paginate($usersQuery)]);
|
||||
} catch (Exception $ex) {
|
||||
return $this->returnJson(['state' => 'exception', 'msg' => 'error paginate users', 'details' => $ex->getMessage()]);
|
||||
}
|
||||
|
||||
|
||||
//return $this->returnJson(['state' => 'success', 'users' => $users->toArray()]);
|
||||
|
||||
}
|
||||
|
||||
private function getRunningUserTasks() {
|
||||
$session = $this->getRequest()->getSession();
|
||||
$state_user_email = $session->read('StateUser.email');
|
||||
$requestResult = $this->JsonRequestClient->getRunningUserTasks($state_user_email);;
|
||||
return $this->returnJson($requestResult);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
} else {
|
||||
$errorArray['user_error'] = "user with $pub not found";
|
||||
$json = json_encode($errorArray);
|
||||
}
|
||||
|
||||
return $this->returnJsonEncoded($json);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* OperatorTypes Controller
|
||||
*
|
||||
* @property \App\Model\Table\OperatorTypesTable $OperatorTypes
|
||||
*
|
||||
* @method \App\Model\Entity\OperatorType[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class OperatorTypesController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$operatorTypes = $this->paginate($this->OperatorTypes);
|
||||
|
||||
$this->set(compact('operatorTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Operator Type id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$operatorType = $this->OperatorTypes->get($id, [
|
||||
'contain' => ['Operators']
|
||||
]);
|
||||
|
||||
$this->set('operatorType', $operatorType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$operatorType = $this->OperatorTypes->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$operatorType = $this->OperatorTypes->patchEntity($operatorType, $this->request->getData());
|
||||
if ($this->OperatorTypes->save($operatorType)) {
|
||||
$this->Flash->success(__('The operator type has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The operator type could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('operatorType'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Operator Type 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)
|
||||
{
|
||||
$operatorType = $this->OperatorTypes->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$operatorType = $this->OperatorTypes->patchEntity($operatorType, $this->request->getData());
|
||||
if ($this->OperatorTypes->save($operatorType)) {
|
||||
$this->Flash->success(__('The operator type has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The operator type could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('operatorType'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Operator Type 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']);
|
||||
$operatorType = $this->OperatorTypes->get($id);
|
||||
if ($this->OperatorTypes->delete($operatorType)) {
|
||||
$this->Flash->success(__('The operator type has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The operator type could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,236 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
//require_once "../../vendor/paragonie/sodium_compat/autoload.php";
|
||||
|
||||
/**
|
||||
* Operators Controller
|
||||
*
|
||||
* @property \App\Model\Table\OperatorsTable $Operators
|
||||
*
|
||||
* @method \App\Model\Entity\Operator[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class OperatorsController extends AppController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->Auth->allow(['ajaxSave', 'ajaxLoad', 'ajaxDelete']);
|
||||
}
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['OperatorTypes']
|
||||
];
|
||||
$operators = $this->paginate($this->Operators);
|
||||
|
||||
$this->set(compact('operators'));
|
||||
}
|
||||
|
||||
public function ajaxSave()
|
||||
{
|
||||
if ($this->request->is('post')) {
|
||||
|
||||
$operatorTypeName = $this->request->getData('operator_type_name');
|
||||
$username = $this->request->getData('username');
|
||||
$pubkey_bin = base64_decode($this->request->getData('user_pubkey'));
|
||||
$data = base64_decode($this->request->getData('data_base64'));
|
||||
$sign = base64_decode($this->request->getData('sign'));
|
||||
|
||||
//$publicKey_hex = bin2hex($pubkey_bin);
|
||||
//$signature_hex = bin2hex($sign);
|
||||
|
||||
if(!sodium_crypto_sign_verify_detached($sign, $data, $pubkey_bin)) {
|
||||
return $this->returnJson([
|
||||
'state' => 'wrong signature',
|
||||
/* 'details' => [
|
||||
'pubkey' => $publicKey_hex,
|
||||
'sign' => $signature_hex,
|
||||
'data' => bin2hex($data)
|
||||
]
|
||||
*/
|
||||
]);
|
||||
}
|
||||
|
||||
$operatorTypeId = $this->Operators->OperatorTypes->
|
||||
find()
|
||||
->where(['name' => $operatorTypeName])
|
||||
->select(['id'])
|
||||
->first();
|
||||
|
||||
// load operator from db if already exist
|
||||
$operator = $this->Operators
|
||||
->find()
|
||||
->where([
|
||||
'operator_type_id' => $operatorTypeId->id,
|
||||
'username' => $username,
|
||||
'user_pubkey' => $pubkey_bin])
|
||||
->first();
|
||||
if(!$operator) {
|
||||
// create new entity
|
||||
$operator = $this->Operators->newEntity();
|
||||
} else {
|
||||
// check if request has valid signature
|
||||
|
||||
}
|
||||
|
||||
$operator = $this->Operators->patchEntity($operator, $this->request->getData());
|
||||
$operator->user_pubkey = $pubkey_bin;
|
||||
$operator->operator_type_id = $operatorTypeId->id;
|
||||
if ($this->Operators->save($operator)) {
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'details' => $operator->getErrors()]);
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
|
||||
}
|
||||
|
||||
public function ajaxLoad()
|
||||
{
|
||||
if ($this->request->is('get')) {
|
||||
$username = $this->request->getQuery('username');
|
||||
$operators = $this->Operators
|
||||
->find()
|
||||
->where(['username' => $username])
|
||||
->contain(['OperatorTypes'])
|
||||
->select(['data_base64', 'OperatorTypes.name'])
|
||||
->toArray();
|
||||
;
|
||||
if($operators) {
|
||||
return $this->returnJson(['state' => 'success', 'operators' => $operators]);
|
||||
} else {
|
||||
return $this->returnJson(['state' => 'not found']);
|
||||
}
|
||||
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
|
||||
}
|
||||
|
||||
function ajaxDelete() {
|
||||
if ($this->request->is('delete')) {
|
||||
$operatorTypeName = $this->request->getData('operator_type_name');
|
||||
$username = $this->request->getData('username');
|
||||
$pubkey_bin = base64_decode($this->request->getData('user_pubkey'));
|
||||
$sign = base64_decode($this->request->getData('sign'));
|
||||
|
||||
$operatorTypeId = $this->Operators->OperatorTypes->
|
||||
find()
|
||||
->where(['name' => $operatorTypeName])
|
||||
->select(['id'])
|
||||
->first();
|
||||
|
||||
// load operator from db if already exist
|
||||
$operator = $this->Operators
|
||||
->find()
|
||||
->where([
|
||||
'operator_type_id' => $operatorTypeId->id,
|
||||
'username' => $username,
|
||||
'user_pubkey' => $pubkey_bin])
|
||||
->first();
|
||||
if(!$operator) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'not found']);
|
||||
} else {
|
||||
$data = base64_decode($operator->data_base64);
|
||||
// check if request has valid signature
|
||||
if(!sodium_crypto_sign_verify_detached($sign, $data, $pubkey_bin)) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'wrong signature']);
|
||||
}
|
||||
}
|
||||
if ($this->Operators->delete($operator)) {
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'details' => $operator->getErrors()]);
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Operator id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$operator = $this->Operators->get($id, [
|
||||
'contain' => ['OperatorTypes']
|
||||
]);
|
||||
|
||||
$this->set('operator', $operator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$operator = $this->Operators->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$operator = $this->Operators->patchEntity($operator, $this->request->getData());
|
||||
if ($this->Operators->save($operator)) {
|
||||
$this->Flash->success(__('The operator has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The operator could not be saved. Please, try again.'));
|
||||
}
|
||||
$operatorTypes = $this->Operators->OperatorTypes->find('list', ['limit' => 200]);
|
||||
$this->set(compact('operator', 'operatorTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Operator 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)
|
||||
{
|
||||
$operator = $this->Operators->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$operator = $this->Operators->patchEntity($operator, $this->request->getData());
|
||||
if ($this->Operators->save($operator)) {
|
||||
$this->Flash->success(__('The operator has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The operator could not be saved. Please, try again.'));
|
||||
}
|
||||
$operatorTypes = $this->Operators->OperatorTypes->find('list', ['limit' => 200]);
|
||||
$this->set(compact('operator', 'operatorTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Operator 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']);
|
||||
$operator = $this->Operators->get($id);
|
||||
if ($this->Operators->delete($operator)) {
|
||||
$this->Flash->success(__('The operator has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The operator could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,86 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 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.2.9
|
||||
* @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace App\Controller;
|
||||
|
||||
use Cake\Core\Configure;
|
||||
use Cake\Http\Exception\ForbiddenException;
|
||||
use Cake\Http\Exception\NotFoundException;
|
||||
use Cake\View\Exception\MissingTemplateException;
|
||||
|
||||
/**
|
||||
* Static content controller
|
||||
*
|
||||
* This controller will render views from Template/Pages/
|
||||
*
|
||||
* @link https://book.cakephp.org/3.0/en/controllers/pages-controller.html
|
||||
*/
|
||||
class PagesController extends AppController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->Auth->allow(['display']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a view
|
||||
*
|
||||
* @param array ...$path Path segments.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Http\Exception\ForbiddenException When a directory traversal attempt.
|
||||
* @throws \Cake\Http\Exception\NotFoundException When the view file could not
|
||||
* be found or \Cake\View\Exception\MissingTemplateException in debug mode.
|
||||
*/
|
||||
public function display(...$path)
|
||||
{
|
||||
|
||||
$count = count($path);
|
||||
if (!$count) {
|
||||
return $this->redirect('/');
|
||||
}
|
||||
if (in_array('..', $path, true) || in_array('.', $path, true)) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
$page = $subpage = null;
|
||||
|
||||
if (!empty($path[0])) {
|
||||
$page = $path[0];
|
||||
}
|
||||
if (!empty($path[1])) {
|
||||
$subpage = $path[1];
|
||||
}
|
||||
/*$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if($result !== true) {
|
||||
return $result;
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
$login_server_session = $this->request->getCookie('GRADIDO_LOGIN', '');*/
|
||||
if($page == "vue" || $page == "vue-dev") {
|
||||
$this->viewBuilder()->setLayout(false);
|
||||
}
|
||||
$this->set(compact('page', 'subpage'));
|
||||
|
||||
try {
|
||||
$this->render(implode('/', $path));
|
||||
} catch (MissingTemplateException $exception) {
|
||||
if (Configure::read('debug')) {
|
||||
throw $exception;
|
||||
}
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,206 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
use Model\Navigation\NaviHierarchy;
|
||||
use Model\Navigation\NaviHierarchyEntry;
|
||||
|
||||
use Cake\ORM\TableRegistry;
|
||||
use Cake\Filesystem\File;
|
||||
|
||||
use App\Form\ProfileForm;
|
||||
|
||||
/**
|
||||
* Profile Controller
|
||||
*/
|
||||
class ProfileController extends AppController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->loadComponent('JsonRequestClient');
|
||||
$this->Auth->allow(['index', 'edit']);
|
||||
$this->set(
|
||||
'naviHierarchy',
|
||||
(new NaviHierarchy())->
|
||||
add(new NaviHierarchyEntry(__('Startseite'), 'Dashboard', 'index', false))->
|
||||
add(new NaviHierarchyEntry(__('Mein Profil'), 'Profile', 'index', true))
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Get binary file data from request data
|
||||
*
|
||||
* @return binary data
|
||||
*/
|
||||
protected function getFileData($requestData)
|
||||
{
|
||||
$binaryFileData = null;
|
||||
// Get a list of UploadedFile objects
|
||||
$file = $requestData['profile_img'];
|
||||
// Read the file data.
|
||||
$type = $file['type'];
|
||||
$error = $file['error'];
|
||||
if ($error === 0 && strpos($type, 'image/') === 0) {
|
||||
$path = new File($file['tmp_name']);
|
||||
$binaryFileData = $path->read(true, 'r');
|
||||
$this->log("binaryFileData: ".$binaryFileData, 'debug');
|
||||
}
|
||||
return $binaryFileData;
|
||||
}
|
||||
/**
|
||||
* Update Profile Data
|
||||
*
|
||||
* ...which is spread over two tables, plus needs to be promoted to the Login Server.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function updateProfileData($requestData, $userId, $communityProfile)
|
||||
{
|
||||
// Update Profile with Form Data!
|
||||
$usersTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
$stateUserQuery = $usersTable
|
||||
->find('all')
|
||||
->select(['id', 'first_name', 'last_name'])
|
||||
->where(['id' => $userId]);
|
||||
|
||||
if ($stateUserQuery->count() == 1) {
|
||||
$stateUser = $stateUserQuery->first();
|
||||
$stateUser = $usersTable->patchEntity($stateUser, $requestData);
|
||||
|
||||
$profilesTable = TableRegistry::getTableLocator()->get('CommunityProfiles');
|
||||
// Save old binary data, because the file input is always empty, in HTML!
|
||||
$oldBinaryData = $communityProfile['profile_img'];
|
||||
|
||||
$communityProfile = $profilesTable->patchEntity($communityProfile, $requestData);
|
||||
$communityProfile['state_user_id'] = $userId;
|
||||
|
||||
$binaryFileData = $this->getFileData($requestData);
|
||||
if ($binaryFileData !== null) {
|
||||
$this->log("CommunityProfile: Writing binary img data.", 'debug');
|
||||
$communityProfile['profile_img'] = $binaryFileData;
|
||||
} else {
|
||||
$this->log("CommunityProfile: Nothing uploaded!", 'debug');
|
||||
$communityProfile['profile_img'] = $oldBinaryData;
|
||||
}
|
||||
if ($profilesTable->save($communityProfile) &&
|
||||
$usersTable->save($stateUser)
|
||||
) {
|
||||
$session = $this->getRequest()->getSession();
|
||||
$session_id = $session->read('session_id');
|
||||
$email = $session->read('StateUser.email');
|
||||
$this->returnJson(
|
||||
$this->JsonRequestClient->sendRequest(
|
||||
json_encode(
|
||||
[
|
||||
'session_id' => $session_id,
|
||||
'email' => $email,
|
||||
'update' => [
|
||||
'User.first_name' => $requestData['first_name'],
|
||||
'User.last_name' => $requestData['last_name']
|
||||
]
|
||||
]
|
||||
),
|
||||
'/updateUserInfos'
|
||||
)
|
||||
);
|
||||
$this->Flash->success(__('Dein Profil wurde aktualisiert!'));
|
||||
}
|
||||
} else {
|
||||
$this->Flash->error(__("Non-recoverable database problem - state_user doesn't exist or not unique!"));
|
||||
}
|
||||
return [$stateUser, $communityProfile];
|
||||
}
|
||||
/**
|
||||
* Get or create CommunityProfile
|
||||
*
|
||||
* @return \Cake\ORM\CommunityProfile
|
||||
*/
|
||||
protected function getCommunityProfile($userId)
|
||||
{
|
||||
$profilesTable = TableRegistry::getTableLocator()->get('CommunityProfiles');
|
||||
$communityProfileQuery = $profilesTable
|
||||
->find('all')
|
||||
->select(['id', 'profile_img', 'profile_desc'])
|
||||
->where(['state_user_id' => $userId]);
|
||||
if ($communityProfileQuery->count() != 1) {
|
||||
$communityProfile = $profilesTable->newEntity();
|
||||
if ($profilesTable->save($communityProfile)) {
|
||||
$this->log("CommunityProfile created.", 'debug');
|
||||
}
|
||||
} else {
|
||||
$communityProfile = $communityProfileQuery->first();
|
||||
}
|
||||
return $communityProfile;
|
||||
}
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if ($result !== true) {
|
||||
return $result;
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
$communityProfile = $session->read('CommunityProfile');
|
||||
if (!$communityProfile) {
|
||||
$this->log("CommunityProfile not found in session! Loading or creating new one.", 'debug');
|
||||
$session->write('CommunityProfile', $this->getCommunityProfile($user['id']));
|
||||
}
|
||||
$this->set('user', $user);
|
||||
$this->set('communityProfile', $communityProfile);
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
}
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
$session = $this->getRequest()->getSession();
|
||||
|
||||
$user = $session->read('StateUser');
|
||||
$communityProfile = $session->read('CommunityProfile');
|
||||
if (!$user) {
|
||||
$result = $this->requestLogin();
|
||||
if ($result !== true) {
|
||||
return $result;
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
}
|
||||
if (!$communityProfile) {
|
||||
$this->log("CommunityProfile not found in session! Loading or creating new one.", 'debug');
|
||||
$session->write('CommunityProfile', $this->getCommunityProfile($user['id']));
|
||||
}
|
||||
|
||||
$profileForm = new ProfileForm();
|
||||
if ($this->request->is('post')) {
|
||||
$requestData = $this->request->getData();
|
||||
if ($profileForm->validate($requestData)) {
|
||||
[$stateUser, $communityProfile] = $this->updateProfileData($requestData, $user['id'], $communityProfile);
|
||||
$user['first_name'] = $stateUser['first_name'];
|
||||
$user['last_name'] = $stateUser['last_name'];
|
||||
$session->write('StateUser.first_name', $stateUser['first_name']);
|
||||
$session->write('StateUser.last_name', $stateUser['last_name']);
|
||||
$session->write('CommunityProfile', $communityProfile);
|
||||
return $this->redirect(['action' => 'index']);
|
||||
} else {
|
||||
$this->Flash->error(__('Something was invalid, please try again!'));
|
||||
}
|
||||
}
|
||||
$this->set('user', $user);
|
||||
$this->set('communityProfile', $communityProfile);
|
||||
$this->set('profileForm', $profileForm);
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
}
|
||||
}
|
||||
@ -1,108 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
use Model\Navigation\NaviHierarchy;
|
||||
use Model\Navigation\NaviHierarchyEntry;
|
||||
/**
|
||||
* Roles Controller
|
||||
*
|
||||
*
|
||||
* @method \App\Model\Entity\Role[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class RolesController extends AppController
|
||||
{
|
||||
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
$roles = $this->paginate($this->Roles);
|
||||
|
||||
$this->set(compact('roles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Role id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$role = $this->Roles->get($id, [
|
||||
'contain' => [],
|
||||
]);
|
||||
|
||||
$this->set('role', $role);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$role = $this->Roles->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$role = $this->Roles->patchEntity($role, $this->request->getData());
|
||||
if ($this->Roles->save($role)) {
|
||||
$this->Flash->success(__('The role has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The role could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('role'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Role 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)
|
||||
{
|
||||
$role = $this->Roles->get($id, [
|
||||
'contain' => [],
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$role = $this->Roles->patchEntity($role, $this->request->getData());
|
||||
if ($this->Roles->save($role)) {
|
||||
$this->Flash->success(__('The role has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The role could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('role'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Role 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']);
|
||||
$role = $this->Roles->get($id);
|
||||
if ($this->Roles->delete($role)) {
|
||||
$this->Flash->success(__('The role has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The role could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,132 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* ServerUsers Controller
|
||||
*
|
||||
* @property \App\Model\Table\ServerUsersTable $ServerUsers
|
||||
*
|
||||
* @method \App\Model\Entity\ServerUser[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class ServerUsersController extends AppController
|
||||
{
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
// uncomment in devmode to add new community server admin user, but don't!!! commit it
|
||||
// $this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->deny('index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$serverUsers = $this->paginate($this->ServerUsers);
|
||||
$this->set(compact('serverUsers'));
|
||||
}
|
||||
|
||||
public function login()
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
if ($this->request->is('post')) {
|
||||
$user = $this->Auth->identify();
|
||||
if ($user) {
|
||||
$this->Auth->setUser($user);
|
||||
return $this->redirect($this->Auth->redirectUrl());
|
||||
}
|
||||
$this->Flash->error(__('Invalid username or password, try again'));
|
||||
}
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
return $this->redirect($this->Auth->logout());
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Server User id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$serverUser = $this->ServerUsers->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
|
||||
$this->set('serverUser', $serverUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$serverUser = $this->ServerUsers->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$serverUser = $this->ServerUsers->patchEntity($serverUser, $this->request->getData());
|
||||
if ($this->ServerUsers->save($serverUser)) {
|
||||
$this->Flash->success(__('The server user has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The server user could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('serverUser'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Server User 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)
|
||||
{
|
||||
$serverUser = $this->ServerUsers->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$serverUser = $this->ServerUsers->patchEntity($serverUser, $this->request->getData());
|
||||
if ($this->ServerUsers->save($serverUser)) {
|
||||
$this->Flash->success(__('The server user has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The server user could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('serverUser'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Server User 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']);
|
||||
$serverUser = $this->ServerUsers->get($id);
|
||||
if ($this->ServerUsers->delete($serverUser)) {
|
||||
$this->Flash->success(__('The server user has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The server user could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,399 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use Cake\ORM\TableRegistry;
|
||||
use Cake\I18n\FrozenTime;
|
||||
|
||||
use Model\Navigation\NaviHierarchy;
|
||||
use Model\Navigation\NaviHierarchyEntry;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
|
||||
/**
|
||||
* StateBalances Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateBalancesTable $StateBalances
|
||||
*
|
||||
* @method \App\Model\Entity\StateBalance[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class StateBalancesController extends AppController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->allow(['overview', 'overviewGdt', 'ajaxListTransactions', 'ajaxGdtOverview', 'ajaxGetBalance', 'ajaxGdtTransactions']);
|
||||
$this->loadComponent('JsonRequestClient');
|
||||
}
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['StateUsers']
|
||||
];
|
||||
$stateBalances = $this->paginate($this->StateBalances);
|
||||
|
||||
$this->set(compact('stateBalances'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function overview()
|
||||
{
|
||||
$this->set(
|
||||
'naviHierarchy',
|
||||
(new NaviHierarchy())->
|
||||
add(new NaviHierarchyEntry(__('Startseite'), 'Dashboard', 'index', false))->
|
||||
add(new NaviHierarchyEntry(__('Kontoübersicht'), 'StateBalances', 'overview', true))
|
||||
);
|
||||
$startTime = microtime(true);
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if ($result !== true) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$user = $session->read('StateUser');
|
||||
$update_balance_result = $this->StateBalances->updateBalances($user['id']);
|
||||
if($update_balance_result['success'] !== true) {
|
||||
$this->addAdminError('StateBalances', 'overview', $update_balance_result, $user['id']);
|
||||
}
|
||||
|
||||
$stateBalancesTable = TableRegistry::getTableLocator()->get('StateBalances');
|
||||
$stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions');
|
||||
$transactionsTable = TableRegistry::getTableLocator()->get('Transactions');
|
||||
|
||||
$stateBalancesTable->updateBalances($user['id']);
|
||||
$gdtSum = 0;
|
||||
$gdtEntries = $this->JsonRequestClient->sendRequestGDT(['email' => $user['email']], 'GdtEntries' . DS . 'sumPerEmailApi');
|
||||
if('success' == $gdtEntries['state'] && 'success' == $gdtEntries['data']['state']) {
|
||||
$gdtSum = intval($gdtEntries['data']['sum']);
|
||||
} else {
|
||||
$this->addAdminError('StateBalancesController', 'overview', $gdtEntries, $user['id'] ? $user['id'] : 0);
|
||||
}
|
||||
|
||||
|
||||
$stateUserTransactionsQuery = $stateUserTransactionsTable
|
||||
->find()
|
||||
->where(['state_user_id' => $user['id']])
|
||||
->order(['balance_date' => 'ASC'])
|
||||
->contain([])
|
||||
;
|
||||
$decay = true;
|
||||
$transactions = [];
|
||||
if($stateUserTransactionsQuery->count() > 0) {
|
||||
$transactions_with_decay = $transactionsTable->listTransactionsHumanReadable($stateUserTransactionsQuery->toArray(), $user, $decay);
|
||||
foreach($transactions_with_decay as $tr) {
|
||||
if(isset($tr['decay'])) {
|
||||
$tr['decay']['type'] = 'decay';
|
||||
$tr['decay']['memo'] = '';
|
||||
$transactions[] = $tr['decay'];
|
||||
}
|
||||
$transactions[] = $tr;
|
||||
}
|
||||
}
|
||||
|
||||
$state_balance = $stateBalancesTable->find()->where(['state_user_id' => $user['id']])->first();
|
||||
|
||||
$body = [
|
||||
'state' => 'success',
|
||||
'transactions' => $transactions,
|
||||
'transactionExecutingCount' => $session->read('Transactions.executing'),
|
||||
'count' => count($transactions),
|
||||
'gdtSum' => $gdtSum,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
];
|
||||
$now = new FrozenTime();
|
||||
$body['decay_date'] = $now;
|
||||
|
||||
if(!$state_balance) {
|
||||
$balance = 0.0;
|
||||
} else {
|
||||
$balance = $stateBalancesTable->calculateDecay($state_balance->amount, $state_balance->record_date, $now);
|
||||
//$balance = $state_balance->partDecay($now);
|
||||
}
|
||||
$calculated_balance = 0;
|
||||
foreach($transactions as $transaction) {
|
||||
if($transaction['type'] == 'decay' || $transaction['type'] == 'send') {
|
||||
$calculated_balance -= $transaction['balance'];
|
||||
} else {
|
||||
$calculated_balance += $transaction['balance'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->set('calculated_balance', $calculated_balance);
|
||||
|
||||
$this->set('transactions', array_reverse($transactions));
|
||||
$this->set('transactionExecutingCount', $session->read('Transactions.executing'));
|
||||
$this->set('balance', $balance);
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
$this->set('gdtSum', $gdtSum);
|
||||
}
|
||||
|
||||
|
||||
public function ajaxGdtOverview()
|
||||
{
|
||||
$gdtSum = 0;
|
||||
$gdtCount = -1;
|
||||
$session = $this->getRequest()->getSession();
|
||||
$user = $session->read('StateUser');
|
||||
|
||||
if(!$user) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'exist a valid session cookie?']);
|
||||
}
|
||||
$gdtEntries = $this->JsonRequestClient->sendRequestGDT(['email' => $user['email']], 'GdtEntries' . DS . 'sumPerEmailApi');
|
||||
|
||||
if('success' == $gdtEntries['state'] && 'success' == $gdtEntries['data']['state']) {
|
||||
$gdtSum = intval($gdtEntries['data']['sum']);
|
||||
if(isset($gdtEntries['data']['count'])) {
|
||||
$gdtCount = intval($gdtEntries['data']['count']);
|
||||
}
|
||||
} else {
|
||||
if($user) {
|
||||
$this->addAdminError('StateBalancesController', 'ajaxGdtOverview', $gdtEntries, $user['id']);
|
||||
} else {
|
||||
$this->addAdminError('StateBalancesController', 'ajaxGdtOverview', $gdtEntries, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->returnJson([
|
||||
'state' => 'success',
|
||||
'transactions' => $transactions,
|
||||
'transactionExecutingCount' => $session->read('Transaction.executing'),
|
||||
'count' => $all_user_transactions_count
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function overviewGdt()
|
||||
{
|
||||
$this->set(
|
||||
'naviHierarchy',
|
||||
(new NaviHierarchy())->
|
||||
add(new NaviHierarchyEntry(__('Startseite'), 'Dashboard', 'index', false))->
|
||||
add(new NaviHierarchyEntry(__('GDT Kontoübersicht'), 'StateBalances', 'overviewGdt', true))
|
||||
);
|
||||
$startTime = microtime(true);
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if ($result !== true) {
|
||||
return $result;
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
$requestResult = $this->JsonRequestClient->sendRequestGDT([
|
||||
'email' => $user['email'],
|
||||
'page' => 1,
|
||||
'count' => 100,
|
||||
'orderDirection' => 'DESC'
|
||||
], 'GdtEntries' . DS . 'listPerEmailApi');
|
||||
|
||||
//var_dump($requestResult);
|
||||
if('success' === $requestResult['state'] && 'success' === $requestResult['data']['state'])
|
||||
{
|
||||
$moreEntrysAsShown = false;
|
||||
if(isset($requestResult['data']['count'])) {
|
||||
if($requestResult['data']['count'] > 100) {
|
||||
$moreEntrysAsShown = true;
|
||||
}
|
||||
} else {
|
||||
$moreEntrysAsShown = $requestResult['data']['moreEntrysAsShown'];
|
||||
}
|
||||
//var_dump(array_keys($requestResult['data']));
|
||||
if(isset($requestResult['data']['gdtEntries'])) {
|
||||
$ownEntries = $requestResult['data']['gdtEntries'];
|
||||
} else {
|
||||
$ownEntries = $requestResult['data']['ownEntries'];
|
||||
}
|
||||
//$gdtEntries = $requestResult['data']['entries'];
|
||||
|
||||
$gdtSum = 0;
|
||||
foreach ($ownEntries as $i => $gdtEntry) {
|
||||
$gdtSum += $gdtEntry['gdt'];
|
||||
//echo "index: $i<br>";
|
||||
//var_dump($gdtEntry);
|
||||
}
|
||||
if (isset($requestResult['data']['connectEntrys'])) {
|
||||
$connectEntries = $requestResult['data']['connectEntrys'];
|
||||
|
||||
foreach ($connectEntries as $entry) {
|
||||
//if(!$count) var_dump($entry);
|
||||
//$count++;
|
||||
$gdtSum += $entry['connect']['gdt_entry']['gdt'];
|
||||
}
|
||||
$this->set('connectEntries', $connectEntries);
|
||||
}
|
||||
|
||||
//echo "gdtSum: $gdtSum<br>";
|
||||
$this->set('gdtSum', $gdtSum);
|
||||
$this->set('ownEntries', $ownEntries);
|
||||
$this->set('moreEntrysAsShown', $moreEntrysAsShown);
|
||||
$this->set('user', $user);
|
||||
|
||||
if (isset($requestResult['data']['publishers'])) {
|
||||
$publishers = $requestResult['data']['publishers'];
|
||||
$this->set('publishers', $publishers);
|
||||
}
|
||||
} else {
|
||||
$this->addAdminError('StateBalancesController', 'overviewGdt', $requestResult, $user['id']);
|
||||
$this->Flash->error(__('Fehler beim GDT Server, bitte abwarten oder den Admin benachrichtigen!'));
|
||||
}
|
||||
}
|
||||
|
||||
public function ajaxGdtTransactions()
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$session = $this->getRequest()->getSession();
|
||||
$user = $session->read('StateUser');
|
||||
if(!$user) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'exist a valid session cookie?']);
|
||||
}
|
||||
|
||||
$requestResult = $this->JsonRequestClient->sendRequestGDT(['email' => $user['email']], 'GdtEntries' . DS . 'listPerEmailApi');
|
||||
$connectEntries = [];
|
||||
$publishers = [];
|
||||
|
||||
//var_dump($requestResult);
|
||||
if('success' === $requestResult['state'] && 'success' === $requestResult['data']['state']) {
|
||||
|
||||
//var_dump(array_keys($requestResult['data']));
|
||||
$ownEntries = $requestResult['data']['ownEntries'];
|
||||
//$gdtEntries = $requestResult['data']['entries'];
|
||||
|
||||
$gdtSum = 0;
|
||||
foreach ($ownEntries as $i => $gdtEntry) {
|
||||
$gdtSum += $gdtEntry['gdt'];
|
||||
//echo "index: $i<br>";
|
||||
//var_dump($gdtEntry);
|
||||
}
|
||||
if (isset($requestResult['data']['connectEntrys'])) {
|
||||
$connectEntries = $requestResult['data']['connectEntrys'];
|
||||
|
||||
foreach ($connectEntries as $entry) {
|
||||
//if(!$count) var_dump($entry);
|
||||
//$count++;
|
||||
$gdtSum += $entry['connect']['gdt_entry']['gdt'];
|
||||
}
|
||||
}
|
||||
|
||||
//echo "gdtSum: $gdtSum<br>";
|
||||
|
||||
if (isset($requestResult['data']['publishers'])) {
|
||||
$publishers = $requestResult['data']['publishers'];
|
||||
}
|
||||
} else {
|
||||
$this->addAdminError('StateBalancesController', 'ajaxGdtTransactions', $requestResult, $user['id']);
|
||||
//$this->Flash->error(__('Fehler beim GDT Server, bitte abwarten oder den Admin benachrichtigen!'));
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'error from gdt server', 'details' => $requestResult]);
|
||||
}
|
||||
|
||||
|
||||
return $this->returnJson([
|
||||
'state' => 'success',
|
||||
'gdtSum' => $gdtSum,
|
||||
'ownEntries' => $ownEntries,
|
||||
'connectEntries' => $connectEntries,
|
||||
'publishers' => $publishers,
|
||||
'gdtSumPerEmail' => $requestResult['data']['gdtSumPerEmail'],
|
||||
'moreEntrysAsShown' => $requestResult['data']['moreEntrysAsShown'],
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
}
|
||||
|
||||
public function sortTransactions($a, $b)
|
||||
{
|
||||
if ($a['date'] == $b['date']) {
|
||||
return 0;
|
||||
}
|
||||
return ($a['date'] > $b['date']) ? -1 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id State Balance id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$stateBalance = $this->StateBalances->get($id, [
|
||||
'contain' => ['StateUsers']
|
||||
]);
|
||||
|
||||
$this->set('stateBalance', $stateBalance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$stateBalance = $this->StateBalances->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$stateBalance = $this->StateBalances->patchEntity($stateBalance, $this->request->getData());
|
||||
if ($this->StateBalances->save($stateBalance)) {
|
||||
$this->Flash->success(__('The state balance has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state balance could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateUsers = $this->StateBalances->StateUsers->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateBalance', 'stateUsers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id State Balance 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)
|
||||
{
|
||||
$stateBalance = $this->StateBalances->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$stateBalance = $this->StateBalances->patchEntity($stateBalance, $this->request->getData());
|
||||
if ($this->StateBalances->save($stateBalance)) {
|
||||
$this->Flash->success(__('The state balance has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state balance could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateUsers = $this->StateBalances->StateUsers->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateBalance', 'stateUsers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id State Balance 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']);
|
||||
$stateBalance = $this->StateBalances->get($id);
|
||||
if ($this->StateBalances->delete($stateBalance)) {
|
||||
$this->Flash->success(__('The state balance has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The state balance could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* StateCreated Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateCreatedTable $StateCreated
|
||||
*
|
||||
* @method \App\Model\Entity\StateCreated[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class StateCreatedController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['Transactions', 'StateUsers']
|
||||
];
|
||||
$stateCreated = $this->paginate($this->StateCreated);
|
||||
|
||||
$this->set(compact('stateCreated'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id State Created id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$stateCreated = $this->StateCreated->get($id, [
|
||||
'contain' => ['Transactions', 'StateUsers']
|
||||
]);
|
||||
|
||||
$this->set('stateCreated', $stateCreated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$stateCreated = $this->StateCreated->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$stateCreated = $this->StateCreated->patchEntity($stateCreated, $this->request->getData());
|
||||
if ($this->StateCreated->save($stateCreated)) {
|
||||
$this->Flash->success(__('The state created has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state created could not be saved. Please, try again.'));
|
||||
}
|
||||
$transactions = $this->StateCreated->Transactions->find('list', ['limit' => 200]);
|
||||
$stateUsers = $this->StateCreated->StateUsers->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateCreated', 'transactions', 'stateUsers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id State Created 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)
|
||||
{
|
||||
$stateCreated = $this->StateCreated->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$stateCreated = $this->StateCreated->patchEntity($stateCreated, $this->request->getData());
|
||||
if ($this->StateCreated->save($stateCreated)) {
|
||||
$this->Flash->success(__('The state created has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state created could not be saved. Please, try again.'));
|
||||
}
|
||||
$transactions = $this->StateCreated->Transactions->find('list', ['limit' => 200]);
|
||||
$stateUsers = $this->StateCreated->StateUsers->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateCreated', 'transactions', 'stateUsers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id State Created 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']);
|
||||
$stateCreated = $this->StateCreated->get($id);
|
||||
if ($this->StateCreated->delete($stateCreated)) {
|
||||
$this->Flash->success(__('The state created has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The state created could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,173 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
use Model\Navigation\NaviHierarchy;
|
||||
use Model\Navigation\NaviHierarchyEntry;
|
||||
|
||||
/**
|
||||
* 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']);
|
||||
$this->set(
|
||||
'naviHierarchy',
|
||||
(new NaviHierarchy())->
|
||||
add(new NaviHierarchyEntry(__('Startseite'), 'Dashboard', 'index', false))->
|
||||
add(new NaviHierarchyEntry(__('Fehler'), 'StateErrors', 'ShowForUser', true))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'])->order(['id']);
|
||||
|
||||
$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']);
|
||||
}
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* StateGroupAddresses Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateGroupAddressesTable $StateGroupAddresses
|
||||
*
|
||||
* @method \App\Model\Entity\StateGroupAddress[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class StateGroupAddressesController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['AddressTypes'],
|
||||
];
|
||||
$stateGroupAddresses = $this->paginate($this->StateGroupAddresses);
|
||||
|
||||
$this->set(compact('stateGroupAddresses'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id State Group Address id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$stateGroupAddress = $this->StateGroupAddresses->get($id, [
|
||||
'contain' => ['StateGroups', 'AddressTypes'],
|
||||
]);
|
||||
|
||||
$this->set('stateGroupAddress', $stateGroupAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$stateGroupAddress = $this->StateGroupAddresses->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$stateGroupAddress = $this->StateGroupAddresses->patchEntity($stateGroupAddress, $this->request->getData());
|
||||
if ($this->StateGroupAddresses->save($stateGroupAddress)) {
|
||||
$this->Flash->success(__('The state group address has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state group address could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateGroups = $this->StateGroupAddresses->StateGroups->find('list', ['limit' => 200]);
|
||||
$addressTypes = $this->StateGroupAddresses->AddressTypes->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateGroupAddress', 'stateGroups', 'addressTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id State Group Address 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)
|
||||
{
|
||||
$stateGroupAddress = $this->StateGroupAddresses->get($id, [
|
||||
'contain' => [],
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$stateGroupAddress = $this->StateGroupAddresses->patchEntity($stateGroupAddress, $this->request->getData());
|
||||
if ($this->StateGroupAddresses->save($stateGroupAddress)) {
|
||||
$this->Flash->success(__('The state group address has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state group address could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateGroups = $this->StateGroupAddresses->StateGroups->find('list', ['limit' => 200]);
|
||||
$addressTypes = $this->StateGroupAddresses->AddressTypes->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateGroupAddress', 'stateGroups', 'addressTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id State Group Address 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']);
|
||||
$stateGroupAddress = $this->StateGroupAddresses->get($id);
|
||||
if ($this->StateGroupAddresses->delete($stateGroupAddress)) {
|
||||
$this->Flash->success(__('The state group address has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The state group address could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,115 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* StateGroupRelationships Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateGroupRelationshipsTable $StateGroupRelationships
|
||||
*
|
||||
* @method \App\Model\Entity\StateGroupRelationship[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class StateGroupRelationshipsController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['StateGroup1s', 'StateGroup2s', 'StateRelationships']
|
||||
];
|
||||
$stateGroupRelationships = $this->paginate($this->StateGroupRelationships);
|
||||
|
||||
$this->set(compact('stateGroupRelationships'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id State Group Relationship id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$stateGroupRelationship = $this->StateGroupRelationships->get($id, [
|
||||
'contain' => ['StateGroup1s', 'StateGroup2s', 'StateRelationships']
|
||||
]);
|
||||
|
||||
$this->set('stateGroupRelationship', $stateGroupRelationship);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$stateGroupRelationship = $this->StateGroupRelationships->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$stateGroupRelationship = $this->StateGroupRelationships->patchEntity($stateGroupRelationship, $this->request->getData());
|
||||
if ($this->StateGroupRelationships->save($stateGroupRelationship)) {
|
||||
$this->Flash->success(__('The state group relationship has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state group relationship could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateGroup1s = $this->StateGroupRelationships->StateGroup1s->find('list', ['limit' => 200]);
|
||||
$stateGroup2s = $this->StateGroupRelationships->StateGroup2s->find('list', ['limit' => 200]);
|
||||
$stateRelationships = $this->StateGroupRelationships->StateRelationships->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateGroupRelationship', 'stateGroup1s', 'stateGroup2s', 'stateRelationships'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id State Group Relationship 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)
|
||||
{
|
||||
$stateGroupRelationship = $this->StateGroupRelationships->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$stateGroupRelationship = $this->StateGroupRelationships->patchEntity($stateGroupRelationship, $this->request->getData());
|
||||
if ($this->StateGroupRelationships->save($stateGroupRelationship)) {
|
||||
$this->Flash->success(__('The state group relationship has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state group relationship could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateGroup1s = $this->StateGroupRelationships->StateGroup1s->find('list', ['limit' => 200]);
|
||||
$stateGroup2s = $this->StateGroupRelationships->StateGroup2s->find('list', ['limit' => 200]);
|
||||
$stateRelationships = $this->StateGroupRelationships->StateRelationships->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateGroupRelationship', 'stateGroup1s', 'stateGroup2s', 'stateRelationships'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id State Group Relationship 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']);
|
||||
$stateGroupRelationship = $this->StateGroupRelationships->get($id);
|
||||
if ($this->StateGroupRelationships->delete($stateGroupRelationship)) {
|
||||
$this->Flash->success(__('The state group relationship has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The state group relationship could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,111 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* StateGroups Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateGroupsTable $StateGroups
|
||||
*
|
||||
* @method \App\Model\Entity\StateGroup[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class StateGroupsController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['Indices']
|
||||
];
|
||||
$stateGroups = $this->paginate($this->StateGroups);
|
||||
|
||||
$this->set(compact('stateGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id State Group id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$stateGroup = $this->StateGroups->get($id, [
|
||||
'contain' => ['Indices', 'StateGroupAddresses', 'StateUsers', 'TransactionGroupCreates', 'Transactions']
|
||||
]);
|
||||
|
||||
$this->set('stateGroup', $stateGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$stateGroup = $this->StateGroups->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$stateGroup = $this->StateGroups->patchEntity($stateGroup, $this->request->getData());
|
||||
if ($this->StateGroups->save($stateGroup)) {
|
||||
$this->Flash->success(__('The state group has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state group could not be saved. Please, try again.'));
|
||||
}
|
||||
$indices = $this->StateGroups->Indices->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateGroup', 'indices'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id State Group 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)
|
||||
{
|
||||
$stateGroup = $this->StateGroups->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$stateGroup = $this->StateGroups->patchEntity($stateGroup, $this->request->getData());
|
||||
if ($this->StateGroups->save($stateGroup)) {
|
||||
$this->Flash->success(__('The state group has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state group could not be saved. Please, try again.'));
|
||||
}
|
||||
$indices = $this->StateGroups->Indices->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateGroup', 'indices'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id State Group 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']);
|
||||
$stateGroup = $this->StateGroups->get($id);
|
||||
if ($this->StateGroups->delete($stateGroup)) {
|
||||
$this->Flash->success(__('The state group has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The state group could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* StateRelationshipTypes Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateRelationshipTypesTable $StateRelationshipTypes
|
||||
*
|
||||
* @method \App\Model\Entity\StateRelationshipType[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class StateRelationshipTypesController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$stateRelationshipTypes = $this->paginate($this->StateRelationshipTypes);
|
||||
|
||||
$this->set(compact('stateRelationshipTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id State Relationship Type id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$stateRelationshipType = $this->StateRelationshipTypes->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
|
||||
$this->set('stateRelationshipType', $stateRelationshipType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$stateRelationshipType = $this->StateRelationshipTypes->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$stateRelationshipType = $this->StateRelationshipTypes->patchEntity($stateRelationshipType, $this->request->getData());
|
||||
if ($this->StateRelationshipTypes->save($stateRelationshipType)) {
|
||||
$this->Flash->success(__('The state relationship type has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state relationship type could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('stateRelationshipType'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id State Relationship Type 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)
|
||||
{
|
||||
$stateRelationshipType = $this->StateRelationshipTypes->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$stateRelationshipType = $this->StateRelationshipTypes->patchEntity($stateRelationshipType, $this->request->getData());
|
||||
if ($this->StateRelationshipTypes->save($stateRelationshipType)) {
|
||||
$this->Flash->success(__('The state relationship type has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state relationship type could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->set(compact('stateRelationshipType'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id State Relationship Type 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']);
|
||||
$stateRelationshipType = $this->StateRelationshipTypes->get($id);
|
||||
if ($this->StateRelationshipTypes->delete($stateRelationshipType)) {
|
||||
$this->Flash->success(__('The state relationship type has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The state relationship type could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,185 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use Cake\Routing\Router;
|
||||
use Cake\I18n\I18n;
|
||||
use Cake\I18n\FrozenTime;
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
use App\Controller\AppController;
|
||||
use App\Form\UserSearchForm;
|
||||
use App\Model\Validation\GenericValidation;
|
||||
|
||||
use Model\Navigation\NaviHierarchy;
|
||||
use Model\Navigation\NaviHierarchyEntry;
|
||||
|
||||
use Model\Transactions\TransactionCreation;
|
||||
use App\Model\Table\StateUsersTable;
|
||||
|
||||
use App\Form\AssignRoleForm;
|
||||
|
||||
|
||||
/**
|
||||
* StateUserRoles Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateUsersTable $StateUsers
|
||||
*
|
||||
* @method \App\Model\Entity\StateUser[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class StateUserRolesController extends AppController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->loadComponent('JsonRequestClient');
|
||||
$this->Auth->allow([
|
||||
// 'search'
|
||||
]);
|
||||
$this->set(
|
||||
'naviHierarchy',
|
||||
(new NaviHierarchy())->
|
||||
add(new NaviHierarchyEntry(__('Startseite'), 'Dashboard', 'index', false))->add(new NaviHierarchyEntry(__('Benutzer suchen'), 'StateUsers', 'search', true))
|
||||
);
|
||||
}
|
||||
|
||||
public function search()
|
||||
{
|
||||
$this->loadModel('StateUsers');
|
||||
$startTime = microtime(true);
|
||||
I18n::setLocale('de_DE');
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
|
||||
$searchForm = new UserSearchForm();
|
||||
|
||||
$timeUsed = microtime(true) - $startTime;
|
||||
//$this->set('timeUsed', $timeUsed);
|
||||
$this->set(compact('timeUsed', 'searchForm'));
|
||||
|
||||
if ($this->request->is('post')) {
|
||||
$requestData = $this->request->getData();
|
||||
|
||||
if ($searchForm->validate($requestData)) {
|
||||
//var_dump($requestData);
|
||||
$searchString = $requestData['search'];
|
||||
|
||||
// find user on community server db
|
||||
$globalSearch = '%' . $searchString . '%';
|
||||
$communityUsers = $this->StateUsers
|
||||
->find('all')
|
||||
->contain([]);
|
||||
|
||||
$communityUsers->where(['OR' => [
|
||||
'first_name LIKE' => $globalSearch,
|
||||
'last_name LIKE' => $globalSearch,
|
||||
//'username LIKE' => $globalSearch,
|
||||
'email LIKE' => $globalSearch
|
||||
]]);
|
||||
|
||||
//var_dump($communityUsers->toArray());
|
||||
$finalUserEntrys = [];
|
||||
// detect states
|
||||
$this->loadModel('Roles');
|
||||
// foreach ($pubkeySorted as $pubhex => $user) {
|
||||
foreach($communityUsers as $communityUser) {
|
||||
$finalUser = $communityUser;
|
||||
$finalUser['pubkeyhex'] = bin2hex(stream_get_contents($communityUser->public_key));
|
||||
|
||||
$state_user_id = $communityUser->id;
|
||||
$stateUserRole = $this->StateUserRoles->find('all')->where(['state_user_id' => $state_user_id])->all();
|
||||
|
||||
$role_ids = "";
|
||||
foreach ($stateUserRole as $userRole) {
|
||||
if($role_ids != "")
|
||||
$role_ids .= ",".$userRole->role_id;
|
||||
else
|
||||
$role_ids = $userRole->role_id;
|
||||
}
|
||||
|
||||
$roles = $this->Roles->find('all')->where(['id IN' => explode(",",$role_ids)])->all();
|
||||
|
||||
$role_names = "";
|
||||
foreach($roles as $role)
|
||||
{
|
||||
if($role_names != "")
|
||||
$role_names .= "<br/>".$role->title;
|
||||
else
|
||||
$role_names = $role->title;
|
||||
}
|
||||
|
||||
$finalUser['role_name'] = $role_names;
|
||||
|
||||
array_push($finalUserEntrys, $finalUser);
|
||||
}
|
||||
|
||||
//var_dump($pubkeySorted);
|
||||
} else {
|
||||
$this->Flash->error(__('Something was invalid, please try again!'));
|
||||
}
|
||||
$this->set('finalUserEntrys', $finalUserEntrys);
|
||||
}
|
||||
$timeUsed = microtime(true) - $startTime;
|
||||
$this->set('timeUsed', $timeUsed);
|
||||
}
|
||||
|
||||
public function assignRole()
|
||||
{
|
||||
$this->loadModel('Roles');
|
||||
$this->loadModel('StateUsers');
|
||||
|
||||
if ($this->request->is('post')) {
|
||||
$requestData = $this->request->getData();
|
||||
|
||||
$public_hex = hex2bin($requestData['public_hex']);
|
||||
|
||||
$stateUser = $this->StateUsers->find('all')->where(['public_key' => $public_hex])->first();
|
||||
|
||||
foreach($requestData['role_id'] as $role_id)
|
||||
{
|
||||
$newStateUserRole = $this->StateUserRoles->newEntity();
|
||||
|
||||
$post_data = [];
|
||||
$post_data['state_user_id'] = $stateUser->id;
|
||||
$post_data['role_id'] = $role_id;
|
||||
$this->StateUserRoles->patchEntity($newStateUserRole, $post_data);
|
||||
$this->StateUserRoles->save($newStateUserRole);
|
||||
|
||||
}
|
||||
|
||||
$this->Flash->success(__('Role has been assigned to User.'));
|
||||
|
||||
return $this->redirect(['controller' => 'state-user-roles', 'action' => 'search']);
|
||||
|
||||
}
|
||||
|
||||
$assignRoleForm = new AssignRoleForm();
|
||||
|
||||
$public_hex = $this->request->getParam('pass')[0];
|
||||
|
||||
$publichex = hex2bin($public_hex);
|
||||
|
||||
$stateUser = $this->StateUsers->find('all')->where(['public_key' => $publichex])->first();
|
||||
|
||||
$stateUserRoles = $this->StateUserRoles->find('all')->where(['state_user_id' => $stateUser->id])->all();
|
||||
|
||||
$role_ids = "";
|
||||
foreach ($stateUserRoles as $userRole) {
|
||||
if($role_ids != "")
|
||||
$role_ids .= ",".$userRole->role_id;
|
||||
else
|
||||
$role_ids = $userRole->role_id;
|
||||
}
|
||||
|
||||
$role_ids = explode(",", $role_ids);
|
||||
|
||||
$roles = $this->Roles->find('list', array('fields' => array('id', 'title')));
|
||||
|
||||
|
||||
$this->set('roles', $roles);
|
||||
$this->set('stateUser', $stateUser);
|
||||
$this->set('role_ids', $role_ids);
|
||||
$this->set('assignRoleForm', $assignRoleForm);
|
||||
$this->set('public_hex', $public_hex);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,291 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
/**
|
||||
* StateUserTransactions Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateUserTransactionsTable $StateUserTransactions
|
||||
*
|
||||
* @method \App\Model\Entity\StateUserTransaction[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class StateUserTransactionsController extends AppController
|
||||
{
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->allow(['ajaxListTransactions']);
|
||||
//$this->loadComponent('JsonRequestClient');
|
||||
}
|
||||
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['StateUsers', 'Transactions', 'TransactionTypes'],
|
||||
];
|
||||
$stateUserTransactions = $this->paginate($this->StateUserTransactions);
|
||||
|
||||
$this->set(compact('stateUserTransactions'));
|
||||
}
|
||||
|
||||
public function sortTransactions($a, $b)
|
||||
{
|
||||
if ($a['date'] == $b['date']) {
|
||||
return 0;
|
||||
}
|
||||
return ($a['date'] > $b['date']) ? -1 : 1;
|
||||
}
|
||||
|
||||
|
||||
public function ajaxListTransactions($page = 1, $count = 20)
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$session = $this->getRequest()->getSession();
|
||||
$user = $session->read('StateUser');
|
||||
if(!$user) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'exist a valid session cookie?']);
|
||||
}
|
||||
|
||||
$paged_state_user_transactions = $this->StateUserTransactions
|
||||
->find('all')
|
||||
->where(['state_user_id' => $user['id'], 'transaction_type_id IN' => [1,2]])
|
||||
->limit($count)
|
||||
->page($page)
|
||||
->order(['transaction_id'])
|
||||
;
|
||||
$all_user_transactions_count = $this->StateUserTransactions
|
||||
->find('all')
|
||||
->where(['state_user_id' => $user['id'], 'transaction_type_id IN' => [1,2]])
|
||||
->count()
|
||||
;
|
||||
$creationTransaction_ids = [];
|
||||
$transferTransaction_ids = [];
|
||||
$allTransaction_ids = [];
|
||||
foreach($paged_state_user_transactions as $state_user_transaction) {
|
||||
$allTransaction_ids[] = $state_user_transaction->transaction_id;
|
||||
switch($state_user_transaction->transaction_type_id) {
|
||||
case 1: $creationTransaction_ids[] = $state_user_transaction->transaction_id; break;
|
||||
case 2: $transferTransaction_ids[] = $state_user_transaction->transaction_id; break;
|
||||
}
|
||||
}
|
||||
$transactionsTable = TableRegistry::getTableLocator()->get('Transactions');
|
||||
$transactionCreationsTable = TableRegistry::getTableLocator()->get('TransactionCreations');
|
||||
$transactionSendCoinsTable = TableRegistry::getTableLocator()->get('TransactionSendCoins');
|
||||
$stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
if(count($allTransaction_ids) > 0) {
|
||||
$transactionEntries = $transactionsTable->find('all')->where(['id IN' => $allTransaction_ids])->order(['id'])->toArray();
|
||||
}
|
||||
if(count($creationTransaction_ids) > 0) {
|
||||
$transactionCreations = $transactionCreationsTable->find('all')->where(['transaction_id IN' => $creationTransaction_ids]);
|
||||
}
|
||||
if(count($transferTransaction_ids)) {
|
||||
$transactionTransfers = $transactionSendCoinsTable->find('all')->where(['transaction_id IN' => $transferTransaction_ids]);
|
||||
}
|
||||
//var_dump($transactions->all());
|
||||
|
||||
$transactions = [];
|
||||
// creations
|
||||
if(isset($transactionCreations)) {
|
||||
foreach ($transactionCreations as $creation) {
|
||||
//var_dump($creation);
|
||||
$transaction_entries_index = array_search($creation->transaction_id, $allTransaction_ids);
|
||||
if(FALSE === $transaction_entries_index) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'code error', 'details' => 'creation, transaction_entries_index is FALSE, shouldn\'t occure']);
|
||||
}
|
||||
$transaction = $transactionEntries[$transaction_entries_index];
|
||||
array_push($transactions, [
|
||||
'name' => 'Gradido Akademie',
|
||||
'type' => 'creation',
|
||||
'transaction_id' => $creation->transaction_id,
|
||||
'date' => $transaction->received,
|
||||
'balance' => $creation->amount,
|
||||
'memo' => $transaction->memo
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// involved users
|
||||
if(isset($transactionTransfers)) {
|
||||
$involvedUserIds = [];
|
||||
|
||||
foreach ($transactionTransfers as $transfer) {
|
||||
//var_dump($sendCoins);
|
||||
if ($transfer->state_user_id != $user['id']) {
|
||||
array_push($involvedUserIds, intval($transfer->state_user_id));
|
||||
} elseif ($transfer->receiver_user_id != $user['id']) {
|
||||
array_push($involvedUserIds, intval($transfer->receiver_user_id));
|
||||
}
|
||||
}
|
||||
|
||||
// exchange key with values and drop duplicates
|
||||
$involvedUser_temp = array_flip($involvedUserIds);
|
||||
// exchange back
|
||||
$involvedUserIds = array_flip($involvedUser_temp);
|
||||
|
||||
$involvedUser = $stateUsersTable->find('all', [
|
||||
'contain' => false,
|
||||
'where' => ['id IN' => $involvedUserIds],
|
||||
'fields' => ['id', 'first_name', 'last_name', 'email']
|
||||
]);
|
||||
//var_dump($involvedUser->toArray());
|
||||
$involvedUserIndices = [];
|
||||
foreach ($involvedUser as $involvedUser) {
|
||||
$involvedUserIndices[$involvedUser->id] = $involvedUser;
|
||||
}
|
||||
|
||||
// transfers - send coins
|
||||
foreach($transactionTransfers as $transfer)
|
||||
{
|
||||
$transaction_entries_index = array_search($transfer->transaction_id, $allTransaction_ids);
|
||||
if(FALSE === $transaction_entries_index) {
|
||||
|
||||
return $this->returnJson([
|
||||
'state' => 'error',
|
||||
'msg' => 'code error',
|
||||
'details' => 'transfer, transaction_entries_index is FALSE, shouldn\'t occure',
|
||||
'data' => ['haystack' => $allTransaction_ids, 'needle' => $transfer->transaction_id]
|
||||
]);
|
||||
}
|
||||
$transaction = $transactionEntries[$transaction_entries_index];
|
||||
$type = '';
|
||||
$otherUser = null;
|
||||
$other_user_public = '';
|
||||
|
||||
if ($transfer->state_user_id == $user['id']) {
|
||||
$type = 'send';
|
||||
|
||||
if(isset($involvedUserIndices[$transfer->receiver_user_id])) {
|
||||
$otherUser = $involvedUserIndices[$transfer->receiver_user_id];
|
||||
}
|
||||
$other_user_public = bin2hex(stream_get_contents($transfer->receiver_public_key));
|
||||
} else if ($transfer->receiver_user_id == $user['id']) {
|
||||
$type = 'receive';
|
||||
if(isset($involvedUserIndices[$transfer->state_user_id])) {
|
||||
$otherUser = $involvedUserIndices[$transfer->state_user_id];
|
||||
}
|
||||
if($transfer->sender_public_key) {
|
||||
$other_user_public = bin2hex(stream_get_contents($transfer->sender_public_key));
|
||||
}
|
||||
}
|
||||
if(null == $otherUser) {
|
||||
$otherUser = $stateUsersTable->newEntity();
|
||||
}
|
||||
array_push($transactions, [
|
||||
'name' => $otherUser->first_name . ' ' . $otherUser->last_name,
|
||||
'email' => $otherUser->email,
|
||||
'type' => $type,
|
||||
'transaction_id' => $transfer->transaction_id,
|
||||
'date' => $transaction->received,
|
||||
'balance' => $transfer->amount,
|
||||
'memo' => $transaction->memo,
|
||||
'pubkey' => $other_user_public
|
||||
]);
|
||||
//*/
|
||||
|
||||
}
|
||||
}
|
||||
uasort($transactions, array($this, 'sortTransactions'));
|
||||
|
||||
return $this->returnJson([
|
||||
'state' => 'success',
|
||||
'transactions' => $transactions,
|
||||
'transactionExecutingCount' => $session->read('Transactions.executing'),
|
||||
'count' => $all_user_transactions_count,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id State User Transaction id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$stateUserTransaction = $this->StateUserTransactions->get($id, [
|
||||
'contain' => ['StateUsers', 'Transactions', 'TransactionTypes'],
|
||||
]);
|
||||
|
||||
$this->set('stateUserTransaction', $stateUserTransaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$stateUserTransaction = $this->StateUserTransactions->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$stateUserTransaction = $this->StateUserTransactions->patchEntity($stateUserTransaction, $this->request->getData());
|
||||
if ($this->StateUserTransactions->save($stateUserTransaction)) {
|
||||
$this->Flash->success(__('The state user transaction has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state user transaction could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateUsers = $this->StateUserTransactions->StateUsers->find('list', ['limit' => 200]);
|
||||
$transactions = $this->StateUserTransactions->Transactions->find('list', ['limit' => 200]);
|
||||
$transactionTypes = $this->StateUserTransactions->TransactionTypes->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateUserTransaction', 'stateUsers', 'transactions', 'transactionTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id State User Transaction 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)
|
||||
{
|
||||
$stateUserTransaction = $this->StateUserTransactions->get($id, [
|
||||
'contain' => [],
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$stateUserTransaction = $this->StateUserTransactions->patchEntity($stateUserTransaction, $this->request->getData());
|
||||
if ($this->StateUserTransactions->save($stateUserTransaction)) {
|
||||
$this->Flash->success(__('The state user transaction has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state user transaction could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateUsers = $this->StateUserTransactions->StateUsers->find('list', ['limit' => 200]);
|
||||
$transactions = $this->StateUserTransactions->Transactions->find('list', ['limit' => 200]);
|
||||
$transactionTypes = $this->StateUserTransactions->TransactionTypes->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateUserTransaction', 'stateUsers', 'transactions', 'transactionTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id State User Transaction 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']);
|
||||
$stateUserTransaction = $this->StateUserTransactions->get($id);
|
||||
if ($this->StateUserTransactions->delete($stateUserTransaction)) {
|
||||
$this->Flash->success(__('The state user transaction has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The state user transaction could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,616 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use Cake\Routing\Router;
|
||||
use Cake\I18n\I18n;
|
||||
use Cake\I18n\FrozenTime;
|
||||
use Cake\ORM\TableRegistry;
|
||||
use Cake\Core\Configure;
|
||||
use Cake\Http\Client;
|
||||
|
||||
use App\Controller\AppController;
|
||||
use App\Form\UserSearchForm;
|
||||
use App\Model\Validation\GenericValidation;
|
||||
|
||||
use Model\Navigation\NaviHierarchy;
|
||||
use Model\Navigation\NaviHierarchyEntry;
|
||||
|
||||
use Model\Transactions\TransactionCreation;
|
||||
|
||||
// for translating
|
||||
__('account created');
|
||||
__('account not on login-server');
|
||||
__('email activated');
|
||||
__('account copied to community');
|
||||
__('email not activated');
|
||||
__('account multiple times on login-server');
|
||||
__('account not on community server');
|
||||
__('no keys');
|
||||
|
||||
/**
|
||||
* StateUsers Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateUsersTable $StateUsers
|
||||
*
|
||||
* @method \App\Model\Entity\StateUser[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class StateUsersController extends AppController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->loadComponent('GradidoNumber');
|
||||
$this->loadComponent('JsonRequestClient');
|
||||
$this->loadComponent('Cookie');
|
||||
$this->Auth->allow([
|
||||
'search', 'ajaxCopyLoginToCommunity', 'ajaxCopyCommunityToLogin',
|
||||
'ajaxDelete', 'ajaxCountTransactions', 'ajaxVerificationEmailResend',
|
||||
'ajaxGetUserEmailVerificationCode', 'ajaxGetCSFRToken', 'login'
|
||||
]);
|
||||
$this->set(
|
||||
'naviHierarchy',
|
||||
(new NaviHierarchy())->
|
||||
add(new NaviHierarchyEntry(__('Startseite'), 'Dashboard', 'index', false))->add(new NaviHierarchyEntry(__('Benutzer suchen'), 'StateUsers', 'search', true))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => []
|
||||
];
|
||||
$stateUsers = $this->paginate($this->StateUsers);
|
||||
|
||||
$this->set(compact('stateUsers'));
|
||||
}
|
||||
|
||||
/*public function listIdentHashes()
|
||||
{
|
||||
$stateUsers = $this->StateUsers->find('all')->toArray();
|
||||
foreach($stateUsers as $i => $user) {
|
||||
$stateUsers[$i]->identHash = TransactionCreation::DRMakeStringHash($user->email);
|
||||
}
|
||||
$this->set('stateUsers', $stateUsers);
|
||||
}*/
|
||||
|
||||
public function login($session_id)
|
||||
{
|
||||
if(isset($session_id) && intval($session_id) !== 0) {
|
||||
$loginServer = Configure::read('LoginServer');
|
||||
$http = new Client();
|
||||
|
||||
try {
|
||||
$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') {
|
||||
$this->Cookie->configKey('GRADIDO_LOGIN', 'encryption', false);
|
||||
$this->Cookie->write('GRADIDO_LOGIN', $session_id);
|
||||
return $this->redirect(['controller' => 'Dashboard', 'action' => 'index']);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$msg = $e->getMessage();
|
||||
$this->Flash->error(__('error http request: ') . $msg);
|
||||
return $this->redirect(['controller' => 'Dashboard', 'action' => 'errorHttpRequest']);
|
||||
}
|
||||
}
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
public function search()
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
I18n::setLocale('de_DE');
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if($result !== true) {
|
||||
return $result;
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
if($user['role'] != 'admin') {
|
||||
return $this->redirect(['controller' => 'dashboard', 'action' => 'index']);
|
||||
}
|
||||
|
||||
$searchForm = new UserSearchForm();
|
||||
|
||||
$timeUsed = microtime(true) - $startTime;
|
||||
//$this->set('timeUsed', $timeUsed);
|
||||
$csfr_token = $this->request->getParam('_csrfToken');
|
||||
$this->set(compact('timeUsed', 'searchForm', 'csfr_token'));
|
||||
$empty_string = '... empty ...';
|
||||
if ($this->request->is('post')) {
|
||||
$finalUserEntrys = [];
|
||||
$requestData = $this->request->getData();
|
||||
$account_state = $requestData['account_state'];
|
||||
if($requestData['search'] == '' && $account_state != 'all') {
|
||||
$requestData['search'] = $empty_string;
|
||||
}
|
||||
|
||||
if($searchForm->validate($requestData)) {
|
||||
//var_dump($requestData);
|
||||
$searchString = $requestData['search'];
|
||||
$searchType = 'unknown';
|
||||
if(GenericValidation::email($searchString, [])) {
|
||||
$searchType = 'email';
|
||||
}
|
||||
// find users on login server
|
||||
$resultJson = $this->JsonRequestClient->getUsers($session->read('session_id'), $searchString, $account_state);
|
||||
$loginServerUser = [];
|
||||
if($resultJson['state'] == 'success') {
|
||||
$dataJson = $resultJson['data'];
|
||||
if($dataJson['state'] != 'success') {
|
||||
if($dataJson['msg'] == 'session not found') {
|
||||
$session->destroy();
|
||||
return $this->redirect(Router::url('/', true) . 'account', 303);
|
||||
}
|
||||
}
|
||||
//var_dump($dataJson);
|
||||
if(isset($dataJson['users'])) {
|
||||
$loginServerUser = $dataJson['users'];
|
||||
}
|
||||
}
|
||||
$pubkeySorted = [];
|
||||
$emptyPubkeys = [];
|
||||
foreach($loginServerUser as $u) {
|
||||
if(!isset($u['public_hex']) || $u['public_hex'] == '') {
|
||||
array_push($emptyPubkeys, $u);
|
||||
} else {
|
||||
if(!isset($pubkeySorted[$u['public_hex']])) {
|
||||
$pubkeySorted[$u['public_hex']] = ['login' => [], 'community' => []];
|
||||
}
|
||||
array_push($pubkeySorted[$u['public_hex']]['login'], $u);
|
||||
}
|
||||
}
|
||||
// find user on community server db
|
||||
|
||||
|
||||
|
||||
$communityUsers = $this->StateUsers
|
||||
->find('all')
|
||||
->contain(['StateBalances' => ['fields' => ['amount', 'state_user_id']]]);
|
||||
|
||||
if($account_state == 'email not activated') {
|
||||
if(count($pubkeySorted) > 0) {
|
||||
$communityUsers->where(['hex(public_key) IN' => array_keys($pubkeySorted)]);
|
||||
} else {
|
||||
$communityUsers = null;
|
||||
}
|
||||
} else {
|
||||
$globalSearch = '%' . $searchString . '%';
|
||||
$communityUsers->where(['OR' => [
|
||||
'first_name LIKE' => $globalSearch,
|
||||
'last_name LIKE' => $globalSearch,
|
||||
'email LIKE' => $globalSearch
|
||||
]]);
|
||||
}
|
||||
|
||||
|
||||
//var_dump($communityUsers->toArray());
|
||||
if($communityUsers) {
|
||||
foreach($communityUsers as $u) {
|
||||
$pubkey_hex = bin2hex(stream_get_contents($u->public_key));
|
||||
$u->public_hex = $pubkey_hex;
|
||||
if(!isset($pubkeySorted[$pubkey_hex])) {
|
||||
$pubkeySorted[$pubkey_hex] = ['login' => [], 'community' => []];
|
||||
}
|
||||
array_push($pubkeySorted[$pubkey_hex]['community'], $u);
|
||||
}
|
||||
}
|
||||
|
||||
// detect states
|
||||
foreach($pubkeySorted as $pubhex => $user) {
|
||||
$finalUser = [];
|
||||
$state = 'account created';
|
||||
$color = 'secondary';
|
||||
$finalUser['balance'] = 0;
|
||||
$finalUser['pubkeyhex'] = $pubhex;
|
||||
$finalUser['created'] = null;
|
||||
|
||||
if(count($user['community']) == 1) {
|
||||
if(isset($user['community'][0]->state_balances) &&
|
||||
isset($user['community'][0]->state_balances[0]['amount'])) {
|
||||
$finalUser['balance'] = $user['community'][0]->state_balances[0]->amount;
|
||||
}
|
||||
}
|
||||
|
||||
if(count($user['login']) == 0) {
|
||||
$state = 'account not on login-server';
|
||||
$color = 'danger';
|
||||
if(count($user['community']) == 1) {
|
||||
$c_user = $user['community'][0];
|
||||
$finalUser['name'] = $c_user->first_name . ' ' . $c_user->last_name;
|
||||
$finalUser['first_name'] = $c_user->first_name;
|
||||
$finalUser['last_name'] = $c_user->last_name;
|
||||
$finalUser['email'] = $c_user->email;
|
||||
}
|
||||
} else if(count($user['login']) == 1) {
|
||||
if($user['login'][0]['email_checked'] == true) {
|
||||
$state = 'email activated';
|
||||
$color = 'primary';
|
||||
|
||||
if(count($user['community']) == 1) {
|
||||
$state = 'account copied to community';
|
||||
$color = 'success';
|
||||
//var_dump($user['community'][0]->state_balances[0]['amount']);
|
||||
}
|
||||
|
||||
} else {
|
||||
$state = 'email not activated';
|
||||
$color = 'warning';
|
||||
}
|
||||
|
||||
$l_user = $user['login'][0];
|
||||
$finalUser['name'] = $l_user['first_name'] . ' ' . $l_user['last_name'];
|
||||
$finalUser['first_name'] = $l_user['first_name'];
|
||||
$finalUser['last_name'] = $l_user['last_name'];
|
||||
$finalUser['email'] = $l_user['email'];
|
||||
$finalUser['created'] = new FrozenTime($l_user['created']);
|
||||
|
||||
} else {
|
||||
$state = 'account multiple times on login-server';
|
||||
$color = 'danger';
|
||||
}
|
||||
$finalUser['indicator'] = ['name' => $state, 'color' => $color];
|
||||
array_push($finalUserEntrys, $finalUser);
|
||||
}
|
||||
|
||||
foreach($emptyPubkeys as $user) {
|
||||
$finalUser = [];
|
||||
$state = 'account not on community server';
|
||||
$color = 'secondary';
|
||||
if($user['email_checked'] == false) {
|
||||
$state = 'email not activated';
|
||||
$color = 'warning';
|
||||
} else {
|
||||
$state = 'no keys';
|
||||
$color = 'warning';
|
||||
}
|
||||
$finalUser['balance'] = 0;
|
||||
$finalUser['pubkeyhex'] = '';
|
||||
$finalUser['name'] = $user['first_name'] . ' ' . $user['last_name'];
|
||||
$finalUser['first_name'] = $user['first_name'];
|
||||
$finalUser['last_name'] = $user['last_name'];
|
||||
$finalUser['email'] = $user['email'];
|
||||
$finalUser['created'] = new FrozenTime($user['created']);
|
||||
$finalUser['indicator'] = ['name' => $state, 'color' => $color];
|
||||
array_push($finalUserEntrys, $finalUser);
|
||||
}
|
||||
//var_dump($pubkeySorted);
|
||||
} else {
|
||||
$this->Flash->error(__('Something was invalid, please try again!'));
|
||||
}
|
||||
|
||||
$this->set('finalUserEntrys', $finalUserEntrys);
|
||||
}
|
||||
$timeUsed = microtime(true) - $startTime;
|
||||
$this->set('timeUsed', $timeUsed);
|
||||
}
|
||||
|
||||
public function ajaxCopyCommunityToLogin()
|
||||
{
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if($result !== true) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
if($user['role'] != 'admin') {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
|
||||
}
|
||||
if($this->request->is('post')) {
|
||||
$jsonData = $this->request->input('json_decode', true);
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
|
||||
}
|
||||
|
||||
public function ajaxCopyLoginToCommunity()
|
||||
{
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if($result !== true) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
if($user['role'] != 'admin') {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
|
||||
}
|
||||
|
||||
if($this->request->is('post')) {
|
||||
$jsonData = $this->request->input('json_decode', true);
|
||||
//$user = $jsonData['user'];
|
||||
//var_dump($jsonData);
|
||||
|
||||
$newStateUser = $this->StateUsers->newEntity();
|
||||
$this->StateUsers->patchEntity($newStateUser, $jsonData);
|
||||
$newStateUser->public_key = hex2bin($jsonData['pubkeyhex']);
|
||||
|
||||
if(!$this->StateUsers->save($newStateUser)) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'error by saving', 'details' => json_encode($newStateUser->errors())]);
|
||||
}
|
||||
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
|
||||
}
|
||||
|
||||
public function ajaxVerificationEmailResend()
|
||||
{
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if($result !== true) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
if($user['role'] != 'admin') {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
|
||||
}
|
||||
if($this->request->is('post')) {
|
||||
$jsonData = $this->request->input('json_decode', true);
|
||||
$email = $jsonData['email'];
|
||||
$session_id = $session->read('session_id');
|
||||
|
||||
return $this->returnJson($this->JsonRequestClient->sendRequest(json_encode([
|
||||
'session_id' => $session_id,
|
||||
'email' => $email
|
||||
]), '/adminEmailVerificationResend'));
|
||||
/*return $this->sendRequest(json_encode([
|
||||
'session_id' => $session_id,
|
||||
'search' => $searchString
|
||||
]), '/getUsers');*/
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
|
||||
}
|
||||
|
||||
public function ajaxGetUserEmailVerificationCode()
|
||||
{
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if($result !== true) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
if($user['role'] != 'admin') {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
|
||||
}
|
||||
if($this->request->is('post')) {
|
||||
$jsonData = $this->request->input('json_decode', true);
|
||||
$email = $jsonData['email'];
|
||||
$session_id = $session->read('session_id');
|
||||
|
||||
return $this->returnJson($this->JsonRequestClient->sendRequest(json_encode([
|
||||
'session_id' => $session_id,
|
||||
'email' => $email,
|
||||
'ask' => ['EmailVerificationCode.Register', 'loginServer.path']
|
||||
]), '/getUserInfos'));
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
|
||||
}
|
||||
|
||||
|
||||
public function ajaxDelete()
|
||||
{
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if($result !== true) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
if($user['role'] != 'admin') {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
|
||||
}
|
||||
|
||||
if($this->request->is('post')) {
|
||||
$jsonData = $this->request->input('json_decode', true);
|
||||
//$user = $jsonData['user'];
|
||||
//var_dump($jsonData);
|
||||
$pubkey = hex2bin($jsonData['pubkeyhex']);
|
||||
$stateUsers = $this->StateUsers->find('all')->where(['public_key' => $pubkey]);
|
||||
if($stateUsers->count() != 1) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid result count']);
|
||||
}
|
||||
|
||||
if ($this->StateUsers->delete($stateUsers->first())) {
|
||||
return $this->returnJson(['state' => 'success']);
|
||||
} else {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'error by deleting', 'details' => json_encode($stateUser->errors())]);
|
||||
}
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
|
||||
}
|
||||
|
||||
public function ajaxCountTransactions()
|
||||
{
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
if($result !== true) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
if($user['role'] != 'admin') {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'not an admin']);
|
||||
}
|
||||
|
||||
if($this->request->is('post')) {
|
||||
$jsonData = $this->request->input('json_decode', true);
|
||||
//$user = $jsonData['user'];
|
||||
//var_dump($jsonData);
|
||||
$pubkey = hex2bin($jsonData['pubkeyhex']);
|
||||
$stateUsers = $this->StateUsers
|
||||
->find('all')
|
||||
->where(['public_key' => $pubkey])
|
||||
->select(['id']);
|
||||
if($stateUsers->count() != 1) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid result count']);
|
||||
}
|
||||
$stateUser = $stateUsers->first();
|
||||
//var_dump($stateUser);
|
||||
//var_dump($stateUser->toArray());
|
||||
$creationsTable = TableRegistry::getTableLocator()->get('TransactionCreations');
|
||||
$creationTransactions = $creationsTable
|
||||
->find('all')
|
||||
->select(['id'])
|
||||
->where(['state_user_id' => $stateUser->id]);
|
||||
|
||||
$transferTable = TableRegistry::getTableLocator()->get('TransactionSendCoins');
|
||||
$transferTransactions = $transferTable
|
||||
->find('all')
|
||||
->where(['OR' => ['state_user_id' => $stateUser->id, 'receiver_user_id' => $stateUser->id]])
|
||||
->select(['state_user_id', 'receiver_user_id']);
|
||||
$counts = ['creation' => $creationTransactions->count(), 'receive' => 0, 'sended' => 0];
|
||||
foreach($transferTransactions as $transfer) {
|
||||
//var_dump($transfer);
|
||||
if($transfer->state_user_id == $stateUser->id) {
|
||||
$counts['sended']++;
|
||||
}
|
||||
if($transfer->receiver_user_id == $stateUser->id) {
|
||||
$counts['receive']++;
|
||||
}
|
||||
}
|
||||
return $this->returnJson(['state' => 'success', 'counts' => $counts]);
|
||||
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
|
||||
|
||||
}
|
||||
|
||||
public function ajaxGetCSFRToken($session_id)
|
||||
{
|
||||
if(!isset($session_id) || $session_id == 0) {
|
||||
$this->returnJson(['state' => 'error', 'msg' => 'no session id']);
|
||||
}
|
||||
|
||||
$client_ip = $this->request->clientIp();
|
||||
|
||||
$loginServer = Configure::read('LoginServer');
|
||||
$url = $loginServer['host'] . ':' . $loginServer['port'];
|
||||
|
||||
$http = new Client();
|
||||
$response = $http->get($url . '/login', ['session_id' => $session_id]);
|
||||
$json = $response->getJson();
|
||||
|
||||
if (isset($json) && count($json) > 0) {
|
||||
if ($json['state'] === 'success') {
|
||||
if($json['clientIP'] == $client_ip) {
|
||||
return $this->returnJson(['state' => 'success', 'csfr' => $this->request->getParam('_csrfToken')]);
|
||||
} else {
|
||||
return $this->returnJson([
|
||||
'state' => 'error',
|
||||
'msg' => 'client ip mismatch',
|
||||
'details' => ['login_server' => $json['clientIP'], 'caller' => $client_ip]]);
|
||||
}
|
||||
} else {
|
||||
return $this->returnJson($json);
|
||||
}
|
||||
} else {
|
||||
return $this->returnJson(['state' => 'error', 'invalid response form logins server']);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
|
||||
getField(vnode, 'receive'),
|
||||
|
||||
getField(vnode, 'sended'),
|
||||
|
||||
getField(vnode, 'creation'),
|
||||
*/
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id State User id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$stateUser = $this->StateUsers->get($id, [
|
||||
'contain' => [
|
||||
'StateBalances',
|
||||
'TransactionCreations' => ['Transactions'],
|
||||
'TransactionSendCoins' => ['Transactions', 'ReceiverUsers'],
|
||||
'TransactionReceivedCoins' => ['Transactions', 'StateUsers']]
|
||||
]);
|
||||
|
||||
$this->set('stateUser', $stateUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$stateUser = $this->StateUsers->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$stateUser = $this->StateUsers->patchEntity($stateUser, $this->request->getData());
|
||||
if ($this->StateUsers->save($stateUser)) {
|
||||
$this->Flash->success(__('The state user has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state user could not be saved. Please, try again.'));
|
||||
}
|
||||
$indices = $this->StateUsers->Indices->find('list', ['limit' => 200]);
|
||||
$stateGroups = $this->StateUsers->StateGroups->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateUser', 'indices', 'stateGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id State User 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)
|
||||
{
|
||||
$stateUser = $this->StateUsers->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$stateUser = $this->StateUsers->patchEntity($stateUser, $this->request->getData());
|
||||
if ($this->StateUsers->save($stateUser)) {
|
||||
$this->Flash->success(__('The state user has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state user could not be saved. Please, try again.'));
|
||||
}
|
||||
$indices = $this->StateUsers->Indices->find('list', ['limit' => 200]);
|
||||
$stateGroups = $this->StateUsers->StateGroups->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateUser', 'indices', 'stateGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id State User 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']);
|
||||
$stateUser = $this->StateUsers->get($id);
|
||||
if ($this->StateUsers->delete($stateUser)) {
|
||||
$this->Flash->success(__('The state user has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The state user could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,681 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
use Cake\ORM\TableRegistry;
|
||||
use Cake\Routing\Router;
|
||||
//use Cake\I18n\Number;
|
||||
use Cake\Http\Client;
|
||||
use Cake\Core\Configure;
|
||||
use Cake\I18n\FrozenDate;
|
||||
use Cake\Datasource\ConnectionManager;
|
||||
|
||||
use Model\Navigation\NaviHierarchy;
|
||||
use Model\Navigation\NaviHierarchyEntry;
|
||||
|
||||
use App\Form\CreationForm;
|
||||
// protobuf transactions
|
||||
//use Model\Messages\Gradido\TransactionCreation;
|
||||
use Model\Transactions\TransactionCreation;
|
||||
|
||||
/**
|
||||
* TransactionCreations Controller
|
||||
*
|
||||
* @property \App\Model\Table\TransactionCreationsTable $TransactionCreations
|
||||
*
|
||||
* @method \App\Model\Entity\TransactionCreation[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class TransactionCreationsController extends AppController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->loadComponent('GradidoNumber');
|
||||
$this->loadComponent('JsonRequestClient');
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
//$this->Auth->allow('create');
|
||||
$this->Auth->allow('ajaxCreate');
|
||||
$this->set(
|
||||
'naviHierarchy',
|
||||
(new NaviHierarchy())->
|
||||
add(new NaviHierarchyEntry(__('Startseite'), 'Dashboard', 'index', false))->add(new NaviHierarchyEntry(__('Gradido schöpfen'), 'TransactionCreations', 'create-multi', true))
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['Transactions', 'StateUsers']
|
||||
];
|
||||
$transactionCreations = $this->paginate($this->TransactionCreations);
|
||||
$identHashes = [];
|
||||
/*foreach ($transactionCreations as $creation) {
|
||||
$identHash = TransactionCreation::DRMakeStringHash($creation->state_user->email);
|
||||
$identHashes[$creation->state_user->id] = $identHash;
|
||||
}*/
|
||||
|
||||
//$this->set(compact('transactionCreations', 'identHashes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Transaction Creation id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$transactionCreation = $this->TransactionCreations->get($id, [
|
||||
'contain' => ['Transactions', 'StateUsers']
|
||||
]);
|
||||
|
||||
$this->set('transactionCreation', $transactionCreation);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$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');
|
||||
}
|
||||
$creationForm = new CreationForm();
|
||||
$transactionCreation = $this->TransactionCreations->newEntity();
|
||||
$transactionCreation->state_user_id = $user['id'];
|
||||
|
||||
// adding possible addresses + input field for copy
|
||||
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
$stateUsers = $stateUserTable->find('all')->contain(false);
|
||||
$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, 'email' => $stateUser->email]);
|
||||
//$stateUser->public_key
|
||||
}
|
||||
$timeUsed = microtime(true) - $startTime;
|
||||
$this->set(compact('transactionCreation', 'timeUsed', 'receiverProposal', 'creationForm'));
|
||||
|
||||
if ($this->request->is('post')) {
|
||||
$requestData = $this->request->getData();
|
||||
$mode = 'next';
|
||||
if (isset($requestData['add'])) {
|
||||
$mode = 'add';
|
||||
}
|
||||
if ($creationForm->validate($requestData)) {
|
||||
$pubKeyHex = '';
|
||||
$identHash = '';
|
||||
$amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']);
|
||||
$receiverIndex = intval($requestData['receiver'])-1;
|
||||
|
||||
if (count($receiverProposal) > $receiverIndex) {
|
||||
$pubKeyHex = $receiverProposal[$receiverIndex]['key'];
|
||||
//$identHash = TransactionCreation::DRMakeStringHash($receiverProposal[$receiverIndex]['email']);
|
||||
}
|
||||
$builderResult = TransactionCreation::build(
|
||||
$amountCent,
|
||||
$requestData['memo'],
|
||||
$pubKeyHex
|
||||
);
|
||||
if ($builderResult['state'] == 'success') {
|
||||
$user_balance = 0;
|
||||
if (isset($user['balance'])) {
|
||||
$user_balance = $user['balance'];
|
||||
}
|
||||
// $session_id, $base64Message, $user_balance = 0
|
||||
$requestResult = $this->JsonRequestClient->sendTransaction(
|
||||
$session->read('session_id'),
|
||||
base64_encode($builderResult['transactionBody']->serializeToString()),
|
||||
$user_balance
|
||||
);
|
||||
if ($requestResult['state'] != 'success') {
|
||||
$this->addAdminError('TransactionCreations', 'create', $requestResult, $user['id']);
|
||||
if ($requestResult['type'] == 'request error') {
|
||||
$this->Flash->error(__('Error by requesting LoginServer, please try again'));
|
||||
} else {
|
||||
$this->Flash->error(__('Error, please wait for the admin to fix it'));
|
||||
}
|
||||
} else {
|
||||
$json = $requestResult['data'];
|
||||
if ($json['state'] != 'success') {
|
||||
if ($json['msg'] == 'session not found') {
|
||||
$session->destroy();
|
||||
return $this->redirect($this->loginServerUrl . 'account', 303);
|
||||
} else {
|
||||
$this->addAdminError('TransactionCreations', 'create', $json, $user['id']);
|
||||
$this->Flash->error(__('Login Server Error, please wait for the admin to fix it'));
|
||||
}
|
||||
} else {
|
||||
$pendingTransactionCount = $session->read('Transactions.pending');
|
||||
if ($pendingTransactionCount == null) {
|
||||
$pendingTransactionCount = 1;
|
||||
} else {
|
||||
$pendingTransactionCount++;
|
||||
}
|
||||
$session->write('Transactions.pending', $pendingTransactionCount);
|
||||
if ($mode === 'next') {
|
||||
return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303);
|
||||
} else {
|
||||
$this->Flash->success(__('Transaction submitted for review.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->Flash->error(__('Building transaction failed'));
|
||||
}
|
||||
// */
|
||||
} else {
|
||||
$this->Flash->error(__('Something was invalid, please try again!'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function createMulti($page = 0)
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$this->viewBuilder()->setLayout('frontend');
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin();
|
||||
$limit = 200;
|
||||
if ($result !== true) {
|
||||
return $result;
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
|
||||
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
|
||||
$connection = ConnectionManager::get('default');
|
||||
$transactionActiveMonth = $connection->execute(
|
||||
'SELECT id, received FROM transactions '
|
||||
. 'where received >= date_sub(date_add(curdate(), interval 1 - day(curdate()) day), interval 2 month) '
|
||||
. 'AND '
|
||||
. 'received < date_add(date_add(curdate(), interval 1 - day(curdate()) day), interval 2 month) '
|
||||
. 'AND '
|
||||
. 'transaction_type_id = 1'
|
||||
)->fetchAll('assoc');
|
||||
$transactionActiveMonthSortedById = [];
|
||||
foreach ($transactionActiveMonth as $t) {
|
||||
$transactionActiveMonthSortedById[$t['id']] = $t['received'];
|
||||
}
|
||||
$firstDayLastMonth = new FrozenDate();
|
||||
$firstDayLastMonth = $firstDayLastMonth->day(1)->subMonth(1);
|
||||
$transactionsLastMonthTargeDate = $this->TransactionCreations
|
||||
->find('all')
|
||||
//->select(['state_user_id', 'target_date', 'amount'])
|
||||
->where(['EXTRACT(YEAR_MONTH FROM target_date) LIKE' => $firstDayLastMonth->format('Ym')])
|
||||
->group(['state_user_id'])
|
||||
->contain([]);
|
||||
$transactionsLastMonthTargeDate->select([
|
||||
'state_user_id',
|
||||
'sum_amount' => $transactionsLastMonthTargeDate->func()->sum('amount')
|
||||
]);
|
||||
|
||||
$transactionsLastMonthTargetDateSortedByStateUserId = [];
|
||||
foreach ($transactionsLastMonthTargeDate as $transactionCreation) {
|
||||
$transactionsLastMonthTargetDateSortedByStateUserId[$transactionCreation->state_user_id] = $transactionCreation->sum_amount;
|
||||
}
|
||||
|
||||
$requestData = $this->request->getData();
|
||||
if ($this->request->is('post') &&
|
||||
isset($requestData['searchButton']) &&
|
||||
isset($requestData['searchText']) &&
|
||||
!empty($requestData['searchText'])
|
||||
) {
|
||||
$mode = 'search';
|
||||
$page = 0;
|
||||
$this->log("search for text: ".$requestData['searchText'], 'debug');
|
||||
$stateUsers = $stateUserTable
|
||||
->find('all')
|
||||
->select(['id', 'first_name', 'last_name', 'email'])
|
||||
->order(['first_name', 'last_name'])
|
||||
->where(
|
||||
['AND' => [
|
||||
'disabled' => 0,
|
||||
'OR' => [
|
||||
'LOWER(first_name) LIKE' => '%'.strtolower($requestData['searchText']).'%',
|
||||
'LOWER(last_name) LIKE' => '%'.strtolower($requestData['searchText']).'%',
|
||||
'LOWER(email) LIKE' => '%'.strtolower($requestData['searchText']).'%'
|
||||
]
|
||||
]
|
||||
]
|
||||
)
|
||||
->contain(['TransactionCreations' => [
|
||||
'fields' => [
|
||||
'TransactionCreations.amount',
|
||||
'TransactionCreations.transaction_id',
|
||||
'TransactionCreations.state_user_id'
|
||||
]
|
||||
]]);
|
||||
$this->log("search query: ".$stateUsers, 'debug');
|
||||
} else {
|
||||
$stateUsers = $stateUserTable
|
||||
->find('all')
|
||||
->select(['id', 'first_name', 'last_name', 'email'])
|
||||
//->order(['id'])
|
||||
->where(['disabled' => 0])
|
||||
->order(['first_name', 'last_name'])
|
||||
->contain(['TransactionCreations' => [
|
||||
'fields' => [
|
||||
'TransactionCreations.amount',
|
||||
'TransactionCreations.transaction_id',
|
||||
'TransactionCreations.state_user_id'
|
||||
]
|
||||
]]);
|
||||
}
|
||||
|
||||
//var_dump($stateUsers->toArray());
|
||||
$possibleReceivers = [];
|
||||
$countUsers = 0;
|
||||
foreach ($stateUsers as $i => $stateUser) {
|
||||
$countUsers++;
|
||||
if ($i < $page * $limit || $i >= ($page + 1) * $limit) {
|
||||
continue;
|
||||
}
|
||||
$sumAmount = 0;
|
||||
$sumAmount2 = 0;
|
||||
if (isset($transactionsLastMonthTargetDateSortedByStateUserId[$stateUser->id])) {
|
||||
$sumAmount2 = $transactionsLastMonthTargetDateSortedByStateUserId[$stateUser->id];
|
||||
}
|
||||
foreach ($stateUser->transaction_creations as $transactionCreation) {
|
||||
//var_dump($transactionCreation);
|
||||
if (isset($transactionActiveMonthSortedById[$transactionCreation->transaction_id])) {
|
||||
$sumAmount += $transactionCreation->amount;
|
||||
}
|
||||
}
|
||||
|
||||
//if($sumAmount < 20000000) {
|
||||
array_push($possibleReceivers, [
|
||||
'name' => $stateUser->first_name . ' ' . $stateUser->last_name,
|
||||
'id' => $stateUser->id,
|
||||
'email' => $stateUser->email,
|
||||
'amount' => $sumAmount,
|
||||
'amount2' => $sumAmount2
|
||||
]);
|
||||
/*} else {
|
||||
$this->Flash->error(__('Creation above 2.000 GDD for 2 last two month'));
|
||||
}*/
|
||||
}
|
||||
// usort($possibleReceivers, function ($a, $b) {
|
||||
// return (strtolower($a['name']) <=> strtolower($b['name']));
|
||||
// });
|
||||
// -> replaced by SQL "order by" above
|
||||
$creationForm = new CreationForm();
|
||||
|
||||
$timeUsed = microtime(true) - $startTime;
|
||||
$this->set(compact('timeUsed', 'stateUsers', 'creationForm', 'possibleReceivers'));
|
||||
|
||||
$this->set('firstDayLastMonth', $firstDayLastMonth);
|
||||
$this->set('activeUser', $user);
|
||||
$this->set('creationForm', $creationForm);
|
||||
$this->set('transactionExecutingCount', $session->read('Transactions.executing'));
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
$this->set('countUsers', $countUsers);
|
||||
$this->set('limit', $limit);
|
||||
$this->set('page', $page);
|
||||
|
||||
if ($this->request->is('post') && (!isset($mode) || !($mode === 'search'))) {
|
||||
$this->log("real POST", 'debug');
|
||||
$mode = 'next';
|
||||
if (isset($requestData['add'])) {
|
||||
$mode = 'add';
|
||||
}
|
||||
//echo "mode: $mode<br>";
|
||||
$memo = $requestData['memo'];
|
||||
$amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']);
|
||||
//$targetDate = $requestData['target_date'];
|
||||
if (!isset($requestData['user']) || count($requestData['user']) == 0) {
|
||||
$this->Flash->error(__('No user selected'));
|
||||
} else {
|
||||
$users = $requestData['user'];
|
||||
$pendingTransactionCount = $session->read('Transactions.pending');
|
||||
if ($pendingTransactionCount == null) {
|
||||
$pendingTransactionCount = 0;
|
||||
}
|
||||
if (isset($requestData['user_pending'])) {
|
||||
$pendings = $requestData['user_pending'];
|
||||
} else {
|
||||
$pendings = [];
|
||||
}
|
||||
$receiverUsers = $stateUserTable->find('all')
|
||||
->where(['id IN' => array_keys($users)])
|
||||
->select(['public_key', 'email', 'id'])
|
||||
->contain(false);
|
||||
|
||||
foreach ($receiverUsers as $receiverUser) {
|
||||
$localAmountCent = $amountCent;
|
||||
//$localTargetDate = $targetDate;
|
||||
$id = $receiverUser->id;
|
||||
if ($requestData['user_amount'][$id] != '') {
|
||||
$localAmountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['user_amount'][$id]);
|
||||
}
|
||||
if (isset($requestData['user_target_date']) && isset($requestData['user_target_date'][$id])) {
|
||||
$localTargetDate = $requestData['user_target_date'][$id];
|
||||
}
|
||||
if (isset($pendings[$id])) {
|
||||
$pendings[$id] += $localAmountCent;
|
||||
} else {
|
||||
$pendings[$id] = $localAmountCent;
|
||||
}
|
||||
$pubKeyHex = bin2hex(stream_get_contents($receiverUser->public_key));
|
||||
$requestAnswear = $this->JsonRequestClient->sendRequest(json_encode([
|
||||
'session_id' => $session->read('session_id'),
|
||||
'email' => $receiverUser->email,
|
||||
'ask' => ['user.identHash']
|
||||
]), '/getUserInfos');
|
||||
|
||||
$identHash = 0;
|
||||
if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) {
|
||||
$identHash = $requestAnswear['data']['userData']['identHash'];
|
||||
} else {
|
||||
$this->Flash->error(__('Error by requesting LoginServer, please try again'));
|
||||
}
|
||||
|
||||
//$identHash = TransactionCreation::DRMakeStringHash($receiverUser->email);
|
||||
$localTargetDateFrozen = FrozenDate::now();
|
||||
$localTargetDateFrozen = $localTargetDateFrozen
|
||||
->year($localTargetDate['year'])
|
||||
->month($localTargetDate['month'])
|
||||
->day($localTargetDate['day']);
|
||||
|
||||
$requestAnswear = $this->JsonRequestClient->sendRequest(json_encode([
|
||||
'session_id' => $session->read('session_id'),
|
||||
'transaction_type' => 'creation',
|
||||
'memo' => $memo,
|
||||
'amount' => $localAmountCent,
|
||||
'target_pubkey' => $pubKeyHex,
|
||||
'target_date' => $localTargetDateFrozen,
|
||||
'blockchain_type' => $this->blockchainType
|
||||
]), '/createTransaction');
|
||||
|
||||
if('success' != $requestAnswear['state']) {
|
||||
$this->addAdminError('TransactionCreations', 'createMulti', $requestAnswear, $user['id']);
|
||||
if ($requestResult['type'] == 'request error') {
|
||||
$this->Flash->error(__('Error by requesting LoginServer, please try again'));
|
||||
} else {
|
||||
$this->Flash->error(__('Error, please wait for the admin to fix it'));
|
||||
}
|
||||
}
|
||||
if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) {
|
||||
$pendingTransactionCount++;
|
||||
//echo "pending transaction count: $pendingTransactionCount<br>";
|
||||
} else {
|
||||
/*
|
||||
* if request contain unknown parameter format, shouldn't happen't at all
|
||||
* {"state": "error", "msg": "parameter format unknown"}
|
||||
* if json parsing failed
|
||||
* {"state": "error", "msg": "json exception", "details":"exception text"}
|
||||
* if session_id is zero or not set
|
||||
* {"state": "error", "msg": "session_id invalid"}
|
||||
* if session id wasn't found on login server, if server was restartet or user logged out (also per timeout, default: 15 minutes)
|
||||
* {"state": "error", "msg": "session not found"}
|
||||
* if session hasn't active user, shouldn't happen't at all, login-server should be checked if happen
|
||||
* {"state": "code error", "msg":"user is zero"}
|
||||
* if transaction type not known
|
||||
* {"state": "error", "msg":"transaction_type unknown"}
|
||||
* if receiver wasn't known to Login-Server
|
||||
* {"state": "not found", "msg":"receiver not found"}
|
||||
* if receiver account disabled, and therefor cannto receive any coins
|
||||
* {"state": "disabled", "msg":"receiver is disabled"}
|
||||
* if amount is invalid in creation
|
||||
* {"state": "invalid parameter", "msg":"invalid amount", "details":"GDD amount in GDD cent ]0,10000000]"}
|
||||
* if transaction was okay and will be further proccessed
|
||||
* {"state":"success"}
|
||||
*/
|
||||
$answear_data = $requestAnswear['data'];
|
||||
if($answear_data['state'] === 'error') {
|
||||
if($answear_data['msg'] === 'session_id invalid' || $answear_data['msg'] === 'session not found') {
|
||||
$this->Flash->error(__('Fehler mit der Session, bitte logge dich erneut ein!'));
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
return;
|
||||
}
|
||||
if($answear_data['msg'] === 'user not in group') {
|
||||
$this->Flash->error(__('Fehler, Benutzer gehört zu einer anderen Gruppe!'));
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
return;
|
||||
}
|
||||
} else if($answear_data['state'] === 'not found' && $answear_data['msg'] === 'receiver not found') {
|
||||
$this->Flash->error(__('Der Empfänger wurde nicht auf dem Login-Server gefunden, hat er sein Konto schon angelegt?'));
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
return;
|
||||
} else if($answear_data['state'] === 'disabled') {
|
||||
$this->Flash->error(__('Der Empfänger ist deaktiviert, daher können ihm zurzeit keine Gradidos gesendet werden.'));
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
return;
|
||||
} else if($answear_data['msg'] === 'invalid amount') {
|
||||
$this->Flash->error(__('Der Betrag ist ungültig, er muss größer als 0 und <= 1000 sein.'));
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
return;
|
||||
} else {
|
||||
$this->Flash->error(__('Unbehandelter Fehler: ') . json_encode($answear_data));
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*echo "pendings: ";
|
||||
var_dump($pendings);
|
||||
echo "<br>";*/
|
||||
foreach ($possibleReceivers as $i => $possibleReceiver) {
|
||||
$id = $possibleReceiver['id'];
|
||||
if (isset($pendings[$id])) {
|
||||
$possibleReceivers[$i]['pending'] = $pendings[$id];
|
||||
}
|
||||
}
|
||||
$this->set('possibleReceivers', $possibleReceivers);
|
||||
if ($pendingTransactionCount > 0) {
|
||||
$user_balance = 0;
|
||||
if (isset($user['balance'])) {
|
||||
$user_balance = $user['balance'];
|
||||
}
|
||||
$session->write('Transactions.pending', $pendingTransactionCount);
|
||||
|
||||
if ($mode === 'next') {
|
||||
return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303);
|
||||
} else {
|
||||
$this->Flash->success(__('Transaction submitted for review.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function ajaxCreate()
|
||||
{
|
||||
if ($this->request->is('post')) {
|
||||
$startTime = microtime(true);
|
||||
$jsonData = $this->request->input('json_decode', true);
|
||||
$session_id = $jsonData['session_id'];
|
||||
if(!isset($jsonData['session_id']) || intval($jsonData['session_id']) == 0) {
|
||||
return $this->returnJson(['state' => 'parameter missing', 'msg' => 'invalid session id']);
|
||||
}
|
||||
|
||||
$login_result = $this->requestLogin($session_id, false);
|
||||
if($login_result !== true) {
|
||||
return $this->returnJson($login_result);
|
||||
}
|
||||
$session = $this->getRequest()->getSession();
|
||||
$user = $session->read('StateUser');
|
||||
|
||||
$memo = '';
|
||||
if(isset($jsonData['memo'])) {
|
||||
$memo = $jsonData['memo'];
|
||||
}
|
||||
$auto_sign = true;
|
||||
if(isset($jsonData['auto_sign'])) {
|
||||
$auto_sign = $jsonData['auto_sign'];
|
||||
}
|
||||
if(!isset($jsonData['amount']) || intval($jsonData['amount']) <= 0) {
|
||||
return $this->returnJson(['state' => 'parameter missing', 'msg' => 'amount not set or <= 0']);
|
||||
}
|
||||
if(!isset($jsonData['email'])) {
|
||||
return $this->returnJson(['state' => 'parameter missing', 'msg' => 'no receiver email set']);
|
||||
}
|
||||
$amount = intval($jsonData['amount']);
|
||||
if($amount > 10000000) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'amount is to big']);
|
||||
}
|
||||
if($amount <= 0) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'amount must be > 0']);
|
||||
}
|
||||
if(!isset($jsonData['target_date'])) {
|
||||
return $this->returnJson(['state' => 'parameter missing', 'msg' => 'target_date not found']);
|
||||
}
|
||||
//$targetDate = $requestData['target_date'];
|
||||
$stateUserTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
$requestAnswear = $this->JsonRequestClient->sendRequest(json_encode([
|
||||
'session_id' => $session_id,
|
||||
'email' => $jsonData['email'],
|
||||
'ask' => ['user.pubkeyhex', 'user.disabled', 'user.identHash']
|
||||
]), '/getUserInfos');
|
||||
$receiverPubKeyHex = '';
|
||||
if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) {
|
||||
// will be allways 64 byte long, even if it is empty
|
||||
$receiverPubKeyHex = $requestAnswear['data']['userData']['pubkeyhex'];
|
||||
} else {
|
||||
return $this->returnJson([
|
||||
'state' => 'error',
|
||||
'msg' => 'receiver email not found on login-server',
|
||||
'details' => $requestAnswear,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
}
|
||||
if($requestAnswear['data']['userData']['disabled']) {
|
||||
return $this->returnJson([
|
||||
'state' => 'error',
|
||||
'msg' => 'receiver is currently disabled, he cannot receive creations',
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
}
|
||||
|
||||
$builderResult = TransactionCreation::build(
|
||||
$amount,
|
||||
$memo,
|
||||
$receiverPubKeyHex,
|
||||
new FrozenDate($jsonData['target_date'])
|
||||
);
|
||||
$transaction_base64 = '';
|
||||
if ($builderResult['state'] == 'success') {
|
||||
// todo: maybe use sodium base 64 encoder to make sure it can be readed from login-server
|
||||
$transaction_base64 = base64_encode($builderResult['transactionBody']->serializeToString());
|
||||
}
|
||||
|
||||
$requestResult = $this->JsonRequestClient->sendTransaction(
|
||||
$session_id,
|
||||
$transaction_base64,
|
||||
$user['balance'],
|
||||
$auto_sign,
|
||||
$this->blockchainType
|
||||
);
|
||||
if ($requestResult['state'] != 'success') {
|
||||
$msg = 'error returned from login server';
|
||||
if ($requestResult['type'] === 'request error') {
|
||||
$msg = 'login server couldn\'t reached';
|
||||
}
|
||||
//$this->Flash->error(__('Error, please wait for the admin to fix it'));
|
||||
return $this->returnJson([
|
||||
'state' => 'request error',
|
||||
'msg' => $msg,
|
||||
'details' => $requestResult,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
} else {
|
||||
$json = $requestResult['data'];
|
||||
if ($json['state'] != 'success') {
|
||||
if ($json['msg'] == 'session not found') {
|
||||
$session->destroy();
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'session not found', 'timeUsed' => microtime(true) - $startTime]);
|
||||
} else {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'login server error', 'details' => $json, 'timeUsed' => microtime(true) - $startTime]);
|
||||
}
|
||||
} else {
|
||||
return $this->returnJson(['state' => 'success', 'timeUsed' => microtime(true) - $startTime]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
|
||||
$transactionCreation = $this->TransactionCreations->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$transactionCreation = $this->TransactionCreations->patchEntity($transactionCreation, $this->request->getData());
|
||||
if ($this->TransactionCreations->save($transactionCreation)) {
|
||||
$this->Flash->success(__('The transaction creation has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The transaction creation could not be saved. Please, try again.'));
|
||||
}
|
||||
$transactions = $this->TransactionCreations->Transactions->find('list', ['limit' => 200]);
|
||||
$stateUsers = $this->TransactionCreations->StateUsers->find('list', ['limit' => 200]);
|
||||
$this->set(compact('transactionCreation', 'transactions', 'stateUsers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Transaction Creation 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)
|
||||
{
|
||||
$transactionCreation = $this->TransactionCreations->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$transactionCreation = $this->TransactionCreations->patchEntity($transactionCreation, $this->request->getData());
|
||||
if ($this->TransactionCreations->save($transactionCreation)) {
|
||||
$this->Flash->success(__('The transaction creation has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The transaction creation could not be saved. Please, try again.'));
|
||||
}
|
||||
$transactions = $this->TransactionCreations->Transactions->find('list', ['limit' => 200]);
|
||||
$stateUsers = $this->TransactionCreations->StateUsers->find('list', ['limit' => 200]);
|
||||
$this->set(compact('transactionCreation', 'transactions', 'stateUsers'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Transaction Creation 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']);
|
||||
$transactionCreation = $this->TransactionCreations->get($id);
|
||||
if ($this->TransactionCreations->delete($transactionCreation)) {
|
||||
$this->Flash->success(__('The transaction creation has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The transaction creation could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* TransactionGroupAddaddress Controller
|
||||
*
|
||||
* @property \App\Model\Table\TransactionGroupAddaddressTable $TransactionGroupAddaddress
|
||||
*
|
||||
* @method \App\Model\Entity\TransactionGroupAddaddres[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class TransactionGroupAddaddressController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['Transactions', 'AddressTypes']
|
||||
];
|
||||
$transactionGroupAddaddress = $this->paginate($this->TransactionGroupAddaddress);
|
||||
|
||||
$this->set(compact('transactionGroupAddaddress'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Transaction Group Addaddres id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$transactionGroupAddaddres = $this->TransactionGroupAddaddress->get($id, [
|
||||
'contain' => ['Transactions', 'AddressTypes']
|
||||
]);
|
||||
|
||||
$this->set('transactionGroupAddaddres', $transactionGroupAddaddres);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$transactionGroupAddaddres = $this->TransactionGroupAddaddress->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$transactionGroupAddaddres = $this->TransactionGroupAddaddress->patchEntity($transactionGroupAddaddres, $this->request->getData());
|
||||
if ($this->TransactionGroupAddaddress->save($transactionGroupAddaddres)) {
|
||||
$this->Flash->success(__('The transaction group addaddres has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The transaction group addaddres could not be saved. Please, try again.'));
|
||||
}
|
||||
$transactions = $this->TransactionGroupAddaddress->Transactions->find('list', ['limit' => 200]);
|
||||
$addressTypes = $this->TransactionGroupAddaddress->AddressTypes->find('list', ['limit' => 200]);
|
||||
$this->set(compact('transactionGroupAddaddres', 'transactions', 'addressTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Transaction Group Addaddres 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)
|
||||
{
|
||||
$transactionGroupAddaddres = $this->TransactionGroupAddaddress->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$transactionGroupAddaddres = $this->TransactionGroupAddaddress->patchEntity($transactionGroupAddaddres, $this->request->getData());
|
||||
if ($this->TransactionGroupAddaddress->save($transactionGroupAddaddres)) {
|
||||
$this->Flash->success(__('The transaction group addaddres has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The transaction group addaddres could not be saved. Please, try again.'));
|
||||
}
|
||||
$transactions = $this->TransactionGroupAddaddress->Transactions->find('list', ['limit' => 200]);
|
||||
$addressTypes = $this->TransactionGroupAddaddress->AddressTypes->find('list', ['limit' => 200]);
|
||||
$this->set(compact('transactionGroupAddaddres', 'transactions', 'addressTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Transaction Group Addaddres 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']);
|
||||
$transactionGroupAddaddres = $this->TransactionGroupAddaddress->get($id);
|
||||
if ($this->TransactionGroupAddaddress->delete($transactionGroupAddaddres)) {
|
||||
$this->Flash->success(__('The transaction group addaddres has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The transaction group addaddres could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* TransactionGroupAllowtrades Controller
|
||||
*
|
||||
* @property \App\Model\Table\TransactionGroupAllowtradesTable $TransactionGroupAllowtrades
|
||||
*
|
||||
* @method \App\Model\Entity\TransactionGroupAllowtrade[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class TransactionGroupAllowtradesController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['Transactions', 'Groups']
|
||||
];
|
||||
$transactionGroupAllowtrades = $this->paginate($this->TransactionGroupAllowtrades);
|
||||
|
||||
$this->set(compact('transactionGroupAllowtrades'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Transaction Group Allowtrade id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$transactionGroupAllowtrade = $this->TransactionGroupAllowtrades->get($id, [
|
||||
'contain' => ['Transactions', 'Groups']
|
||||
]);
|
||||
|
||||
$this->set('transactionGroupAllowtrade', $transactionGroupAllowtrade);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$transactionGroupAllowtrade = $this->TransactionGroupAllowtrades->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$transactionGroupAllowtrade = $this->TransactionGroupAllowtrades->patchEntity($transactionGroupAllowtrade, $this->request->getData());
|
||||
if ($this->TransactionGroupAllowtrades->save($transactionGroupAllowtrade)) {
|
||||
$this->Flash->success(__('The transaction group allowtrade has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The transaction group allowtrade could not be saved. Please, try again.'));
|
||||
}
|
||||
$transactions = $this->TransactionGroupAllowtrades->Transactions->find('list', ['limit' => 200]);
|
||||
$groups = $this->TransactionGroupAllowtrades->Groups->find('list', ['limit' => 200]);
|
||||
$this->set(compact('transactionGroupAllowtrade', 'transactions', 'groups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Transaction Group Allowtrade 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)
|
||||
{
|
||||
$transactionGroupAllowtrade = $this->TransactionGroupAllowtrades->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$transactionGroupAllowtrade = $this->TransactionGroupAllowtrades->patchEntity($transactionGroupAllowtrade, $this->request->getData());
|
||||
if ($this->TransactionGroupAllowtrades->save($transactionGroupAllowtrade)) {
|
||||
$this->Flash->success(__('The transaction group allowtrade has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The transaction group allowtrade could not be saved. Please, try again.'));
|
||||
}
|
||||
$transactions = $this->TransactionGroupAllowtrades->Transactions->find('list', ['limit' => 200]);
|
||||
$groups = $this->TransactionGroupAllowtrades->Groups->find('list', ['limit' => 200]);
|
||||
$this->set(compact('transactionGroupAllowtrade', 'transactions', 'groups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Transaction Group Allowtrade 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']);
|
||||
$transactionGroupAllowtrade = $this->TransactionGroupAllowtrades->get($id);
|
||||
if ($this->TransactionGroupAllowtrades->delete($transactionGroupAllowtrade)) {
|
||||
$this->Flash->success(__('The transaction group allowtrade has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The transaction group allowtrade could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
/**
|
||||
* TransactionGroupCreates Controller
|
||||
*
|
||||
* @property \App\Model\Table\TransactionGroupCreatesTable $TransactionGroupCreates
|
||||
*
|
||||
* @method \App\Model\Entity\TransactionGroupCreate[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class TransactionGroupCreatesController extends AppController
|
||||
{
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['Transactions', 'StateGroups']
|
||||
];
|
||||
$transactionGroupCreates = $this->paginate($this->TransactionGroupCreates);
|
||||
|
||||
$this->set(compact('transactionGroupCreates'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id Transaction Group Create id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$transactionGroupCreate = $this->TransactionGroupCreates->get($id, [
|
||||
'contain' => ['Transactions', 'StateGroups']
|
||||
]);
|
||||
|
||||
$this->set('transactionGroupCreate', $transactionGroupCreate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$transactionGroupCreate = $this->TransactionGroupCreates->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$transactionGroupCreate = $this->TransactionGroupCreates->patchEntity($transactionGroupCreate, $this->request->getData());
|
||||
if ($this->TransactionGroupCreates->save($transactionGroupCreate)) {
|
||||
$this->Flash->success(__('The transaction group create has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The transaction group create could not be saved. Please, try again.'));
|
||||
}
|
||||
$transactions = $this->TransactionGroupCreates->Transactions->find('list', ['limit' => 200]);
|
||||
$stateGroups = $this->TransactionGroupCreates->StateGroups->find('list', ['limit' => 200]);
|
||||
$this->set(compact('transactionGroupCreate', 'transactions', 'stateGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id Transaction Group Create 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)
|
||||
{
|
||||
$transactionGroupCreate = $this->TransactionGroupCreates->get($id, [
|
||||
'contain' => []
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$transactionGroupCreate = $this->TransactionGroupCreates->patchEntity($transactionGroupCreate, $this->request->getData());
|
||||
if ($this->TransactionGroupCreates->save($transactionGroupCreate)) {
|
||||
$this->Flash->success(__('The transaction group create has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The transaction group create could not be saved. Please, try again.'));
|
||||
}
|
||||
$transactions = $this->TransactionGroupCreates->Transactions->find('list', ['limit' => 200]);
|
||||
$stateGroups = $this->TransactionGroupCreates->StateGroups->find('list', ['limit' => 200]);
|
||||
$this->set(compact('transactionGroupCreate', 'transactions', 'stateGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id Transaction Group Create 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']);
|
||||
$transactionGroupCreate = $this->TransactionGroupCreates->get($id);
|
||||
if ($this->TransactionGroupCreates->delete($transactionGroupCreate)) {
|
||||
$this->Flash->success(__('The transaction group create has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The transaction group create could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
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