Merge changes from master and this branch.

This commit is contained in:
elweyn 2022-06-28 11:17:06 +02:00
commit 0c819522a1
12 changed files with 283 additions and 151 deletions

View File

@ -1 +0,0 @@
šøl"a©`ÑùÞÇ& ˜YOlö>u½AÜWäæTL`äöÀ4)4ÒÕ$;šÀÑ?'ƒðáRX+Í!a†"¤X[õüŒ£ä(0"Œlí® hq[°Øã,C¹É)

View File

@ -1,55 +0,0 @@
{
"folders": {},
"connections": {
"mariaDB-180637bab9c-385a8c5454123150": {
"provider": "mysql",
"driver": "mariaDB",
"name": "gradido_community",
"save-password": true,
"read-only": false,
"configuration": {
"host": "localhost",
"port": "3306",
"database": "gradido_community",
"url": "jdbc:mariadb://localhost:3306/gradido_community",
"home": "mysql_client",
"type": "dev",
"auth-model": "native"
},
"custom-properties": {
"resultset.binary.representation": "hex"
}
}
},
"virtual-models": {
"mariaDB-180637bab9c-385a8c5454123150": {
"gradido_community": {
":users": {
"properties": {
"erd.diagram.state": {
"serialized": "<diagram version=\"1\" name=\"empty\" time=\"202205192015\"><entities><data-source id=\"mariaDB-180637bab9c-385a8c5454123150\"><entity id=\"1\" name=\"users\" fq-name=\"gradido_community.users\" order=\"0\" color-bg=\"255,128,64\" x=\"340\" y=\"201\"><path name=\"gradido_community\"/></entity><entity id=\"2\" name=\"user_setting\" fq-name=\"gradido_community.user_setting\" order=\"1\" x=\"367\" y=\"563\"><path name=\"gradido_community\"/></entity><entity id=\"3\" name=\"transactions\" fq-name=\"gradido_community.transactions\" order=\"2\" x=\"604\" y=\"33\"><path name=\"gradido_community\"/></entity><entity id=\"4\" name=\"transaction_links\" fq-name=\"gradido_community.transaction_links\" order=\"3\" x=\"601\" y=\"351\"><path name=\"gradido_community\"/></entity><entity id=\"5\" name=\"migrations\" fq-name=\"gradido_community.migrations\" order=\"4\" x=\"27\" y=\"27\"><path name=\"gradido_community\"/></entity><entity id=\"6\" name=\"login_email_opt_in\" fq-name=\"gradido_community.login_email_opt_in\" order=\"5\" x=\"17\" y=\"166\"><path name=\"gradido_community\"/></entity><entity id=\"7\" name=\"login_elopage_buys\" fq-name=\"gradido_community.login_elopage_buys\" order=\"6\" x=\"18\" y=\"354\"><path name=\"gradido_community\"/></entity><entity id=\"8\" name=\"admin_pending_creations\" fq-name=\"gradido_community.admin_pending_creations\" order=\"7\" x=\"343\" y=\"12\"><path name=\"gradido_community\"/></entity><entity id=\"9\" name=\"Contributions\" fq-name=\"gradido_community.Contributions\" order=\"8\" x=\"954\" y=\"162\"><path name=\"gradido_community\"/></entity><entity id=\"10\" name=\"ContributionCategory\" fq-name=\"gradido_community.ContributionCategory\" order=\"9\" x=\"954\" y=\"15\"><path name=\"gradido_community\"/></entity><entity id=\"11\" name=\"CreationActivities\" fq-name=\"gradido_community.CreationActivities\" order=\"10\" border-width=\"3\" x=\"958\" y=\"523\"><path name=\"gradido_community\"/></entity></data-source></entities><relations/></diagram>"
}
},
"attributes": {
"public_key": {
"transforms": {
"custom": "resultset.binary.representation"
}
}
}
}
}
}
},
"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
}
}
}

View File

