Merge branch 'master' into 3112-bugbackend-email-links-of-stage2-send-to-production

This commit is contained in:
mahula 2023-07-04 10:22:48 +02:00 committed by GitHub
commit c021295a9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 70 additions and 780 deletions

View File

@ -21,11 +21,6 @@ KLICKTIPP_PASSWORD=secret321
KLICKTIPP_APIKEY_DE=SomeFakeKeyDE
KLICKTIPP_APIKEY_EN=SomeFakeKeyEN
# IOTA
IOTA=false
IOTA_API_URL=https://chrysalis-nodes.iota.org
IOTA_COMMUNITY_ALIAS=GRADIDO: TestHelloWelt1
# Community
COMMUNITY_NAME=Gradido Entwicklung
COMMUNITY_URL=http://localhost/

View File

@ -22,11 +22,6 @@ KLICKTIPP_PASSWORD=$KLICKTIPP_PASSWORD
KLICKTIPP_APIKEY_DE=$KLICKTIPP_APIKEY_DE
KLICKTIPP_APIKEY_EN=$KLICKTIPP_APIKEY_EN
# IOTA
IOTA=$IOTA
IOTA_API_URL=https://chrysalis-nodes.iota.org
IOTA_COMMUNITY_ALIAS=GRADIDO: TestHelloWelt1
# Community
COMMUNITY_NAME=$COMMUNITY_NAME
COMMUNITY_URL=$COMMUNITY_URL

View File

@ -33,8 +33,6 @@ LABEL maintainer="support@gradido.net"
# Install Additional Software
## install: git
#RUN apk --no-cache add git
# Install Build Tool for Rust for @iota/client
RUN apk add --no-cache rust cargo python3 make g++
# Settings
## Expose Container Port
@ -94,9 +92,6 @@ CMD /bin/sh -c "yarn run start"
##################################################################################
FROM base as production
# Remove Build Tool for Rust else they would bloat the image unneccessary
RUN apk del rust cargo python3 make g++
# Copy "binary"-files from build image
COPY --from=build ${DOCKER_WORKDIR}/build ./build
COPY --from=build ${DOCKER_WORKDIR}/../database/build ../database/build

View File

