mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into contributions-table
This commit is contained in:
commit
92b076e8b1
3
.dbeaver/credentials-config.json
Normal file
3
.dbeaver/credentials-config.json
Normal file
@ -0,0 +1,3 @@
|
||||
4ƒk׀ךֻ1°,•<EFBFBD>fעbלAלqִ¬cי<EFBFBD>#¾›צ¾ר#s’8-ְ1‰&»;נצד"¢פשל7€d¥jM?‘bljfB¼ƒqֱ=
|
||||
<EFBFBD>ײmyפ¿
|
||||
vת·´V
|
||||
32
.dbeaver/data-sources.json
Normal file
32
.dbeaver/data-sources.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"folders": {},
|
||||
"connections": {
|
||||
"mariaDB-1813fbbc7bc-107c0b3aeaeb91ab": {
|
||||
"provider": "mysql",
|
||||
"driver": "mariaDB",
|
||||
"name": "gradido",
|
||||
"save-password": true,
|
||||
"read-only": false,
|
||||
"configuration": {
|
||||
"host": "localhost",
|
||||
"port": "3306",
|
||||
"url": "jdbc:mariadb://localhost:3306/",
|
||||
"home": "mysql_client",
|
||||
"type": "dev",
|
||||
"auth-model": "native",
|
||||
"handlers": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"connection-types": {
|
||||
"dev": {
|
||||
"name": "Development",
|
||||
"color": "255,255,255",
|
||||
"description": "Regular development database",
|
||||
"auto-commit": true,
|
||||
"confirm-execute": false,
|
||||
"confirm-data-change": false,
|
||||
"auto-close-transactions": false
|
||||
}
|
||||
}
|
||||
}
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -528,7 +528,7 @@ jobs:
|
||||
report_name: Coverage Backend
|
||||
type: lcov
|
||||
result_path: ./backend/coverage/lcov.info
|
||||
min_coverage: 66
|
||||
min_coverage: 68
|
||||
token: ${{ github.token }}
|
||||
|
||||
##########################################################################
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,5 @@
|
||||
.dbeaver
|
||||
.project
|
||||
*.log
|
||||
*.bak
|
||||
/node_modules/*
|
||||
messages.pot
|
||||
nbproject
|
||||
|
||||
18
.project
Normal file
18
.project
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Gradido</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.jkiss.dbeaver.DBeaverNature</nature>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
40
CHANGELOG.md
40
CHANGELOG.md
@ -4,8 +4,48 @@ All notable changes to this project will be documented in this file. Dates are d
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [1.9.0](https://github.com/gradido/gradido/compare/1.8.3...1.9.0)
|
||||
|
||||
- refactor: 🍰 Refactor To `filters` Object And Rename Filters Properties [`#1914`](https://github.com/gradido/gradido/pull/1914)
|
||||
- refactor register button position [`#1964`](https://github.com/gradido/gradido/pull/1964)
|
||||
- fixed redeem link is mobile start false [`#1958`](https://github.com/gradido/gradido/pull/1958)
|
||||
- 1951 remove back link and remove gray box [`#1959`](https://github.com/gradido/gradido/pull/1959)
|
||||
- 1952 change footer icons color an remove save login [`#1955`](https://github.com/gradido/gradido/pull/1955)
|
||||
- fix: License should be a valid SPDX license expression [`#1954`](https://github.com/gradido/gradido/pull/1954)
|
||||
- refactor: 🍰 Refactor THX Page – 2. Step [`#1858`](https://github.com/gradido/gradido/pull/1858)
|
||||
- fix: Add Timezone to Decay Start Block [`#1931`](https://github.com/gradido/gradido/pull/1931)
|
||||
- devops: Update License in all package.json [`#1925`](https://github.com/gradido/gradido/pull/1925)
|
||||
- docu: Creation Flowchart [`#1918`](https://github.com/gradido/gradido/pull/1918)
|
||||
- refactor: Use Logger Categories [`#1912`](https://github.com/gradido/gradido/pull/1912)
|
||||
- 1883 remove the animated coins in the profile settings [`#1946`](https://github.com/gradido/gradido/pull/1946)
|
||||
- 1942 replace pictures for carousel [`#1943`](https://github.com/gradido/gradido/pull/1943)
|
||||
- 1933 auth footer is not on one level [`#1941`](https://github.com/gradido/gradido/pull/1941)
|
||||
- 1929 styling new template for password component [`#1935`](https://github.com/gradido/gradido/pull/1935)
|
||||
- 1926 button concept for gradido template [`#1927`](https://github.com/gradido/gradido/pull/1927)
|
||||
- 1916 remove select language from register form [`#1930`](https://github.com/gradido/gradido/pull/1930)
|
||||
- rename files from auth folder, rule vue name = name files [`#1937`](https://github.com/gradido/gradido/pull/1937)
|
||||
- Add files Bild_1_2400.jpg [`#1945`](https://github.com/gradido/gradido/pull/1945)
|
||||
- Bilder für Slider [`#1940`](https://github.com/gradido/gradido/pull/1940)
|
||||
- contribution analysis of elopage and concept proposal [`#1917`](https://github.com/gradido/gradido/pull/1917)
|
||||
- 1676 feature federation technical concept [`#1711`](https://github.com/gradido/gradido/pull/1711)
|
||||
- more details about Windows installation [`#1842`](https://github.com/gradido/gradido/pull/1842)
|
||||
- Concept to Introduce Gradido ID [`#1797`](https://github.com/gradido/gradido/pull/1797)
|
||||
- first draft of concept event protocol [`#1796`](https://github.com/gradido/gradido/pull/1796)
|
||||
- 1682 new design for the login and registration area [`#1693`](https://github.com/gradido/gradido/pull/1693)
|
||||
- fix: Database Connection Charset to utf8mb4_unicode_ci [`#1915`](https://github.com/gradido/gradido/pull/1915)
|
||||
- refactor: 🍰 Create Filter Object in GQL And Rename Args [`#1860`](https://github.com/gradido/gradido/pull/1860)
|
||||
- feat: 🍰 Improve Apollo Logging [`#1859`](https://github.com/gradido/gradido/pull/1859)
|
||||
- Add files via upload [`#1903`](https://github.com/gradido/gradido/pull/1903)
|
||||
- 🍰 Hide Pagenation On Short Transactionlist [`#1875`](https://github.com/gradido/gradido/pull/1875)
|
||||
- 🍰 Ignore macOS .DS_Store Files [`#1902`](https://github.com/gradido/gradido/pull/1902)
|
||||
- pre I from #1682, add images, svg for new styling [`#1900`](https://github.com/gradido/gradido/pull/1900)
|
||||
- add browserstack logo image [`#1888`](https://github.com/gradido/gradido/pull/1888)
|
||||
|
||||
#### [1.8.3](https://github.com/gradido/gradido/compare/1.8.2...1.8.3)
|
||||
|
||||
> 13 May 2022
|
||||
|
||||
- Release 1.8.3 [`#1899`](https://github.com/gradido/gradido/pull/1899)
|
||||
- Checkbox [`#1894`](https://github.com/gradido/gradido/pull/1894)
|
||||
- fix: Count Deprecated Links as Well [`#1892`](https://github.com/gradido/gradido/pull/1892)
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"description": "Administraion Interface for Gradido",
|
||||
"main": "index.js",
|
||||
"author": "Moriz Wahl",
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.0",
|
||||
"license": "Apache-2.0",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
|
||||
@ -2,7 +2,12 @@ import gql from 'graphql-tag'
|
||||
|
||||
export const listTransactionLinksAdmin = gql`
|
||||
query ($currentPage: Int = 1, $pageSize: Int = 5, $userId: Int!) {
|
||||
listTransactionLinksAdmin(currentPage: $currentPage, pageSize: $pageSize, userId: $userId) {
|
||||
listTransactionLinksAdmin(
|
||||
currentPage: $currentPage
|
||||
pageSize: $pageSize
|
||||
userId: $userId
|
||||
filters: { withRedeemed: true, withExpired: true, withDeleted: true }
|
||||
) {
|
||||
linkCount
|
||||
linkList {
|
||||
id
|
||||
|
||||
@ -1,12 +1,7 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export const searchUsers = gql`
|
||||
query (
|
||||
$searchText: String!
|
||||
$currentPage: Int
|
||||
$pageSize: Int
|
||||
$filters: SearchUsersFiltersInput
|
||||
) {
|
||||
query ($searchText: String!, $currentPage: Int, $pageSize: Int, $filters: SearchUsersFilters) {
|
||||
searchUsers(
|
||||
searchText: $searchText
|
||||
currentPage: $currentPage
|
||||
|
||||
@ -72,8 +72,8 @@ describe('Creation', () => {
|
||||
currentPage: 1,
|
||||
pageSize: 25,
|
||||
filters: {
|
||||
filterByActivated: true,
|
||||
filterByDeleted: false,
|
||||
byActivated: true,
|
||||
byDeleted: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -274,8 +274,8 @@ describe('Creation', () => {
|
||||
currentPage: 1,
|
||||
pageSize: 25,
|
||||
filters: {
|
||||
filterByActivated: true,
|
||||
filterByDeleted: false,
|
||||
byActivated: true,
|
||||
byDeleted: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -293,8 +293,8 @@ describe('Creation', () => {
|
||||
currentPage: 1,
|
||||
pageSize: 25,
|
||||
filters: {
|
||||
filterByActivated: true,
|
||||
filterByDeleted: false,
|
||||
byActivated: true,
|
||||
byDeleted: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -312,8 +312,8 @@ describe('Creation', () => {
|
||||
currentPage: 2,
|
||||
pageSize: 25,
|
||||
filters: {
|
||||
filterByActivated: true,
|
||||
filterByDeleted: false,
|
||||
byActivated: true,
|
||||
byDeleted: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
@ -103,8 +103,8 @@ export default {
|
||||
currentPage: this.currentPage,
|
||||
pageSize: this.perPage,
|
||||
filters: {
|
||||
filterByActivated: true,
|
||||
filterByDeleted: false,
|
||||
byActivated: true,
|
||||
byDeleted: false,
|
||||
},
|
||||
},
|
||||
fetchPolicy: 'network-only',
|
||||
|
||||
@ -83,8 +83,8 @@ describe('UserSearch', () => {
|
||||
currentPage: 1,
|
||||
pageSize: 25,
|
||||
filters: {
|
||||
filterByActivated: null,
|
||||
filterByDeleted: null,
|
||||
byActivated: null,
|
||||
byDeleted: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -104,8 +104,8 @@ describe('UserSearch', () => {
|
||||
currentPage: 1,
|
||||
pageSize: 25,
|
||||
filters: {
|
||||
filterByActivated: false,
|
||||
filterByDeleted: null,
|
||||
byActivated: false,
|
||||
byDeleted: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -126,8 +126,8 @@ describe('UserSearch', () => {
|
||||
currentPage: 1,
|
||||
pageSize: 25,
|
||||
filters: {
|
||||
filterByActivated: null,
|
||||
filterByDeleted: true,
|
||||
byActivated: null,
|
||||
byDeleted: true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -148,8 +148,8 @@ describe('UserSearch', () => {
|
||||
currentPage: 2,
|
||||
pageSize: 25,
|
||||
filters: {
|
||||
filterByActivated: null,
|
||||
filterByDeleted: null,
|
||||
byActivated: null,
|
||||
byDeleted: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -170,8 +170,8 @@ describe('UserSearch', () => {
|
||||
currentPage: 1,
|
||||
pageSize: 25,
|
||||
filters: {
|
||||
filterByActivated: null,
|
||||
filterByDeleted: null,
|
||||
byActivated: null,
|
||||
byDeleted: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -189,8 +189,8 @@ describe('UserSearch', () => {
|
||||
currentPage: 1,
|
||||
pageSize: 25,
|
||||
filters: {
|
||||
filterByActivated: null,
|
||||
filterByDeleted: null,
|
||||
byActivated: null,
|
||||
byDeleted: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
<b-button class="unconfirmedRegisterMails" variant="light" @click="unconfirmedRegisterMails">
|
||||
<b-icon icon="envelope" variant="danger"></b-icon>
|
||||
{{
|
||||
filterByActivated === null
|
||||
filters.byActivated === null
|
||||
? $t('all_emails')
|
||||
: filterByActivated === false
|
||||
: filters.byActivated === false
|
||||
? $t('unregistered_emails')
|
||||
: ''
|
||||
}}
|
||||
@ -14,9 +14,9 @@
|
||||
<b-button class="deletedUserSearch" variant="light" @click="deletedUserSearch">
|
||||
<b-icon icon="x-circle" variant="danger"></b-icon>
|
||||
{{
|
||||
filterByDeleted === null
|
||||
filters.byDeleted === null
|
||||
? $t('all_emails')
|
||||
: filterByDeleted === true
|
||||
: filters.byDeleted === true
|
||||
? $t('deleted_user')
|
||||
: ''
|
||||
}}
|
||||
@ -72,8 +72,10 @@ export default {
|
||||
searchResult: [],
|
||||
massCreation: [],
|
||||
criteria: '',
|
||||
filterByActivated: null,
|
||||
filterByDeleted: null,
|
||||
filters: {
|
||||
byActivated: null,
|
||||
byDeleted: null,
|
||||
},
|
||||
rows: 0,
|
||||
currentPage: 1,
|
||||
perPage: 25,
|
||||
@ -82,11 +84,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
unconfirmedRegisterMails() {
|
||||
this.filterByActivated = this.filterByActivated === null ? false : null
|
||||
this.filters.byActivated = this.filters.byActivated === null ? false : null
|
||||
this.getUsers()
|
||||
},
|
||||
deletedUserSearch() {
|
||||
this.filterByDeleted = this.filterByDeleted === null ? true : null
|
||||
this.filters.byDeleted = this.filters.byDeleted === null ? true : null
|
||||
this.getUsers()
|
||||
},
|
||||
getUsers() {
|
||||
@ -97,10 +99,7 @@ export default {
|
||||
searchText: this.criteria,
|
||||
currentPage: this.currentPage,
|
||||
pageSize: this.perPage,
|
||||
filters: {
|
||||
filterByActivated: this.filterByActivated,
|
||||
filterByDeleted: this.filterByDeleted,
|
||||
},
|
||||
filters: this.filters,
|
||||
},
|
||||
fetchPolicy: 'no-cache',
|
||||
})
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gradido-backend",
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.0",
|
||||
"description": "Gradido unified backend providing an API-Service for Gradido Transactions",
|
||||
"main": "src/index.ts",
|
||||
"repository": "https://github.com/gradido/gradido/backend",
|
||||
|
||||
@ -10,7 +10,7 @@ Decimal.set({
|
||||
})
|
||||
|
||||
const constants = {
|
||||
DB_VERSION: '0037-contributions_table',
|
||||
DB_VERSION: '0039-contributions_table',
|
||||
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
|
||||
LOG4JS_CONFIG: 'log4js-config.json',
|
||||
// default log level on production should be info
|
||||
|
||||
@ -12,6 +12,6 @@ export default class SearchUsersArgs {
|
||||
@Field(() => Int, { nullable: true })
|
||||
pageSize?: number
|
||||
|
||||
@Field(() => SearchUsersFilters, { nullable: true })
|
||||
@Field(() => SearchUsersFilters, { nullable: true, defaultValue: null })
|
||||
filters: SearchUsersFilters
|
||||
}
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import { Field, InputType, ObjectType } from 'type-graphql'
|
||||
import { Field, InputType } from 'type-graphql'
|
||||
|
||||
@ObjectType()
|
||||
@InputType('SearchUsersFiltersInput')
|
||||
@InputType()
|
||||
export default class SearchUsersFilters {
|
||||
@Field(() => Boolean, { nullable: true, defaultValue: null })
|
||||
filterByActivated?: boolean | null
|
||||
byActivated: boolean
|
||||
|
||||
@Field(() => Boolean, { nullable: true, defaultValue: null })
|
||||
filterByDeleted?: boolean | null
|
||||
byDeleted: boolean
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import { ArgsType, Field } from 'type-graphql'
|
||||
import { Field, InputType } from 'type-graphql'
|
||||
|
||||
@ArgsType()
|
||||
@InputType()
|
||||
export default class TransactionLinkFilters {
|
||||
@Field(() => Boolean, { nullable: true, defaultValue: true })
|
||||
filterByDeleted?: boolean
|
||||
@Field(() => Boolean, { nullable: true })
|
||||
withDeleted: boolean
|
||||
|
||||
@Field(() => Boolean, { nullable: true, defaultValue: true })
|
||||
filterByExpired?: boolean
|
||||
@Field(() => Boolean, { nullable: true })
|
||||
withExpired: boolean
|
||||
|
||||
@Field(() => Boolean, { nullable: true, defaultValue: true })
|
||||
filterByRedeemed?: boolean
|
||||
@Field(() => Boolean, { nullable: true })
|
||||
withRedeemed: boolean
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import { convertObjValuesToArray } from '@/util/utilities'
|
||||
import { objectValuesToArray } from '@/util/utilities'
|
||||
import { testEnvironment, resetToken, cleanDB } from '@test/helpers'
|
||||
import { userFactory } from '@/seeds/factory/user'
|
||||
import { creationFactory } from '@/seeds/factory/creation'
|
||||
import { creations } from '@/seeds/creation/index'
|
||||
import { transactionLinkFactory } from '@/seeds/factory/transactionLink'
|
||||
import { transactionLinks } from '@/seeds/transactionLink/index'
|
||||
import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg'
|
||||
import { peterLustig } from '@/seeds/users/peter-lustig'
|
||||
import { stephenHawking } from '@/seeds/users/stephen-hawking'
|
||||
@ -12,14 +15,18 @@ import { garrickOllivander } from '@/seeds/users/garrick-ollivander'
|
||||
import {
|
||||
deleteUser,
|
||||
unDeleteUser,
|
||||
searchUsers,
|
||||
createPendingCreation,
|
||||
createPendingCreations,
|
||||
updatePendingCreation,
|
||||
deletePendingCreation,
|
||||
confirmPendingCreation,
|
||||
} from '@/seeds/graphql/mutations'
|
||||
import { getPendingCreations, login } from '@/seeds/graphql/queries'
|
||||
import {
|
||||
getPendingCreations,
|
||||
login,
|
||||
searchUsers,
|
||||
listTransactionLinksAdmin,
|
||||
} from '@/seeds/graphql/queries'
|
||||
import { GraphQLError } from 'graphql'
|
||||
import { User } from '@entity/User'
|
||||
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
||||
@ -366,7 +373,7 @@ describe('AdminResolver', () => {
|
||||
data: {
|
||||
searchUsers: {
|
||||
userCount: 4,
|
||||
userList: expect.arrayContaining(convertObjValuesToArray(allUsers)),
|
||||
userList: expect.arrayContaining(objectValuesToArray(allUsers)),
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -382,8 +389,8 @@ describe('AdminResolver', () => {
|
||||
variables: {
|
||||
...variablesWithoutTextAndFilters,
|
||||
filters: {
|
||||
filterByActivated: null,
|
||||
filterByDeleted: null,
|
||||
byActivated: null,
|
||||
byDeleted: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -392,7 +399,7 @@ describe('AdminResolver', () => {
|
||||
data: {
|
||||
searchUsers: {
|
||||
userCount: 4,
|
||||
userList: expect.arrayContaining(convertObjValuesToArray(allUsers)),
|
||||
userList: expect.arrayContaining(objectValuesToArray(allUsers)),
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -408,8 +415,8 @@ describe('AdminResolver', () => {
|
||||
variables: {
|
||||
...variablesWithoutTextAndFilters,
|
||||
filters: {
|
||||
filterByActivated: false,
|
||||
filterByDeleted: null,
|
||||
byActivated: false,
|
||||
byDeleted: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -434,8 +441,8 @@ describe('AdminResolver', () => {
|
||||
variables: {
|
||||
...variablesWithoutTextAndFilters,
|
||||
filters: {
|
||||
filterByActivated: null,
|
||||
filterByDeleted: true,
|
||||
byActivated: null,
|
||||
byDeleted: true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -460,8 +467,8 @@ describe('AdminResolver', () => {
|
||||
variables: {
|
||||
...variablesWithoutTextAndFilters,
|
||||
filters: {
|
||||
filterByActivated: false,
|
||||
filterByDeleted: true,
|
||||
byActivated: false,
|
||||
byDeleted: true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -1324,4 +1331,266 @@ describe('AdminResolver', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('transaction links list', () => {
|
||||
const variables = {
|
||||
userId: 1, // dummy, may be replaced
|
||||
filters: null,
|
||||
currentPage: 1,
|
||||
pageSize: 5,
|
||||
}
|
||||
|
||||
describe('unauthenticated', () => {
|
||||
it('returns an error', async () => {
|
||||
await expect(
|
||||
query({
|
||||
query: listTransactionLinksAdmin,
|
||||
variables,
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
errors: [new GraphQLError('401 Unauthorized')],
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('authenticated', () => {
|
||||
describe('without admin rights', () => {
|
||||
beforeAll(async () => {
|
||||
user = await userFactory(testEnv, bibiBloxberg)
|
||||
await query({
|
||||
query: login,
|
||||
variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' },
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await cleanDB()
|
||||
resetToken()
|
||||
})
|
||||
|
||||
it('returns an error', async () => {
|
||||
await expect(
|
||||
query({
|
||||
query: listTransactionLinksAdmin,
|
||||
variables,
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
errors: [new GraphQLError('401 Unauthorized')],
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with admin rights', () => {
|
||||
beforeAll(async () => {
|
||||
// admin 'peter@lustig.de' has to exists for 'creationFactory'
|
||||
admin = await userFactory(testEnv, peterLustig)
|
||||
|
||||
user = await userFactory(testEnv, bibiBloxberg)
|
||||
variables.userId = user.id
|
||||
variables.pageSize = 25
|
||||
// bibi needs GDDs
|
||||
const bibisCreation = creations.find((creation) => creation.email === 'bibi@bloxberg.de')
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await creationFactory(testEnv, bibisCreation!)
|
||||
// bibis transaktion links
|
||||
const bibisTransaktionLinks = transactionLinks.filter(
|
||||
(transactionLink) => transactionLink.email === 'bibi@bloxberg.de',
|
||||
)
|
||||
for (let i = 0; i < bibisTransaktionLinks.length; i++) {
|
||||
await transactionLinkFactory(testEnv, bibisTransaktionLinks[i])
|
||||
}
|
||||
|
||||
// admin: only now log in
|
||||
await query({
|
||||
query: login,
|
||||
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await cleanDB()
|
||||
resetToken()
|
||||
})
|
||||
|
||||
describe('without any filters', () => {
|
||||
it('finds 6 open transaction links and no deleted or redeemed', async () => {
|
||||
await expect(
|
||||
query({
|
||||
query: listTransactionLinksAdmin,
|
||||
variables,
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
data: {
|
||||
listTransactionLinksAdmin: {
|
||||
linkCount: 6,
|
||||
linkList: expect.not.arrayContaining([
|
||||
expect.objectContaining({
|
||||
memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(',
|
||||
createdAt: expect.any(String),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
memo: 'Da habe ich mich wohl etwas übernommen.',
|
||||
deletedAt: expect.any(String),
|
||||
}),
|
||||
]),
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('all filters are null', () => {
|
||||
it('finds 6 open transaction links and no deleted or redeemed', async () => {
|
||||
await expect(
|
||||
query({
|
||||
query: listTransactionLinksAdmin,
|
||||
variables: {
|
||||
...variables,
|
||||
filters: {
|
||||
withDeleted: null,
|
||||
withExpired: null,
|
||||
withRedeemed: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
data: {
|
||||
listTransactionLinksAdmin: {
|
||||
linkCount: 6,
|
||||
linkList: expect.not.arrayContaining([
|
||||
expect.objectContaining({
|
||||
memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(',
|
||||
createdAt: expect.any(String),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
memo: 'Da habe ich mich wohl etwas übernommen.',
|
||||
deletedAt: expect.any(String),
|
||||
}),
|
||||
]),
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('filter with deleted', () => {
|
||||
it('finds 6 open transaction links, 1 deleted, and no redeemed', async () => {
|
||||
await expect(
|
||||
query({
|
||||
query: listTransactionLinksAdmin,
|
||||
variables: {
|
||||
...variables,
|
||||
filters: {
|
||||
withDeleted: true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
data: {
|
||||
listTransactionLinksAdmin: {
|
||||
linkCount: 7,
|
||||
linkList: expect.arrayContaining([
|
||||
expect.not.objectContaining({
|
||||
memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(',
|
||||
createdAt: expect.any(String),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
memo: 'Da habe ich mich wohl etwas übernommen.',
|
||||
deletedAt: expect.any(String),
|
||||
}),
|
||||
]),
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('filter by expired', () => {
|
||||
it('finds 5 open transaction links, 1 expired, and no redeemed', async () => {
|
||||
await expect(
|
||||
query({
|
||||
query: listTransactionLinksAdmin,
|
||||
variables: {
|
||||
...variables,
|
||||
filters: {
|
||||
withExpired: true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
data: {
|
||||
listTransactionLinksAdmin: {
|
||||
linkCount: 7,
|
||||
linkList: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(',
|
||||
createdAt: expect.any(String),
|
||||
}),
|
||||
expect.not.objectContaining({
|
||||
memo: 'Da habe ich mich wohl etwas übernommen.',
|
||||
deletedAt: expect.any(String),
|
||||
}),
|
||||
]),
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
// TODO: works not as expected, because 'redeemedAt' and 'redeemedBy' have to be added to the transaktion link factory
|
||||
describe.skip('filter by redeemed', () => {
|
||||
it('finds 6 open transaction links, 1 deleted, and no redeemed', async () => {
|
||||
await expect(
|
||||
query({
|
||||
query: listTransactionLinksAdmin,
|
||||
variables: {
|
||||
...variables,
|
||||
filters: {
|
||||
withDeleted: null,
|
||||
withExpired: null,
|
||||
withRedeemed: true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
data: {
|
||||
listTransactionLinksAdmin: {
|
||||
linkCount: 6,
|
||||
linkList: expect.arrayContaining([
|
||||
expect.not.objectContaining({
|
||||
memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(',
|
||||
createdAt: expect.any(String),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
memo: 'Yeah, eingelöst!',
|
||||
redeemedAt: expect.any(String),
|
||||
redeemedBy: expect.any(Number),
|
||||
}),
|
||||
expect.not.objectContaining({
|
||||
memo: 'Da habe ich mich wohl etwas übernommen.',
|
||||
deletedAt: expect.any(String),
|
||||
}),
|
||||
]),
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -59,12 +59,12 @@ export class AdminResolver {
|
||||
|
||||
const filterCriteria: ObjectLiteral[] = []
|
||||
if (filters) {
|
||||
if (filters.filterByActivated !== null) {
|
||||
filterCriteria.push({ emailChecked: filters.filterByActivated })
|
||||
if (filters.byActivated !== null) {
|
||||
filterCriteria.push({ emailChecked: filters.byActivated })
|
||||
}
|
||||
|
||||
if (filters.filterByDeleted !== null) {
|
||||
filterCriteria.push({ deletedAt: filters.filterByDeleted ? Not(IsNull()) : IsNull() })
|
||||
if (filters.byDeleted !== null) {
|
||||
filterCriteria.push({ deletedAt: filters.byDeleted ? Not(IsNull()) : IsNull() })
|
||||
}
|
||||
}
|
||||
|
||||
@ -458,9 +458,10 @@ export class AdminResolver {
|
||||
async listTransactionLinksAdmin(
|
||||
@Args()
|
||||
{ currentPage = 1, pageSize = 5, order = Order.DESC }: Paginated,
|
||||
@Args()
|
||||
@Arg('filters', () => TransactionLinkFilters, { nullable: true })
|
||||
filters: TransactionLinkFilters,
|
||||
@Arg('userId', () => Int) userId: number,
|
||||
@Arg('userId', () => Int)
|
||||
userId: number,
|
||||
): Promise<TransactionLinkResult> {
|
||||
const user = await dbUser.findOneOrFail({ id: userId })
|
||||
const where: {
|
||||
@ -469,12 +470,16 @@ export class AdminResolver {
|
||||
validUntil?: FindOperator<Date> | null
|
||||
} = {
|
||||
userId,
|
||||
redeemedBy: null,
|
||||
validUntil: MoreThan(new Date()),
|
||||
}
|
||||
if (filters) {
|
||||
if (filters.withRedeemed) delete where.redeemedBy
|
||||
if (filters.withExpired) delete where.validUntil
|
||||
}
|
||||
if (!filters.filterByRedeemed) where.redeemedBy = null
|
||||
if (!filters.filterByExpired) where.validUntil = MoreThan(new Date())
|
||||
const [transactionLinks, count] = await dbTransactionLink.findAndCount({
|
||||
where,
|
||||
withDeleted: filters.filterByDeleted,
|
||||
withDeleted: filters ? filters.withDeleted : false,
|
||||
order: {
|
||||
createdAt: order,
|
||||
},
|
||||
|
||||
@ -105,35 +105,6 @@ export const unDeleteUser = gql`
|
||||
}
|
||||
`
|
||||
|
||||
export const searchUsers = gql`
|
||||
query (
|
||||
$searchText: String!
|
||||
$currentPage: Int
|
||||
$pageSize: Int
|
||||
$filters: SearchUsersFiltersInput
|
||||
) {
|
||||
searchUsers(
|
||||
searchText: $searchText
|
||||
currentPage: $currentPage
|
||||
pageSize: $pageSize
|
||||
filters: $filters
|
||||
) {
|
||||
userCount
|
||||
userList {
|
||||
userId
|
||||
firstName
|
||||
lastName
|
||||
email
|
||||
creation
|
||||
emailChecked
|
||||
hasElopage
|
||||
emailConfirmationSend
|
||||
deletedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const createPendingCreations = gql`
|
||||
mutation ($pendingCreations: [CreatePendingCreationArgs!]!) {
|
||||
createPendingCreations(pendingCreations: $pendingCreations) {
|
||||
|
||||
@ -91,6 +91,30 @@ export const sendResetPasswordEmail = gql`
|
||||
}
|
||||
`
|
||||
|
||||
export const searchUsers = gql`
|
||||
query ($searchText: String!, $currentPage: Int, $pageSize: Int, $filters: SearchUsersFilters) {
|
||||
searchUsers(
|
||||
searchText: $searchText
|
||||
currentPage: $currentPage
|
||||
pageSize: $pageSize
|
||||
filters: $filters
|
||||
) {
|
||||
userCount
|
||||
userList {
|
||||
userId
|
||||
firstName
|
||||
lastName
|
||||
email
|
||||
creation
|
||||
emailChecked
|
||||
hasElopage
|
||||
emailConfirmationSend
|
||||
deletedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const listGDTEntriesQuery = gql`
|
||||
query ($currentPage: Int!, $pageSize: Int!) {
|
||||
listGDTEntries(currentPage: $currentPage, pageSize: $pageSize) {
|
||||
@ -164,3 +188,32 @@ export const getPendingCreations = gql`
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const listTransactionLinksAdmin = gql`
|
||||
query (
|
||||
$userId: Int!
|
||||
$filters: TransactionLinkFilters
|
||||
$currentPage: Int = 1
|
||||
$pageSize: Int = 5
|
||||
) {
|
||||
listTransactionLinksAdmin(
|
||||
userId: $userId
|
||||
filters: $filters
|
||||
currentPage: $currentPage
|
||||
pageSize: $pageSize
|
||||
) {
|
||||
linkCount
|
||||
linkList {
|
||||
id
|
||||
amount
|
||||
holdAvailableAmount
|
||||
memo
|
||||
code
|
||||
createdAt
|
||||
validUntil
|
||||
redeemedAt
|
||||
deletedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
@ -3,5 +3,8 @@ export interface TransactionLinkInterface {
|
||||
amount: number
|
||||
memo: string
|
||||
createdAt?: Date
|
||||
// TODO: for testing
|
||||
// redeemedAt?: Date
|
||||
// redeemedBy?: number
|
||||
deletedAt?: boolean
|
||||
}
|
||||
|
||||
@ -30,6 +30,10 @@ bei Gradidio sei dabei!`,
|
||||
amount: 19.99,
|
||||
memo: `Kein Trick, keine Zauberrei,
|
||||
bei Gradidio sei dabei!`,
|
||||
// TODO: for testing
|
||||
// memo: `Yeah, eingelöst!`,
|
||||
// redeemedAt: new Date(2022, 2, 2),
|
||||
// redeemedBy: not null,
|
||||
},
|
||||
{
|
||||
email: 'bibi@bloxberg.de',
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
import { EntityRepository, Repository } from '@dbTools/typeorm'
|
||||
import { UserSetting } from '@entity/UserSetting'
|
||||
import { isStringBoolean } from '@/util/validate'
|
||||
|
||||
@EntityRepository(UserSetting)
|
||||
export class UserSettingRepository extends Repository<UserSetting> {
|
||||
async setOrUpdate(userId: number, value: string): Promise<UserSetting> {
|
||||
let entity = await this.findOne({ userId: userId })
|
||||
|
||||
if (!entity) {
|
||||
entity = new UserSetting()
|
||||
entity.userId = userId
|
||||
}
|
||||
entity.value = value
|
||||
return this.save(entity)
|
||||
}
|
||||
|
||||
async readBoolean(userId: number): Promise<boolean> {
|
||||
const entity = await this.findOne({ userId: userId })
|
||||
if (!entity || !isStringBoolean(entity.value)) {
|
||||
return true
|
||||
}
|
||||
return entity.value.toLowerCase() === 'true'
|
||||
}
|
||||
}
|
||||
@ -20,7 +20,6 @@ const communityDbUser: dbUser = {
|
||||
isAdmin: null,
|
||||
publisherId: 0,
|
||||
passphrase: '',
|
||||
settings: [],
|
||||
hasId: function (): boolean {
|
||||
throw new Error('Function not implemented.')
|
||||
},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export const convertObjValuesToArray = (obj: { [x: string]: string }): Array<string> => {
|
||||
export const objectValuesToArray = (obj: { [x: string]: string }): Array<string> => {
|
||||
return Object.keys(obj).map(function (key) {
|
||||
return obj[key]
|
||||
})
|
||||
|
||||
@ -1,32 +1,39 @@
|
||||
# database
|
||||
|
||||
## Project setup
|
||||
```
|
||||
|
||||
```bash
|
||||
yarn install
|
||||
```
|
||||
|
||||
## Upgrade migrations production
|
||||
```
|
||||
|
||||
```bash
|
||||
yarn up
|
||||
```
|
||||
|
||||
## Upgrade migrations development
|
||||
```
|
||||
|
||||
```bash
|
||||
yarn dev_up
|
||||
```
|
||||
|
||||
## Downgrade migrations production
|
||||
```
|
||||
|
||||
```bash
|
||||
yarn down
|
||||
```
|
||||
|
||||
## Downgrade migrations development
|
||||
```
|
||||
|
||||
```bash
|
||||
yarn dev_down
|
||||
```
|
||||
|
||||
## Reset database
|
||||
```
|
||||
|
||||
```bash
|
||||
yarn dev_reset
|
||||
```
|
||||
|
||||
Runs all down migrations and after this all up migrations.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm'
|
||||
import { UserSetting } from '../UserSetting'
|
||||
import { UserSetting } from '../0002-add_settings/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' })
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm'
|
||||
import { User } from '../User'
|
||||
import { User } from '../0034-drop_server_user_table/User'
|
||||
|
||||
@Entity()
|
||||
export class UserSetting extends BaseEntity {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm'
|
||||
import { UserSetting } from '../UserSetting'
|
||||
import { UserSetting } from '../0002-add_settings/UserSetting'
|
||||
|
||||
@Entity('state_users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||
export class User extends BaseEntity {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm'
|
||||
import { UserSetting } from '../UserSetting'
|
||||
import { UserSetting } from '../0002-add_settings/UserSetting'
|
||||
|
||||
@Entity('state_users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||
export class User extends BaseEntity {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm'
|
||||
import { UserSetting } from '../UserSetting'
|
||||
import { UserSetting } from '../0002-add_settings/UserSetting'
|
||||
|
||||
@Entity('state_users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||
export class User extends BaseEntity {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm'
|
||||
import { UserSetting } from '../UserSetting'
|
||||
import { UserSetting } from '../0002-add_settings/UserSetting'
|
||||
|
||||
@Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||
export class User extends BaseEntity {
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
OneToMany,
|
||||
DeleteDateColumn,
|
||||
} from 'typeorm'
|
||||
import { UserSetting } from '../UserSetting'
|
||||
import { UserSetting } from '../0002-add_settings/UserSetting'
|
||||
|
||||
@Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||
export class User extends BaseEntity {
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
OneToMany,
|
||||
DeleteDateColumn,
|
||||
} from 'typeorm'
|
||||
import { UserSetting } from '../UserSetting'
|
||||
import { UserSetting } from '../0002-add_settings/UserSetting'
|
||||
|
||||
@Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||
export class User extends BaseEntity {
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
OneToMany,
|
||||
DeleteDateColumn,
|
||||
} from 'typeorm'
|
||||
import { UserSetting } from '../UserSetting'
|
||||
import { UserSetting } from '../0002-add_settings/UserSetting'
|
||||
|
||||
@Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||
export class User extends BaseEntity {
|
||||
|
||||
70
database/entity/0037-drop_user_setting_table/User.ts
Normal file
70
database/entity/0037-drop_user_setting_table/User.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, DeleteDateColumn } from 'typeorm'
|
||||
|
||||
@Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||
export class User extends BaseEntity {
|
||||
@PrimaryGeneratedColumn('increment', { unsigned: true })
|
||||
id: number
|
||||
|
||||
@Column({ name: 'public_key', type: 'binary', length: 32, default: null, nullable: true })
|
||||
pubKey: Buffer
|
||||
|
||||
@Column({ name: 'privkey', type: 'binary', length: 80, default: null, nullable: true })
|
||||
privKey: Buffer
|
||||
|
||||
@Column({ length: 255, unique: true, nullable: false, collation: 'utf8mb4_unicode_ci' })
|
||||
email: string
|
||||
|
||||
@Column({
|
||||
name: 'first_name',
|
||||
length: 255,
|
||||
nullable: true,
|
||||
default: null,
|
||||
collation: 'utf8mb4_unicode_ci',
|
||||
})
|
||||
firstName: string
|
||||
|
||||
@Column({
|
||||
name: 'last_name',
|
||||
length: 255,
|
||||
nullable: true,
|
||||
default: null,
|
||||
collation: 'utf8mb4_unicode_ci',
|
||||
})
|
||||
lastName: string
|
||||
|
||||
@DeleteDateColumn()
|
||||
deletedAt: Date | null
|
||||
|
||||
@Column({ type: 'bigint', default: 0, unsigned: true })
|
||||
password: BigInt
|
||||
|
||||
@Column({ name: 'email_hash', type: 'binary', length: 32, default: null, nullable: true })
|
||||
emailHash: Buffer
|
||||
|
||||
@Column({ name: 'created', default: () => 'CURRENT_TIMESTAMP', nullable: false })
|
||||
createdAt: Date
|
||||
|
||||
@Column({ name: 'email_checked', type: 'bool', nullable: false, default: false })
|
||||
emailChecked: boolean
|
||||
|
||||
@Column({ length: 4, default: 'de', collation: 'utf8mb4_unicode_ci', nullable: false })
|
||||
language: string
|
||||
|
||||
@Column({ name: 'is_admin', type: 'datetime', nullable: true, default: null })
|
||||
isAdmin: Date | null
|
||||
|
||||
@Column({ name: 'referrer_id', type: 'int', unsigned: true, nullable: true, default: null })
|
||||
referrerId?: number | null
|
||||
|
||||
@Column({ name: 'publisher_id', default: 0 })
|
||||
publisherId: number
|
||||
|
||||
@Column({
|
||||
type: 'text',
|
||||
name: 'passphrase',
|
||||
collation: 'utf8mb4_unicode_ci',
|
||||
nullable: true,
|
||||
default: null,
|
||||
})
|
||||
passphrase: string
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
import Decimal from 'decimal.js-light'
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, DeleteDateColumn } from 'typeorm'
|
||||
import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer'
|
||||
|
||||
@Entity('contribution_links')
|
||||
export class ContributionLink extends BaseEntity {
|
||||
@PrimaryGeneratedColumn('increment', { unsigned: true })
|
||||
id: number
|
||||
|
||||
@Column({ length: 100, nullable: false, collation: 'utf8mb4_unicode_ci' })
|
||||
name: string
|
||||
|
||||
@Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' })
|
||||
memo: string
|
||||
|
||||
@Column({ name: 'valid_from', type: 'datetime', nullable: false })
|
||||
validFrom: Date
|
||||
|
||||
@Column({ name: 'valid_to', type: 'datetime', nullable: true, default: null })
|
||||
validTo: Date | null
|
||||
|
||||
@Column({
|
||||
type: 'decimal',
|
||||
precision: 40,
|
||||
scale: 20,
|
||||
nullable: false,
|
||||
transformer: DecimalTransformer,
|
||||
})
|
||||
amount: Decimal
|
||||
|
||||
@Column({ length: 12, nullable: false, collation: 'utf8mb4_unicode_ci' })
|
||||
cycle: string
|
||||
|
||||
@Column({ name: 'max_per_cycle', unsigned: true, nullable: false, default: 1 })
|
||||
maxPerCycle: number
|
||||
|
||||
@Column({
|
||||
name: 'max_amount_per_month',
|
||||
type: 'decimal',
|
||||
precision: 40,
|
||||
scale: 20,
|
||||
nullable: true,
|
||||
default: null,
|
||||
transformer: DecimalTransformer,
|
||||
})
|
||||
maxAmountPerMonth: Decimal | null
|
||||
|
||||
@Column({
|
||||
name: 'total_max_count_of_contribution',
|
||||
type: 'int',
|
||||
unsigned: true,
|
||||
nullable: true,
|
||||
default: null,
|
||||
})
|
||||
totalMaxCountOfContribution: number | null
|
||||
|
||||
@Column({
|
||||
name: 'max_account_balance',
|
||||
type: 'decimal',
|
||||
precision: 40,
|
||||
scale: 20,
|
||||
nullable: true,
|
||||
default: null,
|
||||
transformer: DecimalTransformer,
|
||||
})
|
||||
maxAccountBalance: Decimal | null
|
||||
|
||||
@Column({
|
||||
name: 'min_gap_hours',
|
||||
type: 'int',
|
||||
unsigned: true,
|
||||
nullable: true,
|
||||
default: null,
|
||||
})
|
||||
minGapHours: number | null
|
||||
|
||||
@Column({ name: 'created_at', type: 'datetime', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt: Date
|
||||
|
||||
@DeleteDateColumn({ name: 'deleted_at' })
|
||||
deletedAt: Date | null
|
||||
|
||||
@Column({ length: 24, nullable: false, collation: 'utf8mb4_unicode_ci' })
|
||||
code: string
|
||||
|
||||
@Column({ name: 'link_enabled', type: 'boolean', default: true })
|
||||
linkEnabled: boolean
|
||||
}
|
||||
@ -1 +1 @@
|
||||
export { Contribution } from './0037-contributions_table/Contribution'
|
||||
export { Contribution } from './0039-contributions_table/Contribution'
|
||||
|
||||
1
database/entity/ContributionLink.ts
Normal file
1
database/entity/ContributionLink.ts
Normal file
@ -0,0 +1 @@
|
||||
export { ContributionLink } from './0038-add_contribution_links_table/ContributionLink'
|
||||
@ -1 +1 @@
|
||||
export { User } from './0034-drop_server_user_table/User'
|
||||
export { User } from './0037-drop_user_setting_table/User'
|
||||
|
||||
@ -1 +0,0 @@
|
||||
export { UserSetting } from './0002-add_settings/UserSetting'
|
||||
@ -1,19 +1,19 @@
|
||||
import { ContributionLink } from './ContributionLink'
|
||||
import { LoginElopageBuys } from './LoginElopageBuys'
|
||||
import { LoginEmailOptIn } from './LoginEmailOptIn'
|
||||
import { Migration } from './Migration'
|
||||
import { Transaction } from './Transaction'
|
||||
import { TransactionLink } from './TransactionLink'
|
||||
import { User } from './User'
|
||||
import { UserSetting } from './UserSetting'
|
||||
import { Contribution } from './Contribution'
|
||||
|
||||
export const entities = [
|
||||
Contribution,
|
||||
ContributionLink,
|
||||
LoginElopageBuys,
|
||||
LoginEmailOptIn,
|
||||
Migration,
|
||||
Transaction,
|
||||
TransactionLink,
|
||||
User,
|
||||
UserSetting,
|
||||
]
|
||||
|
||||
19
database/migrations/0037-drop_user_setting_table.ts
Normal file
19
database/migrations/0037-drop_user_setting_table.ts
Normal file
@ -0,0 +1,19 @@
|
||||
/* MIGRATION DROP user_setting TABLE */
|
||||
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn('DROP TABLE `user_setting`;')
|
||||
}
|
||||
|
||||
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn(`
|
||||
CREATE TABLE IF NOT EXISTS \`user_setting\` (
|
||||
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`userId\` int(11) NOT NULL,
|
||||
\`key\` varchar(255) NOT NULL,
|
||||
\`value\` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (\`id\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`)
|
||||
}
|
||||
35
database/migrations/0038-add_contribution_links_table.ts
Normal file
35
database/migrations/0038-add_contribution_links_table.ts
Normal file
@ -0,0 +1,35 @@
|
||||
/* MIGRATION TO ADD CONTRIBUTION_LINKS
|
||||
*
|
||||
* This migration adds the table `contribution_links` in order to store all sorts of contribution_links data
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn(`
|
||||
CREATE TABLE IF NOT EXISTS \`contribution_links\` (
|
||||
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`name\` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
\`memo\` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
\`valid_from\` datetime NOT NULL,
|
||||
\`valid_to\` datetime NULL,
|
||||
\`amount\` bigint(20) NOT NULL,
|
||||
\`cycle\` varchar(12) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'ONCE',
|
||||
\`max_per_cycle\` int(10) unsigned NOT NULL DEFAULT '1',
|
||||
\`max_amount_per_month\` bigint(20) NULL DEFAULT NULL,
|
||||
\`total_max_count_of_contribution\` int(10) unsigned NULL DEFAULT NULL,
|
||||
\`max_account_balance\` bigint(20) NULL DEFAULT NULL,
|
||||
\`min_gap_hours\` int(10) unsigned NULL DEFAULT NULL,
|
||||
\`created_at\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`deleted_at\` datetime NULL DEFAULT NULL,
|
||||
\`code\` varchar(24) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
\`link_enabled\` tinyint(4) NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY (\`id\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`)
|
||||
}
|
||||
|
||||
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
// write downgrade logic as parameter of queryFn
|
||||
await queryFn(`DROP TABLE IF EXISTS \`contribution_links\`;`)
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gradido-database",
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.0",
|
||||
"description": "Gradido Database Tool to execute database migrations",
|
||||
"main": "src/index.ts",
|
||||
"repository": "https://github.com/gradido/gradido/database",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bootstrap-vue-gradido-wallet",
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node run/server.js",
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
<b-collapse id="nav-collapse" is-nav class="mt-5 mt-lg-0">
|
||||
<b-navbar-nav class="ml-auto" right>
|
||||
<b-nav-item href="https://gradido.net/de/" target="_blank">
|
||||
<b-nav-item :href="`https://gradido.net/${$i18n.locale}`" target="_blank">
|
||||
{{ $t('auth.navbar.aboutGradido') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/register" class="authNavbar ml-lg-5">{{ $t('signup') }}</b-nav-item>
|
||||
|
||||
@ -63,29 +63,25 @@
|
||||
<b-row>
|
||||
<b-col><input-email v-model="form.email"></input-email></b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row class="mt-4 mb-4">
|
||||
<b-col class="mb-4 mb-md-0">
|
||||
<b-form-checkbox
|
||||
id="registerCheckbox"
|
||||
v-model="form.agree"
|
||||
:name="$t('site.signup.agree')"
|
||||
>
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-v-html -->
|
||||
<span class="text-muted" v-html="$t('site.signup.agree')"></span>
|
||||
</b-form-checkbox>
|
||||
</b-col>
|
||||
|
||||
<b-col class="d-flex justify-content-end">
|
||||
<b-button
|
||||
type="submit"
|
||||
:disabled="disabled"
|
||||
:variant="disabled ? 'gradido-disable' : 'gradido'"
|
||||
>
|
||||
{{ $t('signup') }}
|
||||
</b-button>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<div class="my-4">
|
||||
<b-form-checkbox
|
||||
id="registerCheckbox"
|
||||
v-model="form.agree"
|
||||
:name="$t('site.signup.agree')"
|
||||
>
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-v-html -->
|
||||
<span class="text-muted" v-html="$t('site.signup.agree')"></span>
|
||||
</b-form-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<b-button
|
||||
type="submit"
|
||||
:disabled="disabled"
|
||||
:variant="disabled ? 'gradido-disable' : 'gradido'"
|
||||
>
|
||||
{{ $t('signup') }}
|
||||
</b-button>
|
||||
</div>
|
||||
</b-form>
|
||||
</validation-observer>
|
||||
</b-container>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gradido",
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.0",
|
||||
"description": "Gradido",
|
||||
"main": "index.js",
|
||||
"repository": "git@github.com:gradido/gradido.git",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user