Merge branch 'master' into 1319-email-optin

This commit is contained in:
Hannes Heine 2022-02-03 09:56:22 +01:00 committed by GitHub
commit 0d11ad5c3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
589 changed files with 4309 additions and 52444 deletions

View File

@ -106,45 +106,6 @@ jobs:
name: docker-database-production_up
path: /tmp/database_up.tar
##############################################################################
# JOB: DOCKER BUILD PRODUCTION LOGIN SERVER ##################################
##############################################################################
build_production_login_server:
name: Docker Build Production - Login Server
runs-on: ubuntu-latest
#needs: [nothing]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: recursive
##########################################################################
# 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
##########################################################################
# LOGIN SERVER ###########################################################
##########################################################################
- name: Login Server | Build `production` image
run: |
docker build -t "gradido/login_server:latest" -t "gradido/login_server:production" -t "gradido/login_server:${VERSION}" -t "gradido/login_server:${BUILD_VERSION}" login_server/
docker save "gradido/login_server" > /tmp/login_server.tar
- name: Upload Artifact
uses: actions/upload-artifact@v2
with:
name: docker-login-server-production
path: /tmp/login_server.tar
##############################################################################
# JOB: DOCKER BUILD PRODUCTION COMMUNITY SERVER ##############################
##############################################################################
@ -262,7 +223,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_login_server, build_production_community_server, build_production_mariadb, build_production_nginx]
needs: [build_production_frontend, build_production_backend, build_production_database_up, build_production_community_server, build_production_mariadb, build_production_nginx]
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
@ -296,13 +257,6 @@ jobs:
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/database_up.tar
- name: Download Docker Image (Login Server)
uses: actions/download-artifact@v2
with:
name: docker-login-server-production
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/login_server.tar
- name: Download Docker Image (Community Server)
uses: actions/download-artifact@v2
with:
@ -335,8 +289,6 @@ jobs:
run: docker push --all-tags gradido/backend
- name: Push database
run: docker push --all-tags gradido/database
- name: Push login_server
run: docker push --all-tags gradido/login_server
- name: Push community_server
run: docker push --all-tags gradido/community_server
- name: Push MariaDB

View File

@ -107,28 +107,6 @@ jobs:
name: docker-database-test_up
path: /tmp/database_up.tar
##############################################################################
# JOB: DOCKER BUILD TEST LOGIN SERVER ########################################
##############################################################################
build_test_login_server:
name: Docker Build Test - Login Server
runs-on: ubuntu-latest
#needs: [nothing]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: true
##########################################################################
# BUILD LOGIN SERVER DOCKER IMAGE ########################################
##########################################################################
- name: login server | Build `release` image
run: |
docker build -t "gradido/login_server:release" -f ./login_server/Dockerfile login_server/
##############################################################################
# JOB: DOCKER BUILD TEST COMMUNITY SERVER ####################################
##############################################################################
@ -470,7 +448,7 @@ jobs:
report_name: Coverage Admin Interface
type: lcov
result_path: ./coverage/lcov.info
min_coverage: 78
min_coverage: 81
token: ${{ github.token }}
##############################################################################
@ -531,73 +509,6 @@ jobs:
min_coverage: 38
token: ${{ github.token }}
##############################################################################
# JOB: UNIT TEST LOGIN-SERVER ###############################################
##############################################################################
unit_test_login_server:
name: Unit tests - Login-Server
runs-on: ubuntu-latest
needs: []
services:
mariadb:
image: gradido/mariadb:test
env:
MARIADB_ALLOW_EMPTY_PASSWORD: 1
MARIADB_USER: root
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping"
--health-interval=6s
--health-timeout=3s
--health-retries=4
steps:
# - name: Debug service
# run: echo "$(docker ps)"
#- name: Debug container choosing script
# run: echo "$(docker container ls | grep mariadb | awk '{ print $1 }')"
- 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
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: true
# Database migration
- name: Start database migration
run: |
docker build --target production_up -t "gradido/database:production_up" database/
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
##########################################################################
# Build Login-Server Test Docker image ###################################
##########################################################################
- name: login server | Build `test` image
run: |
docker build -t "gradido/login_server:test" -f ./login_server/Dockerfiles/ubuntu/Dockerfile.test login_server/
##########################################################################
# UNIT TESTS BACKEND LOGIN-SERVER #######################################
##########################################################################
- name: Login-Server | Unit tests
run: |
docker run --network container:$(docker container ls | grep mariadb | awk '{ print $1 }') -v ~/coverage:/code/build_cov/coverage -v $(pwd)/configs/login_server:/etc/grd_login gradido/login_server:test
cp -r ~/coverage ./coverage
##########################################################################
# COVERAGE CHECK BACKEND LOGIN-SERVER ####################################
##########################################################################
- name: backend login | Coverage check
uses: webcraftmedia/coverage-check-action@master
with:
report_name: Coverage Backend Login
type: lcov
result_path: ./coverage/coverage.info
min_coverage: 34
token: ${{ github.token }}
##############################################################################
# JOB: UNIT TEST COMMUNITY-SERVER ###########################################
##############################################################################
@ -627,11 +538,6 @@ jobs:
- name: get database migration container id
run: echo "::set-output name=id::$(docker container ls | grep database | awk '{ print $1 }')"
id: database_container
- name: Start Login-Server
run: docker run --network ${{ steps.network.outputs.id }} --name=login-server -d gradido/login_server:with-config
- name: get login-server container id
run: echo "::set-output name=id::$(docker container ls | grep login_server | awk '{ print $1 }')"
id: login_server_container
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
@ -647,9 +553,6 @@ jobs:
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/community_server.tar
# for debugging login-server
- name: check login-server
run: docker logs ${{ steps.login_server_container.outputs.id }}
- name: check mariadb
run: docker logs ${{ steps.mariadb_container.outputs.id }}
- name: check migration

28
.gitmodules vendored
View File

@ -3,34 +3,6 @@
url = https://github.com/gradido/gn.git
branch = master
[submodule "login_server/dependencies/tinf"]
path = login_server/dependencies/tinf
url = https://github.com/jibsen/tinf.git
[submodule "login_server/dependencies/mariadb-connector-c"]
path = login_server/dependencies/mariadb-connector-c
url = https://github.com/MariaDB/mariadb-connector-c.git
[submodule "login_server/src/proto"]
path = login_server/src/proto
url = https://github.com/gradido/gradido_protocol.git
[submodule "login_server/dependencies/spirit-po"]
path = login_server/dependencies/spirit-po
url = https://github.com/cbeck88/spirit-po.git
[submodule "login_server/dependencies/poco"]
path = login_server/dependencies/poco
url = https://github.com/pocoproject/poco.git
[submodule "login_server/dependencies/cmake-modules"]
path = login_server/dependencies/cmake-modules
url = https://github.com/viaduck/cmake-modules.git
[submodule "community_server/src/protobuf"]
path = community_server/src/protobuf
url = https://github.com/gradido/gradido_protocol.git
[submodule "login_server/dependencies/libsodium"]
path = login_server/dependencies/libsodium
url = https://github.com/jedisct1/libsodium.git
[submodule "login_server/src/proto"]
path = login_server/src/proto
url = https://github.com/gradido/gradido_protocol.git
[submodule "login_server/dependencies/protobuf"]
path = login_server/dependencies/protobuf
url = https://github.com/protocolbuffers/protobuf.git

View File

@ -60,8 +60,7 @@ docker-compose -f docker-compose.yml up
- [frontend](./frontend) Wallet frontend
- [backend](./backend) GraphQL & Business logic backend
- [mariadb](./mariadb) Database backend
- [login_server](./login_server) User credential storage & business logic backend
- [community_server](./community_server/) Business logic 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.

View File

