diff --git a/README.md b/README.md
index 87b4f44e5..91ac65dab 100644
--- a/README.md
+++ b/README.md
@@ -131,7 +131,7 @@ Each component (frontend, admin, backend and database) has its own `.env` file.
Each component has a `.env.dist` file. This file contains all environment variables used by the component and can be used as pattern. If you want to use a local `.env`, copy the `.env.dist` and adjust the variables accordingly.
-Each component has a `.env.template` file. These files are very important on deploy.
+Each component has a `.env.template` file. These files are very important on deploy. They use COMMUNITY_HOST instead of different urls for different modules because in deploy using nginx is expected for routing incoming request to the correct module
There is one `.env.dist` in the `deployment/bare_metal/` folder. This `.env.dist` contains all variables used by the components, e.g. unites all `.env.dist` from the components. On deploy, we copy this `.env.dist` to `.env` and set all variables in this new file. The deploy script loads this variables and provides them by the `.env.templates` of each component, creating an `.env` for each component (see in `deployment/bare_metal/start.sh` the `envsubst`).
diff --git a/admin/.env.dist b/admin/.env.dist
index 66c84dda8..d92f3d9bc 100644
--- a/admin/.env.dist
+++ b/admin/.env.dist
@@ -1,4 +1,6 @@
-GRAPHQL_URI=http://localhost:4000/graphql
-WALLET_AUTH_URL=http://localhost/authenticate?token={token}
-WALLET_URL=http://localhost/login
+GRAPHQL_URL=http://localhost:4000
+GRAPHQL_PATH=/graphql
+WALLET_URL=http://localhost
+WALLET_AUTH_PATH=/authenticate?token={token}
+WALLET_LOGIN_PATH=/login
DEBUG_DISABLE_AUTH=false
\ No newline at end of file
diff --git a/admin/.env.template b/admin/.env.template
index 488c9aba4..11e849271 100644
--- a/admin/.env.template
+++ b/admin/.env.template
@@ -1,6 +1,8 @@
CONFIG_VERSION=$ADMIN_CONFIG_VERSION
-GRAPHQL_URI=$GRAPHQL_URI
-WALLET_AUTH_URL=$WALLET_AUTH_URL
-WALLET_URL=$WALLET_URL
-DEBUG_DISABLE_AUTH=false
\ No newline at end of file
+COMMUNITY_HOST=$COMMUNITY_HOST
+URL_PROTOCOL=$URL_PROTOCOL
+WALLET_AUTH_PATH=$WALLET_AUTH_PATH
+WALLET_LOGIN_PATH=$WALLET_LOGIN_PATH
+GRAPHQL_PATH=$GRAPHQL_PATH
+DEBUG_DISABLE_AUTH=false
diff --git a/admin/src/components/NavBar.vue b/admin/src/components/NavBar.vue
index 2efeda048..4191290f3 100644
--- a/admin/src/components/NavBar.vue
+++ b/admin/src/components/NavBar.vue
@@ -38,8 +38,8 @@ export default {
name: 'navbar',
methods: {
async logout() {
- window.location.assign(CONFIG.WALLET_URL)
- // window.location = CONFIG.WALLET_URL
+ window.location.assign(CONFIG.WALLET_LOGIN_URL)
+ // window.location = CONFIG.WALLET_LOGIN_URL
this.$store.dispatch('logout')
await this.$apollo.mutate({
mutation: logout,
diff --git a/admin/src/config/index.js b/admin/src/config/index.js
index fe373386d..708815398 100644
--- a/admin/src/config/index.js
+++ b/admin/src/config/index.js
@@ -7,37 +7,45 @@ const pkg = require('../../package')
const constants = {
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
- EXPECTED: 'v1.2022-03-18',
+ EXPECTED: 'v2.2024-01-04',
CURRENT: '',
},
}
const version = {
APP_VERSION: pkg.version,
- BUILD_COMMIT: process.env.BUILD_COMMIT || null,
+ BUILD_COMMIT: process.env.BUILD_COMMIT ?? null,
// self reference of `version.BUILD_COMMIT` is not possible at this point, hence the duplicate code
- BUILD_COMMIT_SHORT: (process.env.BUILD_COMMIT || '0000000').slice(0, 7),
- PORT: process.env.PORT || 8080,
+ BUILD_COMMIT_SHORT: (process.env.BUILD_COMMIT ?? '0000000').slice(0, 7),
+ PORT: process.env.PORT ?? 8080,
}
const environment = {
NODE_ENV: process.env.NODE_ENV,
- DEBUG: process.env.NODE_ENV !== 'production' || false,
- PRODUCTION: process.env.NODE_ENV === 'production' || false,
+ DEBUG: process.env.NODE_ENV !== 'production' ?? false,
+ PRODUCTION: process.env.NODE_ENV === 'production' ?? false,
}
+const COMMUNITY_HOST = process.env.COMMUNITY_HOST ?? undefined
+const URL_PROTOCOL = process.env.URL_PROTOCOL ?? 'http'
+const COMMUNITY_URL =
+ COMMUNITY_HOST && URL_PROTOCOL ? URL_PROTOCOL + '://' + COMMUNITY_HOST : undefined
+const WALLET_URL = process.env.WALLET_URL ?? COMMUNITY_URL ?? 'http://localhost'
+
const endpoints = {
- GRAPHQL_URI: process.env.GRAPHQL_URI || 'http://localhost:4000/graphql',
- WALLET_AUTH_URL: process.env.WALLET_AUTH_URL || 'http://localhost/authenticate?token={token}',
- WALLET_URL: process.env.WALLET_URL || 'http://localhost/login',
+ GRAPHQL_URL:
+ (process.env.GRAPHQL_URL ?? COMMUNITY_URL ?? 'http://localhost:4000') +
+ process.env.GRAPHQL_PATH ?? '/graphql',
+ WALLET_AUTH_URL: WALLET_URL + (process.env.WALLET_AUTH_PATH ?? '/authenticate?token={token}'),
+ WALLET_LOGIN_URL: WALLET_URL + (process.env.WALLET_LOGIN_PATH ?? '/login'),
}
const debug = {
- DEBUG_DISABLE_AUTH: process.env.DEBUG_DISABLE_AUTH === 'true' || false,
+ DEBUG_DISABLE_AUTH: process.env.DEBUG_DISABLE_AUTH === 'true' ?? false,
}
// Check config version
-constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION || constants.CONFIG_VERSION.DEFAULT
+constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION ?? constants.CONFIG_VERSION.DEFAULT
if (
![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes(
constants.CONFIG_VERSION.CURRENT,
diff --git a/admin/src/plugins/apolloProvider.js b/admin/src/plugins/apolloProvider.js
index 8b02013f4..122857031 100644
--- a/admin/src/plugins/apolloProvider.js
+++ b/admin/src/plugins/apolloProvider.js
@@ -16,7 +16,7 @@ const authLink = new ApolloLink((operation, forward) => {
return forward(operation).map((response) => {
if (response.errors && response.errors[0].message === '403.13 - Client certificate revoked') {
store.dispatch('logout', null)
- window.location.assign(CONFIG.WALLET_URL)
+ window.location.assign(CONFIG.WALLET_LOGIN_URL)
return response
}
const newToken = operation.getContext().response.headers.get('token')
diff --git a/backend/.env.dist b/backend/.env.dist
index 9844d8c4a..96afd1ab5 100644
--- a/backend/.env.dist
+++ b/backend/.env.dist
@@ -28,9 +28,9 @@ DLT_CONNECTOR_URL=http://localhost:6010
# Community
COMMUNITY_NAME=Gradido Entwicklung
COMMUNITY_URL=http://localhost/
-COMMUNITY_REGISTER_URL=http://localhost/register
-COMMUNITY_REDEEM_URL=http://localhost/redeem/{code}
-COMMUNITY_REDEEM_CONTRIBUTION_URL=http://localhost/redeem/CL-{code}
+COMMUNITY_REGISTER_PATH=/register
+COMMUNITY_REDEEM_PATH=/redeem/{code}
+COMMUNITY_REDEEM_CONTRIBUTION_PATH=/redeem/CL-{code}
COMMUNITY_DESCRIPTION=Die lokale Entwicklungsumgebung von Gradido.
COMMUNITY_SUPPORT_MAIL=support@supportmail.com
@@ -47,10 +47,10 @@ EMAIL_SENDER=info@gradido.net
EMAIL_PASSWORD=xxx
EMAIL_SMTP_URL=gmail.com
EMAIL_SMTP_PORT=587
-EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/{optin}{code}
-EMAIL_LINK_SETPASSWORD=http://localhost/reset-password/{optin}
-EMAIL_LINK_FORGOTPASSWORD=http://localhost/forgot-password
-EMAIL_LINK_OVERVIEW=http://localhost/overview
+EMAIL_LINK_VERIFICATION_PATH=/checkEmail/{optin}{code}
+EMAIL_LINK_SETPASSWORD_PATH=/reset-password/{optin}
+EMAIL_LINK_FORGOTPASSWORD_PATH=/forgot-password
+EMAIL_LINK_OVERVIEW_PATH=/overview
EMAIL_CODE_VALID_TIME=1440
EMAIL_CODE_REQUEST_TIME=10
diff --git a/backend/.env.template b/backend/.env.template
index e79122368..1cf7d9dee 100644
--- a/backend/.env.template
+++ b/backend/.env.template
@@ -1,5 +1,5 @@
# must match the CONFIG_VERSION.EXPECTED definition in scr/config/index.ts
-CONFIG_VERSION=v20.2023-09-19
+CONFIG_VERSION=$BACKEND_CONFIG_VERSION
# Server
JWT_SECRET=$JWT_SECRET
@@ -25,14 +25,15 @@ KLICKTIPP_APIKEY_EN=$KLICKTIPP_APIKEY_EN
# DltConnector
DLT_CONNECTOR=$DLT_CONNECTOR
-DLT_CONNECTOR_URL=$DLT_CONNECTOR_URL
+DLT_CONNECTOR_PORT=$DLT_CONNECTOR_PORT
# Community
+COMMUNITY_HOST=$COMMUNITY_HOST
+URL_PROTOCOL=$URL_PROTOCOL
COMMUNITY_NAME=$COMMUNITY_NAME
-COMMUNITY_URL=$COMMUNITY_URL
-COMMUNITY_REGISTER_URL=$COMMUNITY_REGISTER_URL
-COMMUNITY_REDEEM_URL=$COMMUNITY_REDEEM_URL
-COMMUNITY_REDEEM_CONTRIBUTION_URL=$COMMUNITY_REDEEM_CONTRIBUTION_URL
+COMMUNITY_REGISTER_PATH=$COMMUNITY_REGISTER_PATH
+COMMUNITY_REDEEM_PATH=$COMMUNITY_REDEEM_PATH
+COMMUNITY_REDEEM_CONTRIBUTION_PATH=$COMMUNITY_REDEEM_CONTRIBUTION_PATH
COMMUNITY_DESCRIPTION=$COMMUNITY_DESCRIPTION
COMMUNITY_SUPPORT_MAIL=$COMMUNITY_SUPPORT_MAIL
@@ -48,12 +49,12 @@ EMAIL_USERNAME=$EMAIL_USERNAME
EMAIL_SENDER=$EMAIL_SENDER
EMAIL_PASSWORD=$EMAIL_PASSWORD
EMAIL_SMTP_URL=$EMAIL_SMTP_URL
-EMAIL_SMTP_PORT=587
-EMAIL_LINK_VERIFICATION=$EMAIL_LINK_VERIFICATION
-EMAIL_LINK_SETPASSWORD=$EMAIL_LINK_SETPASSWORD
-EMAIL_LINK_FORGOTPASSWORD=$EMAIL_LINK_FORGOTPASSWORD
-EMAIL_LINK_OVERVIEW=$EMAIL_LINK_OVERVIEW
-EMAIL_CODE_VALID_TIME=$EMAIL_CODE_VALID_TIME
+EMAIL_SMTP_PORT=$EMAIL_SMTP_PORT
+EMAIL_LINK_VERIFICATION_PATH=$EMAIL_LINK_VERIFICATION_PATH
+EMAIL_LINK_SETPASSWORD_PATH=$EMAIL_LINK_SETPASSWORD_PATH
+EMAIL_LINK_FORGOTPASSWORD_PATH=$EMAIL_LINK_FORGOTPASSWORD_PATH
+EMAIL_LINK_OVERVIEW_PATH=$EMAIL_LINK_OVERVIEW_PATH
+EMAIL_CODE_VALID_TIME=$EMAIL_CODE_VALID_TIME_PATH
EMAIL_CODE_REQUEST_TIME=$EMAIL_CODE_REQUEST_TIME
# Webhook
diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts
index 7fbc0aae0..1ec5a98e6 100644
--- a/backend/src/config/index.ts
+++ b/backend/src/config/index.ts
@@ -19,7 +19,7 @@ const constants = {
LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
- EXPECTED: 'v20.2023-09-19',
+ EXPECTED: 'v21.2024-01-06',
CURRENT: '',
},
}
@@ -51,18 +51,23 @@ const klicktipp = {
KLICKTIPP_APIKEY_EN: process.env.KLICKTIPP_APIKEY_EN ?? 'SomeFakeKeyEN',
}
+const COMMUNITY_HOST = process.env.COMMUNITY_HOST ?? 'localhost'
+const URL_PROTOCOL = process.env.URL_PROTOCOL ?? 'http'
+const COMMUNITY_URL = process.env.COMMUNITY_URL ?? `${URL_PROTOCOL}://${COMMUNITY_HOST}`
+const DLT_CONNECTOR_PORT = process.env.DLT_CONNECTOR_PORT ?? 6010
+
const dltConnector = {
DLT_CONNECTOR: process.env.DLT_CONNECTOR === 'true' || false,
- DLT_CONNECTOR_URL: process.env.DLT_CONNECTOR_URL ?? 'http://localhost:6010',
+ DLT_CONNECTOR_URL: process.env.DLT_CONNECTOR_URL ?? `${COMMUNITY_URL}:${DLT_CONNECTOR_PORT}`,
}
const community = {
COMMUNITY_NAME: process.env.COMMUNITY_NAME ?? 'Gradido Entwicklung',
- COMMUNITY_URL: process.env.COMMUNITY_URL ?? 'http://localhost/',
- COMMUNITY_REGISTER_URL: process.env.COMMUNITY_REGISTER_URL ?? 'http://localhost/register',
- COMMUNITY_REDEEM_URL: process.env.COMMUNITY_REDEEM_URL ?? 'http://localhost/redeem/{code}',
+ COMMUNITY_URL,
+ COMMUNITY_REGISTER_URL: COMMUNITY_URL + (process.env.COMMUNITY_REGISTER_PATH ?? '/register'),
+ COMMUNITY_REDEEM_URL: COMMUNITY_URL + (process.env.COMMUNITY_REDEEM_PATH ?? '/redeem/{code}'),
COMMUNITY_REDEEM_CONTRIBUTION_URL:
- process.env.COMMUNITY_REDEEM_CONTRIBUTION_URL ?? 'http://localhost/redeem/CL-{code}',
+ COMMUNITY_URL + (process.env.COMMUNITY_REDEEM_CONTRIBUTION_PATH ?? '/redeem/CL-{code}'),
COMMUNITY_DESCRIPTION:
process.env.COMMUNITY_DESCRIPTION ?? 'Die lokale Entwicklungsumgebung von Gradido.',
COMMUNITY_SUPPORT_MAIL: process.env.COMMUNITY_SUPPORT_MAIL ?? 'support@supportmail.com',
@@ -74,8 +79,8 @@ const loginServer = {
}
const email = {
- EMAIL: process.env.EMAIL === 'true' || false,
- EMAIL_TEST_MODUS: process.env.EMAIL_TEST_MODUS === 'true' || false,
+ EMAIL: process.env.EMAIL === 'true' ?? false,
+ EMAIL_TEST_MODUS: process.env.EMAIL_TEST_MODUS === 'true' ?? false,
EMAIL_TEST_RECEIVER: process.env.EMAIL_TEST_RECEIVER ?? 'stage1@gradido.net',
EMAIL_USERNAME: process.env.EMAIL_USERNAME ?? '',
EMAIL_SENDER: process.env.EMAIL_SENDER ?? 'info@gradido.net',
@@ -85,19 +90,19 @@ const email = {
// eslint-disable-next-line no-unneeded-ternary
EMAIL_TLS: process.env.EMAIL_TLS === 'false' ? false : true,
EMAIL_LINK_VERIFICATION:
- process.env.EMAIL_LINK_VERIFICATION ?? 'http://localhost/checkEmail/{optin}{code}',
+ COMMUNITY_URL + (process.env.EMAIL_LINK_VERIFICATION_PATH ?? '/checkEmail/{optin}{code}'),
EMAIL_LINK_SETPASSWORD:
- process.env.EMAIL_LINK_SETPASSWORD ?? 'http://localhost/reset-password/{optin}',
+ COMMUNITY_URL + (process.env.EMAIL_LINK_SETPASSWORD_PATH ?? '/reset-password/{optin}'),
EMAIL_LINK_FORGOTPASSWORD:
- process.env.EMAIL_LINK_FORGOTPASSWORD ?? 'http://localhost/forgot-password',
- EMAIL_LINK_OVERVIEW: process.env.EMAIL_LINK_OVERVIEW ?? 'http://localhost/overview',
+ COMMUNITY_URL + (process.env.EMAIL_LINK_FORGOTPASSWORD_PATH ?? '/forgot-password'),
+ EMAIL_LINK_OVERVIEW: COMMUNITY_URL + (process.env.EMAIL_LINK_OVERVIEW_PATH ?? '/overview'),
// time in minutes a optin code is valid
EMAIL_CODE_VALID_TIME: process.env.EMAIL_CODE_VALID_TIME
- ? parseInt(process.env.EMAIL_CODE_VALID_TIME) || 1440
+ ? parseInt(process.env.EMAIL_CODE_VALID_TIME) ?? 1440
: 1440,
// time in minutes that must pass to request a new optin code
EMAIL_CODE_REQUEST_TIME: process.env.EMAIL_CODE_REQUEST_TIME
- ? parseInt(process.env.EMAIL_CODE_REQUEST_TIME) || 10
+ ? parseInt(process.env.EMAIL_CODE_REQUEST_TIME) ?? 10
: 10,
}
@@ -124,9 +129,9 @@ if (
const federation = {
FEDERATION_BACKEND_SEND_ON_API: process.env.FEDERATION_BACKEND_SEND_ON_API ?? '1_0',
FEDERATION_VALIDATE_COMMUNITY_TIMER:
- Number(process.env.FEDERATION_VALIDATE_COMMUNITY_TIMER) || 60000,
+ Number(process.env.FEDERATION_VALIDATE_COMMUNITY_TIMER) ?? 60000,
FEDERATION_XCOM_SENDCOINS_ENABLED:
- process.env.FEDERATION_XCOM_SENDCOINS_ENABLED === 'true' || false,
+ process.env.FEDERATION_XCOM_SENDCOINS_ENABLED === 'true' ?? false,
// default value for community-uuid is equal uuid of stage-3
FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID:
process.env.FEDERATION_XCOM_RECEIVER_COMMUNITY_UUID ?? '56a55482-909e-46a4-bfa2-cd025e894ebc',
diff --git a/backend/src/emails/templates/addedContributionMessage/html.pug b/backend/src/emails/templates/addedContributionMessage/html.pug
index 7865b2099..ff7c89c30 100644
--- a/backend/src/emails/templates/addedContributionMessage/html.pug
+++ b/backend/src/emails/templates/addedContributionMessage/html.pug
@@ -9,6 +9,6 @@ block content
h2= t('emails.addedContributionMessage.readMessage')
div(class="p_content")= t('emails.addedContributionMessage.toSeeAndAnswerMessage')
- a.button-3(href=`${communityURL}community/contributions`) #{t('emails.general.toAccount')}
+ a.button-3(href=`${communityURL}/community/contributions`) #{t('emails.general.toAccount')}
include ../includes/doNotReply.pug
diff --git a/backend/src/emails/templates/includes/contributionDetailsCTA.pug b/backend/src/emails/templates/includes/contributionDetailsCTA.pug
index fb2906419..0a3bd395d 100644
--- a/backend/src/emails/templates/includes/contributionDetailsCTA.pug
+++ b/backend/src/emails/templates/includes/contributionDetailsCTA.pug
@@ -1,7 +1,7 @@
//-
h2= t('emails.general.contributionDetails')
div(class="p_content")= t('emails.contribution.toSeeContributionsAndMessages')
-a.button-3(href=`${communityURL}community/contributions`) #{t('emails.general.toAccount')}
+a.button-3(href=`${communityURL}/community/contributions`) #{t('emails.general.toAccount')}
div(class="p_content")= t('emails.general.orCopyLink')
-a.clink(href=`${communityURL}community/contributions`) #{`${communityURL}community/contributions`}
\ No newline at end of file
+a.clink(href=`${communityURL}/community/contributions`) #{`${communityURL}/community/contributions`}
\ No newline at end of file
diff --git a/backend/src/emails/templates/transactionLinkRedeemed/html.pug b/backend/src/emails/templates/transactionLinkRedeemed/html.pug
index b24c5da40..281ee9205 100644
--- a/backend/src/emails/templates/transactionLinkRedeemed/html.pug
+++ b/backend/src/emails/templates/transactionLinkRedeemed/html.pug
@@ -13,6 +13,6 @@ block content
br
= t('emails.general.detailsYouFindOnLinkToYourAccount')
- a.button-3(href=`${communityURL}transactions`) #{t('emails.general.toAccount')}
+ a.button-3(href=`${communityURL}/transactions`) #{t('emails.general.toAccount')}
include ../includes/doNotReply.pug
diff --git a/backend/src/emails/templates/transactionReceived/html.pug b/backend/src/emails/templates/transactionReceived/html.pug
index 93de2c88e..5370ec03e 100644
--- a/backend/src/emails/templates/transactionReceived/html.pug
+++ b/backend/src/emails/templates/transactionReceived/html.pug
@@ -9,7 +9,7 @@ block content
h2= t('emails.general.transactionDetails')
div(class="p_content")= t('emails.general.detailsYouFindOnLinkToYourAccount')
- a.button-3(href=`${communityURL}transactions`) #{t('emails.general.toAccount')}
+ a.button-3(href=`${communityURL}/transactions`) #{t('emails.general.toAccount')}
include ../includes/doNotReply.pug
diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist
index 1335e06a5..eb1e45f79 100644
--- a/deployment/bare_metal/.env.dist
+++ b/deployment/bare_metal/.env.dist
@@ -1,87 +1,99 @@
-GRADIDO_LOG_PATH=/home/gradido/gradido/deployment/bare_metal/log
+# Need to adjust!
+COMMUNITY_NAME="Your community name"
+COMMUNITY_DESCRIPTION="Short Description from your Community."
+COMMUNITY_HOST=gddhost.tld
+COMMUNITY_SUPPORT_MAIL=support@supportmail.com
+# setup email account for sending gradido system messages to users
+EMAIL=true
+EMAIL_USERNAME=peter@lustig.de
+EMAIL_SENDER=peter@lustig.de
+EMAIL_PASSWORD=1234
+EMAIL_SMTP_URL=smtp.lustig.de
+EMAIL_SMTP_PORT=587
+
+# how many minutes email verification code is valid
+# also used for password reset code
+EMAIL_CODE_VALID_TIME=1440
+# how many minutes user must wait before he can request the email verification code again
+# also used for password reset code
+EMAIL_CODE_REQUEST_TIME=10
+
+# Need to adjust by updates
+# config versions
+DATABASE_CONFIG_VERSION=v1.2022-03-18
+BACKEND_CONFIG_VERSION=v21.2024-01-06
+FRONTEND_CONFIG_VERSION=v5.2024-01-08
+ADMIN_CONFIG_VERSION=v2.2024-01-04
+FEDERATION_CONFIG_VERSION=v1.2023-01-09
+FEDERATION_DHT_CONFIG_VERSION=v3.2023-04-26
+
+FEDERATION_DHT_TOPIC=GRADIDO_HUB
+
+# Need adjustments for test system
+URL_PROTOCOL=https
# start script
+# only for test server
DEPLOY_SEED_DATA=false
+# test email
+# if true all email will be send to EMAIL_TEST_RECEIVER instead of email address of user
+EMAIL_TEST_MODUS=false
+EMAIL_TEST_RECEIVER=test_team@gradido.net
-# nginx
-NGINX_REWRITE_LEGACY_URLS=true
-NGINX_SSL=true
-NGINX_SERVER_NAME=stage1.gradido.net
-NGINX_SSL_CERTIFICATE=/etc/letsencrypt/live/stage1.gradido.net/fullchain.pem
-NGINX_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/stage1.gradido.net/privkey.pem
-NGINX_SSL_DHPARAM=/etc/letsencrypt/ssl-dhparams.pem
-NGINX_SSL_INCLUDE=/etc/letsencrypt/options-ssl-nginx.conf
-NGINX_UPDATE_PAGE_ROOT=/home/gradido/gradido/deployment/bare_metal/nginx/update-page
+# Logging
+LOG_LEVEL=INFO
+GRADIDO_LOG_PATH=/home/gradido/gradido/deployment/bare_metal/log
+TYPEORM_LOGGING_RELATIVE_PATH=../deployment/bare_metal/log/typeorm.backend.log
# webhook
WEBHOOK_GITHUB_SECRET=secret
WEBHOOK_GITHUB_BRANCH=master
-# community
-COMMUNITY_NAME="Gradido Development Stage1"
-COMMUNITY_URL=https://stage1.gradido.net/
-COMMUNITY_REGISTER_URL=https://stage1.gradido.net/register
-COMMUNITY_REDEEM_URL=https://stage1.gradido.net/redeem/{code}
-COMMUNITY_REDEEM_CONTRIBUTION_URL=https://stage1.gradido.net/redeem/CL-{code}
-COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community"
-COMMUNITY_SUPPORT_MAIL=support@supportmail.com
-
-# backend
-BACKEND_CONFIG_VERSION=v17.2023-07-03
+# frontend and admin paths, usually don't need changes
+# used in nginx config and for links in emails
+COMMUNITY_REGISTER_PATH=/register
+COMMUNITY_REDEEM_PATH=/redeem/{code}
+COMMUNITY_REDEEM_CONTRIBUTION_PATH=/redeem/CL-{code}
+WALLET_LOGIN_PATH=/login
+WALLET_AUTH_PATH=/authenticate?token={token}
+EMAIL_LINK_VERIFICATION_PATH=/checkEmail/{optin}{code}
+EMAIL_LINK_SETPASSWORD_PATH=/reset-password/{optin}
+EMAIL_LINK_FORGOTPASSWORD_PATH=/forgot-password
+EMAIL_LINK_OVERVIEW_PATH=/overview
+ADMIN_AUTH_PATH=/admin/authenticate?token={token}
+GRAPHQL_PATH=/graphql
+# login expire time
JWT_EXPIRES_IN=10m
+
+# Federation
+# if you set the value of FEDERATION_DHT_TOPIC, the DHT hyperswarm will start to announce and listen
+# on an hash created from this topic
+# FEDERATION_DHT_TOPIC=GRADIDO_HUB
+# FEDERATION_DHT_SEED=64ebcb0e3ad547848fef4197c6e2332f
+# the api port is the baseport, which will be added with the api-version, e.g. 1_0 = 5010
+FEDERATION_COMMUNITY_API_PORT=5000
+FEDERATION_VALIDATE_COMMUNITY_TIMER=60000
+
+# comma separated list of api-versions, which cause starting several federation modules
+FEDERATION_COMMUNITY_APIS=1_0,1_1
+
+# externe gradido services (more added in future)
GDT_API_URL=https://gdt.gradido.net
-TYPEORM_LOGGING_RELATIVE_PATH=../deployment/bare_metal/log/typeorm.backend.log
+# DLT-Connector (still in develop)
+DLT_CONNECTOR=false
+DLT_CONNECTOR_PORT=6010
+# used for combining a newsletter on klicktipp with this gradido community
+# if used, user will be subscribed on register and can unsubscribe in his account
KLICKTIPP=false
KLICKTIPP_USER=
KLICKTIPP_PASSWORD=
KLICKTIPP_APIKEY_DE=
KLICKTIPP_APIKEY_EN=
-EMAIL=true
-EMAIL_TEST_MODUS=false
-EMAIL_TEST_RECEIVER=test_team@gradido.net
-EMAIL_USERNAME=peter@lustig.de
-EMAIL_SENDER=peter@lustig.de
-EMAIL_PASSWORD=1234
-EMAIL_SMTP_URL=smtp.lustig.de
-EMAIL_LINK_VERIFICATION=https://stage1.gradido.net/checkEmail/{optin}{code}
-EMAIL_LINK_SETPASSWORD=https://stage1.gradido.net/reset-password/{optin}
-EMAIL_LINK_FORGOTPASSWORD=https://stage1.gradido.net/forgot-password
-EMAIL_LINK_OVERVIEW=https://stage1.gradido.net/overview
-EMAIL_CODE_VALID_TIME=1440
-EMAIL_CODE_REQUEST_TIME=10
-
-WEBHOOK_ELOPAGE_SECRET=secret
-
-# Federation
-FEDERATION_DHT_CONFIG_VERSION=v3.2023-04-26
-# if you set the value of FEDERATION_DHT_TOPIC, the DHT hyperswarm will start to announce and listen
-# on an hash created from this topic
-# FEDERATION_DHT_TOPIC=GRADIDO_HUB
-# FEDERATION_DHT_SEED=64ebcb0e3ad547848fef4197c6e2332f
-FEDERATION_COMMUNITY_URL=http://stage1.gradido.net
-# the api port is the baseport, which will be added with the api-version, e.g. 1_0 = 5010
-FEDERATION_COMMUNITY_API_PORT=5000
-
-FEDERATION_CONFIG_VERSION=v1.2023-01-09
-# comma separated list of api-versions, which cause starting several federation modules
-FEDERATION_COMMUNITY_APIS=1_0,1_1
-
-# database
-DATABASE_CONFIG_VERSION=v1.2022-03-18
-
-# frontend
-FRONTEND_CONFIG_VERSION=v4.2022-12-20
-
-GRAPHQL_URI=https://stage1.gradido.net/graphql
-ADMIN_AUTH_URL=https://stage1.gradido.net/admin/authenticate?token={token}
-
-DEFAULT_PUBLISHER_ID=2896
-
-META_URL=http://localhost
+# Meta data in frontend pages, important when shared via facebook or twitter or for search engines
META_TITLE_DE="Gradido – Dein Dankbarkeitskonto"
META_TITLE_EN="Gradido - Your gratitude account"
META_DESCRIPTION_DE="Dankbarkeit ist die Währung der neuen Zeit. Immer mehr Menschen entfalten ihr Potenzial und gestalten eine gute Zukunft für alle."
@@ -90,8 +102,17 @@ META_KEYWORDS_DE="Grundeinkommen, Währung, Dankbarkeit, Schenk-Ökonomie, Natü
META_KEYWORDS_EN="Basic Income, Currency, Gratitude, Gift Economy, Natural Economy of Life, Economy, Ecology, Potential Development, Giving and Thanking, Cycle of Life, Monetary System"
META_AUTHOR="Bernd Hückstädt - Gradido-Akademie"
-# admin
-ADMIN_CONFIG_VERSION=v1.2022-03-18
+# update page shown while updating gradido
+# page will be fed with status changes
+NGINX_UPDATE_PAGE_ROOT=/home/gradido/gradido/deployment/bare_metal/nginx/update-page
+# NGINX SSL Setup with certbot
+# will be generated by start.sh with $COMMUNITY_HOST, only need to setup manual if setup differ from default
+#NGINX_SSL_CERTIFICATE=/etc/letsencrypt/live/gddhost.tld/fullchain.pem
+#NGINX_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/gddhost.tld/privkey.pem
+NGINX_SSL_DHPARAM=/etc/letsencrypt/ssl-dhparams.pem
+NGINX_SSL_INCLUDE=/etc/letsencrypt/options-ssl-nginx.conf
-WALLET_AUTH_URL=https://stage1.gradido.net/authenticate?token={token}
-WALLET_URL=https://stage1.gradido.net/login
+# LEGACY
+NGINX_REWRITE_LEGACY_URLS=false
+DEFAULT_PUBLISHER_ID=2896
+WEBHOOK_ELOPAGE_SECRET=secret
\ No newline at end of file
diff --git a/deployment/bare_metal/doc/server.drawio b/deployment/bare_metal/doc/server.drawio
new file mode 100644
index 000000000..e65220821
--- /dev/null
+++ b/deployment/bare_metal/doc/server.drawio
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/deployment/bare_metal/nginx/sites-available/gradido.conf.ssl.template b/deployment/bare_metal/nginx/sites-available/gradido.conf.ssl.template
index a99327745..b8559a0fb 100644
--- a/deployment/bare_metal/nginx/sites-available/gradido.conf.ssl.template
+++ b/deployment/bare_metal/nginx/sites-available/gradido.conf.ssl.template
@@ -1,16 +1,16 @@
server {
- if ($host = $NGINX_SERVER_NAME) {
+ if ($host = $COMMUNITY_HOST) {
return 301 https://$host$request_uri;
}
- server_name $NGINX_SERVER_NAME;
+ server_name $COMMUNITY_HOST;
listen 80;
listen [::]:80;
return 404;
}
server {
- server_name $NGINX_SERVER_NAME;
+ server_name $COMMUNITY_HOST;
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
diff --git a/deployment/bare_metal/nginx/sites-available/gradido.conf.template b/deployment/bare_metal/nginx/sites-available/gradido.conf.template
index f6149a818..6b885a26a 100644
--- a/deployment/bare_metal/nginx/sites-available/gradido.conf.template
+++ b/deployment/bare_metal/nginx/sites-available/gradido.conf.template
@@ -1,5 +1,5 @@
server {
- server_name $NGINX_SERVER_NAME;
+ server_name $COMMUNITY_HOST;
listen 80;
listen [::]:80;
diff --git a/deployment/bare_metal/nginx/sites-available/update-page.conf.ssl.template b/deployment/bare_metal/nginx/sites-available/update-page.conf.ssl.template
index ddcb9ffc1..06bc5bbc0 100644
--- a/deployment/bare_metal/nginx/sites-available/update-page.conf.ssl.template
+++ b/deployment/bare_metal/nginx/sites-available/update-page.conf.ssl.template
@@ -1,16 +1,16 @@
server {
- if ($host = $NGINX_SERVER_NAME) {
+ if ($host = $COMMUNITY_HOST) {
return 301 https://$host$request_uri;
}
- server_name $NGINX_SERVER_NAME;
+ server_name $COMMUNITY_HOST;
listen 80;
listen [::]:80;
return 404;
}
server {
- server_name $NGINX_SERVER_NAME;
+ server_name $COMMUNITY_HOST;
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
diff --git a/deployment/bare_metal/nginx/sites-available/update-page.conf.template b/deployment/bare_metal/nginx/sites-available/update-page.conf.template
index c26a705ce..e6cb51c7c 100644
--- a/deployment/bare_metal/nginx/sites-available/update-page.conf.template
+++ b/deployment/bare_metal/nginx/sites-available/update-page.conf.template
@@ -1,6 +1,6 @@
server {
- server_name _;
+ server_name $COMMUNITY_HOST;
listen 80;
listen [::]:80;
diff --git a/deployment/bare_metal/start.sh b/deployment/bare_metal/start.sh
index 5d5744bd6..4b6498ee0 100755
--- a/deployment/bare_metal/start.sh
+++ b/deployment/bare_metal/start.sh
@@ -10,12 +10,17 @@ PROJECT_ROOT=$SCRIPT_DIR/../..
NGINX_CONFIG_DIR=$SCRIPT_DIR/nginx/sites-available
set +o allexport
+# enable nvm
+export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
+
# NOTE: all config values will be in process.env when starting
# the services and will therefore take precedence over the .env
# We have to load the backend .env to get DB_USERNAME, DB_PASSWORD AND JWT_SECRET
+# and the dht-node .env to get FEDERATION_DHT_SEED
export_var(){
export $1=$(grep -v '^#' $PROJECT_ROOT/backend/.env | grep -e "$1" | sed -e 's/.*=//')
+ export $1=$(grep -v '^#' $PROJECT_ROOT/dht-node/.env | grep -e "$1" | sed -e 's/.*=//')
}
if [ -f "$PROJECT_ROOT/backend/.env" ]; then
@@ -24,6 +29,10 @@ if [ -f "$PROJECT_ROOT/backend/.env" ]; then
export_var 'JWT_SECRET'
fi
+if [ -f "$PROJECT_ROOT/dht-node/.env" ]; then
+ export_var 'FEDERATION_DHT_SEED'
+fi
+
# Load .env or .env.dist if not present
if [ -f "$SCRIPT_DIR/.env" ]; then
set -o allexport
@@ -35,6 +44,14 @@ else
set +o allexport
fi
+# set env variables dynamic if not already set in .env or .env.dist
+: ${NGINX_SSL_CERTIFICATE:=/etc/letsencrypt/live/$COMMUNITY_HOST/fullchain.pem}
+: ${NGINX_SSL_CERTIFICATE_KEY:=/etc/letsencrypt/live/$COMMUNITY_HOST/privkey.pem}
+
+# export env variables
+export NGINX_SSL_CERTIFICATE
+export NGINX_SSL_CERTIFICATE_KEY
+
# lock start
if [ -f $LOCK_FILE ] ; then
echo "Already building!"
@@ -54,8 +71,7 @@ exec > >(tee -a $UPDATE_HTML) 2>&1
# configure nginx for the update-page
echo 'Configuring nginx to serve the update-page' >> $UPDATE_HTML
-rm /etc/nginx/sites-enabled/gradido.conf
-ln -s /etc/nginx/sites-available/update-page.conf /etc/nginx/sites-enabled/
+ln -sf $SCRIPT_DIR/nginx/sites-available/update-page.conf $SCRIPT_DIR/nginx/sites-enabled/default
sudo /etc/init.d/nginx restart
# stop all services
@@ -100,9 +116,9 @@ export FEDERATION_NGINX_CONF=$(< $NGINX_CONFIG_DIR/gradido-federation.conf.locat
# *** 3rd generate gradido nginx config including federation modules per api-version
echo 'Generate new gradido nginx config' >> $UPDATE_HTML
-case "$NGINX_SSL" in
- true) TEMPLATE_FILE="gradido.conf.ssl.template" ;;
- *) TEMPLATE_FILE="gradido.conf.template" ;;
+case "$URL_PROTOCOL" in
+ 'https') TEMPLATE_FILE="gradido.conf.ssl.template" ;;
+ *) TEMPLATE_FILE="gradido.conf.template" ;;
esac
envsubst '$FEDERATION_NGINX_CONF' < $NGINX_CONFIG_DIR/$TEMPLATE_FILE > $NGINX_CONFIG_DIR/gradido.conf.tmp
unset FEDERATION_NGINX_CONF
@@ -112,9 +128,9 @@ rm $NGINX_CONFIG_DIR/gradido-federation.conf.locations
# Generate update-page.conf from template
echo 'Generate new update-page nginx config' >> $UPDATE_HTML
-case "$NGINX_SSL" in
- true) TEMPLATE_FILE="update-page.conf.ssl.template" ;;
- *) TEMPLATE_FILE="update-page.conf.template" ;;
+case "$URL_PROTOCOL" in
+ 'https') TEMPLATE_FILE="update-page.conf.ssl.template" ;;
+ *) TEMPLATE_FILE="update-page.conf.template" ;;
esac
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $NGINX_CONFIG_DIR/$TEMPLATE_FILE > $NGINX_CONFIG_DIR/update-page.conf
@@ -177,8 +193,7 @@ if [ "$DEPLOY_SEED_DATA" = "true" ]; then
fi
# TODO maybe handle this differently?
export NODE_ENV=production
-pm2 start --name gradido-backend "yarn --cwd $PROJECT_ROOT/backend start" -l $GRADIDO_LOG_PATH/pm2.backend.$TODAY.log --log-date-format 'YYYY-MM-DD HH:mm:ss.SSS'
-pm2 save
+
# Install & build frontend
echo 'Updating frontend' >> $UPDATE_HTML
@@ -189,8 +204,6 @@ yarn install
yarn build
# TODO maybe handle this differently?
export NODE_ENV=production
-pm2 start --name gradido-frontend "yarn --cwd $PROJECT_ROOT/frontend start" -l $GRADIDO_LOG_PATH/pm2.frontend.$TODAY.log --log-date-format 'YYYY-MM-DD HH:mm:ss.SSS'
-pm2 save
# Install & build admin
echo 'Updating admin' >> $UPDATE_HTML
@@ -201,8 +214,6 @@ yarn install
yarn build
# TODO maybe handle this differently?
export NODE_ENV=production
-pm2 start --name gradido-admin "yarn --cwd $PROJECT_ROOT/admin start" -l $GRADIDO_LOG_PATH/pm2.admin.$TODAY.log --log-date-format 'YYYY-MM-DD HH:mm:ss.SSS'
-pm2 save
# Install & build dht-node
echo 'Updating dht-node' >> $UPDATE_HTML
@@ -213,15 +224,6 @@ yarn install
yarn build
# TODO maybe handle this differently?
export NODE_ENV=production
-if [ ! -z $FEDERATION_DHT_TOPIC ]; then
- pm2 start --name gradido-dht-node "yarn --cwd $PROJECT_ROOT/dht-node start" -l $GRADIDO_LOG_PATH/pm2.dht-node.$TODAY.log --log-date-format 'YYYY-MM-DD HH:mm:ss.SSS'
- pm2 save
-else
- echo "=====================================================================" >> $UPDATE_HTML
- echo "WARNING: FEDERATION_DHT_TOPIC not configured. DHT-Node not started..." >> $UPDATE_HTML
- echo "=====================================================================" >> $UPDATE_HTML
-fi
-
# Install & build federation
echo 'Updating federation' >> $UPDATE_HTML
@@ -233,6 +235,20 @@ yarn build
# TODO maybe handle this differently?
export NODE_ENV=production
+# start after building all to use up less ressources
+pm2 start --name gradido-backend "yarn --cwd $PROJECT_ROOT/backend start" -l $GRADIDO_LOG_PATH/pm2.backend.$TODAY.log --log-date-format 'YYYY-MM-DD HH:mm:ss.SSS'
+pm2 start --name gradido-frontend "yarn --cwd $PROJECT_ROOT/frontend start" -l $GRADIDO_LOG_PATH/pm2.frontend.$TODAY.log --log-date-format 'YYYY-MM-DD HH:mm:ss.SSS'
+pm2 start --name gradido-admin "yarn --cwd $PROJECT_ROOT/admin start" -l $GRADIDO_LOG_PATH/pm2.admin.$TODAY.log --log-date-format 'YYYY-MM-DD HH:mm:ss.SSS'
+pm2 save
+if [ ! -z $FEDERATION_DHT_TOPIC ]; then
+ pm2 start --name gradido-dht-node "yarn --cwd $PROJECT_ROOT/dht-node start" -l $GRADIDO_LOG_PATH/pm2.dht-node.$TODAY.log --log-date-format 'YYYY-MM-DD HH:mm:ss.SSS'
+ pm2 save
+else
+ echo "=====================================================================" >> $UPDATE_HTML
+ echo "WARNING: FEDERATION_DHT_TOPIC not configured. DHT-Node not started..." >> $UPDATE_HTML
+ echo "=====================================================================" >> $UPDATE_HTML
+fi
+
# set FEDERATION_PORT from FEDERATION_COMMUNITY_APIS
IFS="," read -a API_ARRAY <<< $FEDERATION_COMMUNITY_APIS
for api in "${API_ARRAY[@]}"
@@ -254,13 +270,9 @@ do
pm2 save
done
-
-
-
# let nginx showing gradido
echo 'Configuring nginx to serve gradido again' >> $UPDATE_HTML
-ln -s /etc/nginx/sites-available/gradido.conf /etc/nginx/sites-enabled/
-rm /etc/nginx/sites-enabled/update-page.conf
+ln -sf $SCRIPT_DIR/nginx/sites-available/gradido.conf $SCRIPT_DIR/nginx/sites-enabled/default
sudo /etc/init.d/nginx restart
# keep the update log
diff --git a/deployment/hetzner_cloud/README.md b/deployment/hetzner_cloud/README.md
new file mode 100644
index 000000000..d03ff0b46
--- /dev/null
+++ b/deployment/hetzner_cloud/README.md
@@ -0,0 +1,124 @@
+# Setup on Hetzner Cloud Server
+Suggested minimal Plan: CX41
+4x vCPU, 16 GB Ram, 160 GB Disk Space, 20.71 € per month (04.01.2024)
+
+Suggested OS:
+Debian 12
+
+For Hetzner Cloud Server a cloud config can be attached, which will be run before first start
+https://community.hetzner.com/tutorials/basic-cloud-config/de
+https://cloudinit.readthedocs.io/en/latest/reference/examples.html
+You can use our [cloudConfig.yaml](./cloudConfig.yaml) but you must insert you own ssh public key,
+like this:
+```yaml
+ssh_authorized_keys:
+ - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAkLGbzbG7KIGfkssKJBkc/0EVAzQ/8vjvVHzNdxhK8J yourname
+```
+
+## After Setup Cloud Server with cloudConfig.yaml
+### setup your domain pointing on server ip address
+### login to your new server as root
+```bash
+ssh -i /path/to/privKey root@gddhost.tld
+```
+
+### Change default shell
+
+```bash
+chsh -s /bin/bash
+chsh -s /bin/bash gradido
+```
+
+### Set password for user `gradido`
+
+```bash
+$ passwd gradido
+# enter new password twice
+```
+
+### Switch to the new user
+
+```bash
+su gradido
+```
+
+### Test authentication via SSH
+
+If you logout from the server you can test authentication:
+
+```bash
+$ ssh -i /path/to/privKey gradido@gddhost.tld
+# This should log you in and allow you to use sudo commands, which will require the user's password
+```
+
+### Disable password root login via ssh
+
+```bash
+sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.org
+sudo sed -i -e '/^\(#\|\)PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config
+sudo sed -i '$a AllowUsers gradido' /etc/ssh/sshd_config
+sudo /etc/init.d/ssh restart
+```
+
+### Test SSH Access only, no root ssh access
+
+```bash
+$ ssh gradido@gddhost.tld
+# Will result in in either a passphrase request for your key or the message 'Permission denied (publickey)'
+$ ssh -i /path/to/privKey root@gddhost.tld
+# Will result in 'Permission denied (publickey)'
+$ ssh -i /path/to/privKey gradido@gddhost.tld
+# Will succeed after entering the correct keys passphrase (if any)
+```
+
+### Install `Gradido` code
+```bash
+cd ~
+git clone https://github.com/gradido/gradido.git
+```
+
+### Adjust the values in `.env`
+
+***!!! Attention !!!***
+
+*Don't forget this step!
+All your following installations in `install.sh` will fail!*
+
+*Notes:*
+
+- *`;` cannot be part of any value!*
+- *The GitHub secret is created on GitHub in Settings -> Webhooks.*
+
+#### Create `.env` and set values
+
+```bash
+cd ~/gradido/deployment/bare_metal
+cp .env.dist .env
+nano .env
+
+# adjust values accordingly
+```
+
+### Run `install.sh`
+***!!! Attention !!!***
+Don't use this script if you have custom config in /etc/nginx/conf.d, because this script
+will remove it and ln ../bare_metal/nginx/conf.d
+
+```bash
+cd ~/gradido/deployment/hetzner_cloud
+sudo ./install.sh
+```
+
+### Make yourself admin
+- Create an account on your new gradido instance
+- Click the link in the activation email
+- go back to your ssh session and copy this command
+
+```bash
+sudo mysql -D gradido_community -e "insert into user_roles(user_id, role) values((select id from users order by id desc limit 1), 'ADMIN');"
+```
+
+- it will make last registered user admin
+- login with you newly created user
+- if you has a link to `Admin Area` it worked and you are admin
+
diff --git a/deployment/hetzner_cloud/cloudConfig.yaml b/deployment/hetzner_cloud/cloudConfig.yaml
new file mode 100644
index 000000000..86e7d5724
--- /dev/null
+++ b/deployment/hetzner_cloud/cloudConfig.yaml
@@ -0,0 +1,46 @@
+#cloud-config
+users:
+ - name: gradido
+ groups: users, admin, sudo
+ sudo: ALL=(ALL) NOPASSWD:/etc/init.d/nginx start,/etc/init.d/nginx stop,/etc/init.d/nginx restart
+ shell: /bin/bash
+ ssh_authorized_keys:
+ -
+
+packages:
+ - fail2ban
+ - ufw
+ - git
+ - mariadb-server
+ - nginx
+ - curl
+ - build-essential
+ - gnupg
+ - certbot
+ - python3-certbot-nginx
+ - logrotate
+ - automysqlbackup
+ - expect
+package_update: true
+package_upgrade: true
+
+runcmd:
+- printf "[sshd]\nenabled = true\nbanaction = iptables-multiport" > /etc/fail2ban/jail.local
+- systemctl enable fail2ban
+
+- ufw allow OpenSSH
+- ufw allow http
+- ufw allow https
+- ufw enable
+
+- sed -i -e '/^\(#\|\)PasswordAuthentication/s/^.*$/PasswordAuthentication no/' /etc/ssh/sshd_config
+- sed -i -e '/^\(#\|\)KbdInteractiveAuthentication/s/^.*$/KbdInteractiveAuthentication no/' /etc/ssh/sshd_config
+- sed -i -e '/^\(#\|\)ChallengeResponseAuthentication/s/^.*$/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config
+- sed -i -e '/^\(#\|\)MaxAuthTries/s/^.*$/MaxAuthTries 3/' /etc/ssh/sshd_config
+- sed -i -e '/^\(#\|\)AllowTcpForwarding/s/^.*$/AllowTcpForwarding no/' /etc/ssh/sshd_config
+- sed -i -e '/^\(#\|\)X11Forwarding/s/^.*$/X11Forwarding no/' /etc/ssh/sshd_config
+- sed -i -e '/^\(#\|\)AllowAgentForwarding/s/^.*$/AllowAgentForwarding no/' /etc/ssh/sshd_config
+- sed -i -e '/^\(#\|\)AuthorizedKeysFile/s/^.*$/AuthorizedKeysFile .ssh\/authorized_keys/' /etc/ssh/sshd_config
+- sed -i '$a AllowUsers gradido root' /etc/ssh/sshd_config
+
+- reboot
\ No newline at end of file
diff --git a/deployment/hetzner_cloud/crontabs.txt b/deployment/hetzner_cloud/crontabs.txt
new file mode 100644
index 000000000..c798b58c4
--- /dev/null
+++ b/deployment/hetzner_cloud/crontabs.txt
@@ -0,0 +1,38 @@
+# Edit this file to introduce tasks to be run by cron.
+#
+# Each task to run has to be defined through a single line
+# indicating with different fields when the task will be run
+# and what command to run for the task
+#
+# To define the time you can provide concrete values for
+# minute (m), hour (h), day of month (dom), month (mon),
+# and day of week (dow) or use '*' in these fields (for 'any').
+#
+# Notice that tasks will be started based on the cron's system
+# daemon's notion of time and timezones.
+#
+# Output of the crontab jobs (including errors) is sent through
+# email to the user the crontab file belongs to (unless redirected).
+#
+# For example, you can run a backup of all your user accounts
+# at 5 a.m every week with:
+# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
+#
+# For more information see the manual pages of crontab(5) and cron(8)
+#
+# m h dom mon dow command
+
+# `yarn` creates output in `/tmp` directory. This output is generated whenever `yarn start` is called.
+# This is especially problematic on staging systems where instable versions are automatically deployed which can lead to an ever restarting,
+# hence generating a lot of yarn output.
+# the following hourly cron clean the /tmp folder
+0 * * * * find /tmp -name "yarn--*" -exec rm -r {} \; > /dev/null
+
+# cronjob for a daily db backup at 3:00am
+0 3 * * * ~/gradido/deployment/bare_metal/backup.sh
+
+# cronjob for a daily logfile clearance at 3:15
+# remove all log files older than 30 days
+15 3 * * * ~/gradido/deployment/bare_metal/removeLogFiles.sh
+
+
diff --git a/deployment/hetzner_cloud/install.sh b/deployment/hetzner_cloud/install.sh
new file mode 100755
index 000000000..ee539370c
--- /dev/null
+++ b/deployment/hetzner_cloud/install.sh
@@ -0,0 +1,153 @@
+#!/bin/bash
+
+# Note: This is needed - since there is Summer-Time included in the default server Setup - UTC is REQUIRED for production data
+timedatectl set-timezone UTC
+timedatectl set-ntp on
+apt purge ntp
+systemctl start systemd-timesyncd
+
+set -o allexport
+SCRIPT_PATH=$(realpath ../bare_metal)
+SCRIPT_DIR=$(dirname $SCRIPT_PATH)
+LOCAL_SCRIPT_PATH=$(realpath $0)
+LOCAL_SCRIPT_DIR=$(dirname $LOCAL_SCRIPT_PATH)
+PROJECT_ROOT=$SCRIPT_DIR/..
+set +o allexport
+
+# If install.sh will be called more than once
+# We have to load the backend .env to get DB_USERNAME, DB_PASSWORD AND JWT_SECRET
+# and the dht-node .env to get FEDERATION_DHT_SEED
+export_var(){
+ export $1=$(grep -v '^#' $PROJECT_ROOT/backend/.env | grep -e "$1" | sed -e 's/.*=//')
+ export $1=$(grep -v '^#' $PROJECT_ROOT/dht-node/.env | grep -e "$1" | sed -e 's/.*=//')
+}
+
+if [ -f "$PROJECT_ROOT/backend/.env" ]; then
+ export_var 'DB_USER'
+ export_var 'DB_PASSWORD'
+ export_var 'JWT_SECRET'
+fi
+
+if [ -f "$PROJECT_ROOT/dht-node/.env" ]; then
+ export_var 'FEDERATION_DHT_SEED'
+fi
+
+
+# Load .env or .env.dist if not present
+# NOTE: all config values will be in process.env when starting
+# the services and will therefore take precedence over the .env
+if [ -f "$SCRIPT_PATH/.env" ]; then
+ set -o allexport
+ source $SCRIPT_PATH/.env
+ set +o allexport
+else
+ set -o allexport
+ source $SCRIPT_PATH/.env.dist
+ set +o allexport
+fi
+
+# Configure git
+git config pull.ff only
+
+# Secure mysql https://gist.github.com/Mins/4602864
+SECURE_MYSQL=$(expect -c "
+
+set timeout 10
+spawn mysql_secure_installation
+
+expect \"Enter current password for root (enter for none):\"
+send \"\r\"
+
+expect \"Switch to unix_socket authentication:\"
+send \"Y\r\"
+
+expect \"Change the root password?\"
+send \"n\r\"
+
+expect \"Remove anonymous users?\"
+send \"y\r\"
+
+expect \"Disallow root login remotely?\"
+send \"y\r\"
+
+expect \"Remove test database and access to it?\"
+send \"y\r\"
+
+expect \"Reload privilege tables now?\"
+send \"y\r\"
+
+expect eof
+")
+echo "$SECURE_MYSQL"
+
+# Configure nginx
+rm /etc/nginx/sites-enabled/default
+envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $SCRIPT_PATH/nginx/sites-available/gradido.conf.template > $SCRIPT_PATH/nginx/sites-available/gradido.conf
+envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $SCRIPT_PATH/nginx/sites-available/update-page.conf.template > $SCRIPT_PATH/nginx/sites-available/update-page.conf
+mkdir $SCRIPT_PATH/nginx/sites-enabled
+ln -s $SCRIPT_PATH/nginx/sites-available/update-page.conf $SCRIPT_PATH/nginx/sites-enabled/default
+ln -s $SCRIPT_PATH/nginx/sites-enabled/default /etc/nginx/sites-enabled
+ln -s $SCRIPT_PATH/nginx/common /etc/nginx/
+rmdir /etc/nginx/conf.d
+ln -s $SCRIPT_PATH/nginx/conf.d /etc/nginx/
+
+# setup https with certbot
+certbot certonly --nginx --non-interactive --agree-tos --domains $COMMUNITY_HOST --email $COMMUNITY_SUPPORT_MAIL
+
+# Install node 16. with nvm, with nodesource is depracted
+sudo -u gradido bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash'
+# Close and reopen your terminal to start using nvm or run the following to use it now:
+sudo -u gradido bash -c 'export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"'
+sudo -u gradido bash -c '. $HOME/.nvm/nvm.sh && nvm install 16' # first installed version will be set to default automatic
+
+# Install yarn
+sudo -u gradido bash -c '. $HOME/.nvm/nvm.sh && npm i -g yarn'
+
+# Install pm2
+sudo -u gradido bash -c '. $HOME/.nvm/nvm.sh && npm i -g pm2 && pm2 startup'
+
+# Install logrotate
+envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $SCRIPT_PATH/logrotate/gradido.conf.template > $SCRIPT_PATH/logrotate/gradido.conf
+cp $SCRIPT_PATH/logrotate/gradido.conf /etc/logrotate.d/gradido.conf
+
+# create db user
+export DB_USER=gradido
+# create a new password only if it not already exist
+if [ -z "${DB_PASSWORD}" ]; then
+ export DB_PASSWORD=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo);
+fi
+mysql < $PROJECT_ROOT/database/.env
+
+# Configure backend
+export JWT_SECRET=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo);
+envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/backend/.env.template > $PROJECT_ROOT/backend/.env
+
+# Configure frontend
+envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/frontend/.env.template > $PROJECT_ROOT/frontend/.env
+
+# Configure admin
+envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/admin/.env.template > $PROJECT_ROOT/admin/.env
+
+# Configure dht-node
+export FEDERATION_DHT_SEED=$(< /dev/urandom tr -dc a-f0-9 | head -c 32;echo);
+envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/dht-node/.env.template > $PROJECT_ROOT/dht-node/.env
+
+# Configure federation
+envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/federation/.env.template > $PROJECT_ROOT/federation/.env
+
+# set all created or modified files back to belonging to gradido
+chown -R gradido:gradido $PROJECT_ROOT
+
+# create cronjob to delete yarn output in /tmp and for making backups regulary
+sudo -u gradido crontab < $LOCAL_SCRIPT_DIR/crontabs.txt
+
+# Start gradido
+# Note: on first startup some errors will occur - nothing serious
+sudo -u gradido $SCRIPT_PATH/start.sh
\ No newline at end of file
diff --git a/dht-node/.env.template b/dht-node/.env.template
index 324d2c3a7..3517ccc9a 100644
--- a/dht-node/.env.template
+++ b/dht-node/.env.template
@@ -21,4 +21,6 @@ FEDERATION_DHT_TOPIC=$FEDERATION_DHT_TOPIC
FEDERATION_DHT_SEED=$FEDERATION_DHT_SEED
FEDERATION_COMMUNITY_URL=$FEDERATION_COMMUNITY_URL
# comma separated values, which apis should be announced
-FEDERATION_COMMUNITY_APIS=$FEDERATION_COMMUNITY_APIS
\ No newline at end of file
+FEDERATION_COMMUNITY_APIS=$FEDERATION_COMMUNITY_APIS
+COMMUNITY_HOST=$COMMUNITY_HOST
+URL_PROTOCOL=$URL_PROTOCOL
diff --git a/dht-node/src/config/index.ts b/dht-node/src/config/index.ts
index 3599dd3c4..fd3df5c21 100644
--- a/dht-node/src/config/index.ts
+++ b/dht-node/src/config/index.ts
@@ -7,7 +7,7 @@ const constants = {
DB_VERSION: '0080-fill_linked_user_gradidoId_of_contributions',
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info
- LOG_LEVEL: process.env.LOG_LEVEL || 'info',
+ LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v4.2024-01-17',
@@ -16,34 +16,38 @@ const constants = {
}
const server = {
- PRODUCTION: process.env.NODE_ENV === 'production' || false,
+ PRODUCTION: process.env.NODE_ENV === 'production' ?? false,
}
const database = {
- DB_HOST: process.env.DB_HOST || 'localhost',
+ DB_HOST: process.env.DB_HOST ?? 'localhost',
DB_PORT: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306,
- DB_USER: process.env.DB_USER || 'root',
- DB_PASSWORD: process.env.DB_PASSWORD || '',
- DB_DATABASE: process.env.DB_DATABASE || 'gradido_community',
+ DB_USER: process.env.DB_USER ?? 'root',
+ DB_PASSWORD: process.env.DB_PASSWORD ?? '',
+ DB_DATABASE: process.env.DB_DATABASE ?? 'gradido_community',
TYPEORM_LOGGING_RELATIVE_PATH:
- process.env.TYPEORM_LOGGING_RELATIVE_PATH || 'typeorm.dht-node.log',
+ process.env.TYPEORM_LOGGING_RELATIVE_PATH ?? 'typeorm.dht-node.log',
}
const community = {
- COMMUNITY_NAME: process.env.COMMUNITY_NAME || 'Gradido Entwicklung',
+ COMMUNITY_NAME: process.env.COMMUNITY_NAME ?? 'Gradido Entwicklung',
COMMUNITY_DESCRIPTION:
- process.env.COMMUNITY_DESCRIPTION || 'Gradido-Community einer lokalen Entwicklungsumgebung.',
+ process.env.COMMUNITY_DESCRIPTION ?? 'Gradido-Community einer lokalen Entwicklungsumgebung.',
}
+const COMMUNITY_HOST = process.env.COMMUNITY_HOST ?? 'localhost'
+const URL_PROTOCOL = process.env.URL_PROTOCOL ?? 'http'
+const COMMUNITY_URL = process.env.COMMUNITY_URL ?? `${URL_PROTOCOL}://${COMMUNITY_HOST}`
+
const federation = {
- FEDERATION_DHT_TOPIC: process.env.FEDERATION_DHT_TOPIC || 'GRADIDO_HUB',
- FEDERATION_DHT_SEED: process.env.FEDERATION_DHT_SEED || null,
- FEDERATION_COMMUNITY_URL: process.env.FEDERATION_COMMUNITY_URL || 'http://localhost',
- FEDERATION_COMMUNITY_APIS: process.env.FEDERATION_COMMUNITY_APIS || '1_0',
+ FEDERATION_DHT_TOPIC: process.env.FEDERATION_DHT_TOPIC ?? 'GRADIDO_HUB',
+ FEDERATION_DHT_SEED: process.env.FEDERATION_DHT_SEED ?? null,
+ FEDERATION_COMMUNITY_URL: process.env.FEDERATION_COMMUNITY_URL ?? COMMUNITY_URL,
+ FEDERATION_COMMUNITY_APIS: process.env.FEDERATION_COMMUNITY_APIS ?? '1_0',
}
// Check config version
-constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION || constants.CONFIG_VERSION.DEFAULT
+constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION ?? constants.CONFIG_VERSION.DEFAULT
if (
![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes(
constants.CONFIG_VERSION.CURRENT,
diff --git a/dlt-connector/jest.config.js b/dlt-connector/jest.config.js
index 2de18cf50..69bc64bb2 100644
--- a/dlt-connector/jest.config.js
+++ b/dlt-connector/jest.config.js
@@ -6,7 +6,7 @@ module.exports = {
collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**', '!src/seeds/**', '!build/**'],
coverageThreshold: {
global: {
- lines: 71,
+ lines: 66,
},
},
setupFiles: ['/test/testSetup.ts'],
diff --git a/dlt-connector/src/config/index.ts b/dlt-connector/src/config/index.ts
index c129af2ea..e6febb482 100644
--- a/dlt-connector/src/config/index.ts
+++ b/dlt-connector/src/config/index.ts
@@ -6,7 +6,7 @@ const constants = {
LOG4JS_CONFIG: 'log4js-config.json',
DB_VERSION: '0003-refactor_transaction_recipe',
// default log level on production should be info
- LOG_LEVEL: process.env.LOG_LEVEL || 'info',
+ LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v4.2023-09-12',
@@ -15,7 +15,7 @@ const constants = {
}
const server = {
- PRODUCTION: process.env.NODE_ENV === 'production' || false,
+ PRODUCTION: process.env.NODE_ENV === 'production' ?? false,
}
const database = {
@@ -35,11 +35,11 @@ const iota = {
}
const dltConnector = {
- DLT_CONNECTOR_PORT: process.env.DLT_CONNECTOR_PORT || 6010,
+ DLT_CONNECTOR_PORT: process.env.DLT_CONNECTOR_PORT ?? 6010,
}
// Check config version
-constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION || constants.CONFIG_VERSION.DEFAULT
+constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION ?? constants.CONFIG_VERSION.DEFAULT
if (
![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes(
constants.CONFIG_VERSION.CURRENT,
diff --git a/dlt-connector/src/data/proto/3_3/GradidoTransaction.ts b/dlt-connector/src/data/proto/3_3/GradidoTransaction.ts
index 4aaa3e25c..f38bcbd1f 100644
--- a/dlt-connector/src/data/proto/3_3/GradidoTransaction.ts
+++ b/dlt-connector/src/data/proto/3_3/GradidoTransaction.ts
@@ -1,5 +1,8 @@
import { Field, Message } from 'protobufjs'
+import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType'
+import { TransactionError } from '@/graphql/model/TransactionError'
+import { logger } from '@/logging/logger'
import { LogError } from '@/server/LogError'
import { SignatureMap } from './SignatureMap'
@@ -41,4 +44,16 @@ export class GradidoTransaction extends Message {
}
return sigPair[0]
}
+
+ getTransactionBody(): TransactionBody {
+ try {
+ return TransactionBody.decode(new Uint8Array(this.bodyBytes))
+ } catch (error) {
+ logger.error('error decoding body from gradido transaction: %s', error)
+ throw new TransactionError(
+ TransactionErrorType.PROTO_DECODE_ERROR,
+ 'cannot decode body from gradido transaction',
+ )
+ }
+ }
}
diff --git a/dlt-connector/src/graphql/resolver/CommunityResolver.ts b/dlt-connector/src/graphql/resolver/CommunityResolver.ts
index d4bbeb28e..741de2e6d 100644
--- a/dlt-connector/src/graphql/resolver/CommunityResolver.ts
+++ b/dlt-connector/src/graphql/resolver/CommunityResolver.ts
@@ -9,8 +9,8 @@ import { TransactionResult } from '@model/TransactionResult'
import { CommunityRepository } from '@/data/Community.repository'
import { AddCommunityContext } from '@/interactions/backendToDb/community/AddCommunity.context'
+import { logger } from '@/logging/logger'
import { LogError } from '@/server/LogError'
-import { logger } from '@/server/logger'
import { iotaTopicFromCommunityUUID } from '@/utils/typeConverter'
@Resolver()
diff --git a/dlt-connector/src/graphql/resolver/TransactionsResolver.ts b/dlt-connector/src/graphql/resolver/TransactionsResolver.ts
index 10b55573e..6a5017fb1 100755
--- a/dlt-connector/src/graphql/resolver/TransactionsResolver.ts
+++ b/dlt-connector/src/graphql/resolver/TransactionsResolver.ts
@@ -4,6 +4,9 @@ import { TransactionDraft } from '@input/TransactionDraft'
import { TransactionRepository } from '@/data/Transaction.repository'
import { CreateTransactionRecipeContext } from '@/interactions/backendToDb/transaction/CreateTransationRecipe.context'
+import { BackendTransactionLoggingView } from '@/logging/BackendTransactionLogging.view'
+import { logger } from '@/logging/logger'
+import { TransactionLoggingView } from '@/logging/TransactionLogging.view'
import { LogError } from '@/server/LogError'
import { TransactionError } from '../model/TransactionError'
@@ -35,8 +38,13 @@ export class TransactionResolver {
}
const backendTransaction = transactionRecipe.backendTransactions[0]
backendTransaction.transactionId = transactionRecipe.id
+ logger.debug(
+ 'store backendTransaction',
+ new BackendTransactionLoggingView(backendTransaction),
+ )
await backendTransaction.save()
} else {
+ logger.debug('store transaction recipe', new TransactionLoggingView(transactionRecipe))
// we can store the transaction and with that automatic the backend transaction
await transactionRecipe.save()
}
diff --git a/dlt-connector/src/graphql/schema.ts b/dlt-connector/src/graphql/schema.ts
index 19a6d5566..bbd61c63f 100755
--- a/dlt-connector/src/graphql/schema.ts
+++ b/dlt-connector/src/graphql/schema.ts
@@ -10,7 +10,6 @@ export const schema = async (): Promise => {
return buildSchema({
resolvers: [TransactionResolver, CommunityResolver],
scalarsMap: [{ type: Decimal, scalar: DecimalScalar }],
- emitSchemaFile: true,
validate: {
validationError: { target: false },
skipMissingProperties: true,
diff --git a/dlt-connector/src/interactions/backendToDb/community/Community.role.ts b/dlt-connector/src/interactions/backendToDb/community/Community.role.ts
index 30d91bfed..2b1514ef2 100644
--- a/dlt-connector/src/interactions/backendToDb/community/Community.role.ts
+++ b/dlt-connector/src/interactions/backendToDb/community/Community.role.ts
@@ -3,7 +3,8 @@ import { Community } from '@entity/Community'
import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType'
import { CommunityDraft } from '@/graphql/input/CommunityDraft'
import { TransactionError } from '@/graphql/model/TransactionError'
-import { logger } from '@/server/logger'
+import { CommunityLoggingView } from '@/logging/CommunityLogging.view'
+import { logger } from '@/logging/logger'
export abstract class CommunityRole {
protected self: Community
@@ -17,9 +18,11 @@ export abstract class CommunityRole {
this.self.foreign = communityDraft.foreign
}
- public store(): Promise {
+ public async store(): Promise {
try {
- return this.self.save()
+ const community = await this.self.save()
+ logger.debug('store community', new CommunityLoggingView(community))
+ return community
} catch (error) {
logger.error('error saving new community into db: %s', error)
throw new TransactionError(TransactionErrorType.DB_ERROR, 'error saving community into db')
diff --git a/dlt-connector/src/interactions/backendToDb/community/HomeCommunity.role.ts b/dlt-connector/src/interactions/backendToDb/community/HomeCommunity.role.ts
index 256cfe1a5..7a4798368 100644
--- a/dlt-connector/src/interactions/backendToDb/community/HomeCommunity.role.ts
+++ b/dlt-connector/src/interactions/backendToDb/community/HomeCommunity.role.ts
@@ -8,7 +8,8 @@ import { Mnemonic } from '@/data/Mnemonic'
import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType'
import { CommunityDraft } from '@/graphql/input/CommunityDraft'
import { TransactionError } from '@/graphql/model/TransactionError'
-import { logger } from '@/server/logger'
+import { CommunityLoggingView } from '@/logging/CommunityLogging.view'
+import { logger } from '@/logging/logger'
import { getDataSource } from '@/typeorm/DataSource'
import { CreateTransactionRecipeContext } from '../transaction/CreateTransationRecipe.context'
@@ -38,6 +39,7 @@ export class HomeCommunityRole extends CommunityRole {
return await getDataSource().transaction(async (transactionalEntityManager) => {
const community = await transactionalEntityManager.save(this.self)
await transactionalEntityManager.save(this.transactionRecipe)
+ logger.debug('store home community', new CommunityLoggingView(community))
return community
})
} catch (error) {
diff --git a/dlt-connector/src/logging/AbstractLogging.view.ts b/dlt-connector/src/logging/AbstractLogging.view.ts
new file mode 100644
index 000000000..ad52e6530
--- /dev/null
+++ b/dlt-connector/src/logging/AbstractLogging.view.ts
@@ -0,0 +1,49 @@
+import util from 'util'
+
+import { Decimal } from 'decimal.js-light'
+
+import { Timestamp } from '@/data/proto/3_3/Timestamp'
+import { TimestampSeconds } from '@/data/proto/3_3/TimestampSeconds'
+import { timestampSecondsToDate, timestampToDate } from '@/utils/typeConverter'
+
+export abstract class AbstractLoggingView {
+ protected bufferStringFormat: BufferEncoding = 'hex'
+
+ // This function gets called automatically when JSON.stringify() is called on this class instance
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public abstract toJSON(): any
+ public toString(): string {
+ return JSON.stringify(this.toJSON(), null, 2)
+ }
+
+ // called form console.log or log4js logging functions
+ [util.inspect.custom](): string {
+ return this.toString()
+ }
+
+ protected dateToString(date: Date | undefined | null): string | undefined {
+ if (date) {
+ return date.toISOString()
+ }
+ return undefined
+ }
+
+ protected decimalToString(number: Decimal | undefined | null): string | undefined {
+ if (number) {
+ return number.toString()
+ }
+ return undefined
+ }
+
+ protected timestampSecondsToDateString(timestamp: TimestampSeconds): string | undefined {
+ if (timestamp && timestamp.seconds) {
+ return timestampSecondsToDate(timestamp).toISOString()
+ }
+ }
+
+ protected timestampToDateString(timestamp: Timestamp): string | undefined {
+ if (timestamp && (timestamp.seconds || timestamp.nanoSeconds)) {
+ return timestampToDate(timestamp).toISOString()
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/AccountLogging.view.ts b/dlt-connector/src/logging/AccountLogging.view.ts
new file mode 100644
index 000000000..76ff7b891
--- /dev/null
+++ b/dlt-connector/src/logging/AccountLogging.view.ts
@@ -0,0 +1,29 @@
+import { Account } from '@entity/Account'
+
+import { AddressType } from '@/data/proto/3_3/enum/AddressType'
+import { getEnumValue } from '@/utils/typeConverter'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { UserLoggingView } from './UserLogging.view'
+
+export class AccountLoggingView extends AbstractLoggingView {
+ public constructor(private account: Account) {
+ super()
+ }
+
+ public toJSON() {
+ return {
+ id: this.account.id,
+ user: this.account.user ? new UserLoggingView(this.account.user).toJSON() : null,
+ derivationIndex: this.account.derivationIndex,
+ derive2pubkey: this.account.derive2Pubkey.toString(this.bufferStringFormat),
+ type: getEnumValue(AddressType, this.account.type),
+ createdAt: this.dateToString(this.account.createdAt),
+ confirmedAt: this.dateToString(this.account.confirmedAt),
+ balanceOnConfirmation: this.decimalToString(this.account.balanceOnConfirmation),
+ balanceConfirmedAt: this.dateToString(this.account.balanceConfirmedAt),
+ balanceOnCreation: this.decimalToString(this.account.balanceOnCreation),
+ balanceCreatedAt: this.dateToString(this.account.balanceCreatedAt),
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/BackendTransactionLogging.view.ts b/dlt-connector/src/logging/BackendTransactionLogging.view.ts
new file mode 100644
index 000000000..d21c765aa
--- /dev/null
+++ b/dlt-connector/src/logging/BackendTransactionLogging.view.ts
@@ -0,0 +1,30 @@
+import { BackendTransaction } from '@entity/BackendTransaction'
+
+import { InputTransactionType } from '@/graphql/enum/InputTransactionType'
+import { getEnumValue } from '@/utils/typeConverter'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { TransactionLoggingView } from './TransactionLogging.view'
+
+export class BackendTransactionLoggingView extends AbstractLoggingView {
+ public constructor(private self: BackendTransaction) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(showTransaction = true): any {
+ return {
+ id: this.self.id,
+ backendTransactionId: this.self.backendTransactionId,
+ transaction:
+ showTransaction && this.self.transaction
+ ? new TransactionLoggingView(this.self.transaction).toJSON(false)
+ : undefined,
+ type: getEnumValue(InputTransactionType, this.self.typeId),
+ balance: this.decimalToString(this.self.balance),
+ createdAt: this.dateToString(this.self.createdAt),
+ confirmedAt: this.dateToString(this.self.confirmedAt),
+ verifiedOnBackend: this.self.verifiedOnBackend,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/CommunityLogging.view.ts b/dlt-connector/src/logging/CommunityLogging.view.ts
new file mode 100644
index 000000000..22f0a4597
--- /dev/null
+++ b/dlt-connector/src/logging/CommunityLogging.view.ts
@@ -0,0 +1,24 @@
+import { Community } from '@entity/Community'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { AccountLoggingView } from './AccountLogging.view'
+
+export class CommunityLoggingView extends AbstractLoggingView {
+ public constructor(private self: Community) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ id: this.self.id,
+ iotaTopic: this.self.iotaTopic,
+ foreign: this.self.foreign,
+ publicKey: this.self.rootPubkey?.toString(this.bufferStringFormat),
+ createdAt: this.dateToString(this.self.createdAt),
+ confirmedAt: this.dateToString(this.self.confirmedAt),
+ aufAccount: this.self.aufAccount ? new AccountLoggingView(this.self.aufAccount) : undefined,
+ gmwAccount: this.self.gmwAccount ? new AccountLoggingView(this.self.gmwAccount) : undefined,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/CommunityRootLogging.view.ts b/dlt-connector/src/logging/CommunityRootLogging.view.ts
new file mode 100644
index 000000000..ba2869755
--- /dev/null
+++ b/dlt-connector/src/logging/CommunityRootLogging.view.ts
@@ -0,0 +1,18 @@
+import { CommunityRoot } from '@/data/proto/3_3/CommunityRoot'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+
+export class CommunityRootLoggingView extends AbstractLoggingView {
+ public constructor(private self: CommunityRoot) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ rootPubkey: Buffer.from(this.self.rootPubkey).toString(this.bufferStringFormat),
+ gmwPubkey: Buffer.from(this.self.gmwPubkey).toString(this.bufferStringFormat),
+ aufPubkey: Buffer.from(this.self.aufPubkey).toString(this.bufferStringFormat),
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/ConfirmedTransactionLogging.view.ts b/dlt-connector/src/logging/ConfirmedTransactionLogging.view.ts
new file mode 100644
index 000000000..8e894a35a
--- /dev/null
+++ b/dlt-connector/src/logging/ConfirmedTransactionLogging.view.ts
@@ -0,0 +1,24 @@
+import { ConfirmedTransaction } from '@/data/proto/3_3/ConfirmedTransaction'
+import { timestampSecondsToDate } from '@/utils/typeConverter'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { GradidoTransactionLoggingView } from './GradidoTransactionLogging.view'
+
+export class ConfirmedTransactionLoggingView extends AbstractLoggingView {
+ public constructor(private self: ConfirmedTransaction) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ id: this.self.id.toString(),
+ transaction: new GradidoTransactionLoggingView(this.self.transaction).toJSON(),
+ confirmedAt: this.dateToString(timestampSecondsToDate(this.self.confirmedAt)),
+ versionNumber: this.self.versionNumber,
+ runningHash: Buffer.from(this.self.runningHash).toString(this.bufferStringFormat),
+ messageId: Buffer.from(this.self.messageId).toString(this.bufferStringFormat),
+ accountBalance: this.self.accountBalance,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/GradidoCreationLogging.view.ts b/dlt-connector/src/logging/GradidoCreationLogging.view.ts
new file mode 100644
index 000000000..43e14b887
--- /dev/null
+++ b/dlt-connector/src/logging/GradidoCreationLogging.view.ts
@@ -0,0 +1,18 @@
+import { GradidoCreation } from '@/data/proto/3_3/GradidoCreation'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { TransferAmountLoggingView } from './TransferAmountLogging.view'
+
+export class GradidoCreationLoggingView extends AbstractLoggingView {
+ public constructor(private self: GradidoCreation) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ recipient: new TransferAmountLoggingView(this.self.recipient).toJSON(),
+ targetDate: this.timestampSecondsToDateString(this.self.targetDate),
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/GradidoDeferredTransferLogging.view.ts b/dlt-connector/src/logging/GradidoDeferredTransferLogging.view.ts
new file mode 100644
index 000000000..89a1f1a29
--- /dev/null
+++ b/dlt-connector/src/logging/GradidoDeferredTransferLogging.view.ts
@@ -0,0 +1,18 @@
+import { GradidoDeferredTransfer } from '@/data/proto/3_3/GradidoDeferredTransfer'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { GradidoTransferLoggingView } from './GradidoTransferLogging.view'
+
+export class GradidoDeferredTransferLoggingView extends AbstractLoggingView {
+ public constructor(private self: GradidoDeferredTransfer) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ ...new GradidoTransferLoggingView(this.self.transfer).toJSON(),
+ ...{ timeout: this.timestampSecondsToDateString(this.self.timeout) },
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/GradidoTransactionLogging.view.ts b/dlt-connector/src/logging/GradidoTransactionLogging.view.ts
new file mode 100644
index 000000000..f23c0b05e
--- /dev/null
+++ b/dlt-connector/src/logging/GradidoTransactionLogging.view.ts
@@ -0,0 +1,29 @@
+import { GradidoTransaction } from '@/data/proto/3_3/GradidoTransaction'
+import { TransactionBody } from '@/data/proto/3_3/TransactionBody'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { SignatureMapLoggingView } from './SignatureMapLogging.view'
+import { TransactionBodyLoggingView } from './TransactionBodyLogging.view'
+
+export class GradidoTransactionLoggingView extends AbstractLoggingView {
+ public constructor(private self: GradidoTransaction) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ let transactionBody: TransactionBody | null | unknown = null
+ try {
+ transactionBody = new TransactionBodyLoggingView(this.self.getTransactionBody())
+ } catch (e) {
+ transactionBody = e
+ }
+ return {
+ sigMap: new SignatureMapLoggingView(this.self.sigMap).toJSON(),
+ bodyBytes: transactionBody,
+ parentMessageId: this.self.parentMessageId
+ ? Buffer.from(this.self.parentMessageId).toString(this.bufferStringFormat)
+ : undefined,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/GradidoTransferLogging.view.ts b/dlt-connector/src/logging/GradidoTransferLogging.view.ts
new file mode 100644
index 000000000..84b5fe604
--- /dev/null
+++ b/dlt-connector/src/logging/GradidoTransferLogging.view.ts
@@ -0,0 +1,18 @@
+import { GradidoTransfer } from '@/data/proto/3_3/GradidoTransfer'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { TransferAmountLoggingView } from './TransferAmountLogging.view'
+
+export class GradidoTransferLoggingView extends AbstractLoggingView {
+ public constructor(private self: GradidoTransfer) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ sender: new TransferAmountLoggingView(this.self.sender),
+ recipient: Buffer.from(this.self.recipient).toString(this.bufferStringFormat),
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/GroupFriendsUpdateLogging.view.ts b/dlt-connector/src/logging/GroupFriendsUpdateLogging.view.ts
new file mode 100644
index 000000000..8d1159d82
--- /dev/null
+++ b/dlt-connector/src/logging/GroupFriendsUpdateLogging.view.ts
@@ -0,0 +1,16 @@
+import { GroupFriendsUpdate } from '@/data/proto/3_3/GroupFriendsUpdate'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+
+export class GroupFriendsUpdateLoggingView extends AbstractLoggingView {
+ public constructor(private self: GroupFriendsUpdate) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ colorFusion: this.self.colorFusion,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/RegisterAddressLogging.view.ts b/dlt-connector/src/logging/RegisterAddressLogging.view.ts
new file mode 100644
index 000000000..bb857e2b8
--- /dev/null
+++ b/dlt-connector/src/logging/RegisterAddressLogging.view.ts
@@ -0,0 +1,22 @@
+import { AddressType } from '@/data/proto/3_3/enum/AddressType'
+import { RegisterAddress } from '@/data/proto/3_3/RegisterAddress'
+import { getEnumValue } from '@/utils/typeConverter'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+
+export class RegisterAddressLoggingView extends AbstractLoggingView {
+ public constructor(private self: RegisterAddress) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ userPublicKey: Buffer.from(this.self.userPubkey).toString(this.bufferStringFormat),
+ addressType: getEnumValue(AddressType, this.self.addressType),
+ nameHash: Buffer.from(this.self.nameHash).toString(this.bufferStringFormat),
+ accountPublicKey: Buffer.from(this.self.accountPubkey).toString(this.bufferStringFormat),
+ derivationIndex: this.self.derivationIndex,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/SignatureMapLogging.view.ts b/dlt-connector/src/logging/SignatureMapLogging.view.ts
new file mode 100644
index 000000000..93feb46f9
--- /dev/null
+++ b/dlt-connector/src/logging/SignatureMapLogging.view.ts
@@ -0,0 +1,17 @@
+import { SignatureMap } from '@/data/proto/3_3/SignatureMap'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { SignaturePairLoggingView } from './SignaturePairLogging.view'
+
+export class SignatureMapLoggingView extends AbstractLoggingView {
+ public constructor(private self: SignatureMap) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ sigPair: this.self.sigPair.map((value) => new SignaturePairLoggingView(value).toJSON()),
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/SignaturePairLogging.view.ts b/dlt-connector/src/logging/SignaturePairLogging.view.ts
new file mode 100644
index 000000000..e88406098
--- /dev/null
+++ b/dlt-connector/src/logging/SignaturePairLogging.view.ts
@@ -0,0 +1,18 @@
+import { SignaturePair } from '@/data/proto/3_3/SignaturePair'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+
+export class SignaturePairLoggingView extends AbstractLoggingView {
+ public constructor(private self: SignaturePair) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ pubkey: Buffer.from(this.self.pubKey).toString(this.bufferStringFormat),
+ signature:
+ Buffer.from(this.self.signature).subarray(0, 31).toString(this.bufferStringFormat) + '..',
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/TransactionBodyLogging.view.ts b/dlt-connector/src/logging/TransactionBodyLogging.view.ts
new file mode 100644
index 000000000..0c287b0a5
--- /dev/null
+++ b/dlt-connector/src/logging/TransactionBodyLogging.view.ts
@@ -0,0 +1,46 @@
+import { CrossGroupType } from '@/data/proto/3_3/enum/CrossGroupType'
+import { TransactionBody } from '@/data/proto/3_3/TransactionBody'
+import { getEnumValue } from '@/utils/typeConverter'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { CommunityRootLoggingView } from './CommunityRootLogging.view'
+import { GradidoCreationLoggingView } from './GradidoCreationLogging.view'
+import { GradidoDeferredTransferLoggingView } from './GradidoDeferredTransferLogging.view'
+import { GradidoTransferLoggingView } from './GradidoTransferLogging.view'
+import { GroupFriendsUpdateLoggingView } from './GroupFriendsUpdateLogging.view'
+import { RegisterAddressLoggingView } from './RegisterAddressLogging.view'
+
+export class TransactionBodyLoggingView extends AbstractLoggingView {
+ public constructor(private self: TransactionBody) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ memo: this.self.memo,
+ createdAt: this.timestampToDateString(this.self.createdAt),
+ versionNumber: this.self.versionNumber,
+ type: getEnumValue(CrossGroupType, this.self.type),
+ otherGroup: this.self.otherGroup,
+ transfer: this.self.transfer
+ ? new GradidoTransferLoggingView(this.self.transfer).toJSON()
+ : undefined,
+ creation: this.self.creation
+ ? new GradidoCreationLoggingView(this.self.creation).toJSON()
+ : undefined,
+ groupFriendsUpdate: this.self.groupFriendsUpdate
+ ? new GroupFriendsUpdateLoggingView(this.self.groupFriendsUpdate).toJSON()
+ : undefined,
+ registerAddress: this.self.registerAddress
+ ? new RegisterAddressLoggingView(this.self.registerAddress).toJSON()
+ : undefined,
+ deferredTransfer: this.self.deferredTransfer
+ ? new GradidoDeferredTransferLoggingView(this.self.deferredTransfer).toJSON()
+ : undefined,
+ communityRoot: this.self.communityRoot
+ ? new CommunityRootLoggingView(this.self.communityRoot).toJSON()
+ : undefined,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/TransactionDraftLogging.view.ts b/dlt-connector/src/logging/TransactionDraftLogging.view.ts
new file mode 100644
index 000000000..5e86822ec
--- /dev/null
+++ b/dlt-connector/src/logging/TransactionDraftLogging.view.ts
@@ -0,0 +1,25 @@
+import { InputTransactionType } from '@/graphql/enum/InputTransactionType'
+import { TransactionDraft } from '@/graphql/input/TransactionDraft'
+import { getEnumValue } from '@/utils/typeConverter'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { UserIdentifierLoggingView } from './UserIdentifierLogging.view'
+
+export class TransactionDraftLoggingView extends AbstractLoggingView {
+ public constructor(private self: TransactionDraft) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ user: new UserIdentifierLoggingView(this.self.user).toJSON(),
+ linkedUser: new UserIdentifierLoggingView(this.self.linkedUser).toJSON(),
+ backendTransactionId: this.self.backendTransactionId,
+ amount: this.decimalToString(this.self.amount),
+ type: getEnumValue(InputTransactionType, this.self.type),
+ createdAt: this.self.createdAt,
+ targetDate: this.self.targetDate,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/TransactionLogging.view.ts b/dlt-connector/src/logging/TransactionLogging.view.ts
new file mode 100644
index 000000000..38443024d
--- /dev/null
+++ b/dlt-connector/src/logging/TransactionLogging.view.ts
@@ -0,0 +1,59 @@
+import { Transaction } from '@entity/Transaction'
+
+import { TransactionType } from '@/data/proto/3_3/enum/TransactionType'
+import { LogError } from '@/server/LogError'
+import { getEnumValue } from '@/utils/typeConverter'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+import { AccountLoggingView } from './AccountLogging.view'
+import { BackendTransactionLoggingView } from './BackendTransactionLogging.view'
+import { CommunityLoggingView } from './CommunityLogging.view'
+
+export class TransactionLoggingView extends AbstractLoggingView {
+ public constructor(private self: Transaction) {
+ super()
+ if (this.self.community === undefined) {
+ throw new LogError('sender community is zero')
+ }
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(showBackendTransactions = true): any {
+ return {
+ id: this.self.id,
+ nr: this.self.nr,
+ bodyBytesLength: this.self.bodyBytes.length,
+ createdAt: this.dateToString(this.self.createdAt),
+ confirmedAt: this.dateToString(this.self.confirmedAt),
+ protocolVersion: this.self.protocolVersion,
+ type: getEnumValue(TransactionType, this.self.type),
+ signature: this.self.signature.subarray(0, 31).toString(this.bufferStringFormat) + '..',
+ community: new CommunityLoggingView(this.self.community).toJSON(),
+ otherCommunity: this.self.otherCommunity
+ ? new CommunityLoggingView(this.self.otherCommunity)
+ : undefined,
+ iotaMessageId: this.self.iotaMessageId
+ ? this.self.iotaMessageId.toString(this.bufferStringFormat)
+ : undefined,
+ signingAccount: this.self.signingAccount
+ ? new AccountLoggingView(this.self.signingAccount)
+ : undefined,
+ recipientAccount: this.self.recipientAccount
+ ? new AccountLoggingView(this.self.recipientAccount)
+ : undefined,
+ amount: this.decimalToString(this.self.amount),
+ accountBalanceOnCreation: this.decimalToString(this.self.accountBalanceOnCreation),
+ accountBalanceOnConfirmation: this.decimalToString(this.self.accountBalanceOnConfirmation),
+ runningHash: this.self.runningHash
+ ? this.self.runningHash.toString(this.bufferStringFormat)
+ : undefined,
+ iotaMilestone: this.self.iotaMilestone,
+ backendTransactions:
+ showBackendTransactions && this.self.backendTransactions
+ ? this.self.backendTransactions.map((backendTransaction) =>
+ new BackendTransactionLoggingView(backendTransaction).toJSON(false),
+ )
+ : undefined,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/TransferAmountLogging.view.ts b/dlt-connector/src/logging/TransferAmountLogging.view.ts
new file mode 100644
index 000000000..8d320b99f
--- /dev/null
+++ b/dlt-connector/src/logging/TransferAmountLogging.view.ts
@@ -0,0 +1,18 @@
+import { TransferAmount } from '@/data/proto/3_3/TransferAmount'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+
+export class TransferAmountLoggingView extends AbstractLoggingView {
+ public constructor(private self: TransferAmount) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ publicKey: Buffer.from(this.self.pubkey).toString(this.bufferStringFormat),
+ amount: this.self.amount,
+ communityId: this.self.communityId,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/UserIdentifierLogging.view.ts b/dlt-connector/src/logging/UserIdentifierLogging.view.ts
new file mode 100644
index 000000000..54ac4b07d
--- /dev/null
+++ b/dlt-connector/src/logging/UserIdentifierLogging.view.ts
@@ -0,0 +1,18 @@
+import { UserIdentifier } from '@/graphql/input/UserIdentifier'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+
+export class UserIdentifierLoggingView extends AbstractLoggingView {
+ public constructor(private self: UserIdentifier) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ uuid: this.self.uuid,
+ communityUuid: this.self.communityUuid,
+ accountNr: this.self.accountNr,
+ }
+ }
+}
diff --git a/dlt-connector/src/logging/UserLogging.view.ts b/dlt-connector/src/logging/UserLogging.view.ts
new file mode 100644
index 000000000..a3cbd66bc
--- /dev/null
+++ b/dlt-connector/src/logging/UserLogging.view.ts
@@ -0,0 +1,20 @@
+import { User } from '@entity/User'
+
+import { AbstractLoggingView } from './AbstractLogging.view'
+
+export class UserLoggingView extends AbstractLoggingView {
+ public constructor(private user: User) {
+ super()
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ public toJSON(): any {
+ return {
+ id: this.user.id,
+ gradidoId: this.user.gradidoID,
+ derive1Pubkey: this.user.derive1Pubkey.toString(this.bufferStringFormat),
+ createdAt: this.dateToString(this.user.createdAt),
+ confirmedAt: this.dateToString(this.user.confirmedAt),
+ }
+ }
+}
diff --git a/dlt-connector/src/server/logger.ts b/dlt-connector/src/logging/logger.ts
similarity index 100%
rename from dlt-connector/src/server/logger.ts
rename to dlt-connector/src/logging/logger.ts
diff --git a/dlt-connector/src/server/LogError.ts b/dlt-connector/src/server/LogError.ts
index 8e145a0ef..69aca1978 100644
--- a/dlt-connector/src/server/LogError.ts
+++ b/dlt-connector/src/server/LogError.ts
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unsafe-argument */
-import { logger } from './logger'
+import { logger } from '@/logging/logger'
export class LogError extends Error {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
diff --git a/dlt-connector/src/server/createServer.ts b/dlt-connector/src/server/createServer.ts
index e02cc3073..ed87d54ac 100755
--- a/dlt-connector/src/server/createServer.ts
+++ b/dlt-connector/src/server/createServer.ts
@@ -9,10 +9,9 @@ import express, { Express } from 'express'
import { Logger } from 'log4js'
import { schema } from '@/graphql/schema'
+import { logger as dltLogger } from '@/logging/logger'
import { Connection } from '@/typeorm/DataSource'
-import { logger as dltLogger } from './logger'
-
type ServerDef = { apollo: ApolloServer; app: Express }
interface MyContext {
diff --git a/dlt-connector/src/typeorm/DataSource.ts b/dlt-connector/src/typeorm/DataSource.ts
index ecdfc1b66..a86a061f3 100644
--- a/dlt-connector/src/typeorm/DataSource.ts
+++ b/dlt-connector/src/typeorm/DataSource.ts
@@ -5,8 +5,8 @@ import { entities } from '@entity/index'
import { Migration } from '@entity/Migration'
import { CONFIG } from '@/config'
+import { logger } from '@/logging/logger'
import { LogError } from '@/server/LogError'
-import { logger } from '@/server/logger'
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class Connection {
diff --git a/dlt-connector/src/utils/typeConverter.ts b/dlt-connector/src/utils/typeConverter.ts
index 1fc46ee4b..52dcd2a98 100644
--- a/dlt-connector/src/utils/typeConverter.ts
+++ b/dlt-connector/src/utils/typeConverter.ts
@@ -7,8 +7,8 @@ import { TransactionBody } from '@/data/proto/3_3/TransactionBody'
import { AccountType } from '@/graphql/enum/AccountType'
import { TransactionErrorType } from '@/graphql/enum/TransactionErrorType'
import { TransactionError } from '@/graphql/model/TransactionError'
+import { logger } from '@/logging/logger'
import { LogError } from '@/server/LogError'
-import { logger } from '@/server/logger'
export const uuid4ToBuffer = (uuid: string): Buffer => {
// Remove dashes from the UUIDv4 string
diff --git a/dlt-connector/test/testSetup.ts b/dlt-connector/test/testSetup.ts
index ff619e95d..71170cbf0 100644
--- a/dlt-connector/test/testSetup.ts
+++ b/dlt-connector/test/testSetup.ts
@@ -1,9 +1,9 @@
-import { logger } from '@/server/logger'
+import { logger } from '@/logging/logger'
jest.setTimeout(1000000)
-jest.mock('@/server/logger', () => {
- const originalModule = jest.requireActual('@/server/logger')
+jest.mock('@/logging/logger', () => {
+ const originalModule = jest.requireActual('@/logging/logger')
return {
__esModule: true,
...originalModule,
diff --git a/dlt-database/src/config/index.ts b/dlt-database/src/config/index.ts
index 20208befc..46a1e580c 100644
--- a/dlt-database/src/config/index.ts
+++ b/dlt-database/src/config/index.ts
@@ -13,19 +13,19 @@ const constants = {
}
const database = {
- DB_HOST: process.env.DB_HOST || 'localhost',
+ DB_HOST: process.env.DB_HOST ?? 'localhost',
DB_PORT: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306,
- DB_USER: process.env.DB_USER || 'root',
- DB_PASSWORD: process.env.DB_PASSWORD || '',
- DB_DATABASE: process.env.DB_DATABASE || 'gradido_dlt',
+ DB_USER: process.env.DB_USER ?? 'root',
+ DB_PASSWORD: process.env.DB_PASSWORD ?? '',
+ DB_DATABASE: process.env.DB_DATABASE ?? 'gradido_dlt',
}
const migrations = {
- MIGRATIONS_TABLE: process.env.MIGRATIONS_TABLE || 'migrations',
+ MIGRATIONS_TABLE: process.env.MIGRATIONS_TABLE ?? 'migrations',
}
// Check config version
-constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION || constants.CONFIG_VERSION.DEFAULT
+constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION ?? constants.CONFIG_VERSION.DEFAULT
if (
![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes(
constants.CONFIG_VERSION.CURRENT,
diff --git a/federation/.env.template b/federation/.env.template
index e6ac8ad7d..91fb1c692 100644
--- a/federation/.env.template
+++ b/federation/.env.template
@@ -13,7 +13,8 @@ DB_PASSWORD=$DB_PASSWORD
DB_DATABASE=gradido_community
# Federation
-FEDERATION_COMMUNITY_URL=$FEDERATION_COMMUNITY_URL
+COMMUNITY_HOST=$COMMUNITY_HOST
+URL_PROTOCOL=$URL_PROTOCOL
FEDERATION_CONFIG_VERSION=$FEDERATION_CONFIG_VERSION
# comma separated list of api-versions, which cause starting several federation modules
FEDERATION_COMMUNITY_APIS=$FEDERATION_COMMUNITY_APIS
\ No newline at end of file
diff --git a/federation/src/config/index.ts b/federation/src/config/index.ts
index 5f1b2e0c6..821df574a 100644
--- a/federation/src/config/index.ts
+++ b/federation/src/config/index.ts
@@ -14,7 +14,7 @@ const constants = {
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',
+ LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v2.2023-08-24',
@@ -25,21 +25,21 @@ const constants = {
const server = {
// JWT_SECRET: process.env.JWT_SECRET || 'secret123',
// JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN || '10m',
- GRAPHIQL: process.env.GRAPHIQL === 'true' || false,
+ GRAPHIQL: process.env.GRAPHIQL === 'true' ?? false,
// GDT_API_URL: process.env.GDT_API_URL || 'https://gdt.gradido.net',
- PRODUCTION: process.env.NODE_ENV === 'production' || false,
+ PRODUCTION: process.env.NODE_ENV === 'production' ?? false,
}
const database = {
- DB_HOST: process.env.DB_HOST || 'localhost',
+ DB_HOST: process.env.DB_HOST ?? 'localhost',
DB_PORT: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306,
- DB_USER: process.env.DB_USER || 'root',
- DB_PASSWORD: process.env.DB_PASSWORD || '',
- DB_DATABASE: process.env.DB_DATABASE || 'gradido_community',
- TYPEORM_LOGGING_RELATIVE_PATH: process.env.TYPEORM_LOGGING_RELATIVE_PATH || 'typeorm.backend.log',
+ DB_USER: process.env.DB_USER ?? 'root',
+ DB_PASSWORD: process.env.DB_PASSWORD ?? '',
+ DB_DATABASE: process.env.DB_DATABASE ?? 'gradido_community',
+ TYPEORM_LOGGING_RELATIVE_PATH: process.env.TYPEORM_LOGGING_RELATIVE_PATH ?? 'typeorm.backend.log',
}
// Check config version
-constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION || constants.CONFIG_VERSION.DEFAULT
+constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION ?? constants.CONFIG_VERSION.DEFAULT
if (
![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes(
constants.CONFIG_VERSION.CURRENT,
@@ -50,10 +50,14 @@ if (
)
}
+const COMMUNITY_HOST = process.env.COMMUNITY_HOST ?? 'localhost'
+const URL_PROTOCOL = process.env.URL_PROTOCOL ?? 'http'
+const COMMUNITY_URL = process.env.COMMUNITY_URL ?? `${URL_PROTOCOL}://${COMMUNITY_HOST}`
+
const federation = {
- FEDERATION_API: process.env.FEDERATION_API || '1_0',
- FEDERATION_PORT: process.env.FEDERATION_PORT || 5010,
- FEDERATION_COMMUNITY_URL: process.env.FEDERATION_COMMUNITY_URL || null,
+ FEDERATION_API: process.env.FEDERATION_API ?? '1_0',
+ FEDERATION_PORT: process.env.FEDERATION_PORT ?? 5010,
+ FEDERATION_COMMUNITY_URL: process.env.FEDERATION_COMMUNITY_URL ?? COMMUNITY_URL,
FEDERATION_TRADING_LEVEL: {
RECEIVER_COMMUNITY_URL: 'https://stage3.gradido.net/api/',
SEND_COINS: true,
diff --git a/frontend/.env.dist b/frontend/.env.dist
index 427d43359..f7e7edcd6 100644
--- a/frontend/.env.dist
+++ b/frontend/.env.dist
@@ -2,13 +2,13 @@
DEFAULT_PUBLISHER_ID=2896
# Endpoints
-GRAPHQL_URI=http://localhost/graphql
-ADMIN_AUTH_URL=http://localhost/admin/authenticate?token={token}
+GRAPHQL_PATH=/graphql
+ADMIN_AUTH_PATH=/admin/authenticate?token={token}
# Community
COMMUNITY_NAME=Gradido Entwicklung
COMMUNITY_URL=http://localhost/
-COMMUNITY_REGISTER_URL=http://localhost/register
+COMMUNITY_REGISTER_PATH=/register
COMMUNITY_DESCRIPTION=Die lokale Entwicklungsumgebung von Gradido.
COMMUNITY_SUPPORT_MAIL=support@supportmail.com
diff --git a/frontend/.env.template b/frontend/.env.template
index 59e34eb80..c365ab8cf 100644
--- a/frontend/.env.template
+++ b/frontend/.env.template
@@ -4,18 +4,19 @@ CONFIG_VERSION=$FRONTEND_CONFIG_VERSION
DEFAULT_PUBLISHER_ID=$DEFAULT_PUBLISHER_ID
# Endpoints
-GRAPHQL_URI=$GRAPHQL_URI
-ADMIN_AUTH_URL=$ADMIN_AUTH_URL
+GRAPHQL_PATH=$GRAPHQL_PATH
+ADMIN_AUTH_PATH=$ADMIN_AUTH_PATH
# Community
COMMUNITY_NAME=$COMMUNITY_NAME
-COMMUNITY_URL=$COMMUNITY_URL
-COMMUNITY_REGISTER_URL=$COMMUNITY_REGISTER_URL
+COMMUNITY_HOST=$COMMUNITY_HOST
+URL_PROTOCOL=$URL_PROTOCOL
+COMMUNITY_REGISTER_PATH=$COMMUNITY_REGISTER_PATH
COMMUNITY_DESCRIPTION=$COMMUNITY_DESCRIPTION
COMMUNITY_SUPPORT_MAIL=$COMMUNITY_SUPPORT_MAIL
# Meta
-META_URL=$META_URL
+META_URL=$COMMUNITY_HOST
META_TITLE_DE=$META_TITLE_DE
META_TITLE_EN=$META_TITLE_EN
META_DESCRIPTION_DE=$META_DESCRIPTION_DE
diff --git a/frontend/src/config/index.js b/frontend/src/config/index.js
index b90376672..dd2e85dac 100644
--- a/frontend/src/config/index.js
+++ b/frontend/src/config/index.js
@@ -8,61 +8,66 @@ const constants = {
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
- EXPECTED: 'v4.2022-12-20',
+ EXPECTED: 'v5.2024-01-08',
CURRENT: '',
},
}
const version = {
APP_VERSION: pkg.version,
- BUILD_COMMIT: process.env.BUILD_COMMIT || null,
+ BUILD_COMMIT: process.env.BUILD_COMMIT ?? null,
// self reference of `version.BUILD_COMMIT` is not possible at this point, hence the duplicate code
- BUILD_COMMIT_SHORT: (process.env.BUILD_COMMIT || '0000000').slice(0, 7),
+ BUILD_COMMIT_SHORT: (process.env.BUILD_COMMIT ?? '0000000').slice(0, 7),
}
const environment = {
NODE_ENV: process.env.NODE_ENV,
- DEBUG: process.env.NODE_ENV !== 'production' || false,
- PRODUCTION: process.env.NODE_ENV === 'production' || false,
- DEFAULT_PUBLISHER_ID: process.env.DEFAULT_PUBLISHER_ID || 2896,
- PORT: process.env.PORT || 3000,
+ DEBUG: process.env.NODE_ENV !== 'production' ?? false,
+ PRODUCTION: process.env.NODE_ENV === 'production' ?? false,
+ DEFAULT_PUBLISHER_ID: process.env.DEFAULT_PUBLISHER_ID ?? 2896,
+ PORT: process.env.PORT ?? 3000,
}
+const COMMUNITY_HOST = process.env.COMMUNITY_HOST ?? 'localhost'
+const URL_PROTOCOL = process.env.URL_PROTOCOL ?? 'http'
+const COMMUNITY_URL = process.env.COMMUNITY_URL ?? `${URL_PROTOCOL}://${COMMUNITY_HOST}`
+
const endpoints = {
- GRAPHQL_URI: process.env.GRAPHQL_URI || 'http://localhost/graphql',
- ADMIN_AUTH_URL: process.env.ADMIN_AUTH_URL || 'http://localhost/admin/authenticate?token={token}',
+ GRAPHQL_URI: COMMUNITY_URL + (process.env.GRAPHQL_PATH ?? '/graphql'),
+ ADMIN_AUTH_URL:
+ COMMUNITY_URL + (process.env.ADMIN_AUTH_PATH ?? '/admin/authenticate?token={token}'),
}
const community = {
- COMMUNITY_NAME: process.env.COMMUNITY_NAME || 'Gradido Entwicklung',
- COMMUNITY_URL: process.env.COMMUNITY_URL || 'http://localhost/',
- COMMUNITY_REGISTER_URL: process.env.COMMUNITY_REGISTER_URL || 'http://localhost/register',
+ COMMUNITY_NAME: process.env.COMMUNITY_NAME ?? 'Gradido Entwicklung',
+ COMMUNITY_URL: COMMUNITY_URL,
+ COMMUNITY_REGISTER_URL: COMMUNITY_URL + (process.env.COMMUNITY_REGISTER_PATH ?? '/register'),
COMMUNITY_DESCRIPTION:
- process.env.COMMUNITY_DESCRIPTION || 'Die lokale Entwicklungsumgebung von Gradido.',
- COMMUNITY_SUPPORT_MAIL: process.env.COMMUNITY_SUPPORT_MAIL || 'support@supportmail.com',
+ process.env.COMMUNITY_DESCRIPTION ?? 'Die lokale Entwicklungsumgebung von Gradido.',
+ COMMUNITY_SUPPORT_MAIL: process.env.COMMUNITY_SUPPORT_MAIL ?? 'support@supportmail.com',
}
const meta = {
- META_URL: process.env.META_URL || 'http://localhost',
- META_TITLE_DE: process.env.META_TITLE_DE || 'Gradido – Dein Dankbarkeitskonto',
- META_TITLE_EN: process.env.META_TITLE_EN || 'Gradido - Your gratitude account',
+ META_URL: process.env.META_URL ?? 'http://localhost',
+ META_TITLE_DE: process.env.META_TITLE_DE ?? 'Gradido – Dein Dankbarkeitskonto',
+ META_TITLE_EN: process.env.META_TITLE_EN ?? 'Gradido - Your gratitude account',
META_DESCRIPTION_DE:
- process.env.META_DESCRIPTION_DE ||
+ process.env.META_DESCRIPTION_DE ??
'Dankbarkeit ist die Währung der neuen Zeit. Immer mehr Menschen entfalten ihr Potenzial und gestalten eine gute Zukunft für alle.',
META_DESCRIPTION_EN:
- process.env.META_DESCRIPTION_EN ||
+ process.env.META_DESCRIPTION_EN ??
'Gratitude is the currency of the new age. More and more people are unleashing their potential and shaping a good future for all.',
META_KEYWORDS_DE:
- process.env.META_KEYWORDS_DE ||
+ process.env.META_KEYWORDS_DE ??
'Grundeinkommen, Währung, Dankbarkeit, Schenk-Ökonomie, Natürliche Ökonomie des Lebens, Ökonomie, Ökologie, Potenzialentfaltung, Schenken und Danken, Kreislauf des Lebens, Geldsystem',
META_KEYWORDS_EN:
- process.env.META_KEYWORDS_EN ||
+ process.env.META_KEYWORDS_EN ??
'Basic Income, Currency, Gratitude, Gift Economy, Natural Economy of Life, Economy, Ecology, Potential Development, Giving and Thanking, Cycle of Life, Monetary System',
- META_AUTHOR: process.env.META_AUTHOR || 'Bernd Hückstädt - Gradido-Akademie',
+ META_AUTHOR: process.env.META_AUTHOR ?? 'Bernd Hückstädt - Gradido-Akademie',
}
// Check config version
-constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION || constants.CONFIG_VERSION.DEFAULT
+constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION ?? constants.CONFIG_VERSION.DEFAULT
if (
![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes(
constants.CONFIG_VERSION.CURRENT,
diff --git a/nginx/gradido.conf b/nginx/gradido.conf
index 403a2766b..2279d1e4f 100644
--- a/nginx/gradido.conf
+++ b/nginx/gradido.conf
@@ -1,5 +1,5 @@
server {
- server_name $NGINX_SERVER_NAME;
+ server_name _;
listen 80;
listen [::]:80;