mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
Merge branch 'master' into dlt_transmit_to_iota
This commit is contained in:
commit
6454adb78e
@ -27,7 +27,7 @@ DLT_CONNECTOR_URL=http://localhost:6010
|
||||
|
||||
# Community
|
||||
COMMUNITY_NAME=Gradido Entwicklung
|
||||
COMMUNITY_URL=http://localhost/
|
||||
COMMUNITY_URL=http://localhost
|
||||
COMMUNITY_REGISTER_PATH=/register
|
||||
COMMUNITY_REDEEM_PATH=/redeem/{code}
|
||||
COMMUNITY_REDEEM_CONTRIBUTION_PATH=/redeem/CL-{code}
|
||||
|
||||
@ -12,7 +12,7 @@ Decimal.set({
|
||||
})
|
||||
|
||||
const constants = {
|
||||
DB_VERSION: '0080-fill_linked_user_gradidoId_of_contributions',
|
||||
DB_VERSION: '0081-user_join_community',
|
||||
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
|
||||
|
||||
@ -3,11 +3,11 @@ import { ArgsType, Field } from 'type-graphql'
|
||||
|
||||
@ArgsType()
|
||||
export class UserArgs {
|
||||
@Field({ nullable: false })
|
||||
@Field()
|
||||
@IsString()
|
||||
identifier: string
|
||||
|
||||
@Field({ nullable: true })
|
||||
@Field()
|
||||
@IsString()
|
||||
communityIdentifier?: string
|
||||
communityIdentifier: string
|
||||
}
|
||||
|
||||
@ -10,6 +10,9 @@ export class User {
|
||||
this.id = user.id
|
||||
this.foreign = user.foreign
|
||||
this.communityUuid = user.communityUuid
|
||||
if (user.community) {
|
||||
this.communityName = user.community.name
|
||||
}
|
||||
this.gradidoID = user.gradidoID
|
||||
this.alias = user.alias
|
||||
if (user.emailContact) {
|
||||
|
||||
@ -142,7 +142,11 @@ describe('send coins', () => {
|
||||
})
|
||||
|
||||
it('logs the error thrown', () => {
|
||||
expect(logger.error).toBeCalledWith('No user with this credentials', 'wrong@email.com')
|
||||
expect(logger.error).toBeCalledWith(
|
||||
'No user with this credentials',
|
||||
'wrong@email.com',
|
||||
homeCom.communityUuid,
|
||||
)
|
||||
})
|
||||
|
||||
describe('deleted recipient', () => {
|
||||
@ -165,13 +169,17 @@ describe('send coins', () => {
|
||||
}),
|
||||
).toEqual(
|
||||
expect.objectContaining({
|
||||
errors: [new GraphQLError('No user to given contact')],
|
||||
errors: [new GraphQLError('No user with this credentials')],
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('logs the error thrown', () => {
|
||||
expect(logger.error).toBeCalledWith('No user to given contact', 'stephen@hawking.uk')
|
||||
expect(logger.error).toBeCalledWith(
|
||||
'No user with this credentials',
|
||||
'stephen@hawking.uk',
|
||||
homeCom.communityUuid,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@ -204,6 +212,7 @@ describe('send coins', () => {
|
||||
expect(logger.error).toBeCalledWith(
|
||||
'No user with this credentials',
|
||||
'garrick@ollivander.com',
|
||||
homeCom.communityUuid,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@ -432,7 +432,7 @@ export class TransactionResolver {
|
||||
const senderUser = getUser(context)
|
||||
|
||||
if (!recipientCommunityIdentifier || (await isHomeCommunity(recipientCommunityIdentifier))) {
|
||||
// processing sendCoins within sender and recepient are both in home community
|
||||
// processing sendCoins within sender and recipient are both in home community
|
||||
const recipientUser = await findUserByIdentifier(
|
||||
recipientIdentifier,
|
||||
recipientCommunityIdentifier,
|
||||
|
||||
@ -2552,6 +2552,7 @@ describe('UserResolver', () => {
|
||||
query: userQuery,
|
||||
variables: {
|
||||
identifier: 'identifier',
|
||||
communityIdentifier: 'community identifier',
|
||||
},
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
@ -2637,13 +2638,11 @@ describe('UserResolver', () => {
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
errors: [
|
||||
new GraphQLError('Found user to given contact, but belongs to other community'),
|
||||
],
|
||||
errors: [new GraphQLError('No user with this credentials')],
|
||||
}),
|
||||
)
|
||||
expect(logger.error).toBeCalledWith(
|
||||
'Found user to given contact, but belongs to other community',
|
||||
'No user with this credentials',
|
||||
'bibi@bloxberg.de',
|
||||
foreignCom1.communityUuid,
|
||||
)
|
||||
|
||||
@ -65,7 +65,7 @@ import random from 'random-bigint'
|
||||
import { randombytes_random } from 'sodium-native'
|
||||
|
||||
import { FULL_CREATION_AVAILABLE } from './const/const'
|
||||
import { getCommunityName, getHomeCommunity } from './util/communities'
|
||||
import { getHomeCommunity } from './util/communities'
|
||||
import { getUserCreations } from './util/creations'
|
||||
import { findUserByIdentifier } from './util/findUserByIdentifier'
|
||||
import { findUsers } from './util/findUsers'
|
||||
@ -821,11 +821,6 @@ export class UserResolver {
|
||||
): Promise<User> {
|
||||
const foundDbUser = await findUserByIdentifier(identifier, communityIdentifier)
|
||||
const modelUser = new User(foundDbUser)
|
||||
if (!foundDbUser.communityUuid) {
|
||||
modelUser.communityName = (await Promise.resolve(getHomeCommunity())).name
|
||||
} else {
|
||||
modelUser.communityName = await getCommunityName(foundDbUser.communityUuid)
|
||||
}
|
||||
return modelUser
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import { Community as DbCommunity } from '@entity/Community'
|
||||
import { ApolloServerTestClient } from 'apollo-server-testing'
|
||||
import { Decimal } from 'decimal.js-light'
|
||||
import { GraphQLError } from 'graphql'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
import { cleanDB, testEnvironment, contributionDateFormatter } from '@test/helpers'
|
||||
|
||||
@ -54,7 +55,7 @@ describe('semaphore', () => {
|
||||
beforeAll(async () => {
|
||||
const now = new Date()
|
||||
homeCom = DbCommunity.create()
|
||||
homeCom.communityUuid = 'homeCom-UUID'
|
||||
homeCom.communityUuid = uuidv4()
|
||||
homeCom.creationDate = new Date('2000-01-01')
|
||||
homeCom.description = 'homeCom description'
|
||||
homeCom.foreign = false
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { FindOptionsWhere } from '@dbTools/typeorm'
|
||||
import { Community } from '@entity/Community'
|
||||
import { User as DbUser } from '@entity/User'
|
||||
import { UserContact as DbUserContact } from '@entity/UserContact'
|
||||
import { validate, version } from 'uuid'
|
||||
@ -6,15 +8,26 @@ import { LogError } from '@/server/LogError'
|
||||
|
||||
import { VALID_ALIAS_REGEX } from './validateAlias'
|
||||
|
||||
/**
|
||||
*
|
||||
* @param identifier could be gradidoID, alias or email of user
|
||||
* @param communityIdentifier could be uuid or name of community
|
||||
* @returns
|
||||
*/
|
||||
export const findUserByIdentifier = async (
|
||||
identifier: string,
|
||||
communityIdentifier?: string,
|
||||
communityIdentifier: string,
|
||||
): Promise<DbUser> => {
|
||||
let user: DbUser | null
|
||||
const communityWhere: FindOptionsWhere<Community> =
|
||||
validate(communityIdentifier) && version(communityIdentifier) === 4
|
||||
? { communityUuid: communityIdentifier }
|
||||
: { name: communityIdentifier }
|
||||
|
||||
if (validate(identifier) && version(identifier) === 4) {
|
||||
user = await DbUser.findOne({
|
||||
where: { gradidoID: identifier, communityUuid: communityIdentifier },
|
||||
relations: ['emailContact'],
|
||||
where: { gradidoID: identifier, community: communityWhere },
|
||||
relations: ['emailContact', 'community'],
|
||||
})
|
||||
if (!user) {
|
||||
throw new LogError('No user found to given identifier(s)', identifier, communityIdentifier)
|
||||
@ -24,28 +37,21 @@ export const findUserByIdentifier = async (
|
||||
where: {
|
||||
email: identifier,
|
||||
emailChecked: true,
|
||||
user: {
|
||||
community: communityWhere,
|
||||
},
|
||||
},
|
||||
relations: ['user'],
|
||||
relations: { user: { community: true } },
|
||||
})
|
||||
if (!userContact) {
|
||||
throw new LogError('No user with this credentials', identifier)
|
||||
}
|
||||
if (!userContact.user) {
|
||||
throw new LogError('No user to given contact', identifier)
|
||||
}
|
||||
if (userContact.user.communityUuid !== communityIdentifier) {
|
||||
throw new LogError(
|
||||
'Found user to given contact, but belongs to other community',
|
||||
identifier,
|
||||
communityIdentifier,
|
||||
)
|
||||
throw new LogError('No user with this credentials', identifier, communityIdentifier)
|
||||
}
|
||||
user = userContact.user
|
||||
user.emailContact = userContact
|
||||
} else if (VALID_ALIAS_REGEX.exec(identifier)) {
|
||||
user = await DbUser.findOne({
|
||||
where: { alias: identifier, communityUuid: communityIdentifier },
|
||||
relations: ['emailContact'],
|
||||
where: { alias: identifier, community: communityWhere },
|
||||
relations: ['emailContact', 'community'],
|
||||
})
|
||||
if (!user) {
|
||||
throw new LogError('No user found to given identifier(s)', identifier, communityIdentifier)
|
||||
|
||||
@ -0,0 +1,94 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
import { Connection } from '@dbTools/typeorm'
|
||||
import { Community as DbCommunity } from '@entity/Community'
|
||||
import { User as DbUser } from '@entity/User'
|
||||
import { ApolloServerTestClient } from 'apollo-server-testing'
|
||||
|
||||
import { cleanDB, testEnvironment } from '@test/helpers'
|
||||
|
||||
import { writeHomeCommunityEntry } from '@/seeds/community'
|
||||
import { userFactory } from '@/seeds/factory/user'
|
||||
import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg'
|
||||
import { bobBaumeister } from '@/seeds/users/bob-baumeister'
|
||||
import { peterLustig } from '@/seeds/users/peter-lustig'
|
||||
|
||||
import { findUserByIdentifier } from './findUserByIdentifier'
|
||||
|
||||
let con: Connection
|
||||
let testEnv: {
|
||||
mutate: ApolloServerTestClient['mutate']
|
||||
query: ApolloServerTestClient['query']
|
||||
con: Connection
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
testEnv = await testEnvironment()
|
||||
con = testEnv.con
|
||||
await cleanDB()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await cleanDB()
|
||||
await con.close()
|
||||
})
|
||||
|
||||
describe('graphql/resolver/util/findUserByIdentifier', () => {
|
||||
let homeCom: DbCommunity
|
||||
let communityUuid: string
|
||||
let communityName: string
|
||||
let userBibi: DbUser
|
||||
|
||||
beforeAll(async () => {
|
||||
homeCom = await writeHomeCommunityEntry()
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
communityUuid = homeCom.communityUuid!
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
communityName = homeCom.communityUuid!
|
||||
|
||||
userBibi = await userFactory(testEnv, bibiBloxberg)
|
||||
await userFactory(testEnv, peterLustig)
|
||||
await userFactory(testEnv, bobBaumeister)
|
||||
})
|
||||
|
||||
describe('communityIdentifier is community uuid', () => {
|
||||
it('userIdentifier is gradido id', async () => {
|
||||
const user = await findUserByIdentifier(userBibi.gradidoID, communityUuid)
|
||||
user.userRoles = []
|
||||
expect(user).toMatchObject(userBibi)
|
||||
})
|
||||
|
||||
it('userIdentifier is alias', async () => {
|
||||
const user = await findUserByIdentifier(userBibi.alias, communityUuid)
|
||||
user.userRoles = []
|
||||
expect(user).toMatchObject(userBibi)
|
||||
})
|
||||
|
||||
it('userIdentifier is email', async () => {
|
||||
const user = await findUserByIdentifier(userBibi.emailContact.email, communityUuid)
|
||||
user.userRoles = []
|
||||
expect(user).toMatchObject(userBibi)
|
||||
})
|
||||
})
|
||||
|
||||
describe('communityIdentifier is community name', () => {
|
||||
it('userIdentifier is gradido id', async () => {
|
||||
const user = await findUserByIdentifier(userBibi.gradidoID, communityName)
|
||||
user.userRoles = []
|
||||
expect(user).toMatchObject(userBibi)
|
||||
})
|
||||
|
||||
it('userIdentifier is alias', async () => {
|
||||
const user = await findUserByIdentifier(userBibi.alias, communityName)
|
||||
user.userRoles = []
|
||||
expect(user).toMatchObject(userBibi)
|
||||
})
|
||||
|
||||
it('userIdentifier is email', async () => {
|
||||
const user = await findUserByIdentifier(userBibi.emailContact.email, communityName)
|
||||
user.userRoles = []
|
||||
expect(user).toMatchObject(userBibi)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -370,7 +370,7 @@ export const adminListContributionMessages = gql`
|
||||
`
|
||||
|
||||
export const user = gql`
|
||||
query ($identifier: String!, $communityIdentifier: String) {
|
||||
query ($identifier: String!, $communityIdentifier: String!) {
|
||||
user(identifier: $identifier, communityIdentifier: $communityIdentifier) {
|
||||
firstName
|
||||
lastName
|
||||
|
||||
@ -4,6 +4,7 @@ export const bibiBloxberg: UserInterface = {
|
||||
email: 'bibi@bloxberg.de',
|
||||
firstName: 'Bibi',
|
||||
lastName: 'Bloxberg',
|
||||
alias: 'BBB',
|
||||
// description: 'Hex Hex',
|
||||
emailChecked: true,
|
||||
language: 'de',
|
||||
|
||||
@ -50,6 +50,7 @@ const communityDbUser: dbUser = {
|
||||
},
|
||||
foreign: false,
|
||||
communityUuid: '55555555-4444-4333-2222-11111111',
|
||||
community: null,
|
||||
}
|
||||
const communityUser = new User(communityDbUser)
|
||||
|
||||
|
||||
70
database/entity/0081-user_join_community/Community.ts
Normal file
70
database/entity/0081-user_join_community/Community.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import {
|
||||
BaseEntity,
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
OneToMany,
|
||||
JoinColumn,
|
||||
} from 'typeorm'
|
||||
import { User } from '../User'
|
||||
|
||||
@Entity('communities')
|
||||
export class Community extends BaseEntity {
|
||||
@PrimaryGeneratedColumn('increment', { unsigned: true })
|
||||
id: number
|
||||
|
||||
@Column({ name: 'foreign', type: 'bool', nullable: false, default: true })
|
||||
foreign: boolean
|
||||
|
||||
@Column({ name: 'url', length: 255, nullable: false })
|
||||
url: string
|
||||
|
||||
@Column({ name: 'public_key', type: 'binary', length: 32, nullable: false })
|
||||
publicKey: Buffer
|
||||
|
||||
@Column({ name: 'private_key', type: 'binary', length: 64, nullable: true })
|
||||
privateKey: Buffer | null
|
||||
|
||||
@Column({
|
||||
name: 'community_uuid',
|
||||
type: 'char',
|
||||
length: 36,
|
||||
nullable: true,
|
||||
collation: 'utf8mb4_unicode_ci',
|
||||
})
|
||||
communityUuid: string | null
|
||||
|
||||
@Column({ name: 'authenticated_at', type: 'datetime', nullable: true })
|
||||
authenticatedAt: Date | null
|
||||
|
||||
@Column({ name: 'name', type: 'varchar', length: 40, nullable: true })
|
||||
name: string | null
|
||||
|
||||
@Column({ name: 'description', type: 'varchar', length: 255, nullable: true })
|
||||
description: string | null
|
||||
|
||||
@CreateDateColumn({ name: 'creation_date', type: 'datetime', nullable: true })
|
||||
creationDate: Date | null
|
||||
|
||||
@CreateDateColumn({
|
||||
name: 'created_at',
|
||||
type: 'datetime',
|
||||
default: () => 'CURRENT_TIMESTAMP(3)',
|
||||
nullable: false,
|
||||
})
|
||||
createdAt: Date
|
||||
|
||||
@UpdateDateColumn({
|
||||
name: 'updated_at',
|
||||
type: 'datetime',
|
||||
onUpdate: 'CURRENT_TIMESTAMP(3)',
|
||||
nullable: true,
|
||||
})
|
||||
updatedAt: Date | null
|
||||
|
||||
@OneToMany(() => User, (user) => user.community)
|
||||
@JoinColumn({ name: 'community_uuid', referencedColumnName: 'communityUuid' })
|
||||
users: User[]
|
||||
}
|
||||
138
database/entity/0081-user_join_community/User.ts
Normal file
138
database/entity/0081-user_join_community/User.ts
Normal file
@ -0,0 +1,138 @@
|
||||
import {
|
||||
BaseEntity,
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
DeleteDateColumn,
|
||||
OneToMany,
|
||||
JoinColumn,
|
||||
OneToOne,
|
||||
ManyToOne,
|
||||
} from 'typeorm'
|
||||
import { Contribution } from '../Contribution'
|
||||
import { ContributionMessage } from '../ContributionMessage'
|
||||
import { UserContact } from '../UserContact'
|
||||
import { UserRole } from '../UserRole'
|
||||
import { Community } from '../Community'
|
||||
|
||||
@Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' })
|
||||
export class User extends BaseEntity {
|
||||
@PrimaryGeneratedColumn('increment', { unsigned: true })
|
||||
id: number
|
||||
|
||||
@Column({ type: 'bool', default: false })
|
||||
foreign: boolean
|
||||
|
||||
@Column({
|
||||
name: 'gradido_id',
|
||||
length: 36,
|
||||
nullable: false,
|
||||
collation: 'utf8mb4_unicode_ci',
|
||||
})
|
||||
gradidoID: string
|
||||
|
||||
@Column({
|
||||
name: 'community_uuid',
|
||||
type: 'char',
|
||||
length: 36,
|
||||
nullable: true,
|
||||
collation: 'utf8mb4_unicode_ci',
|
||||
})
|
||||
communityUuid: string
|
||||
|
||||
@ManyToOne(() => Community, (community) => community.users)
|
||||
@JoinColumn({ name: 'community_uuid', referencedColumnName: 'communityUuid' })
|
||||
community: Community | null
|
||||
|
||||
@Column({
|
||||
name: 'alias',
|
||||
length: 20,
|
||||
nullable: true,
|
||||
default: null,
|
||||
collation: 'utf8mb4_unicode_ci',
|
||||
})
|
||||
alias: string
|
||||
|
||||
@OneToOne(() => UserContact, (emailContact: UserContact) => emailContact.user)
|
||||
@JoinColumn({ name: 'email_id' })
|
||||
emailContact: UserContact
|
||||
|
||||
@Column({ name: 'email_id', type: 'int', unsigned: true, nullable: true, default: null })
|
||||
emailId: number | null
|
||||
|
||||
@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({ name: 'created_at', default: () => 'CURRENT_TIMESTAMP(3)', nullable: false })
|
||||
createdAt: Date
|
||||
|
||||
@DeleteDateColumn({ name: 'deleted_at', nullable: true })
|
||||
deletedAt: Date | null
|
||||
|
||||
@Column({ type: 'bigint', default: 0, unsigned: true })
|
||||
password: BigInt
|
||||
|
||||
@Column({
|
||||
name: 'password_encryption_type',
|
||||
type: 'int',
|
||||
unsigned: true,
|
||||
nullable: false,
|
||||
default: 0,
|
||||
})
|
||||
passwordEncryptionType: number
|
||||
|
||||
@Column({ length: 4, default: 'de', collation: 'utf8mb4_unicode_ci', nullable: false })
|
||||
language: string
|
||||
|
||||
@Column({ type: 'bool', default: false })
|
||||
hideAmountGDD: boolean
|
||||
|
||||
@Column({ type: 'bool', default: false })
|
||||
hideAmountGDT: boolean
|
||||
|
||||
@OneToMany(() => UserRole, (userRole) => userRole.user)
|
||||
@JoinColumn({ name: 'user_id' })
|
||||
userRoles: UserRole[]
|
||||
|
||||
@Column({ name: 'referrer_id', type: 'int', unsigned: true, nullable: true, default: null })
|
||||
referrerId?: number | null
|
||||
|
||||
@Column({
|
||||
name: 'contribution_link_id',
|
||||
type: 'int',
|
||||
unsigned: true,
|
||||
nullable: true,
|
||||
default: null,
|
||||
})
|
||||
contributionLinkId?: number | null
|
||||
|
||||
@Column({ name: 'publisher_id', default: 0 })
|
||||
publisherId: number
|
||||
|
||||
@OneToMany(() => Contribution, (contribution) => contribution.user)
|
||||
@JoinColumn({ name: 'user_id' })
|
||||
contributions?: Contribution[]
|
||||
|
||||
@OneToMany(() => ContributionMessage, (message) => message.user)
|
||||
@JoinColumn({ name: 'user_id' })
|
||||
messages?: ContributionMessage[]
|
||||
|
||||
@OneToMany(() => UserContact, (userContact: UserContact) => userContact.user)
|
||||
@JoinColumn({ name: 'user_id' })
|
||||
userContacts?: UserContact[]
|
||||
}
|
||||
@ -1 +1 @@
|
||||
export { Community } from './0068-community_tables_public_key_length/Community'
|
||||
export { Community } from './0081-user_join_community/Community'
|
||||
|
||||
@ -1 +1 @@
|
||||
export { User } from './0073-introduce_foreign_user_in_users_table/User'
|
||||
export { User } from './0081-user_join_community/User'
|
||||
|
||||
11
database/migrations/0081-user_join_community.ts
Normal file
11
database/migrations/0081-user_join_community.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn(
|
||||
'ALTER TABLE users MODIFY community_uuid VARCHAR(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;',
|
||||
)
|
||||
}
|
||||
|
||||
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn(
|
||||
'ALTER TABLE users MODIFY community_uuid VARCHAR(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;',
|
||||
)
|
||||
}
|
||||
@ -4,7 +4,7 @@ import dotenv from 'dotenv'
|
||||
dotenv.config()
|
||||
|
||||
const constants = {
|
||||
DB_VERSION: '0080-fill_linked_user_gradidoId_of_contributions',
|
||||
DB_VERSION: '0081-user_join_community',
|
||||
LOG4JS_CONFIG: 'log4js-config.json',
|
||||
// default log level on production should be info
|
||||
LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',
|
||||
|
||||
@ -10,7 +10,7 @@ Decimal.set({
|
||||
})
|
||||
|
||||
const constants = {
|
||||
DB_VERSION: '0080-fill_linked_user_gradidoId_of_contributions',
|
||||
DB_VERSION: '0081-user_join_community',
|
||||
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
|
||||
|
||||
@ -4,7 +4,7 @@ module.exports = {
|
||||
collectCoverageFrom: ['src/**/*.{js,vue}', '!**/node_modules/**', '!**/?(*.)+(spec|test).js?(x)'],
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
lines: 95,
|
||||
lines: 94,
|
||||
},
|
||||
},
|
||||
moduleFileExtensions: [
|
||||
|
||||
@ -1,47 +1,37 @@
|
||||
[
|
||||
{
|
||||
"locale": "de",
|
||||
"date": "30.10.2023",
|
||||
"text": "Gradido wird dezentral (Beta)",
|
||||
"url": "/send",
|
||||
"extra": "Gradido-Communities können nun ihre eigenen dezentralen Gradido-Server betreiben. Transaktionen zwischen den Servern sind möglich. Im Senden-Dialog findest Du ein Auswahl-Menü mit den verfügbaren Communities, um das Ziel für den Empfänger auszuwählen. Bitte beachte, dass diese Funktion sich noch in der Beta-Testphase befindet und die Communities erst nach und nach hinzugefügt werden.",
|
||||
"extra2": "Wenn Ihr als Community Euren eigenen Gradido-Server betreiben wollt, schreibt uns bitte eine E-Mail an ",
|
||||
"email": "support@gradido.net"
|
||||
"text": "Gradido-Kreise – Gemeinsam mit Freunden die Zukunft gestalten",
|
||||
"button": "Mehr erfahren",
|
||||
"url": "https://gradido.net/de/gradido-kreise-gemeinsam-mit-freunden-die-zukunft-gestalten",
|
||||
"extra": "Ganz gleich, ob Ihr bereits einer Gruppe zugehörig seid oder ob Ihr Euch über Gradido gefunden habt – wenn Ihr gemeinsam Gradido nutzen wollt, braucht Ihr nicht gleich einen eigenen Gradido-Server."
|
||||
},
|
||||
{
|
||||
"locale": "en",
|
||||
"date": "30.10.2023",
|
||||
"text": "Gradido becomes decentralized (Beta)",
|
||||
"url": "/send",
|
||||
"extra": "Gradido communities can now run their own decentralized Gradido servers. Transactions between the servers are possible. In the send dialog you will find a dropdown menu with the available communities to select the destination for the receiver. Please note that this feature is still in beta testing and communities will be added gradually.",
|
||||
"extra2": "If you want to run your own Gradido server as a community, please send us an email to ",
|
||||
"email": "support@gradido.net"
|
||||
"text": "Gradido circles - Shaping the future together with friends",
|
||||
"button": "Learn more",
|
||||
"url": "https://gradido.net/en/gradido-kreise-gemeinsam-mit-freunden-die-zukunft-gestalten/",
|
||||
"extra": "No matter whether you already belong to a group or whether you found each other via Gradido - if you want to use Gradido together, you don't need your own Gradido server."
|
||||
},
|
||||
{
|
||||
"locale": "fr",
|
||||
"date": "30.10.2023",
|
||||
"text": "Gradido devient décentralisé (Beta)",
|
||||
"url": "/send",
|
||||
"extra": "Les communautés Gradido peuvent désormais gérer leurs propres serveurs Gradido décentralisés. Les transactions entre les serveurs sont possibles. Dans la boîte de dialogue d'envoi, tu trouveras un menu de sélection avec les communautés disponibles pour choisir la destination du destinataire. Veuillez noter que cette fonction est encore en phase de test bêta et que les communautés ne seront ajoutées qu'au fur et à mesure.",
|
||||
"extra2": "Si vous souhaitez exploiter votre propre serveur Gradido en tant que communauté, veuillez nous envoyer un e-mail à ",
|
||||
"email": "support@gradido.net"
|
||||
"text": "Cercles Gradido - Construire l'avenir ensemble avec des amis ",
|
||||
"button": "En savoir plus",
|
||||
"url": "https://gradido.net/fr/gradido-kreise-gemeinsam-mit-freunden-die-zukunft-gestalten/",
|
||||
"extra": "Que vous fassiez déjà partie d'un groupe ou que vous vous soyez trouvés par le biais de Gradido, si vous voulez utiliser Gradido ensemble, vous n'avez pas besoin de votre propre serveur Gradido."
|
||||
},
|
||||
{
|
||||
"locale": "es",
|
||||
"date": "30.10.2023",
|
||||
"text": "Gradido se descentraliza (Beta)",
|
||||
"url": "/send",
|
||||
"extra": "Las comunidades de Gradido ya pueden gestionar sus propios servidores descentralizados de Gradido. Las transacciones entre los servidores son posibles. En el diálogo de envío encontrarás un menú desplegable con las comunidades disponibles para seleccionar el destino del destinatario. Ten en cuenta que esta función aún está en fase de pruebas beta y que las comunidades se irán añadiendo poco a poco.",
|
||||
"extra2": "Si quieres gestionar tu propio servidor Gradido como comunidad, envíanos un correo electrónico a ",
|
||||
"email": "support@gradido.net"
|
||||
"text": "Círculos Gradido - Forjar el futuro entre amigos ",
|
||||
"button": "Más información",
|
||||
"url": "https://gradido.net/es/gradido-kreise-gemeinsam-mit-freunden-die-zukunft-gestalten/",
|
||||
"extra": "No importa si ya pertenecéis a un grupo o si os habéis encontrado a través de Gradido: si queréis utilizar Gradido juntos, no necesitáis vuestro propio servidor Gradido."
|
||||
},
|
||||
{
|
||||
"locale": "nl",
|
||||
"date": "30.10.2023",
|
||||
"text": "Gradido wordt gedecentraliseerd (Beta)",
|
||||
"url": "/send",
|
||||
"extra": "Gradido-gemeenschappen kunnen nu hun eigen gedecentraliseerde Gradido-servers beheren. Transacties tussen de servers zijn mogelijk. In het verzenddialoogvenster vind je een vervolgkeuzemenu met de beschikbare communities om de bestemming voor de ontvanger te selecteren. Houd er rekening mee dat deze functie zich nog in de beta-testfase bevindt en dat de communities beetje bij beetje zullen worden toegevoegd.",
|
||||
"extra2": "Als je je eigen Gradido server als community wilt gebruiken, stuur ons dan een e-mail naar ",
|
||||
"email": "support@gradido.net"
|
||||
"text": "Gradidokringen - Samen met vrienden de toekomst vormgeven",
|
||||
"button": "Meer informatie",
|
||||
"url": "https://gradido.net/nl/gradido-kreise-gemeinsam-mit-freunden-die-zukunft-gestalten/",
|
||||
"extra": "Het maakt niet uit of je al tot een groep behoort of dat je elkaar via Gradido hebt gevonden - als je Gradido samen wilt gebruiken, heb je geen eigen Gradido-server nodig."
|
||||
}
|
||||
]
|
||||
|
||||
@ -1,16 +1,23 @@
|
||||
<template>
|
||||
<div class="community-switch">
|
||||
<b-dropdown no-flip :text="value.name">
|
||||
<b-dropdown-item
|
||||
v-for="community in communities"
|
||||
@click.prevent="updateCommunity(community)"
|
||||
:key="community.id"
|
||||
:title="community.description"
|
||||
:active="value.uuid === community.uuid"
|
||||
>
|
||||
{{ community.name }}
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
<div v-if="!validCommunityIdentifier">
|
||||
<b-dropdown no-flip :text="value.name">
|
||||
<b-dropdown-item
|
||||
v-for="community in communities"
|
||||
@click.prevent="updateCommunity(community)"
|
||||
:key="community.id"
|
||||
:title="community.description"
|
||||
:active="value.uuid === community.uuid"
|
||||
>
|
||||
{{ community.name }}
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
</div>
|
||||
<div v-else class="mb-4 mt-2">
|
||||
<b-row>
|
||||
<b-col class="font-weight-bold" :title="value.description">{{ value.name }}</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@ -26,6 +33,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
communities: [],
|
||||
validCommunityIdentifier: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -33,6 +41,27 @@ export default {
|
||||
this.$emit('input', community)
|
||||
},
|
||||
setDefaultCommunity() {
|
||||
// when we already get an identifier via url we choose this if the community exist
|
||||
if (this.communityIdentifier && this.communities.length >= 1) {
|
||||
const foundCommunity = this.communities.find((community) => {
|
||||
if (
|
||||
community.uuid === this.communityIdentifier ||
|
||||
community.name === this.communityIdentifier
|
||||
) {
|
||||
this.validCommunityIdentifier = true
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
if (foundCommunity) {
|
||||
this.updateCommunity(foundCommunity)
|
||||
return
|
||||
}
|
||||
this.toastError('invalid community identifier in url')
|
||||
}
|
||||
if (this.validCommunityIdentifier && !this.communityIdentifier) {
|
||||
this.validCommunityIdentifier = false
|
||||
}
|
||||
// set default community, the only one which isn't foreign
|
||||
// we assume it is only one entry with foreign = false
|
||||
if (this.value.uuid === '' && this.communities.length) {
|
||||
@ -48,12 +77,17 @@ export default {
|
||||
query: selectCommunities,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setDefaultCommunity()
|
||||
computed: {
|
||||
communityIdentifier() {
|
||||
return this.$route.params && this.$route.params.communityIdentifier
|
||||
},
|
||||
},
|
||||
updated() {
|
||||
this.setDefaultCommunity()
|
||||
},
|
||||
mounted() {
|
||||
this.setDefaultCommunity()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
||||
@ -4,7 +4,7 @@ import flushPromises from 'flush-promises'
|
||||
import { SEND_TYPES } from '@/pages/Send'
|
||||
import { createMockClient } from 'mock-apollo-client'
|
||||
import VueApollo from 'vue-apollo'
|
||||
import { userAndCommunity, selectCommunities as selectCommunitiesQuery } from '@/graphql/queries'
|
||||
import { user, selectCommunities as selectCommunitiesQuery } from '@/graphql/queries'
|
||||
|
||||
const mockClient = createMockClient()
|
||||
const apolloProvider = new VueApollo({
|
||||
@ -32,6 +32,9 @@ describe('TransactionForm', () => {
|
||||
params: {},
|
||||
query: {},
|
||||
},
|
||||
$router: {
|
||||
replace: jest.fn(),
|
||||
},
|
||||
}
|
||||
|
||||
const propsData = {
|
||||
@ -47,23 +50,21 @@ describe('TransactionForm', () => {
|
||||
})
|
||||
}
|
||||
|
||||
const userAndCommunityMock = jest.fn()
|
||||
const userMock = jest.fn()
|
||||
|
||||
mockClient.setRequestHandler(
|
||||
userAndCommunity,
|
||||
userAndCommunityMock
|
||||
.mockRejectedValueOnce({ message: 'Query user name fails!' })
|
||||
.mockResolvedValue({
|
||||
data: {
|
||||
user: {
|
||||
firstName: 'Bibi',
|
||||
lastName: 'Bloxberg',
|
||||
},
|
||||
community: {
|
||||
name: 'Gradido Entwicklung',
|
||||
},
|
||||
user,
|
||||
userMock.mockRejectedValueOnce({ message: 'Query user name fails!' }).mockResolvedValue({
|
||||
data: {
|
||||
user: {
|
||||
firstName: 'Bibi',
|
||||
lastName: 'Bloxberg',
|
||||
},
|
||||
}),
|
||||
community: {
|
||||
name: 'Gradido Entwicklung',
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
mockClient.setRequestHandler(
|
||||
@ -410,7 +411,8 @@ Die ganze Welt bezwingen.“`)
|
||||
describe('with gradido ID', () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
mocks.$route.query.gradidoID = 'gradido-ID'
|
||||
mocks.$route.params.userIdentifier = 'gradido-ID'
|
||||
mocks.$route.params.communityIdentifier = 'community-ID'
|
||||
wrapper = Wrapper()
|
||||
await wrapper.vm.$nextTick()
|
||||
})
|
||||
@ -421,8 +423,9 @@ Die ganze Welt bezwingen.“`)
|
||||
})
|
||||
|
||||
it('queries the username', () => {
|
||||
expect(userAndCommunityMock).toBeCalledWith({
|
||||
expect(userMock).toBeCalledWith({
|
||||
identifier: 'gradido-ID',
|
||||
communityIdentifier: 'community-ID',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -55,22 +55,15 @@
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col class="font-weight-bold">
|
||||
<div v-if="!communityUuid">
|
||||
<community-switch
|
||||
v-model="form.targetCommunity"
|
||||
:disabled="isBalanceDisabled"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="mb-4">
|
||||
<b-row>
|
||||
<b-col class="font-weight-bold">{{ recipientCommunity.name }}</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
<community-switch
|
||||
v-model="form.targetCommunity"
|
||||
:disabled="isBalanceDisabled"
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
<b-col cols="12" v-if="radioSelected === sendTypes.send">
|
||||
<div v-if="!gradidoID">
|
||||
<div v-if="!userIdentifier">
|
||||
<input-identifier
|
||||
:name="$t('form.recipient')"
|
||||
:label="$t('form.recipient')"
|
||||
@ -150,8 +143,7 @@ import InputIdentifier from '@/components/Inputs/InputIdentifier'
|
||||
import InputAmount from '@/components/Inputs/InputAmount'
|
||||
import InputTextarea from '@/components/Inputs/InputTextarea'
|
||||
import CommunitySwitch from '@/components/CommunitySwitch.vue'
|
||||
import { userAndCommunity } from '@/graphql/queries'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { user } from '@/graphql/queries'
|
||||
import { COMMUNITY_NAME } from '@/config'
|
||||
|
||||
export default {
|
||||
@ -193,11 +185,7 @@ export default {
|
||||
this.$refs.formValidator.validate()
|
||||
},
|
||||
onSubmit() {
|
||||
if (this.gradidoID) this.form.identifier = this.gradidoID
|
||||
if (this.communityUuid) {
|
||||
this.recipientCommunity.uuid = this.communityUuid
|
||||
this.form.targetCommunity = this.recipientCommunity
|
||||
}
|
||||
if (this.userIdentifier) this.form.identifier = this.userIdentifier.identifier
|
||||
this.$emit('set-transaction', {
|
||||
selected: this.radioSelected,
|
||||
identifier: this.form.identifier,
|
||||
@ -214,29 +202,23 @@ export default {
|
||||
this.form.memo = ''
|
||||
this.form.targetCommunity = { uuid: '', name: COMMUNITY_NAME }
|
||||
this.$refs.formValidator.validate()
|
||||
if (this.$route.query && !isEmpty(this.$route.query))
|
||||
this.$router.replace({ query: undefined })
|
||||
this.$router.replace('/send')
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
UserName: {
|
||||
query() {
|
||||
return userAndCommunity
|
||||
return user
|
||||
},
|
||||
fetchPolicy: 'network-only',
|
||||
variables() {
|
||||
return {
|
||||
identifier: this.gradidoID,
|
||||
communityUuid: this.communityUuid,
|
||||
}
|
||||
return this.userIdentifier
|
||||
},
|
||||
skip() {
|
||||
return !this.gradidoID
|
||||
return !this.userIdentifier
|
||||
},
|
||||
update({ user, community }) {
|
||||
update({ user }) {
|
||||
this.userName = `${user.firstName} ${user.lastName}`
|
||||
this.recipientCommunity.name = community.name
|
||||
this.recipientCommunity.uuid = this.communityUuid
|
||||
},
|
||||
error({ message }) {
|
||||
this.toastError(message)
|
||||
@ -261,11 +243,18 @@ export default {
|
||||
sendTypes() {
|
||||
return SEND_TYPES
|
||||
},
|
||||
gradidoID() {
|
||||
return this.$route.query && this.$route.query.gradidoID
|
||||
},
|
||||
communityUuid() {
|
||||
return this.$route.query && this.$route.query.communityUuid
|
||||
userIdentifier() {
|
||||
if (
|
||||
this.$route.params &&
|
||||
this.$route.params.userIdentifier &&
|
||||
this.$route.params.communityIdentifier
|
||||
) {
|
||||
return {
|
||||
identifier: this.$route.params.userIdentifier,
|
||||
communityIdentifier: this.$route.params.communityIdentifier,
|
||||
}
|
||||
}
|
||||
return null
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@ -15,16 +15,20 @@
|
||||
{{ item.extra }}
|
||||
<br />
|
||||
<br />
|
||||
{{ item.extra2 }}
|
||||
<a :href="'mailto:' + item.email">{{ item.email }}</a>
|
||||
<span v-if="item.extra2">
|
||||
{{ item.extra2 }}
|
||||
</span>
|
||||
<span v-if="item.email">
|
||||
<a :href="'mailto:' + item.email">{{ item.email }}</a>
|
||||
</span>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row class="my-5">
|
||||
<b-col cols="12">
|
||||
<div class="text-lg-right">
|
||||
<b-button variant="gradido" :to="item.url">
|
||||
{{ $t('community.startNewsButton') }}
|
||||
<b-button variant="gradido" :href="item.url" target="_blank">
|
||||
{{ item.button }}
|
||||
</b-button>
|
||||
</div>
|
||||
</b-col>
|
||||
|
||||
@ -47,7 +47,12 @@ describe('Name', () => {
|
||||
describe('with linked user', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper.setProps({
|
||||
linkedUser: { firstName: 'Bibi', lastName: 'Bloxberg', gradidoID: 'gradido-ID' },
|
||||
linkedUser: {
|
||||
firstName: 'Bibi',
|
||||
lastName: 'Bloxberg',
|
||||
gradidoID: 'gradido-ID',
|
||||
communityUuid: 'community UUID',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@ -70,10 +75,11 @@ describe('Name', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('pushes query for gradidoID', () => {
|
||||
it('pushes params for gradidoID and community UUID', () => {
|
||||
expect(routerPushMock).toBeCalledWith({
|
||||
query: {
|
||||
gradidoID: 'gradido-ID',
|
||||
params: {
|
||||
communityIdentifier: 'community UUID',
|
||||
userIdentifier: 'gradido-ID',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@ -37,9 +37,9 @@ export default {
|
||||
async tunnelEmail() {
|
||||
if (this.$route.path !== '/send') await this.$router.push({ path: '/send' })
|
||||
this.$router.push({
|
||||
query: {
|
||||
gradidoID: this.linkedUser.gradidoID,
|
||||
communityUuid: this.linkedUser.communityUuid,
|
||||
params: {
|
||||
userIdentifier: this.linkedUser.gradidoID,
|
||||
communityIdentifier: this.linkedUser.communityUuid,
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
@ -285,23 +285,10 @@ export const openCreations = gql`
|
||||
`
|
||||
|
||||
export const user = gql`
|
||||
query($identifier: String!) {
|
||||
user(identifier: $identifier) {
|
||||
firstName
|
||||
lastName
|
||||
communityName
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const userAndCommunity = gql`
|
||||
query($identifier: String!, $communityUuid: String!) {
|
||||
user(identifier: $identifier) {
|
||||
query($identifier: String!, $communityIdentifier: String!) {
|
||||
user(identifier: $identifier, communityIdentifier: $communityIdentifier) {
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
community(communityUuid: $communityUuid) {
|
||||
name
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
"moderator": "Moderator",
|
||||
"moderators": "Moderatoren",
|
||||
"myContributions": "Meine Beiträge",
|
||||
"startNewsButton": "Gradidos versenden",
|
||||
"submitContribution": "Schreiben"
|
||||
},
|
||||
"communityInfo": "Gemeinschaft Information",
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
"moderator": "Moderator",
|
||||
"moderators": "Moderators",
|
||||
"myContributions": "My contributions",
|
||||
"startNewsButton": "Send Gradidos",
|
||||
"submitContribution": "Contribute"
|
||||
},
|
||||
"communityInfo": "Community Information",
|
||||
|
||||
@ -29,6 +29,7 @@ describe('Login', () => {
|
||||
commit: mockStoreCommit,
|
||||
state: {
|
||||
publisherId: 12345,
|
||||
redirectPath: '/overview',
|
||||
},
|
||||
},
|
||||
$loading: {
|
||||
|
||||
@ -106,7 +106,7 @@ export default {
|
||||
if (this.$route.params.code) {
|
||||
this.$router.push(`/redeem/${this.$route.params.code}`)
|
||||
} else {
|
||||
this.$router.push('/overview')
|
||||
this.$router.push(this.$store.state.redirectPath)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
||||
@ -38,6 +38,7 @@ describe('Send', () => {
|
||||
},
|
||||
$route: {
|
||||
query: {},
|
||||
params: {},
|
||||
},
|
||||
$router: {
|
||||
push: routerPushMock,
|
||||
@ -175,7 +176,9 @@ describe('Send', () => {
|
||||
|
||||
describe('with gradidoID query', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$route.query.gradidoID = 'gradido-ID'
|
||||
jest.clearAllMocks()
|
||||
mocks.$route.params.userIdentifier = 'gradido-ID'
|
||||
mocks.$route.params.communityIdentifier = 'community-ID'
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
@ -226,11 +229,7 @@ describe('Send', () => {
|
||||
})
|
||||
|
||||
it('resets the gradido ID query in route', () => {
|
||||
expect(routerPushMock).toBeCalledWith({
|
||||
query: {
|
||||
gradidoID: undefined,
|
||||
},
|
||||
})
|
||||
expect(routerPushMock).toBeCalledWith('send')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -172,7 +172,7 @@ export default {
|
||||
throw new Error(`undefined transactionData.selected : ${this.transactionData.selected}`)
|
||||
}
|
||||
this.loading = false
|
||||
this.$router.push({ query: { gradidoID: undefined, communityUuid: undefined } })
|
||||
this.$router.push('send')
|
||||
},
|
||||
onBack() {
|
||||
this.currentTransactionStep = TRANSACTION_STEPS.transactionForm
|
||||
|
||||
@ -36,6 +36,8 @@ const addNavigationGuards = (router, store, apollo) => {
|
||||
// handle authentication
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (to.meta.requiresAuth && !store.state.token) {
|
||||
// store redirect path
|
||||
store.commit('redirectPath', to.path)
|
||||
next({ path: '/login' })
|
||||
} else {
|
||||
next()
|
||||
|
||||
@ -66,11 +66,11 @@ describe('router', () => {
|
||||
|
||||
describe('send', () => {
|
||||
it('requires authorization', () => {
|
||||
expect(routes.find((r) => r.path === '/send').meta.requiresAuth).toBeTruthy()
|
||||
expect(routes.find((r) => r.path.startsWith('/send')).meta.requiresAuth).toBeTruthy()
|
||||
})
|
||||
|
||||
it('loads the "Send" page', async () => {
|
||||
const component = await routes.find((r) => r.path === '/send').component()
|
||||
const component = await routes.find((r) => r.path.startsWith('/send')).component()
|
||||
expect(component.default.name).toBe('Send')
|
||||
})
|
||||
})
|
||||
|
||||
@ -19,7 +19,9 @@ const routes = [
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/send',
|
||||
// userIdentifier can be username, email or gradidoID
|
||||
// communityIdentifier can be community name or community UUID
|
||||
path: '/send/:communityIdentifier?/:userIdentifier?',
|
||||
component: () => import('@/pages/Send'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
|
||||
@ -58,6 +58,9 @@ export const mutations = {
|
||||
setDarkMode: (state, darkMode) => {
|
||||
state.darkMode = !!darkMode
|
||||
},
|
||||
redirectPath: (state, redirectPath) => {
|
||||
state.redirectPath = redirectPath || '/overview'
|
||||
},
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
@ -89,6 +92,7 @@ export const actions = {
|
||||
commit('hideAmountGDT', true)
|
||||
commit('email', '')
|
||||
commit('setDarkMode', false)
|
||||
commit('redirectPath', '/overview')
|
||||
localStorage.clear()
|
||||
},
|
||||
}
|
||||
@ -119,6 +123,7 @@ try {
|
||||
hideAmountGDT: null,
|
||||
email: '',
|
||||
darkMode: false,
|
||||
redirectPath: '/overview',
|
||||
},
|
||||
getters: {},
|
||||
// Syncronous mutation of the state
|
||||
|
||||
@ -264,7 +264,7 @@ describe('Vuex store', () => {
|
||||
|
||||
it('calls twelve commits', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toHaveBeenCalledTimes(13)
|
||||
expect(commit).toHaveBeenCalledTimes(14)
|
||||
})
|
||||
|
||||
it('commits token', () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user