mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into admin_user_search_optimization
This commit is contained in:
commit
488a113ae7
17
CHANGELOG.md
17
CHANGELOG.md
@ -4,8 +4,25 @@ All notable changes to this project will be documented in this file. Dates are d
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [1.6.4](https://github.com/gradido/gradido/compare/1.6.3...1.6.4)
|
||||
|
||||
- fix: Admin Email Confirmation Date and Time [`#1448`](https://github.com/gradido/gradido/pull/1448)
|
||||
- Fix: Do not log password or token to the console [`#1477`](https://github.com/gradido/gradido/pull/1477)
|
||||
- Fix: Elopage Hook Crash [`#1474`](https://github.com/gradido/gradido/pull/1474)
|
||||
- 538 unify all buttons [`#1455`](https://github.com/gradido/gradido/pull/1455)
|
||||
- 833 old error is shown for a second even if transaction is successful [`#1460`](https://github.com/gradido/gradido/pull/1460)
|
||||
- fix: Wrong Email Spelling in German [`#1446`](https://github.com/gradido/gradido/pull/1446)
|
||||
- fix: Redirect to Login after Register [`#1445`](https://github.com/gradido/gradido/pull/1445)
|
||||
- refactor: Split User Table Component in Admin Interface [`#1443`](https://github.com/gradido/gradido/pull/1443)
|
||||
- remove user table [`c6a469e`](https://github.com/gradido/gradido/commit/c6a469e08f16101c8fb78958eda69b163b815ed3)
|
||||
- open creations table [`9ef575d`](https://github.com/gradido/gradido/commit/9ef575d6b140a4c768e4330a18eaa3b04346b483)
|
||||
- User Search Table [`ae2d535`](https://github.com/gradido/gradido/commit/ae2d5355d62f525187dd1cdb1448aec63fb05d3f)
|
||||
|
||||
#### [1.6.3](https://github.com/gradido/gradido/compare/1.6.2...1.6.3)
|
||||
|
||||
> 9 February 2022
|
||||
|
||||
- v1.6.3 [`#1447`](https://github.com/gradido/gradido/pull/1447)
|
||||
- add .btn-outline-secondary in scss [`#1442`](https://github.com/gradido/gradido/pull/1442)
|
||||
- Profil settings and footer refactor [`#1440`](https://github.com/gradido/gradido/pull/1440)
|
||||
- profil settings header info refactor style [`cbaa016`](https://github.com/gradido/gradido/commit/cbaa0162b9366e5de722235aeb633908c59bb3e1)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"description": "Administraion Interface for Gradido",
|
||||
"main": "index.js",
|
||||
"author": "Moriz Wahl",
|
||||
"version": "1.6.3",
|
||||
"version": "1.6.4",
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="component-confirm-register-mail">
|
||||
<div class="shadow p-3 mb-5 bg-white rounded">
|
||||
<div v-if="checked">{{ $t('unregister_mail.text_true', { date: dateLastSend }) }}</div>
|
||||
<div v-if="checked">{{ $t('unregister_mail.text_true') }}</div>
|
||||
<div v-else>
|
||||
{{ $t('unregister_mail.text_false', { date: dateLastSend, mail: email }) }}
|
||||
|
||||
|
||||
@ -63,7 +63,11 @@
|
||||
<confirm-register-mail-formular
|
||||
:checked="row.item.emailChecked"
|
||||
:email="row.item.email"
|
||||
:dateLastSend="$d(new Date(), 'long')"
|
||||
:dateLastSend="
|
||||
row.item.emailConfirmationSend
|
||||
? $d(new Date(row.item.emailConfirmationSend), 'long')
|
||||
: ''
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
<template #show-transaction-list>
|
||||
|
||||
@ -17,6 +17,7 @@ export const searchUsers = gql`
|
||||
creation
|
||||
emailChecked
|
||||
hasElopage
|
||||
emailConfirmationSend
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,9 +54,9 @@ const dateTimeFormats = {
|
||||
},
|
||||
long: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
weekday: 'short',
|
||||
weekday: 'long',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
},
|
||||
@ -78,9 +78,9 @@ const dateTimeFormats = {
|
||||
},
|
||||
long: {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
weekday: 'short',
|
||||
weekday: 'long',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
},
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
"info": "Email bestätigen, wiederholt senden an:",
|
||||
"success": "Erfolgreiches Senden des Bestätigungs-Links an die E-Mail des Nutzers! ({email})",
|
||||
"text_false": " Die letzte Email wurde am {date} Uhr an das Mitglied ({mail}) gesendet.",
|
||||
"text_true": " Die Email wurde am {date} Uhr bestätigt."
|
||||
"text_true": " Die Email wurde bestätigt."
|
||||
},
|
||||
"user_search": "Nutzer-Suche"
|
||||
}
|
||||
|
||||
@ -76,8 +76,8 @@
|
||||
"error": "Error sending the confirmation link to the user: {message}",
|
||||
"info": "Confirm email, send repeatedly to:",
|
||||
"success": "Successfully send the confirmation link to the user's email! ({email})",
|
||||
"text_false": "The last email was sent to the member ({mail}) on {date} clock.",
|
||||
"text_true": "The email was confirmed on {date} clock."
|
||||
"text_false": "The last email was sent to the member ({mail}) on {date}.",
|
||||
"text_true": "The email was confirmed."
|
||||
},
|
||||
"user_search": "User search"
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gradido-backend",
|
||||
"version": "1.6.3",
|
||||
"version": "1.6.4",
|
||||
"description": "Gradido unified backend providing an API-Service for Gradido Transactions",
|
||||
"main": "src/index.ts",
|
||||
"repository": "https://github.com/gradido/gradido/backend",
|
||||
@ -18,6 +18,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/lodash.clonedeep": "^4.5.6",
|
||||
"apollo-log": "^1.1.0",
|
||||
"apollo-server-express": "^2.25.2",
|
||||
"apollo-server-testing": "^2.25.2",
|
||||
@ -29,6 +30,7 @@
|
||||
"graphql": "^15.5.1",
|
||||
"jest": "^27.2.4",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"module-alias": "^2.2.2",
|
||||
"moment": "^2.29.1",
|
||||
"mysql2": "^2.3.0",
|
||||
|
||||
@ -4,7 +4,7 @@ import dotenv from 'dotenv'
|
||||
dotenv.config()
|
||||
|
||||
const constants = {
|
||||
DB_VERSION: '0020-rename_and_clean_state_users',
|
||||
DB_VERSION: '0021-elopagebuys_fields_nullable',
|
||||
}
|
||||
|
||||
const server = {
|
||||
|
||||
@ -22,6 +22,9 @@ export class UserAdmin {
|
||||
|
||||
@Field(() => Boolean)
|
||||
hasElopage: boolean
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
emailConfirmationSend?: string
|
||||
}
|
||||
|
||||
@ObjectType()
|
||||
|
||||
@ -22,7 +22,10 @@ import { BalanceRepository } from '../../typeorm/repository/Balance'
|
||||
import { calculateDecay } from '../../util/decay'
|
||||
import { AdminPendingCreation } from '@entity/AdminPendingCreation'
|
||||
import { hasElopageBuys } from '../../util/hasElopageBuys'
|
||||
import { User as dbUser } from '@entity/User'
|
||||
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
|
||||
|
||||
// const EMAIL_OPT_IN_REGISTER = 1
|
||||
// const EMAIL_OPT_UNKNOWN = 3 // elopage?
|
||||
|
||||
@Resolver()
|
||||
export class AdminResolver {
|
||||
@ -57,6 +60,26 @@ export class AdminResolver {
|
||||
adminUser.creation = await getUserCreations(user.id)
|
||||
adminUser.emailChecked = user.emailChecked
|
||||
adminUser.hasElopage = await hasElopageBuys(user.email)
|
||||
if (!user.emailChecked) {
|
||||
const emailOptIn = await LoginEmailOptIn.findOne(
|
||||
{
|
||||
userId: user.id,
|
||||
},
|
||||
{
|
||||
order: {
|
||||
updatedAt: 'DESC',
|
||||
createdAt: 'DESC',
|
||||
},
|
||||
},
|
||||
)
|
||||
if (emailOptIn) {
|
||||
if (emailOptIn.updatedAt) {
|
||||
adminUser.emailConfirmationSend = emailOptIn.updatedAt.toISOString()
|
||||
} else {
|
||||
adminUser.emailConfirmationSend = emailOptIn.createdAt.toISOString()
|
||||
}
|
||||
}
|
||||
}
|
||||
return adminUser
|
||||
}),
|
||||
)
|
||||
@ -73,8 +96,7 @@ export class AdminResolver {
|
||||
): Promise<number[]> {
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const user = await userRepository.findByEmail(email)
|
||||
const isActivated = await hasActivatedEmail(user.email)
|
||||
if (!isActivated) {
|
||||
if (!user.emailChecked) {
|
||||
throw new Error('Creation could not be saved, Email is not activated')
|
||||
}
|
||||
const creations = await getUserCreations(user.id)
|
||||
@ -386,8 +408,3 @@ function isCreationValid(creations: number[], amount: number, creationDate: Date
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
async function hasActivatedEmail(email: string): Promise<boolean> {
|
||||
const user = await dbUser.findOne({ email })
|
||||
return user ? user.emailChecked : false
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import { ApolloLogPlugin } from 'apollo-log'
|
||||
import { ApolloLogPlugin, LogMutateData } from 'apollo-log'
|
||||
import cloneDeep from 'lodash.clonedeep'
|
||||
|
||||
const plugins = [
|
||||
{
|
||||
@ -21,7 +22,22 @@ const plugins = [
|
||||
}
|
||||
},
|
||||
},
|
||||
ApolloLogPlugin(),
|
||||
ApolloLogPlugin({
|
||||
mutate: (data: LogMutateData) => {
|
||||
// We need to deep clone the object in order to not modify the actual request
|
||||
const dataCopy = cloneDeep(data)
|
||||
|
||||
// mask password if part of the query
|
||||
if (dataCopy.context.request.variables && dataCopy.context.request.variables.password) {
|
||||
dataCopy.context.request.variables.password = '***'
|
||||
}
|
||||
|
||||
// mask token at all times
|
||||
dataCopy.context.context.token = '***'
|
||||
|
||||
return dataCopy
|
||||
},
|
||||
}),
|
||||
]
|
||||
|
||||
export default plugins
|
||||
|
||||
@ -53,12 +53,13 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
membership,
|
||||
} = req.body
|
||||
|
||||
loginElopageBuy.affiliateProgramId = parseInt(product.affiliate_program_id)
|
||||
loginElopageBuy.publisherId = parseInt(publisher.id)
|
||||
loginElopageBuy.orderId = parseInt(order_id)
|
||||
loginElopageBuy.productId = parseInt(product_id)
|
||||
loginElopageBuy.affiliateProgramId = parseInt(product.affiliate_program_id) || null
|
||||
loginElopageBuy.publisherId = parseInt(publisher.id) || null
|
||||
loginElopageBuy.orderId = parseInt(order_id) || null
|
||||
loginElopageBuy.productId = parseInt(product_id) || null
|
||||
// TODO: WHAT THE ACTUAL FUK? Please save this as float in the future directly in the database
|
||||
loginElopageBuy.productPrice = Math.trunc(parseFloat(product.price) * 100)
|
||||
const productPrice = parseFloat(product.price)
|
||||
loginElopageBuy.productPrice = productPrice ? Math.trunc(productPrice * 100) : 0
|
||||
loginElopageBuy.payerEmail = payer.email
|
||||
loginElopageBuy.publisherEmail = publisher.email
|
||||
// eslint-disable-next-line camelcase
|
||||
@ -66,7 +67,7 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
loginElopageBuy.successDate = new Date(success_date)
|
||||
loginElopageBuy.event = event
|
||||
// TODO this was never set on login_server - its unclear if this is the correct value
|
||||
loginElopageBuy.elopageUserId = parseInt(membership.id)
|
||||
loginElopageBuy.elopageUserId = parseInt(membership.id) || null
|
||||
|
||||
const firstName = payer.first_name
|
||||
const lastName = payer.last_name
|
||||
@ -79,7 +80,13 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
}
|
||||
|
||||
// Save the hook data
|
||||
await LoginElopageBuys.save(loginElopageBuy)
|
||||
try {
|
||||
await LoginElopageBuys.save(loginElopageBuy)
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Error saving LoginElopageBuy', error)
|
||||
return
|
||||
}
|
||||
|
||||
// create user for certain products
|
||||
/*
|
||||
@ -90,7 +97,10 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
Business-Mitgliedschaft, 43960
|
||||
Förderbeitrag: 49106
|
||||
*/
|
||||
if ([36001, 43741, 43870, 43944, 43960, 49106].includes(loginElopageBuy.productId)) {
|
||||
if (
|
||||
loginElopageBuy.productId &&
|
||||
[36001, 43741, 43870, 43944, 43960, 49106].includes(loginElopageBuy.productId)
|
||||
) {
|
||||
const email = loginElopageBuy.payerEmail
|
||||
|
||||
const VALIDATE_EMAIL = /^[a-zA-Z0-9.!#$%&?*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
|
||||
@ -123,7 +133,7 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
email,
|
||||
firstName,
|
||||
lastName,
|
||||
publisherId: loginElopageBuy.publisherId,
|
||||
publisherId: loginElopageBuy.publisherId || 0, // This seemed to be the default value if not set
|
||||
})
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
|
||||
@ -913,6 +913,18 @@
|
||||
"@types/koa-compose" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/lodash.clonedeep@^4.5.6":
|
||||
version "4.5.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.6.tgz#3b6c40a0affe0799a2ce823b440a6cf33571d32b"
|
||||
integrity sha512-cE1jYr2dEg1wBImvXlNtp0xDoS79rfEdGozQVgliDZj1uERH4k+rmEMTudP9b4VQ8O6nRb5gPqft0QzEQGMQgA==
|
||||
dependencies:
|
||||
"@types/lodash" "*"
|
||||
|
||||
"@types/lodash@*":
|
||||
version "4.14.178"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8"
|
||||
integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==
|
||||
|
||||
"@types/long@^4.0.0":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
|
||||
|
||||
@ -5,8 +5,8 @@ export class LoginElopageBuys extends BaseEntity {
|
||||
@PrimaryGeneratedColumn('increment', { unsigned: true })
|
||||
id: number
|
||||
|
||||
@Column({ name: 'elopage_user_id', nullable: false })
|
||||
elopageUserId: number
|
||||
@Column({ type: 'int', width: 11, name: 'elopage_user_id', nullable: true, default: null })
|
||||
elopageUserId: number | null
|
||||
|
||||
@Column({ name: 'affiliate_program_id', nullable: false })
|
||||
affiliateProgramId: number
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
|
||||
|
||||
@Entity('login_elopage_buys')
|
||||
export class LoginElopageBuys extends BaseEntity {
|
||||
@PrimaryGeneratedColumn('increment', { unsigned: true })
|
||||
id: number
|
||||
|
||||
@Column({ type: 'int', width: 11, name: 'elopage_user_id', nullable: true, default: null })
|
||||
elopageUserId: number | null
|
||||
|
||||
@Column({ type: 'int', width: 11, name: 'affiliate_program_id', nullable: true, default: null })
|
||||
affiliateProgramId: number | null
|
||||
|
||||
@Column({ type: 'int', width: 11, name: 'publisher_id', nullable: true, default: null })
|
||||
publisherId: number | null
|
||||
|
||||
@Column({ type: 'int', width: 11, name: 'order_id', nullable: true, default: null })
|
||||
orderId: number | null
|
||||
|
||||
@Column({ type: 'int', width: 11, name: 'product_id', nullable: true, default: null })
|
||||
productId: number | null
|
||||
|
||||
@Column({ name: 'product_price', nullable: false })
|
||||
productPrice: number
|
||||
|
||||
@Column({
|
||||
name: 'payer_email',
|
||||
length: 255,
|
||||
nullable: false,
|
||||
charset: 'utf8',
|
||||
collation: 'utf8_bin',
|
||||
})
|
||||
payerEmail: string
|
||||
|
||||
@Column({
|
||||
name: 'publisher_email',
|
||||
length: 255,
|
||||
nullable: false,
|
||||
charset: 'utf8',
|
||||
collation: 'utf8_bin',
|
||||
})
|
||||
publisherEmail: string
|
||||
|
||||
@Column({ nullable: false })
|
||||
payed: boolean
|
||||
|
||||
@Column({ name: 'success_date', nullable: false })
|
||||
successDate: Date
|
||||
|
||||
@Column({ length: 255, nullable: false })
|
||||
event: string
|
||||
}
|
||||
@ -1 +1 @@
|
||||
export { LoginElopageBuys } from './0003-login_server_tables/LoginElopageBuys'
|
||||
export { LoginElopageBuys } from './0021-elopagebuys_fields_nullable/LoginElopageBuys'
|
||||
|
||||
25
database/migrations/0021-elopagebuys_fields_nullable.ts
Normal file
25
database/migrations/0021-elopagebuys_fields_nullable.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/* MIGRATION TO ALLOW NULL FIELDS ON ELOPAGEBUYS
|
||||
*
|
||||
* This migration allows null on `affiliate_program_id`,
|
||||
* `publisher_id`, `order_id`. `product_id`.
|
||||
*/
|
||||
|
||||
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn(
|
||||
'ALTER TABLE `login_elopage_buys` MODIFY COLUMN `affiliate_program_id` int(11) DEFAULT NULL;',
|
||||
)
|
||||
await queryFn(
|
||||
'ALTER TABLE `login_elopage_buys` MODIFY COLUMN `publisher_id` int(11) DEFAULT NULL;',
|
||||
)
|
||||
await queryFn('ALTER TABLE `login_elopage_buys` MODIFY COLUMN `order_id` int(11) DEFAULT NULL;')
|
||||
await queryFn('ALTER TABLE `login_elopage_buys` MODIFY COLUMN `product_id` int(11) DEFAULT NULL;')
|
||||
}
|
||||
|
||||
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn(
|
||||
'ALTER TABLE `login_elopage_buys` MODIFY COLUMN `affiliate_program_id` int(11) NOT NULL;',
|
||||
)
|
||||
await queryFn('ALTER TABLE `login_elopage_buys` MODIFY COLUMN `publisher_id` int(11) NOT NULL;')
|
||||
await queryFn('ALTER TABLE `login_elopage_buys` MODIFY COLUMN `order_id` int(11) NOT NULL;')
|
||||
await queryFn('ALTER TABLE `login_elopage_buys` MODIFY COLUMN `product_id` int(11) NOT NULL;')
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gradido-database",
|
||||
"version": "1.6.3",
|
||||
"version": "1.6.4",
|
||||
"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.6.3",
|
||||
"version": "1.6.4",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node run/server.js",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gradido",
|
||||
"version": "1.6.3",
|
||||
"version": "1.6.4",
|
||||
"description": "Gradido",
|
||||
"main": "index.js",
|
||||
"repository": "git@github.com:gradido/gradido.git",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user