mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-12 15:25:49 +00:00
Merge branch 'master' into refactor_remove_community_server
This commit is contained in:
commit
712a92b8ba
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -1,4 +1 @@
|
||||
[submodule "gn"]
|
||||
path = gn
|
||||
url = https://github.com/gradido/gn.git
|
||||
branch = master
|
||||
|
||||
|
||||
3
admin/.gitignore
vendored
3
admin/.gitignore
vendored
@ -2,7 +2,8 @@ node_modules/
|
||||
dist/
|
||||
.cache/
|
||||
|
||||
.env
|
||||
/.env
|
||||
/.env.bak
|
||||
|
||||
# coverage folder
|
||||
coverage/
|
||||
|
||||
1
backend/.gitignore
vendored
1
backend/.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
/node_modules/
|
||||
/.env
|
||||
/.env.bak
|
||||
/build/
|
||||
package-json.lock
|
||||
coverage
|
||||
|
||||
@ -7,5 +7,4 @@ export const INALIENABLE_RIGHTS = [
|
||||
RIGHTS.CREATE_USER,
|
||||
RIGHTS.SEND_RESET_PASSWORD_EMAIL,
|
||||
RIGHTS.SET_PASSWORD,
|
||||
RIGHTS.CHECK_USERNAME,
|
||||
]
|
||||
|
||||
@ -17,7 +17,6 @@ export enum RIGHTS {
|
||||
SEND_RESET_PASSWORD_EMAIL = 'SEND_RESET_PASSWORD_EMAIL',
|
||||
SET_PASSWORD = 'SET_PASSWORD',
|
||||
UPDATE_USER_INFOS = 'UPDATE_USER_INFOS',
|
||||
CHECK_USERNAME = 'CHECK_USERNAME',
|
||||
HAS_ELOPAGE = 'HAS_ELOPAGE',
|
||||
// Admin
|
||||
SEARCH_USERS = 'SEARCH_USERS',
|
||||
|
||||
@ -4,7 +4,7 @@ import dotenv from 'dotenv'
|
||||
dotenv.config()
|
||||
|
||||
const constants = {
|
||||
DB_VERSION: '0019-replace_login_user_id_with_state_user_id',
|
||||
DB_VERSION: '0020-rename_and_clean_state_users',
|
||||
}
|
||||
|
||||
const server = {
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
import { ArgsType, Field } from 'type-graphql'
|
||||
|
||||
@ArgsType()
|
||||
export default class CheckUsernameArgs {
|
||||
@Field(() => String)
|
||||
username: string
|
||||
}
|
||||
@ -8,12 +8,6 @@ export default class UpdateUserInfosArgs {
|
||||
@Field({ nullable: true })
|
||||
lastName?: string
|
||||
|
||||
@Field({ nullable: true })
|
||||
description?: string
|
||||
|
||||
@Field({ nullable: true })
|
||||
username?: string
|
||||
|
||||
@Field({ nullable: true })
|
||||
language?: string
|
||||
|
||||
|
||||
@ -5,10 +5,10 @@ import { AuthChecker } from 'type-graphql'
|
||||
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 '@dbTools/typeorm'
|
||||
import { UserRepository } from '../../typeorm/repository/User'
|
||||
import { INALIENABLE_RIGHTS } from '../../auth/INALIENABLE_RIGHTS'
|
||||
import { ServerUser } from '@entity/ServerUser'
|
||||
|
||||
const isAuthorized: AuthChecker<any> = async ({ context }, rights) => {
|
||||
context.role = ROLE_UNAUTHORIZED // unauthorized user
|
||||
@ -38,8 +38,7 @@ const isAuthorized: AuthChecker<any> = async ({ context }, rights) => {
|
||||
// TODO this implementation is bullshit - two database queries cause our user identifiers are not aligned and vary between email, id and pubKey
|
||||
const userRepository = await getCustomRepository(UserRepository)
|
||||
const user = await userRepository.findByPubkeyHex(context.pubKey)
|
||||
const serverUserRepository = await getCustomRepository(ServerUserRepository)
|
||||
const countServerUsers = await serverUserRepository.count({ email: user.email })
|
||||
const countServerUsers = await ServerUser.count({ email: user.email })
|
||||
context.role = countServerUsers > 0 ? ROLE_ADMIN : ROLE_USER
|
||||
|
||||
context.setHeaders.push({ key: 'token', value: encode(decoded.pubKey) })
|
||||
|
||||
@ -16,8 +16,6 @@ export class User {
|
||||
this.email = json.email
|
||||
this.firstName = json.first_name
|
||||
this.lastName = json.last_name
|
||||
this.username = json.username
|
||||
this.description = json.description
|
||||
this.pubkey = json.public_hex
|
||||
this.language = json.language
|
||||
this.publisherId = json.publisher_id
|
||||
@ -37,12 +35,6 @@ export class User {
|
||||
@Field(() => String)
|
||||
lastName: string
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
username?: string
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
description?: string
|
||||
|
||||
@Field(() => String)
|
||||
pubkey: string
|
||||
/*
|
||||
@ -55,9 +47,6 @@ export class User {
|
||||
|
||||
@Field(() =>>> Boolean)
|
||||
emailChecked: boolean
|
||||
|
||||
@Field(() => Boolean)
|
||||
passphraseShown: boolean
|
||||
*/
|
||||
|
||||
@Field(() => String)
|
||||
@ -68,10 +57,6 @@ export class User {
|
||||
disabled: boolean
|
||||
*/
|
||||
|
||||
/* I suggest to have a group as type here
|
||||
@Field(() => ID)
|
||||
groupId: number
|
||||
*/
|
||||
// what is publisherId?
|
||||
@Field(() => Int, { nullable: true })
|
||||
publisherId?: number
|
||||
|
||||
@ -9,7 +9,6 @@ import { CreatePendingCreations } from '../model/CreatePendingCreations'
|
||||
import { UpdatePendingCreation } from '../model/UpdatePendingCreation'
|
||||
import { RIGHTS } from '../../auth/RIGHTS'
|
||||
import { TransactionRepository } from '../../typeorm/repository/Transaction'
|
||||
import { TransactionCreationRepository } from '../../typeorm/repository/TransactionCreation'
|
||||
import { UserRepository } from '../../typeorm/repository/User'
|
||||
import CreatePendingCreationArgs from '../arg/CreatePendingCreationArgs'
|
||||
import UpdatePendingCreationArgs from '../arg/UpdatePendingCreationArgs'
|
||||
@ -198,13 +197,12 @@ export class AdminResolver {
|
||||
transaction = await transactionRepository.save(transaction)
|
||||
if (!transaction) throw new Error('Could not create transaction')
|
||||
|
||||
const transactionCreationRepository = getCustomRepository(TransactionCreationRepository)
|
||||
let transactionCreation = new TransactionCreation()
|
||||
transactionCreation.transactionId = transaction.id
|
||||
transactionCreation.userId = pendingCreation.userId
|
||||
transactionCreation.amount = parseInt(pendingCreation.amount.toString())
|
||||
transactionCreation.targetDate = pendingCreation.date
|
||||
transactionCreation = await transactionCreationRepository.save(transactionCreation)
|
||||
transactionCreation = await TransactionCreation.save(transactionCreation)
|
||||
if (!transactionCreation) throw new Error('Could not create transactionCreation')
|
||||
|
||||
const userTransactionRepository = getCustomRepository(UserTransactionRepository)
|
||||
@ -256,9 +254,7 @@ async function getUserCreations(id: number): Promise<number[]> {
|
||||
const lastMonthNumber = moment().subtract(1, 'month').format('M')
|
||||
const currentMonthNumber = moment().format('M')
|
||||
|
||||
const transactionCreationRepository = getCustomRepository(TransactionCreationRepository)
|
||||
const createdAmountsQuery = await transactionCreationRepository
|
||||
.createQueryBuilder('transaction_creations')
|
||||
const createdAmountsQuery = await TransactionCreation.createQueryBuilder('transaction_creations')
|
||||
.select('MONTH(transaction_creations.target_date)', 'target_month')
|
||||
.addSelect('SUM(transaction_creations.amount)', 'sum')
|
||||
.where('transaction_creations.state_user_id = :id', { id })
|
||||
|
||||
@ -8,7 +8,6 @@ import CONFIG from '../../config'
|
||||
import { User } from '../model/User'
|
||||
import { User as DbUser } from '@entity/User'
|
||||
import { encode } from '../../auth/JWT'
|
||||
import CheckUsernameArgs from '../arg/CheckUsernameArgs'
|
||||
import CreateUserArgs from '../arg/CreateUserArgs'
|
||||
import UnsecureLoginArgs from '../arg/UnsecureLoginArgs'
|
||||
import UpdateUserInfosArgs from '../arg/UpdateUserInfosArgs'
|
||||
@ -19,11 +18,11 @@ import { UserRepository } from '../../typeorm/repository/User'
|
||||
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
|
||||
import { sendResetPasswordEmail } from '../../mailer/sendResetPasswordEmail'
|
||||
import { sendAccountActivationEmail } from '../../mailer/sendAccountActivationEmail'
|
||||
import { LoginElopageBuysRepository } from '../../typeorm/repository/LoginElopageBuys'
|
||||
import { klicktippSignIn } from '../../apis/KlicktippController'
|
||||
import { RIGHTS } from '../../auth/RIGHTS'
|
||||
import { ServerUserRepository } from '../../typeorm/repository/ServerUser'
|
||||
import { ROLE_ADMIN } from '../../auth/ROLES'
|
||||
import { LoginElopageBuys } from '@entity/LoginElopageBuys'
|
||||
import { ServerUser } from '@entity/ServerUser'
|
||||
|
||||
const EMAIL_OPT_IN_RESET_PASSWORD = 2
|
||||
const EMAIL_OPT_IN_REGISTER = 1
|
||||
@ -224,8 +223,6 @@ export class UserResolver {
|
||||
user.email = userEntity.email
|
||||
user.firstName = userEntity.firstName
|
||||
user.lastName = userEntity.lastName
|
||||
user.username = userEntity.username
|
||||
user.description = userEntity.description
|
||||
user.pubkey = userEntity.pubKey.toString('hex')
|
||||
user.language = userEntity.language
|
||||
|
||||
@ -278,8 +275,6 @@ export class UserResolver {
|
||||
user.email = email
|
||||
user.firstName = dbUser.firstName
|
||||
user.lastName = dbUser.lastName
|
||||
user.username = dbUser.username
|
||||
user.description = dbUser.description
|
||||
user.pubkey = dbUser.pubKey.toString('hex')
|
||||
user.language = dbUser.language
|
||||
|
||||
@ -303,8 +298,7 @@ export class UserResolver {
|
||||
user.coinanimation = coinanimation
|
||||
|
||||
// context.role is not set to the actual role yet on login
|
||||
const serverUserRepository = await getCustomRepository(ServerUserRepository)
|
||||
const countServerUsers = await serverUserRepository.count({ email: user.email })
|
||||
const countServerUsers = await ServerUser.count({ email: user.email })
|
||||
user.isAdmin = countServerUsers > 0
|
||||
|
||||
context.setHeaders.push({
|
||||
@ -339,13 +333,6 @@ export class UserResolver {
|
||||
language = DEFAULT_LANGUAGE
|
||||
}
|
||||
|
||||
// Validate username
|
||||
// TODO: never true
|
||||
const username = ''
|
||||
if (username.length > 3 && !this.checkUsername({ username })) {
|
||||
throw new Error('Username already in use')
|
||||
}
|
||||
|
||||
// Validate email unique
|
||||
// TODO: i can register an email in upper/lower case twice
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
@ -361,13 +348,10 @@ export class UserResolver {
|
||||
// const encryptedPrivkey = SecretKeyCryptographyEncrypt(keyPair[1], passwordHash[1])
|
||||
const emailHash = getEmailHash(email)
|
||||
|
||||
// Table: state_users
|
||||
const dbUser = new DbUser()
|
||||
dbUser.email = email
|
||||
dbUser.firstName = firstName
|
||||
dbUser.lastName = lastName
|
||||
dbUser.username = username
|
||||
dbUser.description = ''
|
||||
dbUser.emailHash = emailHash
|
||||
dbUser.language = language
|
||||
dbUser.publisherId = publisherId
|
||||
@ -591,8 +575,6 @@ export class UserResolver {
|
||||
{
|
||||
firstName,
|
||||
lastName,
|
||||
description,
|
||||
username,
|
||||
language,
|
||||
publisherId,
|
||||
password,
|
||||
@ -604,17 +586,6 @@ export class UserResolver {
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const userEntity = await userRepository.findByPubkeyHex(context.pubKey)
|
||||
|
||||
if (username) {
|
||||
throw new Error('change username currently not supported!')
|
||||
// TODO: this error was thrown on login_server whenever you tried to change the username
|
||||
// to anything except "" which is an exception to the rules below. Those were defined
|
||||
// aswell, even tho never used.
|
||||
// ^[a-zA-Z][a-zA-Z0-9_-]*$
|
||||
// username must start with [a-z] or [A-Z] and than can contain also [0-9], - and _
|
||||
// username already used
|
||||
// userEntity.username = username
|
||||
}
|
||||
|
||||
if (firstName) {
|
||||
userEntity.firstName = firstName
|
||||
}
|
||||
@ -623,10 +594,6 @@ export class UserResolver {
|
||||
userEntity.lastName = lastName
|
||||
}
|
||||
|
||||
if (description) {
|
||||
userEntity.description = description
|
||||
}
|
||||
|
||||
if (language) {
|
||||
if (!isLanguage(language)) {
|
||||
throw new Error(`"${language}" isn't a valid language`)
|
||||
@ -685,30 +652,6 @@ export class UserResolver {
|
||||
return true
|
||||
}
|
||||
|
||||
@Authorized([RIGHTS.CHECK_USERNAME])
|
||||
@Query(() => Boolean)
|
||||
async checkUsername(@Args() { username }: CheckUsernameArgs): Promise<boolean> {
|
||||
// Username empty?
|
||||
if (username === '') {
|
||||
throw new Error('Username must be set.')
|
||||
}
|
||||
|
||||
// Do we fullfil the minimum character length?
|
||||
const MIN_CHARACTERS_USERNAME = 2
|
||||
if (username.length < MIN_CHARACTERS_USERNAME) {
|
||||
throw new Error(`Username must be at minimum ${MIN_CHARACTERS_USERNAME} characters long.`)
|
||||
}
|
||||
|
||||
const usersFound = await DbUser.count({ username })
|
||||
|
||||
// Username already present?
|
||||
if (usersFound !== 0) {
|
||||
throw new Error(`Username "${username}" already taken.`)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@Authorized([RIGHTS.HAS_ELOPAGE])
|
||||
@Query(() => Boolean)
|
||||
async hasElopage(@Ctx() context: any): Promise<boolean> {
|
||||
@ -718,8 +661,7 @@ export class UserResolver {
|
||||
return false
|
||||
}
|
||||
|
||||
const loginElopageBuysRepository = getCustomRepository(LoginElopageBuysRepository)
|
||||
const elopageBuyCount = await loginElopageBuysRepository.count({ payerEmail: userEntity.email })
|
||||
const elopageBuyCount = await LoginElopageBuys.count({ payerEmail: userEntity.email })
|
||||
return elopageBuyCount > 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
import { EntityRepository, Repository } from '@dbTools/typeorm'
|
||||
import { LoginElopageBuys } from '@entity/LoginElopageBuys'
|
||||
|
||||
@EntityRepository(LoginElopageBuys)
|
||||
export class LoginElopageBuysRepository extends Repository<LoginElopageBuys> {}
|
||||
@ -1,5 +0,0 @@
|
||||
import { EntityRepository, Repository } from '@dbTools/typeorm'
|
||||
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
|
||||
|
||||
@EntityRepository(LoginEmailOptIn)
|
||||
export class LoginEmailOptInRepository extends Repository<LoginEmailOptIn> {}
|
||||
@ -1,5 +0,0 @@
|
||||
import { EntityRepository, Repository } from '@dbTools/typeorm'
|
||||
import { ServerUser } from '@entity/ServerUser'
|
||||
|
||||
@EntityRepository(ServerUser)
|
||||
export class ServerUserRepository extends Repository<ServerUser> {}
|
||||
@ -1,5 +0,0 @@
|
||||
import { EntityRepository, Repository } from '@dbTools/typeorm'
|
||||
import { TransactionCreation } from '@entity/TransactionCreation'
|
||||
|
||||
@EntityRepository(TransactionCreation)
|
||||
export class TransactionCreationRepository extends Repository<TransactionCreation> {}
|
||||
@ -28,16 +28,13 @@
|
||||
*/
|
||||
|
||||
import { LoginElopageBuys } from '@entity/LoginElopageBuys'
|
||||
import { getCustomRepository } from '@dbTools/typeorm'
|
||||
import { UserResolver } from '../graphql/resolver/UserResolver'
|
||||
import { LoginElopageBuysRepository } from '../typeorm/repository/LoginElopageBuys'
|
||||
import { User as dbUser } from '@entity/User'
|
||||
|
||||
export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Elopage Hook received', req.body)
|
||||
res.status(200).end() // Responding is important
|
||||
const loginElopageBuyRepository = await getCustomRepository(LoginElopageBuysRepository)
|
||||
const loginElopageBuy = new LoginElopageBuys()
|
||||
|
||||
const {
|
||||
@ -82,7 +79,7 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
}
|
||||
|
||||
// Save the hook data
|
||||
await loginElopageBuyRepository.save(loginElopageBuy)
|
||||
await LoginElopageBuys.save(loginElopageBuy)
|
||||
|
||||
// create user for certain products
|
||||
/*
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
worker_count = 2
|
||||
io_worker_count = 1
|
||||
data_root_folder = /opt/instance/.gradido
|
||||
hedera_mirror_endpoint = hcs.testnet.mirrornode.hedera.com:5600
|
||||
sibling_node_file = /opt/instance/.gradido/sibling_nodes.txt
|
||||
#group_requests_endpoint = 0.0.0.0:13701
|
||||
#record_requests_endpoint = 0.0.0.0:13702
|
||||
#manage_network_requests_endpoint = 0.0.0.0:13703
|
||||
grpc_endpoint = 0.0.0.0:13701
|
||||
json_rpc_port = 13702
|
||||
|
||||
|
||||
# larger value, larger batch, less concurrency
|
||||
blockchain_append_batch_size = 1000
|
||||
#blochchain_init_batch_size = 1000
|
||||
#block_record_outbound_batch_size = 100
|
||||
general_batch_size = 1000
|
||||
group_register_topic_id = 0.0.79574
|
||||
|
||||
topic_reset_allowed = 1
|
||||
3
database/.gitignore
vendored
3
database/.gitignore
vendored
@ -8,7 +8,8 @@ yarn-error.log*
|
||||
test/unit/coverage
|
||||
|
||||
package-lock.json
|
||||
.env
|
||||
/.env
|
||||
/.env.bak
|
||||
.env.development.local
|
||||
.env.production.local
|
||||
|
||||
|
||||
68
database/entity/0020-rename_and_clean_state_users/User.ts
Normal file
68
database/entity/0020-rename_and_clean_state_users/User.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm'
|
||||
import { UserSetting } from '../UserSetting'
|
||||
|
||||
@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
|
||||
|
||||
@Column({ type: 'bool', default: false })
|
||||
disabled: boolean
|
||||
|
||||
@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: 'publisher_id', default: 0 })
|
||||
publisherId: number
|
||||
|
||||
@Column({
|
||||
type: 'text',
|
||||
name: 'passphrase',
|
||||
collation: 'utf8mb4_unicode_ci',
|
||||
nullable: true,
|
||||
default: null,
|
||||
})
|
||||
passphrase: string
|
||||
|
||||
@OneToMany(() => UserSetting, (userSetting) => userSetting.user)
|
||||
settings: UserSetting[]
|
||||
}
|
||||
@ -1 +1 @@
|
||||
export { User } from './0019-replace_login_user_id_with_state_user_id/User'
|
||||
export { User } from './0020-rename_and_clean_state_users/User'
|
||||
|
||||
39
database/migrations/0020-rename_and_clean_state_users.ts
Normal file
39
database/migrations/0020-rename_and_clean_state_users.ts
Normal file
@ -0,0 +1,39 @@
|
||||
/* MIGRATION TO CLEAN UP AND RENAME STATE_USERS
|
||||
*
|
||||
* This migration renames 'state_users` to `users`
|
||||
* and removes columns with no meaningful value
|
||||
*/
|
||||
|
||||
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
// rename `state_users` table to `users`
|
||||
await queryFn('RENAME TABLE `state_users` TO `users`;')
|
||||
|
||||
// Remove the column `index_id` from `users`, it only contains 0 as value
|
||||
await queryFn('ALTER TABLE `users` DROP COLUMN `index_id`;')
|
||||
|
||||
// Remove the column `username` from `users`, it contains only '' or NULL
|
||||
await queryFn('ALTER TABLE `users` DROP COLUMN `username`;')
|
||||
|
||||
// Remove the column `description` from `users`, it contains only '' or NULL
|
||||
await queryFn('ALTER TABLE `users` DROP COLUMN `description`;')
|
||||
|
||||
// Remove the column `passphrase_shown` from `users`, it contains only 0 as value
|
||||
await queryFn('ALTER TABLE `users` DROP COLUMN `passphrase_shown`;')
|
||||
}
|
||||
|
||||
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn(
|
||||
'ALTER TABLE `users` ADD COLUMN `passphrase_shown` tinyint(4) NOT NULL DEFAULT 0 AFTER `email_checked`;',
|
||||
)
|
||||
await queryFn(
|
||||
"ALTER TABLE `users` ADD COLUMN `description` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT '' AFTER `disabled`;",
|
||||
)
|
||||
await queryFn(
|
||||
'ALTER TABLE `users` ADD COLUMN `username` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL AFTER `last_name`;',
|
||||
)
|
||||
await queryFn(
|
||||
'ALTER TABLE `users` ADD COLUMN `index_id` smallint(6) NOT NULL DEFAULT 0 AFTER `id`;',
|
||||
)
|
||||
|
||||
await queryFn('RENAME TABLE `users` TO `state_users`;')
|
||||
}
|
||||
@ -12,17 +12,13 @@ define(User, (faker: typeof Faker, context?: UserContext) => {
|
||||
user.email = context.email ? context.email : faker.internet.email()
|
||||
user.firstName = context.firstName ? context.firstName : faker.name.firstName()
|
||||
user.lastName = context.lastName ? context.lastName : faker.name.lastName()
|
||||
user.username = context.username ? context.username : faker.internet.userName()
|
||||
user.disabled = context.disabled ? context.disabled : false
|
||||
user.indexId = 0
|
||||
user.description = context.description ? context.description : faker.random.words(4)
|
||||
// TODO Create real password and keys/hash
|
||||
user.password = context.password ? context.password : BigInt(0)
|
||||
user.privKey = context.privKey ? context.privKey : randomBytes(80)
|
||||
user.emailHash = context.emailHash ? context.emailHash : randomBytes(32)
|
||||
user.createdAt = context.createdAt ? context.createdAt : faker.date.recent()
|
||||
user.emailChecked = context.emailChecked === undefined ? false : context.emailChecked
|
||||
user.passphraseShown = context.passphraseShown ? context.passphraseShown : false
|
||||
user.language = context.language ? context.language : 'en'
|
||||
user.publisherId = context.publisherId ? context.publisherId : 0
|
||||
user.passphrase = context.passphrase ? context.passphrase : faker.random.words(24)
|
||||
|
||||
@ -3,15 +3,12 @@ export interface UserContext {
|
||||
email?: string
|
||||
firstName?: string
|
||||
lastName?: string
|
||||
username?: string
|
||||
disabled?: boolean
|
||||
description?: string
|
||||
password?: BigInt
|
||||
privKey?: Buffer
|
||||
emailHash?: Buffer
|
||||
createdAt?: Date
|
||||
emailChecked?: boolean
|
||||
passphraseShown?: boolean
|
||||
language?: string
|
||||
publisherId?: number
|
||||
passphrase?: string
|
||||
|
||||
@ -3,15 +3,12 @@ export interface UserInterface {
|
||||
email?: string
|
||||
firstName?: string
|
||||
lastName?: string
|
||||
username?: string
|
||||
description?: string
|
||||
password?: BigInt
|
||||
pubKey?: Buffer
|
||||
privKey?: Buffer
|
||||
emailHash?: Buffer
|
||||
createdAt?: Date
|
||||
emailChecked?: boolean
|
||||
passphraseShown?: boolean
|
||||
language?: string
|
||||
disabled?: boolean
|
||||
groupId?: number
|
||||
|
||||
@ -42,15 +42,12 @@ const createUserContext = (context: UserInterface): UserContext => {
|
||||
email: context.email,
|
||||
firstName: context.firstName,
|
||||
lastName: context.lastName,
|
||||
username: context.username,
|
||||
disabled: context.disabled,
|
||||
description: context.description,
|
||||
password: context.password,
|
||||
privKey: context.privKey,
|
||||
emailHash: context.emailHash,
|
||||
createdAt: context.createdAt,
|
||||
emailChecked: context.emailChecked,
|
||||
passphraseShown: context.passphraseShown,
|
||||
language: context.language,
|
||||
publisherId: context.publisherId,
|
||||
}
|
||||
@ -59,7 +56,6 @@ const createUserContext = (context: UserInterface): UserContext => {
|
||||
const createServerUserContext = (context: UserInterface): ServerUserContext => {
|
||||
return {
|
||||
role: context.role,
|
||||
username: context.username,
|
||||
password: context.serverUserPassword,
|
||||
email: context.email,
|
||||
activated: context.activated,
|
||||
|
||||
@ -3,7 +3,7 @@ export const bibiBloxberg = {
|
||||
firstName: 'Bibi',
|
||||
lastName: 'Bloxberg',
|
||||
username: 'bibi',
|
||||
description: 'Hex Hex',
|
||||
// description: 'Hex Hex',
|
||||
password: BigInt('12825419584724616625'),
|
||||
pubKey: Buffer.from('42de7e4754625b730018c3b4ea745a4d043d9d867af352d0f08871793dfa6743', 'hex'),
|
||||
privKey: Buffer.from(
|
||||
@ -13,7 +13,6 @@ export const bibiBloxberg = {
|
||||
emailHash: Buffer.from('38a0d8c8658a5681cc1180c5d9e2b2a18e4f611db8ab3ca61de4aa91ae94219b', 'hex'),
|
||||
createdAt: new Date('2021-11-26T11:32:16'),
|
||||
emailChecked: true,
|
||||
passphraseShown: false,
|
||||
language: 'de',
|
||||
disabled: false,
|
||||
groupId: 1,
|
||||
|
||||
@ -3,7 +3,7 @@ export const bobBaumeister = {
|
||||
firstName: 'Bob',
|
||||
lastName: 'der Baumeister',
|
||||
username: 'bob',
|
||||
description: 'Können wir das schaffen? Ja, wir schaffen das!',
|
||||
// description: 'Können wir das schaffen? Ja, wir schaffen das!',
|
||||
password: BigInt('3296644341468822636'),
|
||||
pubKey: Buffer.from('a509d9a146374fc975e3677db801ae8a4a83bff9dea96da64053ff6de6b2dd7e', 'hex'),
|
||||
privKey: Buffer.from(
|
||||
@ -13,7 +13,6 @@ export const bobBaumeister = {
|
||||
emailHash: Buffer.from('4b8ce4e175587aaf33da19e272719da1a547daff557820191fab0c65c5a3b7f1', 'hex'),
|
||||
createdAt: new Date('2021-11-26T11:36:31'),
|
||||
emailChecked: true,
|
||||
passphraseShown: false,
|
||||
language: 'de',
|
||||
disabled: false,
|
||||
groupId: 1,
|
||||
|
||||
@ -3,13 +3,12 @@ export const garrickOllivander = {
|
||||
firstName: 'Garrick',
|
||||
lastName: 'Ollivander',
|
||||
username: 'garrick',
|
||||
description: `Curious ... curious ...
|
||||
Renowned wandmaker Mr Ollivander owns the wand shop Ollivanders: Makers of Fine Wands Since 382 BC in Diagon Alley. His shop is widely considered the best place to purchase a wand.`,
|
||||
// description: `Curious ... curious ...
|
||||
// Renowned wandmaker Mr Ollivander owns the wand shop Ollivanders: Makers of Fine Wands Since 382 BC in Diagon Alley. His shop is widely considered the best place to purchase a wand.`,
|
||||
password: BigInt('0'),
|
||||
emailHash: Buffer.from('91e358000e908146342789979d62a7255b2b88a71dad0c6a10e32af44be57886', 'hex'),
|
||||
createdAt: new Date('2022-01-10T10:23:17'),
|
||||
emailChecked: false,
|
||||
passphraseShown: false,
|
||||
language: 'en',
|
||||
disabled: false,
|
||||
groupId: 1,
|
||||
|
||||
@ -3,7 +3,7 @@ export const peterLustig = {
|
||||
firstName: 'Peter',
|
||||
lastName: 'Lustig',
|
||||
username: 'peter',
|
||||
description: 'Latzhose und Nickelbrille',
|
||||
// description: 'Latzhose und Nickelbrille',
|
||||
password: BigInt('3917921995996627700'),
|
||||
pubKey: Buffer.from('7281e0ee3258b08801f3ec73e431b4519677f65c03b0382c63a913b5784ee770', 'hex'),
|
||||
privKey: Buffer.from(
|
||||
@ -13,7 +13,6 @@ export const peterLustig = {
|
||||
emailHash: Buffer.from('9f700e6f6ec351a140b674c0edd4479509697b023bd8bee8826915ef6c2af036', 'hex'),
|
||||
createdAt: new Date('2020-11-25T10:48:43'),
|
||||
emailChecked: true,
|
||||
passphraseShown: false,
|
||||
language: 'de',
|
||||
disabled: false,
|
||||
groupId: 1,
|
||||
|
||||
@ -3,7 +3,7 @@ export const raeuberHotzenplotz = {
|
||||
firstName: 'Räuber',
|
||||
lastName: 'Hotzenplotz',
|
||||
username: 'räuber',
|
||||
description: 'Pfefferpistole',
|
||||
// description: 'Pfefferpistole',
|
||||
password: BigInt('12123692783243004812'),
|
||||
pubKey: Buffer.from('d7c70f94234dff071d982aa8f41583876c356599773b5911b39080da2b8c2d2b', 'hex'),
|
||||
privKey: Buffer.from(
|
||||
@ -13,7 +13,6 @@ export const raeuberHotzenplotz = {
|
||||
emailHash: Buffer.from('ec8d34112adb40ff2f6538b05660b03440372690f034cd7d6322d17020233c77', 'hex'),
|
||||
createdAt: new Date('2021-11-26T11:32:16'),
|
||||
emailChecked: true,
|
||||
passphraseShown: false,
|
||||
language: 'de',
|
||||
disabled: false,
|
||||
groupId: 1,
|
||||
|
||||
@ -32,10 +32,10 @@ WEBHOOK_ELOPAGE_SECRET=secret
|
||||
|
||||
GDT_API_URL=https://gdt.gradido.net
|
||||
|
||||
COMMUNITY_NAME=Gradido Development Stage1
|
||||
COMMUNITY_NAME="Gradido Development Stage1"
|
||||
COMMUNITY_URL=https://stage1.gradido.net/
|
||||
COMMUNITY_REGISTER_URL=https://stage1.gradido.net/register
|
||||
COMMUNITY_DESCRIPTION=Gradido Development Stage1 Test Community
|
||||
COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community"
|
||||
|
||||
KLICKTIPP=false
|
||||
KLICKTIPP_USER=
|
||||
|
||||
@ -14,9 +14,13 @@ set +o allexport
|
||||
# NOTE: all config values will be in process.env when starting
|
||||
# the services and will therefore take precedence over the .env
|
||||
if [ -f "$SCRIPT_DIR/.env" ]; then
|
||||
export $(cat $SCRIPT_DIR/.env | sed 's/#.*//g' | xargs)
|
||||
set -o allexport
|
||||
source $SCRIPT_DIR/.env
|
||||
set +o allexport
|
||||
else
|
||||
export $(cat $SCRIPT_DIR/.env.dist | sed 's/#.*//g' | xargs)
|
||||
set -o allexport
|
||||
source $SCRIPT_DIR/.env.dist
|
||||
set +o allexport
|
||||
fi
|
||||
|
||||
# Configure git
|
||||
@ -110,7 +114,6 @@ sudo mysql <<EOFMYSQL
|
||||
EOFMYSQL
|
||||
|
||||
# Configure database
|
||||
# TODO - do this in the start.sh to regenerate configs on each deploy
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/database/.env.template > $PROJECT_ROOT/database/.env
|
||||
|
||||
# Configure backend
|
||||
|
||||
@ -10,13 +10,29 @@ PROJECT_ROOT=$SCRIPT_DIR/../..
|
||||
NGINX_CONFIG_DIR=$SCRIPT_DIR/nginx/sites-available
|
||||
set +o allexport
|
||||
|
||||
# Load .env or .env.dist if not present
|
||||
# NOTE: all config values will be in process.env when starting
|
||||
# the services and will therefore take precedence over the .env
|
||||
|
||||
# We have to load the backend .env to get DB_USERNAME, DB_PASSWORD AND JWT_SECRET
|
||||
export_var(){
|
||||
export $1=$(grep -v '^#' $PROJECT_ROOT/backend/.env | grep -e "$1" | sed -e 's/.*=//')
|
||||
}
|
||||
|
||||
if [ -f "$PROJECT_ROOT/backend/.env" ]; then
|
||||
export_var 'DB_USER'
|
||||
export_var 'DB_PASSWORD'
|
||||
export_var 'JWT_SECRET'
|
||||
fi
|
||||
|
||||
# Load .env or .env.dist if not present
|
||||
if [ -f "$SCRIPT_DIR/.env" ]; then
|
||||
export $(cat $SCRIPT_DIR/.env | sed 's/#.*//g' | xargs)
|
||||
set -o allexport
|
||||
source $SCRIPT_DIR/.env
|
||||
set +o allexport
|
||||
else
|
||||
export $(cat $SCRIPT_DIR/.env.dist | sed 's/#.*//g' | xargs)
|
||||
set -o allexport
|
||||
source $SCRIPT_DIR/.env.dist
|
||||
set +o allexport
|
||||
fi
|
||||
|
||||
# lock start
|
||||
@ -64,6 +80,16 @@ case "$NGINX_SSL" in
|
||||
esac
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $NGINX_CONFIG_DIR/$TEMPLATE_FILE > $NGINX_CONFIG_DIR/update-page.conf
|
||||
|
||||
# Regenerate .env files
|
||||
cp -f $PROJECT_ROOT/database/.env $PROJECT_ROOT/database/.env.bak
|
||||
cp -f $PROJECT_ROOT/backend/.env $PROJECT_ROOT/backend/.env.bak
|
||||
cp -f $PROJECT_ROOT/frontend/.env $PROJECT_ROOT/frontend/.env.bak
|
||||
cp -f $PROJECT_ROOT/admin/.env $PROJECT_ROOT/admin/.env.bak
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/database/.env.template > $PROJECT_ROOT/database/.env
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/backend/.env.template > $PROJECT_ROOT/backend/.env
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/frontend/.env.template > $PROJECT_ROOT/frontend/.env
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/admin/.env.template > $PROJECT_ROOT/admin/.env
|
||||
|
||||
# Install & build database
|
||||
echo 'Updating database<br>' >> $UPDATE_HTML
|
||||
cd $PROJECT_ROOT/database
|
||||
|
||||
3
frontend/.gitignore
vendored
3
frontend/.gitignore
vendored
@ -8,7 +8,8 @@ yarn-error.log*
|
||||
test/unit/coverage
|
||||
|
||||
package-lock.json
|
||||
.env
|
||||
/.env
|
||||
/.env.bak
|
||||
.env.development.local
|
||||
.env.production.local
|
||||
|
||||
|
||||
@ -22,8 +22,6 @@ export const updateUserInfos = gql`
|
||||
mutation(
|
||||
$firstName: String
|
||||
$lastName: String
|
||||
$description: String
|
||||
$username: String
|
||||
$password: String
|
||||
$passwordNew: String
|
||||
$locale: String
|
||||
@ -32,8 +30,6 @@ export const updateUserInfos = gql`
|
||||
updateUserInfos(
|
||||
firstName: $firstName
|
||||
lastName: $lastName
|
||||
description: $description
|
||||
username: $username
|
||||
password: $password
|
||||
passwordNew: $passwordNew
|
||||
language: $locale
|
||||
|
||||
@ -4,11 +4,9 @@ export const login = gql`
|
||||
query($email: String!, $password: String!, $publisherId: Int) {
|
||||
login(email: $email, password: $password, publisherId: $publisherId) {
|
||||
email
|
||||
username
|
||||
firstName
|
||||
lastName
|
||||
language
|
||||
description
|
||||
coinanimation
|
||||
klickTipp {
|
||||
newsletterState
|
||||
@ -24,11 +22,9 @@ export const verifyLogin = gql`
|
||||
query {
|
||||
verifyLogin {
|
||||
email
|
||||
username
|
||||
firstName
|
||||
lastName
|
||||
language
|
||||
description
|
||||
coinanimation
|
||||
klickTipp {
|
||||
newsletterState
|
||||
@ -93,12 +89,6 @@ export const sendResetPasswordEmail = gql`
|
||||
}
|
||||
`
|
||||
|
||||
export const checkUsername = gql`
|
||||
query($username: String!) {
|
||||
checkUsername(username: $username)
|
||||
}
|
||||
`
|
||||
|
||||
export const listGDTEntriesQuery = gql`
|
||||
query($currentPage: Int!, $pageSize: Int!) {
|
||||
listGDTEntries(currentPage: $currentPage, pageSize: $pageSize) {
|
||||
|
||||
@ -15,18 +15,15 @@ export const mutations = {
|
||||
email: (state, email) => {
|
||||
state.email = email
|
||||
},
|
||||
username: (state, username) => {
|
||||
state.username = username
|
||||
},
|
||||
// username: (state, username) => {
|
||||
// state.username = username
|
||||
// },
|
||||
firstName: (state, firstName) => {
|
||||
state.firstName = firstName
|
||||
},
|
||||
lastName: (state, lastName) => {
|
||||
state.lastName = lastName
|
||||
},
|
||||
description: (state, description) => {
|
||||
state.description = description
|
||||
},
|
||||
token: (state, token) => {
|
||||
state.token = token
|
||||
},
|
||||
@ -56,10 +53,9 @@ export const actions = {
|
||||
login: ({ dispatch, commit }, data) => {
|
||||
commit('email', data.email)
|
||||
commit('language', data.language)
|
||||
commit('username', data.username)
|
||||
// commit('username', data.username)
|
||||
commit('firstName', data.firstName)
|
||||
commit('lastName', data.lastName)
|
||||
commit('description', data.description)
|
||||
commit('coinanimation', data.coinanimation)
|
||||
commit('newsletterState', data.klickTipp.newsletterState)
|
||||
commit('hasElopage', data.hasElopage)
|
||||
@ -69,10 +65,9 @@ export const actions = {
|
||||
logout: ({ commit, state }) => {
|
||||
commit('token', null)
|
||||
commit('email', null)
|
||||
commit('username', '')
|
||||
// commit('username', '')
|
||||
commit('firstName', '')
|
||||
commit('lastName', '')
|
||||
commit('description', '')
|
||||
commit('coinanimation', true)
|
||||
commit('newsletterState', null)
|
||||
commit('hasElopage', false)
|
||||
@ -96,8 +91,7 @@ try {
|
||||
language: null,
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
username: '',
|
||||
description: '',
|
||||
// username: '',
|
||||
token: null,
|
||||
isAdmin: false,
|
||||
coinanimation: true,
|
||||
|
||||
@ -18,10 +18,8 @@ const {
|
||||
language,
|
||||
email,
|
||||
token,
|
||||
username,
|
||||
firstName,
|
||||
lastName,
|
||||
description,
|
||||
coinanimation,
|
||||
newsletterState,
|
||||
publisherId,
|
||||
@ -65,14 +63,6 @@ describe('Vuex store', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('username', () => {
|
||||
it('sets the state of username', () => {
|
||||
const state = { username: null }
|
||||
username(state, 'user')
|
||||
expect(state.username).toEqual('user')
|
||||
})
|
||||
})
|
||||
|
||||
describe('firstName', () => {
|
||||
it('sets the state of firstName', () => {
|
||||
const state = { firstName: null }
|
||||
@ -89,14 +79,6 @@ describe('Vuex store', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('description', () => {
|
||||
it('sets the state of description', () => {
|
||||
const state = { description: null }
|
||||
description(state, 'Nickelbrille')
|
||||
expect(state.description).toEqual('Nickelbrille')
|
||||
})
|
||||
})
|
||||
|
||||
describe('coinanimation', () => {
|
||||
it('sets the state of coinanimation', () => {
|
||||
const state = { coinanimation: true }
|
||||
@ -169,10 +151,8 @@ describe('Vuex store', () => {
|
||||
const commitedData = {
|
||||
email: 'user@example.org',
|
||||
language: 'de',
|
||||
username: 'peter',
|
||||
firstName: 'Peter',
|
||||
lastName: 'Lustig',
|
||||
description: 'Nickelbrille',
|
||||
coinanimation: false,
|
||||
klickTipp: {
|
||||
newsletterState: true,
|
||||
@ -182,9 +162,9 @@ describe('Vuex store', () => {
|
||||
isAdmin: true,
|
||||
}
|
||||
|
||||
it('calls eleven commits', () => {
|
||||
it('calls nine commits', () => {
|
||||
login({ commit, state }, commitedData)
|
||||
expect(commit).toHaveBeenCalledTimes(11)
|
||||
expect(commit).toHaveBeenCalledTimes(9)
|
||||
})
|
||||
|
||||
it('commits email', () => {
|
||||
@ -197,49 +177,39 @@ describe('Vuex store', () => {
|
||||
expect(commit).toHaveBeenNthCalledWith(2, 'language', 'de')
|
||||
})
|
||||
|
||||
it('commits username', () => {
|
||||
login({ commit, state }, commitedData)
|
||||
expect(commit).toHaveBeenNthCalledWith(3, 'username', 'peter')
|
||||
})
|
||||
|
||||
it('commits firstName', () => {
|
||||
login({ commit, state }, commitedData)
|
||||
expect(commit).toHaveBeenNthCalledWith(4, 'firstName', 'Peter')
|
||||
expect(commit).toHaveBeenNthCalledWith(3, 'firstName', 'Peter')
|
||||
})
|
||||
|
||||
it('commits lastName', () => {
|
||||
login({ commit, state }, commitedData)
|
||||
expect(commit).toHaveBeenNthCalledWith(5, 'lastName', 'Lustig')
|
||||
})
|
||||
|
||||
it('commits description', () => {
|
||||
login({ commit, state }, commitedData)
|
||||
expect(commit).toHaveBeenNthCalledWith(6, 'description', 'Nickelbrille')
|
||||
expect(commit).toHaveBeenNthCalledWith(4, 'lastName', 'Lustig')
|
||||
})
|
||||
|
||||
it('commits coinanimation', () => {
|
||||
login({ commit, state }, commitedData)
|
||||
expect(commit).toHaveBeenNthCalledWith(7, 'coinanimation', false)
|
||||
expect(commit).toHaveBeenNthCalledWith(5, 'coinanimation', false)
|
||||
})
|
||||
|
||||
it('commits newsletterState', () => {
|
||||
login({ commit, state }, commitedData)
|
||||
expect(commit).toHaveBeenNthCalledWith(8, 'newsletterState', true)
|
||||
expect(commit).toHaveBeenNthCalledWith(6, 'newsletterState', true)
|
||||
})
|
||||
|
||||
it('commits hasElopage', () => {
|
||||
login({ commit, state }, commitedData)
|
||||
expect(commit).toHaveBeenNthCalledWith(9, 'hasElopage', false)
|
||||
expect(commit).toHaveBeenNthCalledWith(7, 'hasElopage', false)
|
||||
})
|
||||
|
||||
it('commits publisherId', () => {
|
||||
login({ commit, state }, commitedData)
|
||||
expect(commit).toHaveBeenNthCalledWith(10, 'publisherId', 1234)
|
||||
expect(commit).toHaveBeenNthCalledWith(8, 'publisherId', 1234)
|
||||
})
|
||||
|
||||
it('commits isAdmin', () => {
|
||||
login({ commit, state }, commitedData)
|
||||
expect(commit).toHaveBeenNthCalledWith(11, 'isAdmin', true)
|
||||
expect(commit).toHaveBeenNthCalledWith(9, 'isAdmin', true)
|
||||
})
|
||||
})
|
||||
|
||||
@ -247,9 +217,9 @@ describe('Vuex store', () => {
|
||||
const commit = jest.fn()
|
||||
const state = {}
|
||||
|
||||
it('calls eleven commits', () => {
|
||||
it('calls nine commits', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenCalledTimes(11)
|
||||
expect(commit).toHaveBeenCalledTimes(9)
|
||||
})
|
||||
|
||||
it('commits token', () => {
|
||||
@ -262,49 +232,39 @@ describe('Vuex store', () => {
|
||||
expect(commit).toHaveBeenNthCalledWith(2, 'email', null)
|
||||
})
|
||||
|
||||
it('commits username', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(3, 'username', '')
|
||||
})
|
||||
|
||||
it('commits firstName', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(4, 'firstName', '')
|
||||
expect(commit).toHaveBeenNthCalledWith(3, 'firstName', '')
|
||||
})
|
||||
|
||||
it('commits lastName', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(5, 'lastName', '')
|
||||
})
|
||||
|
||||
it('commits description', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(6, 'description', '')
|
||||
expect(commit).toHaveBeenNthCalledWith(4, 'lastName', '')
|
||||
})
|
||||
|
||||
it('commits coinanimation', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(7, 'coinanimation', true)
|
||||
expect(commit).toHaveBeenNthCalledWith(5, 'coinanimation', true)
|
||||
})
|
||||
|
||||
it('commits newsletterState', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(8, 'newsletterState', null)
|
||||
expect(commit).toHaveBeenNthCalledWith(6, 'newsletterState', null)
|
||||
})
|
||||
|
||||
it('commits hasElopage', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(9, 'hasElopage', false)
|
||||
expect(commit).toHaveBeenNthCalledWith(7, 'hasElopage', false)
|
||||
})
|
||||
|
||||
it('commits publisherId', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(10, 'publisherId', null)
|
||||
expect(commit).toHaveBeenNthCalledWith(8, 'publisherId', null)
|
||||
})
|
||||
|
||||
it('commits isAdmin', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenNthCalledWith(11, 'isAdmin', false)
|
||||
expect(commit).toHaveBeenNthCalledWith(9, 'isAdmin', false)
|
||||
})
|
||||
|
||||
// how to get this working?
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { configure, extend } from 'vee-validate'
|
||||
// eslint-disable-next-line camelcase
|
||||
import { required, email, min, max, is_not } from 'vee-validate/dist/rules'
|
||||
import { checkUsername } from './graphql/queries'
|
||||
|
||||
export const loadAllRules = (i18nCallback) => {
|
||||
configure({
|
||||
@ -49,32 +48,6 @@ export const loadAllRules = (i18nCallback) => {
|
||||
},
|
||||
})
|
||||
|
||||
extend('gddUsernameUnique', {
|
||||
async validate(value) {
|
||||
this.$apollo
|
||||
.query({
|
||||
query: checkUsername,
|
||||
variables: {
|
||||
username: value,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
return result.data.checkUsername
|
||||
})
|
||||
.catch(() => {
|
||||
return false
|
||||
})
|
||||
},
|
||||
message: (_, values) => i18nCallback.t('form.validation.usernmae-unique', values),
|
||||
})
|
||||
|
||||
extend('gddUsernameRgex', {
|
||||
validate(value) {
|
||||
return !!value.match(/^[a-zA-Z][-_a-zA-Z0-9]{2,}$/)
|
||||
},
|
||||
message: (_, values) => i18nCallback.t('form.validation.usernmae-regex', values),
|
||||
})
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
extend('is_not', {
|
||||
// eslint-disable-next-line camelcase
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
<sidebar class="main-sidebar" :elopageUri="elopageUri" @admin="admin" @logout="logout" />
|
||||
</div>
|
||||
|
||||
<div class="main-page ml-2 mr-2" style="width: 100%" @click="visible = false">
|
||||
<div class="main-page" style="width: 100%" @click="visible = false">
|
||||
<div class="main-content">
|
||||
<fade-transition :duration="200" origin="center top" mode="out-in">
|
||||
<router-view
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-container>
|
||||
<gdd-send :currentTransactionStep="currentTransactionStep" class="pt-3">
|
||||
<gdd-send :currentTransactionStep="currentTransactionStep" class="pt-3 ml-2 mr-2">
|
||||
<template #transaction-form>
|
||||
<transaction-form :balance="balance" @set-transaction="setTransaction"></transaction-form>
|
||||
</template>
|
||||
@ -97,6 +97,12 @@ export default {
|
||||
onReset() {
|
||||
this.currentTransactionStep = 0
|
||||
},
|
||||
updateTransactions(pagination) {
|
||||
this.$emit('update-transactions', pagination)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.updateTransactions(0)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -19,7 +19,6 @@ describe('UserCard_FormUserData', () => {
|
||||
state: {
|
||||
firstName: 'Peter',
|
||||
lastName: 'Lustig',
|
||||
description: '',
|
||||
},
|
||||
commit: storeCommitMock,
|
||||
},
|
||||
@ -59,10 +58,6 @@ describe('UserCard_FormUserData', () => {
|
||||
expect(wrapper.findAll('div.col').at(4).text()).toBe('Lustig')
|
||||
})
|
||||
|
||||
it('renders the description', () => {
|
||||
expect(wrapper.findAll('div.col').at(6).text()).toBe('')
|
||||
})
|
||||
|
||||
describe('edit user data', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper.find('svg.bi-pencil').trigger('click')
|
||||
@ -80,11 +75,9 @@ describe('UserCard_FormUserData', () => {
|
||||
it('does not change the userdate when cancel is clicked', async () => {
|
||||
await wrapper.findAll('input').at(0).setValue('Petra')
|
||||
await wrapper.findAll('input').at(1).setValue('Lustiger')
|
||||
await wrapper.find('textarea').setValue('Keine Nickelbrille')
|
||||
await wrapper.find('svg.bi-x-circle').trigger('click')
|
||||
expect(wrapper.findAll('div.col').at(2).text()).toBe('Peter')
|
||||
expect(wrapper.findAll('div.col').at(4).text()).toBe('Lustig')
|
||||
expect(wrapper.findAll('div.col').at(6).text()).toBe('')
|
||||
})
|
||||
|
||||
it('has a submit button', () => {
|
||||
@ -108,7 +101,6 @@ describe('UserCard_FormUserData', () => {
|
||||
jest.clearAllMocks()
|
||||
await wrapper.findAll('input').at(0).setValue('Petra')
|
||||
await wrapper.findAll('input').at(1).setValue('Lustiger')
|
||||
await wrapper.find('textarea').setValue('Keine Nickelbrille')
|
||||
await wrapper.find('form').trigger('keyup')
|
||||
await wrapper.find('button[type="submit"]').trigger('click')
|
||||
await flushPromises()
|
||||
@ -120,7 +112,6 @@ describe('UserCard_FormUserData', () => {
|
||||
variables: {
|
||||
firstName: 'Petra',
|
||||
lastName: 'Lustiger',
|
||||
description: 'Keine Nickelbrille',
|
||||
},
|
||||
}),
|
||||
)
|
||||
@ -134,10 +125,6 @@ describe('UserCard_FormUserData', () => {
|
||||
expect(storeCommitMock).toBeCalledWith('lastName', 'Lustiger')
|
||||
})
|
||||
|
||||
it('commits description to store', () => {
|
||||
expect(storeCommitMock).toBeCalledWith('description', 'Keine Nickelbrille')
|
||||
})
|
||||
|
||||
it('toasts a success message', () => {
|
||||
expect(toastSuccessMock).toBeCalledWith('settings.name.change-success')
|
||||
})
|
||||
@ -155,7 +142,6 @@ describe('UserCard_FormUserData', () => {
|
||||
jest.clearAllMocks()
|
||||
await wrapper.findAll('input').at(0).setValue('Petra')
|
||||
await wrapper.findAll('input').at(1).setValue('Lustiger')
|
||||
await wrapper.find('textarea').setValue('Keine Nickelbrille')
|
||||
await wrapper.find('form').trigger('keyup')
|
||||
await wrapper.find('button[type="submit"]').trigger('click')
|
||||
await flushPromises()
|
||||
@ -167,7 +153,6 @@ describe('UserCard_FormUserData', () => {
|
||||
variables: {
|
||||
firstName: 'Petra',
|
||||
lastName: 'Lustiger',
|
||||
description: 'Keine Nickelbrille',
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
@ -43,17 +43,6 @@
|
||||
<b-input type="text" v-model="form.lastName"></b-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row class="mb-3" v-show="false">
|
||||
<b-col class="col-12">
|
||||
<small>{{ $t('form.description') }}</small>
|
||||
</b-col>
|
||||
<b-col v-if="showUserData" class="col-12">
|
||||
{{ form.description }}
|
||||
</b-col>
|
||||
<b-col v-else class="col-12">
|
||||
<b-textarea rows="3" max-rows="6" v-model="form.description"></b-textarea>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row class="text-right" v-if="!showUserData">
|
||||
<b-col>
|
||||
@ -85,7 +74,6 @@ export default {
|
||||
form: {
|
||||
firstName: this.$store.state.firstName,
|
||||
lastName: this.$store.state.lastName,
|
||||
description: this.$store.state.description,
|
||||
},
|
||||
loading: true,
|
||||
}
|
||||
@ -94,14 +82,12 @@ export default {
|
||||
cancelEdit() {
|
||||
this.form.firstName = this.$store.state.firstName
|
||||
this.form.lastName = this.$store.state.lastName
|
||||
this.form.description = this.$store.state.description
|
||||
this.showUserData = true
|
||||
},
|
||||
loadSubmitButton() {
|
||||
if (
|
||||
this.form.firstName !== this.$store.state.firstName ||
|
||||
this.form.lastName !== this.$store.state.lastName ||
|
||||
this.form.description !== this.$store.state.description
|
||||
this.form.lastName !== this.$store.state.lastName
|
||||
) {
|
||||
this.loading = false
|
||||
} else {
|
||||
@ -116,13 +102,11 @@ export default {
|
||||
variables: {
|
||||
firstName: this.form.firstName,
|
||||
lastName: this.form.lastName,
|
||||
description: this.form.description,
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
this.$store.commit('firstName', this.form.firstName)
|
||||
this.$store.commit('lastName', this.form.lastName)
|
||||
this.$store.commit('description', this.form.description)
|
||||
this.showUserData = true
|
||||
this.$toasted.success(this.$t('settings.name.change-success'))
|
||||
})
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div fluid="sm">
|
||||
<div fluid="sm" class="mr-2">
|
||||
<user-card :balance="balance" :transactionCount="transactionCount"></user-card>
|
||||
<form-user-data />
|
||||
<hr />
|
||||
@ -34,6 +34,14 @@ export default {
|
||||
balance: { type: Number, default: 0 },
|
||||
transactionCount: { type: Number, default: 0 },
|
||||
},
|
||||
methods: {
|
||||
updateTransactions(pagination) {
|
||||
this.$emit('update-transactions', pagination)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.updateTransactions(0)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="pb-4">
|
||||
<b-tabs content-class="mt-3 pt-4 pb-4" justified>
|
||||
<b-tabs content-class="" justified>
|
||||
<b-tab :title="'Gradido (' + $n(balance, 'decimal') + ' GDD)'" class="px-4">
|
||||
<p class="tab-tex">{{ $t('transaction.gdd-text') }}</p>
|
||||
|
||||
@ -53,17 +53,20 @@ export default {
|
||||
</script>
|
||||
<style>
|
||||
.nav-tabs > li > a {
|
||||
/* adjust padding for height*/
|
||||
padding-top: 14px;
|
||||
padding-bottom: 14px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.nav-tabs > li.active {
|
||||
background-color: aquamarine;
|
||||
font-size: larger;
|
||||
.nav-tabs .nav-link {
|
||||
background-color: rgba(204, 204, 204, 0.185);
|
||||
}
|
||||
.nav-tabs .nav-link.active {
|
||||
background-color: rgb(248 249 254);
|
||||
}
|
||||
|
||||
.nav-tabs > li > a {
|
||||
outline: none !important;
|
||||
.tab-content {
|
||||
padding-top: 25px;
|
||||
border-left: 1px inset rgba(28, 110, 164, 0.1);
|
||||
border-right: 1px inset rgba(28, 110, 164, 0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
1
gn
1
gn
@ -1 +0,0 @@
|
||||
Subproject commit 5437e2f882c54efe4f501f7cd0d97f53806d0b74
|
||||
Loading…
x
Reference in New Issue
Block a user