Merge branch 'humhub_options' into humhub_export_user

This commit is contained in:
einhornimmond 2024-04-15 11:56:29 +02:00
commit b40ad3254a
47 changed files with 777 additions and 165 deletions

View File

@ -68,10 +68,11 @@ FEDERATION_XCOM_SENDCOINS_ENABLED=false
# GMS
# GMS_ACTIVE=true
# Coordinates of Illuminz test instance
#GMS_URL=http://54.176.169.179:3071
GMS_URL=http://localhost:4044/
#GMS_API_URL=http://54.176.169.179:3071
GMS_API_URL=http://localhost:4044/
GMS_DASHBOARD_URL=http://localhost:8080/
# HUMHUB
HUMHUB_ACTIVE=false
#HUMHUB_API_URL=https://community.gradido.net/
#HUMHUB_JWT_KEY=
#HUMHUB_JWT_KEY=

View File

@ -66,9 +66,13 @@ FEDERATION_XCOM_SENDCOINS_ENABLED=$FEDERATION_XCOM_SENDCOINS_ENABLED
# GMS
GMS_ACTIVE=$GMS_ACTIVE
GMS_URL=$GMS_URL
GMS_API_URL=$GMS_API_URL
GMS_DASHBOARD_URL=$GMS_DASHBOARD_URL
GMS_WEBHOOK_SECRET=$GMS_WEBHOOK_SECRET
GMS_CREATE_USER_THROW_ERRORS=$GMS_CREATE_USER_THROW_ERRORS
# HUMHUB
HUMHUB_ACTIVE=$HUMHUB_ACTIVE
HUMHUB_API_URL=$HUMHUB_API_URL
HUMHUB_JWT_KEY=$HUMHUB_JWT_KEY
HUMHUB_JWT_KEY=$HUMHUB_JWT_KEY

View File