@ -19,7 +19,6 @@
"locales": "scripts/sort.sh"
},
"dependencies": {
"@iota/client": "^2",
"apollo-server-express": "^2.25.2",
"await-semaphore": "^0.1.3",
"axios": "^0.21.1",

View File

@ -1,43 +0,0 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { IotaClientSingleton } from '@/apis/IotaConnector'
import { CONFIG } from '@/config'
CONFIG.IOTA = true
CONFIG.IOTA_COMMUNITY_ALIAS = 'GRADIDO: TestHelloWelt1'
CONFIG.IOTA_API_URL = 'https://chrysalis-nodes.iota.org'
describe('apis/IotaConnector/enabled', () => {
describe('Hello World', () => {
const now = new Date()
let messageId: string
const messageString = 'Hello World - ' + now.toString()
const messageHexString = Buffer.from(messageString, 'utf8').toString('hex')
const indexHexString = Buffer.from(CONFIG.IOTA_COMMUNITY_ALIAS, 'utf8').toString('hex')
it('sends hello world message to iota tangle', async () => {
const iotaMessage = await IotaClientSingleton.getInstance()?.sendDataMessage(messageString)
expect(iotaMessage).toMatchObject({
message: {
payload: {
data: messageHexString,
index: indexHexString,
},
},
messageId: expect.any(String),
})
messageId =
iotaMessage?.messageId ?? '5498130bc3918e1a7143969ce05805502417e3e1bd596d3c44d6a0adeea22710'
})
it('receives hello world message from iota tangle by message id', async () => {
const iotaMessage = await IotaClientSingleton.getInstance()?.getMessage(messageId)
expect(iotaMessage).toMatchObject({
message: {
payload: {
data: messageHexString,
index: indexHexString,
},
},
messageId,
})
})
})
})

View File

@ -1,93 +0,0 @@
import { Client, ClientBuilder } from '@iota/client'
import { MessageWrapper } from '@iota/client/lib/types'
import { CONFIG } from '@/config'
import { backendLogger as logger } from '@/server/logger'
// Source: https://refactoring.guru/design-patterns/singleton/typescript/example
// and ../federation/client/FederationClientFactory.ts
/**
* A Singleton class defines the `getInstance` method that lets clients access
* the unique singleton instance.
*/
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
class IotaClientSingleton {
// eslint-disable-next-line no-use-before-define
private static instance: IotaClientSingleton
private client: Client
/**
* The Singleton's constructor should always be private to prevent direct
* construction calls with the `new` operator.
*/
// eslint-disable-next-line no-useless-constructor, @typescript-eslint/no-empty-function
private constructor() {}
/**
* The static method that controls the access to the singleton instance.
*
* This implementation let you subclass the Singleton class while keeping
* just one instance of each subclass around.
*/
public static getInstance(): IotaClientSingleton | undefined {
if (!CONFIG.IOTA || !CONFIG.IOTA_API_URL) {
logger.info(`Iota are disabled via config...`)
return
}
if (!IotaClientSingleton.instance) {
IotaClientSingleton.instance = new IotaClientSingleton()
try {
IotaClientSingleton.instance.client = new ClientBuilder().node(CONFIG.IOTA_API_URL).build()
} catch (e) {
logger.error("couldn't connect to iota")
return
}
}
return IotaClientSingleton.instance
}
/**
* send data message onto iota tangle
* use CONFIG.IOTA_COMMUNITY_ALIAS for index
* @param {string} message - the message as utf based string, will be converted to hex automatically from @iota/client
* @return {Promise<MessageWrapper>} the iota message typed
*/
public sendDataMessage(message: string): Promise<MessageWrapper> {
return this.client.message().index(CONFIG.IOTA_COMMUNITY_ALIAS).data(message).submit()
}
/**
* receive message for known message id from iota tangle
* @param {string} messageId - as hex string
* @return {Promise<MessageWrapper>} the iota message typed
*/
public getMessage(messageId: string): Promise<MessageWrapper> {
return this.client.getMessage().data(messageId)
}
}
export { IotaClientSingleton }
/**
* example for message:
```json
{
message: {
networkId: '1454675179895816119',
parentMessageIds: [
'5f30efecca59fdfef7c103e85ef691b2b1dc474e9eae9056888a6d58605083e7',
'77cef2fb405daedcd7469e009bb87a6d9a4840e618cdb599cd21a30a9fec88dc',
'7d2cfb39f40585ba568a29ad7e85c1478b2584496eb736d4001ac344f6a6cacf',
'c66da602874220dfa26925f6be540d37c0084d37cd04726fcc5be9d80b36f850'
],
payload: {
type: 2,
index: '4752414449444f3a205465737448656c6c6f57656c7431',
data: '48656c6c6f20576f726c64202d20546875204a756e20303820323032332031343a35393a343520474d542b3030303020284b6f6f7264696e69657274652057656c747a65697429'
},
nonce: '13835058055282465157'
},
messageId: '5498130bc3918e1a7143969ce05805502417e3e1bd596d3c44d6a0adeea22710'
}
```
*/

View File

@ -1,26 +0,0 @@
import { IotaClientSingleton } from '@/apis/IotaConnector'
import { CONFIG } from '@/config'
import { backendLogger as logger } from '@/server/logger'
describe('apis/IotaConnector/disabled', () => {
beforeEach(() => {
CONFIG.IOTA = false
})
it('getInstance return undefined if iota is disabled', () => {
const spyLog = jest.spyOn(logger, 'info')
expect(IotaClientSingleton.getInstance()).toBeUndefined()
expect(spyLog).toHaveBeenCalledWith('Iota are disabled via config...')
})
})
describe('apis/IotaConnector/invalidIotaUrl', () => {
beforeEach(() => {
CONFIG.IOTA = true
CONFIG.IOTA_API_URL = 'invalidUrl'
})
it('log "couldn\'t connect to iota"', () => {
const spyLog = jest.spyOn(logger, 'error')
expect(IotaClientSingleton.getInstance()).toBeUndefined()
expect(spyLog).toHaveBeenCalledWith("couldn't connect to iota")
})
})

View File

@ -19,7 +19,7 @@ const constants = {
LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v16.2023-06-08',
EXPECTED: 'v17.2023-07-03',
CURRENT: '',
},
}
@ -51,12 +51,6 @@ const klicktipp = {
KLICKTIPP_APIKEY_EN: process.env.KLICKTIPP_APIKEY_EN ?? 'SomeFakeKeyEN',
}
const iota = {
IOTA: process.env.IOTA === 'true' || false,
IOTA_API_URL: process.env.IOTA_API_URL ?? 'https://chrysalis-nodes.iota.org',
IOTA_COMMUNITY_ALIAS: process.env.IOTA_COMMUNITY_ALIAS ?? 'GRADIDO: TestHelloWelt1',
}
const community = {
COMMUNITY_NAME: process.env.COMMUNITY_NAME ?? 'Gradido Entwicklung',
COMMUNITY_URL: process.env.COMMUNITY_URL ?? 'http://localhost/',
@ -132,7 +126,6 @@ export const CONFIG = {
...server,
...database,
...klicktipp,
...iota,
...community,
...email,
...loginServer,

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@ COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community"
COMMUNITY_SUPPORT_MAIL=support@supportmail.com
# backend
BACKEND_CONFIG_VERSION=v16.2023-06-08
BACKEND_CONFIG_VERSION=v17.2023-07-03
JWT_EXPIRES_IN=10m
GDT_API_URL=https://gdt.gradido.net
@ -40,9 +40,6 @@ KLICKTIPP_PASSWORD=
KLICKTIPP_APIKEY_DE=
KLICKTIPP_APIKEY_EN=
# IOTA
IOTA=false
EMAIL=true
EMAIL_TEST_MODUS=false
EMAIL_TEST_RECEIVER=test_team@gradido.net

View File

@ -1,14 +1,14 @@
[
{
"locale": "de",
"date": "4. juni 2023",
"date": "4. Juli 2023",
"text": "Neue Funktion verfügbar: Jetzt Benutzernamen eintragen!",
"url": "/settings",
"extra": "Deine persönlichen Daten sind uns wichtig, und wir legen großen Wert auf deren Schutz. Wir wissen, dass nicht jeder seine E-Mail-Adresse anderen Benutzern preisgeben möchte. Aus diesem Grund kannst du nun einen Benutzernamen deiner Wahl in den Einstellungen angeben. Dies ist auch ein wichtiger Bestandteil unserer Vorbereitung für die bevorstehende Einführung unserer dezentralen Community-Server."
},
{
"locale": "en",
"date": "4 july 2023",
"date": "4 July 2023",
"text": "New function available: Enter username now!",
"url": "/settings",
"extra": "Your personal information is important to us, and we take great care to protect it. We know that not everyone wants to reveal their email address to other users. For this reason, you can now enter a username of your choice in the settings. This is also an important part of our preparation for the upcoming launch of our decentralized community servers."

View File

@ -0,0 +1,50 @@
import { mount } from '@vue/test-utils'
import RightSide from './RightSide'
const localVue = global.localVue
describe('RightSide', () => {
let wrapper
const mocks = {
$route: {
path: '/community/contribute',
},
}
const Wrapper = () => {
return mount(RightSide, { localVue, mocks })
}
describe('at /community/contribute', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('has name set to "community"', () => {
expect(wrapper.vm.name).toBe('community')
})
})
describe('at /settings', () => {
beforeEach(() => {
mocks.$route.path = '/settings'
wrapper = Wrapper()
})
it('has name set to "empty"', () => {
expect(wrapper.vm.name).toBe('empty')
})
})
describe('at /overview', () => {
beforeEach(() => {
mocks.$route.path = '/overview'
wrapper = Wrapper()
})
it('has name set to "transactions"', () => {
expect(wrapper.vm.name).toBe('transactions')
})
})
})