@ -12,7 +12,7 @@
"dev": "yarn run serve",
"build": "vue-cli-service build",
"lint": "eslint --ext .js,.vue .",
"test": "jest --coverage",
"test": "TZ=UTC jest --coverage",
"locales": "scripts/missing-keys.sh && scripts/sort.sh"
},
"dependencies": {
@ -36,14 +36,12 @@
"graphql": "^15.6.1",
"identity-obj-proxy": "^3.0.0",
"jest": "26.6.3",
"moment": "^2.29.1",
"regenerator-runtime": "^0.13.9",
"stats-webpack-plugin": "^0.7.0",
"vue": "^2.6.11",
"vue-apollo": "^3.0.8",
"vue-i18n": "^8.26.5",
"vue-jest": "^3.0.7",
"vue-moment": "^4.1.0",
"vue-router": "^3.5.3",
"vue-toasted": "^1.1.28",
"vuex": "^3.6.2",

View File

@ -5,14 +5,6 @@ import { createPendingCreations } from '../graphql/createPendingCreations'
const localVue = global.localVue
const apolloMock = jest.fn().mockResolvedValue({
data: {
verifyLogin: {
name: 'success',
id: 0,
},
},
})
const apolloMutateMock = jest.fn().mockResolvedValue({
data: {
createPendingCreation: [0, 0, 0],
@ -23,19 +15,12 @@ const toastedErrorMock = jest.fn()
const toastedSuccessMock = jest.fn()
const mocks = {
$t: jest.fn((t) => t),
$moment: jest.fn(() => {
return {
format: jest.fn((m) => m),
subtract: jest.fn(() => {
return {
format: jest.fn((m) => m),
}
}),
}
$t: jest.fn((t, options) => (options ? [t, options] : t)),
$d: jest.fn((d) => {
const date = new Date(d)
return date.toISOString().split('T')[0]
}),
$apollo: {
query: apolloMock,
mutate: apolloMutateMock,
},
$store: {
@ -56,7 +41,12 @@ const mocks = {
const propsData = {
type: '',
creation: [],
itemsMassCreation: {},
}
const now = new Date(Date.now())
const getCreationDate = (sub) => {
const date = sub === 0 ? now : new Date(now.getFullYear(), now.getMonth() - sub, 1, 0)
return date.toISOString().split('T')[0]
}
describe('CreationFormular', () => {
@ -75,21 +65,24 @@ describe('CreationFormular', () => {
expect(wrapper.find('.component-creation-formular').exists()).toBeTruthy()
})
describe('server sends back moderator data', () => {
it('called store commit with mocked data', () => {
expect(stateCommitMock).toBeCalledWith('moderator', { name: 'success', id: 0 })
})
})
describe('server throws error for moderator data call', () => {
beforeEach(() => {
jest.clearAllMocks()
apolloMock.mockRejectedValueOnce({ message: 'Ouch!' })
wrapper = Wrapper()
describe('text and value form props', () => {
beforeEach(async () => {
wrapper = mount(CreationFormular, {
localVue,
mocks,
propsData: {
creationUserData: { memo: 'Memo from property', amount: 42 },
...propsData,
},
})
})
it('has called store commit with fake data', () => {
expect(stateCommitMock).toBeCalledWith('moderator', { id: 0, name: 'Test Moderator' })
it('has text taken from props', () => {
expect(wrapper.vm.text).toBe('Memo from property')
})
it('has value taken from props', () => {
expect(wrapper.vm.value).toBe(42)
})
})
@ -98,52 +91,6 @@ describe('CreationFormular', () => {
expect(wrapper.findAll('input[type="radio"]').length).toBe(3)
})
describe('with mass creation', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ type: 'massCreation', creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ text: 'Test create coins' })
await wrapper.setData({ value: 90 })
})
describe('first radio button', () => {
beforeEach(async () => {
await wrapper.findAll('input[type="radio"]').at(0).setChecked()
})
it('emits update-radio-selected with index 0', () => {
expect(wrapper.emitted()['update-radio-selected']).toEqual([
[expect.arrayContaining([0])],
])
})
})
describe('second radio button', () => {
beforeEach(async () => {
await wrapper.findAll('input[type="radio"]').at(1).setChecked()
})
it('emits update-radio-selected with index 1', () => {
expect(wrapper.emitted()['update-radio-selected']).toEqual([
[expect.arrayContaining([1])],
])
})
})
describe('third radio button', () => {
beforeEach(async () => {
await wrapper.findAll('input[type="radio"]').at(2).setChecked()
})
it('emits update-radio-selected with index 2', () => {
expect(wrapper.emitted()['update-radio-selected']).toEqual([
[expect.arrayContaining([2])],
])
})
})
})
describe('with single creation', () => {
beforeEach(async () => {
jest.clearAllMocks()
@ -153,17 +100,17 @@ describe('CreationFormular', () => {
item: { email: 'benjamin@bluemchen.de' },
})
await wrapper.findAll('input[type="radio"]').at(1).setChecked()
await wrapper.find('textarea').setValue('Test create coins')
await wrapper.find('input[type="number"]').setValue(90)
})
describe('first radio button', () => {
beforeEach(async () => {
await wrapper.findAll('input[type="radio"]').at(0).setChecked()
await wrapper.find('textarea').setValue('Test create coins')
})
it('sets rangeMax to 200', () => {
expect(wrapper.vm.rangeMax).toBe(400)
expect(wrapper.vm.rangeMax).toBe(200)
})
describe('sendForm', () => {
@ -177,7 +124,7 @@ describe('CreationFormular', () => {
mutation: createPendingCreation,
variables: {
email: 'benjamin@bluemchen.de',
creationDate: 'YYYY-MM-01',
creationDate: getCreationDate(2),
amount: 90,
memo: 'Test create coins',
moderator: 0,
@ -185,9 +132,30 @@ describe('CreationFormular', () => {
}),
)
})
it('emits update-user-data', () => {
expect(wrapper.emitted('update-user-data')).toEqual([
[{ email: 'benjamin@bluemchen.de' }, [0, 0, 0]],
])
})
it('toasts a success message', () => {
expect(toastedSuccessMock).toBeCalledWith([
'creation_form.toasted',
{ email: 'benjamin@bluemchen.de', value: '90' },
])
})
it('updates open creations in store', () => {
expect(stateCommitMock).toBeCalledWith('openCreationsPlus', 1)
})
it('resets the form data', () => {
expect(wrapper.vm.value).toBe(0)
})
})
describe('sendForm', () => {
describe('sendForm with server error', () => {
beforeEach(async () => {
apolloMutateMock.mockRejectedValueOnce({ message: 'Ouch!' })
await wrapper.find('.test-submit').trigger('click')
@ -373,9 +341,18 @@ describe('CreationFormular', () => {
})
})
describe('with mass creation', () => {
describe('mass creation with success', () => {
beforeEach(async () => {
jest.clearAllMocks()
apolloMutateMock.mockResolvedValue({
data: {
createPendingCreations: {
success: true,
successfulCreation: ['bob@baumeister.de', 'bibi@bloxberg.de'],
failedCreation: [],
},
},
})
await wrapper.setProps({
type: 'massCreation',
creation: [200, 400, 600],
@ -395,14 +372,14 @@ describe('CreationFormular', () => {
pendingCreations: [
{
email: 'bob@baumeister.de',
creationDate: 'YYYY-MM-01',
creationDate: getCreationDate(1),
amount: 200,
memo: 'Test mass create coins',
moderator: 0,
},
{
email: 'bibi@bloxberg.de',
creationDate: 'YYYY-MM-01',
creationDate: getCreationDate(1),
amount: 200,
memo: 'Test mass create coins',
moderator: 0,
@ -412,6 +389,73 @@ describe('CreationFormular', () => {
}),
)
})
it('updates open creations in store', () => {
expect(stateCommitMock).toBeCalledWith('openCreationsPlus', 2)
})
it('emits remove-all-bookmark', () => {
expect(wrapper.emitted('remove-all-bookmark')).toBeTruthy()
})
})
describe('mass creation with success but all failed', () => {
beforeEach(async () => {
jest.clearAllMocks()
apolloMutateMock.mockResolvedValue({
data: {
createPendingCreations: {
success: true,
successfulCreation: [],
failedCreation: ['bob@baumeister.de', 'bibi@bloxberg.de'],
},
},
})
await wrapper.setProps({
type: 'massCreation',
creation: [200, 400, 600],
items: [{ email: 'bob@baumeister.de' }, { email: 'bibi@bloxberg.de' }],
})
await wrapper.findAll('input[type="radio"]').at(1).setChecked()
await wrapper.find('textarea').setValue('Test mass create coins')
await wrapper.find('input[type="number"]').setValue(200)
await wrapper.find('.test-submit').trigger('click')
})
it('updates open creations in store', () => {
expect(stateCommitMock).toBeCalledWith('openCreationsPlus', 0)
})
it('toasts two errors', () => {
expect(toastedErrorMock).toBeCalledWith(
'Could not created PendingCreation for bob@baumeister.de',
)
expect(toastedErrorMock).toBeCalledWith(
'Could not created PendingCreation for bibi@bloxberg.de',
)
})
})
describe('mass creation with error', () => {
beforeEach(async () => {
jest.clearAllMocks()
apolloMutateMock.mockRejectedValue({
message: 'Oh no!',
})
await wrapper.setProps({
type: 'massCreation',
creation: [200, 400, 600],
items: [{ email: 'bob@baumeister.de' }, { email: 'bibi@bloxberg.de' }],
})
await wrapper.findAll('input[type="radio"]').at(1).setChecked()
await wrapper.find('textarea').setValue('Test mass create coins')
await wrapper.find('input[type="number"]').setValue(200)
await wrapper.find('.test-submit').trigger('click')
})
it('toasts an error message', () => {
expect(toastedErrorMock).toBeCalledWith('Oh no!')
})
})
})
})

View File

@ -7,51 +7,15 @@
<label>{{ $t('creation_form.select_month') }}</label>
</div>
<b-row class="ml-4">
<b-col>
<b-form-radio
id="beforeLastMonth"
v-model="radioSelected"
:value="beforeLastMonth"
:disabled="creation[0] === 0"
size="lg"
@change="updateRadioSelected(beforeLastMonth, 0, creation[0])"
>
<label for="beforeLastMonth">
{{ beforeLastMonth.short }} {{ creation[0] != null ? creation[0] + ' GDD' : '' }}
</label>
</b-form-radio>
</b-col>
<b-col>
<b-form-radio
id="lastMonth"
v-model="radioSelected"
:value="lastMonth"
:disabled="creation[1] === 0"
size="lg"
@change="updateRadioSelected(lastMonth, 1, creation[1])"
>
<label for="lastMonth">
{{ lastMonth.short }} {{ creation[1] != null ? creation[1] + ' GDD' : '' }}
</label>
</b-form-radio>
</b-col>
<b-col>
<b-form-radio
id="currentMonth"
v-model="radioSelected"
:value="currentMonth"
:disabled="creation[2] === 0"
size="lg"
@change="updateRadioSelected(currentMonth, 2, creation[2])"
>
<label for="currentMonth">
{{ currentMonth.short }} {{ creation[2] != null ? creation[2] + ' GDD' : '' }}
</label>
</b-form-radio>
</b-col>
<b-form-radio-group
v-model="selected"
:options="radioOptions"
value-field="item"
text-field="name"
name="month-selection"
></b-form-radio-group>
</b-row>
<div class="m-4" v-show="createdIndex != null">
<b-row class="m-4" v-show="selected !== ''">
<label>{{ $t('creation_form.select_value') }}</label>
<div>
<b-input-group prepend="GDD" append=".00">
@ -62,7 +26,6 @@
:max="rangeMax"
></b-form-input>
</b-input-group>
<b-input-group prepend="0" :append="String(rangeMax)" class="mt-3">
<b-form-input
type="range"
@ -73,7 +36,7 @@
></b-form-input>
</b-input-group>
</div>
</div>
</b-row>
<div class="m-4">
<label>{{ $t('creation_form.enter_text') }}</label>
<div>
@ -100,18 +63,17 @@
variant="success"
class="test-submit"
@click="submitCreation"
:disabled="radioSelected === '' || value <= 0 || text.length < 10"
:disabled="selected === '' || value <= 0 || text.length < 10"
>
{{ $t('creation_form.update_creation') }}
</b-button>
<b-button
v-else
type="button"
variant="success"
class="test-submit"
@click="submitCreation"
:disabled="radioSelected === '' || value <= 0 || text.length < 10"
:disabled="selected === '' || value <= 0 || text.length < 10"
>
{{ $t('creation_form.submit_creation') }}
</b-button>
@ -123,11 +85,12 @@
</div>
</template>
<script>
import { verifyLogin } from '../graphql/verifyLogin'
import { createPendingCreation } from '../graphql/createPendingCreation'
import { createPendingCreations } from '../graphql/createPendingCreations'
import { creationMonths } from '../mixins/creationMonths'
export default {
name: 'CreationFormular',
mixins: [creationMonths],
props: {
type: {
type: String,
@ -166,71 +129,39 @@ export default {
},
data() {
return {
radioSelected: '',
text: !this.creationUserData.memo ? '' : this.creationUserData.memo,
value: !this.creationUserData.amount ? 0 : this.creationUserData.amount,
rangeMin: 0,
rangeMax: 1000,
currentMonth: {
short: this.$moment().format('MMMM'),
long: this.$moment().format('YYYY-MM-DD'),
year: this.$moment().format('YYYY'),
},
lastMonth: {
short: this.$moment().subtract(1, 'month').format('MMMM'),
long: this.$moment().subtract(1, 'month').format('YYYY-MM') + '-01',
year: this.$moment().subtract(1, 'month').format('YYYY'),
},
beforeLastMonth: {
short: this.$moment().subtract(2, 'month').format('MMMM'),
long: this.$moment().subtract(2, 'month').format('YYYY-MM') + '-01',
year: this.$moment().subtract(2, 'month').format('YYYY'),
},
submitObj: null,
isdisabled: true,
createdIndex: null,
selected: '',
}
},
methods: {
// Auswählen eines Zeitraumes
updateRadioSelected(name, index, openCreation) {
this.createdIndex = index
updateRadioSelected(name) {
// do we want to reset the memo everytime the month changes?
this.text = this.$t('creation_form.creation_for') + ' ' + name.short + ' ' + name.year
// Wenn Mehrfachschöpfung
if (this.type === 'massCreation') {
// An Creation.vue emitten und radioSelectedMass aktualisieren
this.$emit('update-radio-selected', [name, index])
} else if (this.type === 'singleCreation') {
if (this.type === 'singleCreation') {
this.rangeMin = 0
// Der maximale offene Betrag an GDD die für ein User noch geschöpft werden kann
this.rangeMax = openCreation
this.rangeMax = name.creation
}
},
submitCreation() {
let submitObj = []
if (this.type === 'massCreation') {
// Die anzahl der Mitglieder aus der Mehrfachschöpfung
const i = Object.keys(this.items).length
// hinweis das eine Mehrfachschöpfung ausgeführt wird an (Anzahl der MItgleider an die geschöpft wird)
// eslint-disable-next-line no-console
console.log('SUBMIT CREATION => ' + this.type + ' >> für VIELE ' + i + ' Mitglieder')
this.submitObj = []
this.items.forEach((item) => {
this.submitObj.push({
submitObj.push({
email: item.email,
creationDate: this.radioSelected.long,
creationDate: this.selected.date,
amount: Number(this.value),
memo: this.text,
moderator: Number(this.$store.state.moderator.id),
})
})
// eslint-disable-next-line no-console
console.log('MehrfachSCHÖPFUNG ABSENDEN FÜR >> ' + i + ' Mitglieder')
this.$apollo
.mutate({
mutation: createPendingCreations,
variables: {
pendingCreations: this.submitObj,
pendingCreations: submitObj,
},
fetchPolicy: 'no-cache',
})
@ -241,6 +172,7 @@ export default {
)
if (result.data.createPendingCreations.failedCreation.length > 0) {
result.data.createPendingCreations.failedCreation.forEach((failed) => {
// TODO: Please localize this error message
this.$toasted.error('Could not created PendingCreation for ' + failed)
})
}
@ -250,18 +182,17 @@ export default {
this.$toasted.error(error.message)
})
} else if (this.type === 'singleCreation') {
this.submitObj = {
submitObj = {
email: this.item.email,
creationDate: this.radioSelected.long,
creationDate: this.selected.date,
amount: Number(this.value),
memo: this.text,
moderator: Number(this.$store.state.moderator.id),
}
this.$apollo
.mutate({
mutation: createPendingCreation,
variables: this.submitObj,
variables: submitObj,
})
.then((result) => {
this.$emit('update-user-data', this.item, result.data.createPendingCreation)
@ -272,36 +203,22 @@ export default {
}),
)
this.$store.commit('openCreationsPlus', 1)
this.submitObj = null
this.createdIndex = null
// das creation Formular reseten
// what is this? Tests says that this.text is not reseted
this.$refs.creationForm.reset()
// Den geschöpften Wert auf o setzen
this.value = 0
})
.catch((error) => {
this.$toasted.error(error.message)
this.submitObj = null
// das creation Formular reseten
this.$refs.creationForm.reset()
// Den geschöpften Wert auf o setzen
this.value = 0
})
}
},
searchModeratorData() {
this.$apollo
.query({ query: verifyLogin })
.then((result) => {
this.$store.commit('moderator', result.data.verifyLogin)
})
.catch(() => {
this.$store.commit('moderator', { id: 0, name: 'Test Moderator' })
})
},
},
created() {
this.searchModeratorData()
watch: {
selected() {
this.updateRadioSelected(this.selected)
},
},
}
</script>

View File

@ -7,8 +7,9 @@ const apolloMutateMock = jest.fn().mockResolvedValue({
data: {
updatePendingCreation: {
creation: [0, 0, 0],
amount: 500,
date: new Date(),
memo: 'qwertzuiopasdfghjkl',
memo: 'Test Schöpfung 2',
moderator: 0,
},
},
@ -20,15 +21,9 @@ const toastedSuccessMock = jest.fn()
const mocks = {
$t: jest.fn((t) => t),
$moment: jest.fn(() => {
return {
format: jest.fn((m) => m),
subtract: jest.fn(() => {
return {
format: jest.fn((m) => m),
}
}),
}
$d: jest.fn((d) => {
const date = new Date(d)
return date.toISOString().split('T')[0]
}),
$apollo: {
mutate: apolloMutateMock,
@ -48,12 +43,18 @@ const mocks = {
},
}
const now = new Date(Date.now())
const getCreationDate = (sub) => {
const date = sub === 0 ? now : new Date(now.getFullYear(), now.getMonth() - sub, 1, 0)
return date.toISOString().split('T')[0]
}
const propsData = {
creation: [200, 400, 600],
creationUserData: {
memo: 'Test schöpfung 1',
amount: 100,
date: '2021-12-01',
date: getCreationDate(0),
},
item: {
id: 0,
@ -82,196 +83,79 @@ describe('EditCreationFormular', () => {
expect(wrapper.findAll('input[type="radio"]').length).toBe(3)
})
describe('with single creation', () => {
it('has the third radio button checked', () => {
expect(wrapper.findAll('input[type="radio"]').at(0).element.checked).toBeFalsy()
expect(wrapper.findAll('input[type="radio"]').at(1).element.checked).toBeFalsy()
expect(wrapper.findAll('input[type="radio"]').at(2).element.checked).toBeTruthy()
})
it('has rangeMax of 700', () => {
expect(wrapper.find('input[type="number"]').attributes('max')).toBe('700')
})
describe('change and save memo and value with success', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper.setProps({ creation: [200, 400, 600] })
await wrapper.setData({ rangeMin: 180 })
await wrapper.setData({ text: 'Test create coins' })
await wrapper.setData({ value: 90 })
await wrapper.find('input[type="number"]').setValue(500)
await wrapper.find('textarea').setValue('Test Schöpfung 2')
await wrapper.find('.test-submit').trigger('click')
})
describe('first radio button', () => {
beforeEach(async () => {
await wrapper.findAll('input[type="radio"]').at(0).setChecked()
})
it('sets rangeMin to 0', () => {
expect(wrapper.vm.rangeMin).toBe(0)
})
it('sets rangeMax to 200', () => {
expect(wrapper.vm.rangeMax).toBe(200)
})
describe('sendForm', () => {
beforeEach(async () => {
await wrapper.find('.test-submit').trigger('click')
})
it('sends ... to apollo', () => {
expect(apolloMutateMock).toBeCalledWith(
expect.objectContaining({
variables: {
amount: 90,
creationDate: 'YYYY-MM-01',
email: 'bob@baumeister.de',
id: 0,
memo: 'Test create coins',
moderator: 0,
},
}),
)
})
it('emits update-user-data', () => {
expect(wrapper.emitted('update-user-data')).toBeTruthy()
expect(wrapper.emitted('update-user-data')).toEqual([
[
{
id: 0,
email: 'bob@baumeister.de',
},
[0, 0, 0],
],
])
})
it('toast success message', () => {
expect(toastedSuccessMock).toBeCalledWith('creation_form.toasted_update')
})
describe('sendForm with error', () => {
beforeEach(async () => {
jest.clearAllMocks()
apolloMutateMock.mockRejectedValue({
message: 'Ouch!',
})
wrapper = Wrapper()
await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] })
await wrapper.setData({ text: 'Test create coins' })
await wrapper.setData({ value: 90 })
await wrapper.findAll('input[type="radio"]').at(0).setChecked()
await wrapper.setData({ rangeMin: 100 })
await wrapper.find('.test-submit').trigger('click')
})
it('toast error message', () => {
expect(toastedErrorMock).toBeCalledWith('Ouch!')
})
})
})
it('calls the API', () => {
expect(apolloMutateMock).toBeCalledWith(
expect.objectContaining({
variables: {
id: 0,
email: 'bob@baumeister.de',
creationDate: getCreationDate(0),
amount: 500,
memo: 'Test Schöpfung 2',
moderator: 0,
},
}),
)
})
describe('second radio button', () => {
beforeEach(async () => {
await wrapper.findAll('input[type="radio"]').at(1).setChecked()
})
it('sets rangeMin to 0', () => {
expect(wrapper.vm.rangeMin).toBe(0)
})
it('sets rangeMax to 400', () => {
expect(wrapper.vm.rangeMax).toBe(400)
})
describe('sendForm', () => {
beforeEach(async () => {
await wrapper.find('.test-submit').trigger('click')
})
it('sends ... to apollo', () => {
expect(apolloMutateMock).toBeCalledWith(
expect.objectContaining({
variables: {
amount: 90,
creationDate: 'YYYY-MM-01',
email: 'bob@baumeister.de',
id: 0,
memo: 'Test create coins',
moderator: 0,
},
}),
)
})
describe('sendForm with error', () => {
beforeEach(async () => {
jest.clearAllMocks()
apolloMutateMock.mockRejectedValue({
message: 'Ouch!',
})
wrapper = Wrapper()
await wrapper.setProps({ creation: [200, 400, 600] })
await wrapper.setData({ text: 'Test create coins' })
await wrapper.setData({ value: 100 })
await wrapper.findAll('input[type="radio"]').at(1).setChecked()
await wrapper.setData({ rangeMin: 180 })
await wrapper.find('.test-submit').trigger('click')
})
it('toast error message', () => {
expect(toastedErrorMock).toBeCalledWith('Ouch!')
})
})
})
it('emits update-user-data', () => {
expect(wrapper.emitted('update-user-data')).toEqual([
[
{
id: 0,
email: 'bob@baumeister.de',
},
[0, 0, 0],
],
])
})
describe('third radio button', () => {
beforeEach(async () => {
await wrapper.setData({ rangeMin: 180 })
await wrapper.findAll('input[type="radio"]').at(2).setChecked()
})
it('emits update-creation-data', () => {
expect(wrapper.emitted('update-creation-data')).toEqual([
[
{
amount: 500,
date: expect.any(Date),
memo: 'Test Schöpfung 2',
moderator: 0,
row: expect.any(Object),
},
],
])
})
it('sets rangeMin to 180', () => {
expect(wrapper.vm.rangeMin).toBe(180)
})
it('toasts a success message', () => {
expect(toastedSuccessMock).toBeCalledWith('creation_form.toasted_update')
})
})
it('sets rangeMax to 700', () => {
expect(wrapper.vm.rangeMax).toBe(700)
})
describe('change and save memo and value with error', () => {
beforeEach(async () => {
apolloMutateMock.mockRejectedValue({ message: 'Oh no!' })
await wrapper.find('input[type="number"]').setValue(500)
await wrapper.find('textarea').setValue('Test Schöpfung 2')
await wrapper.find('.test-submit').trigger('click')
})
describe('sendForm with success', () => {
beforeEach(async () => {
await wrapper.find('.test-submit').trigger('click')
})
it('sends ... to apollo', () => {
expect(apolloMutateMock).toBeCalledWith(
expect.objectContaining({
variables: {
amount: 90,
creationDate: 'YYYY-MM-DD',
email: 'bob@baumeister.de',
id: 0,
memo: 'Test create coins',
moderator: 0,
},
}),
)
})
})
describe('sendForm with error', () => {
beforeEach(async () => {
jest.clearAllMocks()
apolloMutateMock.mockRejectedValue({
message: 'Ouch!',
})
wrapper = Wrapper()
await wrapper.setProps({ creation: [200, 400, 600] })
await wrapper.setData({ text: 'Test create coins' })
await wrapper.setData({ value: 90 })
await wrapper.findAll('input[type="radio"]').at(2).setChecked()
await wrapper.setData({ rangeMin: 180 })
await wrapper.find('.test-submit').trigger('click')
})
it('toast error message', () => {
expect(toastedErrorMock).toBeCalledWith('Ouch!')
})
})
it('toasts an error message', () => {
expect(toastedErrorMock).toBeCalledWith('Oh no!')
})
})
})

View File

@ -6,65 +6,14 @@
<label>{{ $t('creation_form.select_month') }}</label>
</div>
<b-row class="m-4">
<b-col class="text-left">
<b-form-radio
id="beforeLastMonth"
v-model="radioSelected"
:value="beforeLastMonth"
:disabled="selectedOpenCreationAmount[0] === 0"
size="lg"
@change="updateRadioSelected(beforeLastMonth, 0, selectedOpenCreationAmount[0])"
>
<label for="beforeLastMonth">
{{ beforeLastMonth.short }}
{{
selectedOpenCreationAmount[0] != null
? selectedOpenCreationAmount[0] + ' GDD'
: ''
}}
</label>
</b-form-radio>
</b-col>
<b-col>
<b-form-radio
id="lastMonth"
v-model="radioSelected"
:value="lastMonth"
:disabled="selectedOpenCreationAmount[1] === 0"
size="lg"
@change="updateRadioSelected(lastMonth, 1, selectedOpenCreationAmount[1])"
>
<label for="lastMonth">
{{ lastMonth.short }}
{{
selectedOpenCreationAmount[1] != null
? selectedOpenCreationAmount[1] + ' GDD'
: ''
}}
</label>
</b-form-radio>
</b-col>
<b-col class="text-right">
<b-form-radio
id="currentMonth"
v-model="radioSelected"
:value="currentMonth"
:disabled="selectedOpenCreationAmount[2] === 0"
size="lg"
@change="updateRadioSelected(currentMonth, 2, selectedOpenCreationAmount[2])"
>
<label for="currentMonth">
{{ currentMonth.short }}
{{
selectedOpenCreationAmount[2] != null
? selectedOpenCreationAmount[2] + ' GDD'
: ''
}}
</label>
</b-form-radio>
</b-col>
<b-form-radio-group
v-model="selected"
:options="radioOptions"
value-field="item"
text-field="name"
name="month-selection"
></b-form-radio-group>
</b-row>
<div class="m-4">
<label>{{ $t('creation_form.select_value') }}</label>
<div>
@ -76,7 +25,6 @@
:max="rangeMax"
></b-form-input>
</b-input-group>
<b-input-group prepend="0" :append="String(rangeMax)" class="mt-3">
<b-form-input
type="range"
@ -113,7 +61,7 @@
variant="success"
class="test-submit"
@click="submitCreation"
:disabled="radioSelected === '' || value <= 0 || text.length < 10"
:disabled="selected === '' || value <= 0 || text.length < 10"
>
{{ $t('creation_form.update_creation') }}
</b-button>
@ -126,8 +74,11 @@
</template>
<script>
import { updatePendingCreation } from '../graphql/updatePendingCreation'
import { creationMonths } from '../mixins/creationMonths'
export default {
name: 'EditCreationFormular',
mixins: [creationMonths],
props: {
item: {
type: Object,
@ -151,51 +102,26 @@ export default {
},
data() {
return {
radioSelected: '',
text: !this.creationUserData.memo ? '' : this.creationUserData.memo,
value: !this.creationUserData.amount ? 0 : this.creationUserData.amount,
rangeMin: 0,
rangeMax: 1000,
currentMonth: {
short: this.$moment().format('MMMM'),
long: this.$moment().format('YYYY-MM-DD'),
},
lastMonth: {
short: this.$moment().subtract(1, 'month').format('MMMM'),
long: this.$moment().subtract(1, 'month').format('YYYY-MM') + '-01',
},
beforeLastMonth: {
short: this.$moment().subtract(2, 'month').format('MMMM'),
long: this.$moment().subtract(2, 'month').format('YYYY-MM') + '-01',
},
submitObj: null,
isdisabled: true,
createdIndex: null,
selectedOpenCreationAmount: {},
selected: '',
}
},
methods: {
updateRadioSelected(name, index, openCreation) {
this.createdIndex = index
this.rangeMin = 0
this.rangeMax = this.creation[index]
},
submitCreation() {
this.submitObj = {
id: this.item.id,
email: this.item.email,
creationDate: this.radioSelected.long,
amount: Number(this.value),
memo: this.text,
moderator: Number(this.$store.state.moderator.id),
}
// hinweis das eine ein einzelne Schöpfung abgesendet wird an (email)
this.$apollo
.mutate({
mutation: updatePendingCreation,
variables: this.submitObj,
variables: {
id: this.item.id,
email: this.item.email,
creationDate: this.selected.date,
amount: Number(this.value),
memo: this.text,
moderator: Number(this.$store.state.moderator.id),
},
})
.then((result) => {
this.$emit('update-user-data', this.item, result.data.updatePendingCreation.creation)
@ -212,8 +138,6 @@ export default {
email: this.item.email,
}),
)
this.submitObj = null
this.createdIndex = null
// das creation Formular reseten
this.$refs.updateCreationForm.reset()
// Den geschöpften Wert auf o setzen
@ -221,7 +145,6 @@ export default {
})
.catch((error) => {
this.$toasted.error(error.message)
this.submitObj = null
// das creation Formular reseten
this.$refs.updateCreationForm.reset()
// Den geschöpften Wert auf o setzen
@ -231,25 +154,10 @@ export default {
},
created() {
if (this.creationUserData.date) {
switch (this.$moment(this.creationUserData.date).format('MMMM')) {
case this.currentMonth.short:
this.createdIndex = 2
this.radioSelected = this.currentMonth
break
case this.lastMonth.short:
this.createdIndex = 1
this.radioSelected = this.lastMonth
break
case this.beforeLastMonth.short:
this.createdIndex = 0
this.radioSelected = this.beforeLastMonth
break
default:
throw new Error('Something went wrong')
}
this.selectedOpenCreationAmount[this.createdIndex] =
this.creation[this.createdIndex] + this.creationUserData.amount
this.rangeMax = this.selectedOpenCreationAmount[this.createdIndex]
const month = this.$d(new Date(this.creationUserData.date), 'month')
const index = this.radioOptions.findIndex((obj) => obj.item.short === month)
this.selected = this.radioOptions[index].item
this.rangeMax = this.creation[index] + this.creationUserData.amount
}
},
}

View File

@ -107,16 +107,7 @@ describe('UserTable', () => {
const mocks = {
$t: jest.fn((t) => t),
$moment: jest.fn(() => {
return {
format: jest.fn((m) => m),
subtract: jest.fn(() => {
return {
format: jest.fn((m) => m),
}
}),
}
}),
$d: jest.fn((d) => d),
$apollo: {
query: apolloQueryMock,
},
@ -199,11 +190,6 @@ describe('UserTable', () => {
})
})
})
// it('expect(wrapper.html()).', () => {
// // eslint-disable-next-line no-console
// console.log(wrapper.html())
// })
})
describe('type UserListSearch', () => {
@ -214,11 +200,6 @@ describe('UserTable', () => {
it('has a DIV element with the class.component-user-table', () => {
expect(wrapper.find('.component-user-table').exists()).toBeTruthy()
})
// it('expect(wrapper.html()).', () => {
// // eslint-disable-next-line no-console
// console.log(wrapper.html())
// })
})
describe('type UserListMassCreation', () => {
@ -229,11 +210,6 @@ describe('UserTable', () => {
it('has a DIV element with the class.component-user-table', () => {
expect(wrapper.find('.component-user-table').exists()).toBeTruthy()
})
// it('expect(wrapper.html()).', () => {
// // eslint-disable-next-line no-console
// console.log(wrapper.html())
// })
})
describe('type PageCreationConfirm', () => {
@ -244,48 +220,6 @@ describe('UserTable', () => {
it('has a DIV element with the class.component-user-table', () => {
expect(wrapper.find('.component-user-table').exists()).toBeTruthy()
})
// it('expect(wrapper.html()).', () => {
// // eslint-disable-next-line no-console
// console.log(wrapper.html())
// })
})
/**
<user-table
v-if="itemsList.length > 0"
type="UserListSearch"
:itemsUser="itemsList"
:fieldsTable="Searchfields"
:criteria="criteria"
:creation="creation"
@update-item="updateItem"
/>
<user-table
v-show="itemsMassCreation.length > 0"
class="shadow p-3 mb-5 bg-white rounded"
type="UserListMassCreation"
:itemsUser="itemsMassCreation"
:fieldsTable="fields"
:criteria="null"
:creation="creation"
@update-item="updateItem"
/>
<user-table
class="mt-4"
type="PageCreationConfirm"
:itemsUser="confirmResult"
:fieldsTable="fields"
@remove-confirm-result="removeConfirmResult"
/>
<user-table
type="PageUserSearch"
:itemsUser="searchResult"
:fieldsTable="fields"
:criteria="criteria"
/>
*/
})
})

View File

@ -116,7 +116,7 @@
<confirm-register-mail-formular
:checked="row.item.emailChecked"
:email="row.item.email"
:dateLastSend="$moment().subtract(1, 'month').format('dddd, DD.MMMM.YYYY HH:mm'),"
:dateLastSend="$d(new Date(), 'long')"
/>
</template>
<template #show-transaction-list>
@ -125,15 +125,18 @@
</row-details>
</template>
<template #cell(bookmark)="row">
<b-button
variant="warning"
v-show="type === 'UserListSearch'"
size="md"
@click="bookmarkPush(row.item)"
class="mr-2"
>
<b-icon icon="plus" variant="success"></b-icon>
</b-button>
<div v-show="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'"
@ -284,11 +287,11 @@ export default {
this.overlay = false
},
bookmarkPush(item) {
this.$emit('update-item', item, 'push')
this.$emit('push-item', item)
},
bookmarkRemove(item) {
if (this.type === 'UserListMassCreation') {
this.$emit('update-item', item, 'remove')
this.$emit('remove-item', item)
}
if (this.type === 'PageCreationConfirm') {

View File

@ -60,6 +60,15 @@ const dateTimeFormats = {
hour: 'numeric',
minute: 'numeric',
},
monthShort: {
month: 'short',
},
month: {
month: 'long',
},
year: {
year: 'numeric',
},
},
de: {
short: {
@ -75,6 +84,15 @@ const dateTimeFormats = {
hour: 'numeric',
minute: 'numeric',
},
monthShort: {
month: 'short',
},
month: {
month: 'long',
},
year: {
year: 'numeric',
},
},
}

View File

@ -18,6 +18,7 @@
"toasted_update": "`Offene Schöpfung {value} GDD) für {email} wurde geändert und liegt zur Bestätigung bereit",
"update_creation": "Schöpfung aktualisieren"
},
"date": "Datum",
"details": "Details",
"e_mail": "E-Mail",
"firstname": "Vorname",

View File

@ -18,8 +18,9 @@
"toasted_update": "Open creation {value} GDD) for {email} has been changed and is ready for confirmation.",
"update_creation": "Creation update"
},
"date": "Date",
"details": "Details",
"e_mail": "E-Mail",
"e_mail": "E-mail",
"firstname": "Firstname",
"gradido_admin_footer": "Gradido Academy Admin Console",
"hide_details": "Hide details from",

View File

@ -17,7 +17,6 @@ import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import moment from 'vue-moment'
import Toasted from 'vue-toasted'
import { apolloProvider } from './plugins/apolloProvider'
@ -26,8 +25,6 @@ Vue.use(BootstrapVue)
Vue.use(IconsPlugin)
Vue.use(moment)
Vue.use(VueApollo)
Vue.use(Toasted, {
@ -48,7 +45,6 @@ i18n.locale =
store.state.moderator && store.state.moderator.language ? store.state.moderator.language : 'en'
new Vue({
moment,
router,
store,
i18n,

View File

@ -6,7 +6,6 @@ import Vue from 'vue'
import VueApollo from 'vue-apollo'
import i18n from './i18n'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import moment from 'vue-moment'
import store from './store/store'
import router from './router/router'
@ -14,7 +13,6 @@ jest.mock('vue')
jest.mock('vue-apollo')
jest.mock('vuex')
jest.mock('vue-i18n')
jest.mock('vue-moment')
jest.mock('./store/store', () => {
return {
state: {
@ -90,10 +88,6 @@ describe('main', () => {
expect(Vue.use).toBeCalledWith(IconsPlugin)
})
it('calls Moment', () => {
expect(Vue.use).toBeCalledWith(moment)
})
it('creates a store', () => {
expect(Vue).toBeCalledWith(
expect.objectContaining({

View File

@ -0,0 +1,35 @@
export const creationMonths = {
props: {
creation: [1000, 1000, 1000],
},
computed: {
creationDates() {
const now = new Date(Date.now())
const dates = [now]
for (let i = 1; i < 3; i++) {
dates.push(new Date(now.getFullYear(), now.getMonth() - i, 1))
}
return dates.reverse()
},
creationDateObjects() {
const result = []
this.creationDates.forEach((date) => {
result.push({
short: this.$d(date, 'month'),
long: this.$d(date, 'short'),
year: this.$d(date, 'year'),
date: this.$d(date, 'short', 'en'),
})
})
return result
},
radioOptions() {
return this.creationDateObjects.map((obj, idx) => {
return {
item: { ...obj, creation: this.creation[idx] },
name: obj.short + (this.creation[idx] ? ' ' + this.creation[idx] + ' GDD' : ''),
}
})
},
},
}

View File

@ -1,6 +1,5 @@
import { shallowMount } from '@vue/test-utils'
import Creation from './Creation.vue'
import Vue from 'vue'
const localVue = global.localVue
@ -29,25 +28,23 @@ const apolloQueryMock = jest.fn().mockResolvedValue({
})
const toastErrorMock = jest.fn()
const storeCommitMock = jest.fn()
const mocks = {
$t: jest.fn((t) => t),
$d: jest.fn((d) => d),
$apollo: {
query: apolloQueryMock,
},
$toasted: {
error: toastErrorMock,
},
$moment: jest.fn(() => {
return {
format: jest.fn((m) => m),
subtract: jest.fn(() => {
return {
format: jest.fn((m) => m),
}
}),
}
}),
$store: {
commit: storeCommitMock,
state: {
userSelectedInMassCreation: [],
},
},
}
describe('Creation', () => {
@ -59,6 +56,7 @@ describe('Creation', () => {
describe('shallowMount', () => {
beforeEach(() => {
jest.clearAllMocks()
wrapper = Wrapper()
})
@ -68,7 +66,15 @@ describe('Creation', () => {
describe('apollo returns user array', () => {
it('calls the searchUser query', () => {
expect(apolloQueryMock).toBeCalled()
expect(apolloQueryMock).toBeCalledWith(
expect.objectContaining({
variables: {
searchText: '',
currentPage: 1,
pageSize: 25,
},
}),
)
})
it('sets the data of itemsList', () => {
@ -93,121 +99,33 @@ describe('Creation', () => {
})
})
describe('update item', () => {
describe('push item', () => {
beforeEach(() => {
jest.clearAllMocks()
})
describe('push', () => {
beforeEach(() => {
wrapper.findComponent({ name: 'UserTable' }).vm.$emit(
'update-item',
{
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
},
'push',
)
})
it('removes the pushed item from itemsList', () => {
expect(wrapper.vm.itemsList).toEqual([
{
userId: 1,
firstName: 'Bibi',
lastName: 'Bloxberg',
email: 'bibi@bloxberg.de',
creation: [200, 400, 600],
showDetails: false,
},
])
})
it('adds the pushed item to itemsMassCreation', () => {
expect(wrapper.vm.itemsMassCreation).toEqual([
{
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
},
])
})
describe('remove', () => {
beforeEach(() => {
wrapper.findComponent({ name: 'UserTable' }).vm.$emit(
'update-item',
{
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
},
'remove',
)
})
it('removes the item from itemsMassCreation', () => {
expect(wrapper.vm.itemsMassCreation).toEqual([])
})
it('adds the item to itemsList', () => {
expect(wrapper.vm.itemsList).toEqual([
{
userId: 1,
firstName: 'Bibi',
lastName: 'Bloxberg',
email: 'bibi@bloxberg.de',
creation: [200, 400, 600],
showDetails: false,
},
{
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
},
])
})
wrapper.findComponent({ name: 'UserTable' }).vm.$emit('push-item', {
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
})
})
describe('error', () => {
const consoleErrorMock = jest.fn()
const warnHandler = Vue.config.warnHandler
beforeEach(() => {
Vue.config.warnHandler = (w) => {}
// eslint-disable-next-line no-console
console.error = consoleErrorMock
wrapper.findComponent({ name: 'UserTable' }).vm.$emit('update-item', {}, 'no-rule')
})
afterEach(() => {
Vue.config.warnHandler = warnHandler
})
it('throws an error', () => {
expect(consoleErrorMock).toBeCalledWith(expect.objectContaining({ message: 'no-rule' }))
})
it('removes the pushed item from itemsList', () => {
expect(wrapper.vm.itemsList).toEqual([
{
userId: 1,
firstName: 'Bibi',
lastName: 'Bloxberg',
email: 'bibi@bloxberg.de',
creation: [200, 400, 600],
showDetails: false,
},
])
})
})
describe('remove all bookmarks', () => {
beforeEach(async () => {
await wrapper.findComponent({ name: 'UserTable' }).vm.$emit(
'update-item',
it('adds the pushed item to itemsMassCreation', () => {
expect(wrapper.vm.itemsMassCreation).toEqual([
{
userId: 2,
firstName: 'Benjamin',
@ -216,8 +134,87 @@ describe('Creation', () => {
creation: [800, 600, 400],
showDetails: false,
},
'push',
)
])
})
it('updates userSelectedInMassCreation in store', () => {
expect(storeCommitMock).toBeCalledWith('setUserSelectedInMassCreation', [
{
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
},
])
})
})
describe('remove item', () => {
beforeEach(async () => {
await wrapper.findComponent({ name: 'UserTable' }).vm.$emit('push-item', {
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
})
await wrapper
.findAllComponents({ name: 'UserTable' })
.at(1)
.vm.$emit('remove-item', {
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
})
})
it('adds the removed item to itemsList', () => {
expect(wrapper.vm.itemsList).toEqual([
{
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
},
{
userId: 1,
firstName: 'Bibi',
lastName: 'Bloxberg',
email: 'bibi@bloxberg.de',
creation: [200, 400, 600],
showDetails: false,
},
])
})
it('removes the item from itemsMassCreation', () => {
expect(wrapper.vm.itemsMassCreation).toEqual([])
})
it('commits empty array as userSelectedInMassCreation', () => {
expect(storeCommitMock).toBeCalledWith('setUserSelectedInMassCreation', [])
})
})
describe('remove all bookmarks', () => {
beforeEach(async () => {
await wrapper.findComponent({ name: 'UserTable' }).vm.$emit('push-item', {
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
})
jest.clearAllMocks()
wrapper.findComponent({ name: 'CreationFormular' }).vm.$emit('remove-all-bookmark')
})
@ -225,8 +222,41 @@ describe('Creation', () => {
expect(wrapper.vm.itemsMassCreation).toEqual([])
})
it('adds all items to itemsList', () => {
expect(wrapper.vm.itemsList).toHaveLength(2)
it('commits empty array to userSelectedInMassCreation', () => {
expect(storeCommitMock).toBeCalledWith('setUserSelectedInMassCreation', [])
})
it('calls searchUsers', () => {
expect(apolloQueryMock).toBeCalled()
})
})
describe('store has items in userSelectedInMassCreation', () => {
beforeEach(() => {
mocks.$store.state.userSelectedInMassCreation = [
{
userId: 2,
firstName: 'Benjamin',
lastName: 'Blümchen',
email: 'benjamin@bluemchen.de',
creation: [800, 600, 400],
showDetails: false,
},
]
wrapper = Wrapper()
})
it('has only one item itemsList', () => {
expect(wrapper.vm.itemsList).toEqual([
{
userId: 1,
firstName: 'Bibi',
lastName: 'Bloxberg',
email: 'bibi@bloxberg.de',
creation: [200, 400, 600],
showDetails: false,
},
])
})
})
@ -237,12 +267,28 @@ describe('Creation', () => {
it('calls API when criteria changes', async () => {
await wrapper.setData({ criteria: 'XX' })
expect(apolloQueryMock).toBeCalled()
expect(apolloQueryMock).toBeCalledWith(
expect.objectContaining({
variables: {
searchText: 'XX',
currentPage: 1,
pageSize: 25,
},
}),
)
})
it('calls API when currentPage changes', async () => {
await wrapper.setData({ currentPage: 2 })
expect(apolloQueryMock).toBeCalled()
expect(apolloQueryMock).toBeCalledWith(
expect.objectContaining({
variables: {
searchText: '',
currentPage: 2,
pageSize: 25,
},
}),
)
})
})

View File

@ -16,7 +16,7 @@
:fieldsTable="Searchfields"
:criteria="criteria"
:creation="creation"
@update-item="updateItem"
@push-item="pushItem"
/>
<b-pagination
pills
@ -35,7 +35,7 @@
:fieldsTable="fields"
:criteria="null"
:creation="creation"
@update-item="updateItem"
@remove-item="removeItem"
/>
<div v-if="itemsMassCreation.length === 0">
{{ $t('multiple_creation_text') }}
@ -65,52 +65,15 @@ export default {
data() {
return {
showArrays: false,
Searchfields: [
{ key: 'bookmark', label: 'bookmark' },
{ key: 'firstName', label: this.$t('firstname') },
{ key: 'lastName', label: this.$t('lastname') },
{
key: 'creation',
// label: this.$t('open_creation') + 'Jan | Feb | März',
label:
this.$moment().subtract(2, 'month').format('MMM') +
' | ' +
this.$moment().subtract(1, 'month').format('MMM') +
' | ' +
this.$moment().format('MMM'),
formatter: (value, key, item) => {
return String(value[0]) + ` | ` + String(value[1]) + ` | ` + String(value[2])
},
},
{ key: 'email', label: this.$t('e_mail') },
],
fields: [
{ key: 'email', label: this.$t('e_mail') },
{ key: 'firstName', label: this.$t('firstname') },
{ key: 'lastName', label: this.$t('lastname') },
{
key: 'creation',
// label: this.$t('open_creation') + 'Jan | Feb | März',
label:
this.$moment().subtract(2, 'month').format('MMM') +
' | ' +
this.$moment().subtract(1, 'month').format('MMM') +
' | ' +
this.$moment().format('MMM'),
formatter: (value, key, item) => {
return String(value[0]) + ` | ` + String(value[1]) + ` | ` + String(value[2])
},
},
{ key: 'bookmark', label: this.$t('remove') },
],
itemsList: [],
itemsMassCreation: [],
itemsMassCreation: this.$store.state.userSelectedInMassCreation,
radioSelectedMass: '',
criteria: '',
creation: [null, null, null],
rows: 0,
currentPage: 1,
perPage: 25,
now: Date.now(),
}
},
async created() {
@ -136,37 +99,81 @@ export default {
showDetails: false,
}
})
if (this.itemsMassCreation.length !== 0) {
const selectedIndices = this.itemsMassCreation.map((item) => item.userId)
this.itemsList = this.itemsList.filter((item) => !selectedIndices.includes(item.userId))
}
})
.catch((error) => {
this.$toasted.error(error.message)
})
},
updateItem(e, event) {
let index = 0
let findArr = {}
switch (event) {
case 'push':
findArr = this.itemsList.find((item) => e.userId === item.userId)
index = this.itemsList.indexOf(findArr)
this.itemsList.splice(index, 1)
this.itemsMassCreation.push(findArr)
break
case 'remove':
findArr = this.itemsMassCreation.find((item) => e.userId === item.userId)
index = this.itemsMassCreation.indexOf(findArr)
this.itemsMassCreation.splice(index, 1)
this.itemsList.push(findArr)
break
default:
throw new Error(event)
}
pushItem(selectedItem) {
this.itemsMassCreation = [
this.itemsList.find((item) => selectedItem.userId === item.userId),
...this.itemsMassCreation,
]
this.itemsList = this.itemsList.filter((item) => selectedItem.userId !== item.userId)
this.$store.commit('setUserSelectedInMassCreation', this.itemsMassCreation)
},
removeItem(selectedItem) {
this.itemsList = [
this.itemsMassCreation.find((item) => selectedItem.userId === item.userId),
...this.itemsList,
]
this.itemsMassCreation = this.itemsMassCreation.filter(
(item) => selectedItem.userId !== item.userId,
)
this.$store.commit('setUserSelectedInMassCreation', this.itemsMassCreation)
},
removeAllBookmark() {
this.itemsMassCreation = []
this.$store.commit('setUserSelectedInMassCreation', [])
this.getUsers()
},
},
computed: {
Searchfields() {
return [
{ key: 'bookmark', label: 'bookmark' },
{ key: 'firstName', label: this.$t('firstname') },
{ key: 'lastName', label: this.$t('lastname') },
{
key: 'creation',
label: this.creationLabel,
formatter: (value, key, item) => {
return value.join(' | ')
},
},
{ key: 'email', label: this.$t('e_mail') },
]
},
fields() {
return [
{ key: 'email', label: this.$t('e_mail') },
{ key: 'firstName', label: this.$t('firstname') },
{ key: 'lastName', label: this.$t('lastname') },
{
key: 'creation',
label: this.creationLabel,
formatter: (value, key, item) => {
return value.join(' | ')
},
},
{ key: 'bookmark', label: this.$t('remove') },
]
},
creationLabel() {
const now = new Date(this.now)
const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1)
const beforeLastMonth = new Date(now.getFullYear(), now.getMonth() - 2, 1)
return [
this.$d(beforeLastMonth, 'monthShort'),
this.$d(lastMonth, 'monthShort'),
this.$d(now, 'monthShort'),
].join(' | ')
},
},
watch: {
currentPage() {
this.getUsers()

View File

@ -39,6 +39,7 @@ const apolloMutateMock = jest.fn().mockResolvedValue({})
const mocks = {
$t: jest.fn((t) => t),
$d: jest.fn((d) => d),
$store: {
commit: storeCommitMock,
},
@ -50,11 +51,6 @@ const mocks = {
error: toastedErrorMock,
success: toastedSuccessMock,
},
$moment: jest.fn((value) => {
return {
format: jest.fn((format) => value),
}
}),
}
describe('CreationConfirm', () => {

View File

@ -96,9 +96,9 @@ export default {
{ key: 'memo', label: 'Text' },
{
key: 'date',
label: 'Datum',
label: this.$t('date'),
formatter: (value) => {
return this.$moment(value).format('ll')
return this.$d(new Date(value), 'short')
},
},
{ key: 'moderator', label: 'Moderator' },

View File

@ -24,22 +24,13 @@ const toastErrorMock = jest.fn()
const mocks = {
$t: jest.fn((t) => t),
$d: jest.fn((d) => d),
$apollo: {
query: apolloQueryMock,
},
$toasted: {
error: toastErrorMock,
},
$moment: jest.fn(() => {
return {
format: jest.fn((m) => m),
subtract: jest.fn(() => {
return {
format: jest.fn((m) => m),
}
}),
}
}),
}
describe('UserSearch', () => {

View File

@ -44,41 +44,14 @@ export default {
data() {
return {
showArrays: false,
fields: [
{ key: 'email', label: this.$t('e_mail') },
{ key: 'firstName', label: this.$t('firstname') },
{ key: 'lastName', label: this.$t('lastname') },
{
key: 'creation',
label: [
this.$moment().subtract(2, 'month').format('MMM'),
this.$moment().subtract(1, 'month').format('MMM'),
this.$moment().format('MMM'),
].join(' | '),
formatter: (value, key, item) => {
return value.join(' | ')
},
},
{ key: 'show_details', label: this.$t('details') },
{ key: 'confirm_mail', label: this.$t('confirmed') },
{ key: 'transactions_list', label: this.$t('transaction') },
],
searchResult: [],
massCreation: [],
criteria: '',
currentMonth: {
short: this.$moment().format('MMMM'),
},
lastMonth: {
short: this.$moment().subtract(1, 'month').format('MMMM'),
},
beforeLastMonth: {
short: this.$moment().subtract(2, 'month').format('MMMM'),
},
filterCheckedEmails: false,
rows: 0,
currentPage: 1,
perPage: 25,
now: Date.now(),
}
},
methods: {
@ -111,6 +84,37 @@ export default {
this.getUsers()
},
},
computed: {
lastMonthDate() {
const now = new Date(this.now)
return new Date(now.getFullYear(), now.getMonth() - 1, 1)
},
beforeLastMonthDate() {
const now = new Date(this.now)
return new Date(now.getFullYear(), now.getMonth() - 2, 1)
},
fields() {
return [
{ key: 'email', label: this.$t('e_mail') },
{ key: 'firstName', label: this.$t('firstname') },
{ key: 'lastName', label: this.$t('lastname') },
{
key: 'creation',
label: [
this.$d(this.beforeLastMonthDate, 'monthShort'),
this.$d(this.lastMonthDate, 'monthShort'),
this.$d(this.now, 'monthShort'),
].join(' | '),
formatter: (value, key, item) => {
return value.join(' | ')
},
},
{ key: 'show_details', label: this.$t('details') },
{ key: 'confirm_mail', label: this.$t('confirmed') },
{ key: 'transactions_list', label: this.$t('transaction') },
]
},
},
created() {
this.getUsers()
},

View File

@ -24,6 +24,9 @@ export const mutations = {
moderator: (state, moderator) => {
state.moderator = moderator
},
setUserSelectedInMassCreation: (state, userSelectedInMassCreation) => {
state.userSelectedInMassCreation = userSelectedInMassCreation
},
}
export const actions = {
@ -44,6 +47,7 @@ const store = new Vuex.Store({
token: CONFIG.DEBUG_DISABLE_AUTH ? 'validToken' : null,
moderator: null,
openCreations: 0,
userSelectedInMassCreation: [],
},
// Syncronous mutation of the state
mutations,

View File

@ -10,6 +10,7 @@ const {
resetOpenCreations,
setOpenCreations,
moderator,
setUserSelectedInMassCreation,
} = mutations
const { logout } = actions
@ -64,6 +65,14 @@ describe('Vuex store', () => {
expect(state.openCreations).toEqual(12)
})
})
describe('setUserSelectedInMassCreation', () => {
it('sets userSelectedInMassCreation to given value', () => {
const state = { userSelectedInMassCreation: [] }
setUserSelectedInMassCreation(state, [0, 1, 2])
expect(state.userSelectedInMassCreation).toEqual([0, 1, 2])
})
})
})
describe('actions', () => {

View File

@ -9032,11 +9032,6 @@ mkdirp@0.x, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1:
dependencies:
minimist "^1.2.5"
moment@^2.19.2, moment@^2.29.1:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@ -12491,13 +12486,6 @@ vue-loader@^15.9.2:
vue-hot-reload-api "^2.3.0"
vue-style-loader "^4.1.0"
vue-moment@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/vue-moment/-/vue-moment-4.1.0.tgz#092a8ff723a96c6f85a0a8e23ad30f0bf320f3b0"
integrity sha512-Gzisqpg82ItlrUyiD9d0Kfru+JorW2o4mQOH06lEDZNgxci0tv/fua1Hl0bo4DozDV2JK1r52Atn/8QVCu8qQw==
dependencies:
moment "^2.19.2"
vue-router@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.5.3.tgz#041048053e336829d05dafacf6a8fb669a2e7999"

View File

@ -37,8 +37,7 @@
"reflect-metadata": "^0.1.13",
"sodium-native": "^3.3.0",
"ts-jest": "^27.0.5",
"type-graphql": "^1.1.1",
"typeorm": "^0.2.38"
"type-graphql": "^1.1.1"
},
"devDependencies": {
"@types/express": "^4.17.12",

View File

@ -26,4 +26,5 @@ export enum RIGHTS {
SEARCH_PENDING_CREATION = 'SEARCH_PENDING_CREATION',
DELETE_PENDING_CREATION = 'DELETE_PENDING_CREATION',
CONFIRM_PENDING_CREATION = 'CONFIRM_PENDING_CREATION',
SEND_ACTIVATION_EMAIL = 'SEND_ACTIVATION_EMAIL',
}

View File

@ -3,6 +3,10 @@
import dotenv from 'dotenv'
dotenv.config()
const constants = {
DB_VERSION: '0016-transaction_signatures',
}
const server = {
PORT: process.env.PORT || 4000,
JWT_SECRET: process.env.JWT_SECRET || 'secret123',
@ -67,6 +71,7 @@ const webhook = {
process.env.APP_SECRET = server.JWT_SECRET
const CONFIG = {
...constants,
...server,
...database,
...klicktipp,

View File

@ -6,7 +6,7 @@ import { decode, encode } from '../../auth/JWT'
import { ROLE_UNAUTHORIZED, ROLE_USER, ROLE_ADMIN } from '../../auth/ROLES'
import { RIGHTS } from '../../auth/RIGHTS'
import { ServerUserRepository } from '../../typeorm/repository/ServerUser'
import { getCustomRepository } from 'typeorm'
import { getCustomRepository } from '@dbTools/typeorm'
import { UserRepository } from '../../typeorm/repository/User'
import { INALIENABLE_RIGHTS } from '../../auth/INALIENABLE_RIGHTS'

View File

@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Resolver, Query, Arg, Args, Authorized, Mutation, Ctx } from 'type-graphql'
import { getCustomRepository, Raw } from 'typeorm'
import { getCustomRepository, Raw } from '@dbTools/typeorm'
import { UserAdmin, SearchUsersResult } from '../model/UserAdmin'
import { PendingCreation } from '../model/PendingCreation'
import { CreatePendingCreations } from '../model/CreatePendingCreations'
@ -10,7 +10,6 @@ import { UpdatePendingCreation } from '../model/UpdatePendingCreation'
import { RIGHTS } from '../../auth/RIGHTS'
import { TransactionRepository } from '../../typeorm/repository/Transaction'
import { TransactionCreationRepository } from '../../typeorm/repository/TransactionCreation'
import { LoginPendingTasksAdminRepository } from '../../typeorm/repository/LoginPendingTasksAdmin'
import { UserRepository } from '../../typeorm/repository/User'
import CreatePendingCreationArgs from '../arg/CreatePendingCreationArgs'
import UpdatePendingCreationArgs from '../arg/UpdatePendingCreationArgs'
@ -23,7 +22,7 @@ import { UserTransactionRepository } from '../../typeorm/repository/UserTransact
import { BalanceRepository } from '../../typeorm/repository/Balance'
import { calculateDecay } from '../../util/decay'
import { LoginUserRepository } from '../../typeorm/repository/LoginUser'
import { LoginPendingTasksAdmin } from '@entity/LoginPendingTasksAdmin'
import { AdminPendingCreation } from '@entity/AdminPendingCreation'
@Resolver()
export class AdminResolver {
@ -68,16 +67,15 @@ export class AdminResolver {
const creations = await getUserCreations(user.id)
const creationDateObj = new Date(creationDate)
if (isCreationValid(creations, amount, creationDateObj)) {
const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository)
const loginPendingTaskAdmin = loginPendingTasksAdminRepository.create()
loginPendingTaskAdmin.userId = user.id
loginPendingTaskAdmin.amount = BigInt(amount * 10000)
loginPendingTaskAdmin.created = new Date()
loginPendingTaskAdmin.date = creationDateObj
loginPendingTaskAdmin.memo = memo
loginPendingTaskAdmin.moderator = moderator
const adminPendingCreation = AdminPendingCreation.create()
adminPendingCreation.userId = user.id
adminPendingCreation.amount = BigInt(amount * 10000)
adminPendingCreation.created = new Date()
adminPendingCreation.date = creationDateObj
adminPendingCreation.memo = memo
adminPendingCreation.moderator = moderator
await loginPendingTasksAdminRepository.save(loginPendingTaskAdmin)
await AdminPendingCreation.save(adminPendingCreation)
}
return getUserCreations(user.id)
}
@ -116,8 +114,7 @@ export class AdminResolver {
const userRepository = getCustomRepository(UserRepository)
const user = await userRepository.findByEmail(email)
const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository)
const pendingCreationToUpdate = await loginPendingTasksAdminRepository.findOneOrFail({ id })
const pendingCreationToUpdate = await AdminPendingCreation.findOneOrFail({ id })
if (pendingCreationToUpdate.userId !== user.id) {
throw new Error('user of the pending creation and send user does not correspond')
@ -137,7 +134,7 @@ export class AdminResolver {
pendingCreationToUpdate.date = new Date(creationDate)
pendingCreationToUpdate.moderator = moderator
await loginPendingTasksAdminRepository.save(pendingCreationToUpdate)
await AdminPendingCreation.save(pendingCreationToUpdate)
const result = new UpdatePendingCreation()
result.amount = parseInt(amount.toString())
result.memo = pendingCreationToUpdate.memo
@ -151,8 +148,7 @@ export class AdminResolver {
@Authorized([RIGHTS.SEARCH_PENDING_CREATION])
@Query(() => [PendingCreation])
async getPendingCreations(): Promise<PendingCreation[]> {
const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository)
const pendingCreations = await loginPendingTasksAdminRepository.find()
const pendingCreations = await AdminPendingCreation.find()
const pendingCreationsPromise = await Promise.all(
pendingCreations.map(async (pendingCreation) => {
@ -179,18 +175,15 @@ export class AdminResolver {
@Authorized([RIGHTS.DELETE_PENDING_CREATION])
@Mutation(() => Boolean)
async deletePendingCreation(@Arg('id') id: number): Promise<boolean> {
const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository)
const entity = await loginPendingTasksAdminRepository.findOneOrFail(id)
const res = await loginPendingTasksAdminRepository.delete(entity)
const entity = await AdminPendingCreation.findOneOrFail(id)
const res = await AdminPendingCreation.delete(entity)
return !!res
}
@Authorized([RIGHTS.CONFIRM_PENDING_CREATION])
@Mutation(() => Boolean)
async confirmPendingCreation(@Arg('id') id: number, @Ctx() context: any): Promise<boolean> {
const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository)
const pendingCreation = await loginPendingTasksAdminRepository.findOneOrFail(id)
const pendingCreation = await AdminPendingCreation.findOneOrFail(id)
const userRepository = getCustomRepository(UserRepository)
const moderatorUser = await userRepository.findByPubkeyHex(context.pubKey)
if (moderatorUser.id === pendingCreation.userId)
@ -202,7 +195,6 @@ export class AdminResolver {
transaction.transactionTypeId = 1
transaction.memo = pendingCreation.memo
transaction.received = receivedCallDate
transaction.blockchainTypeId = 1
transaction = await transactionRepository.save(transaction)
if (!transaction) throw new Error('Could not create transaction')
@ -251,7 +243,7 @@ export class AdminResolver {
userBalance.modified = receivedCallDate
userBalance.recordDate = receivedCallDate
await balanceRepository.save(userBalance)
await loginPendingTasksAdminRepository.delete(pendingCreation)
await AdminPendingCreation.delete(pendingCreation)
return true
}
@ -280,12 +272,12 @@ async function getUserCreations(id: number): Promise<number[]> {
.orderBy('target_month', 'ASC')
.getRawMany()
const loginPendingTasksAdminRepository = getCustomRepository(LoginPendingTasksAdminRepository)
const pendingAmountsQuery = await loginPendingTasksAdminRepository
.createQueryBuilder('login_pending_tasks_admin')
.select('MONTH(login_pending_tasks_admin.date)', 'target_month')
.addSelect('SUM(login_pending_tasks_admin.amount)', 'sum')
.where('login_pending_tasks_admin.userId = :id', { id })
const pendingAmountsQuery = await AdminPendingCreation.createQueryBuilder(
'admin_pending_creations',
)
.select('MONTH(admin_pending_creations.date)', 'target_month')
.addSelect('SUM(admin_pending_creations.amount)', 'sum')
.where('admin_pending_creations.userId = :id', { id })
.andWhere({
date: Raw((alias) => `${alias} >= :date and ${alias} < :endDate`, {
date: dateBeforeLastMonth,
@ -336,7 +328,7 @@ async function getUserCreations(id: number): Promise<number[]> {
]
}
function updateCreations(creations: number[], pendingCreation: LoginPendingTasksAdmin): number[] {
function updateCreations(creations: number[], pendingCreation: AdminPendingCreation): number[] {
const dateMonth = moment().format('YYYY-MM')
const dateLastMonth = moment().subtract(1, 'month').format('YYYY-MM')
const dateBeforeLastMonth = moment().subtract(2, 'month').format('YYYY-MM')

View File

@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Resolver, Query, Ctx, Authorized } from 'type-graphql'
import { getCustomRepository } from 'typeorm'
import { getCustomRepository } from '@dbTools/typeorm'
import { Balance } from '../model/Balance'
import { BalanceRepository } from '../../typeorm/repository/Balance'
import { UserRepository } from '../../typeorm/repository/User'

View File

@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Resolver, Query, Args, Ctx, Authorized, Arg } from 'type-graphql'
import { getCustomRepository } from 'typeorm'
import { getCustomRepository } from '@dbTools/typeorm'
import CONFIG from '../../config'
import { GdtEntryList } from '../model/GdtEntryList'
import Paginated from '../arg/Paginated'

View File

@ -3,7 +3,7 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Resolver, Query, Args, Authorized, Ctx, Mutation } from 'type-graphql'
import { getCustomRepository, getConnection, QueryRunner } from 'typeorm'
import { getCustomRepository, getConnection, QueryRunner } from '@dbTools/typeorm'
import CONFIG from '../../config'
import { sendTransactionReceivedEmail } from '../../mailer/sendTransactionReceivedEmail'
@ -36,172 +36,6 @@ import { hasUserAmount, isHexPublicKey } from '../../util/validate'
import { LoginUserRepository } from '../../typeorm/repository/LoginUser'
import { RIGHTS } from '../../auth/RIGHTS'
/*
# Test
## Prepare
> sudo systemctl start docker
> docker-compose up mariadb
> DROP all databases
> docker-compose down
> docker compose up mariadb database
> verify there is exactly one database `gradido_community`
TODO:
INSERT INTO `login_groups` (`id`, `alias`, `name`, `url`, `host`, `home`, `description`) VALUES
(1, 'docker', 'docker gradido group', 'localhost', 'nginx', '/', 'gradido test group for docker and stage2 with blockchain db');
>> Database is cool
### Start login server
> docker-compose up login-server community-server nginx
>> Login & community servers and nginx proxy are up and running
## Build database
> cd database
> yarn
> yarn build
> cd ..
>> Database has been built successful
### Start backend (no docker for debugging)
> cd backend
> yarn
> yarn dev
>> Backend is up and running
### Create users
> chromium http://localhost:4000/graphql
> mutation{createUser(email: "receiver@user.net", firstName: "Receiver", lastName: "user", password: "123!AAAb", language: "de")}
> mutation{createUser(email: "sender@user.net", firstName: "Sender", lastName: "user", password: "123!AAAb", language: "de")}
> mutation{createUser(email: "creator@user.net", firstName: "Creator", lastName: "user", password: "123!AAAb", language: "de")}
>> Verify you have 3 entries in `login_users`, `login_user_backups` and `state_users`
### make creator an admin
> INSERT INTO login_user_roles (id, user_id, role_id) VALUES (NULL, '3', '1');
> UPDATE login_users SET email_checked = 1 WHERE id = 3;
> uncomment line: 19 in community_server/src/Controller/ServerUsersController.php
> chromium http://localhost/server-users/add
> create user `creator` `123` `creator@different.net`
>> verify you have 1 entry in `server_users`
> login with user on http://localhost/server-users
> activate server user by changing the corresponding flag in the interface
> navigate to http://localhost/transaction-creations/create-multi
> create 1000GDD for user sender@user.net
> navigate to http://localhost
> login with `creator@user.net` `123!AAAb`
> confirm transaction (top right corner - click the thingy, click the green button `Transaktion abschließen`)
### the test:
> chromium http://localhost:4000/graphql
> query{login(email: "sender@user.net", password: "123!AAAb"){pubkey}}
>> copy token from network tab (inspect)
> mutation{sendCoins(email: "receiver@user.net", amount: 10.0, memo: "Hier!")}
> mutation{sendCoins(email: "receiver@user.net", amount: 10.0, memo: "Hier!")}
> Headers: {"Authorization": "Bearer ${token}"}
>> Verify via Database that stuff is as it should see `state_balance` & `transaction_send_coins`
### create decay block
> chromium http://localhost/transactions/add
> login with `creator` `123`
> select `decay start`
> press submit
> wait for at least 0.02 display of decay on user sender@user.net on old frontend, this should be aprox 10min
> chromium http://localhost:4000/graphql
> query{login(email: "sender@user.net", password: "123!AAAb"){pubkey}}
>> copy token from network tab (inspect)
> mutation{sendCoins(email: "receiver@user.net", amount: 10.0, memo: "Hier!")}
>> verify in `transaction_send_coins` that a decay was taken into account
>> same in `state_balances`
>> now check the old frontend
>>> sender@user.net should have a decay of 0.02
>>> while receiver@user.net should have zero decay on anything (old frontend)
### Export data
> docker-compose up phpmyadmin
> chromium http://localhost:8074/
> select gradido_community
> export
> select custom
> untick structure
> ok
## Results
NOTE: We decided not to write the `transaction_signatures` since its unused. This is the main difference.
NOTE: We fixed a bug in the `state_user_transactions code` with the new implementation of apollo
Master:
--
-- Dumping data for table `state_user_transactions`
--
INSERT INTO `state_user_transactions` (`id`, `state_user_id`, `transaction_id`, `transaction_type_id`, `balance`, `balance_date`) VALUES
(1, 2, 1, 1, 10000000, '2021-11-05 12:45:18'),
(2, 2, 2, 2, 9900000, '2021-11-05 12:48:35'),
(3, 1, 2, 2, 100000, '2021-11-05 12:48:35'),
(4, 2, 3, 2, 9800000, '2021-11-05 12:49:07'),
(5, 1, 3, 2, 200000, '2021-11-05 12:49:07'),
(6, 2, 5, 2, 9699845, '2021-11-05 13:03:50'),
(7, 1, 5, 2, 99996, '2021-11-05 13:03:50');
--
-- Dumping data for table `transactions`
--
INSERT INTO `transactions` (`id`, `state_group_id`, `transaction_type_id`, `tx_hash`, `memo`, `received`, `blockchain_type_id`) VALUES
(1, NULL, 1, 0x9ccdcd01ccb6320c09c2d1da2f0bf735a95ece0e7c1df6bbff51918fbaec061700000000000000000000000000000000, '', '2021-11-05 12:45:18', 1),
(2, NULL, 2, 0x58d7706a67fa4ff4b8038168c6be39a2963d7e28e9d3872759ad09c519fe093700000000000000000000000000000000, 'Hier!', '2021-11-05 12:48:35', 1),
(3, NULL, 2, 0x427cd214f92ef35af671129d50edc5a478c53d1e464f285b7615d9794a69f69b00000000000000000000000000000000, 'Hier!', '2021-11-05 12:49:07', 1),
(4, NULL, 9, 0x32807368f0906a21b94c072599795bc9eeab88fb565df82e85cc62a4fdcde48500000000000000000000000000000000, '', '2021-11-05 12:51:51', 1),
(5, NULL, 2, 0x75eb729e0f60a1c8cead1342955853d2440d7a2ea57dfef6d4a18bff0d94491e00000000000000000000000000000000, 'Hier!', '2021-11-05 13:03:50', 1);
--
-- Dumping data for table `transaction_signatures`
--
INSERT INTO `transaction_signatures` (`id`, `transaction_id`, `signature`, `pubkey`) VALUES
(1, 1, 0x5888edcdcf77aaadad6d321882903bc831d7416f17213fd5020a764365b5fcb336e4c7917385a1278ea44ccdb31eac4a09e448053b5e3f8f1fe5da3baf53c008, 0xd5b20f8dee415038bfa2b6b0e1b40ff54850351109444863b04d6d28825b7b7d),
(2, 2, 0xf6fef428f8f22faf7090f7d740e6088d1d90c58ae92d757117d7d91d799e659f3a3a0c65a3fd97cbde798e761f9d23eff13e8810779a184c97c411f28e7c4608, 0xdc74a589004377ab14836dce68ce2ca34e5b17147cd78ad4b3afe8137524ae8a),
(3, 3, 0x8ebe9730c6cf61f56ef401d6f2bd229f3c298ca3c2791ee9137e4827b7af6c6d6566fca616eb1fe7adc2e4d56b5c7350ae3990c9905580630fa75ecffca8e001, 0xdc74a589004377ab14836dce68ce2ca34e5b17147cd78ad4b3afe8137524ae8a),
(4, 5, 0x50cf418f7e217391e89ab9c2879ae68d7c7c597d846b4fe1c082b5b16e5d0c85c328fbf48ad3490bcfe94f446700ae0a4b0190e76d26cc752abced58f480c80f, 0xdc74a589004377ab14836dce68ce2ca34e5b17147cd78ad4b3afe8137524ae8a);
This Feature Branch:
--
-- Dumping data for table `state_user_transactions`
--
INSERT INTO `state_user_transactions` (`id`, `state_user_id`, `transaction_id`, `transaction_type_id`, `balance`, `balance_date`) VALUES
(1, 2, 1, 1, 10000000, '2021-11-05 00:25:46'),
(12, 2, 7, 2, 9900000, '2021-11-05 00:55:37'),
(13, 1, 7, 2, 100000, '2021-11-05 00:55:37'),
(14, 2, 8, 2, 9800000, '2021-11-05 01:00:04'),
(15, 1, 8, 2, 200000, '2021-11-05 01:00:04'),
(16, 2, 10, 2, 9699772, '2021-11-05 01:17:41'),
(17, 1, 10, 2, 299995, '2021-11-05 01:17:41');
--
-- Dumping data for table `transactions`
--
INSERT INTO `transactions` (`id`, `state_group_id`, `transaction_type_id`, `tx_hash`, `memo`, `received`, `blockchain_type_id`) VALUES
(1, NULL, 1, 0xdd030d475479877587d927ed9024784ba62266cf1f3d87862fc98ad68f7b26e400000000000000000000000000000000, '', '2021-11-05 00:25:46', 1),
(7, NULL, 2, NULL, 'Hier!', '2021-11-05 00:55:37', 1),
(8, NULL, 2, NULL, 'Hier!', '2021-11-05 01:00:04', 1),
(9, NULL, 9, 0xb1cbedbf126aa35f5edbf06e181c415361d05228ab4da9d19a4595285a673dfa00000000000000000000000000000000, '', '2021-11-05 01:05:34', 1),
(10, NULL, 2, NULL, 'Hier!', '2021-11-05 01:17:41', 1);
--
-- Dumping data for table `transaction_signatures`
--
INSERT INTO `transaction_signatures` (`id`, `transaction_id`, `signature`, `pubkey`) VALUES
(1, 1, 0x60d632479707e5d01cdc32c3326b5a5bae11173a0c06b719ee7b552f9fd644de1a0cd4afc207253329081d39dac1a63421f51571d836995c649fc39afac7480a, 0x48c45cb4fea925e83850f68f2fa8f27a1a4ed1bcba68cdb59fcd86adef3f52ee);
*/
// Helper function
async function calculateAndAddDecayTransactions(
userTransactions: dbUserTransaction[],

View File

@ -3,7 +3,7 @@
import fs from 'fs'
import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql'
import { getConnection, getCustomRepository, getRepository, QueryRunner } from 'typeorm'
import { getConnection, getCustomRepository, getRepository, QueryRunner } from '@dbTools/typeorm'
import CONFIG from '../../config'
import { User } from '../model/User'
import { User as DbUser } from '@entity/User'
@ -476,6 +476,8 @@ export class UserResolver {
return 'success'
}
// THis is used by the admin only - should we move it to the admin resolver?
@Authorized([RIGHTS.SEND_ACTIVATION_EMAIL])
@Mutation(() => Boolean)
async sendActivationEmail(@Arg('email') email: string): Promise<boolean> {
const loginUserRepository = getCustomRepository(LoginUserRepository)

View File

@ -1,15 +1,12 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import 'reflect-metadata'
import 'module-alias/register'
import { ApolloServer } from 'apollo-server-express'
import express from 'express'
import express, { Express } from 'express'
// database
import connection from '../typeorm/connection'
import getDBVersion from '../typeorm/getDBVersion'
import { checkDBVersion } from '../typeorm/DBVersion'
// server
import cors from './cors'
@ -24,27 +21,25 @@ import schema from '../graphql/schema'
// webhooks
import { elopageWebhook } from '../webhook/elopage'
import { Connection } from '@dbTools/typeorm'
// TODO implement
// import queryComplexity, { simpleEstimator, fieldConfigEstimator } from "graphql-query-complexity";
const DB_VERSION = '0012-login_user_backups_unify_wordlist'
type ServerDef = { apollo: ApolloServer; app: Express; con: Connection }
const createServer = async (context: any = serverContext): Promise<any> => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const createServer = async (context: any = serverContext): Promise<ServerDef> => {
// open mysql connection
const con = await connection()
if (!con || !con.isConnected) {
throw new Error(`Couldn't open connection to database`)
throw new Error(`Fatal: Couldn't open connection to database`)
}
// check for correct database version
const dbVersion = await getDBVersion()
if (!dbVersion || dbVersion.indexOf(DB_VERSION) === -1) {
throw new Error(
`Wrong database version - the backend requires '${DB_VERSION}' but found '${
dbVersion || 'None'
}'`,
)
const dbVersion = await checkDBVersion(CONFIG.DB_VERSION)
if (!dbVersion) {
throw new Error('Fatal: Database Version incorrect')
}
// Express Server
@ -58,15 +53,6 @@ const createServer = async (context: any = serverContext): Promise<any> => {
// bodyparser urlencoded for elopage
app.use(express.urlencoded({ extended: true }))
// Log every request
/*
app.use((req, res, next) => {
// eslint-disable-next-line no-console
console.log(req)
next()
})
*/
// Elopage Webhook
app.post('/hook/elopage/' + CONFIG.WEBHOOK_ELOPAGE_SECRET, elopageWebhook)

View File

@ -0,0 +1,28 @@
import { Migration } from '@entity/Migration'
const getDBVersion = async (): Promise<string | null> => {
try {
const dbVersion = await Migration.findOne({ order: { version: 'DESC' } })
return dbVersion ? dbVersion.fileName : null
} catch (error) {
// eslint-disable-next-line no-console
console.log(error)
return null
}
}
const checkDBVersion = async (DB_VERSION: string): Promise<boolean> => {
const dbVersion = await getDBVersion()
if (!dbVersion || dbVersion.indexOf(DB_VERSION) === -1) {
// eslint-disable-next-line no-console
console.log(
`Wrong database version detected - the backend requires '${DB_VERSION}' but found '${
dbVersion || 'None'
}`,
)
return false
}
return true
}
export { checkDBVersion, getDBVersion }

View File

@ -1,11 +1,12 @@
import { createConnection, Connection, FileLogger } from 'typeorm'
// TODO This is super weird - since the entities are defined in another project they have their own globals.
// We cannot use our connection here, but must use the external typeorm installation
import { Connection, createConnection, FileLogger } from '@dbTools/typeorm'
import CONFIG from '../config'
import { entities } from '@entity/index'
const connection = async (): Promise<Connection | null> => {
let con = null
try {
con = await createConnection({
return createConnection({
name: 'default',
type: 'mysql',
host: CONFIG.DB_HOST,
@ -23,9 +24,8 @@ const connection = async (): Promise<Connection | null> => {
} catch (error) {
// eslint-disable-next-line no-console
console.log(error)
return null
}
return con
}
export default connection

View File

@ -1,15 +0,0 @@
import { getRepository } from 'typeorm'
import { Migration } from '@entity/Migration'
const getDBVersion = async (): Promise<string | null> => {
try {
const dbVersion = await getRepository(Migration).findOne({ order: { version: 'DESC' } })
return dbVersion ? dbVersion.fileName : null
} catch (error) {
// eslint-disable-next-line no-console
console.log(error)
return null
}
}
export default getDBVersion

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { Balance } from '@entity/Balance'
@EntityRepository(Balance)

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { LoginElopageBuys } from '@entity/LoginElopageBuys'
@EntityRepository(LoginElopageBuys)

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
@EntityRepository(LoginEmailOptIn)

View File

@ -1,5 +0,0 @@
import { EntityRepository, Repository } from 'typeorm'
import { LoginPendingTasksAdmin } from '@entity/LoginPendingTasksAdmin'
@EntityRepository(LoginPendingTasksAdmin)
export class LoginPendingTasksAdminRepository extends Repository<LoginPendingTasksAdmin> {}

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { LoginUser } from '@entity/LoginUser'
@EntityRepository(LoginUser)

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { LoginUserBackup } from '@entity/LoginUserBackup'
@EntityRepository(LoginUserBackup)

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { ServerUser } from '@entity/ServerUser'
@EntityRepository(ServerUser)

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { Transaction } from '@entity/Transaction'
@EntityRepository(Transaction)

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { TransactionCreation } from '@entity/TransactionCreation'
@EntityRepository(TransactionCreation)

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { User } from '@entity/User'
@EntityRepository(User)

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { UserSetting } from '@entity/UserSetting'
import { Setting } from '../../graphql/enum/Setting'
import { isStringBoolean } from '../../util/validate'

View File

@ -1,4 +1,4 @@
import { EntityRepository, Repository } from 'typeorm'
import { EntityRepository, Repository } from '@dbTools/typeorm'
import { Order } from '../../graphql/enum/Order'
import { UserTransaction } from '@entity/UserTransaction'
import { TransactionTypeId } from '../../graphql/enum/TransactionTypeId'

View File

@ -1,4 +1,4 @@
import { getCustomRepository } from 'typeorm'
import { getCustomRepository } from '@dbTools/typeorm'
import { Decay } from '../graphql/model/Decay'
import { TransactionRepository } from '../typeorm/repository/Transaction'

View File

@ -1,6 +1,6 @@
import { User as dbUser } from '@entity/User'
import { Balance as dbBalance } from '@entity/Balance'
import { getRepository } from 'typeorm'
import { getRepository } from '@dbTools/typeorm'
import { calculateDecay } from './decay'
function isStringBoolean(value: string): boolean {

View File

@ -28,7 +28,7 @@
*/
import { LoginElopageBuys } from '@entity/LoginElopageBuys'
import { getCustomRepository } from 'typeorm'
import { getCustomRepository } from '@dbTools/typeorm'
import { UserResolver } from '../graphql/resolver/UserResolver'
import { LoginElopageBuysRepository } from '../typeorm/repository/LoginElopageBuys'
import { LoginUserRepository } from '../typeorm/repository/LoginUser'

View File

@ -677,11 +677,6 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@sqltools/formatter@^1.2.2":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.3.tgz#1185726610acc37317ddab11c3c7f9066966bd20"
integrity sha512-O3uyB/JbkAEMZaP3YqyHH7TMnex7tWyCbCI4EfJdOCoN6HIhqdJBWTM6aCCiWQ/5f5wxjgU735QAIpJbjDvmzg==
"@szmarczak/http-timer@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
@ -1012,11 +1007,6 @@
dependencies:
"@types/yargs-parser" "*"
"@types/zen-observable@0.8.3":
version "0.8.3"
resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3"
integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==
"@typescript-eslint/eslint-plugin@^4.28.0":
version "4.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276"
@ -1191,21 +1181,11 @@ ansi-escapes@^4.2.1:
dependencies:
type-fest "^0.21.3"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@ -1225,11 +1205,6 @@ ansi-styles@^5.0.0:
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
anymatch@^3.0.3, anymatch@~3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
@ -1436,11 +1411,6 @@ apollo-utilities@^1.0.1, apollo-utilities@^1.3.0:
ts-invariant "^0.4.0"
tslib "^1.10.0"
app-root-path@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad"
integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==
arg@^4.1.0:
version "4.1.3"
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
@ -1453,11 +1423,6 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@ -1583,11 +1548,6 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
binary-extensions@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
@ -1678,14 +1638,6 @@ buffer-from@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
buffer@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.2.1"
busboy@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b"
@ -1739,17 +1691,6 @@ caniuse-lite@^1.0.30001264:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz#0613c9e6c922e422792e6fcefdf9a3afeee4f8c3"
integrity sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==
chalk@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
dependencies:
ansi-styles "^2.2.1"
escape-string-regexp "^1.0.2"
has-ansi "^2.0.0"
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.0.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@ -1816,18 +1757,6 @@ cli-boxes@^2.2.1:
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
cli-highlight@^2.1.11:
version "2.1.11"
resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.11.tgz#49736fa452f0aaf4fae580e30acb26828d2dc1bf"
integrity sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==
dependencies:
chalk "^4.0.0"
highlight.js "^10.7.1"
mz "^2.4.0"
parse5 "^5.1.1"
parse5-htmlparser2-tree-adapter "^6.0.0"
yargs "^16.0.0"
cliui@^7.0.2:
version "7.0.4"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
@ -2151,11 +2080,6 @@ dotenv@^10.0.0:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
dotenv@^8.2.0:
version "8.6.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==
duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
@ -2264,7 +2188,7 @@ escape-html@~1.0.3:
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
@ -2619,11 +2543,6 @@ fb-watchman@^2.0.0:
dependencies:
bser "2.1.1"
figlet@^1.1.1:
version "1.5.2"
resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.5.2.tgz#dda34ff233c9a48e36fcff6741aeb5bafe49b634"
integrity sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ==
file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
@ -2911,13 +2830,6 @@ graphql@^15.5.1:
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.6.1.tgz#9125bdf057553525da251e19e96dab3d3855ddfc"
integrity sha512-3i5lu0z6dRvJ48QP9kFxBkJ7h4Kso7PS8eahyTFz5Jm6CvQfLtNIE8LX9N6JLnXTuwR+sIYnXzaWp6anOg0QQw==
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
dependencies:
ansi-regex "^2.0.0"
has-bigints@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
@ -2957,11 +2869,6 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
highlight.js@^10.7.1:
version "10.7.3"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
hosted-git-info@^2.1.4:
version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
@ -3053,11 +2960,6 @@ iconv-lite@^0.6.2:
dependencies:
safer-buffer ">= 2.1.2 < 3.0.0"
ieee754@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
ignore-by-default@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
@ -3797,13 +3699,6 @@ js-yaml@^3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
jsdom@^16.6.0:
version "16.7.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710"
@ -4180,11 +4075,6 @@ minimist@^1.2.0, minimist@^1.2.5:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
mkdirp@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
module-alias@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0"
@ -4229,15 +4119,6 @@ mysql2@^2.3.0:
seq-queue "^0.0.5"
sqlstring "^2.3.2"
mz@^2.4.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"
named-placeholders@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/named-placeholders/-/named-placeholders-1.1.2.tgz#ceb1fbff50b6b33492b5cf214ccf5e39cef3d0e8"
@ -4347,7 +4228,7 @@ nwsapi@^2.2.0:
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==
object-assign@^4, object-assign@^4.0.1:
object-assign@^4:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
@ -4500,11 +4381,6 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
parent-require@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/parent-require/-/parent-require-1.0.0.tgz#746a167638083a860b0eef6732cb27ed46c32977"
integrity sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc=
parse-json@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
@ -4513,23 +4389,11 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
parse5-htmlparser2-tree-adapter@^6.0.0:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
dependencies:
parse5 "^6.0.1"
parse5@6.0.1, parse5@^6.0.1:
parse5@6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
parse5@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178"
integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==
parseurl@^1.3.2, parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@ -4887,11 +4751,6 @@ safe-buffer@^5.0.1:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
sax@>=0.6.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
saxes@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d"
@ -5136,13 +4995,6 @@ string.prototype.trimstart@^1.0.4:
call-bind "^1.0.2"
define-properties "^1.1.3"
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
dependencies:
ansi-regex "^2.0.0"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
@ -5186,11 +5038,6 @@ subscriptions-transport-ws@^0.9.19:
symbol-observable "^1.0.4"
ws "^5.2.0 || ^6.0.0 || ^7.0.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
supports-color@^5.3.0, supports-color@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
@ -5264,20 +5111,6 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.1"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
dependencies:
any-promise "^1.0.0"
throat@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375"
@ -5462,29 +5295,6 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"
typeorm@^0.2.38:
version "0.2.38"
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.38.tgz#2af08079919f6ab04cd17017f9faa2c8d5cd566f"
integrity sha512-M6Y3KQcAREQcphOVJciywf4mv6+A0I/SeR+lWNjKsjnQ+a3XcMwGYMGL0Jonsx3H0Cqlf/3yYqVki1jIXSK/xg==
dependencies:
"@sqltools/formatter" "^1.2.2"
app-root-path "^3.0.0"
buffer "^6.0.3"
chalk "^4.1.0"
cli-highlight "^2.1.11"
debug "^4.3.1"
dotenv "^8.2.0"
glob "^7.1.6"
js-yaml "^4.0.0"
mkdirp "^1.0.4"
reflect-metadata "^0.1.13"
sha.js "^2.4.11"
tslib "^2.1.0"
xml2js "^0.4.23"
yargonaut "^1.1.4"
yargs "^17.0.1"
zen-observable-ts "^1.0.0"
typescript@^4.3.4:
version "4.4.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324"
@ -5750,19 +5560,6 @@ xml-name-validator@^3.0.0:
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
xml2js@^0.4.23:
version "0.4.23"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
dependencies:
sax ">=0.6.0"
xmlbuilder "~11.0.0"
xmlbuilder@~11.0.0:
version "11.0.1"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
xmlchars@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
@ -5791,21 +5588,12 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargonaut@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/yargonaut/-/yargonaut-1.1.4.tgz#c64f56432c7465271221f53f5cc517890c3d6e0c"
integrity sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==
dependencies:
chalk "^1.1.1"
figlet "^1.1.1"
parent-require "^1.0.0"
yargs-parser@20.x, yargs-parser@^20.2.2:
version "20.2.9"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
yargs@^16.0.0, yargs@^16.2.0:
yargs@^16.2.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
@ -5818,19 +5606,6 @@ yargs@^16.0.0, yargs@^16.2.0:
y18n "^5.0.5"
yargs-parser "^20.2.2"
yargs@^17.0.1:
version "17.2.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.1.tgz#e2c95b9796a0e1f7f3bf4427863b42e0418191ea"
integrity sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==
dependencies:
cliui "^7.0.2"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.0"
y18n "^5.0.5"
yargs-parser "^20.2.2"
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
@ -5844,15 +5619,7 @@ zen-observable-ts@^0.8.21:
tslib "^1.9.3"
zen-observable "^0.8.0"
zen-observable-ts@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz#2d1aa9d79b87058e9b75698b92791c1838551f83"
integrity sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA==
dependencies:
"@types/zen-observable" "0.8.3"
zen-observable "0.8.15"
zen-observable@0.8.15, zen-observable@^0.8.0:
zen-observable@^0.8.0:
version "0.8.15"
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15"
integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==

Binary file not shown.

View File

@ -1,515 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-21 13:37+0200\n"
"PO-Revision-Date: 2021-06-21 13:38+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.0\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: build/http_pages/LoginPage.cpp:196 build/http_pages/LoginPage.cpp:275
msgid "Login"
msgstr "Anmeldung"
#: build/http_pages/LoginPage.cpp:196
msgid "E-Mail or password isn't right, please try again!"
msgstr ""
"E-Mail und Passwort Kombination stimmen nicht, bitte versuche es erneut. "
#: build/http_pages/LoginPage.cpp:205
msgid "Passwort"
msgstr "Passwort"
#: build/http_pages/LoginPage.cpp:205
msgid ""
"Passwort wird noch berechnet, bitte versuche es in etwa 1 Minute erneut."
msgstr ""
#: build/http_pages/LoginPage.cpp:208 build/http_pages/LoginPage.cpp:211
msgid "User"
msgstr ""
#: build/http_pages/LoginPage.cpp:208
msgid "Error in saved data, the server admin will look at it."
msgstr ""
#: build/http_pages/LoginPage.cpp:211
msgid "Benutzer ist deaktiviert, kein Login möglich!"
msgstr ""
#: build/http_pages/LoginPage.cpp:275
msgid "Username and password are needed!"
msgstr "E-Mail und Passwort werden benötigt!"
#: build/http_pages/LoginPage.cpp:376 src/cpp/model/Session.cpp:161
#: src/cpp/model/Session.cpp:168 src/cpp/model/Session.cpp:220
#: src/cpp/model/Session.cpp:231
msgid "E-Mail"
msgstr ""
#: build/http_pages/LoginPage.cpp:381
#: src/cpp/SingletonManager/SessionManager.cpp:603
#: src/cpp/SingletonManager/SessionManager.cpp:609
#: src/cpp/SingletonManager/SessionManager.cpp:614
#: src/cpp/SingletonManager/SessionManager.cpp:619
#: src/cpp/SingletonManager/SessionManager.cpp:624
#: src/cpp/SingletonManager/SessionManager.cpp:629
msgid "Password"
msgstr "Passwort"
#: build/http_pages/LoginPage.cpp:384
msgid " Login "
msgstr "Anmeldung"
#: build/http_pages/LoginPage.cpp:391
msgid "You haven't any account yet? Please follow the link to create one."
msgstr "Du hast noch kein Gradido-Konto?"
#: build/http_pages/LoginPage.cpp:395
msgid "Create New Account"
msgstr "Neues Konto erstellen"
#: build/http_pages/LoginPage.cpp:403
msgid "Passwort vergessen"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:155
msgid "E-Mail verifizieren"
msgstr "E-Mail überprüfen"
#: build/http_pages/CheckEmailPage.cpp:165
msgid ""
"Deine E-Mail wurde erfolgreich bestätigt. Du kannst nun Gradidos versenden."
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:170
msgid "Zur Startseite"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:175
msgid "Bitte gib deinen E-Mail Verification Code ein:"
msgstr "Bitte gib deinen E-Mail Verification Code ein:"
#: build/http_pages/CheckEmailPage.cpp:178 src/cpp/model/Session.cpp:184
msgid "Email Verification Code"
msgstr "Email Verification Code"
#: build/http_pages/CheckEmailPage.cpp:185
msgid "&Uuml;berpr&uuml;fe Code"
msgstr "&Uuml;berpr&uuml;fe Code"
#: build/http_pages/CheckEmailPage.cpp:190
msgid "Du hast bisher keinen Code erhalten?"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:193
msgid "E-Mail erneut zuschicken (in Arbeit)"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:198
msgid "Funktioniert dein E-Mail Verification Code nicht?"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:201
msgid "Schicke uns eine E-Mail und wir k&uuml;mmern uns darum: "
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:208
#: build/http_pages/ResetPasswordPage.cpp:273
msgid "E-Mail an Support schicken"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:174
#: build/http_pages/ResetPasswordPage.cpp:217
msgid "Gib bitte hier deine E-Mail Adresse an:"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:183
msgid "Bestätigen"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:225
msgid "Hast du dir deine Passphrase notiert oder gemerkt?"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:234
#: build/http_pages/PassphrasePage.cpp:373
msgid "Ja"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:241
msgid "Nein"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:247
msgid "Absenden"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:255
msgid "Dir wird eine E-Mail zugeschickt um dein Passwort zur&uuml;ckzusetzen."
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:260
msgid "Der Admin hat eine E-Mail bekommen und wird sich bei dir melden."
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:265
msgid ""
"Du hast bereits eine E-Mail bekommen. Bitte schau auch in dein Spam-"
"Verzeichnis nach. "
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:268
msgid ""
"Du hast wirklich keine E-Mail erhalten und auch schon ein paar Minuten "
"gewartet?"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:41
#: build/http_pages/PassphrasePage.cpp:111
#: build/http_pages/PassphrasePage.cpp:132 src/cpp/model/Session.cpp:465
#: src/cpp/model/Session.cpp:477 src/cpp/model/Session.cpp:491
msgid "Passphrase"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:42
#: build/http_pages/PassphrasePage.cpp:451
msgid "Neues Konto anlegen"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:43
msgid "2/3"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:111
msgid ""
"Diese Passphrase ist ung&uuml;ltig, bitte &uuml;berpr&uuml;fen oder neu "
"generieren (lassen)."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:132
msgid "intern error please try again later"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:147
msgid "3/3"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:150
#: build/http_pages/PassphrasePage.cpp:153
msgid "1/3"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:152
msgid "Neues Passwort anlegen"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:270
msgid "Passphrase abschreiben"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:287
msgid "Was ist eine Passphrase?"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:290
msgid "Deine Passphrase besteht aus den im grünen Feld angezeigten Wörtern."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:293
msgid "Sie dient deiner Sicherheit."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:296
msgid ""
"Du brauchst deine Passphrase um dein Konto wiederherzustellen, wenn du mal "
"dein Passwort vergessen haben solltest."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:300
msgid "Deine Passphrase (Groß/Kleinschreibung beachten)"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:309
#: build/http_pages/PassphrasePage.cpp:352
msgid "Was zu tun ist:"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:312
msgid ""
"Schreibe dir die obenstehende Passphrase <b>von Hand</b> auf ein Blatt "
"Papier!"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:315
msgid "Speichere sie auf keinen Fall auf deinem Rechner oder Mobilgerät!!"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:318
msgid "Bewahre sie an einem sicheren Ort auf!"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:322
#: build/http_pages/PassphrasePage.cpp:478
#: build/http_pages/PassphrasePage.cpp:487
#: build/http_pages/PassphrasePage.cpp:511
msgid "Weiter"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:355
msgid "Hast du dir deine Passphrase gemerkt?"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:358
msgid ""
"Dann zeig es mir. Zur Unterstützung gebe ich dir deine Wörter aber in "
"anderer Reihenfolge."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:361
msgid "Klicke sie an um sie einzusetzen."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:364
msgid "Überprüfe dabei, ob du alle Wörter richtig geschrieben hast!"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:370
msgid ""
"Weil du kein Javascript verwendest geht es direkt weiter. Hast du dir deine "
"Passphrase gemerkt oder aufgeschrieben?"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:429
msgid "Deine E-Mail Adresse wurde erfolgreich bestätigt."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:437
msgid "Neue Gradido Adresse anlegen / wiederherstellen"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:440
msgid ""
"Möchtest du ein neues Gradido-Konto anlegen oder ein bestehendes "
"wiederherstellen?"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:460
msgid "Bestehendes Konto wiederherstellen"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:469
msgid ""
"Falls du ein bestehendes Konto wiederherstellen willst, gib hier deine "
"Passphrase ein:"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:497
msgid "Konto wiederherstellen / Neues Passwort anlegen"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:501
msgid ""
"Um dein Konto wiederherzustellen und dir ein Neues Passwort auswählen zu "
"können, tippe hier bitte die Wörter deiner Passphrase in der richtigen "
"Reihenfolge ein, welche du dir aufgeschrieben hast."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:524
msgid "Fehler"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:527
msgid ""
"Ungültige Seite, wenn du das siehst stimmt hier etwas nicht. Bitte wende "
"dich an den Server-Admin."
msgstr ""
#: src/cpp/model/Session.cpp:147 src/cpp/model/Session.cpp:177
#: src/cpp/model/Session.cpp:645 src/cpp/model/Session.cpp:651
#: src/cpp/model/Session.cpp:937 src/cpp/model/Session.cpp:953
msgid "Benutzer"
msgstr ""
#: src/cpp/model/Session.cpp:147
msgid "Eingeloggter Benutzer ist kein Admin"
msgstr ""
#: src/cpp/model/Session.cpp:153 src/cpp/model/Session.cpp:212
msgid "Vorname"
msgstr ""
#: src/cpp/model/Session.cpp:153 src/cpp/model/Session.cpp:157
#: src/cpp/model/Session.cpp:212 src/cpp/model/Session.cpp:216
msgid ""
"Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen "
"<>&;"
msgstr ""
#: src/cpp/model/Session.cpp:157 src/cpp/model/Session.cpp:216
msgid "Nachname"
msgstr ""
#: src/cpp/model/Session.cpp:161 src/cpp/model/Session.cpp:220
msgid "Bitte gebe eine g&uuml;ltige E-Mail Adresse an."
msgstr ""
#: src/cpp/model/Session.cpp:168
msgid "F&uuml;r diese E-Mail Adresse gibt es bereits einen Account"
msgstr ""
#: src/cpp/model/Session.cpp:177 src/cpp/model/Session.cpp:184
msgid "Fehler beim speichern!"
msgstr ""
#: src/cpp/model/Session.cpp:231
msgid "F&uuml;r diese E-Mail Adresse gibt es bereits ein Konto"
msgstr ""
#: src/cpp/model/Session.cpp:255
msgid "Server"
msgstr ""
#: src/cpp/model/Session.cpp:255
msgid "Fehler beim speichen des Kontos bitte versuche es später noch einmal"
msgstr ""
#: src/cpp/model/Session.cpp:350 src/cpp/model/Session.cpp:390
#: src/cpp/model/Session.cpp:832 src/cpp/model/Session.cpp:841
msgid "E-Mail Verification"
msgstr "E-Mail Überprüfung"
#: src/cpp/model/Session.cpp:350
msgid "Du hast dein Konto bereits aktiviert!"
msgstr ""
#: src/cpp/model/Session.cpp:390
msgid "Falscher Code f&uuml;r aktiven Login"
msgstr ""
#: src/cpp/model/Session.cpp:465
msgid "Deine Passphrase ist ung&uuml;tig"
msgstr ""
#: src/cpp/model/Session.cpp:477
msgid "Ein Fehler trat auf, bitte versuche es erneut"
msgstr ""
#: src/cpp/model/Session.cpp:491
msgid "Das ist nicht die richtige Passphrase."
msgstr ""
#: src/cpp/model/Session.cpp:645
msgid "Konnte Community Server nicht erreichen. E-Mail an den Admin ist raus."
msgstr ""
#: src/cpp/model/Session.cpp:651
msgid ""
"Fehler beim L&ouml;schen des Accounts. Bitte logge dich erneut ein und "
"versuche es nochmal."
msgstr ""
#: src/cpp/model/Session.cpp:832
msgid "Konnte kein passendes Konto finden."
msgstr ""
#: src/cpp/model/Session.cpp:841
msgid "Fehler beim laden des Benutzers."
msgstr ""
#: src/cpp/model/Session.cpp:937
msgid "Kein g&uuml;ltiger Benutzer, bitte logge dich erneut ein."
msgstr ""
#: src/cpp/model/Session.cpp:953
msgid "Fehler beim generieren der Passphrase, der Admin bekommt eine E-Mail. "
msgstr ""
#: src/cpp/model/email/Email.cpp:174
msgid "Default Email Subject"
msgstr ""
#: src/cpp/model/email/Email.cpp:180
msgid "Error from Gradido Login Server"
msgstr "Fehler auf dem Gradido Login Server"
#: src/cpp/model/email/Email.cpp:200
msgid "Gradido: E-Mail Verification"
msgstr "Gradido: E-Mail Überprüfung"
#: src/cpp/model/email/Email.cpp:246
msgid "Gradido: Reset Password"
msgstr "Gradido: Passwort zurücksetzen"
#: src/cpp/SingletonManager/SessionManager.cpp:604
msgid ""
"Please enter a valid password with at least 8 characters, upper and lower "
"case letters, at least one number and one special character (@$!%*?&+-_)!"
msgstr ""
"Bitte gebe ein gültiges Password ein mit mindestens 8 Zeichen, Groß- und "
"Kleinbuchstaben, mindestens einer Zahl und einem Sonderzeichen (@$!%*?&+-_) "
"ein!"
#: src/cpp/SingletonManager/SessionManager.cpp:610
msgid "Your password is to short!"
msgstr "Dein Passwort ist zu kurz!"
#: src/cpp/SingletonManager/SessionManager.cpp:615
msgid "Your password does not contain lowercase letters!"
msgstr "Dein Passwort enthält keine Kleinbuchstaben!"
#: src/cpp/SingletonManager/SessionManager.cpp:620
msgid "Your password does not contain any capital letters!"
msgstr " Dein Passwort enthält keine Großbuchstaben!"
#: src/cpp/SingletonManager/SessionManager.cpp:625
msgid "Your password does not contain any number!"
msgstr "Dein Passwort enthält keine Zahlen!"
#: src/cpp/SingletonManager/SessionManager.cpp:630
msgid "Your password does not contain special characters (@$!%*?&+-)!"
msgstr "Dein Passwort enthält keine Sonderzeichen (@$!%*?&+-)!"
#~ msgid "Account"
#~ msgstr "Konto"
#~ msgid "E-Mail Address not checked, do you already get one?"
#~ msgstr ""
#~ "E-Mail Adresse wurde noch nicht überprüft. Hast du schon in deine E-Mails "
#~ "geschaut? Bitte schau auch in dein Spam-Verzeichnis nach."
#~ msgid ""
#~ "Schreibe dir deine Passphrase auf und packe sie gut weg. Du brauchst sie "
#~ "um deine Adresse wiederherzustellen. Wenn du sie verlierst, sind auch "
#~ "deine Gradidos verloren."
#~ msgstr ""
#~ "Schreibe dir deine Passphrase auf oder drucke sie aus und bewahre sie "
#~ "<b>in Papier-Form</b> an einem sicheren Ort auf (speichere sie nicht auf "
#~ "deinem Rechner oder Mobilgerät)! Du brauchst deine Passphrase um dein "
#~ "Konto wiederherzustellen, wenn du mal dein Passort vergessen haben "
#~ "solltest. "
#~ msgid ""
#~ "Der neue Gradido basiert technisch auf einer Kryptowährung (wie z.B. "
#~ "Bitcoin) um maximale Sicherheit zu erreichen."
#~ msgstr ""
#~ "Der neue Gradido basiert technisch auf einer Kryptowährung (wie z.B. "
#~ "Bitcoin) um für dich die maximale Sicherheit zu gewährleisten."
#~ msgid ""
#~ "Der Code stimmt nicht, bitte &uuml;berpr&uuml;fe ihn nochmal oder "
#~ "registriere dich erneut oder wende dich an den Server-Admin"
#~ msgstr ""
#~ "Der Code stimmt nicht, bitte &uuml;berpr&uuml;fe ihn nochmal oder "
#~ "schreibe mir eine E-Mail an: coin@gradido.net."

Binary file not shown.

View File

@ -1,428 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-05-28 10:50+0200\n"
"PO-Revision-Date: 2020-05-28 10:53+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: en_GB\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.3.1\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:85
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:124
msgid "Login"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:85
msgid "E-Mail or password isn't right, please try again!"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:88
msgid "Passwort"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:88
msgid ""
"Passwort wird noch berechnet, bitte versuche es in etwa 1 Minute erneut."
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:91
msgid "Account"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:91
msgid "E-Mail Address not checked, do you already get one?"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:124
msgid "Username and password are needed!"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:175
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:50
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:54
#: model/Session.cpp:163 model/Session.cpp:170 model/Session.cpp:209
#: model/Session.cpp:234
msgid "E-Mail"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:178
msgid "Password"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:180
msgid " Login "
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:182
msgid "You haven't any account yet? Please follow the link to create one."
msgstr "Don't have an Gradido-account yet?"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:183
msgid "Create New Account"
msgstr "Sign Up"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\login.cpsp:186
msgid "Passwort vergessen"
msgstr "Reset Password"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkEmail.cpsp:97
msgid "Bitte gebe deinen E-Mail Verification Code ein:"
msgstr "Please enter your E-Mail Verification Code:"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkEmail.cpsp:98
#: model/Session.cpp:186
msgid "Email Verification Code"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkEmail.cpsp:100
msgid "&Uuml;berpr&uuml;fe Code"
msgstr "Check Code"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkEmail.cpsp:104
msgid "Du hast bisher keinen Code erhalten?"
msgstr "You didn't get a code yet?"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkEmail.cpsp:105
msgid "E-Mail erneut zuschicken (in Arbeit)"
msgstr "Re-Send E-Mail (work in progress)"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkEmail.cpsp:108
msgid "Funktioniert dein E-Mail Verification Code nicht?"
msgstr "Your E-Mail Verfication Code doesn't work?"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkEmail.cpsp:109
msgid "Schicke uns eine E-Mail und wir k&uuml;mmern uns darum: "
msgstr "Send us a E-Mail and we take care of it:"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\checkEmail.cpsp:110
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:133
msgid "E-Mail an Support schicken"
msgstr "Send E-Mail to support"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:50
msgid "E-Mail Adresse konnte nicht gefunden werden oder ist nicht aktiviert."
msgstr "E-Mail not found or not activated."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:54
msgid "E-Mail Adresse nicht angegeben."
msgstr "Please give your E-Mail Address."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:59
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:74
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:26
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:94
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:114
#: model/Session.cpp:495 model/Session.cpp:507 model/Session.cpp:515
msgid "Passphrase"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:59
msgid "Bitte w&auml;hle eine Option aus."
msgstr "Please choose one Option."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:74
msgid "Ung&uuml;ltige Option"
msgstr "Invalid option"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:107
msgid "Gebe bitte hier deine E-Mail Adresse an:"
msgstr "Please enter a valid email."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:109
msgid "Hast du dir deine Passphrase notiert oder gemerkt?"
msgstr "Do you memorized your passphrase?"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:113
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:196
msgid "Ja"
msgstr "Yes"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:118
msgid "Nein"
msgstr "No"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:123
msgid "Absenden"
msgstr "Send"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:127
msgid "Dir wird eine E-Mail zugeschickt um dein Passwort zur&uuml;ckzusetzen."
msgstr "You get an E-Mail to reset your password."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:129
msgid "Der Admin hat eine E-Mail bekommen und wird sich bei dir melden."
msgstr "The Admin get an E-Mail, wait on his replay."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:131
msgid ""
"Du hast bereits eine E-Mail bekommen. Bitte schau auch in dein Spam-"
"Verzeichnis nach. "
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\resetPassword.cpsp:132
msgid ""
"Du hast wirklich keine E-Mail erhalten und auch schon ein paar Minuten "
"gewartet?"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:27
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:256
msgid "Neues Konto anlegen"
msgstr "Create new Account"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:28
msgid "2/3"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:94
msgid ""
"Diese Passphrase ist ung&uuml;ltig, bitte &uuml;berpr&uuml;fen oder neu "
"generieren (lassen)."
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:114
msgid "intern error please try again later"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:129
msgid "3/3"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:132
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:135
msgid "1/3"
msgstr ""
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:134
msgid "Neues Passwort anlegen"
msgstr "Create new Password"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:153
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:188
msgid "Was zu tun ist:"
msgstr "What to do:"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:154
msgid ""
"Schreibe dir deine Passphrase auf und packe sie gut weg. Du brauchst sie um "
"deine Adresse wiederherzustellen. Wenn du sie verlierst, sind auch deine "
"Gradidos verloren."
msgstr ""
"Write down your passphrase and put it away well. You need it to restore your "
"address. If you lose them, your Gradidos are lost too."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:157
msgid "Deine Passphrase (Groß/Kleinschreibung beachten)"
msgstr "Your Passphrase"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:161
msgid "Was ist eine Passphrase?"
msgstr "What is a passphrase?"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:162
msgid ""
"Die Passphrase kommt aus dem Crypto-Bereich und ist ein Weg einen "
"komplizierte kryptografischen Schlüssel in einer lesbaren Form darzustellen."
msgstr ""
"The passphrase comes from the crypto area and is a way to represent a "
"complicated cryptographic key in a legible form."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:163
msgid ""
"Der neue Gradido basiert technisch auf einer Kryptowährung (wie z.B. "
"Bitcoin) um maximale Sicherheit zu erreichen."
msgstr ""
"The new Gradido is technically based on a cryptocurrency (such as Bitcoin) "
"to achieve maximum security for you."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:165
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:275
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:280
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:293
msgid "Weiter"
msgstr "Next"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:189
msgid "Hast du dir deine Passphrase gemerkt?"
msgstr "Do you memorized your passphrase?"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:190
msgid ""
"Dann zeig es mir. Zur Unterstützung gebe ich dir deine Wörter aber in "
"anderer Reihenfolge."
msgstr ""
"Then show me. I will give you your words in a different order as support."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:191
msgid "Klicke sie an um sie einzusetzen."
msgstr "Click on it to use it."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:195
msgid ""
"Weil du kein Javascript verwendest geht es direkt weiter. Hast du dir deine "
"Passphrase gemerkt oder aufgeschrieben?"
msgstr ""
"Because you don't use javascript it goes straight on. Did you remember or "
"write down your passphrase?"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:242
msgid "Deine E-Mail Adresse wurde erfolgreich bestätigt."
msgstr "Your email address has been successfully confirmed."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:246
msgid "Neue Gradido Adresse anlegen / wiederherstellen"
msgstr "Create / restore new Gradido address"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:247
msgid ""
"Möchtest du ein neues Gradido-Konto anlegen oder ein bestehendes "
"wiederherstellen?"
msgstr ""
"Do you want to restore an existing Gradido account or create a new one?"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:263
msgid "Bestehendes Konto wiederherstellen"
msgstr "Restore existing Account"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:270
msgid ""
"Falls du ein bestehendes Konto wiederherstellen willst, gib hier deine "
"Passphrase ein:"
msgstr ""
"If you want to restore an existing account, enter your passphrase here:"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:288
msgid "Konto wiederherstellen / Neues Passwort anlegen"
msgstr "Restore account / create new password"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:289
msgid ""
"Um dein Konto wiederherzustellen, dir ein Neues Passwort auswählen zu "
"können, tippe hier bitte die Wörter deiner Passphrase in der richtigen "
"Reihenfolge ein, welche du dir aufgeschrieben hast."
msgstr ""
"To restore your account and to be able to choose a new password, please type "
"in the words of your passphrase in the correct order, which you have written "
"down."
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:303
msgid "Fehler"
msgstr "Erro"
#: F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp:304
msgid ""
"Ungültige Seite, wenn du das siehst stimmt hier etwas nicht. Bitte wende "
"dich an den Server-Admin."
msgstr ""
"Invalid page, if you see that something is wrong here. Please contact the "
"server admin."
#: model/Session.cpp:149 model/Session.cpp:180 model/Session.cpp:700
#: model/Session.cpp:706 model/Session.cpp:1005
msgid "Benutzer"
msgstr "User"
#: model/Session.cpp:149
msgid "Eingeloggter Benutzer ist kein Admin"
msgstr "Logged in user is not admin"
#: model/Session.cpp:155 model/Session.cpp:201
msgid "Vorname"
msgstr "Firstname"
#: model/Session.cpp:155 model/Session.cpp:159 model/Session.cpp:201
#: model/Session.cpp:205
msgid ""
"Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen "
"<>&;"
msgstr "Please enter your Name. At least 3 Character, without <>& and ;"
#: model/Session.cpp:159 model/Session.cpp:205
msgid "Nachname"
msgstr "Lastname"
#: model/Session.cpp:163 model/Session.cpp:209
msgid "Bitte gebe eine g&uuml;ltige E-Mail Adresse an."
msgstr "Please enter a valid email."
#: model/Session.cpp:170 model/Session.cpp:234
msgid "F&uuml;r diese E-Mail Adresse gibt es bereits einen Account"
msgstr "This email has an account already."
#: model/Session.cpp:180 model/Session.cpp:186
msgid "Fehler beim speichern!"
msgstr "Error while saving!"
#: model/Session.cpp:379 model/Session.cpp:438 model/Session.cpp:881
#: model/Session.cpp:889
msgid "E-Mail Verification"
msgstr ""
#: model/Session.cpp:379
msgid "Du hast dein Konto bereits aktiviert!"
msgstr "You already activated your account!"
#: model/Session.cpp:438
msgid "Falscher Code f&uuml;r aktiven Login"
msgstr "Wrong Code for active Login."
#: model/Session.cpp:495
msgid "Deine Passphrase ist ung&uuml;tig"
msgstr "Your passphrase is invalid"
#: model/Session.cpp:507
msgid "Ein Fehler trat auf, bitte versuche es erneut"
msgstr "An error occurred, please try again"
#: model/Session.cpp:515
msgid "Das ist nicht die richtige Passphrase."
msgstr "This is not the correct passphrase."
#: model/Session.cpp:700
msgid "Konnte Community Server nicht erreichen. E-Mail an den Admin ist raus."
msgstr "Couldn't connect to the community server, send E-Mail to admin."
#: model/Session.cpp:706
msgid ""
"Fehler beim L&ouml;schen des Accounts. Bitte logge dich erneut ein und "
"versuche es nochmal."
msgstr "Error by deleting the account. Please re-login and try again."
#: model/Session.cpp:881
msgid "Konnte kein passendes Konto finden."
msgstr "This Account didn't seem to exist."
#: model/Session.cpp:889
msgid "Fehler beim laden des Benutzers."
msgstr ""
#: model/Session.cpp:1005
msgid "Kein g&uuml;ltiger Benutzer, bitte logge dich erneut ein."
msgstr "Invalid User, please re-login."
#~ msgid "*Das Konto muss nach dem 01.09.2019 angelegt worden sein."
#~ msgstr "* The account must have been created after September 1st, 2019."
#~ msgid "Nein, bitte ein neues erstellen!"
#~ msgstr "No, please create a new one!"
#~ msgid "Deine Passphrase"
#~ msgstr "Your passphrase"
#~ msgid ""
#~ "Der Code stimmt nicht, bitte &uuml;berpr&uuml;fe ihn nochmal oder "
#~ "registriere dich erneut oder wende dich an den Server-Admin"
#~ msgstr ""
#~ "The email verification code isn't correct. Please check at spell errors "
#~ "and try again or ask the server admin."

View File

@ -1,477 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-06-21 13:37+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: build/http_pages/LoginPage.cpp:196 build/http_pages/LoginPage.cpp:275
msgid "Login"
msgstr ""
#: build/http_pages/LoginPage.cpp:196
msgid "E-Mail or password isn't right, please try again!"
msgstr ""
#: build/http_pages/LoginPage.cpp:205
msgid "Passwort"
msgstr ""
#: build/http_pages/LoginPage.cpp:205
msgid ""
"Passwort wird noch berechnet, bitte versuche es in etwa 1 Minute erneut."
msgstr ""
#: build/http_pages/LoginPage.cpp:208 build/http_pages/LoginPage.cpp:211
msgid "User"
msgstr ""
#: build/http_pages/LoginPage.cpp:208
msgid "Error in saved data, the server admin will look at it."
msgstr ""
#: build/http_pages/LoginPage.cpp:211
msgid "Benutzer ist deaktiviert, kein Login möglich!"
msgstr ""
#: build/http_pages/LoginPage.cpp:275
msgid "Username and password are needed!"
msgstr ""
#: build/http_pages/LoginPage.cpp:376 src/cpp/model/Session.cpp:161
#: src/cpp/model/Session.cpp:168 src/cpp/model/Session.cpp:220
#: src/cpp/model/Session.cpp:231
msgid "E-Mail"
msgstr ""
#: build/http_pages/LoginPage.cpp:381
#: src/cpp/SingletonManager/SessionManager.cpp:603
#: src/cpp/SingletonManager/SessionManager.cpp:609
#: src/cpp/SingletonManager/SessionManager.cpp:614
#: src/cpp/SingletonManager/SessionManager.cpp:619
#: src/cpp/SingletonManager/SessionManager.cpp:624
#: src/cpp/SingletonManager/SessionManager.cpp:629
msgid "Password"
msgstr ""
#: build/http_pages/LoginPage.cpp:384
msgid " Login "
msgstr ""
#: build/http_pages/LoginPage.cpp:391
msgid "You haven't any account yet? Please follow the link to create one."
msgstr ""
#: build/http_pages/LoginPage.cpp:395
msgid "Create New Account"
msgstr ""
#: build/http_pages/LoginPage.cpp:403
msgid "Passwort vergessen"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:155
msgid "E-Mail verifizieren"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:165
msgid ""
"Deine E-Mail wurde erfolgreich bestätigt. Du kannst nun Gradidos versenden."
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:170
msgid "Zur Startseite"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:175
msgid "Bitte gib deinen E-Mail Verification Code ein:"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:178 src/cpp/model/Session.cpp:184
msgid "Email Verification Code"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:185
msgid "&Uuml;berpr&uuml;fe Code"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:190
msgid "Du hast bisher keinen Code erhalten?"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:193
msgid "E-Mail erneut zuschicken (in Arbeit)"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:198
msgid "Funktioniert dein E-Mail Verification Code nicht?"
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:201
msgid "Schicke uns eine E-Mail und wir k&uuml;mmern uns darum: "
msgstr ""
#: build/http_pages/CheckEmailPage.cpp:208
#: build/http_pages/ResetPasswordPage.cpp:273
msgid "E-Mail an Support schicken"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:174
#: build/http_pages/ResetPasswordPage.cpp:217
msgid "Gib bitte hier deine E-Mail Adresse an:"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:183
msgid "Bestätigen"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:225
msgid "Hast du dir deine Passphrase notiert oder gemerkt?"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:234
#: build/http_pages/PassphrasePage.cpp:373
msgid "Ja"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:241
msgid "Nein"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:247
msgid "Absenden"
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:255
msgid "Dir wird eine E-Mail zugeschickt um dein Passwort zur&uuml;ckzusetzen."
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:260
msgid "Der Admin hat eine E-Mail bekommen und wird sich bei dir melden."
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:265
msgid ""
"Du hast bereits eine E-Mail bekommen. Bitte schau auch in dein Spam-"
"Verzeichnis nach. "
msgstr ""
#: build/http_pages/ResetPasswordPage.cpp:268
msgid ""
"Du hast wirklich keine E-Mail erhalten und auch schon ein paar Minuten "
"gewartet?"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:41
#: build/http_pages/PassphrasePage.cpp:111
#: build/http_pages/PassphrasePage.cpp:132 src/cpp/model/Session.cpp:465
#: src/cpp/model/Session.cpp:477 src/cpp/model/Session.cpp:491
msgid "Passphrase"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:42
#: build/http_pages/PassphrasePage.cpp:451
msgid "Neues Konto anlegen"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:43
msgid "2/3"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:111
msgid ""
"Diese Passphrase ist ung&uuml;ltig, bitte &uuml;berpr&uuml;fen oder neu "
"generieren (lassen)."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:132
msgid "intern error please try again later"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:147
msgid "3/3"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:150
#: build/http_pages/PassphrasePage.cpp:153
msgid "1/3"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:152
msgid "Neues Passwort anlegen"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:270
msgid "Passphrase abschreiben"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:287
msgid "Was ist eine Passphrase?"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:290
msgid "Deine Passphrase besteht aus den im grünen Feld angezeigten Wörtern."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:293
msgid "Sie dient deiner Sicherheit."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:296
msgid ""
"Du brauchst deine Passphrase um dein Konto wiederherzustellen, wenn du mal "
"dein Passwort vergessen haben solltest."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:300
msgid "Deine Passphrase (Groß/Kleinschreibung beachten)"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:309
#: build/http_pages/PassphrasePage.cpp:352
msgid "Was zu tun ist:"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:312
msgid ""
"Schreibe dir die obenstehende Passphrase <b>von Hand</b> auf ein Blatt "
"Papier!"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:315
msgid "Speichere sie auf keinen Fall auf deinem Rechner oder Mobilgerät!!"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:318
msgid "Bewahre sie an einem sicheren Ort auf!"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:322
#: build/http_pages/PassphrasePage.cpp:478
#: build/http_pages/PassphrasePage.cpp:487
#: build/http_pages/PassphrasePage.cpp:511
msgid "Weiter"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:355
msgid "Hast du dir deine Passphrase gemerkt?"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:358
msgid ""
"Dann zeig es mir. Zur Unterstützung gebe ich dir deine Wörter aber in "
"anderer Reihenfolge."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:361
msgid "Klicke sie an um sie einzusetzen."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:364
msgid "Überprüfe dabei, ob du alle Wörter richtig geschrieben hast!"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:370
msgid ""
"Weil du kein Javascript verwendest geht es direkt weiter. Hast du dir deine "
"Passphrase gemerkt oder aufgeschrieben?"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:429
msgid "Deine E-Mail Adresse wurde erfolgreich bestätigt."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:437
msgid "Neue Gradido Adresse anlegen / wiederherstellen"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:440
msgid ""
"Möchtest du ein neues Gradido-Konto anlegen oder ein bestehendes "
"wiederherstellen?"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:460
msgid "Bestehendes Konto wiederherstellen"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:469
msgid ""
"Falls du ein bestehendes Konto wiederherstellen willst, gib hier deine "
"Passphrase ein:"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:497
msgid "Konto wiederherstellen / Neues Passwort anlegen"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:501
msgid ""
"Um dein Konto wiederherzustellen und dir ein Neues Passwort auswählen zu "
"können, tippe hier bitte die Wörter deiner Passphrase in der richtigen "
"Reihenfolge ein, welche du dir aufgeschrieben hast."
msgstr ""
#: build/http_pages/PassphrasePage.cpp:524
msgid "Fehler"
msgstr ""
#: build/http_pages/PassphrasePage.cpp:527
msgid ""
"Ungültige Seite, wenn du das siehst stimmt hier etwas nicht. Bitte wende "
"dich an den Server-Admin."
msgstr ""
#: src/cpp/model/Session.cpp:147 src/cpp/model/Session.cpp:177
#: src/cpp/model/Session.cpp:645 src/cpp/model/Session.cpp:651
#: src/cpp/model/Session.cpp:937 src/cpp/model/Session.cpp:953
msgid "Benutzer"
msgstr ""
#: src/cpp/model/Session.cpp:147
msgid "Eingeloggter Benutzer ist kein Admin"
msgstr ""
#: src/cpp/model/Session.cpp:153 src/cpp/model/Session.cpp:212
msgid "Vorname"
msgstr ""
#: src/cpp/model/Session.cpp:153 src/cpp/model/Session.cpp:157
#: src/cpp/model/Session.cpp:212 src/cpp/model/Session.cpp:216
msgid ""
"Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen "
"<>&;"
msgstr ""
#: src/cpp/model/Session.cpp:157 src/cpp/model/Session.cpp:216
msgid "Nachname"
msgstr ""
#: src/cpp/model/Session.cpp:161 src/cpp/model/Session.cpp:220
msgid "Bitte gebe eine g&uuml;ltige E-Mail Adresse an."
msgstr ""
#: src/cpp/model/Session.cpp:168
msgid "F&uuml;r diese E-Mail Adresse gibt es bereits einen Account"
msgstr ""
#: src/cpp/model/Session.cpp:177 src/cpp/model/Session.cpp:184
msgid "Fehler beim speichern!"
msgstr ""
#: src/cpp/model/Session.cpp:231
msgid "F&uuml;r diese E-Mail Adresse gibt es bereits ein Konto"
msgstr ""
#: src/cpp/model/Session.cpp:255
msgid "Server"
msgstr ""
#: src/cpp/model/Session.cpp:255
msgid "Fehler beim speichen des Kontos bitte versuche es später noch einmal"
msgstr ""
#: src/cpp/model/Session.cpp:350 src/cpp/model/Session.cpp:390
#: src/cpp/model/Session.cpp:832 src/cpp/model/Session.cpp:841
msgid "E-Mail Verification"
msgstr ""
#: src/cpp/model/Session.cpp:350
msgid "Du hast dein Konto bereits aktiviert!"
msgstr ""
#: src/cpp/model/Session.cpp:390
msgid "Falscher Code f&uuml;r aktiven Login"
msgstr ""
#: src/cpp/model/Session.cpp:465
msgid "Deine Passphrase ist ung&uuml;tig"
msgstr ""
#: src/cpp/model/Session.cpp:477
msgid "Ein Fehler trat auf, bitte versuche es erneut"
msgstr ""
#: src/cpp/model/Session.cpp:491
msgid "Das ist nicht die richtige Passphrase."
msgstr ""
#: src/cpp/model/Session.cpp:645
msgid "Konnte Community Server nicht erreichen. E-Mail an den Admin ist raus."
msgstr ""
#: src/cpp/model/Session.cpp:651
msgid ""
"Fehler beim L&ouml;schen des Accounts. Bitte logge dich erneut ein und "
"versuche es nochmal."
msgstr ""
#: src/cpp/model/Session.cpp:832
msgid "Konnte kein passendes Konto finden."
msgstr ""
#: src/cpp/model/Session.cpp:841
msgid "Fehler beim laden des Benutzers."
msgstr ""
#: src/cpp/model/Session.cpp:937
msgid "Kein g&uuml;ltiger Benutzer, bitte logge dich erneut ein."
msgstr ""
#: src/cpp/model/Session.cpp:953
msgid "Fehler beim generieren der Passphrase, der Admin bekommt eine E-Mail. "
msgstr ""
#: src/cpp/model/email/Email.cpp:174
msgid "Default Email Subject"
msgstr ""
#: src/cpp/model/email/Email.cpp:180
msgid "Error from Gradido Login Server"
msgstr ""
#: src/cpp/model/email/Email.cpp:200
msgid "Gradido: E-Mail Verification"
msgstr ""
#: src/cpp/model/email/Email.cpp:246
msgid "Gradido: Reset Password"
msgstr ""
#: src/cpp/SingletonManager/SessionManager.cpp:604
msgid ""
"Please enter a valid password with at least 8 characters, upper and lower "
"case letters, at least one number and one special character (@$!%*?&+-_)!"
msgstr ""
#: src/cpp/SingletonManager/SessionManager.cpp:610
msgid "Your password is to short!"
msgstr ""
#: src/cpp/SingletonManager/SessionManager.cpp:615
msgid "Your password does not contain lowercase letters!"
msgstr ""
#: src/cpp/SingletonManager/SessionManager.cpp:620
msgid "Your password does not contain any capital letters!"
msgstr ""
#: src/cpp/SingletonManager/SessionManager.cpp:625
msgid "Your password does not contain any number!"
msgstr ""
#: src/cpp/SingletonManager/SessionManager.cpp:630
msgid "Your password does not contain special characters (@$!%*?&+-)!"
msgstr ""

File diff suppressed because it is too large Load Diff

View File

@ -1,58 +0,0 @@
HTTPServer.port = 1200
JSONServer.port = 1201
Gradido.group_id = 1
crypto.server_admin_public = f909a866baec97c5460b8d7a93b72d3d4d20cc45d9f15d78bd83944eb9286b7f
crypto.server_key = a51ef8ac7ef1abf162fb7a65261acd7a
# TODO auto-generate in docker build step
crypto.app_secret = 21ffbbc616fe
# Server admin Passphrase
# nerve execute merit pool talk hockey basic win cargo spin disagree ethics swear price purchase say clutch decrease slow half forest reform cheese able
#
phpServer.url = http://localhost/
phpServer.host = nginx
loginServer.path = http://localhost/account
loginServer.default_locale = de
loginServer.db.host = mariadb
loginServer.db.name = gradido_community
loginServer.db.user = root
loginServer.db.password =
loginServer.db.port = 3306
frontend.checkEmailPath = vue/checkEmail
frontend.resetPasswordPath = vue/reset
email.disable = true
#email.username =
#email.sender =
#email.admin_receiver =
#email.password =
#email.smtp.url =
#email.smtp.port =
# binary is default, for debugging also json is possible
#hedera.consensus.message_format = json
# TESTNET or MAINNET, TESTNET is default
hedera.nettype = TESTNET
# server setup types: test, staging or production
ServerSetupType=test
dev.default_group = docker
# Session timeout in minutes
#
session.timeout = 15
# Disabling security features for faster develop and testing
unsecure.allow_passwort_via_json_request = 1
unsecure.allow_auto_sign_transactions = 1
unsecure.allow_cors_all = 1
# default disable, passwords must contain a number, a lower character, a high character, special character, and be at least 8 characters long
unsecure.allow_all_passwords = 1

View File

@ -1,57 +0,0 @@
HTTPServer.port = 1200
JSONServer.port = 1201
Gradido.group_id = 1
crypto.server_admin_public = f909a866baec97c5460b8d7a93b72d3d4d20cc45d9f15d78bd83944eb9286b7f
crypto.server_key = a51ef8ac7ef1abf162fb7a65261acd7a
# TODO auto-generate in docker build step
crypto.app_secret = 21ffbbc616fe
# Server admin Passphrase
# nerve execute merit pool talk hockey basic win cargo spin disagree ethics swear price purchase say clutch decrease slow half forest reform cheese able
#
phpServer.url = http://localhost/
phpServer.host = nginx
loginServer.path = http://localhost/account
loginServer.default_locale = de
loginServer.db.host = mariadb
loginServer.db.name = gradido_community_test
loginServer.db.user = root
loginServer.db.password =
loginServer.db.port = 3306
frontend.checkEmailPath = http://localhost/reset
email.disable = true
#email.username =
#email.sender =
#email.admin_receiver =
#email.password =
#email.smtp.url =
#email.smtp.port =
# binary is default, for debugging also json is possible
#hedera.consensus.message_format = json
# TESTNET or MAINNET, TESTNET is default
hedera.nettype = TESTNET
# server setup types: test, staging or production
ServerSetupType=test
dev.default_group = docker
# Session timeout in minutes
#
session.timeout = 15
# Disabling security features for faster develop and testing
unsecure.allow_passwort_via_json_request = 1
unsecure.allow_auto_sign_transactions = 1
unsecure.allow_cors_all = 1
# default disable, passwords must contain a number, a lower character, a high character, special character, and be at least 8 characters long
unsecure.allow_all_passwords = 1

View File

@ -1,25 +1,34 @@
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToOne } from 'typeorm'
import { TransactionCreation } from './TransactionCreation'
import { TransactionSendCoin } from './TransactionSendCoin'
import { TransactionCreation } from '../TransactionCreation'
import { TransactionSendCoin } from '../TransactionSendCoin'
@Entity('transactions')
export class Transaction extends BaseEntity {
@PrimaryGeneratedColumn()
id: number
@Column({ name: 'transaction_type_id' })
@Column({ name: 'state_group_id', unsigned: true, default: null })
stateGroupId: number
@Column({ name: 'transaction_type_id', unsigned: true, nullable: false })
transactionTypeId: number
@Column({ name: 'tx_hash', type: 'binary', length: 48 })
@Column({ name: 'tx_hash', type: 'binary', length: 48, default: null })
txHash: Buffer
@Column()
@Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' })
memo: string
@Column({ type: 'timestamp' })
@Column({ type: 'timestamp', nullable: false, default: () => 'CURRENT_TIMESTAMP' })
received: Date
@Column({ name: 'blockchain_type_id' })
@Column({
name: 'blockchain_type_id',
type: 'bigint',
unsigned: true,
nullable: false,
default: 1,
})
blockchainTypeId: number
@OneToOne(() => TransactionSendCoin, (transactionSendCoin) => transactionSendCoin.transaction)

View File

@ -1,5 +1,5 @@
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from 'typeorm'
import { Transaction } from './Transaction'
import { Transaction } from '../Transaction'
@Entity('transaction_creations')
export class TransactionCreation extends BaseEntity {

View File

@ -1,5 +1,5 @@
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from 'typeorm'
import { Transaction } from './Transaction'
import { Transaction } from '../Transaction'
@Entity('transaction_send_coins')
export class TransactionSendCoin extends BaseEntity {

View File

@ -1,21 +1,21 @@
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm'
import { Transaction } from './Transaction'
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from 'typeorm'
import { Transaction } from '../Transaction'
@Entity('transaction_signatures')
export class TransactionSignature extends BaseEntity {
@PrimaryGeneratedColumn()
@PrimaryGeneratedColumn('increment', { unsigned: true })
id: number
@Column({ name: 'transaction_id' })
transactionId: number
@Column({ type: 'binary', length: 64 })
@Column({ type: 'binary', length: 64, nullable: false })
signature: Buffer
@Column({ type: 'binary', length: 32 })
@Column({ type: 'binary', length: 32, nullable: false })
pubkey: Buffer
@ManyToOne(() => Transaction)
@OneToOne(() => Transaction)
@JoinColumn({ name: 'transaction_id' })
transaction: Transaction
}

View File

@ -1,5 +1,5 @@
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm'
import { UserSetting } from './UserSetting'
import { UserSetting } from '../UserSetting'
// Moriz: I do not like the idea of having two user tables
@Entity('state_users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })

View File

@ -1,5 +1,5 @@
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm'
import { User } from './User'
import { User } from '../User'
@Entity()
export class UserSetting extends BaseEntity {

View File

@ -0,0 +1,25 @@
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
@Entity('admin_pending_creations')
export class AdminPendingCreation extends BaseEntity {
@PrimaryGeneratedColumn('increment', { unsigned: true })
id: number
@Column({ unsigned: true, nullable: false })
userId: number
@Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' })
created: Date
@Column({ type: 'datetime', nullable: false })
date: Date
@Column({ length: 256, nullable: true, default: null })
memo: string
@Column({ type: 'bigint', nullable: false })
amount: BigInt
@Column()
moderator: number
}

View File

@ -0,0 +1,34 @@
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToOne } from 'typeorm'
import { TransactionCreation } from '../TransactionCreation'
import { TransactionSendCoin } from '../TransactionSendCoin'
@Entity('transactions')
export class Transaction extends BaseEntity {
// TODO the id is defined as bigint(20) - there might be problems with that: https://github.com/typeorm/typeorm/issues/2400
@PrimaryGeneratedColumn('increment', { unsigned: true })
id: number
@Column({ name: 'transaction_type_id', unsigned: true, nullable: false })
transactionTypeId: number
@Column({ name: 'tx_hash', type: 'binary', length: 48, default: null })
txHash: Buffer
@Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' })
memo: string
@Column({ type: 'timestamp', nullable: false, default: () => 'CURRENT_TIMESTAMP' })
received: Date
@Column({ type: 'binary', length: 64, nullable: true, default: null })
signature: Buffer
@Column({ type: 'binary', length: 32, nullable: true, default: null })
pubkey: Buffer
@OneToOne(() => TransactionSendCoin, (transactionSendCoin) => transactionSendCoin.transaction)
transactionSendCoin: TransactionSendCoin
@OneToOne(() => TransactionCreation, (transactionCreation) => transactionCreation.transaction)
transactionCreation: TransactionCreation
}

View File

@ -0,0 +1 @@
export { AdminPendingCreation } from './0015-admin_pending_creations/AdminPendingCreation'

View File

@ -1 +0,0 @@
export { LoginPendingTasksAdmin } from './0005-admin_tables/LoginPendingTasksAdmin'

View File

@ -1 +0,0 @@
export { LoginUserRoles } from './0003-login_server_tables/LoginUserRoles'

View File

@ -1 +1 @@
export { Transaction } from './0001-init_db/Transaction'
export { Transaction } from './0016-transaction_signatures/Transaction'

View File

@ -1 +0,0 @@
export { TransactionSignature } from './0001-init_db/TransactionSignature'

View File

@ -2,34 +2,30 @@ import { Balance } from './Balance'
import { LoginElopageBuys } from './LoginElopageBuys'
import { LoginEmailOptIn } from './LoginEmailOptIn'
import { LoginUser } from './LoginUser'
import { LoginUserRoles } from './LoginUserRoles'
import { LoginUserBackup } from './LoginUserBackup'
import { Migration } from './Migration'
import { ServerUser } from './ServerUser'
import { Transaction } from './Transaction'
import { TransactionCreation } from './TransactionCreation'
import { TransactionSignature } from './TransactionSignature'
import { TransactionSendCoin } from './TransactionSendCoin'
import { User } from './User'
import { UserSetting } from './UserSetting'
import { UserTransaction } from './UserTransaction'
import { LoginPendingTasksAdmin } from './LoginPendingTasksAdmin'
import { AdminPendingCreation } from './AdminPendingCreation'
export const entities = [
AdminPendingCreation,
Balance,
LoginElopageBuys,
LoginEmailOptIn,
LoginUser,
LoginUserRoles,
LoginUserBackup,
Migration,
ServerUser,
Transaction,
TransactionCreation,
TransactionSignature,
TransactionSendCoin,
User,
UserSetting,
UserTransaction,
LoginPendingTasksAdmin,
]

View File

@ -0,0 +1,142 @@
/* MIGRATION TO DROP UNUSED TABLES
*
* This migration removes all tables without data and entity definition.
* Base for evaluation are the production data from 27.01.2022 which had 40 tables present
* The migration reduces the amount of tables to 28
*/
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(`DROP TABLE \`login_app_access_tokens\`;`)
await queryFn(`DROP TABLE \`pending_transactions\`;`)
await queryFn(`DROP TABLE \`roles\`;`)
await queryFn(`DROP TABLE \`state_created\`;`)
await queryFn(`DROP TABLE \`state_groups\`;`)
await queryFn(`DROP TABLE \`state_group_addresses\`;`)
await queryFn(`DROP TABLE \`state_group_relationships\`;`)
await queryFn(`DROP TABLE \`state_relationship_types\`;`)
await queryFn(`DROP TABLE \`state_user_roles\`;`)
await queryFn(`DROP TABLE \`transaction_group_addaddress\`;`)
await queryFn(`DROP TABLE \`transaction_group_allowtrades\`;`)
await queryFn(`DROP TABLE \`transaction_group_creates\`;`)
}
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(`
CREATE TABLE IF NOT EXISTS \`login_app_access_tokens\` (
\`id\` int unsigned NOT NULL AUTO_INCREMENT,
\`user_id\` int NOT NULL,
\`access_code\` bigint unsigned NOT NULL,
\`created\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
\`updated\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (\`id\`),
UNIQUE KEY \`access_code\` (\`access_code\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`)
await queryFn(`
CREATE TABLE \`pending_transactions\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`transactionID\` varchar(25) COLLATE utf8mb4_unicode_ci NOT NULL,
\`service\` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
\`method\` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
\`h_server_id\` int(11) NOT NULL,
\`timeout\` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (\`id\`),
UNIQUE KEY \`transactionID\` (\`transactionID\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
await queryFn(`
CREATE TABLE \`roles\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`title\` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
await queryFn(`
CREATE TABLE \`state_created\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`transaction_id\` int(10) unsigned NOT NULL,
\`month\` tinyint(3) unsigned NOT NULL,
\`year\` smallint(5) unsigned NOT NULL,
\`state_user_id\` int(10) unsigned NOT NULL,
\`created\` datetime NOT NULL,
\`short_ident_hash\` int(10) unsigned NOT NULL,
PRIMARY KEY (\`id\`),
KEY \`short_ident_hash\` (\`short_ident_hash\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
await queryFn(`
CREATE TABLE \`state_groups\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`index_id\` varbinary(64) NOT NULL,
\`name\` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
\`root_public_key\` binary(32) NOT NULL,
\`user_count\` smallint(5) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
await queryFn(`
CREATE TABLE \`state_group_addresses\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`group_id\` int(10) unsigned NOT NULL,
\`public_key\` binary(32) NOT NULL,
\`address_type_id\` int(10) unsigned NOT NULL,
PRIMARY KEY (\`id\`),
UNIQUE KEY \`public_key\` (\`public_key\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
await queryFn(`
CREATE TABLE \`state_group_relationships\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`group1_id\` int(10) unsigned NOT NULL,
\`group2_id\` int(10) unsigned NOT NULL,
\`state_relationship_id\` int(10) unsigned NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
await queryFn(`
CREATE TABLE \`state_relationship_types\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`name\` varchar(25) COLLATE utf8mb4_unicode_ci NOT NULL,
\`text\` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
await queryFn(`
CREATE TABLE \`state_user_roles\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`state_user_id\` int(11) NOT NULL,
\`role_id\` int(11) NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
await queryFn(`
CREATE TABLE \`transaction_group_addaddress\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`transaction_id\` int(10) unsigned NOT NULL,
\`address_type_id\` int(10) unsigned NOT NULL,
\`remove_from_group\` tinyint(1) DEFAULT 0,
\`public_key\` binary(32) NOT NULL,
\`state_user_id\` int(10) unsigned NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
await queryFn(`
CREATE TABLE \`transaction_group_allowtrades\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`transaction_id\` int(10) unsigned NOT NULL,
\`remote_group_id\` varbinary(64) NOT NULL,
\`allow\` tinyint(4) NOT NULL DEFAULT 0,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
await queryFn(`
CREATE TABLE \`transaction_group_creates\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`transaction_id\` int(10) unsigned NOT NULL,
\`group_public_key\` binary(32) NOT NULL,
\`group_id\` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
\`name\` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
}

View File

@ -0,0 +1,351 @@
/* MIGRATION TO DROP UNUSED TABLES
*
* This migration removes all tables with static or unused data and entity definition.
* Base for evaluation are the production data from 27.01.2022 which had 28 tables present
* The migration reduces the amount of tables to 16
*/
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(`DROP TABLE \`address_types\`;`)
await queryFn(`DROP TABLE \`admin_errors\`;`)
await queryFn(`DROP TABLE \`blockchain_types\`;`)
await queryFn(`DROP TABLE \`community_profiles\`;`)
await queryFn(`DROP TABLE \`login_email_opt_in_types\`;`)
await queryFn(`DROP TABLE \`login_groups\`;`)
await queryFn(`DROP TABLE \`login_roles\`;`)
await queryFn(`DROP TABLE \`login_user_roles\`;`)
await queryFn(`DROP TABLE \`operators\`;`)
await queryFn(`DROP TABLE \`operator_types\`;`)
await queryFn(`DROP TABLE \`state_errors\`;`)
await queryFn(`DROP TABLE \`transaction_types\`;`)
}
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(`
CREATE TABLE \`address_types\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`name\` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
\`text\` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
// NOTE: Static data might be needed as enum definitions
await queryFn(`
INSERT INTO \`address_types\` VALUES
(1,'user main','user main address');
`)
await queryFn(`
CREATE TABLE \`admin_errors\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`state_user_id\` int(11) NOT NULL,
\`controller\` varchar(255) NOT NULL,
\`action\` varchar(255) NOT NULL,
\`state\` varchar(255) NOT NULL,
\`msg\` varchar(255) NOT NULL,
\`details\` varchar(255) DEFAULT NULL,
\`created\` datetime NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=155 DEFAULT CHARSET=utf8mb4;
`)
// NOTE: This data is no longer generated
await queryFn(`
INSERT INTO \`admin_errors\` VALUES
(54,272,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2020-11-04 17:57:07'),
(55,272,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2020-11-04 17:57:16'),
(56,193,'StateBalancesController','overview','error','server response status code isn\\'t 200','403','2020-11-24 12:44:31'),
(57,79,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2020-12-31 19:17:52'),
(58,79,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2020-12-31 19:18:04'),
(59,44,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-01-12 20:58:45'),
(60,44,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-01-12 21:02:02'),
(61,44,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-01-12 21:02:04'),
(62,44,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-01-12 21:02:19'),
(63,20,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-01-13 22:32:59'),
(64,20,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-01-14 23:54:19'),
(65,161,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-01-27 10:29:09'),
(66,161,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-01-27 10:29:11'),
(67,161,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-01-27 10:29:23'),
(68,20,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-02-03 00:27:36'),
(69,685,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-02-06 11:48:09'),
(70,685,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-02-06 11:53:14'),
(71,685,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-02-06 11:53:20'),
(72,502,'TransactionCreations','createMulti','error','json exception','System exception: cannot unlock mutex','2021-03-24 21:22:14'),
(73,502,'TransactionCreations','createMulti','error','json exception','System exception: cannot unlock mutex','2021-03-24 21:23:38'),
(74,259,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-02 15:07:07'),
(75,79,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-14 20:31:50'),
(76,79,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-14 20:31:57'),
(77,79,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-14 20:32:23'),
(78,79,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-14 20:32:57'),
(79,199,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-14 21:43:13'),
(80,199,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-14 21:43:47'),
(81,199,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-14 21:44:45'),
(82,272,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-14 22:57:10'),
(83,272,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-14 22:57:18'),
(84,1162,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-21 12:50:53'),
(85,1162,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-21 12:51:27'),
(86,1162,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-21 12:51:32'),
(87,1162,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-21 12:51:54'),
(88,1162,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-21 12:52:29'),
(89,1162,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-21 12:53:33'),
(90,1162,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-21 12:53:37'),
(91,1162,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-23 12:27:57'),
(92,1162,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-23 12:28:02'),
(93,900,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-27 18:59:08'),
(94,900,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-27 18:59:16'),
(95,900,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-27 18:59:27'),
(96,900,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-27 19:00:51'),
(97,900,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-27 19:01:18'),
(98,900,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-27 19:04:22'),
(99,900,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-27 19:04:39'),
(100,1087,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-27 19:43:18'),
(101,240,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-28 22:00:05'),
(102,240,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-28 22:00:35'),
(103,240,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-28 22:00:37'),
(104,240,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-28 22:00:44'),
(105,90,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-29 14:05:59'),
(106,90,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-29 14:06:07'),
(107,90,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-29 14:06:15'),
(108,90,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-04-29 14:07:13'),
(109,79,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-05-01 10:18:03'),
(110,20,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-05-08 00:25:20'),
(111,84,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-05-08 22:34:27'),
(112,84,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-05-08 22:35:47'),
(113,776,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-05-12 10:24:55'),
(114,776,'TransactionSendCoins','create','success','(Leere Message)','(Leere Details)','2021-05-13 13:47:07'),
(115,1339,'StateBalancesController','overview','success','(Leere Message)','(Leere Details)','2021-07-13 08:54:30'),
(116,1339,'StateBalancesController','overview','success','(Leere Message)','(Leere Details)','2021-07-13 08:54:30'),
(117,943,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:46:40'),
(118,943,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:05'),
(119,943,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:05'),
(120,751,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:20'),
(121,943,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:21'),
(122,943,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:21'),
(123,751,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:22'),
(124,751,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:22'),
(125,11,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:36'),
(126,11,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:43'),
(127,943,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:43'),
(128,11,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:43'),
(129,943,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:46'),
(130,943,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-08-12 14:47:46'),
(131,11,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:48:47'),
(132,11,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:48:52'),
(133,11,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-08-12 14:48:52'),
(134,943,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:49:24'),
(135,943,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:49:26'),
(136,943,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-08-12 14:49:26'),
(137,751,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:49:58'),
(138,751,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:50:00'),
(139,751,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-08-12 14:50:00'),
(140,943,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:50:57'),
(141,943,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:51:01'),
(142,943,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-08-12 14:51:02'),
(143,11,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-08-12 14:51:10'),
(144,11,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:51:10'),
(145,11,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:52:39'),
(146,943,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:52:44'),
(147,82,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:54:25'),
(148,284,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-08-12 14:54:35'),
(149,1439,'StateBalancesController','overview','success','(Leere Message)','(Leere Details)','2021-09-16 15:44:16'),
(150,1439,'StateBalancesController','overview','success','(Leere Message)','(Leere Details)','2021-09-16 15:44:27'),
(151,11,'StateBalancesController','overview','error','server response status code isn\\'t 200','500','2021-09-22 11:03:10'),
(152,11,'StateBalancesController','ajaxGdtOverview','error','server response status code isn\\'t 200','500','2021-09-22 11:16:33'),
(153,82,'StateBalancesController','overview','error','server response status code isn\\'t 200','403','2021-11-23 16:03:57'),
(154,82,'StateBalancesController','overview','error','server response status code isn\\'t 200','403','2021-11-23 16:04:10');
`)
await queryFn(`
CREATE TABLE \`blockchain_types\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`name\` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
\`text\` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
\`symbol\` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
// NOTE: Static data might be needed as enum definitions
await queryFn(`
INSERT INTO \`blockchain_types\` VALUES
(1,'mysql','use mysql db as blockchain, work only with single community-server',NULL),
(2,'hedera','use hedera for transactions','HBAR');
`)
await queryFn(`
CREATE TABLE \`community_profiles\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`state_user_id\` int(10) unsigned NOT NULL,
\`profile_img\` longblob DEFAULT NULL,
\`profile_desc\` varchar(2000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (\`id\`),
KEY \`state_user_id\` (\`state_user_id\`)
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
// NOTE: The data was removed due to large binary images in the database. If this data is needed please get it from the backup file.
await queryFn(`
CREATE TABLE \`login_email_opt_in_types\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`name\` varchar(255) NOT NULL,
\`description\` varchar(255) NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
`)
// NOTE: Static data might be needed as enum definitions
await queryFn(`
INSERT INTO \`login_email_opt_in_types\` VALUES
(1,'register','Email Verification Code for register from new User.'),
(2,'resetPassword','Email Verification Code for reset Password (only if passphrase is known)');
`)
await queryFn(`
CREATE TABLE \`login_groups\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`alias\` varchar(190) NOT NULL,
\`name\` varchar(255) NOT NULL,
\`url\` varchar(255) NOT NULL,
\`host\` varchar(255) DEFAULT '/',
\`home\` varchar(255) DEFAULT '/',
\`description\` text DEFAULT NULL,
PRIMARY KEY (\`id\`),
UNIQUE KEY \`alias\` (\`alias\`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
`)
// NOTE: Static data might be needed as enum definitions
await queryFn(`
INSERT INTO \`login_groups\` VALUES
(1,'gdd1','gdd1','gdd1.gradido.com','','/','gdd1 group');
`)
await queryFn(`
CREATE TABLE \`login_roles\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`name\` varchar(255) NOT NULL,
\`description\` varchar(255) NOT NULL,
\`flags\` bigint(20) NOT NULL DEFAULT 0,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
`)
// NOTE: Static data might be needed as enum definitions
await queryFn(`
INSERT INTO \`login_roles\` VALUES
(1,'admin','darf einfach alles',0);
`)
await queryFn(`
CREATE TABLE \`login_user_roles\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`user_id\` int(11) NOT NULL,
\`role_id\` int(11) NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
`)
// NOTE: This data is not used - therefore we remove it.
// This data is aligned to the `server_users` table except the entry 4,
// this one is missing in the other table
// and after checking with administration, we figured out that
// this is a data fragement no longer needed.
await queryFn(`
INSERT INTO \`login_user_roles\` VALUES
(1,28,1),
(2,37,1),
(3,50,1),
(4,44,1),
(5,872,1);
`)
await queryFn(`
CREATE TABLE \`operators\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`username\` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
\`user_pubkey\` binary(32) NOT NULL,
\`data_base64\` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
\`modified\` datetime NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
// NOTE: This data seems not to have any use
await queryFn(`
INSERT INTO \`operators\` VALUES
(5,'einhornimmond',0x78DCFAA8341B3A39B3C5502B4D9ACDBC4B181A10CC0D94187498E0A0C74288E0,'i99a5/wWGmQN4AF8ilUXhHJVV/3At82f6CNNh3ewdVyTTAqugcdeG53DEMNUxCTFwk7KIg==','2019-09-17 13:08:22');
`)
await queryFn(`
CREATE TABLE \`operator_types\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`name\` varchar(25) COLLATE utf8mb4_unicode_ci NOT NULL,
\`text\` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
// NOTE: Static data might be needed as enum definitions
await queryFn(`
INSERT INTO \`operator_types\` VALUES
(1,'hedera','Hedera Keys for sign and pay hedera transactions'),
(2,'gradido-user','default gradido user keys'),
(3,'gradido-group','default gradido group root keys, other address are derived');
`)
await queryFn(`
CREATE TABLE \`state_errors\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`state_user_id\` int(10) unsigned NOT NULL,
\`transaction_type_id\` int(10) unsigned NOT NULL,
\`created\` datetime NOT NULL,
\`message_json\` text COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=161 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
// NOTE: This data is no longer generated
await queryFn(`
INSERT INTO \`state_errors\` VALUES
(9,11,1,'2020-08-07 10:40:03','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(17,528,2,'2021-02-10 08:04:32','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"sender 0 hasn\\'t enough GDD"}]}'),
(115,82,1,'2021-09-01 11:14:25','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(119,82,1,'2021-09-06 18:55:55','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(138,502,1,'2021-10-31 00:00:32','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(139,502,1,'2021-11-02 19:50:36','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(140,502,1,'2021-11-07 13:32:11','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(141,502,1,'2021-11-16 22:04:59','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(142,502,1,'2021-11-21 23:47:14','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(143,502,1,'2021-11-22 00:14:40','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(144,502,1,'2021-11-25 21:40:15','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(145,502,1,'2021-11-25 22:45:06','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(146,502,1,'2021-11-29 12:52:12','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(147,502,1,'2021-12-04 01:56:10','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(148,502,1,'2021-12-06 13:12:08','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(149,502,1,'2021-12-06 13:18:20','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(150,502,1,'2021-12-16 21:06:34','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(151,502,1,'2021-12-20 23:11:44','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(152,502,1,'2022-01-04 13:19:31','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(153,502,1,'2022-01-04 13:54:33','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(154,502,1,'2022-01-04 13:55:32','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(155,502,1,'2022-01-04 14:02:35','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(156,502,1,'2022-01-04 14:50:49','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(157,502,1,'2022-01-04 14:51:41','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(158,502,1,'2022-01-19 00:32:46','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(159,502,1,'2022-01-19 00:52:42','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}'),
(160,502,1,'2022-01-25 08:31:57','{"state":"error","msg":"error validate transaction","details":[{"TransactionCreation::validate":"Creation more than 1.000 GDD per Month for in target_date not allowed"}]}');
`)
await queryFn(`
CREATE TABLE \`transaction_types\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`name\` varchar(90) COLLATE utf8mb4_unicode_ci NOT NULL,
\`text\` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`)
// NOTE: Static data might be needed as enum definitions
await queryFn(`
INSERT INTO \`transaction_types\` VALUES
(1,'creation','create new gradidos for member and also for group (in development)'),
(2,'transfer','send gradidos from one member to another, also cross group transfer'),
(3,'group create','create a new group, trigger creation of new hedera topic and new blockchain on node server'),
(4,'group add member','add user to a group or move if he was already in a group'),
(5,'group remove member','remove user from group, maybe he was moved elsewhere'),
(6,'hedera topic create','create new topic on hedera'),
(7,'hedera topic send message','send consensus message over hedera topic'),
(8,'hedera account create','create new account on hedera for holding some founds with unencrypted keys'),
(9,'decay start','signalize the starting point for decay calculation, allowed only once per chain');
`)
}

View File

@ -0,0 +1,35 @@
/* MIGRATION TO PROPERLY STORE PENDING CREATIONS
*
* There were two tables for the pending tasks,
* since the login_server used some crypto to store its
* tasks there. It was easier to create a new table.
* This migration drops the old unused table and renames
* the new table to properly describe what it does
*/
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
// drop duplicate table, it was unused
await queryFn('DROP TABLE `login_pending_tasks`;')
// rename the new pending creations table to a proper table name
await queryFn('RENAME TABLE `login_pending_tasks_admin` TO `admin_pending_creations`;')
}
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn('RENAME TABLE `admin_pending_creations` TO `login_pending_tasks_admin`;')
await queryFn(`
CREATE TABLE \`login_pending_tasks\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`user_id\` int(10) unsigned DEFAULT 0,
\`request\` varbinary(2048) NOT NULL,
\`created\` datetime NOT NULL,
\`finished\` datetime DEFAULT '2000-01-01 00:00:00',
\`result_json\` text DEFAULT NULL,
\`param_json\` text DEFAULT NULL,
\`task_type_id\` int(10) unsigned NOT NULL,
\`child_pending_task_id\` int(10) unsigned DEFAULT 0,
\`parent_pending_task_id\` int(10) unsigned DEFAULT 0,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=795 DEFAULT CHARSET=utf8mb4
`)
}

View File

@ -0,0 +1,60 @@
/* MIGRATION TO CLEANUP TRANSACTIONS TABLE
*
* This migration cleans up the transactions table and
* combines its data with transaction_signatures.
*/
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
// Drop column `state_group_id` since it only contains "0" as value, no variation.
// Furthermore it was not present in our model itself (meaning that newly created )
await queryFn('ALTER TABLE `transactions` DROP COLUMN `state_group_id`;')
// Drop column `blockchain_type_id` since it only contains "1" as value, no variation.
await queryFn('ALTER TABLE `transactions` DROP COLUMN `blockchain_type_id`;')
// Create `signature` column - for data from `transaction_signatures` table.
await queryFn(
'ALTER TABLE `transactions` ADD COLUMN `signature` binary(64) DEFAULT NULL AFTER `received`;',
)
// Create `pubkey` column - for data from `transaction_signatures` table.
await queryFn(
'ALTER TABLE `transactions` ADD COLUMN `pubkey` binary(32) DEFAULT NULL AFTER `signature`;',
)
// Transfer data from `transaction_signatures` table to `transactions` table
await queryFn(`
UPDATE transactions
INNER JOIN transaction_signatures ON transactions.id = transaction_signatures.transaction_id
SET transactions.signature = transaction_signatures.signature, transactions.pubkey = transaction_signatures.pubkey;
`)
// Drop `transaction_signatures` table
await queryFn('DROP TABLE `transaction_signatures`;')
}
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(`
CREATE TABLE \`transaction_signatures\` (
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
\`transaction_id\` int(10) unsigned NOT NULL,
\`signature\` binary(64) NOT NULL,
\`pubkey\` binary(32) NOT NULL,
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
`)
await queryFn(`
INSERT INTO transaction_signatures (transaction_id, signature, pubkey)
(SELECT id as transaction_id, signature, pubkey FROM transactions WHERE signature IS NOT NULL and pubkey IS NOT NULL);
`)
await queryFn('ALTER TABLE `transactions` DROP COLUMN `pubkey`;')
await queryFn('ALTER TABLE `transactions` DROP COLUMN `signature`;')
await queryFn(
'ALTER TABLE `transactions` ADD COLUMN `blockchain_type_id` bigint(20) unsigned NOT NULL DEFAULT 1 AFTER `received` ;',
)
await queryFn(
'ALTER TABLE `transactions` ADD COLUMN `state_group_id` int(10) unsigned DEFAULT NULL AFTER `id`;',
)
// We have to set the correct values previously in the table , since its not the same as the column's default
await queryFn('UPDATE `transactions` SET `state_group_id` = 0;')
}

View File

@ -1,16 +0,0 @@
import Faker from 'faker'
import { define } from 'typeorm-seeding'
import { LoginUserRoles } from '../../entity/LoginUserRoles'
import { LoginUserRolesContext } from '../interface/UserContext'
define(LoginUserRoles, (faker: typeof Faker, context?: LoginUserRolesContext) => {
if (!context) context = {}
if (!context.userId) throw new Error('LoginUserRoles: No userId present!')
if (!context.roleId) throw new Error('LoginUserRoles: No roleId present!')
const userRoles = new LoginUserRoles()
userRoles.userId = context.userId
userRoles.roleId = context.roleId
return userRoles
})

View File

@ -1,18 +0,0 @@
import Faker from 'faker'
import { define } from 'typeorm-seeding'
import { TransactionSignature } from '../../entity/TransactionSignature'
import { TransactionSignatureContext } from '../interface/TransactionContext'
import { randomBytes } from 'crypto'
define(TransactionSignature, (faker: typeof Faker, context?: TransactionSignatureContext) => {
if (!context || !context.transaction) {
throw new Error('TransactionSignature: No transaction present!')
}
const transactionSignature = new TransactionSignature()
transactionSignature.signature = context.signature ? context.signature : randomBytes(64)
transactionSignature.pubkey = context.pubkey ? context.pubkey : randomBytes(32)
transactionSignature.transaction = context.transaction
return transactionSignature
})

View File

@ -12,7 +12,8 @@ define(Transaction, (faker: typeof Faker, context?: TransactionContext) => {
transaction.txHash = context.txHash ? context.txHash : randomBytes(48)
transaction.memo = context.memo || context.memo === '' ? context.memo : faker.lorem.sentence()
transaction.received = context.received ? context.received : new Date()
transaction.blockchainTypeId = context.blockchainTypeId ? context.blockchainTypeId : 1
transaction.signature = context.signature ? context.signature : randomBytes(64)
transaction.pubkey = context.signaturePubkey ? context.signaturePubkey : randomBytes(32)
if (context.transactionSendCoin) transaction.transactionSendCoin = context.transactionSendCoin
if (context.transactionCreation) transaction.transactionCreation = context.transactionCreation

View File

@ -9,6 +9,8 @@ export interface TransactionContext {
memo?: string
received?: Date
blockchainTypeId?: number
signature?: Buffer
signaturePubkey?: Buffer
transactionSendCoin?: TransactionSendCoin
transactionCreation?: TransactionCreation
}
@ -43,10 +45,6 @@ export interface UserTransactionContext {
transactionTypeId?: number
balance?: number
balanceDate?: Date
}
export interface TransactionSignatureContext {
signature?: Buffer
pubkey?: Buffer
transaction?: Transaction
}

View File

@ -10,17 +10,14 @@ import {
TransactionContext,
TransactionCreationContext,
UserTransactionContext,
TransactionSignatureContext,
} from '../../interface/TransactionContext'
import { UserInterface } from '../../interface/UserInterface'
import { User } from '../../../entity/User'
import { LoginUser } from '../../../entity/LoginUser'
import { LoginUserBackup } from '../../../entity/LoginUserBackup'
import { ServerUser } from '../../../entity/ServerUser'
import { LoginUserRoles } from '../../../entity/LoginUserRoles'
import { Balance } from '../../../entity/Balance'
import { Transaction } from '../../../entity/Transaction'
import { TransactionSignature } from '../../../entity/TransactionSignature'
import { UserTransaction } from '../../../entity/UserTransaction'
import { TransactionCreation } from '../../../entity/TransactionCreation'
import { Factory } from 'typeorm-seeding'
@ -33,10 +30,6 @@ export const userSeeder = async (factory: Factory, userData: UserInterface): Pro
if (userData.isAdmin) {
await factory(ServerUser)(createServerUserContext(userData)).create()
// This is crazy: we just need the relation to roleId but no role at all
// It works with LoginRoles empty!!
await factory(LoginUserRoles)(createLoginUserRolesContext(loginUser)).create()
}
if (userData.addBalance) {
@ -51,9 +44,6 @@ export const userSeeder = async (factory: Factory, userData: UserInterface): Pro
await factory(UserTransaction)(
createUserTransactionContext(userData, user, transaction),
).create()
await factory(TransactionSignature)(
createTransactionSignatureContext(userData, transaction),
).create()
}
}
@ -166,16 +156,7 @@ const createUserTransactionContext = (
transactionTypeId: transaction.transactionTypeId,
balance: context.amount,
balanceDate: context.recordDate,
}
}
const createTransactionSignatureContext = (
context: UserInterface,
transaction: Transaction,
): TransactionSignatureContext => {
return {
signature: context.signature,
pubkey: context.signaturePubkey,
transaction,
}
}

1
database/src/typeorm.ts Normal file
View File

@ -0,0 +1 @@
export * from 'typeorm'

View File

@ -78,28 +78,6 @@ services:
# bind the local folder to the docker to allow live reload
- ./database:/app
#########################################################
## LOGIN SERVER #########################################
#########################################################
login-server:
build:
dockerfile: Dockerfiles/ubuntu/Dockerfile.debug
networks:
- external-net
- internal-net
security_opt:
- seccomp:unconfined
cap_add:
- SYS_PTRACE
volumes:
- ./logs:/var/log/grd_login
- ./login_server/src:/code/src
- ./login_server/dependencies:/code/dependencies
- ./login_server/scripts:/code/scripts
- ./configs/login_server:/etc/grd_login
- login_build_ubuntu_3.1:/code/build
#########################################################
## COMMUNITY SERVER (cakephp with php-fpm) ##############
#########################################################
@ -156,4 +134,3 @@ volumes:
backend_database_build:
database_node_modules:
database_build:
login_build_ubuntu_3.1:

View File

@ -35,28 +35,6 @@ services:
volumes:
- db_test_vol:/var/lib/mysql
#########################################################
## LOGIN SERVER #########################################
#########################################################
login-server:
build:
context: ./login_server/
dockerfile: Dockerfiles/ubuntu/Dockerfile.test
security_opt:
- seccomp:unconfined
cap_add:
- SYS_PTRACE
depends_on:
- mariadb
networks:
- internal-net
volumes:
- ./logs:/var/log/grd_login
- ./login_server/src:/code/src
- ./configs/login_server:/etc/grd_login
- login_build_cov:/code/build_cov
- ./coverage/login:/code/build_cov/coverage_html
#########################################################
## COMMUNITY SERVER (cakephp with php-fpm) ##############
#########################################################
@ -98,4 +76,3 @@ networks:
volumes:
db_test_vol:
login_build_cov:

View File

@ -129,26 +129,9 @@ services:
#env_file:
# - ./frontend/.env
#########################################################
## LOGIN SERVER #########################################
#########################################################
login-server:
build:
context: ./login_server/
depends_on:
- mariadb
networks:
- internal-net
ports:
- 1200:1200
- 1201:1201
volumes:
- ./configs/login_server:/etc/grd_login
#########################################################
## NGINX ################################################
#########################################################
## nginx, connect login-server and community-server together (and php-fpm to community-server)
nginx:
build:
context: ./nginx/

View File

@ -20,16 +20,11 @@
"@vue/cli-plugin-unit-jest": "^4.5.12",
"@vue/test-utils": "^1.1.3",
"apollo-boost": "^0.4.9",
"axios": "^0.21.1",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^27.3.1",
"babel-preset-vue": "^2.0.2",
"bootstrap": "4.3.1",
"bootstrap-vue": "^2.5.0",
"d3": "^5.7.0",
"datamaps": "^0.5.9",
"date-fns": "^1.30.1",
"dropzone": "^5.5.1",
"bootstrap": "^4.5.3",
"bootstrap-vue": "^2.21.2",
"es6-promise": "^4.1.1",
"eslint": "^7.25.0",
"eslint-config-prettier": "^8.1.0",
@ -44,31 +39,22 @@
"express": "^4.17.1",
"flatpickr": "^4.5.7",
"flush-promises": "^1.0.2",
"fuse.js": "^3.2.0",
"google-maps": "^3.2.1",
"graphql": "^15.5.1",
"identity-obj-proxy": "^3.0.0",
"jest": "^26.6.3",
"jest-canvas-mock": "^2.3.1",
"jest-environment-jsdom-sixteen": "^2.0.0",
"nouislider": "^12.1.0",
"particles-bg-vue": "1.2.3",
"perfect-scrollbar": "^1.3.0",
"portal-vue": "^2.1.7",
"prettier": "^2.2.1",
"qrcode": "^1.4.4",
"quill": "^1.3.6",
"regenerator-runtime": "^0.13.7",
"sweetalert2": "^9.5.4",
"vee-validate": "^3.4.5",
"vue": "^2.6.11",
"vue": "2.6.12",
"vue-apollo": "^3.0.7",
"vue-bootstrap-typeahead": "^0.2.6",
"vue-cli-plugin-i18n": "^1.0.1",
"vue-clickaway": "^2.2.2",
"vue-clipboard2": "^0.3.0",
"vue-flatpickr-component": "^8.1.2",
"vue-focus": "^2.1.0",
"vue-good-table": "^2.21.3",
"vue-i18n": "^8.22.4",
"vue-jest": "^3.0.7",
"vue-loading-overlay": "^3.4.2",

View File

@ -1,126 +0,0 @@
/*!
=========================================================
* Bootstrap Vue Gradido Wallet- v0.0.1
=========================================================
* Product Page: https://www.gradido.net
* Copyright 2020 Bernd Hückstädt - Gradido (https://www.gradido.net)
* Coded by www.gradido.net
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
// Core
@import "custom/functions";
@import "custom/variables";
@import "custom/mixins";
// Bootstrap (4.1.3) components
@import "~bootstrap/scss/alert";
@import "~bootstrap/scss/badge";
@import "~bootstrap/scss/breadcrumb";
@import "~bootstrap/scss/button-group";
@import "~bootstrap/scss/buttons";
@import "~bootstrap/scss/card";
@import "~bootstrap/scss/carousel";
@import "~bootstrap/scss/close";
@import "~bootstrap/scss/code";
@import "~bootstrap/scss/custom-forms";
@import "~bootstrap/scss/dropdown";
@import "~bootstrap/scss/forms";
@import "~bootstrap/scss/grid";
@import "~bootstrap/scss/images";
@import "~bootstrap/scss/input-group";
@import "~bootstrap/scss/jumbotron";
@import "~bootstrap/scss/list-group";
@import "~bootstrap/scss/media";
@import "~bootstrap/scss/modal";
@import "~bootstrap/scss/nav";
@import "~bootstrap/scss/navbar";
@import "~bootstrap/scss/pagination";
@import "~bootstrap/scss/popover";
@import "~bootstrap/scss/print";
@import "~bootstrap/scss/progress";
@import "~bootstrap/scss/reboot";
@import "~bootstrap/scss/root";
@import "~bootstrap/scss/tables";
@import "~bootstrap/scss/toasts";
@import "~bootstrap/scss/tooltip";
@import "~bootstrap/scss/transitions";
@import "~bootstrap/scss/type";
@import "~bootstrap/scss/utilities";
@import "~bootstrap/scss/variables";
// Utilities
@import "~bootstrap/scss/utilities/align";
@import "~bootstrap/scss/utilities/background";
@import "~bootstrap/scss/utilities/borders";
@import "~bootstrap/scss/utilities/clearfix";
@import "~bootstrap/scss/utilities/display";
@import "~bootstrap/scss/utilities/embed";
@import "~bootstrap/scss/utilities/flex";
@import "~bootstrap/scss/utilities/float";
@import "~bootstrap/scss/utilities/overflow";
@import "~bootstrap/scss/utilities/position";
@import "~bootstrap/scss/utilities/screenreaders";
@import "~bootstrap/scss/utilities/shadows";
@import "~bootstrap/scss/utilities/sizing";
@import "~bootstrap/scss/utilities/spacing";
@import "~bootstrap/scss/utilities/stretched-link";
@import "~bootstrap/scss/utilities/text";
@import "~bootstrap/scss/utilities/visibility";
// Mixins
@import "~bootstrap/scss/mixins/alert";
@import "~bootstrap/scss/mixins/badge";
@import "~bootstrap/scss/mixins/border-radius";
@import "~bootstrap/scss/mixins/box-shadow";
@import "~bootstrap/scss/mixins/breakpoints";
@import "~bootstrap/scss/mixins/buttons";
@import "~bootstrap/scss/mixins/caret";
@import "~bootstrap/scss/mixins/clearfix";
@import "~bootstrap/scss/mixins/deprecate";
@import "~bootstrap/scss/mixins/float";
@import "~bootstrap/scss/mixins/forms";
@import "~bootstrap/scss/mixins/gradients";
@import "~bootstrap/scss/mixins/grid-framework";
@import "~bootstrap/scss/mixins/grid";
@import "~bootstrap/scss/mixins/hover";
@import "~bootstrap/scss/mixins/image";
@import "~bootstrap/scss/mixins/list-group";
@import "~bootstrap/scss/mixins/lists";
@import "~bootstrap/scss/mixins/nav-divider";
@import "~bootstrap/scss/mixins/pagination";
@import "~bootstrap/scss/mixins/reset-text";
@import "~bootstrap/scss/mixins/resize";
@import "~bootstrap/scss/mixins/screen-reader";
@import "~bootstrap/scss/mixins/size";
@import "~bootstrap/scss/mixins/table-row";
@import "~bootstrap/scss/mixins/text-emphasis";
@import "~bootstrap/scss/mixins/text-hide";
@import "~bootstrap/scss/mixins/text-truncate";
@import "~bootstrap/scss/mixins/transition";
@import "~bootstrap/scss/mixins/visibility";
// Argon utilities and components
@import "custom/reboot";
@import "custom/utilities";
@import "custom/components";
// Vendor (Plugins)
@import "custom/vendors";

View File

@ -1,39 +0,0 @@
//
// Dismissible alert
//
.alert-dismissible {
.close {
top: 50%;
right: $alert-padding-x;
padding: 0;
transform: translateY(-50%);
color: rgba($white, .6);
opacity: 1;
&:hover,
&:focus {
color: rgba($white, .9);
opacity: 1 !important;
}
@include media-breakpoint-down(xs) {
top: 1rem;
right: .5rem;
}
&>span:not(.sr-only) {
font-size: 1.5rem;
background-color: transparent;
color: rgba($white, .6);
}
&:hover,
&:focus {
&>span:not(.sr-only) {
background-color: transparent;
color: rgba($white, .9);
}
}
}
}

View File

@ -1,46 +0,0 @@
//
// Alert
//
.alert {
font-size: $font-size-sm;
}
// Alert heading
.alert-heading {
font-weight: $font-weight-bold;
font-size: $h4-font-size;
margin-top: .15rem;
}
// Alert icon
.alert-icon {
font-size: 1.25rem;
margin-right: 1.25rem;
display: inline-block;
vertical-align: middle;
i.ni {
position: relative;
top: 1px;
}
}
// Alert text next to an alert icon
.alert-text {
display: inline-block;
vertical-align: middle;
}
// Alert links
[class*="alert-"] {
.alert-link {
color: $white;
border-bottom: 1px dotted rgba($white, .5);
}
}

View File

@ -1,22 +0,0 @@
//
// Avatar group
//
// General styles
.avatar-group {
.avatar {
position: relative;
z-index: 2;
border: 2px solid $card-bg;
&:hover {
z-index: 3;
}
}
.avatar + .avatar {
margin-left: -1rem;
}
}

View File

@ -1,42 +0,0 @@
//
// Avatar
//
// General styles
.avatar {
color: $white;
background-color: $gray-500;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 1rem;
border-radius: 50%;
height: 48px;
width: 48px;
img {
width: 100%;
border-radius: 50%;
}
+ .avatar-content {
display: inline-block;
margin-left: .75rem;
}
}
// Avatar size variations
.avatar-lg {
width: 58px;
height: 58px;
font-size: $font-size-sm;
}
.avatar-sm {
width: 36px;
height: 36px;
font-size: $font-size-sm;
}

View File

@ -1,12 +0,0 @@
//
// Brand buttons
//
// Color variations
@each $color, $value in $brand-colors {
.btn-#{$color} {
@include button-variant($value, $value);
}
}

View File

@ -1,92 +0,0 @@
//
// Icon buttons
//
.btn-icon {
.btn-inner--icon {
img {
width: 20px;
}
}
.btn-inner--text:not(:first-child) {
margin-left: 0.75em;
}
.btn-inner--text:not(:last-child) {
margin-right: 0.75em;
}
}
// Button only with icon and NO text
.btn-icon-only {
width: 2.375rem;
height: 2.375rem;
padding: 0;
}
a.btn-icon-only {
line-height: 2.5;
}
.btn-icon-only.btn-sm {
width: 2rem;
height: 2rem;
}
//
// Clipboard button
// dedicated element for copying icons
//
.btn-icon-clipboard {
margin: 0;
padding: 1.5rem;
font-size: $font-size-base;
font-weight: $font-weight-normal;
line-height: 1.25;
color: $gray-800;
background-color: $gray-100;
border-radius: $border-radius;
border: 0;
text-align: left;
font-family: inherit;
display: inline-block;
vertical-align: middle;
text-decoration: none;
-moz-appearance: none;
cursor: pointer;
width: 100%;
margin: .5rem 0;
&:hover {
background-color: $white;
box-shadow: rgba(0, 0, 0, .1) 0 0 0 1px, rgba(0, 0, 0, .1) 0 4px 16px;
}
> div {
align-items: center;
display: flex;
}
i {
box-sizing: content-box;
color: theme-color("primary");
vertical-align: middle;
font-size: 1.5rem;
}
span {
display: inline-block;
font-size: 0.875rem;
line-height: 1.5;
margin-left: 16px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
}
}

View File

@ -1,91 +0,0 @@
//
// Icon buttons
//
// General styles
.btn {
position: relative;
text-transform: $btn-text-transform;
transition: $transition-base;
letter-spacing: $btn-letter-spacing;
font-size: $input-btn-font-size;
will-change: transform;
&:hover {
@include box-shadow($btn-hover-box-shadow);
transform: translateY($btn-hover-translate-y);
}
&:not(:last-child) {
margin-right: .5rem;
}
// Icons
i:not(:first-child),
svg:not(:first-child) {
margin-left: .5rem;
}
i:not(:last-child),
svg:not(:last-child) {
margin-right: .5rem;
}
}
// Remove translateY and margin animation when btn is included in a btn-group or input-group
.btn-group,
.input-group {
.btn {
margin-right: 0;
transform: translateY(0);
}
}
// Size variations
.btn-sm {
font-size: $input-btn-font-size-sm;
}
.btn-lg {
font-size: $input-btn-font-size-lg;
}
// Some quick fixes (to revise)
// Fixes
[class*="btn-outline-"] {
border-width: 1px;
}
.btn-outline-secondary {
color: darken(theme-color("secondary"), 50%);
}
.btn-inner--icon {
i:not(.fa) {
position: relative;
top: 2px;
}
}
.btn-link {
font-weight: $btn-font-weight;
box-shadow: none;
&:hover {
box-shadow: none;
transform: none;
}
}
.btn-neutral {
color: theme-color("primary");
}

View File

@ -1,10 +0,0 @@
//
// Card with hover animations
//
.card-lift--hover {
&:hover {
transform: translateY(-20px);
@include transition($transition-base);
}
}

Some files were not shown because too many files have changed in this diff Show More