@ -1,55 +0,0 @@
{
"folders": {},
"connections": {
"mariaDB-180637bab9c-385a8c5454123150": {
"provider": "mysql",
"driver": "mariaDB",
"name": "gradido_community",
"save-password": true,
"read-only": false,
"configuration": {
"host": "localhost",
"port": "3306",
"database": "gradido_community",
"url": "jdbc:mariadb://localhost:3306/gradido_community",
"home": "mysql_client",
"type": "dev",
"auth-model": "native"
},
"custom-properties": {
"resultset.binary.representation": "hex"
}
}
},
"virtual-models": {
"mariaDB-180637bab9c-385a8c5454123150": {
"gradido_community": {
":users": {
"properties": {
"erd.diagram.state": {
"serialized": "<diagram version=\"1\" name=\"empty\" time=\"202205200159\"><entities><data-source id=\"mariaDB-180637bab9c-385a8c5454123150\"><entity id=\"1\" name=\"users\" fq-name=\"gradido_community.users\" order=\"0\" color-bg=\"255,128,64\" x=\"331\" y=\"192\"><path name=\"gradido_community\"/></entity><entity id=\"2\" name=\"user_setting\" fq-name=\"gradido_community.user_setting\" order=\"1\" x=\"322\" y=\"612\"><path name=\"gradido_community\"/></entity><entity id=\"3\" name=\"transactions\" fq-name=\"gradido_community.transactions\" order=\"3\" x=\"653\" y=\"28\"><path name=\"gradido_community\"/></entity><entity id=\"4\" name=\"transaction_links\" fq-name=\"gradido_community.transaction_links\" order=\"4\" x=\"1044\" y=\"36\"><path name=\"gradido_community\"/></entity><entity id=\"5\" name=\"migrations\" fq-name=\"gradido_community.migrations\" order=\"5\" x=\"27\" y=\"27\"><path name=\"gradido_community\"/></entity><entity id=\"6\" name=\"login_email_opt_in\" fq-name=\"gradido_community.login_email_opt_in\" order=\"6\" x=\"-70\" y=\"187\"><path name=\"gradido_community\"/></entity><entity id=\"7\" name=\"login_elopage_buys\" fq-name=\"gradido_community.login_elopage_buys\" order=\"7\" x=\"3\" y=\"464\"><path name=\"gradido_community\"/></entity><entity id=\"8\" name=\"PendingActivities\" fq-name=\"gradido_community.PendingActivities\" order=\"8\" x=\"656\" y=\"502\"><path name=\"gradido_community\"/></entity><entity id=\"9\" name=\"Contributions\" fq-name=\"gradido_community.Contributions\" order=\"2\" x=\"1025\" y=\"367\"><path name=\"gradido_community\"/></entity></data-source></entities><relations><relation name=\"PendingActivities_FK\" fq-name=\"gradido_community.PendingActivities.PendingActivities_FK\" type=\"fk\" pk-ref=\"1\" fk-ref=\"8\"><bend type=\"abs\" x=\"597\" y=\"511\"/></relation><relation name=\"PendingActivities_FK_2\" fq-name=\"gradido_community.PendingActivities.PendingActivities_FK_2\" type=\"fk\" pk-ref=\"1\" fk-ref=\"8\"/><relation name=\"transactions_FK\" fq-name=\"gradido_community.transactions.transactions_FK\" type=\"fk\" pk-ref=\"1\" fk-ref=\"3\"/><relation name=\"users_FK\" fq-name=\"gradido_community.users.users_FK\" type=\"fk\" pk-ref=\"1\" fk-ref=\"1\"><bend type=\"abs\" x=\"481\" y=\"566\"/><bend type=\"abs\" x=\"446\" y=\"566\"/></relation><relation name=\"user_setting_FK\" fq-name=\"gradido_community.user_setting.user_setting_FK\" type=\"fk\" pk-ref=\"1\" fk-ref=\"2\"/><relation name=\"login_email_opt_in_FK\" fq-name=\"gradido_community.login_email_opt_in.login_email_opt_in_FK\" type=\"fk\" pk-ref=\"1\" fk-ref=\"6\"/><relation name=\"transactions_FK_1\" fq-name=\"gradido_community.transactions.transactions_FK_1\" type=\"fk\" pk-ref=\"4\" fk-ref=\"3\"/><relation name=\"PendingActivities_FK_1\" fq-name=\"gradido_community.PendingActivities.PendingActivities_FK_1\" type=\"fk\" pk-ref=\"9\" fk-ref=\"8\"/><relation name=\"users_FK_1\" fq-name=\"gradido_community.users.users_FK_1\" type=\"fk\" pk-ref=\"9\" fk-ref=\"1\"/></relations></diagram>"
}
},
"attributes": {
"public_key": {
"transforms": {
"custom": "resultset.binary.representation"
}
}
}
}
}
}
},
"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
}
}
}