@ -7,12 +7,13 @@ import axios from 'axios'
import { CONFIG } from '@/config'
import { LogError } from '@/server/LogError'
import { backendLogger as logger } from '@/server/logger'
import { ensureUrlEndsWithSlash } from '@/util/utilities'
import { GmsUser } from './model/GmsUser'
/*
export async function communityList(): Promise<GmsCommunity[] | string | undefined> {
const baseUrl = CONFIG.GMS_URL.endsWith('/') ? CONFIG.GMS_URL : CONFIG.GMS_URL.concat('/')
const baseUrl = ensureUrlEndsWithSlash(CONFIG.GMS_URL)
const service = 'community/list?page=1&perPage=20'
const config = {
headers: {
@ -44,7 +45,7 @@ export async function communityList(): Promise<GmsCommunity[] | string | undefin
}
export async function userList(): Promise<GmsUser[] | string | undefined> {
const baseUrl = CONFIG.GMS_URL.endsWith('/') ? CONFIG.GMS_URL : CONFIG.GMS_URL.concat('/')
const baseUrl = ensureUrlEndsWithSlash(CONFIG.GMS_URL)
const service = 'community-user/list?page=1&perPage=20'
const config = {
headers: {
@ -80,7 +81,7 @@ export async function userList(): Promise<GmsUser[] | string | undefined> {
}
export async function userByUuid(uuid: string): Promise<GmsUser[] | string | undefined> {
const baseUrl = CONFIG.GMS_URL.endsWith('/') ? CONFIG.GMS_URL : CONFIG.GMS_URL.concat('/')
const baseUrl = ensureUrlEndsWithSlash(CONFIG.GMS_URL)
const service = 'community-user/list?page=1&perPage=20'
const config = {
headers: {
@ -118,7 +119,7 @@ export async function userByUuid(uuid: string): Promise<GmsUser[] | string | und
export async function createGmsUser(apiKey: string, user: GmsUser): Promise<boolean> {
if (CONFIG.GMS_ACTIVE) {
const baseUrl = CONFIG.GMS_URL.endsWith('/') ? CONFIG.GMS_URL : CONFIG.GMS_URL.concat('/')
const baseUrl = ensureUrlEndsWithSlash(CONFIG.GMS_API_URL)
const service = 'community-user'
const config = {
headers: {
@ -152,7 +153,7 @@ export async function createGmsUser(apiKey: string, user: GmsUser): Promise<bool
export async function updateGmsUser(apiKey: string, user: GmsUser): Promise<boolean> {
if (CONFIG.GMS_ACTIVE) {
const baseUrl = CONFIG.GMS_URL.endsWith('/') ? CONFIG.GMS_URL : CONFIG.GMS_URL.concat('/')
const baseUrl = ensureUrlEndsWithSlash(CONFIG.GMS_API_URL)
const service = 'community-user'
const config = {
headers: {
@ -189,7 +190,7 @@ export async function verifyAuthToken(
communityUuid: string,
token: string,
): Promise<string> {
const baseUrl = CONFIG.GMS_URL.endsWith('/') ? CONFIG.GMS_URL : CONFIG.GMS_URL.concat('/')
const baseUrl = ensureUrlEndsWithSlash(CONFIG.GMS_API_URL)
const service = 'verify-auth-token?token='.concat(token).concat('&uuid=').concat(communityUuid)
const config = {
headers: {

View File

@ -12,14 +12,14 @@ Decimal.set({
})
const constants = {
DB_VERSION: '0083-join_community_federated_communities',
DB_VERSION: '0084-introduce_humhub_registration',
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
LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v22.2024-03-14',
EXPECTED: 'v23.2024-04-04',
CURRENT: '',
},
}
@ -145,7 +145,8 @@ const gms = {
GMS_ACTIVE: process.env.GMS_ACTIVE === 'true' || false,
GMS_CREATE_USER_THROW_ERRORS: process.env.GMS_CREATE_USER_THROW_ERRORS === 'true' || false,
// koordinates of Illuminz-instance of GMS
GMS_URL: process.env.GMS_HOST ?? 'http://localhost:4044/',
GMS_API_URL: process.env.GMS_API_URL ?? 'http://localhost:4044/',
GMS_DASHBOARD_URL: process.env.GMS_DASHBOARD_URL ?? 'http://localhost:8080/',
// used as secret postfix attached at the gms community-auth-url endpoint ('/hook/gms/' + 'secret')
GMS_WEBHOOK_SECRET: process.env.GMS_WEBHOOK_SECRET ?? 'secret',
}

View File

@ -6,6 +6,7 @@ import { CONFIG } from '@/config'
// eslint-disable-next-line camelcase
import { AuthenticationClient as V1_0_AuthenticationClient } from '@/federation/client/1_0/AuthenticationClient'
import { backendLogger as logger } from '@/server/logger'
import { ensureUrlEndsWithSlash } from '@/util/utilities'
import { OpenConnectionArgs } from './client/1_0/model/OpenConnectionArgs'
import { AuthenticationClientFactory } from './client/AuthenticationClientFactory'
@ -39,9 +40,7 @@ export async function startCommunityAuthentication(
const args = new OpenConnectionArgs()
args.publicKey = homeCom.publicKey.toString('hex')
// TODO encrypt url with foreignCom.publicKey and sign it with homeCom.privateKey
args.url = homeFedCom.endPoint.endsWith('/')
? homeFedCom.endPoint
: homeFedCom.endPoint + '/' + homeFedCom.apiVersion
args.url = ensureUrlEndsWithSlash(homeFedCom.endPoint).concat(homeFedCom.apiVersion)
logger.debug(
'Authentication: before client.openConnection() args:',
homeCom.publicKey.toString('hex'),

View File

@ -2,6 +2,7 @@ import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCom
import { GraphQLClient } from 'graphql-request'
import { backendLogger as logger } from '@/server/logger'
import { ensureUrlEndsWithSlash } from '@/util/utilities'
import { OpenConnectionArgs } from './model/OpenConnectionArgs'
import { openConnection } from './query/openConnection'
@ -13,9 +14,7 @@ export class AuthenticationClient {
constructor(dbCom: DbFederatedCommunity) {
this.dbCom = dbCom
this.endpoint = `${dbCom.endPoint.endsWith('/') ? dbCom.endPoint : dbCom.endPoint + '/'}${
dbCom.apiVersion
}/`
this.endpoint = ensureUrlEndsWithSlash(dbCom.endPoint).concat(dbCom.apiVersion).concat('/')
this.client = new GraphQLClient(this.endpoint, {
method: 'POST',
jsonSerializer: {

View File

@ -4,6 +4,7 @@ import { GraphQLClient } from 'graphql-request'
import { getPublicCommunityInfo } from '@/federation/client/1_0/query/getPublicCommunityInfo'
import { getPublicKey } from '@/federation/client/1_0/query/getPublicKey'
import { backendLogger as logger } from '@/server/logger'
import { ensureUrlEndsWithSlash } from '@/util/utilities'
import { PublicCommunityInfoLoggingView } from './logging/PublicCommunityInfoLogging.view'
import { GetPublicKeyResult } from './model/GetPublicKeyResult'
@ -16,9 +17,7 @@ export class FederationClient {
constructor(dbCom: DbFederatedCommunity) {
this.dbCom = dbCom
this.endpoint = `${dbCom.endPoint.endsWith('/') ? dbCom.endPoint : dbCom.endPoint + '/'}${
dbCom.apiVersion
}/`
this.endpoint = ensureUrlEndsWithSlash(dbCom.endPoint).concat(dbCom.apiVersion).concat('/')
this.client = new GraphQLClient(this.endpoint, {
method: 'GET',
jsonSerializer: {

View File

@ -3,6 +3,7 @@ import { GraphQLClient } from 'graphql-request'
import { LogError } from '@/server/LogError'
import { backendLogger as logger } from '@/server/logger'
import { ensureUrlEndsWithSlash } from '@/util/utilities'
import { SendCoinsArgsLoggingView } from './logging/SendCoinsArgsLogging.view'
import { SendCoinsResultLoggingView } from './logging/SendCoinsResultLogging.view'
@ -20,9 +21,7 @@ export class SendCoinsClient {
constructor(dbCom: DbFederatedCommunity) {
this.dbCom = dbCom
this.endpoint = `${dbCom.endPoint.endsWith('/') ? dbCom.endPoint : dbCom.endPoint + '/'}${
dbCom.apiVersion
}/`
this.endpoint = ensureUrlEndsWithSlash(dbCom.endPoint).concat(dbCom.apiVersion).concat('/')
this.client = new GraphQLClient(this.endpoint, {
method: 'POST',
jsonSerializer: {

View File

@ -5,6 +5,7 @@ import { FederationClient as V1_0_FederationClient } from '@/federation/client/1
// eslint-disable-next-line camelcase
import { FederationClient as V1_1_FederationClient } from '@/federation/client/1_1/FederationClient'
import { ApiVersionType } from '@/federation/enum/apiVersionType'
import { ensureUrlEndsWithSlash } from '@/util/utilities'
// eslint-disable-next-line camelcase
type FederationClient = V1_0_FederationClient | V1_1_FederationClient
@ -47,10 +48,7 @@ export class FederationClientFactory {
const instance = FederationClientFactory.instanceArray.find(
(instance) => instance.id === dbCom.id,
)
// TODO: found a way to prevent double code with FederationClient::constructor
const endpoint = `${dbCom.endPoint.endsWith('/') ? dbCom.endPoint : dbCom.endPoint + '/'}${
dbCom.apiVersion
}/`
const endpoint = ensureUrlEndsWithSlash(dbCom.endPoint).concat(dbCom.apiVersion)
// check if endpoint is still the same and not changed meanwhile
if (instance && instance.client.getEndpoint() === endpoint) {
return instance.client

View File

@ -46,6 +46,10 @@ export class UpdateUserInfosArgs {
@IsBoolean()
hideAmountGDT?: boolean
@Field({ nullable: true })
@IsBoolean()
humhubAllowed?: boolean
@Field({ nullable: true })
@IsBoolean()
gmsAllowed?: boolean
@ -54,6 +58,10 @@ export class UpdateUserInfosArgs {
@IsEnum(GmsPublishNameType)
gmsPublishName?: GmsPublishNameType | null
@Field(() => GmsPublishNameType, { nullable: true })
@IsEnum(GmsPublishNameType)
humhubPublishName?: GmsPublishNameType | null
@Field(() => Location, { nullable: true })
@isValidLocation()
gmsLocation?: Location | null

View File

@ -1,6 +1,8 @@
import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCommunity'
import { ObjectType, Field, Int } from 'type-graphql'
import { ensureUrlEndsWithSlash } from '@/util/utilities'
@ObjectType()
export class FederatedCommunity {
constructor(dbCom: DbFederatedCommunity) {
@ -8,7 +10,7 @@ export class FederatedCommunity {
this.foreign = dbCom.foreign
this.publicKey = dbCom.publicKey.toString('hex')
this.apiVersion = dbCom.apiVersion
this.endPoint = dbCom.endPoint.endsWith('/') ? dbCom.endPoint : dbCom.endPoint + '/'
this.endPoint = ensureUrlEndsWithSlash(dbCom.endPoint)
this.lastAnnouncedAt = dbCom.lastAnnouncedAt
this.verifiedAt = dbCom.verifiedAt
this.lastErrorAt = dbCom.lastErrorAt

View File

@ -32,8 +32,10 @@ export class User {
this.hasElopage = null
this.hideAmountGDD = user.hideAmountGDD
this.hideAmountGDT = user.hideAmountGDT
this.humhubAllowed = user.humhubAllowed
this.gmsAllowed = user.gmsAllowed
this.gmsPublishName = user.gmsPublishName
this.humhubPublishName = user.humhubPublishName
this.gmsPublishLocation = user.gmsPublishLocation
}
}
@ -80,12 +82,18 @@ export class User {
@Field(() => Boolean)
hideAmountGDT: boolean
@Field(() => Boolean)
humhubAllowed: boolean
@Field(() => Boolean)
gmsAllowed: boolean
@Field(() => GmsPublishNameType, { nullable: true })
gmsPublishName: GmsPublishNameType | null
@Field(() => GmsPublishNameType, { nullable: true })
humhubPublishName: GmsPublishNameType | null
@Field(() => GmsPublishLocationType, { nullable: true })
gmsPublishLocation: GmsPublishLocationType | null

View File

@ -183,7 +183,9 @@ describe('UserResolver', () => {
communityUuid: homeCom.communityUuid,
foreign: false,
gmsAllowed: true,
humhubAllowed: false,
gmsPublishName: 0,
humhubPublishName: 0,
gmsPublishLocation: 2,
location: null,
gmsRegistered: false,

View File

@ -394,8 +394,8 @@ export class UserResolver {
logger.addContext('user', 'unknown')
logger.info(`forgotPassword(${email})...`)
email = email.trim().toLowerCase()
const user = await findUserByEmail(email).catch(() => {
logger.warn(`fail on find UserContact per ${email}`)
const user = await findUserByEmail(email).catch((error) => {
logger.warn(`fail on find UserContact per ${email} because: ${error}`)
})
if (!user || user.deletedAt) {
@ -559,8 +559,10 @@ export class UserResolver {
passwordNew,
hideAmountGDD,
hideAmountGDT,
humhubAllowed,
gmsAllowed,
gmsPublishName,
humhubPublishName,
gmsLocation,
gmsPublishLocation,
} = updateUserInfosArgs
@ -617,12 +619,18 @@ export class UserResolver {
if (hideAmountGDT !== undefined) {
user.hideAmountGDT = hideAmountGDT
}
if (humhubAllowed !== undefined) {
user.humhubAllowed = humhubAllowed
}
if (gmsAllowed !== undefined) {
user.gmsAllowed = gmsAllowed
}
if (gmsPublishName !== null && gmsPublishName !== undefined) {
user.gmsPublishName = gmsPublishName
}
if (humhubPublishName !== null && humhubPublishName !== undefined) {
user.humhubPublishName = humhubPublishName
}
if (gmsLocation) {
user.location = Location2Point(gmsLocation)
}

View File

@ -4,13 +4,16 @@ import { verifyAuthToken } from '@/apis/gms/GmsClient'
import { CONFIG } from '@/config'
import { GmsUserAuthenticationResult } from '@/graphql/model/GmsUserAuthenticationResult'
import { backendLogger as logger } from '@/server/logger'
import { ensureUrlEndsWithSlash } from '@/util/utilities'
export async function authenticateGmsUserPlayground(
token: string,
dbUser: DbUser,
): Promise<GmsUserAuthenticationResult> {
const result = new GmsUserAuthenticationResult()
result.url = CONFIG.GMS_URL.concat('/playground')
const dashboardUrl = ensureUrlEndsWithSlash(CONFIG.GMS_DASHBOARD_URL)
result.url = dashboardUrl.concat('playground')
result.token = await verifyAuthToken(dbUser.communityUuid, token)
logger.info('GmsUserAuthenticationResult:', result)
return result

View File

@ -52,7 +52,9 @@ const communityDbUser: dbUser = {
communityUuid: '55555555-4444-4333-2222-11111111',
community: null,
gmsPublishName: 0,
humhubPublishName: 0,
gmsAllowed: false,
humhubAllowed: false,
location: null,
gmsPublishLocation: 2,
gmsRegistered: false,

View File

@ -29,3 +29,7 @@ export function resetInterface<T extends Record<string, any>>(obj: T): T {
}
return obj
}
export const ensureUrlEndsWithSlash = (url: string): string => {
return url.endsWith('/') ? url : url.concat('/')
}

View File

@ -0,0 +1,176 @@
import {
BaseEntity,
Entity,
PrimaryGeneratedColumn,
Column,
DeleteDateColumn,
OneToMany,
JoinColumn,
OneToOne,
Geometry,
ManyToOne,
} from 'typeorm'
import { Contribution } from '../Contribution'
import { ContributionMessage } from '../ContributionMessage'
import { UserContact } from '../UserContact'
import { UserRole } from '../UserRole'
import { GeometryTransformer } from '../../src/typeorm/GeometryTransformer'
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: 'gms_publish_name', type: 'int', unsigned: true, nullable: false, default: 0 })
gmsPublishName: number
@Column({ name: 'humhub_publish_name', type: 'int', unsigned: true, nullable: false, default: 0 })
humhubPublishName: number
@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
@Column({ name: 'gms_allowed', type: 'bool', default: true })
gmsAllowed: boolean
@Column({
name: 'location',
type: 'geometry',
default: null,
nullable: true,
transformer: GeometryTransformer,
})
location: Geometry | null
@Column({
name: 'gms_publish_location',
type: 'int',
unsigned: true,
nullable: false,
default: 2,
})
gmsPublishLocation: number
@Column({ name: 'gms_registered', type: 'bool', default: false })
gmsRegistered: boolean
@Column({ name: 'gms_registered_at', type: 'datetime', default: null, nullable: true })
gmsRegisteredAt: Date | null
@Column({ name: 'humhub_allowed', type: 'bool', default: false })
humhubAllowed: boolean
@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[]
}

View File

@ -1 +1 @@
export { User } from './0082-introduce_gms_registration/User'
export { User } from './0084-introduce_humhub_registration/User'

View File

@ -0,0 +1,16 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(
'ALTER TABLE `users` ADD COLUMN IF NOT EXISTS `humhub_allowed` tinyint(1) NOT NULL DEFAULT 0 AFTER `gms_registered_at`;',
)
await queryFn(
'ALTER TABLE `users` ADD COLUMN IF NOT EXISTS `humhub_publish_name` int unsigned NOT NULL DEFAULT 0 AFTER `gms_publish_name`;',
)
}
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn('ALTER TABLE `users` DROP COLUMN IF EXISTS `humhub_allowed`;')
await queryFn('ALTER TABLE `users` DROP COLUMN IF EXISTS `humhub_publish_name`;')
}

View File

@ -122,11 +122,13 @@ WEBHOOK_ELOPAGE_SECRET=secret
# GMS
GMS_ACTIVE=false
# Coordinates of Illuminz test instance
#GMS_URL=http://54.176.169.179:3071
GMS_URL=http://localhost:4044/
#GMS_API_URL=http://54.176.169.179:3071
GMS_API_URL=http://localhost:4044/
GMS_DASHBOARD_URL=http://localhost:8080/
GMS_WEBHOOK_SECRET=secret
GMS_CREATE_USER_THROW_ERRORS=false
# HUMHUB
HUMHUB_ACTIVE=false
#HUMHUB_API_URL=https://community.gradido.net
#HUMHUB_JWT_KEY=

View File

@ -4,7 +4,7 @@ import dotenv from 'dotenv'
dotenv.config()
const constants = {
DB_VERSION: '0083-join_community_federated_communities',
DB_VERSION: '0084-introduce_humhub_registration',
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info
LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',

View File

@ -10,7 +10,7 @@ Decimal.set({
})
const constants = {
DB_VERSION: '0083-join_community_federated_communities',
DB_VERSION: '0084-introduce_humhub_registration',
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

View File

@ -23,3 +23,4 @@ META_KEYWORDS_EN="Basic Income, Currency, Gratitude, Gift Economy, Natural Econo
META_AUTHOR="Bernd Hückstädt - Gradido-Akademie"
GMS_ACTIVE=false
HUMHUB_ACTIVE=false

View File

@ -25,4 +25,5 @@ META_KEYWORDS_DE=$META_KEYWORDS_DE
META_KEYWORDS_EN=$META_KEYWORDS_EN
META_AUTHOR=$META_AUTHOR
GMS_ACTIVE=$GMS_ACTIVE
GMS_ACTIVE=$GMS_ACTIVE
HUMHUB_ACTIVE=$HUMHUB_ACTIVE

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -34,7 +34,7 @@ describe('Sidebar', () => {
describe('the genaral section', () => {
it('has six nav-items', () => {
expect(wrapper.findAll('ul').at(0).findAll('.nav-item')).toHaveLength(6)
expect(wrapper.findAll('ul').at(0).findAll('.nav-item')).toHaveLength(7)
})
it('has nav-item "navigation.overview" in navbar', () => {
@ -60,6 +60,10 @@ describe('Sidebar', () => {
it('has nav-item "navigation.info" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(5).text()).toContain('navigation.info')
})
it('has nav-item "usersearch" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(6).text()).toContain('navigation.usersearch')
})
})
describe('the specific section', () => {

View File

@ -28,10 +28,14 @@
<b-icon icon="layers" aria-hidden="true"></b-icon>
<span class="ml-2">{{ $t('GDT') }}</span>
</b-nav-item>
<b-nav-item to="/information" active-class="activeRoute">
<b-nav-item to="/information" class="mb-3" active-class="activeRoute">
<b-img src="/img/svg/info.svg" height="20" class="svg-icon" />
<span class="ml-2">{{ $t('navigation.info') }}</span>
</b-nav-item>
<b-nav-item to="/usersearch" active-class="activeRoute">
<b-img src="/img/loupe.png" height="20" />
<span class="ml-2">{{ $t('navigation.usersearch') }}</span>
</b-nav-item>
</b-nav>
<hr class="m-3" />
<b-nav vertical class="w-100">

View File

@ -1,45 +0,0 @@
<template>
<div class="form-user-gms-switch">
<b-form-checkbox
test="BFormCheckbox"
v-model="gmsAllowed"
name="check-button"
switch
@change="onChange"
></b-form-checkbox>
</div>
</template>
<script>
import { updateUserInfos } from '@/graphql/mutations'
export default {
name: 'UserGMSSwitch',
data() {
return {
gmsAllowed: this.$store.state.gmsAllowed,
}
},
methods: {
async onChange() {
this.$apollo
.mutate({
mutation: updateUserInfos,
variables: {
gmsAllowed: this.gmsAllowed,
},
})
.then(() => {
this.$store.commit('gmsAllowed', this.gmsAllowed)
this.$emit('gmsAllowed', this.gmsAllowed)
this.toastSuccess(
this.gmsAllowed ? this.$t('settings.GMS.enabled') : this.$t('settings.GMS.disabled'),
)
})
.catch((error) => {
this.gmsAllowed = this.$store.state.gmsAllowed
this.toastError(error.message)
})
},
},
}
</script>

View File

@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils'
import UserGMSNamingFormat from './UserGMSNamingFormat.vue'
import UserNamingFormat from './UserNamingFormat.vue'
import { toastErrorSpy } from '@test/testSetup'
const mockAPIcall = jest.fn()
@ -8,10 +8,10 @@ const storeCommitMock = jest.fn()
const localVue = global.localVue
describe('UserGMSNamingFormat', () => {
describe('UserNamingFormat', () => {
let wrapper
beforeEach(() => {
wrapper = mount(UserGMSNamingFormat, {
wrapper = mount(UserNamingFormat, {
mocks: {
$t: (key) => key, // Mocking the translation function
$store: {
@ -27,6 +27,9 @@ describe('UserGMSNamingFormat', () => {
localVue,
propsData: {
selectedOption: 'GMS_PUBLISH_NAME_ALIAS_OR_INITALS',
initialValue: 'GMS_PUBLISH_NAME_ALIAS_OR_INITALS',
attrName: 'gmsPublishName',
successMessage: 'success message',
},
})
})
@ -53,16 +56,16 @@ describe('UserGMSNamingFormat', () => {
const dropdownItem = wrapper.findAll('.dropdown-item').at(3) // Click the fourth item
await dropdownItem.trigger('click')
expect(wrapper.emitted().gmsPublishName).toBeTruthy()
expect(wrapper.emitted().gmsPublishName.length).toBe(1)
expect(wrapper.emitted().gmsPublishName[0]).toEqual(['GMS_PUBLISH_NAME_FIRST_INITIAL'])
expect(wrapper.emitted().valueChanged).toBeTruthy()
expect(wrapper.emitted().valueChanged.length).toBe(1)
expect(wrapper.emitted().valueChanged[0]).toEqual(['GMS_PUBLISH_NAME_FIRST_INITIAL'])
})
it('does not update when clicking on already selected option', async () => {
const dropdownItem = wrapper.findAll('.dropdown-item').at(0) // Click the first item (which is already selected)
await dropdownItem.trigger('click')
expect(wrapper.emitted().gmsPublishName).toBeFalsy()
expect(wrapper.emitted().valueChanged).toBeFalsy()
})
describe('update with error', () => {

View File

@ -1,5 +1,5 @@
<template>
<div class="user-gms-naming-format">
<div class="user-naming-format">
<b-dropdown v-model="selectedOption">
<template slot="button-content">{{ selectedOptionLabel }}</template>
<b-dropdown-item
@ -18,10 +18,15 @@
import { updateUserInfos } from '@/graphql/mutations'
export default {
name: 'UserGMSNamingFormat',
name: 'UserNamingFormat',
props: {
initialValue: { type: String, default: 'GMS_PUBLISH_NAME_ALIAS_OR_INITALS' },
attrName: { type: String },
successMessage: { type: String },
},
data() {
return {
selectedOption: this.$store.state.gmsPublishName ?? 'GMS_PUBLISH_NAME_ALIAS_OR_INITALS',
selectedOption: this.initialValue,
dropdownOptions: [
{
label: this.$t('settings.GMS.publish-name.alias-or-initials'),
@ -62,16 +67,16 @@ export default {
return
}
try {
const variables = []
variables[this.attrName] = option.value
await this.$apollo.mutate({
mutation: updateUserInfos,
variables: {
gmsPublishName: option.value,
},
variables,
})
this.toastSuccess(this.$t('settings.GMS.publish-name.updated'))
this.toastSuccess(this.successMessage)
this.selectedOption = option.value
this.$store.commit('gmsPublishName', option.value)
this.$emit('gmsPublishName', option.value)
this.$store.commit(this.attrName, option.value)
this.$emit('valueChanged', option.value)
} catch (error) {
this.toastError(error.message)
}
@ -80,8 +85,8 @@ export default {
}
</script>
<style>
.user-gms-naming-format > .dropdown,
.user-gms-naming-format > .dropdown > .dropdown-toggle > ul.dropdown-menu {
.user-naming-format > .dropdown,
.user-naming-format > .dropdown > .dropdown-toggle > ul.dropdown-menu {
width: 100%;
}
</style>

View File

@ -0,0 +1,50 @@
<template>
<div class="form-user-switch">
<b-form-checkbox
test="BFormCheckbox"
v-model="value"
name="check-button"
switch
@change="onChange"
></b-form-checkbox>
</div>
</template>
<script>
import { updateUserInfos } from '@/graphql/mutations'
export default {
name: 'UserSettingsSwitch',
props: {
initialValue: { type: Boolean, default: false },
attrName: { type: String },
enabledText: { type: String },
disabledText: { type: String },
},
data() {
return {
value: this.initialValue,
}
},
methods: {
async onChange() {
const variables = []
variables[this.attrName] = this.value
this.$apollo
.mutate({
mutation: updateUserInfos,
variables,
})
.then(() => {
this.$store.commit(this.attrName, this.value)
this.$emit('valueChanged', this.value)
this.toastSuccess(this.value ? this.enabledText : this.disabledText)
})
.catch((error) => {
this.value = this.initialValue
this.toastError(error.message)
})
},
},
}
</script>

View File

@ -22,6 +22,7 @@ const version = {
const features = {
GMS_ACTIVE: process.env.GMS_ACTIVE ?? false,
HUMHUB_ACTIVE: process.env.HUMHUB_ACTIVE ?? false,
}
const environment = {

View File

@ -35,7 +35,9 @@ export const updateUserInfos = gql`
$hideAmountGDD: Boolean
$hideAmountGDT: Boolean
$gmsAllowed: Boolean
$humhubAllowed: Boolean
$gmsPublishName: GmsPublishNameType
$humhubPublishName: GmsPublishNameType
$gmsLocation: Location
$gmsPublishLocation: GmsPublishLocationType
) {
@ -49,7 +51,9 @@ export const updateUserInfos = gql`
hideAmountGDD: $hideAmountGDD
hideAmountGDT: $hideAmountGDT
gmsAllowed: $gmsAllowed
humhubAllowed: $humhubAllowed
gmsPublishName: $gmsPublishName
humhubPublishName: $humhubPublishName
gmsLocation: $gmsLocation
gmsPublishLocation: $gmsPublishLocation
)
@ -173,7 +177,9 @@ export const login = gql`
newsletterState
}
gmsAllowed
humhubAllowed
gmsPublishName
humhubPublishName
gmsPublishLocation
hasElopage
publisherId

View File

@ -19,6 +19,14 @@ export const verifyLogin = gql`
}
}
`
export const authenticateGmsUserSearch = gql`
query {
authenticateGmsUserSearch {
url
token
}
}
`
export const transactionsQuery = gql`
query($currentPage: Int = 1, $pageSize: Int = 25, $order: Order = DESC) {

View File

@ -9,6 +9,7 @@
"GDD": "GDD",
"GDT": "GDT",
"GMS": "Gradido Karte",
"Humhub": "Gradido Community",
"PersonalDetails": "Persönliche Angaben",
"advanced-calculation": "Vorausberechnung",
"asterisks": "****",
@ -268,7 +269,8 @@
"send": "Senden",
"settings": "Einstellung",
"support": "Support",
"transactions": "Transaktionen"
"transactions": "Transaktionen",
"usersearch": "Nutzersuche"
},
"openHours": "Offene Stunden",
"pageTitle": {
@ -278,7 +280,8 @@
"overview": "Willkommen {name}",
"send": "Sende Gradidos",
"settings": "Einstellungen",
"transactions": "Deine Transaktionen"
"transactions": "Deine Transaktionen",
"usersearch": "Geografische Nutzersuche"
},
"qrCode": "QR Code",
"send_gdd": "GDD versenden",
@ -324,6 +327,16 @@
},
"hideAmountGDD": "Dein GDD Betrag ist versteckt.",
"hideAmountGDT": "Dein GDT Betrag ist versteckt.",
"humhub": {
"disabled": "Daten werden nicht in die Gradido Community exportiert",
"enabled": "Daten werden in die Gradido Community exportiert",
"export-consequences": "In der Gradido Community können dich alle Benutzer mit deinem Vor- und Nachnamen finden.",
"naming-format": "Namensformat in der Gradido Community",
"publish-name": {
"updated": "Namensformat für die Gradido Community aktualisiert."
},
"switch": "Erlaubnis Daten in die Gradido Community zu exportieren."
},
"info": "Transaktionen können nun per Benutzername oder E-Mail-Adresse getätigt werden.",
"language": {
"changeLanguage": "Sprache ändern",
@ -411,6 +424,11 @@
"transaction-link": {
"send_you": "sendet dir"
},
"usersearch": {
"headline": "Geografische Nutzersuche",
"text": "Ganz gleich zu welcher Community du gehörst, mit dem Geo Matching System findest du Mitglieder aller Communities auf einer Landkarte. Du kannst nach Angeboten und Bedürfnissen filtern und dir die Nutzer anzeigen lassen, die zu Dir passen.\n\nMit dem Button wird ein neues Browser-Fenster geöffnet, in dem dir die Nutzer in deinem Umfeld auf einer Karte angezeigt werden.",
"button": "Starte die Nutzersuche..."
},
"via_link": "über einen Link",
"welcome": "Willkommen in der Gemeinschaft"
}

View File

@ -9,6 +9,7 @@
"GDD": "GDD",
"GDT": "GDT",
"GMS": "Gradido Map",
"Humhub": "Gradido Community",
"PersonalDetails": "Personal details",
"advanced-calculation": "Advanced calculation",
"asterisks": "****",
@ -268,7 +269,8 @@
"send": "Send",
"settings": "Settings",
"support": "Support",
"transactions": "Transactions"
"transactions": "Transactions",
"usersearch": "Geographical User Search"
},
"openHours": "Open Hours",
"pageTitle": {
@ -278,7 +280,8 @@
"overview": "Welcome {name}",
"send": "Send Gradidos",
"settings": "Settings",
"transactions": "Your transactions"
"transactions": "Your transactions",
"usersearch": "Geographical User Search"
},
"qrCode": "QR Code",
"send_gdd": "Send GDD",
@ -324,6 +327,16 @@
},
"hideAmountGDD": "Your GDD amount is hidden.",
"hideAmountGDT": "Your GDT amount is hidden.",
"humhub": {
"disabled": "Data not exported into the Gradido Community",
"enabled": "Data exported into the Gradido Community",
"export-consequences": "In the Gradido Community, all users can find you by your first and last name.",
"naming-format": "Format of name in the Gradido Community",
"publish-name": {
"updated": "Format of name for the Gradido Community updated."
},
"switch": "Allow data export into the Gradido Community."
},
"info": "Transactions can now be made by username or email address.",
"language": {
"changeLanguage": "Change language",
@ -411,6 +424,11 @@
"transaction-link": {
"send_you": "wants to send you"
},
"usersearch": {
"headline": "Geographical User Search",
"text": "No matter which community you belong to, with the Geo Matching System you can find members of all communities on a map. You can filter according to offers and needs and display the users that match you.\n\nThe button opens a new browser window in which the users in your area are displayed on a map.",
"button": "Start user search... "
},
"via_link": "via Link",
"welcome": "Welcome to the community"
}

View File

@ -242,7 +242,19 @@
"profile": "Mi Perfil",
"send": "Enviar",
"support": "Soporte",
"transactions": "Transacciones"
"transactions": "Transacciones",
"usersearch": "Buscar usuarios"
},
"openHours": "Open Hours",
"pageTitle": {
"community": "Create Gradido",
"gdt": "Tu GDT Transacciones",
"information": "{community}",
"overview": "Welcome {name}",
"send": "Enviar Gradidos",
"settings": "Soporte",
"transactions": "Tu Transacciones",
"usersearch": "Búsqueda geográfica de usuarios"
},
"qrCode": "Código QR",
"send_gdd": "Enviar GDD",
@ -334,6 +346,11 @@
"transaction-link": {
"send_you": "te envía"
},
"usersearch": {
"headline": "Búsqueda geográfica de usuarios",
"text": "No importa a qué comunidad pertenezcas, con el Geo Matching System puedes encontrar miembros de todas las comunidades en un mapa. Puedes filtrar según ofertas y requisitos y visualizar los usuarios que coinciden con tu perfil.\n\nEl botón abre una nueva ventana del navegador en la que se muestran en un mapa los usuarios de tu zona.",
"button": "Iniciar la búsqueda de usuarios..."
},
"via_link": "atraves de un enlace",
"welcome": "Bienvenido a la comunidad."
}

View File

@ -250,7 +250,8 @@
"send": "Envoyer",
"settings": "Configuration",
"support": "Aide",
"transactions": "Transactions"
"transactions": "Transactions",
"usersearch": "Recherche d'utilisateurs"
},
"openHours": "Heures ouverte",
"pageTitle": {
@ -260,7 +261,8 @@
"overview": "Bienvenue {name}",
"send": "Envoyé Gradidos",
"settings": "Configuration",
"transactions": "Vos transactions"
"transactions": "Vos transactions",
"usersearch": "Recherche géographique d'utilisateurs"
},
"qrCode": "QR Code",
"send_gdd": "Envoyer GDD",
@ -352,6 +354,11 @@
"transaction-link": {
"send_you": "veut vous envoyer"
},
"usersearch": {
"headline": "Recherche géographique d'utilisateurs",
"text": "Quelle que soit la communauté à laquelle tu appartiens, le système de géo-matching te permet de trouver des membres de toutes les communautés sur une carte géographique. Tu peux filtrer selon les offres et les besoins et afficher les utilisateurs qui te correspondent.\n\nEn cliquant sur le bouton, une nouvelle fenêtre de navigateur s'ouvre et t'affiche les utilisateurs de ton entourage sur une carte.",
"button": "Commence la recherche d'utilisateurs..."
},
"via_link": "par lien",
"welcome": "Bienvenu dans la communauté"
}

View File

@ -242,7 +242,19 @@
"profile": "Mijn profiel",
"send": "Sturen",
"support": "Support",
"transactions": "Transacties"
"transactions": "Transacties",
"usersearch": "Gebruiker zoeken"
},
"openHours": "Open Hours",
"pageTitle": {
"community": "Create Gradido",
"gdt": "Your GDT transactions",
"information": "{community}",
"overview": "Welcome {name}",
"send": "Send Gradidos",
"settings": "Settings",
"transactions": "Your transactions",
"usersearch": "Geografisch zoeken naar gebruikers"
},
"qrCode": "QR Code",
"send_gdd": "GDD sturen",
@ -334,6 +346,11 @@
"transaction-link": {
"send_you": "stuurt jou"
},
"usersearch": {
"headline": "Geografisch zoeken naar gebruikers",
"text": "Het maakt niet uit tot welke community je behoort, met het Geo Matching System kun je leden van alle communities vinden op een kaart. Je kunt filteren op aanbiedingen en vereisten en de gebruikers weergeven die aan je profiel voldoen.\n\nDe knop opent een nieuw browservenster waarin de gebruikers in je omgeving op een kaart worden weergegeven.",
"button": "Start het zoeken naar gebruikers..."
},
"via_link": "via een link",
"welcome": "Welkom in de gemeenschap"
}

View File

@ -79,44 +79,91 @@
</b-col>
</b-row>
</b-tab>
<div v-if="isGMS">
<div v-if="isExternService">
<b-tab :title="$t('ExternServices')">
<div class="h2">{{ $t('ExternServices') }}</div>
<div class="h3">{{ $t('GMS') }}</div>
<b-row class="mb-3">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.switch') }}
<div class="text-small">
{{ gmsAllowed ? $t('settings.GMS.enabled') : $t('settings.GMS.disabled') }}
</div>
</b-col>
<b-col cols="12" md="6" lg="6" class="text-right">
<user-g-m-s-switch @gmsAllowed="gmsStateSwitch" />
</b-col>
</b-row>
<div v-if="gmsAllowed">
<b-row class="mb-4">
<div v-if="isGMS">
<div class="h3">{{ $t('GMS') }}</div>
<b-row class="mb-3">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.naming-format') }}
{{ $t('settings.GMS.switch') }}
<div class="text-small">
{{ gmsAllowed ? $t('settings.GMS.enabled') : $t('settings.GMS.disabled') }}
</div>
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-naming-format />
<b-col cols="12" md="6" lg="6" class="text-right">
<user-settings-switch
@valueChanged="gmsStateSwitch"
:initialValue="$store.state.gmsAllowed"
:attrName="'gmsAllowed'"
:enabledText="$t('settings.GMS.enabled')"
:disabledText="$t('settings.GMS.disabled')"
/>
</b-col>
</b-row>
<b-row class="mb-4">
<div v-if="gmsAllowed">
<b-row class="mb-4">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.naming-format') }}
</b-col>
<b-col cols="12" md="6" lg="6">
<user-naming-format
:initialValue="$store.state.gmsPublishName"
:attrName="'gmsPublishName'"
:successMessage="$t('settings.GMS.publish-name.updated')"
/>
</b-col>
</b-row>
<b-row class="mb-4">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.location-format') }}
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-location-format />
</b-col>
</b-row>
<b-row class="mb-5">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.location.label') }}
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-location />
</b-col>
</b-row>
</div>
</div>
<div v-if="isHumhub">
<div class="h3">{{ $t('Humhub') }}</div>
{{ $t('settings.humhub.export-consequences') }}
<b-row class="mb-3">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.location-format') }}
{{ $t('settings.humhub.switch') }}
<div class="text-small">
{{
humhubAllowed ? $t('settings.humhub.enabled') : $t('settings.humhub.disabled')
}}
</div>
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-location-format />
<b-col cols="12" md="6" lg="6" class="text-right">
<user-settings-switch
@valueChanged="humhubStateSwitch"
:initialValue="$store.state.humhubAllowed"
:attrName="'humhubAllowed'"
:enabledText="$t('settings.humhub.enabled')"
:disabledText="$t('settings.humhub.disabled')"
/>
</b-col>
</b-row>
<b-row class="mb-5">
<b-row v-if="humhubAllowed" class="mb-4">
<b-col cols="12" md="6" lg="6">
{{ $t('settings.GMS.location.label') }}
{{ $t('settings.humhub.naming-format') }}
</b-col>
<b-col cols="12" md="6" lg="6">
<user-g-m-s-location />
<user-naming-format
:initialValue="$store.state.humhubPublishName"
:attrName="'humhubPublishName'"
:successMessage="$t('settings.humhub.publish-name.updated')"
/>
</b-col>
</b-row>
</div>
@ -133,28 +180,28 @@
</div>
</template>
<script>
import UserGMSSwitch from '@/components/UserSettings/UserGMSSwitch'
import UserGMSNamingFormat from '@/components/UserSettings/UserGMSNamingFormat'
import UserNamingFormat from '@/components/UserSettings/UserNamingFormat'
import UserGMSLocationFormat from '@/components/UserSettings/UserGMSLocationFormat'
import UserGMSLocation from '@/components/UserSettings/UserGMSLocation'
import UserName from '@/components/UserSettings/UserName.vue'
import UserPassword from '@/components/UserSettings/UserPassword'
import UserLanguage from '@/components/LanguageSwitch2.vue'
import UserNewsletter from '@/components/UserSettings/UserNewsletter.vue'
import UserSettingsSwitch from '../components/UserSettings/UserSettingsSwitch.vue'
import { updateUserInfos } from '@/graphql/mutations'
import CONFIG from '../config'
export default {
name: 'Profile',
components: {
UserGMSSwitch,
UserGMSNamingFormat,
UserNamingFormat,
UserGMSLocationFormat,
UserGMSLocation,
UserName,
UserPassword,
UserLanguage,
UserNewsletter,
UserSettingsSwitch,
},
props: {
balance: { type: Number, default: 0 },
@ -163,7 +210,15 @@ export default {
data() {
const { state } = this.$store
const { darkMode, firstName, lastName, email, newsletterState, gmsAllowed } = state
const {
darkMode,
firstName,
lastName,
email,
newsletterState,
gmsAllowed,
humhubAllowed,
} = state
return {
darkMode,
@ -173,6 +228,7 @@ export default {
email,
newsletterState,
gmsAllowed,
humhubAllowed,
mutation: '',
variables: {},
}
@ -183,9 +239,15 @@ export default {
const { firstName, lastName } = this.$store.state
return firstName === this.firstName && lastName === this.lastName
},
isExternService() {
return this.isGMS || this.isHumhub
},
isGMS() {
return CONFIG.GMS_ACTIVE
},
isHumhub() {
return CONFIG.HUMHUB_ACTIVE
},
},
// TODO: watch: {
// darkMode(val) {
@ -214,6 +276,9 @@ export default {
gmsStateSwitch(eventData) {
this.gmsAllowed = eventData
},
humhubStateSwitch(eventData) {
this.humhubAllowed = eventData
},
},
}
</script>

View File

@ -0,0 +1,73 @@
import { mount } from '@vue/test-utils'
import UserSearch from './UserSearch'
import { toastErrorSpy } from '../../test/testSetup'
import { authenticateGmsUserSearch } from '@/graphql/queries'
const localVue = global.localVue
window.scrollTo = jest.fn()
const apolloQueryMock = jest
.fn()
.mockResolvedValueOnce({
data: {
authenticateGmsUserSearch: {
gmsUri: 'http://localhost:8080/playground?not initialized',
},
},
})
.mockResolvedValue('default')
describe('UserSearch', () => {
let wrapper
const mocks = {
$t: jest.fn((t) => t),
$n: jest.fn(),
$i18n: {
locale: 'en',
},
$apollo: {
query: apolloQueryMock,
},
}
const Wrapper = () => {
return mount(UserSearch, {
localVue,
mocks,
})
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders the usersearch page', () => {
expect(wrapper.find('div.usersearch').exists()).toBeTruthy()
})
it('calls authenticateGmsUserSearch', () => {
expect(apolloQueryMock).toBeCalledWith(
expect.objectContaining({
query: authenticateGmsUserSearch,
}),
)
})
describe('error apolloQueryMock', () => {
beforeEach(async () => {
jest.clearAllMocks()
apolloQueryMock.mockRejectedValue({
message: 'uups',
})
wrapper = Wrapper()
})
it('toasts an error message', () => {
expect(toastErrorSpy).toBeCalledWith('authenticateGmsUserSearch failed!')
})
})
})
})

View File

@ -0,0 +1,56 @@
<template>
<div class="usersearch">
<b-container class="bg-white appBoxShadow gradido-border-radius p-4 mt--3">
<div class="h3">{{ $t('usersearch.headline') }}</div>
<div class="my-4 text-small">
<span
v-for="(line, lineNumber) of $t('usersearch.text').split('\n')"
v-bind:key="lineNumber"
>
{{ line }}
<br />
</span>
</div>
<b-row class="my-5">
<b-col cols="12">
<div class="text-lg-right">
<b-button variant="gradido" :href="this.gmsUri" target="_blank">
{{ $t('usersearch.button') }}
</b-button>
</div>
</b-col>
</b-row>
</b-container>
</div>
</template>
<script>
import { authenticateGmsUserSearch } from '@/graphql/queries'
export default {
name: 'UserSearch',
data() {
return {
gmsUri: 'not initialized',
}
},
methods: {
async authenticateGmsUserPlayground() {
this.$apollo
.query({
query: authenticateGmsUserSearch,
})
.then(async (result) => {
this.gmsUri =
result.data.authenticateGmsUserSearch.url +
'?accesstoken=' +
result.data.authenticateGmsUserSearch.token
})
.catch(() => {
this.toastError('authenticateGmsUserSearch failed!')
})
},
},
created() {
this.authenticateGmsUserPlayground()
},
}
</script>

View File

@ -49,8 +49,8 @@ describe('router', () => {
expect(routes.find((r) => r.path === '/').redirect()).toEqual({ path: '/login' })
})
it('has 19 routes defined', () => {
expect(routes).toHaveLength(19)
it('has 20 routes defined', () => {
expect(routes).toHaveLength(20)
})
describe('overview', () => {
@ -142,6 +142,17 @@ describe('router', () => {
})
})
describe('usersearch', () => {
it('requires authorization', () => {
expect(routes.find((r) => r.path === '/usersearch').meta.requiresAuth).toBeTruthy()
})
it('loads the "UserSearch" page', async () => {
const component = await routes.find((r) => r.path === '/usersearch').component()
expect(component.default.name).toBe('UserSearch')
})
})
describe('gdt', () => {
it('requires authorization', () => {
expect(routes.find((r) => r.path === '/gdt').meta.requiresAuth).toBeTruthy()

View File

@ -80,6 +80,14 @@ const routes = [
pageTitle: 'information',
},
},
{
path: '/usersearch',
component: () => import('@/pages/UserSearch'),
meta: {
requiresAuth: true,
pageTitle: 'usersearch',
},
},
// {
// path: '/storys',
// component: () => import('@/pages/TopStorys'),

View File

@ -38,9 +38,15 @@ export const mutations = {
gmsAllowed: (state, gmsAllowed) => {
state.gmsAllowed = gmsAllowed
},
humhubAllowed: (state, humhubAllowed) => {
state.humhubAllowed = humhubAllowed
},
gmsPublishName: (state, gmsPublishName) => {
state.gmsPublishName = gmsPublishName
},
humhubPublishName: (state, humhubPublishName) => {
state.humhubPublishName = humhubPublishName
},
gmsPublishLocation: (state, gmsPublishLocation) => {
state.gmsPublishLocation = gmsPublishLocation
},
@ -81,7 +87,9 @@ export const actions = {
commit('lastName', data.lastName)
commit('newsletterState', data.klickTipp.newsletterState)
commit('gmsAllowed', data.gmsAllowed)
commit('humhubAllowed', data.humhubAllowed)
commit('gmsPublishName', data.gmsPublishName)
commit('humhubPublishName', data.humhubPublishName)
commit('gmsPublishLocation', data.gmsPublishLocation)
commit('hasElopage', data.hasElopage)
commit('publisherId', data.publisherId)
@ -98,7 +106,9 @@ export const actions = {
commit('lastName', '')
commit('newsletterState', null)
commit('gmsAllowed', null)
commit('humhubAllowed', null)
commit('gmsPublishName', null)
commit('humhubPublishName', null)
commit('gmsPublishLocation', null)
commit('hasElopage', false)
commit('publisherId', null)
@ -133,7 +143,9 @@ try {
roles: [],
newsletterState: null,
gmsAllowed: null,
humhubAllowed: null,
gmsPublishName: null,
humhubPublishName: null,
gmsPublishLocation: null,
hasElopage: false,
publisherId: null,

View File

@ -29,7 +29,9 @@ const {
username,
newsletterState,
gmsAllowed,
humhubAllowed,
gmsPublishName,
humhubPublishName,
gmsPublishLocation,
publisherId,
roles,
@ -133,6 +135,14 @@ describe('Vuex store', () => {
})
})
describe('humhubAllowed', () => {
it('sets the state of humhubAllowed', () => {
const state = { humhubAllowed: null }
humhubAllowed(state, true)
expect(state.humhubAllowed).toEqual(true)
})
})
describe('gmsPublishName', () => {
it('sets gmsPublishName', () => {
const state = { gmsPublishName: null }
@ -141,6 +151,14 @@ describe('Vuex store', () => {
})
})
describe('humhubPublishName', () => {
it('sets humhubPublishName', () => {
const state = { humhubPublishName: null }
humhubPublishName(state, 'GMS_PUBLISH_NAME_INITIALS')
expect(state.humhubPublishName).toEqual('GMS_PUBLISH_NAME_INITIALS')
})
})
describe('gmsPublishLocation', () => {
it('sets gmsPublishLocation', () => {
const state = { gmsPublishLocation: null }
@ -218,7 +236,9 @@ describe('Vuex store', () => {
newsletterState: true,
},
gmsAllowed: true,
humhubAllowed: false,
gmsPublishName: 'GMS_PUBLISH_NAME_FULL',
humhubPublishName: 'GMS_PUBLISH_NAME_FULL',
gmsPublishLocation: 'GMS_LOCATION_TYPE_EXACT',
hasElopage: false,
publisherId: 1234,
@ -227,9 +247,9 @@ describe('Vuex store', () => {
hideAmountGDT: true,
}
it('calls fifteen commits', () => {
it('calls seventeen commits', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenCalledTimes(15)
expect(commit).toHaveBeenCalledTimes(17)
})
it('commits gradidoID', () => {
@ -267,39 +287,49 @@ describe('Vuex store', () => {
expect(commit).toHaveBeenNthCalledWith(7, 'gmsAllowed', true)
})
it('commits humhubAllowed', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(8, 'humhubAllowed', false)
})
it('commits gmsPublishName', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(8, 'gmsPublishName', 'GMS_PUBLISH_NAME_FULL')
expect(commit).toHaveBeenNthCalledWith(9, 'gmsPublishName', 'GMS_PUBLISH_NAME_FULL')
})
it('commits humhubPublishName', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(10, 'humhubPublishName', 'GMS_PUBLISH_NAME_FULL')
})
it('commits gmsPublishLocation', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(9, 'gmsPublishLocation', 'GMS_LOCATION_TYPE_EXACT')
expect(commit).toHaveBeenNthCalledWith(11, 'gmsPublishLocation', 'GMS_LOCATION_TYPE_EXACT')
})
it('commits hasElopage', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(10, 'hasElopage', false)
expect(commit).toHaveBeenNthCalledWith(12, 'hasElopage', false)
})
it('commits publisherId', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(11, 'publisherId', 1234)
expect(commit).toHaveBeenNthCalledWith(13, 'publisherId', 1234)
})
it('commits roles', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(12, 'roles', ['admin'])
expect(commit).toHaveBeenNthCalledWith(14, 'roles', ['admin'])
})
it('commits hideAmountGDD', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(13, 'hideAmountGDD', false)
expect(commit).toHaveBeenNthCalledWith(15, 'hideAmountGDD', false)
})
it('commits hideAmountGDT', () => {
login({ commit, state }, commitedData)
expect(commit).toHaveBeenNthCalledWith(14, 'hideAmountGDT', true)
expect(commit).toHaveBeenNthCalledWith(16, 'hideAmountGDT', true)
})
})
@ -307,9 +337,9 @@ describe('Vuex store', () => {
const commit = jest.fn()
const state = {}
it('calls seventeen commits', () => {
it('calls nineteen commits', () => {
logout({ commit, state })
expect(commit).toHaveBeenCalledTimes(17)
expect(commit).toHaveBeenCalledTimes(19)
})
it('commits token', () => {
@ -347,44 +377,54 @@ describe('Vuex store', () => {
expect(commit).toHaveBeenNthCalledWith(7, 'gmsAllowed', null)
})
it('commits humhubAllowed', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(8, 'humhubAllowed', null)
})
it('commits gmsPublishName', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(8, 'gmsPublishName', null)
expect(commit).toHaveBeenNthCalledWith(9, 'gmsPublishName', null)
})
it('commits humhubPublishName', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(10, 'humhubPublishName', null)
})
it('commits gmsPublishLocation', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(9, 'gmsPublishLocation', null)
expect(commit).toHaveBeenNthCalledWith(11, 'gmsPublishLocation', null)
})
it('commits hasElopage', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(10, 'hasElopage', false)
expect(commit).toHaveBeenNthCalledWith(12, 'hasElopage', false)
})
it('commits publisherId', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(11, 'publisherId', null)
expect(commit).toHaveBeenNthCalledWith(13, 'publisherId', null)
})
it('commits roles', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(12, 'roles', null)
expect(commit).toHaveBeenNthCalledWith(14, 'roles', null)
})
it('commits hideAmountGDD', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(13, 'hideAmountGDD', false)
expect(commit).toHaveBeenNthCalledWith(15, 'hideAmountGDD', false)
})
it('commits hideAmountGDT', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(14, 'hideAmountGDT', true)
expect(commit).toHaveBeenNthCalledWith(16, 'hideAmountGDT', true)
})
it('commits email', () => {
logout({ commit, state })
expect(commit).toHaveBeenNthCalledWith(15, 'email', '')
expect(commit).toHaveBeenNthCalledWith(17, 'email', '')
})
// how to get this working?