3
.gitignore vendored
View File

@ -1,5 +1,4 @@
/.dbeaver/*
.dbeaver/*
.dbeaver
.project
*.log
*.bak

View File

@ -1,18 +0,0 @@
<?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>

View File

@ -1963,6 +1963,189 @@ describe('AdminResolver', () => {
}),
)
})
it('returns an error if missing startDate', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
validFrom: null,
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError('Start-Date is not initialized. A Start-Date must be set!'),
],
}),
)
})
it('returns an error if missing endDate', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
validTo: null,
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('End-Date is not initialized. An End-Date must be set!')],
}),
)
})
it('returns an error if endDate is before startDate', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
validFrom: new Date('2022-06-18T00:00:00.001Z').toISOString(),
validTo: new Date('2022-06-18T00:00:00.000Z').toISOString(),
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(`The value of validFrom must before or equals the validTo!`),
],
}),
)
})
it('returns an error if name is an empty string', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
name: '',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('The name must be initialized!')],
}),
)
})
it('returns an error if name is shorter than 5 characters', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
name: '123',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(
`The value of 'name' with a length of 3 did not fulfill the requested bounderies min=5 and max=100`,
),
],
}),
)
})
it('returns an error if name is longer than 100 characters', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
name: '12345678901234567892123456789312345678941234567895123456789612345678971234567898123456789912345678901',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(
`The value of 'name' with a length of 101 did not fulfill the requested bounderies min=5 and max=100`,
),
],
}),
)
})
it('returns an error if memo is an empty string', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
memo: '',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('The memo must be initialized!')],
}),
)
})
it('returns an error if memo is shorter than 5 characters', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
memo: '123',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(
`The value of 'memo' with a length of 3 did not fulfill the requested bounderies min=5 and max=255`,
),
],
}),
)
})
it('returns an error if memo is longer than 255 characters', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
memo: '1234567890123456789212345678931234567894123456789512345678961234567897123456789812345678991234567890123456789012345678921234567893123456789412345678951234567896123456789712345678981234567899123456789012345678901234567892123456789312345678941234567895123456',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(
`The value of 'memo' with a length of 256 did not fulfill the requested bounderies min=5 and max=255`,
),
],
}),
)
})
it('returns an error if amount is not positive', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
amount: new Decimal(0),
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError('The amount=0 must be initialized with a positiv value!'),
],
}),
)
})
})
describe('listContributionLinks', () => {

View File

@ -57,6 +57,10 @@ export const FULL_CREATION_AVAILABLE = [
MAX_CREATION_AMOUNT,
MAX_CREATION_AMOUNT,
]
const CONTRIBUTIONLINK_NAME_MAX_CHARS = 100
const CONTRIBUTIONLINK_NAME_MIN_CHARS = 5
const CONTRIBUTIONLINK_MEMO_MAX_CHARS = 255
const CONTRIBUTIONLINK_MEMO_MIN_CHARS = 5
@Resolver()
export class AdminResolver {
@ -231,7 +235,6 @@ export class AdminResolver {
@Args() { email, amount, memo, creationDate }: AdminCreateContributionArgs,
@Ctx() context: Context,
): Promise<Decimal[]> {
logger.trace('adminCreateContribution...')
const user = await dbUser.findOne({ email }, { withDeleted: true })
if (!user) {
throw new Error(`Could not find user with email: ${email}`)
@ -572,6 +575,39 @@ export class AdminResolver {
maxPerCycle,
}: ContributionLinkArgs,
): Promise<ContributionLink> {
isStartEndDateValid(validFrom, validTo)
if (!name) {
logger.error(`The name must be initialized!`)
throw new Error(`The name must be initialized!`)
}
if (
name.length < CONTRIBUTIONLINK_NAME_MIN_CHARS ||
name.length > CONTRIBUTIONLINK_NAME_MAX_CHARS
) {
const msg = `The value of 'name' with a length of ${name.length} did not fulfill the requested bounderies min=${CONTRIBUTIONLINK_NAME_MIN_CHARS} and max=${CONTRIBUTIONLINK_NAME_MAX_CHARS}`
logger.error(`${msg}`)
throw new Error(`${msg}`)
}
if (!memo) {
logger.error(`The memo must be initialized!`)
throw new Error(`The memo must be initialized!`)
}
if (
memo.length < CONTRIBUTIONLINK_MEMO_MIN_CHARS ||
memo.length > CONTRIBUTIONLINK_MEMO_MAX_CHARS
) {
const msg = `The value of 'memo' with a length of ${memo.length} did not fulfill the requested bounderies min=${CONTRIBUTIONLINK_MEMO_MIN_CHARS} and max=${CONTRIBUTIONLINK_MEMO_MAX_CHARS}`
logger.error(`${msg}`)
throw new Error(`${msg}`)
}
if (!amount) {
logger.error(`The amount must be initialized!`)
throw new Error('The amount must be initialized!')
}
if (!new Decimal(amount).isPositive()) {
logger.error(`The amount=${amount} must be initialized with a positiv value!`)
throw new Error(`The amount=${amount} must be initialized with a positiv value!`)
}
const dbContributionLink = new DbContributionLink()
dbContributionLink.amount = amount
dbContributionLink.name = name
@ -584,6 +620,7 @@ export class AdminResolver {
dbContributionLink.maxAmountPerMonth = maxAmountPerMonth
dbContributionLink.maxPerCycle = maxPerCycle
await dbContributionLink.save()
logger.debug(`createContributionLink successful!`)
return new ContributionLink(dbContributionLink)
}
@ -613,6 +650,7 @@ export class AdminResolver {
throw new Error('Contribution Link not found to given id.')
}
await contributionLink.softRemove()
logger.debug(`deleteContributionLink successful!`)
const newContributionLink = await DbContributionLink.findOne({ id }, { withDeleted: true })
return newContributionLink ? newContributionLink.deletedAt : null
}
@ -647,6 +685,7 @@ export class AdminResolver {
dbContributionLink.maxAmountPerMonth = maxAmountPerMonth
dbContributionLink.maxPerCycle = maxPerCycle
await dbContributionLink.save()
logger.debug(`updateContributionLink successful!`)
return new ContributionLink(dbContributionLink)
}
}
@ -716,6 +755,27 @@ function updateCreations(creations: Decimal[], contribution: Contribution): Deci
return creations
}
const isStartEndDateValid = (
startDate: string | null | undefined,
endDate: string | null | undefined,
): void => {
if (!startDate) {
logger.error('Start-Date is not initialized. A Start-Date must be set!')
throw new Error('Start-Date is not initialized. A Start-Date must be set!')
}
if (!endDate) {
logger.error('End-Date is not initialized. An End-Date must be set!')
throw new Error('End-Date is not initialized. An End-Date must be set!')
}
// check if endDate is before startDate
if (new Date(endDate).getTime() - new Date(startDate).getTime() < 0) {
logger.error(`The value of validFrom must before or equals the validTo!`)
throw new Error(`The value of validFrom must before or equals the validTo!`)
}
}
const getCreationMonths = (): number[] => {
const now = new Date(Date.now())
return [

View File

@ -1,9 +1,18 @@
<template>
<div>
<b-carousel :interval="13000">
<b-carousel-slide img-src="/img/template/Foto_01_2400_small.jpg"></b-carousel-slide>
<b-carousel-slide img-src="/img/template/Foto_02_2400_small.jpg"></b-carousel-slide>
<b-carousel-slide img-src="/img/template/Foto_03_2400_small.jpg"></b-carousel-slide>
<b-carousel-slide img-src="/img/template/Foto_01_2400_small.jpg">
<div class="caption-first-text">{{ $t('auth.left.gratitude') }}</div>
<div class="caption-second-text">{{ $t('auth.left.oneGratitude') }}</div>
</b-carousel-slide>
<b-carousel-slide img-src="/img/template/Foto_02_2400_small.jpg">
<div class="caption-first-text">{{ $t('auth.left.dignity') }}</div>
<div class="caption-second-text">{{ $t('auth.left.oneDignity') }}</div>
</b-carousel-slide>
<b-carousel-slide img-src="/img/template/Foto_03_2400_small.jpg">
<div class="caption-first-text">{{ $t('auth.left.donation') }}</div>
<div class="caption-second-text">{{ $t('auth.left.oneDonation') }}</div>
</b-carousel-slide>
</b-carousel>
</div>
</template>
@ -15,6 +24,21 @@ export default {
</script>
<style>
.carousel-caption {
color: #fff;
top: 317px;
text-shadow: 2px 2px 8px #000000;
font-size: xx-large;
}
.caption-first-text {
font-size: 150%;
}
.caption-second-text {
font-size: 80%;
}
.carousel {
position: relative;
height: 110%;

View File

@ -13,9 +13,6 @@
<auth-carousel class="carousel" />
</div>
<div class="bg-txt-box position-relative d-none d-lg-block text-center align-self-center">
<div class="h0 text-white">{{ $t('auth.left.gratitude') }}</div>
<div class="h1 text-white">{{ $t('auth.left.newCurrency') }}</div>
<div class="h2 text-white">{{ $t('auth.left.oneAnotherNature') }}</div>
<b-link :href="`https://gradido.net/${$i18n.locale}`" target="_blank">
<b-button variant="gradido">
{{ $t('auth.left.learnMore') }}
@ -150,20 +147,10 @@ export default {
}
.bg-txt-box {
margin-top: 317px;
margin-top: 520px;
text-shadow: 2px 2px 8px #000000;
max-width: 733px;
}
.bg-txt-box > .h0 {
font-size: 4em;
text-shadow: -2px -2px -8px #e4a907;
}
.bg-txt-box .h1,
.bg-txt-box .h2 {
font-size: 1.5em;
text-shadow: -2px -2px -8px #e4a907;
}
.bg-img {
border-radius: 0% 50% 70% 0% / 50% 70% 70% 50%;

View File

@ -6,12 +6,16 @@
"advanced-calculation": "Vorausberechnung",
"auth": {
"left": {
"dignity": "Würde",
"donation": "Gabe",
"gratitude": "Dankbarkeit",
"hasAccount": "Du hast schon einen Account?",
"hereLogin": "Hier Anmelden",
"learnMore": "Erfahre mehr …",
"newCurrency": "Die neue Währung",
"oneAnotherNature": "FÜR EINANDER, FÜR ALLE, FÜR DIE NATUR"
"oneDignity": "Wir schenken einander und danken mit Gradido.",
"oneDonation": "Du bist ein Geschenk für die Gemeinschaft. 1000 Dank, weil du bei uns bist.",
"oneGratitude": "Die neue Währung. Für einander, für alle Menschen, für die Natur."
},
"navbar": {
"aboutGradido": "Über Gradido"

View File

@ -6,12 +6,16 @@
"advanced-calculation": "Advanced calculation",
"auth": {
"left": {
"dignity": "Dignity",
"donation": "Donation",
"gratitude": "Gratitude",
"hasAccount": "You already have an account?",
"hereLogin": "Log in here",
"learnMore": "Learn more …",
"newCurrency": "The new currency",
"oneAnotherNature": "FOR EACH OTHER, FOR ALL, FOR NATURE"
"oneDignity": "We gift to each other and give thanks with Gradido.",
"oneDonation": "You are a gift for the community. 1000 thanks because you are with us.",
"oneGratitude": "The new currency. For each other, for all people, for nature."
},
"navbar": {
"aboutGradido": "About Gradido"