Merge branch 'optin-valid-time' into show-valid-time-of-link-in-email

This commit is contained in:
Moriz Wahl 2022-03-29 00:59:47 +02:00
commit 9eda41b24a
68 changed files with 3218 additions and 582 deletions

View File

@ -1,3 +1,5 @@
CONFIG_VERSION=v1.2022-03-18
GRAPHQL_URI=http://localhost:4000/graphql
WALLET_AUTH_URL=http://localhost/authenticate?token={token}
WALLET_URL=http://localhost/login

View File

@ -1,3 +1,5 @@
CONFIG_VERSION=$ADMIN_CONFIG_VERSION
GRAPHQL_URI=$GRAPHQL_URI
WALLET_AUTH_URL=$WALLET_AUTH_URL
WALLET_URL=$WALLET_URL

View File

@ -4,11 +4,20 @@
// Load Package Details for some default values
const pkg = require('../../package')
const constants = {
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v1.2022-03-18',
CURRENT: '',
},
}
const version = {
APP_VERSION: pkg.version,
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').substr(0, 7),
BUILD_COMMIT_SHORT: (process.env.BUILD_COMMIT || '0000000').slice(0, 7),
PORT: process.env.PORT || 8080,
}
const environment = {
@ -27,14 +36,24 @@ const debug = {
DEBUG_DISABLE_AUTH: process.env.DEBUG_DISABLE_AUTH === 'true' || false,
}
const options = {}
// Check config version
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,
)
) {
throw new Error(
`Fatal: Config Version incorrect - expected "${constants.CONFIG_VERSION.EXPECTED}" or "${constants.CONFIG_VERSION.DEFAULT}", but found "${constants.CONFIG_VERSION.CURRENT}"`,
)
}
const CONFIG = {
...constants,
...version,
...environment,
...endpoints,
...options,
...debug,
}
export default CONFIG
module.exports = CONFIG

View File

@ -88,6 +88,7 @@ export default {
notActivated: this.filterCheckedEmails,
isDeleted: this.filterDeletedUser,
},
fetchPolicy: 'no-cache',
})
.then((result) => {
this.rows = result.data.searchUsers.userCount

View File

@ -2,11 +2,12 @@ const path = require('path')
const webpack = require('webpack')
const Dotenv = require('dotenv-webpack')
const StatsPlugin = require('stats-webpack-plugin')
const CONFIG = require('./src/config')
// vue.config.js
module.exports = {
devServer: {
port: process.env.PORT || 8080,
port: CONFIG.PORT,
},
pluginOptions: {
i18n: {
@ -34,7 +35,7 @@ module.exports = {
// 'process.env.DOCKER_WORKDIR': JSON.stringify(process.env.DOCKER_WORKDIR),
// 'process.env.BUILD_DATE': JSON.stringify(process.env.BUILD_DATE),
// 'process.env.BUILD_VERSION': JSON.stringify(process.env.BUILD_VERSION),
'process.env.BUILD_COMMIT': JSON.stringify(process.env.BUILD_COMMIT),
'process.env.BUILD_COMMIT': JSON.stringify(CONFIG.BUILD_COMMIT),
// 'process.env.PORT': JSON.stringify(process.env.PORT),
}),
// generate webpack stats to allow analysis of the bundlesize
@ -46,7 +47,7 @@ module.exports = {
},
css: {
// Enable CSS source maps.
sourceMap: process.env.NODE_ENV !== 'production',
sourceMap: CONFIG.NODE_ENV !== 'production',
},
outputDir: path.resolve(__dirname, './dist'),
}

View File

@ -1,3 +1,5 @@
CONFIG_VERSION=v2.2022-03-24
# Server
PORT=4000
JWT_SECRET=secret123
@ -38,10 +40,11 @@ EMAIL_SENDER=info@gradido.net
EMAIL_PASSWORD=xxx
EMAIL_SMTP_URL=gmail.com
EMAIL_SMTP_PORT=587
EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/{code}
EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/{optin}{code}
EMAIL_LINK_SETPASSWORD=http://localhost/reset/{code}
EMAIL_LINK_FORGOTPASSWORD=http://localhost/forgot-password
EMAIL_CODE_VALID_TIME=1440
EMAIL_CODE_REQUEST_TIME=10
# Webhook
WEBHOOK_ELOPAGE_SECRET=secret

View File

@ -1,3 +1,5 @@
CONFIG_VERSION=$BACKEND_CONFIG_VERSION
# Server
JWT_SECRET=$JWT_SECRET
JWT_EXPIRES_IN=10m

View File

@ -12,6 +12,11 @@ Decimal.set({
const constants = {
DB_VERSION: '0033-add_referrer_id',
DECAY_START_TIME: new Date('2021-05-13 17:46:31'), // GMT+0
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v2.2022-03-24',
CURRENT: '',
},
}
const server = {
@ -62,14 +67,19 @@ const email = {
EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'gmail.com',
EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '587',
EMAIL_LINK_VERIFICATION:
process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{code}',
process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{optin}{code}',
EMAIL_LINK_SETPASSWORD:
process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/reset-password/{code}',
process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/reset-password/{optin}',
EMAIL_LINK_FORGOTPASSWORD:
process.env.EMAIL_LINK_FORGOTPASSWORD || 'http://localhost/forgot-password',
// 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
: 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
: 10,
}
const webhook = {
@ -80,6 +90,18 @@ const webhook = {
// This is needed by graphql-directive-auth
process.env.APP_SECRET = server.JWT_SECRET
// Check config version
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,
)
) {
throw new Error(
`Fatal: Config Version incorrect - expected "${constants.CONFIG_VERSION.EXPECTED}" or "${constants.CONFIG_VERSION.DEFAULT}", but found "${constants.CONFIG_VERSION.CURRENT}"`,
)
}
const CONFIG = {
...constants,
...server,

View File

@ -16,4 +16,7 @@ export default class CreateUserArgs {
@Field(() => Int, { nullable: true })
publisherId: number
@Field(() => String, { nullable: true })
redeemCode?: string | null
}

View File

@ -0,0 +1,11 @@
import { registerEnumType } from 'type-graphql'
export enum OptInType {
EMAIL_OPT_IN_REGISTER = 1,
EMAIL_OPT_IN_RESET_PASSWORD = 2,
}
registerEnumType(OptInType, {
name: 'OptInType', // this one is mandatory
description: 'Type of the email optin', // this one is optional
})

View File

@ -34,6 +34,8 @@ import { Decay } from '@model/Decay'
import Paginated from '@arg/Paginated'
import { Order } from '@enum/Order'
import { communityUser } from '@/util/communityUser'
import { checkOptInCode, activationLink } from './UserResolver'
import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail'
// const EMAIL_OPT_IN_REGISTER = 1
// const EMAIL_OPT_UNKNOWN = 3 // elopage?
@ -369,6 +371,39 @@ export class AdminResolver {
const user = await dbUser.findOneOrFail({ id: userId })
return userTransactions.map((t) => new Transaction(t, new User(user), communityUser))
}
@Authorized([RIGHTS.SEND_ACTIVATION_EMAIL])
@Mutation(() => Boolean)
async sendActivationEmail(@Arg('email') email: string): Promise<boolean> {
email = email.trim().toLowerCase()
const user = await dbUser.findOneOrFail({ email: email })
// can be both types: REGISTER and RESET_PASSWORD
let optInCode = await LoginEmailOptIn.findOne({
where: { userId: user.id },
order: { updatedAt: 'DESC' },
})
optInCode = await checkOptInCode(optInCode, user.id)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const emailSent = await sendAccountActivationEmail({
link: activationLink(optInCode),
firstName: user.firstName,
lastName: user.lastName,
email,
})
/* uncomment this, when you need the activation link on the console
// In case EMails are disabled log the activation link for the user
if (!emailSent) {
// eslint-disable-next-line no-console
console.log(`Account confirmation link: ${activationLink}`)
}
*/
return true
}
}
interface CreationMap {

View File

@ -34,6 +34,9 @@ import { virtualLinkTransaction, virtualDecayTransaction } from '@/util/virtualT
import Decimal from 'decimal.js-light'
import { calculateDecay } from '@/util/decay'
const MEMO_MAX_CHARS = 255
const MEMO_MIN_CHARS = 5
export const executeTransaction = async (
amount: Decimal,
memo: string,
@ -45,6 +48,14 @@ export const executeTransaction = async (
throw new Error('Sender and Recipient are the same.')
}
if (memo.length > MEMO_MAX_CHARS) {
throw new Error(`memo text is too long (${MEMO_MAX_CHARS} characters maximum)`)
}
if (memo.length < MEMO_MIN_CHARS) {
throw new Error(`memo text is too short (${MEMO_MIN_CHARS} characters minimum)`)
}
// validate amount
const receivedCallDate = new Date()
const sendBalance = await calculateBalance(sender.id, amount.mul(-1), receivedCallDate)
@ -117,6 +128,7 @@ export const executeTransaction = async (
recipientFirstName: recipient.firstName,
recipientLastName: recipient.lastName,
email: recipient.email,
senderEmail: sender.email,
amount,
memo,
})

View File

@ -11,7 +11,7 @@ import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
import { User } from '@entity/User'
import CONFIG from '@/config'
import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail'
import { printEmailCodeValidTime } from './UserResolver'
import { printTimeDuration } from './UserResolver'
// import { klicktippSignIn } from '@/apis/KlicktippController'
@ -125,7 +125,10 @@ describe('UserResolver', () => {
describe('account activation email', () => {
it('sends an account activation email', () => {
const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(/{code}/g, emailOptIn)
const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(
/{optin}/g,
emailOptIn,
).replace(/{code}/g, '')
expect(sendAccountActivationEmail).toBeCalledWith({
link: activationLink,
firstName: 'Peter',
@ -415,19 +418,16 @@ describe('UserResolver', () => {
})
})
describe('printEmailCodeValidTime', () => {
describe('printTimeDuration', () => {
it('works with 10 minutes', () => {
CONFIG.EMAIL_CODE_VALID_TIME = 10
expect(printEmailCodeValidTime()).toBe('10 minutes')
expect(printTimeDuration(10)).toBe('10 minutes')
})
it('works with 1440 minutes', () => {
CONFIG.EMAIL_CODE_VALID_TIME = 1440
expect(printEmailCodeValidTime()).toBe('24 hours')
expect(printTimeDuration(1440)).toBe('24 hours')
})
it('works with 1410 minutes', () => {
CONFIG.EMAIL_CODE_VALID_TIME = 1410
expect(printEmailCodeValidTime()).toBe('23 hours and 30 minutes')
expect(printTimeDuration(1410)).toBe('23 hours and 30 minutes')
})
})

View File

@ -3,10 +3,11 @@
import fs from 'fs'
import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql'
import { getConnection, getCustomRepository, QueryRunner } from '@dbTools/typeorm'
import { getConnection, getCustomRepository } from '@dbTools/typeorm'
import CONFIG from '@/config'
import { User } from '@model/User'
import { User as DbUser } from '@entity/User'
import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink'
import { encode } from '@/auth/JWT'
import CreateUserArgs from '@arg/CreateUserArgs'
import UnsecureLoginArgs from '@arg/UnsecureLoginArgs'
@ -14,6 +15,7 @@ import UpdateUserInfosArgs from '@arg/UpdateUserInfosArgs'
import { klicktippNewsletterStateMiddleware } from '@/middleware/klicktippMiddleware'
import { UserSettingRepository } from '@repository/UserSettingRepository'
import { Setting } from '@enum/Setting'
import { OptInType } from '@enum/OptInType'
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
import { sendResetPasswordEmail as sendResetPasswordEmailMailer } from '@/mailer/sendResetPasswordEmail'
import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail'
@ -23,9 +25,6 @@ import { ROLE_ADMIN } from '@/auth/ROLES'
import { hasElopageBuys } from '@/util/hasElopageBuys'
import { ServerUser } from '@entity/ServerUser'
const EMAIL_OPT_IN_RESET_PASSWORD = 2
const EMAIL_OPT_IN_REGISTER = 1
// eslint-disable-next-line @typescript-eslint/no-var-requires
const sodium = require('sodium-native')
// eslint-disable-next-line @typescript-eslint/no-var-requires
@ -147,57 +146,47 @@ const SecretKeyCryptographyDecrypt = (encryptedMessage: Buffer, encryptionKey: B
return message
}
const createEmailOptIn = async (
loginUserId: number,
queryRunner: QueryRunner,
): Promise<LoginEmailOptIn> => {
let emailOptIn = await LoginEmailOptIn.findOne({
userId: loginUserId,
emailOptInTypeId: EMAIL_OPT_IN_REGISTER,
})
if (emailOptIn) {
if (isOptInCodeValid(emailOptIn)) {
throw new Error(`email already sent less than ${printEmailCodeValidTime()} ago`)
}
emailOptIn.updatedAt = new Date()
emailOptIn.resendCount++
} else {
emailOptIn = new LoginEmailOptIn()
emailOptIn.verificationCode = random(64)
emailOptIn.userId = loginUserId
emailOptIn.emailOptInTypeId = EMAIL_OPT_IN_REGISTER
}
await queryRunner.manager.save(emailOptIn).catch((error) => {
// eslint-disable-next-line no-console
console.log('Error while saving emailOptIn', error)
throw new Error('error saving email opt in')
})
const newEmailOptIn = (userId: number): LoginEmailOptIn => {
const emailOptIn = new LoginEmailOptIn()
emailOptIn.verificationCode = random(64)
emailOptIn.userId = userId
emailOptIn.emailOptInTypeId = OptInType.EMAIL_OPT_IN_REGISTER
return emailOptIn
}
const getOptInCode = async (loginUserId: number): Promise<LoginEmailOptIn> => {
let optInCode = await LoginEmailOptIn.findOne({
userId: loginUserId,
emailOptInTypeId: EMAIL_OPT_IN_RESET_PASSWORD,
})
// Check for `CONFIG.EMAIL_CODE_VALID_TIME` minute delay
// needed by AdminResolver
// checks if given code exists and can be resent
// if optIn does not exits, it is created
export const checkOptInCode = async (
optInCode: LoginEmailOptIn | undefined,
userId: number,
optInType: OptInType = OptInType.EMAIL_OPT_IN_REGISTER,
): Promise<LoginEmailOptIn> => {
if (optInCode) {
if (isOptInCodeValid(optInCode)) {
throw new Error(`email already sent less than $(printEmailCodeValidTime()} minutes ago`)
if (!canResendOptIn(optInCode)) {
throw new Error(
`email already sent less than ${printTimeDuration(
CONFIG.EMAIL_CODE_REQUEST_TIME,
)} minutes ago`,
)
}
optInCode.updatedAt = new Date()
optInCode.resendCount++
} else {
optInCode = new LoginEmailOptIn()
optInCode.verificationCode = random(64)
optInCode.userId = loginUserId
optInCode.emailOptInTypeId = EMAIL_OPT_IN_RESET_PASSWORD
optInCode = newEmailOptIn(userId)
}
await LoginEmailOptIn.save(optInCode)
optInCode.emailOptInTypeId = optInType
await LoginEmailOptIn.save(optInCode).catch(() => {
throw new Error('Unable to save optin code.')
})
return optInCode
}
export const activationLink = (optInCode: LoginEmailOptIn): string => {
return CONFIG.EMAIL_LINK_SETPASSWORD.replace(/{optin}/g, optInCode.verificationCode.toString())
}
@Resolver()
export class UserResolver {
@Authorized([RIGHTS.VERIFY_LOGIN])
@ -305,7 +294,8 @@ export class UserResolver {
@Authorized([RIGHTS.CREATE_USER])
@Mutation(() => User)
async createUser(
@Args() { email, firstName, lastName, language, publisherId }: CreateUserArgs,
@Args()
{ email, firstName, lastName, language, publisherId, redeemCode = null }: CreateUserArgs,
): Promise<User> {
// TODO: wrong default value (should be null), how does graphql work here? Is it an required field?
// default int publisher_id = 0;
@ -338,6 +328,12 @@ export class UserResolver {
dbUser.language = language
dbUser.publisherId = publisherId
dbUser.passphrase = passphrase.join(' ')
if (redeemCode) {
const transactionLink = await dbTransactionLink.findOne({ code: redeemCode })
if (transactionLink) {
dbUser.referrerId = transactionLink.userId
}
}
// TODO this field has no null allowed unlike the loginServer table
// dbUser.pubKey = Buffer.from(randomBytes(32)) // Buffer.alloc(32, 0) default to 0000...
// dbUser.pubkey = keyPair[0]
@ -355,14 +351,17 @@ export class UserResolver {
throw new Error('error saving user')
})
// Store EmailOptIn in DB
// TODO: this has duplicate code with sendResetPasswordEmail
const emailOptIn = await createEmailOptIn(dbUser.id, queryRunner)
const emailOptIn = newEmailOptIn(dbUser.id)
await queryRunner.manager.save(emailOptIn).catch((error) => {
// eslint-disable-next-line no-console
console.log('Error while saving emailOptIn', error)
throw new Error('error saving email opt in')
})
const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(
/{code}/g,
/{optin}/g,
emailOptIn.verificationCode.toString(),
)
).replace(/{code}/g, redeemCode ? '/' + redeemCode : '')
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const emailSent = await sendAccountActivationEmail({
@ -380,6 +379,7 @@ export class UserResolver {
console.log(`Account confirmation link: ${activationLink}`)
}
*/
await queryRunner.commitTransaction()
} catch (e) {
await queryRunner.rollbackTransaction()
@ -390,68 +390,22 @@ export class UserResolver {
return new User(dbUser)
}
// THis is used by the admin only - should we move it to the admin resolver?
@Authorized([RIGHTS.SEND_ACTIVATION_EMAIL])
@Mutation(() => Boolean)
async sendActivationEmail(@Arg('email') email: string): Promise<boolean> {
email = email.trim().toLowerCase()
const user = await DbUser.findOneOrFail({ email: email })
const queryRunner = getConnection().createQueryRunner()
await queryRunner.connect()
await queryRunner.startTransaction('READ UNCOMMITTED')
try {
const emailOptIn = await createEmailOptIn(user.id, queryRunner)
const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(
/{code}/g,
emailOptIn.verificationCode.toString(),
)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const emailSent = await sendAccountActivationEmail({
link: activationLink,
firstName: user.firstName,
lastName: user.lastName,
email,
duration: printEmailCodeValidTime(),
})
/* uncomment this, when you need the activation link on the console
// In case EMails are disabled log the activation link for the user
if (!emailSent) {
// eslint-disable-next-line no-console
console.log(`Account confirmation link: ${activationLink}`)
}
*/
await queryRunner.commitTransaction()
} catch (e) {
await queryRunner.rollbackTransaction()
throw e
} finally {
await queryRunner.release()
}
return true
}
@Authorized([RIGHTS.SEND_RESET_PASSWORD_EMAIL])
@Query(() => Boolean)
async sendResetPasswordEmail(@Arg('email') email: string): Promise<boolean> {
// TODO: this has duplicate code with createUser
email = email.trim().toLowerCase()
const user = await DbUser.findOneOrFail({ email })
const optInCode = await getOptInCode(user.id)
// can be both types: REGISTER and RESET_PASSWORD
let optInCode = await LoginEmailOptIn.findOne({
userId: user.id,
})
const link = CONFIG.EMAIL_LINK_SETPASSWORD.replace(
/{code}/g,
optInCode.verificationCode.toString(),
)
optInCode = await checkOptInCode(optInCode, user.id, OptInType.EMAIL_OPT_IN_RESET_PASSWORD)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const emailSent = await sendResetPasswordEmailMailer({
link,
link: activationLink(optInCode),
firstName: user.firstName,
lastName: user.lastName,
email,
@ -488,8 +442,10 @@ export class UserResolver {
})
// Code is only valid for `CONFIG.EMAIL_CODE_VALID_TIME` minutes
if (!isOptInCodeValid(optInCode)) {
throw new Error(`email was sent more than ${printEmailCodeValidTime()} ago`)
if (!isOptInValid(optInCode)) {
throw new Error(
`email was sent more than ${printTimeDuration(CONFIG.EMAIL_CODE_VALID_TIME)} ago`,
)
}
// load user
@ -532,11 +488,6 @@ export class UserResolver {
throw new Error('error saving user: ' + error)
})
// Delete Code
await queryRunner.manager.remove(optInCode).catch((error) => {
throw new Error('error deleting code: ' + error)
})
await queryRunner.commitTransaction()
} catch (e) {
await queryRunner.rollbackTransaction()
@ -547,7 +498,7 @@ export class UserResolver {
// Sign into Klicktipp
// TODO do we always signUp the user? How to handle things with old users?
if (optInCode.emailOptInTypeId === EMAIL_OPT_IN_REGISTER) {
if (optInCode.emailOptInTypeId === OptInType.EMAIL_OPT_IN_REGISTER) {
try {
await klicktippSignIn(user.email, user.language, user.firstName, user.lastName)
} catch {
@ -567,8 +518,10 @@ export class UserResolver {
async queryOptIn(@Arg('optIn') optIn: string): Promise<boolean> {
const optInCode = await LoginEmailOptIn.findOneOrFail({ verificationCode: optIn })
// Code is only valid for `CONFIG.EMAIL_CODE_VALID_TIME` minutes
if (!isOptInCodeValid(optInCode)) {
throw new Error(`email was sent more than $(printEmailCodeValidTime()} ago`)
if (!isOptInValid(optInCode)) {
throw new Error(
`email was sent more than ${printTimeDuration(CONFIG.EMAIL_CODE_VALID_TIME)} ago`,
)
}
return true
}
@ -675,23 +628,32 @@ export class UserResolver {
}
}
function isOptInCodeValid(optInCode: LoginEmailOptIn) {
const timeElapsed = Date.now() - new Date(optInCode.updatedAt).getTime()
return timeElapsed <= CONFIG.EMAIL_CODE_VALID_TIME * 60 * 1000
const isTimeExpired = (optIn: LoginEmailOptIn, duration: number): boolean => {
const timeElapsed = Date.now() - new Date(optIn.updatedAt).getTime()
// time is given in minutes
return timeElapsed <= duration * 60 * 1000
}
const emailCodeValidTime = (): { hours?: number; minutes: number } => {
if (CONFIG.EMAIL_CODE_VALID_TIME > 60) {
const isOptInValid = (optIn: LoginEmailOptIn): boolean => {
return isTimeExpired(optIn, CONFIG.EMAIL_CODE_VALID_TIME)
}
const canResendOptIn = (optIn: LoginEmailOptIn): boolean => {
return !isTimeExpired(optIn, CONFIG.EMAIL_CODE_REQUEST_TIME)
}
const getTimeDurationObject = (time: number): { hours?: number; minutes: number } => {
if (time > 60) {
return {
hours: Math.floor(CONFIG.EMAIL_CODE_VALID_TIME / 60),
minutes: CONFIG.EMAIL_CODE_VALID_TIME % 60,
hours: Math.floor(time / 60),
minutes: time % 60,
}
}
return { minutes: CONFIG.EMAIL_CODE_VALID_TIME }
return { minutes: time }
}
export const printEmailCodeValidTime = (): string => {
const time = emailCodeValidTime()
export const printTimeDuration = (duration: number): string => {
const time = getTimeDurationObject(duration)
const result = time.minutes > 0 ? `${time.minutes} minutes` : ''
if (time.hours) return `${time.hours} hours` + (result !== '' ? ` and ${result}` : '')
return result

View File

@ -17,6 +17,7 @@ describe('sendTransactionReceivedEmail', () => {
recipientFirstName: 'Peter',
recipientLastName: 'Lustig',
email: 'peter@lustig.de',
senderEmail: 'bibi@bloxberg.de',
amount: new Decimal(42.0),
memo: 'Vielen herzlichen Dank für den neuen Hexenbesen!',
})
@ -30,6 +31,7 @@ describe('sendTransactionReceivedEmail', () => {
expect.stringContaining('Hallo Peter Lustig') &&
expect.stringContaining('42,00 GDD') &&
expect.stringContaining('Bibi Bloxberg') &&
expect.stringContaining('(bibi@bloxberg.de)') &&
expect.stringContaining('Vielen herzlichen Dank für den neuen Hexenbesen!'),
})
})

View File

@ -8,6 +8,7 @@ export const sendTransactionReceivedEmail = (data: {
recipientFirstName: string
recipientLastName: string
email: string
senderEmail: string
amount: Decimal
memo: string
}): Promise<boolean> => {

View File

@ -9,6 +9,7 @@ export const transactionReceived = {
recipientFirstName: string
recipientLastName: string
email: string
senderEmail: string
amount: Decimal
memo: string
}): string =>
@ -16,7 +17,7 @@ export const transactionReceived = {
Du hast soeben ${data.amount.toFixed(2).replace('.', ',')} GDD von ${data.senderFirstName} ${
data.senderLastName
} erhalten.
} (${data.senderEmail}) erhalten.
${data.senderFirstName} ${data.senderLastName} schreibt:
${data.memo}

View File

@ -45,6 +45,7 @@ export const createUser = gql`
$email: String!
$language: String!
$publisherId: Int
$redeemCode: String
) {
createUser(
email: $email
@ -52,6 +53,7 @@ export const createUser = gql`
lastName: $lastName
language: $language
publisherId: $publisherId
redeemCode: $redeemCode
) {
id
}

View File

@ -1,3 +1,5 @@
CONFIG_VERSION=v1.2022-03-18
DB_HOST=localhost
DB_PORT=3306
DB_USER=root

View File

@ -1,3 +1,5 @@
CONFIG_VERSION=$DATABASE_CONFIG_VERSION
DB_HOST=localhost
DB_PORT=3306
DB_USER=$DB_USER

View File

@ -3,6 +3,14 @@
import dotenv from 'dotenv'
dotenv.config()
const constants = {
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v1.2022-03-18',
CURRENT: '',
},
}
const database = {
DB_HOST: process.env.DB_HOST || 'localhost',
DB_PORT: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306,
@ -15,6 +23,18 @@ const migrations = {
MIGRATIONS_TABLE: process.env.MIGRATIONS_TABLE || 'migrations',
}
const CONFIG = { ...database, ...migrations }
// Check config version
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,
)
) {
throw new Error(
`Fatal: Config Version incorrect - expected "${constants.CONFIG_VERSION.EXPECTED}" or "${constants.CONFIG_VERSION.DEFAULT}", but found "${constants.CONFIG_VERSION.CURRENT}"`,
)
}
const CONFIG = { ...constants, ...database, ...migrations }
export default CONFIG

View File

@ -18,6 +18,8 @@ WEBHOOK_GITHUB_SECRET=secret
WEBHOOK_GITHUB_BRANCH=master
# backend
BACKEND_CONFIG_VERSION=v1.2022-03-18
EMAIL=true
EMAIL_USERNAME=peter@lustig.de
EMAIL_SENDER=peter@lustig.de
@ -43,6 +45,9 @@ KLICKTIPP_PASSWORD=
KLICKTIPP_APIKEY_DE=
KLICKTIPP_APIKEY_EN=
# database
DATABASE_CONFIG_VERSION=v1.2022-03-18
# frontend
GRAPHQL_URI=https://stage1.gradido.net/graphql
ADMIN_AUTH_URL=https://stage1.gradido.net/admin/authenticate?token={token}

View File

@ -31,6 +31,37 @@ Andererseits soll aber, wenn eine Community sich bei der Geldschöpfung nicht an
Aber grundsätzlich bleibt bei allen *Community-Gradido*-Währungen die Vergänglichkeit als Sicherungsmechanismus des Geldvolumens und der 1:1 Umtausch zwischen verschiedenen *Community-Gradidos* bestehen.
#### Community-Gradido
Um das Thema *Community-Gradido* näher zu beleuchten, wird im Folgenden eine etwas technischer Beschreibung gewählt. Der eingangs verwendete Begriff von *Colored-Gradido* wird hiermit abgelöst durch *Community-Gradido*. Dies soll analog der verschiedenen Währungen wie Euro, US-Dollar, Yen, etc. abgebildet werden. Das heißt die Gradido-Anwendung wird intern einen Datentyp "Money" haben, der neben dem Betrag auch die Währung trägt. Somit kann immer für einen Geld-Betrag X aus dem Datentyp *Money* alle Information herausgelesen bzw. übertragen werden. Gleichzeitig wird der Datentyp alle notwendigen Hilfsmethoden unterstützen, die für eine korrekte Anzeige, Berechnungen wie Vergänglichkeit oder sonstige Additionen und Subtraktionen notwendig sind.
Die Information über die Währung wird intern über einen eindeutigen Community-Schlüssel getragen, wodurch für jeden Betrag die Aussage möglich ist in welcher Community dieser Betrag einmal geschöpft wurde. Der Community-Schlüssel wird schon bei der Inbetriebnahme einer Community erstellt und dient in verschiedenen anderen fachlichen Prozessen - Stichwort Inter-Community-Communication - als eindeutiger Identifikator einer Community. Die weiteren Auswirkungen auf die Kontoführung und deren Berechnungen und Verwaltung von Transaktionen wird dementsprechend berücksichtigt und detailliert in der [Kontenverwaltung](./Kontenverwaltung.md) beschrieben werden.
##### Datentyp "Money"
Type Money {
* Attribute
* Integer Betrag; // in Gradido-Cent und damit ohne Nachkommastellen
* String CommunityKey; // eindeutiger CommunityKey z.B. eine UUID
* Methoden
* zurAnzeige(); // liefert den Betrag als String mit 2 Nachkommastellen und dem Gradido-Währungssymbol
* plus(Money m) // prüft, ob der CommunityKey von m gleich dem internen CommunityKey ist und falls ja wird der Betrag von m zu dem internen Betrag aufaddiert, sonst wird eine Exception geworfen
* minus(Money m) // prüft, ob der CommunityKey von m gleich dem internen CommunityKey ist und falls ja wird der Betrag von m von dem internen Betrag subtrahiert, sonst wird eine Exception geworfen
* isSameCommunity(Money m) // liefert TRUE wenn der CommunityKey von m gleich dem internen CommunityKey ist, sonst FALSE
* decay(Long sec) // berechnet die Vergänglichkeit des internen Betrages mit der übergebenen Dauer sec nach der Formel: Betrag - (Betrag x 0.99999997802044727 ^ sec)
}
Damit erfüllt der Datentyp *Money* zum einen die interne Unterscheidung von Gradidos aus unterschiedlichen Communities und unterliegt andererseits den sonst aufgestellten Anforderungen der Gradido-Anwendung:
* alle Gradidos unterliegen der Vergänglichkeit, egal aus welcher Community diese geschöpft wurden
* es gibt keinen Unterschied in der Wertigkeit von Gradidos, egal aus welcher Community diese stammen
Ob ein Benutzer aus Community A mit einem anderen Benutzer aus Community B handeln möchte, sprich per Transaktion Gradidos austauschen möchte, unterliegt allein dem Benutzer selbst und wird von der Anwendung nicht unterbunden. Es sind zukünftig Ideen geplant ( siehe Abschnitt "Schutz vor Falschgeld"), dass die Anwendung den Benutzer hierbei unterstützt - Stichwort: Blacklisting, Bereinigung, etc. - aber dies bleibt dennoch völlig unter der Abwägung, Kontrolle und des Risikos alleine beim Benutzer selbst.
Alle weiteren Auswirkungen im Zusammenspiel mit dem Datentyp Money auf die sonstigen Kontobewegungen und den möglichen unterschiedlichen CommunityKeys, wird, wie schon erwähnt, in der [Kontenverwaltung](./Kontenverwaltung.md) detailliert beschrieben.
#### Schutz vor Falschgeld
- Blacklisting
@ -43,13 +74,11 @@ Aber grundsätzlich bleibt bei allen *Community-Gradido*-Währungen die Vergäng
* Vergänglichkeitsbereinigung
* 1. GDD anderer Communities nach Menge von wenig nach viel
| PR-Kommentare | |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ulf 07.11.2021 | Wenn die geblacklisteten Coins prioritisiert vergehen kann der findige Angreifer den Verfall umgehen, indem er sich ungültige/blacklistete Coins erschafft, die dann genau seinem Verfall entsprechen. |
| Claus-Peter 25.11.2021 | Das Kapitel "Schutz vor Falschgeld" ist wohl eher noch im Status "Brainstorming" zu verstehen. Hier wurden mögliche Regeln notiert, die noch nicht in ihrer Gänze durchdacht und konzipiert sind.<br />Der Punkt Vergänglichkeitsbereinigung sagt folgendes aus:<br />Kontostand am 01.01.2021:<br />- 100 GDD aus der eigenen Community<br />- 100 GDD aus Community A<br />- 100 GDD aus Community B<br />- gesamt 300 GDD<br /><br />Nach einem Jahr ohne irgendwelche weiteren Transaktionen ergibt sich folgendes am 31.12.2021:<br />- Vergänglichkeit mit 365 Tagen bei 300 GDD = 150 GDD (nicht gerechnet, sondern 50%)<br />- die 150 GDD Vergänglichkeit als Tx-Buchung führt zu folgendem Kontostand:<br /> * 100 GDD aus der eigenen Community<br /> * 50 GDD aus der Community A<br /> * 0 GDD aus der Community B<br /> * gesamt 150 GDD<br /><br />Soweit der Gedankengang zur Bereinigung des Kontos mit GDD aus anderen Communities. Das hat keine Auswirkung auf die Wertigkeit, sondern soll sich allein auf die Reduktion der Viefältigkeit an Community-Währungen im eigenen Konto führen. |
* Bezahl-Vorbereitung
* Austausch von Blacklist zw. Teilnehmer
* ggf. Übersteuern der Balcklist falls gewünscht
@ -59,20 +88,24 @@ Aber grundsätzlich bleibt bei allen *Community-Gradido*-Währungen die Vergäng
| Ulf 07.11.2021 | Ich denke die vervielfachung von Coins und damit eine Ab/Auf-Wertung der jeweiligen Währen einer Community ist entgegen dem Konzept von Gradido. Gradido schafft eine stabile Zeit-Tausch-Einheit. Diese sollte Weltweit den gleichen Wert haben - warum sollte der Peruaner für seine Zeit weniger Gradido bekommen als ein Europäer? Das zementiert einfach weiterhin die bestehende Ordnung auf dem Planeten. Wollen wir das?<br />Daher mein Credo: Niemals einen Faktor zwischen Communities einführen. |
| Claus-Peter 25.11.2021 | Den Kommentar verstehe ich nicht in Bezug auf die zitierten Dokument-Zeilen.<br />Wo finden sich Hinweise auf eine Ab/Auf-Wertung der Währung?<br />Das Blacklisting ist mit Sicherheit ein sehr sensibler Punkt und muss genauestens und tiefer durchdacht und konzipiert werden.<br />Ansonsten stimme ich dem Inhalt und deinem Credo voll zu. |
### Anzeige und -Darstellung
Da es also mehrere Communities geben wird, benötigt jede Community ihren eigenen Namen und gar ein Symbol oder Bild, um eine optische Unterscheidung oder gar eigenes Branding bei der Anzeige in den Systemen sicherzustellen. Für eine Aussendarstellung wäre eine Beschreibung der Community und ihre eigene Philosopie, was die Community auszeichnet hilfreich. Diese Werte müssen vom Community-Administrator gepflegt werden können.
### Mitgliederverwaltung
Für die Verwaltung von Community-Mitgliedern werden entsprechende Verwaltungsprozesse wie Registrierung, Login mit Autentifizierung, eine Benutzerverwaltung für neue, bestehende und ausscheidende Mitgleider benötigt. Die Benutzerverwaltung stellt zusätzlich die Anforderung, dass ein Community-Mitglied eindeutig identifizierbar ist und das Community übergreifend. Das bedeutet es kann eine Person immer nur einmal existieren und darf auch niemals in mehreren Communities gleichzeitig Mitglied sein. Denn es muss sichergestellt werden, dass eine Person sich keine unerlaubte Vorteile durch zum Beispiel mehrfache Geldschöpfung in mehreren Communities verschafft.
Für die Verwaltung von Community-Mitgliedern werden entsprechende Verwaltungsprozesse wie Registrierung, Login mit Autentifizierung, eine Benutzerverwaltung für neue, bestehende und ausscheidende Mitgleider benötigt. Die Benutzerverwaltung stellt zusätzlich die Anforderung, dass ein Community-Mitglied eindeutig identifizierbar ist und das Community übergreifend. Das bedeutet es kann eine Person immer nur einmal existieren und darf auch niemals in mehreren Communities gleichzeitig Mitglied sein. Denn es muss sichergestellt werden, dass eine Person sich keine unerlaubte Vorteile durch zum Beispiel mehrfache Geldschöpfung in mehreren Communities verschafft.
Die Details der Mitgliederverwaltung werden beschrieben im Dokument [BenutzerVerwaltung](.\BenutzerVerwaltung.md).
#### ToDo:
Die oben beschriebene "global eindeutige Identifizierung" eines Mitglieds über alle Communities ist zunächst hier als grundlegend wünschenswertes Ziel aufgenommen. Da dies aber aktuell und vermutlich sogar in naher Zukunft technisch nicht möglich sein wird, gilt es Strategien zu entwerfen, die auf anderem Wege - z.B. Vertrauens- und Beziehungsgraphen auswerten und weitere SoftKriterien, die ein Mitglied identifizieren - eine quasi "übergreifende Identifzierung" per SoftSkills ermöglichen.
Die Details der Mitgliederverwaltung werden beschrieben im Dokument [BenutzerVerwaltung](./BenutzerVerwaltung.md).
### Community-Netzwerk
Ein grundlegender Ansatz des Gradido-Systems beinhaltet die Einstufung aller beteiligten Gradido-Communities als gleichberechtigte Einheiten. Diese bilden unterneinander ein Kommunikations-Netzwerk zum Austausch an Informationen, aber auch zum Aufbau eines gemeinsamen Verbundes weiterer Aktivitäten.
Ein grundlegender Ansatz des Gradido-Systems beinhaltet die Einstufung aller beteiligten Gradido-Communities als gleichberechtigte Einheiten. Diese bilden untereinander ein Kommunikations-Netzwerk zum Austausch an Informationen, aber auch zum Aufbau eines gemeinsamen Verbundes weiterer Aktivitäten.
#### Vernetzung
@ -101,7 +134,6 @@ Durch das Community-Netzwerk erfolgt auch der sehr wichtige Prozess der Sichers
| Ulf 07.11.2021 | Diese Anforderung ist technisch nicht zu erfüllen.<br />1. Eine Identifikation einer Person erfolgt immer mithilfe eines technischem Identifiers wie z.B. der Personalausweisnummer, EMail, Telefonnummer oder anderes. Schon durch diese Abstraktion kann ein Nutzer mehr als eine Identität aufbauen (2 Telefonnummer z.B.)<br />2. Die Prüfung auf Eindeutigkeit in einem dezentralen Netzwerk kann nicht sichergestellt werden, da Teile des Netzwerks zum Zeitpunkt der Prüfung nicht erreichbar oder gar unbekannt sein können.<br />3. Bedarf es den Austausch der Personen-Identifikation zwischen dem Communties: "kennst du email@domain.com?". Diese Daten können verschlüsselt werden z.B mit `hash(salt,email)` welche dann an jede Community geschickt werden: kennst du `hash(salt,email), salt`? Was dazu führt, dass jede Community den hash aller seiner EMails errechen muss - die Skalierung ist entsprechend schlecht.<br /><br />Alternativ kann hier eine Blockchain eingesetzt werden, welche `hash(salt,email), salt` speichert und als dezentrales Nachschlagewerk für alle zugänglich ist. Hier erwarte ich ein Konzept, bevor wir das umsetzen können. Die Sicherheit der Nutzerdaten ist ebenfalls genau zu untersuchen, wenn wir das ganze ins Internet blasen. |
| Claus-Peter 25.11.2021 | Ja da gebe ich dir nach heutigem Stand vollkommen Recht, dass es dafür derzeit keine 100% technische Lösung gibt.<br />Trotzdem ist das Thema fachlich gewünscht und wir müssen uns Gedanken machen, wie wir dafür eine technische Lösung finden können, die nahezu an die Anforderungen heranreicht. Genau deshalb endet dieser Absatz mit dem Hinweis auf die technsiche Konzeption. |
### Hirarchische Community
Um die Vision Gradido als Währung nicht nur in Communities als gemeinsame Interessensgemeinschaften zu etablieren, sondern auch für ganze Communen, Bundesländer, Nationen oder gar weltweit, bedarf es einer Strukturierung von Communities. Dazu dient das Konzept der *hierarchischen Community*, seinen Ursprung in der Abbildung des Föderalismus von Deutschland findet. Das bedeutet, dass eine baumartige Struktur von Communities aufgebaut werden kann, wie nachfolgendes Bild schemenhaft zeigt:
@ -111,7 +143,6 @@ Um die Vision Gradido als Währung nicht nur in Communities als gemeinsame Inter
| Ulf 25.11.2021 | Ich denke Förderalismus wie in der Bundesrepublik ist mit Gradido nicht möglich. Es ergibt sich durch das Schwundgeld einfach keine Vorteile eines Förderalismus.<br />Szenario Straßenbau zwischen zwei Communties:<br />- Warum sollte Geld von beiden Communities auf ein drittes Konto fließen, wenn es dort doch nur vergeht?<br />- Ist es nicht realistischer, dass beide Communties sich auf den Straßenbau einigen und das Geld direkt an den Auftragnehmer überweisen, um dem Schwund so weit es geht zu entgehen.<br /><br />Warum sollte sich eine Community einer anderen unterordnen? Was sind die Vorteile?<br />*Nur ein Gedanke* |
| Claus-Peter 25.11.2021 | Ich kann deinen Gedanken und Bedenken folgen, doch andererseits kann ich auch dem Föderalismus etwas abgewinnen.<br />Klar würde sich eine Community schwer tun, sich einer anderen Community unterzuordnen. Doch genau da beginnt die Überlegung, wie man ein Community-übergreifendes Projekt organisieren könnte? Da gibt es schon Vorteile, die natürlich noch feiner konzipiert und ausformuliert werden müssen. Daher sollten wir die Hierarchie von Communities nicht im Vorhinein ausschließen. |
![hierarchisches Community-Modell](./image/HierarchischesCommunityModell.png)
Es wird somit zwischen zwei Communities aus direkt benachbarten Ebenen eine Parent-Child-Beziehung erzeugt. Dadurch gehen diese beiden Communities eine besondere Beziehung untereinander ein, die zu folgenden veränderten Eigenschaften und Verhalten der Parent- und der Child-Community führen:
@ -157,7 +188,7 @@ Für die Dreifach-Geldschöpfung verwaltet die Community drei Arten von Konten:
Für jedes Mitglied der Community wird also ein eigenes AktiveGrundeinkommen-Konto verwaltet, auf das ein Drittel der monatlichen Geldschöpfung unter Einhaltung der AGE-Regeln fließt. Das Gemeinwohlkonto und das AUF-Konto existieren pro Community einmal und auf jedes der beiden Konten fließen monatlich die beiden anderen Drittel der Geldschöpfung.
Somit muss also eine Community für jede Kontoart die entsprechenden Kontoverwaltungsprozesse anbieten. Einmal in Verbindung pro Mitglied für das AGE-Konto und dann jeweils eine Verwaltung für das Gemeinwohlkonto und eine Verwaltung für das AUF-Konto. Die Berechtigungen für die Zugriffe auf die drei Kontoarten müssen ebenfalls in der Community gepflegt und kontrolliert werden. Das bedeutet die Community muss ihren Mitgliedern auf ihre eigenen AGE-Konten Zugriffsrechte erteilen und diese auch kontrollieren, so dass keine unerlaubten Zugriffe stattfinden können. Dann müssen in der Community bestimmte Mitglieder Sonderberechtigungen erhalten, um die Verwaltung des Gemeinwohlkontos und des AUF-Kontos durchführen zu können. Die Verwaltung der Berechtigungen ist wiederum alleine dem Community-Administrator erlaubt. Die Details der Kontenverwaltung ist im Dokument [KontenVerwaltung](.\KontenVerwaltung.md) beschrieben.
Somit muss also eine Community für jede Kontoart die entsprechenden Kontoverwaltungsprozesse anbieten. Einmal in Verbindung pro Mitglied für das AGE-Konto und dann jeweils eine Verwaltung für das Gemeinwohlkonto und eine Verwaltung für das AUF-Konto. Die Berechtigungen für die Zugriffe auf die drei Kontoarten müssen ebenfalls in der Community gepflegt und kontrolliert werden. Das bedeutet die Community muss ihren Mitgliedern auf ihre eigenen AGE-Konten Zugriffsrechte erteilen und diese auch kontrollieren, so dass keine unerlaubten Zugriffe stattfinden können. Dann müssen in der Community bestimmte Mitglieder Sonderberechtigungen erhalten, um die Verwaltung des Gemeinwohlkontos und des AUF-Kontos durchführen zu können. Die Verwaltung der Berechtigungen ist wiederum alleine dem Community-Administrator erlaubt. Die Details der Kontenverwaltung ist im Dokument [KontenVerwaltung](./KontenVerwaltung.md) beschrieben.
### Tätigkeitsverwaltung
@ -168,7 +199,6 @@ Hier handelt es sich um eine Verwaltung von Tätigkeitsbeschreibungen, die von d
| Ulf 07.11.2021 | Was ist wenn Tätigkeit A in Community X vergütet wird und Tätigkeit B in Community Y:<br />- Ich übe Tätigkeiten A & B aus<br />- Muss ich mich entscheiden, welche Tätigkeit ich vergütet wissen will? (Stichwort eindeutige Registrierung im gesammten Netzwerk) |
| Claus-Peter 25.11.2021 | Gute Frage!<br />Ich denke wir sollten im 1. Schritt damit beginnen, dass jede Community ihre eigene Aktivitätenliste pflegt. Es werden dann wohl gleiche Aktivitäten in mehreren Listen der verschiedenen Communities auftauchen.<br /><br />Ich kann aber als Mitglied der Community A eine Tätigkeit A.X von einem Mitglied aus Community B bestätigt bekommen und natürlich auch von Mitgliedern aus meine Community A.<br /><br />Dazu müssen dann natürlich die notwendigen Informationen zw. den Communities für eine Cross-Community-Bestätigung ausgetauscht werden. Das führt dann genau zu dem gewünschten Effekt, dass zw. zwei Communities ein Informationsaustausch stattfindet, der dann eine Aussage über den Cross-Handel und das Vertrauen ermöglicht. |
Zu der Liste der Tätigkeiten gibt es einen weiteren Prozess, der in dem Dokument [RegelnDerGeldschoepfung](./RegelnDerGeldschoepfung.md) näher beschrieben ist. Hier kann soviel erst einmal gesagt werden, dass die Tätigkeitenliste als Grundlage dient, damit ein Mitglied für seine erbrachten Leistungen für das Allgemeinwohl dann sein monatliches *Aktives Grundeinkommen* gutgeschrieben bekommt. Dieses Gutschreiben des AGEs unterliegt noch einer vorherigen Bestätigung von anderen Community- oder auch Community übergreifenden Mitgliedern. Somit erfolgt dadurch eine implizite Vernetzung der Mitglieder durch dieses aktive Bestätigen anderer Leistungen, was gleichzeitig wieder Vorraussetzung ist, um sein eigenes AGE zu erhalten.
### Berechtigungsverwaltung
@ -183,6 +213,18 @@ Mit der Vernetzung der Communities und dem gemeinsamen Handel zwischen Community
In diesem Kapitel werden die Attribute beschrieben, die in einer Community zu speichern sind.
#### Key
Der *Community-Key* dient zur technisch eindeutigen Identifizierung einer Gradido-Community in dem Multi-Community-Kommunikations Verbund. Der *Key* wird direkt bei der Inbetriebnahme einer neuen Community initialisiert - zum Beispiel als einfache UUID oder eine andere alphanummerische Sequenz - und während der Federation mit den schon existierenden Communities ausgetauscht. Falls dabei auffällt, dass irgendwelche Konflikte, wie ein exakt gleicher Key einer anderen Community oder gleiche URL bei unterschiedlichen Keys, etc. , exisitieren, dann wird der Key mit einem neuen Wert initialisiert bis alle Konflikte für eine Eindeutigkeit der Community im gesamten Community-Verbund beseitigt sind.
Die Motivation dieses technischen Schlüssels liegt in der einmaligen Initialisierung bei der Community-Erstellung und in der Unveränderlichkeit danach. Alle anderen möglichen Attribute, die ebenfalls als Schlüssel für eine Community nutzbar wären, wie die URL oder evtl. der Name, können im Laufe der Existenz einer Community verändert werden.
Der genaue Vorgang dieser *Key*-Initialisierung wird weiter unten im Kapitel "Neue Community erstellen" bzw. im technischen Konzept der Federation beschrieben.
Die Verwendung des *Community-Key* wird auch zur Identifikation eines in der Community geschöpften Betrages - genannt *Currency-Key* - verwendet, so dass mit jedem Betrag gleichzeitig auch die Zuordnung zur Schöpfungs-Community hergestellt werden kann. Details hierzu siehe Kapitel "*Community-Gradido*" weiter oben.
Das Attribut *Key* wird einmalig definiert und kann nicht mehr verändert werden. Es gibt keine Schreibrechte für nachträgliches Ändern, auch nicht von einem Administrator.
#### Name
Das Attribut *Name* dient zur möglichst eindeutigen Benennung der Community. Er wird als Menschen lesbare Anzeige und als Unterscheidungskriterium bei mehreren Communities eingesetzt. Nur der Community Administrator kann diesen setzen und verändern.
@ -195,9 +237,9 @@ Das Attribut *Bild* wird für die Anzeige einer Community verwendet und kann nur
Das Attribut *Beschreibung* ist ein Text, der die Philosophie der Community ausdrücken soll. Hier können sich die Community-Mitglieder eine gemeinsame Formulierung ausdenken, die nach ihrer Vorstellung den Kern und die Grundregeln ihrer Gemeinschaft am besten ausdrücken. Dies könnte wie eine Art Aussendarstellung für neue Mitglieder dienen. Aber nur der Community-Administrator hat die Schreib-Rechte für dieses Attribut.
#### Serverzuordnung
#### URL
Das Attribut *Serverzuordnung* ist technisch motiviert und dient zusammen mit dem Attribut Name der eindeutigen Identifikation einer Community. Bei der Gründung einer neuen Community muss festgelegt werden auf welchem Server diese Community gehostet wird - auf einem schon vorhandenen Server oder ein extra für diese Community neu aufgesetzter Server. Das Attribut Serverzuordnung muss aber für eine Virtualisierung und technische Skalierung auf mehrere Server-Instanzen vorbereitet sein, sodass keine direkte physische Hardware-Serverzuordnung hierdurch fixiert ist. Aber auch ein eventueller Umzug der Community von einem Server auf einen anderen Server muss möglich sein. Der Community-Administrator hat alleiniges Zugriffsrecht auf dieses Attribut.
Das Attribut *URL* ist eher technisch motiviert und dient zur weltweit eindeutigen Adressierung einer Community. Bei der Gründung einer neuen Community muss festgelegt werden über welche URL diese Community addressiert werden kann. Das Routing wo exakt die Community gehostet wird - auf einem schon vorhandenen Server oder ein extra für diese Community neu aufgesetztem Server - muss von der URL unabhängig in der Community-Konfiguration vom Administrator definiert werden. Das Attribut URL muss aber für eine Virtualisierung und technische Skalierung auf mehrere Server-Instanzen vorbereitet sein, sodass keine direkte physische Hardware-Serverzuordnung hierdurch fixiert ist. Aber auch ein eventueller Umzug der Community von einem Server auf einen anderen Server muss möglich sein. Der Community-Administrator hat alleiniges Zugriffsrecht auf dieses Attribut.
#### Liste von Benutzer
@ -205,11 +247,11 @@ Dieses Listenattribut beinhaltet Benutzer-Elemente, die erfolgreich als Mitglied
#### Gemeinwohlkonto
Das Attribut *Gemeinwohlkonto* dient als ein Konto-Element, das den Kontotyp Gemeinwohlkonto repräsentiert. Alle Kontobewegungen, wie Geldschöpfung, Geldtransfers, etc., die das Gemeinwohl dieser Community betreffen, werden über dieses Attribut abgewickelt. Details zu Kontobewegungen werden im Dokument [KontenVerwaltung](KontenVerwaltung.md) beschrieben und die Regeln und Vorgänge der Geldschöpfung sind im Dokument [RegelnDerGeldschoepfung](RegelnDerGeldschoepfung.md) zu finden. Auf dieses Attribut haben nur Mitglieder mit entsprechenden Zugriffsrechten die Erlaubnis und Möglichkeiten darauf Einsicht zu nehmen und Prozesse auszulösen.
Das Attribut *Gemeinwohlkonto* dient als ein Konto-Element, das den Kontotyp Gemeinwohlkonto repräsentiert. Alle Kontobewegungen, wie Geldschöpfung, Geldtransfers, etc., die das Gemeinwohl dieser Community betreffen, werden über dieses Attribut abgewickelt. Details zu Kontobewegungen werden im Dokument [KontenVerwaltung](./KontenVerwaltung.md) beschrieben und die Regeln und Vorgänge der Geldschöpfung sind im Dokument [RegelnDerGeldschoepfung](./RegelnDerGeldschoepfung.md) zu finden. Auf dieses Attribut haben nur Mitglieder mit entsprechenden Zugriffsrechten die Erlaubnis und Möglichkeiten darauf Einsicht zu nehmen und Prozesse auszulösen.
#### Ausgleichs- und Umweltkonto AUF-Konto
Das Attribut *Ausgleichs- und Umweltkonto* dient als ein Konto-Element, das den Kontotyp AUF-Konto repräsentiert. Alle Kontobewegungen, wie Geldschöpfung, Geldtransfers, etc., die das AUF-Konto dieser Community betreffen, werden über dieses Attribut abgewickelt. Details zu Kontobewegungen werden im Dokument [KontenVerwaltung](KontenVerwaltung.md) beschrieben und die Regeln und Vorgänge der Geldschöpfung sind im Dokument [RegelnDerGeldschoepfung](RegelnDerGeldschoepfung.md) zu finden. Auf dieses Attribut haben nur Mitglieder mit entsprechenden Zugriffsrechten die Erlaubnis und Möglichkeiten darauf Einsicht zu nehmen und Prozesse auszulösen.
Das Attribut *Ausgleichs- und Umweltkonto* dient als ein Konto-Element, das den Kontotyp AUF-Konto repräsentiert. Alle Kontobewegungen, wie Geldschöpfung, Geldtransfers, etc., die das AUF-Konto dieser Community betreffen, werden über dieses Attribut abgewickelt. Details zu Kontobewegungen werden im Dokument [KontenVerwaltung](./KontenVerwaltung.md) beschrieben und die Regeln und Vorgänge der Geldschöpfung sind im Dokument [RegelnDerGeldschoepfung](./RegelnDerGeldschoepfung.md) zu finden. Auf dieses Attribut haben nur Mitglieder mit entsprechenden Zugriffsrechten die Erlaubnis und Möglichkeiten darauf Einsicht zu nehmen und Prozesse auszulösen.
#### Verteilungsschlüssel der Dreifachen-Schöpfung
@ -237,7 +279,7 @@ Der Prozess *Neue Community erstellen* kann in zwei grundlegende Schritte unterg
Um eine neue Community zu erstellen wird eine dafür speziell konzepierte Infrastruktur benötigt. Die technischen Details dieser Infrastruktur werden in der *technischen Infrastruktur Beschreibung* als eigenständiges Dokument dem Administrator der neuen Community zur Verfügung gestellt. Diese ist neben den Installationsskripten und Anwendungsdateien Teil des Auslieferungspaketes der Gradido-Anwendung.
Sobald der Administrator die geforderte Infrastruktur in Betrieb genommen und darauf die entsprechenden Installationsskripte ausgeführt hat erfolgt die eigentliche Erstellung und Registrierung der neue Community. Das heißt beim erstmaligen Start der Gradido-Anwendung wird automatisch der Prozess *Neue Community erstellen* gestartet.
Sobald der Administrator die geforderte Infrastruktur in Betrieb genommen und darauf die entsprechenden Installationsskripte ausgeführt hat, erfolgt die eigentliche Erstellung und Registrierung der neue Community. Das heißt beim erstmaligen Start der Gradido-Anwendung wird automatisch der Prozess *Neue Community erstellen* gestartet.
#### Ablauf
@ -245,18 +287,133 @@ Der Prozess *Neue Community erstellen* wird entweder automatisiert beim erstmali
![Ablauf Neue Community erstellen](./image/Ablauf_Neue_Community_erstellen.png)
##### Einzelschritte
Der oben grafisch dargestellte Ablauf wird in drei grobe Teile untergliedert:
1. )den eigentlichen Community-Prozess "*neue Community erstellen*" (links in grün gehalten), in dem die Community spezifischen Attribute erfasst, geladen und/oder angelegt werden. Dazu gehören neben dem Erfassen der Community eigenen Attributen, das Laden von vordefinierten Standard-Daten wie die Tätigkeitsliste, Berechtigungen, etc. und optional als eigenständiger Prozess die Erfassung bzw das Anlegen von neuen Community-Mitgliedern.
2. das Starten der "*Federation*" als Hintergrundprozess, um die neu erstellte Community im Gradido-Community-Verbund bekannt zu machen. Dietechnischen Details der *Federation* werden im Dokument [Federation](../TechnicalRequirements/Federation.md " ") beschrieben. Dabei wird
* als erstes geprüft, ob in der eigenen Community die notwendigen Attribute wie Community-Key, URL und ggf. weitere korrekt initialisiert und gespeichert sind. Falls nicht wird der Hintergrundprozess mit einem Fehler abgebrochen
* dann werden die Attribute Community-Key und URL in eine *newCommunity*-Message gepackt und asynchron an den Public-Channel der Community-Federation des Gradido-Community-Verbundes gesendet
* Im Anschluss geht der Federation-Prozess in den "Lausch-Modus" auf eingehende Messages am *Public-Channel*. Die Verarbeitung von eingehenden Messages muss so sichergestellt werden, dass einerseits keine Message verloren geht auch bei DownTimes und andererseits, dass eine Message erst aus dem Public-Channel gelöscht wird, sobald diese vollständig abgearbeitet ist. Der Federation-Prozess lauscht auf Messages vom Typ *replyNewCommunity* und *newCommunity*, die bei Empfang entsprechend verarbeitet werden:
* *replyNewCommunity*-Messages werden auf die zuvor gesendete *newCommunity*-Message als Antwort von allen anderen schon im Verbund existierenden Communities erwartet. Je nach MessageState erfolgt eine unterschiedliche Weiterverarbeitung:
* Ist der *MessageState = OK*, dann werden die erhaltenen Daten - Community-Key und URL - von der antwortenden Community in der Community-Datenbank als internen Liste für "*bekannte Communities*" gespeichert. Nach dem Speichern eines neue Community-Eintrags in dieser Liste wird asynchron der dritten und letzten Schritt der Federation *"Community-Communication"* als Hintergrundprozess getriggert und geht dann wieder zurück in den "Lausch-Modus" am Public-Channel.
* Ist der MessageState = requestNewKey, dann erfolgt eine Neugenerierung und Speicherung des eigenen Community-Keys, der dann erneut als *newCommunity*-Message auf den Public-Channel verschickt wird. Danach geht der Federation-Prozess wieder in den "Lauch-Modus", um auf Anworten der existierenden Communities zu warten.
* *newCommunity*-Messages werden von neu erstellten Communities im Rahmen derer Federation in den Public-Channel gesendet. Diese Messages sollten möglichst zeitnah von möglichst vielen schon existierenden Communities beantwortet werden. Dazu wird zuerst in der Community-Datenbank nach Einträgen gesucht, die den gleichen Community-Key aber eine unterschiedliche URL als zu den empfangenen Daten haben:
* Sollte es einen solchen Eintrag geben, dann wird eine *replyNewCommunity*-Message erzeugt mit *MessageState = requestNewKey* und ohne weitere Daten in den Public-Channel zurückgesendet. Danach wird wieder in den "Lausch-Modus" am Public-Channel gewechselt.
* Sollte es keine solche Einträge geben, dann werden die eigenen Daten *Community-Ke*y und *URL* in eine *replyNewCommunity*-Message gepackt, der *MessageState = OK* gesetzt und direkt in den Public-Channel zurückgesendet. Danach wird wieder in den "Lausch-Modus" am Public-Channel gewechselt.
* | PR-Kommentar | |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Ulf<br />24.03.2022 | Schitte 1 & 2 sind komplett durch die Federation an sich abgedeckt. Bereits über die Federatierungsschnittstelle wird eine Direktverbindung zum Peer aufgebaut um Daten auszutauschen (die URLs)<br />Mehr infos:<br />[https://en.wikipedia.org/wiki/Kademlia](https://en.wikipedia.org/wiki/Kademlia)[https://github.com/hyperswarm/dht](https://github.com/hyperswarm/dht) |
*
3. und die *"Community-Communication"* als Hintergrundprozess. Dieser liest zuerst die eigenen Community-Daten und geht dann per Direkt-Verbindung über die URL mit der neuen Community in Dialog, um sich zuerst gegenseitig zu authentifizieren und um dann die Community spezifischen Daten untereinander auszutauschen. Der logische Ablauf dieser Kommunikation soll wie folgt dargestellt ablaufen:
![AuthenticateCommunityCommunication](.\image\AuthenticateCommunityCommunication.png " ")
Die genaue Beschreibung der dazu verwendeten APIs beider Communities erfolgt in der technischen Konzeption [CommunityCommunication](../TechnicalRequirements/CommunityCommunication.md). Wie der obigen Grafik zu entnehmen ist, erfolgt bei einer neuen Community eine einmalig zu durchlaufende Aufruf-Kette zur Authentifizierung (1. Sequenz), deren Ergebnisse in den beteiligten Communities gespeichert bleiben. Der danach folgende Request (2. Sequenz) wird vor jeder neu initiierten Kommunikation zwischen zwei Communities notwendig, um ein zeitlich gültiges Authentifizierungs-Token für die nachfolgenden fachlichen Requeste (3. Sequenz) zu erhalten.
Die aller erste fachliche Kommunikation zwischen einer neu erstellten und einer schon existierenden Community ist die Annäherung der beiden Communities, in dem sie sich gegenseitig mit dem Request "*familiarizeCommunity*" ihre eigenen Daten in Form eines *CommunityTO*-TransferObjektes austauschen. Im zweiten Schritt erfragen sie sich gegenseitig, wie sie zukünftig miteinander Handel treiben wollen. Die Details über die Aushandlung des Tradinglevels der beiden Communities sind hier im Dokument im Anwendungsfall [Communities Tradinglevel aushandeln](#Communities-Tradinglevel-aushandeln) beschrieben.
#### Ende Status
1. Community-Infrastruktur ist installiert und aktiv
2. neue Community ist erzeugt und Daten in der Community-DB gespeichert
3. der Hintergrundprozess "Community-Vernetzung" ist am Laufen
3. der Hintergrundprozess *Federatio*n ist am Laufen
* die initiale "newCommunity-Msg" mit den eigenen Community-Daten ist in den Public-Channel versendet
* ein Listener lauscht am Public-Channel auf Antworten (replyNewCommunityMsg) der schon existenten Communities
* ein Listener lauscht am Public-CHannel auf initiale "newCommunity-Msg" anderer neuer Communities
4. mit dem ersten Empfangen einer Reply-Msg einer anderen Community, wird der Community-Connection Prozess gestartet, der mit jedem Empfang von neuen Community-Daten eine P2P-Verbindung zu dieser Community aufbaut, um direkt detaillierte Daten auszutauschen
5. die vordefinierte Tätigkeitsliste ist geladen
6. die vordefinierten Berechtigungen sind aktiv
7. optional sind schon Mitglieder erfasst und in der Datenbank gespeichert
* ein Listener lauscht am Public-Channel auf Antworten (*replyNewCommunity*-Msg) der schon existenten Communities
* ein Listener lauscht am Public-Channel auf initiale "*newCommunity*-Msg" anderer neuer Communities
4. mit dem ersten Empfangen einer *replyNewCommunity*-Msg einer anderen Community, wird der *Community-Communication* Prozess gestartet und ist am Laufen.
5. mit jedem Empfang einer *replyNewCommunity*-Msg haben sich die involvierten Communities direkt miteinander verbunden, sich gegenseitig authentifiziert (Austausch der public-Keys) und weitere Daten ausgetauscht
6. die vordefinierte Tätigkeitsliste ist geladen
7. die vordefinierten Berechtigungen sind aktiv
8. optional sind schon Mitglieder erfasst und in der Datenbank gespeichert
#### Fehlerfälle
### Communities Tradinglevel aushandeln
Im Anwendungsfall *Communities Tradinglevel aushandeln* geht es darum, dass die beiden involvierten Communities sich gegenseitig anfragen und bestätigen auf welchem Level bzw. mit welchen Detailtiefe sie zukünftig Datenaustauschen und miteinander interagieren.
Diese Aushandlung bedarf auf beiden Seiten administrative als auch strategische Interaktionen und Entscheidungen. Daher kann dies kein synchroner Anfrage-Bestätigungs-Loop sein, sondern es muss zwischen einer Tradinglevel-Anfrage und ihrer Bestätigung ein Zeitfenster von gegebenenfalls mehreren Tagen vorgesehen werden.
Folgende Tradinglevels sind derzeit vorgesehen:
* Mitglieder-Details senden : Kennung, ob die *Community-A* zukünftig weitere Details über die eigenen Mitglieder an *Community-B* sendet
* Mitglieder-Details empfangen : Kennung, ob die *Community-A* zukünftig weitere Details über die Mitglieder von *Community-B* empfängt
* Geld empfangen : Kennung, ob *Community-A* zukünftig Geld an *Community-B* sendet
* Geld senden : Kennung, ob *Community-A* zukünftig Geld von *Community-B* empfängt
* Aktivitäten senden : Kennung, ob *Community-A* zukünftig die offenen Aktivitäten seiner Mitglieder an *Community-B* zur Bestätigung sendet
* Aktivitäten empfangen : Kennung, ob *Community-A* zukünftig die offenen Aktivitäten der Mitglieder von *Community-B* zur Bestätigung empfängt
* Backup senden : Kennung, ob *Community-A* zukünftig Daten an *Community-B* als Backup sendet
* Backup empfangen : Kennung, ob *Community-A* zukünftig Daten von *Community-B* als Backup empfängt
#### Vorraussetzungen
Bevor *Community-A* mit dem Aushandeln des Tradinglevels mit *Community-B* beginnen kann, muss in der *Community-A* erst einmal selbst Konsens geschaffen sein, welchen Level mal haben und auch unterstützen will. Das bedeutet der Administrator und die Community-Verantwortlichen müssen in der *Community-A* mit den eigenen Mitgliedern sich darüber einig sein, wie sie zukünftig mit der *Community-B* und deren Mitgliedern im Vertrauen und im Austausch stehen wollen.
Sobald diese Vorstellung des zukünftigen Austausches klar ist und die administrativen und organisatorischen Vorraussetzungen dazu getroffen und umgesetzt sind - z.B. bei Bereitschaft für Backup-Daten empfangen müssen auch ausreichend Resourcen für diesen Dienst vorhanden sein oder bei Mitglieder-Details senden müssen die Mitglieder damit einverstanden sein - kann die Anfrage von *Community-A* an *Community-B* gestartet werden.
#### Ablauf
##### PR-Kommentar:
Ulf:
Das Teilnehmen an der Federation startet diesen Prozess
Claus-Peter:
Nicht ganz, ja bei der Federation wird es einen Austausch des
Trading-Levels geben. Dazu muss dieser aber vorher in den Communities
insbesonderen der neu hinzugekommenen Community schon definiert bzw.
konfiguriert sein. Und diese Konfiguration ist entweder in der Community
schon abgeklärt oder es handelt sich lediglich um die
Default-Konfiguration und muss im Laufe der Zeit aktualisierbar sein.
Community-A startet den Prozess des Tradinglevel-aushandelns indem der Administrator die zuvor geschaffenen Vorraussetzungen entsprechend in der Community internen Datenbank erfasst. Ob dies per Configurationsdatei oder über ein Admin-Dialog umgesetzt wird, bleibt erst einmal offen.
Um den eigentlichen fachlichen Request mit den vorhandenen Tradinglevel-Daten aufrufen zu können, muss zuerst die Kommunikation zwischen den Communities zur Authentifizierung mit dem Request *openCommunication* abgesetzt werden. Nach Erhalt eines gültigen JWT-Tokens wird dann die Anfrage von *Community-A* nach dem gewünschten Trading-Level mit *Community-B* über den Aufruf requestTradingLevel abgesetzt. Als direktes Ergebnis dieser Anfrage erhält Community-A nur die Information, ob Community-B die TradingLevel-Daten erfolgreich erhalten hat oder nicht.
In *Community-A* selbst wird intern vermerkt, dass die TradingLevel-Anfrage an *Community-B* abgeschickt und offen ist.
In *Community-B* sind die angefragten Tradinglevel-Daten von *Community-A* in der internen Community-Liste gespeichert und müssen nun die Community internen Abstimmungen und Vorbereitungen erfolgen. Diese kann durchaus über einen längeren Zeitraum von mehreren Tagen dauern.
##### PR-Kommentar
Ulf:
Das ist ein kontinuierlicher Prozess, da er einseitig erfolgt und nur das zutun einer Partei benötigt.
Claus-Peter:
Wenn dies ein kontinuierlicher Prozess ist, dann wird es auch auf beiden
Seiten Änderungen geben können. Klar ist, dass eine Community-A den
Trading-Level von Community-B abfragt. Die Abfrage wird ohne Zutun von
Community-B Mitgliedern automatisch ablaufen. Aber die evtl. Änderungen,
die vor einer Aktualisierungsabfrage passieren, werden aber in der
Community unter den Mitgliedern oder zumindest unter den
Support/Admins/Vorständen o.ä abgestimmt. Und diese Abstimmungsaufwände
kosten bestimmt einige Zeit, bis diese in der Trading-Level-Konfig
einpflegbar und dann auch von anderen Communities abfragbar sind.
Sobald in *Community-B* das Abstimmungsprozedere und die Vorstellungen des zukünftigen Interagierens mit *Community-A* beendet und erfasst sind, startet *Community-B* selbst die Bestätigung der offenen Anfrage von *Community-A*. Dazu muss auch wieder erst die Kommunikation authentifiziert und eröffnet werden, um ein gültiges JWT-Token zu erhalten. Mit dem Token und den in *Community-B* abgestimmten TradingLevel-Daten erfolgt über *confirmTradingLevel* die Übertragung der Daten nach *Community-A*. Mit Erhalt und Speicherung der Daten erfolgt eine erste Auswertung für den direkten Response an *Community-B*. Dieses Ergebnis für *Community-B* kann folgende Konstellationen haben:
* OK : bei vollständiger Übereinstimmung des zuvor angefragten TradingLevels
* ERROR : der Empfang und die Prüfung der erhaltenen TradingLevel-Daten sind technisch fehlerhaft. *Community-B* muss den *confirmTradingLevel*-Request ausführen.
* RESERVE : die Daten wurden erfolgreich empfangen, die Prüfung ergab Unterschiede, der Trading-Level wird unter Vorbehalt bis zur abschliessenden Prüfung erst einmal so gestartet. Eventuelle Änderungen erfolgen mit einem erneuten *Request/ConfirmTradingLevel*-Loop.
* REJECT : die Daten wurden erfolgreich empfangen, die Prüfung ergab gravierende Unterschiede, der Trading-Level muss erneut vollständig ausgehandelt werden. Bis dahin werden alle Trading-Interaktion zwischen den beiden Communities abgelehnt.
#### Ende Status
Als Ende diese Anwendungsfalles kann es folgende Konstellationen geben:
* die Abstimmung und der Austausch waren erfolgreich, so dass nun in beiden Communities der gleiche TradingLevel zu jeder involvierten Community gespeichert ist. Die Interaktionen des ausgehandelten TradingLevels sind nicht aktiviert, es stehen lediglich die Informationen bereit welche Interaktionen zwischen den Communities A und B erwünscht und bestätigt sind.
* die Abstimmung und der Austausch wurden unter Vorbehalt angenommen. Es sind in beiden Communities der gleiche TradingLevel zu jeder involvierten Community gespeichert. Die Interaktionen des ausgehandelten TradingLevels sind nicht aktiviert, es stehen lediglich die Informationen bereit welche Interaktionen zwischen den Communities A und B ausgehandelt sind und unter Vorbehalt angewendet werden können.
* Die Abstimmung und der Austausch sind erfolgt, im Ergebnis sind die TradingLevels der beiden Communities zu unterschiedlich, so dass diese abgelehnt wurden. Die Daten bleiben aber auch in diesem Fall in der jeweiligen Community gespeichert, so dass für zukünftige Anfragen schon einmal ein Eindruck der jeweiligen Community vorhanden ist.
#### Fehlerfälle
@ -331,78 +488,3 @@ Der Prozess *Neue Community erstellen* wird entweder automatisiert beim erstmali
#### Ende Status
#### Fehlerfälle
# Besprechung 19.08.2021 19:00 mit Bernd
## Kreis-Mensch-Sein-Community
Felix Kramer
noch keine eigene Währung, wollen gerne Gradido
haben auch aktives Grundeinkommen
passt aber nicht ganz zur Gradido Philosophie, weil Gemeinwohlleistung zu unterschiedlich bewertet werden.
-> Colored Gradido?
Community-Creation
GDD1 (gold) ist existent
Felix baut GGD2-Infrastruktur auf
* Frage: willst du GDD1(gold) oder eigene Währung?
* Antwort: nein ich will eigene GDD2 (rot)
* muss neue Währung erzeugen
* Antwort: ja, dann Anfrage an GDD1, dass GDD2 auch Goldene GDD1 schöpfen darf?
* Ja wird akzeptiert
* dann bekommt GDD2 die Lizenz goldene GDD1 schöpfen kann
Kommt später heraus, dass GDD2 nicht mehr den goldenen Regeln entspricht, dann muss die Lizenz zum goldene GDD1 Schöpfen für GDD2 gesperrt werden.
Bisher geschöpfte goldene GDD2 beleiben aber erhalten.
Es darf keine Markierung des Bot-Mitglieds geben, da Missbrauch/Fehler möglich
Identität für ein Mitglied muss Human/Nichthuman enthalten
GDD2 muss mit Lizenzentzug wechseln auf eigene Währung um weiterschöpfen zu können.
Mitgliederwechsel in andere Community muss dann auch Währungswechsel berücksichtigen.
Bestcase: 1 Blockchain pro Währung
GDD1(gold) existent
GDD2(gold) soll gegründet werden
GDD2 baut Infrasturktur auf
Frage an GDD2, ob goldene oder andere?
### Tätigkeiten, die von der Community aktzeptiert werden
Nachweise für durchgeführte Tätigkeiten, bevor diese dem AGE-Konto gutgeschrieben werden?
Liste der Tätigkeiten muss von Community erstellt, bestätigt und verwaltet werden
Bei Tätigkeit von x Stunden für das AGE muss aus der Liste die passende Tätigkeit gewählt werden und per Nachweis (andere Mitglieder, Video, o.ä.)
Bei Krankheit o.ä. muss es aber möglich sein, dass dennoch Geld auf das AGE-Konto kommt.
| PR-Kommentar | |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ulf 07.11.2021 | Definition? Ist Faulheit eine Krankheit? |
| Claus-Peter 25.11.2021 | :-) Das kommt auf die solidarische Einstellung der Community an ;-)<br /><br />da drängt sich mir die Gegenfrage auf: Bis zu welchem Alter bekommt ein Kind sein AGE-Geld geschöpft nur durch seine blos Existenz? Oder andersherum, ab und bis zu welchem Alter muss eine Gegenleistung erbracht werden, Stichworte: unbeschwerte Kindheit und wohlverdiente Altersruhe? |
Kontaktförderung durch gewichtete Tätigkeitsbestätigung ( bei mind. 2 Bestätigungen pro Tätigkeit muss mind. ein neues Mitglied dabei sein)
Liste von Mitgliedern, die ich bestätigt habe:
* Kontaktpflege
* Gewichtung
* Vernetzung
Ricardo Leppe Podcast Lern und Memotechniken

View File

@ -1,20 +1,23 @@
<mxfile>
<mxfile host="65bd71144e">
<diagram id="Lc_Wy6ZhKx3Be9Prl_QG" name="Page-1">
<mxGraphModel dx="1088" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1654" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="28" value="Community-Prozess" style="html=1;align=left;verticalAlign=top;absoluteArcSize=1;arcSize=18;dashed=0;spacingTop=10;spacingRight=30;strokeColor=#82b366;strokeWidth=2;fillColor=#d5e8d4;gradientColor=#97d077;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="40" y="130" width="1220" height="910" as="geometry"/>
<mxCell id="28" value="&lt;b&gt;Gradido-Anwendung&lt;/b&gt;" style="html=1;align=left;verticalAlign=top;absoluteArcSize=1;arcSize=18;dashed=0;spacingTop=10;spacingRight=30;strokeColor=#82b366;strokeWidth=2;fillColor=#d5e8d4;gradientColor=#97d077;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="40" y="130" width="1220" height="990" as="geometry"/>
</mxCell>
<mxCell id="27" value="Prozess: Community-Vernetzung" style="html=1;align=left;verticalAlign=top;absoluteArcSize=1;arcSize=18;dashed=0;spacingTop=10;spacingRight=30;strokeColor=#6c8ebf;strokeWidth=2;fillColor=#dae8fc;gradientColor=#7ea6e0;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="610" y="264.5" width="640" height="555.5" as="geometry"/>
<mxCell id="108" value="Community-Prozess" style="html=1;align=left;verticalAlign=top;absoluteArcSize=1;arcSize=18;dashed=0;spacingTop=10;spacingRight=30;strokeColor=#005700;strokeWidth=2;fillColor=#008a00;fontColor=#ffffff;rounded=1;" vertex="1" parent="1">
<mxGeometry x="110" y="180" width="240" height="640" as="geometry"/>
</mxCell>
<mxCell id="27" value="Hintergrund-Prozess: &lt;b&gt;Federation&lt;/b&gt;" style="html=1;align=left;verticalAlign=top;absoluteArcSize=1;arcSize=18;dashed=0;spacingTop=10;spacingRight=30;strokeColor=#6c8ebf;strokeWidth=2;fillColor=#dae8fc;gradientColor=#7ea6e0;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="610" y="264.5" width="640" height="645.5" as="geometry"/>
</mxCell>
<mxCell id="30" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontColor=#000000;strokeColor=#000000;" parent="1" source="2" target="4" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="185" y="170"/>
<mxPoint x="250" y="170"/>
<mxPoint x="230" y="170"/>
</Array>
</mxGeometry>
</mxCell>
@ -26,11 +29,11 @@
<mxPoint x="250" y="210" as="targetPoint"/>
<Array as="points">
<mxPoint x="405" y="170"/>
<mxPoint x="250" y="170"/>
<mxPoint x="230" y="170"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="77" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;" edge="1" parent="1" source="3" target="75">
<mxCell id="77" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;" parent="1" source="3" target="75" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="405" y="170"/>
@ -38,7 +41,7 @@
</Array>
</mxGeometry>
</mxCell>
<mxCell id="95" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.75;entryY=0;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;" edge="1" parent="1" source="3" target="38">
<mxCell id="95" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.75;entryY=0;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;" parent="1" source="3" target="38" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="70"/>
@ -54,74 +57,62 @@
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="4" value="Initialisiere Prozess &lt;br&gt;&quot;Neue Community erstellen&quot;" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;rounded=1;" parent="1" vertex="1">
<mxGeometry x="150" y="202.63" width="200" height="40" as="geometry"/>
<mxGeometry x="130" y="220" width="200" height="40" as="geometry"/>
</mxCell>
<mxCell id="8" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#000000;" parent="1" source="5" target="7" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="5" value="Attribute der Community erfassen &lt;br&gt;bzw. aus Config lesen&lt;br&gt;&lt;div style=&quot;text-align: left&quot;&gt;&lt;span&gt;- Name&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left&quot;&gt;&lt;span&gt;- Icon / Bild (opt.)&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left&quot;&gt;&lt;span&gt;- Beschreibung&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left&quot;&gt;&lt;span&gt;- hosted Server / URL&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left&quot;&gt;&lt;span&gt;- Währungsname (opt.)&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left&quot;&gt;&lt;span&gt;- Währungskürzel (opt.)&lt;/span&gt;&lt;/div&gt;" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;rounded=1;" parent="1" vertex="1">
<mxGeometry x="150" y="280" width="200" height="120" as="geometry"/>
<mxGeometry x="130" y="280" width="200" height="120" as="geometry"/>
</mxCell>
<mxCell id="12" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#000000;exitX=0.75;exitY=0;exitDx=0;exitDy=0;" parent="1" source="24" target="13" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="520" y="420" as="targetPoint"/>
<Array as="points">
<mxPoint x="425" y="451"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="51" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#1A1A1A;" edge="1" parent="1" source="7" target="50">
<mxCell id="51" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#1A1A1A;" parent="1" source="7" target="50" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="7" value="erzeuge techn. Community-Keys:&lt;br&gt;&lt;div style=&quot;text-align: left&quot;&gt;&lt;span&gt;- Community-ID&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left&quot;&gt;&lt;span&gt;- Community-Currency-ID&lt;/span&gt;&lt;/div&gt;" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;rounded=1;" parent="1" vertex="1">
<mxGeometry x="150" y="423.13" width="200" height="60" as="geometry"/>
<mxCell id="7" value="erzeuge techn. Community-Keys:&lt;br&gt;&lt;div style=&quot;text-align: left&quot;&gt;&lt;span&gt;- Key&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left&quot;&gt;&lt;span&gt;- Currency-Key&lt;/span&gt;&lt;/div&gt;" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;rounded=1;" parent="1" vertex="1">
<mxGeometry x="130" y="423.13" width="200" height="60" as="geometry"/>
</mxCell>
<mxCell id="17" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#000000;" parent="1" source="13" target="16" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="70" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;" edge="1" parent="1" source="13" target="72">
<mxCell id="70" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="13" target="72" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="785" y="364.5"/>
<mxPoint x="785" y="364.5"/>
<mxPoint x="755" y="365"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="74" value="Nein" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=14;fontColor=#000000;labelBackgroundColor=#B0E3E6;rounded=1;" vertex="1" connectable="0" parent="70">
<mxCell id="74" value="Nein" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=10;fontColor=#000000;labelBackgroundColor=#B0E3E6;rounded=1;" parent="70" vertex="1" connectable="0">
<mxGeometry x="-0.2906" y="-1" relative="1" as="geometry">
<mxPoint as="offset"/>
<mxPoint x="-1" y="-4" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="13" value="Community-Attribute:&#10;(Name, Community-ID, URL)&#10;vorhanden?" style="rhombus;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;align=center;rounded=1;" parent="1" vertex="1">
<mxGeometry x="690" y="410.5" width="190" height="80" as="geometry"/>
<mxCell id="13" value="Community-Attribute:&#10;(Community-Key, URL, etc.)&#10;vorhanden?" style="rhombus;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;align=center;rounded=1;" parent="1" vertex="1">
<mxGeometry x="660" y="410" width="190" height="80" as="geometry"/>
</mxCell>
<mxCell id="19" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#000000;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="16" target="20" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="785" y="517.13" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="16" value="Sende Community-Attribute&lt;br&gt;auf public Channel" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="960" y="429.76" width="210" height="40" as="geometry"/>
<mxCell id="16" value="Sende &quot;&lt;b&gt;newCommunity-Msg&quot;&lt;/b&gt;&lt;br&gt;mit Community-Key und URL&lt;br&gt;auf public Channel" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="960" y="420" width="210" height="60" as="geometry"/>
</mxCell>
<mxCell id="83" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;" edge="1" parent="1" source="20" target="80">
<mxCell id="83" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;exitX=0.329;exitY=1.013;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitPerimeter=0;" parent="1" source="20" target="80" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="20" value="lausche an public Channel&lt;br&gt;auf&lt;br&gt;&quot;replyNewCommuntiy-Msg&quot;&lt;br&gt;&quot;newCommuntiy-Msg&quot;" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxCell id="20" value="&lt;i&gt;&quot;Lausch-Modus&quot;&lt;/i&gt; an public Channel&lt;br&gt;auf&lt;br&gt;&quot;&lt;b&gt;replyNewCommuntiy-Msg&lt;/b&gt;&quot;&lt;br&gt;&quot;&lt;b&gt;newCommuntiy-Msg&lt;/b&gt;&quot;" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="960" y="511.62999999999994" width="210" height="65" as="geometry"/>
</mxCell>
<mxCell id="25" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#000000;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="22" target="20" edge="1">
<mxCell id="132" style="edgeStyle=none;html=1;entryX=0.75;entryY=0;entryDx=0;entryDy=0;fontSize=10;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="22" target="131">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="910" y="544"/>
<mxPoint x="910" y="544"/>
<mxPoint x="715" y="770"/>
<mxPoint x="728" y="770"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="22" value="speichere empfangene&lt;br&gt;Community-Daten in&lt;br&gt;Community-DB" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="690" y="516.6299999999999" width="210" height="55" as="geometry"/>
</mxCell>
<mxCell id="24" value="Starte Community-Vernetzung &lt;br&gt;als Hintergrundprozess" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;rounded=1;" parent="1" vertex="1">
<mxGeometry x="290" y="622.63" width="180" height="39.5" as="geometry"/>
<mxGeometry x="650" y="664.44" width="130" height="55" as="geometry"/>
</mxCell>
<mxCell id="37" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;fontColor=#000000;strokeColor=#000000;" parent="1" source="34" target="36" edge="1">
<mxGeometry relative="1" as="geometry"/>
@ -146,9 +137,9 @@
</mxGeometry>
</mxCell>
<mxCell id="36" value="neue Mitglieder&lt;br&gt;erfassen?" style="rhombus;whiteSpace=wrap;html=1;fontColor=#ffffff;strokeColor=#2D7600;strokeWidth=2;fillColor=#60a917;rounded=1;" parent="1" vertex="1">
<mxGeometry x="130" y="754.5" width="140" height="80" as="geometry"/>
<mxGeometry x="130" y="710" width="140" height="80" as="geometry"/>
</mxCell>
<mxCell id="38" value="Community-Prozess" style="html=1;align=left;verticalAlign=top;absoluteArcSize=1;arcSize=18;dashed=0;spacingTop=10;spacingRight=30;strokeColor=#82b366;strokeWidth=2;fillColor=#d5e8d4;gradientColor=#97d077;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxCell id="38" value="Community-Prozess" style="html=1;align=left;verticalAlign=top;absoluteArcSize=1;arcSize=18;dashed=0;spacingTop=10;spacingRight=30;strokeColor=#005700;strokeWidth=2;fillColor=#008a00;fontColor=#ffffff;rounded=1;" parent="1" vertex="1">
<mxGeometry x="290" y="834.5" width="260" height="120" as="geometry"/>
</mxCell>
<mxCell id="45" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontColor=#FFFFFF;strokeColor=#000000;" parent="1" source="39" target="43" edge="1">
@ -163,140 +154,238 @@
<mxGeometry x="330" y="874.5" width="200" height="40" as="geometry"/>
</mxCell>
<mxCell id="43" value="" style="ellipse;html=1;shape=endState;fillColor=#000000;strokeColor=#000000;labelBackgroundColor=#97D077;fontColor=#FFFFFF;rounded=1;" parent="1" vertex="1">
<mxGeometry x="185" y="1060" width="30" height="30" as="geometry"/>
<mxGeometry x="185" y="1139" width="30" height="30" as="geometry"/>
</mxCell>
<mxCell id="53" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0.514;entryDx=0;entryDy=0;entryPerimeter=0;strokeColor=#1A1A1A;" edge="1" parent="1" source="50" target="52">
<mxCell id="53" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0.514;entryDx=0;entryDy=0;entryPerimeter=0;strokeColor=#1A1A1A;" parent="1" source="50" target="52" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="50" value="speichere Community-Daten &lt;br&gt;in Community-DB" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;rounded=1;" vertex="1" parent="1">
<mxGeometry x="150" y="503.13" width="200" height="39.5" as="geometry"/>
<mxCell id="50" value="speichere Community-Daten &lt;br&gt;in Community-DB" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;rounded=1;" parent="1" vertex="1">
<mxGeometry x="130" y="503.13" width="200" height="39.5" as="geometry"/>
</mxCell>
<mxCell id="54" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#1A1A1A;exitX=0.374;exitY=0.232;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="52" target="24">
<mxCell id="54" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=#1A1A1A;exitX=1.274;exitY=0.127;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="52" target="75" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="302" y="596"/>
<mxPoint x="380" y="596"/>
<mxPoint x="302" y="645"/>
<mxPoint x="450" y="645"/>
</Array>
<mxPoint x="360" y="645.3800000000001" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="55" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#1A1A1A;exitX=-0.226;exitY=0.784;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="52" target="34">
<mxCell id="55" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#1A1A1A;exitX=1.224;exitY=0.678;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="52" target="34" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points"/>
</mxGeometry>
</mxCell>
<mxCell id="52" value="" style="html=1;points=[];perimeter=orthogonalPerimeter;fillColor=#000000;strokeColor=none;rotation=90;rounded=1;" vertex="1" parent="1">
<mxGeometry x="250" y="480.13" width="5" height="185" as="geometry"/>
<mxCell id="52" value="" style="html=1;points=[];perimeter=orthogonalPerimeter;fillColor=#000000;strokeColor=none;rotation=90;rounded=1;" parent="1" vertex="1">
<mxGeometry x="230" y="483.13" width="5" height="185" as="geometry"/>
</mxCell>
<mxCell id="62" value="newCommunity-Msg" style="html=1;shape=mxgraph.infographic.ribbonSimple;notch1=0;notch2=20;align=center;verticalAlign=middle;fontSize=14;fontStyle=0;fillColor=#d5e8d4;strokeColor=#82b366;fontColor=#000000;rounded=1;rotation=15;" vertex="1" parent="1">
<mxCell id="62" value="newCommunity-Msg" style="html=1;shape=mxgraph.infographic.ribbonSimple;notch1=0;notch2=20;align=center;verticalAlign=middle;fontSize=14;fontStyle=0;fillColor=#d5e8d4;strokeColor=#82b366;fontColor=#000000;rounded=1;rotation=15;" parent="1" vertex="1">
<mxGeometry x="1184.99" y="463.13" width="170" height="20" as="geometry"/>
</mxCell>
<mxCell id="69" value="&lt;font style=&quot;font-size: 12px&quot;&gt;replyNewCommunity-Msg&lt;/font&gt;" style="html=1;shape=mxgraph.infographic.ribbonSimple;notch1=20;notch2=0;align=left;verticalAlign=middle;fontSize=14;fontStyle=0;flipH=1;fillColor=#d5e8d4;strokeColor=#82b366;fontColor=#000000;rounded=1;" vertex="1" parent="1">
<mxCell id="69" value="&lt;font style=&quot;font-size: 12px&quot;&gt;replyNewCommunity-Msg&lt;/font&gt;" style="html=1;shape=mxgraph.infographic.ribbonSimple;notch1=20;notch2=0;align=left;verticalAlign=middle;fontSize=14;fontStyle=0;flipH=1;fillColor=#d5e8d4;strokeColor=#82b366;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="1180.01" y="519.51" width="160" height="20" as="geometry"/>
</mxCell>
<mxCell id="73" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="72" target="5">
<mxCell id="73" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="72" target="5" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points"/>
</mxGeometry>
</mxCell>
<mxCell id="72" value="Fehlermeldung &lt;br&gt;wegen&lt;br&gt;fehlender Parameter" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;strokeColor=#2D7600;fillColor=#B0E3E6;fontColor=#000000;rounded=1;" vertex="1" parent="1">
<mxGeometry x="725" y="314.5" width="120" height="50" as="geometry"/>
<mxCell id="72" value="Fehlermeldung &lt;br&gt;wegen&lt;br&gt;fehlender Parameter" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;strokeColor=#2D7600;fillColor=#B0E3E6;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="695" y="315" width="120" height="50" as="geometry"/>
</mxCell>
<mxCell id="76" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="75" target="13">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="450" y="451"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="75" value="Starte Community-Vernetzung &lt;br&gt;als Hintergrundprozess" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;rounded=1;" vertex="1" parent="1">
<mxGeometry x="360" y="202.63" width="180" height="39.5" as="geometry"/>
</mxCell>
<mxCell id="79" value="&lt;font style=&quot;font-size: 12px&quot;&gt;newCommunity-Msg&lt;/font&gt;" style="html=1;shape=mxgraph.infographic.ribbonSimple;notch1=20;notch2=0;align=left;verticalAlign=middle;fontSize=14;fontStyle=0;flipH=1;fillColor=#d5e8d4;strokeColor=#82b366;fontColor=#000000;rounded=1;rotation=0;" vertex="1" parent="1">
<mxGeometry x="1180.01" y="546.39" width="160" height="20" as="geometry"/>
</mxCell>
<mxCell id="81" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;" edge="1" parent="1" source="80" target="22">
<mxCell id="129" style="edgeStyle=none;html=1;entryX=0.029;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;fontSize=10;" edge="1" parent="1" source="75" target="13">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="82" value="Ja" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=14;fontColor=#000000;labelBackgroundColor=#7EA6E0;" vertex="1" connectable="0" parent="81">
<mxCell id="75" value="Starte &lt;b&gt;&quot;Federation&quot;&lt;/b&gt;&lt;br&gt;als Hintergrundprozess" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#008a00;strokeColor=#005700;fontColor=#ffffff;rounded=1;" parent="1" vertex="1">
<mxGeometry x="360" y="430.25" width="180" height="39.5" as="geometry"/>
</mxCell>
<mxCell id="79" value="&lt;font style=&quot;font-size: 12px&quot;&gt;newCommunity-Msg&lt;/font&gt;" style="html=1;shape=mxgraph.infographic.ribbonSimple;notch1=20;notch2=0;align=left;verticalAlign=middle;fontSize=14;fontStyle=0;flipH=1;fillColor=#d5e8d4;strokeColor=#82b366;fontColor=#000000;rounded=1;rotation=0;" parent="1" vertex="1">
<mxGeometry x="1180.01" y="546.39" width="160" height="20" as="geometry"/>
</mxCell>
<mxCell id="81" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.965;entryY=0.489;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;exitX=0.026;exitY=0.498;exitDx=0;exitDy=0;exitPerimeter=0;entryPerimeter=0;" parent="1" source="80" target="123" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="82" value="Ja" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=10;fontColor=#000000;labelBackgroundColor=#7EA6E0;" parent="81" vertex="1" connectable="0">
<mxGeometry x="-0.4267" y="2" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="85" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;" edge="1" parent="1" source="80" target="84">
<mxCell id="112" value="" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="80" target="84">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="80" value="replyNewCommunityMsg?" style="rhombus;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;align=center;rounded=1;" vertex="1" parent="1">
<mxGeometry x="970" y="588.76" width="190" height="47.87" as="geometry"/>
<mxCell id="80" value="Type&#10;replyNewCommunityMsg?&#10;" style="rhombus;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;align=center;rounded=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="950" y="673.89" width="158" height="36.11" as="geometry"/>
</mxCell>
<mxCell id="93" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;exitX=0.499;exitY=0.966;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="84" target="86">
<mxCell id="111" value="" style="edgeStyle=none;html=1;exitX=0.032;exitY=0.484;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="84" target="110">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="84" value="Type&#10;newCommunityMsg?&#10;" style="rhombus;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;align=center;rounded=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="950" y="740.06" width="158" height="34.87" as="geometry"/>
</mxCell>
<mxCell id="94" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;exitX=0.845;exitY=0.011;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.805;entryY=0.99;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="86" target="20" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1065" y="717.8699999999999" as="sourcePoint"/>
<mxPoint x="1130" y="577" as="targetPoint"/>
<Array as="points"/>
<mxPoint x="1130" y="700.63" as="sourcePoint"/>
</mxGeometry>
</mxCell>
<mxCell id="96" value="Ja" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=14;fontColor=#000000;labelBackgroundColor=#7EA6E0;" vertex="1" connectable="0" parent="93">
<mxGeometry x="-0.2741" y="-1" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
<mxCell id="86" value="Sende &quot;&lt;b&gt;replyNewCommunity-Msg&lt;/b&gt;&quot;&lt;br&gt;mit Msg-State&amp;nbsp;&lt;b&gt;&quot;requestNewKey&quot;&lt;/b&gt;&lt;br&gt;auf public Channel" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="960" y="796.93" width="200" height="50" as="geometry"/>
</mxCell>
<mxCell id="84" value="NewCommunityMsg?" style="rhombus;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;align=center;rounded=1;" vertex="1" parent="1">
<mxGeometry x="970" y="650" width="190" height="47.87" as="geometry"/>
<mxCell id="89" value="replyNewCommunity-Msg" style="html=1;shape=mxgraph.infographic.ribbonSimple;notch1=0;notch2=20;align=left;verticalAlign=middle;fontSize=14;fontStyle=0;fillColor=#d5e8d4;strokeColor=#82b366;fontColor=#000000;rounded=1;rotation=-50;" parent="1" vertex="1">
<mxGeometry x="1144.39" y="723.3" width="242.49" height="20" as="geometry"/>
</mxCell>
<mxCell id="94" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.25;entryY=1;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;" edge="1" parent="1" source="86" target="22">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="86" value="Sende Community-Attribute&lt;br&gt;auf public Channel" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" vertex="1" parent="1">
<mxGeometry x="960" y="730" width="210" height="40" as="geometry"/>
</mxCell>
<mxCell id="89" value="replyNewCommunity-Msg" style="html=1;shape=mxgraph.infographic.ribbonSimple;notch1=0;notch2=20;align=left;verticalAlign=middle;fontSize=14;fontStyle=0;fillColor=#d5e8d4;strokeColor=#82b366;fontColor=#000000;rounded=1;rotation=-45;" vertex="1" parent="1">
<mxGeometry x="1179.98" y="657.38" width="180.01" height="20" as="geometry"/>
</mxCell>
<mxCell id="97" value="" style="group" vertex="1" connectable="0" parent="1">
<mxCell id="97" value="" style="group" parent="1" vertex="1" connectable="0">
<mxGeometry x="1359.9950000000001" y="460.0049999999999" width="232.6199999999999" height="182.6300000000001" as="geometry"/>
</mxCell>
<mxCell id="65" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;rotation=-90;strokeColor=#36393d;fillColor=#66B2FF;rounded=1;" vertex="1" parent="97">
<mxCell id="65" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;rotation=-90;strokeColor=#36393d;fillColor=#66B2FF;rounded=1;" parent="97" vertex="1">
<mxGeometry x="24.99499999999989" y="-24.99499999999989" width="182.63" height="232.62" as="geometry"/>
</mxCell>
<mxCell id="66" value="public Channel" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;fontColor=#000000;fontSize=14;rounded=1;" vertex="1" parent="97">
<mxCell id="66" value="public Channel" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;fontColor=#000000;fontSize=14;rounded=1;" parent="97" vertex="1">
<mxGeometry x="96.30500000000006" y="74.99500000000012" width="40" height="20" as="geometry"/>
</mxCell>
<mxCell id="98" value="Prozess: Community-Connection" style="html=1;align=left;verticalAlign=top;absoluteArcSize=1;arcSize=18;dashed=0;spacingTop=10;spacingRight=30;strokeColor=#6c8ebf;strokeWidth=2;fillColor=#dae8fc;gradientColor=#7ea6e0;fontColor=#000000;rounded=1;" vertex="1" parent="1">
<mxGeometry x="610" y="834.5" width="640" height="185.5" as="geometry"/>
<mxCell id="98" value="Hintergrund-Prozess: &lt;b&gt;Community-Communication&lt;/b&gt;" style="html=1;align=left;verticalAlign=top;absoluteArcSize=1;arcSize=18;dashed=0;spacingTop=10;spacingRight=30;strokeColor=#6c8ebf;strokeWidth=2;fillColor=#dae8fc;gradientColor=#7ea6e0;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="610" y="920" width="640" height="185.5" as="geometry"/>
</mxCell>
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;fillColor=#ffffff;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="99" target="105">
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;fillColor=#ffffff;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="137" target="105" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="99" value="stelle P2P-Verbindung zu &lt;br&gt;neuer Community her&lt;br&gt;und tausche detailiete Daten aus" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" vertex="1" parent="1">
<mxGeometry x="974.99" y="881" width="210" height="67" as="geometry"/>
</mxCell>
<mxCell id="102" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;" edge="1" parent="1" source="100" target="99">
<mxCell id="139" value="" style="edgeStyle=none;html=1;fontSize=10;" edge="1" parent="1" source="99" target="137">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="100" value="Daten einer neuen&#10;Community erhalten?" style="rhombus;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;align=center;rounded=1;" vertex="1" parent="1">
<mxGeometry x="637" y="874.5" width="190" height="80" as="geometry"/>
<mxCell id="99" value="authentifiziere und autorisiere&lt;br&gt;Direkt-Verbindung per&amp;nbsp;&lt;br&gt;OpenID Connect" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="975" y="957.25" width="205.01" height="60" as="geometry"/>
</mxCell>
<mxCell id="101" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="22" target="100">
<mxCell id="101" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="131" target="134" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="670" y="544"/>
<mxPoint x="670" y="790"/>
<mxPoint x="732" y="790"/>
<mxPoint x="695" y="988"/>
</Array>
<mxPoint x="732" y="960" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="103" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;fillColor=#ffffff;" parent="1" edge="1">
<mxGeometry width="100" height="100" relative="1" as="geometry">
<mxPoint x="1190.64" y="987" as="sourcePoint"/>
<mxPoint x="1340.64" y="987" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="104" value="neue Community" style="rounded=1;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=14;fontColor=#000000;fillColor=#B0E3E6;align=center;gradientColor=#97D077;" parent="1" vertex="1">
<mxGeometry x="1356.3" y="907.25" width="240.01" height="212.75" as="geometry"/>
</mxCell>
<mxCell id="136" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontSize=10;" edge="1" parent="1" source="105" target="43">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="200" y="1068"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="103" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;fillColor=#ffffff;" edge="1" parent="1">
<mxGeometry width="100" height="100" relative="1" as="geometry">
<mxPoint x="1190.01" y="914" as="sourcePoint"/>
<mxPoint x="1340.01" y="914" as="targetPoint"/>
</mxGeometry>
<mxCell id="105" value="speichere empfangene&lt;br&gt;Community-Daten in&lt;br&gt;Community-DB" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" parent="1" vertex="1">
<mxGeometry x="730" y="1040" width="180" height="55" as="geometry"/>
</mxCell>
<mxCell id="104" value="neue Community" style="rounded=1;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=14;fontColor=#000000;fillColor=#B0E3E6;align=center;gradientColor=#97D077;" vertex="1" parent="1">
<mxGeometry x="1359.99" y="840" width="240.01" height="160" as="geometry"/>
</mxCell>
<mxCell id="107" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;fillColor=#ffffff;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="105" target="100">
<mxCell id="114" value="" style="edgeStyle=none;html=1;fontSize=10;exitX=0.963;exitY=0.51;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="109" target="86">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="105" value="speichere empfangene&lt;br&gt;Community-Daten in&lt;br&gt;Community-DB" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" vertex="1" parent="1">
<mxGeometry x="810" y="954.5" width="150" height="55" as="geometry"/>
<mxCell id="115" value="Ja" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=10;labelBackgroundColor=#7EA6E0;" vertex="1" connectable="0" parent="114">
<mxGeometry x="0.3135" relative="1" as="geometry">
<mxPoint x="-7" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="109" value="Community-Eintrag&#10;gefunden?" style="rhombus;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;align=center;rounded=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="750" y="798" width="150" height="47.87" as="geometry"/>
</mxCell>
<mxCell id="113" value="" style="edgeStyle=none;html=1;fontSize=10;" edge="1" parent="1" source="110" target="109">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="110" value="suche in Community-DB&lt;br style=&quot;font-size: 10px&quot;&gt;nach empfangenem&lt;br style=&quot;font-size: 10px&quot;&gt;Community-Key aber mit&lt;br&gt;unterschiedlicher URL" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="750" y="730" width="150" height="55" as="geometry"/>
</mxCell>
<mxCell id="116" value="Sende &quot;&lt;b&gt;replyNewCommunity-Msg&lt;/b&gt;&quot;&lt;br&gt;mit Msg-State&amp;nbsp;&lt;b&gt;&quot;OK&quot;&lt;/b&gt;&amp;nbsp;und eigenem Community-Key&lt;br&gt;und URL auf public Channel" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="960" y="855" width="230" height="50" as="geometry"/>
</mxCell>
<mxCell id="117" value="" style="edgeStyle=none;html=1;fontSize=10;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="109" target="116">
<mxGeometry relative="1" as="geometry">
<mxPoint x="894.45" y="785.4837000000002" as="sourcePoint"/>
<Array as="points">
<mxPoint x="825" y="880"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="118" value="Nein" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=10;labelBackgroundColor=#7EA6E0;" vertex="1" connectable="0" parent="117">
<mxGeometry x="0.3135" relative="1" as="geometry">
<mxPoint x="-7" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="122" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;entryX=0.908;entryY=0.998;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.909;exitY=-0.02;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="116" target="20">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1140" y="586.63" as="targetPoint"/>
<Array as="points">
<mxPoint x="1169" y="780"/>
<mxPoint x="1151" y="780"/>
</Array>
<mxPoint x="1140" y="710.6300000000001" as="sourcePoint"/>
</mxGeometry>
</mxCell>
<mxCell id="124" style="edgeStyle=none;html=1;fontSize=10;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="123" target="22">
<mxGeometry relative="1" as="geometry">
<mxPoint x="758" y="660" as="targetPoint"/>
<Array as="points">
<mxPoint x="780" y="692"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="125" value="Ja" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=10;labelBackgroundColor=#7EA6E0;" vertex="1" connectable="0" parent="124">
<mxGeometry x="-0.6276" y="1" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="127" value="" style="edgeStyle=none;html=1;fontSize=10;" edge="1" parent="1" source="123" target="126">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="130" value="Nein" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=10;labelBackgroundColor=#7EA6E0;" vertex="1" connectable="0" parent="127">
<mxGeometry x="-0.4527" relative="1" as="geometry">
<mxPoint x="1" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="123" value="Msg-State OK?" style="rhombus;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;align=center;rounded=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="820" y="673.89" width="108" height="36.11" as="geometry"/>
</mxCell>
<mxCell id="128" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=10;" edge="1" parent="1" source="126" target="16">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="874" y="450"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="126" value="erzeuge und speichere&lt;br&gt;neuen Community-Key in&lt;br&gt;Community-DB" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" vertex="1" parent="1">
<mxGeometry x="803.5" y="576.63" width="141" height="55" as="geometry"/>
</mxCell>
<mxCell id="133" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=10;" edge="1" parent="1" source="131" target="20">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="695" y="780"/>
<mxPoint x="630" y="780"/>
<mxPoint x="630" y="544"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="131" value="trigger &lt;br&gt;Hintergrundprozess&lt;br style=&quot;font-size: 10px&quot;&gt;&lt;i&gt;Community-Communication&lt;/i&gt;&lt;br&gt;für neue Community" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="630" y="834.5" width="130" height="55" as="geometry"/>
</mxCell>
<mxCell id="135" value="" style="edgeStyle=none;html=1;fontSize=10;" edge="1" parent="1" source="134" target="99">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="134" value="lese eigene Daten aus Datenbank&lt;br&gt;und bereite diese für den&amp;nbsp;&lt;br&gt;Community-Handshake auf" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" vertex="1" parent="1">
<mxGeometry x="724" y="959.5" width="186" height="55.5" as="geometry"/>
</mxCell>
<mxCell id="137" value="tausche detaillierte Daten&lt;br&gt;über public API-Calls aus" style="html=1;align=center;verticalAlign=top;absoluteArcSize=1;arcSize=10;dashed=0;fillColor=#b0e3e6;strokeColor=#0e8088;fontColor=#000000;rounded=1;" vertex="1" parent="1">
<mxGeometry x="975" y="1037" width="205.01" height="60" as="geometry"/>
</mxCell>
<mxCell id="140" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;fontSize=14;fontColor=#000000;strokeColor=#1A1A1A;fillColor=#ffffff;" edge="1" parent="1">
<mxGeometry width="100" height="100" relative="1" as="geometry">
<mxPoint x="1194.9900000000002" y="1066.5" as="sourcePoint"/>
<mxPoint x="1344.9900000000002" y="1066.5" as="targetPoint"/>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>

View File

@ -0,0 +1,286 @@
<mxfile host="65bd71144e">
<diagram id="ymh7Jh5NIHEcxBqobDAe" name="Seite-1">
<mxGraphModel dx="1088" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="2336" pageHeight="1654" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="30" value="" style="endArrow=none;html=1;fontSize=20;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="260" y="1480" as="sourcePoint"/>
<mxPoint x="260" y="540" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="64" value="" style="endArrow=none;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" target="63" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1300" y="1480" as="sourcePoint"/>
<mxPoint x="1299.5" y="200" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="62" value="" style="endArrow=none;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" target="61" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1160" y="1190" as="sourcePoint"/>
<mxPoint x="890" y="380" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="2" value="invocation chain to authenticate a new community and to open a community communication in the community network" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=20;" parent="1" vertex="1">
<mxGeometry x="40" y="10" width="1320" height="30" as="geometry"/>
</mxCell>
<mxCell id="3" value="new&lt;br&gt;Community A" style="rounded=1;whiteSpace=wrap;html=1;fontSize=20;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="200" y="80" width="120" height="80" as="geometry"/>
</mxCell>
<mxCell id="4" value="existing Community B" style="rounded=1;whiteSpace=wrap;html=1;fontSize=20;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="960" y="80" width="400" height="80" as="geometry"/>
</mxCell>
<mxCell id="5" value="" style="endArrow=none;html=1;fontSize=20;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;" parent="1" target="3" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="260" y="541" as="sourcePoint"/>
<mxPoint x="730" y="460" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="6" value="" style="endArrow=none;html=1;fontSize=20;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;" parent="1" source="8" target="60" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1019.5" y="1622" as="sourcePoint"/>
<mxPoint x="1019.5" y="200" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="7" value="encrypt community-key&amp;nbsp; of community-B with own private key" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="210" y="220" width="100" height="60" as="geometry"/>
</mxCell>
<mxCell id="9" value="" style="endArrow=classic;startArrow=none;html=1;fontSize=12;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;startFill=0;" parent="1" source="7" target="8" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="310" y="300" as="sourcePoint"/>
<mxPoint x="730" y="450" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="10" value="request with own community key and encrypted community key of community-B as InputData" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;" parent="9" vertex="1" connectable="0">
<mxGeometry x="0.1697" y="-1" relative="1" as="geometry">
<mxPoint x="-46" y="-1" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="12" value="" style="endArrow=classic;html=1;fontSize=12;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=1;exitY=1;exitDx=0;exitDy=0;" parent="1" source="13" target="11" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="260" y="1243" as="sourcePoint"/>
<mxPoint x="730" y="1353" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="14" value="request with JWT-Token and CommunityTO as InputData" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;" parent="12" vertex="1" connectable="0">
<mxGeometry x="0.1296" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="16" value="" style="endArrow=classic;html=1;fontSize=12;exitX=0;exitY=1;exitDx=0;exitDy=0;" parent="1" source="11" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="680" y="1393" as="sourcePoint"/>
<mxPoint x="260" y="1293" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="17" value="response with CommunityTO as OutputData" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;" parent="16" vertex="1" connectable="0">
<mxGeometry x="0.0958" y="1" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="18" value="Service: &lt;br&gt;&lt;b&gt;request&lt;br&gt;TradingLevel&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1250" y="1363" width="100" height="50" as="geometry"/>
</mxCell>
<mxCell id="20" value="" style="endArrow=classic;html=1;fontSize=12;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=1;exitY=1;exitDx=0;exitDy=0;" parent="1" target="18" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="310" y="1363" as="sourcePoint"/>
<mxPoint x="970" y="1363" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="21" value="request with JWT-Token and TradingLevelTO-InputData" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;" parent="20" vertex="1" connectable="0">
<mxGeometry x="0.1296" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="8" value="Service:&lt;br&gt;&lt;b&gt;authenticate&lt;br&gt;Community&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="970" y="280" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="26" value="" style="endArrow=none;html=1;fontSize=20;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;" parent="1" target="8" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1020" y="1190" as="sourcePoint"/>
<mxPoint x="1019.5" y="220" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="27" value="if given community key of community-A&lt;br&gt;is known" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="970" y="320" width="100" height="60" as="geometry"/>
</mxCell>
<mxCell id="28" value="generate and keep&lt;br&gt;one-time code together with given encrypted community key&amp;nbsp;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="970" y="380" width="100" height="90" as="geometry"/>
</mxCell>
<mxCell id="31" value="" style="endArrow=classic;html=1;fontSize=12;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0;entryDx=0;entryDy=0;" parent="1" source="28" target="38" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="970" y="521" as="sourcePoint"/>
<mxPoint x="310" y="490" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="32" value="redirect back to Community-A with one-time code" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;" parent="31" vertex="1" connectable="0">
<mxGeometry x="0.0958" y="1" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="33" value="" style="endArrow=classic;html=1;fontSize=12;exitX=0;exitY=1;exitDx=0;exitDy=0;" parent="1" source="8" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="960" y="320" as="sourcePoint"/>
<mxPoint x="260" y="320" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="36" value="" style="endArrow=classic;html=1;fontSize=12;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=1;exitY=1;exitDx=0;exitDy=0;" parent="1" source="38" target="35" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="310" y="601" as="sourcePoint"/>
<mxPoint x="730" y="691" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="37" value="request with one-time code, own public key as InputData" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;" parent="36" vertex="1" connectable="0">
<mxGeometry x="0.1296" relative="1" as="geometry">
<mxPoint x="-93" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="38" value="Endpoint:&lt;br&gt;&lt;b&gt;redirect URI&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="210" y="470" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="11" value="Service: &lt;b&gt;familiarize&lt;br&gt;Community&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1250" y="1243" width="100" height="50" as="geometry"/>
</mxCell>
<mxCell id="13" value="initialize CommunityTO" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="210" y="1203" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="15" value="define and offer&lt;br&gt;own TradingLevel Idea" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="210" y="1320" width="100" height="43" as="geometry"/>
</mxCell>
<mxCell id="39" value="" style="endArrow=classic;html=1;fontSize=12;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0;entryDx=0;entryDy=0;" parent="1" source="47" target="46" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="960" y="861" as="sourcePoint"/>
<mxPoint x="260" y="831" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="40" value="response with public key of Community-B as OutputData" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;" parent="39" vertex="1" connectable="0">
<mxGeometry x="0.0958" y="1" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="42" value="decrypt&amp;nbsp; previous received and kept community-key with given &lt;br&gt;public key" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1110" y="600" width="100" height="70" as="geometry"/>
</mxCell>
<mxCell id="43" value="" style="endArrow=none;html=1;fontSize=20;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;" parent="1" source="44" target="42" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1160" y="1061" as="sourcePoint"/>
<mxPoint x="1160" y="391" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="44" value="&lt;span&gt;if decrypted key matches own community key&lt;/span&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1110" y="670" width="100" height="50" as="geometry"/>
</mxCell>
<mxCell id="46" value="&lt;span&gt;store public key of Community-B&lt;/span&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="210" y="760" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="47" value="store public key of community-A" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1110" y="720" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="35" value="Endpoint:&amp;nbsp;&lt;br&gt;&lt;b&gt;verify&lt;br&gt;OneTimeCode&lt;br&gt;&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1110" y="510" width="100" height="50" as="geometry"/>
</mxCell>
<mxCell id="48" value="" style="endArrow=none;html=1;fontSize=20;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;" parent="1" source="42" target="35" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1160" y="640" as="sourcePoint"/>
<mxPoint x="1160" y="320" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="41" value="check one-time code" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1110" y="560" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="49" value="&lt;span&gt;encrypt community-key&amp;nbsp; of community-B with own private key&lt;/span&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="210" y="830" width="100" height="60" as="geometry"/>
</mxCell>
<mxCell id="50" value="" style="endArrow=classic;startArrow=none;html=1;fontSize=12;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;startFill=0;" parent="1" target="52" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="310" y="890" as="sourcePoint"/>
<mxPoint x="970" y="890" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="51" value="request with own community key and encrypted community key of community-B as InputData" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;" parent="50" vertex="1" connectable="0">
<mxGeometry x="0.1697" y="-1" relative="1" as="geometry">
<mxPoint x="-46" y="-1" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="52" value="Service: &lt;br&gt;&lt;b&gt;open Communication&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1110" y="887" width="100" height="50" as="geometry"/>
</mxCell>
<mxCell id="53" value="" style="endArrow=none;html=1;fontSize=20;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;" parent="1" source="18" target="11" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1300" y="1213" as="sourcePoint"/>
<mxPoint x="1300" y="1072" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="54" value="" style="endArrow=none;dashed=1;html=1;strokeWidth=2;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="40" y="810" as="sourcePoint"/>
<mxPoint x="1370" y="810" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="55" value="" style="endArrow=classic;html=1;fontSize=12;exitX=0;exitY=1;exitDx=0;exitDy=0;" parent="1" source="59" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1110" y="1200" as="sourcePoint"/>
<mxPoint x="260" y="1167" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="56" value="response with JWT-Token as OutputData" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;" parent="55" vertex="1" connectable="0">
<mxGeometry x="0.0958" y="1" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="57" value="search with community key the entry of community-A" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1110" y="937" width="100" height="70" as="geometry"/>
</mxCell>
<mxCell id="58" value="decrypt with public key of community-A the given encrypted community-key" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1110" y="1007" width="100" height="70" as="geometry"/>
</mxCell>
<mxCell id="59" value="&lt;span&gt;if decrypted key matches own community key generate JWT-Token&lt;/span&gt;" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1110" y="1077" width="100" height="90" as="geometry"/>
</mxCell>
<mxCell id="60" value="Key-Provider" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="960" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="61" value="Token-Provider" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1100" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="63" value="Community-Endpoint" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1240" y="120" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="65" value="" style="endArrow=none;dashed=1;html=1;strokeWidth=2;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="40.000000000000455" y="210.00000000000045" as="sourcePoint"/>
<mxPoint x="1370" y="210.00000000000045" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="66" value="&lt;font style=&quot;font-size: 16px&quot;&gt;1. Sequence:&lt;br&gt;singular processing after community creation&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=20;" parent="1" vertex="1">
<mxGeometry x="40" y="210" width="140" height="120" as="geometry"/>
</mxCell>
<mxCell id="67" value="&lt;font style=&quot;font-size: 16px&quot;&gt;2. Sequence:&lt;br&gt;recurrent processing to open community communication session&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=20;" parent="1" vertex="1">
<mxGeometry x="40" y="810" width="140" height="150" as="geometry"/>
</mxCell>
<mxCell id="68" value="" style="endArrow=none;dashed=1;html=1;strokeWidth=2;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="40" y="1190" as="sourcePoint"/>
<mxPoint x="1370" y="1190" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="69" value="&lt;font style=&quot;font-size: 16px&quot;&gt;3. Sequence:&lt;br&gt;community communication session&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontStyle=1;fontSize=20;" parent="1" vertex="1">
<mxGeometry x="40" y="1190" width="140" height="100" as="geometry"/>
</mxCell>
<mxCell id="70" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=4;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="261" y="1580" as="sourcePoint"/>
<mxPoint x="261" y="1480" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="71" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=4;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1299.5" y="1580" as="sourcePoint"/>
<mxPoint x="1299.5" y="1480" as="targetPoint"/>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@ -0,0 +1,253 @@
<mxfile host="65bd71144e">
<diagram id="sY0-nLNpXMrYDOU7Baq7" name="Seite-1">
<mxGraphModel dx="907" dy="667" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1654" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="104" value="&lt;font style=&quot;font-size: 20px&quot;&gt;&lt;b&gt;DARION privat&lt;/b&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;verticalAlign=top;fillColor=#fa6800;strokeColor=#C73500;fontColor=#000000;" vertex="1" parent="1">
<mxGeometry x="880" y="721" width="560" height="1079" as="geometry"/>
</mxCell>
<mxCell id="103" value="&lt;font style=&quot;font-size: 20px&quot;&gt;&lt;b&gt;INTEGRATION&lt;/b&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;verticalAlign=top;fillColor=#e3c800;strokeColor=#B09500;fontColor=#000000;" vertex="1" parent="1">
<mxGeometry x="880" y="40" width="560" height="560" as="geometry"/>
</mxCell>
<mxCell id="101" value="&lt;font style=&quot;font-size: 20px&quot;&gt;&lt;b&gt;PRODUKTION&lt;/b&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#a0522d;strokeColor=#6D1F00;fontColor=#ffffff;align=center;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="80" y="40" width="640" height="1760" as="geometry"/>
</mxCell>
<mxCell id="2" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;STRATO: Managed Server XXLX-8&lt;/b&gt;&lt;b style=&quot;text-align: left&quot;&gt;&amp;nbsp;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" parent="1" vertex="1">
<mxGeometry x="170" y="120" width="470" height="241" as="geometry"/>
</mxCell>
<mxCell id="3" value="&lt;ul style=&quot;font-family: &amp;quot;liberation serif&amp;quot; , serif&quot;&gt;&lt;li style=&quot;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;AMD Opteron(tm) Processor 4180 (6 x 2,6 GHz)&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 16GB&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;806 GB HDD&lt;/li&gt;&lt;li style=&quot;&quot;&gt;&lt;b&gt;OS:&lt;/b&gt;&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;align=left;" parent="1" vertex="1">
<mxGeometry x="235" y="151" width="340" height="110" as="geometry"/>
</mxCell>
<mxCell id="4" value="&lt;span style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;gradido.net: &lt;/b&gt;&lt;br&gt;gradido Hauptseite,&lt;br&gt;wordpress&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;" parent="1" vertex="1">
<mxGeometry x="190" y="271" width="150" height="80" as="geometry"/>
</mxCell>
<mxCell id="5" value="&lt;font face=&quot;liberation serif, serif&quot;&gt;&lt;span style=&quot;font-size: 16px&quot;&gt;21 weitere Domains&lt;/span&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;" parent="1" vertex="1">
<mxGeometry x="350" y="271" width="140" height="50" as="geometry"/>
</mxCell>
<mxCell id="6" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;STRATO:&amp;nbsp;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;Root Server Linux C4-47: Staging&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" parent="1" vertex="1">
<mxGeometry x="925" y="120" width="470" height="401" as="geometry"/>
</mxCell>
<mxCell id="7" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;AMD Opteron™ 1385 (4 x 2,7 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;:&amp;nbsp;&lt;/span&gt;4 GB DDR 2 / 8 GB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;2 x 500 GB HDD (Raid 1)&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 20.04 LTS 64bit&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt; 85.214.157.229:1618&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" parent="1" vertex="1">
<mxGeometry x="990" y="151" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="8" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;nginx 1.18.0 (Ubuntu)&lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="945" y="271" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="9" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;php-fpm7.4&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1072" y="271" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="10" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br style=&quot;font-size: 12px;&quot;&gt;Distrib 10.3.31-MariaDB&lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1165" y="319.75" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="11" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;ufw 0.36&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1141" y="271" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="12" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;node v12.19.0&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1215" y="271" width="80" height="30" as="geometry"/>
</mxCell>
<mxCell id="13" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;Gradido Backend &lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 4000&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="945" y="319.75" width="90" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="14" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;Gradido Login Server &lt;br style=&quot;font-size: 12px;&quot;&gt;HTTP Port: 1200&lt;br style=&quot;font-size: 12px;&quot;&gt;JSON: 1201&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1042" y="319.75" width="110" height="51" as="geometry"/>
</mxCell>
<mxCell id="15" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;gdt.gradido.net:&lt;/b&gt; GDT-Server for testing&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="945" y="381" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="16" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;stage1.gradido.net:&lt;/b&gt; Auto-Deployed Gradido Setup on master branch&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="945" y="431" width="120" height="70" as="geometry"/>
</mxCell>
<mxCell id="17" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;stagelive.gradido.net:&lt;/b&gt; Test with Live Data (dbs deleted&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="1075" y="431" width="110" height="70" as="geometry"/>
</mxCell>
<mxCell id="18" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;staging.gradido.net:&lt;/b&gt;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="1075" y="381" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="19" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Login via ssh key or password&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;align=left;fontSize=12;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="1245" y="411" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="20" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;align=left;fontSize=12;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="1245" y="461" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="21" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;STRATO:&amp;nbsp;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;Root Server Linux C4-40: Support&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="170" y="401" width="470" height="440" as="geometry"/>
</mxCell>
<mxCell id="22" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;AMD Opteron™ 1389 (4 x 2,9 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 8&lt;/span&gt;&amp;nbsp;GB DDR 2 / 8 GB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;2 x 1 TB HDD (Raid 1)&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04 LTS 64bit&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;85.214.26.213: 11771&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="235" y="432" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="23" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="190" y="552" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="24" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="317" y="552" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="25" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br style=&quot;font-size: 12px&quot;&gt;Distrib 10.1.44-MariaDB&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="460" y="552" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="26" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;ufw 0.36&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="386" y="552" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="28" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Elasticsearch version 7.8.0, Port 9200&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="190" y="611" width="90" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="29" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Zammad (install: Puma 3.12.6, Port 3000, Postgresql, Port 5432, redis, Port 6379)&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="287" y="611" width="163" height="50.25" as="geometry"/>
</mxCell>
<mxCell id="30" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;kanban.gradido.net:&lt;/b&gt; Wekan Kanban Board, anfangs für Sprintplanung genutzt&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="190" y="681" width="130" height="70" as="geometry"/>
</mxCell>
<mxCell id="31" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;support.gradido.net: &lt;/b&gt;Zammad&lt;br&gt;Support-Tool, lief nicht mit 4 GB Arbeitsspeicher&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="330" y="731" width="110" height="80" as="geometry"/>
</mxCell>
<mxCell id="33" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;wolke.gradido.net:&lt;/b&gt;&lt;br&gt;Nextcloud&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="330" y="681" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="34" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Login via password&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="490" y="691" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="35" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="490" y="742" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="36" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;no ssh&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;align=left;fontSize=12;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="510" y="271" width="90" height="40" as="geometry"/>
</mxCell>
<mxCell id="37" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;loolwsd (part of nextlcoud for edit documents in Browser) Port: 9982 + 9983&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="460" y="611.25" width="150" height="50" as="geometry"/>
</mxCell>
<mxCell id="38" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;STRATO:&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;VPS Linux V5-49: git + gdt&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="170" y="881" width="470" height="400" as="geometry"/>
</mxCell>
<mxCell id="39" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;GB HDD&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04 LTS 64bit&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;85.214.134.190: 19152&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="235" y="912" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="40" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="190" y="1032" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="41" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="317" y="1032" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="42" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br style=&quot;font-size: 12px&quot;&gt;Distrib 10.4.12-MariaDB&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="290" y="1099.75" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="43" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;ufw 0.36&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="386" y="1032" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="44" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;MongoDB version v3.6.3, Port: 27017&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="190" y="1099.75" width="90" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="45" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;OpenSSL 1.1.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="457" y="1032" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="46" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;gdt.gradido.com: &lt;/b&gt;&lt;br&gt;Main Production GDT-Server&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="190" y="1161" width="130" height="70" as="geometry"/>
</mxCell>
<mxCell id="49" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;admin login only via password&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="370" y="1170" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="50" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="490" y="1170" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="52" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;git main repository before we used github&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="433.5" y="1099.75" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="53" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;git login also via ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="370" y="1220" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="54" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 10px&quot;&gt;10 Tage Backup&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="490" y="1220" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="55" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;1fire:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: Main Production Server&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="170" y="1321" width="470" height="400" as="geometry"/>
</mxCell>
<mxCell id="56" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;25 GB&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;212.83.56.124: 17611&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="235" y="1352" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="57" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="190" y="1472" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="58" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="317" y="1472" width="93" height="29" as="geometry"/>
</mxCell>
<mxCell id="60" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;ufw 0.35&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="446" y="1472" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="61" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br&gt;Distrib 10.1.43-MariaDB, &lt;br&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="190" y="1543.25" width="130" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="62" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;node v12.13.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="517" y="1472" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="63" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;gdd1.gradido.com: &lt;/b&gt;Gradido Main Server&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="190" y="1601" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="64" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via password or ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="370" y="1610" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="65" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="490" y="1610" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="68" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;db backups&amp;nbsp;gelegentlich manuell, &lt;br&gt;download in verschlüsseltes TrueCrypt Volume auf&amp;nbsp;Arbeits-Laptop&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="370" y="1660" width="230" height="51" as="geometry"/>
</mxCell>
<mxCell id="69" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Gradido Backend &lt;br&gt;Apollo&lt;br&gt;Port: 4000&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="330" y="1543.25" width="100" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="70" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Gradido Login Server HTTP Port: 1200, json: 1201&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="440" y="1543.25" width="110" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="71" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;DARIO privat:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;RockPi 4&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="920" y="800" width="470" height="280" as="geometry"/>
</mxCell>
<mxCell id="72" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;Rockchip RK3399 (2x ARM A72&lt;br/&gt;1.8 GHz, 4x ARM A53 1.4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;:&amp;nbsp;&lt;/span&gt;4 GB Ram / 8 GB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;MicroSD + NVME SSD&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="985" y="831" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="79" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;privater Hauptwebserver, &lt;br&gt;auch zum Testen von Gradido (GDT + Community-Server)&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="950" y="954.5" width="300" height="40" as="geometry"/>
</mxCell>
<mxCell id="81" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;GDT Production Backup Server&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="950" y="1004.5" width="300" height="41" as="geometry"/>
</mxCell>
<mxCell id="84" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;DARIO privat:&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;J4125B-ITX&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="920" y="1120" width="470" height="280" as="geometry"/>
</mxCell>
<mxCell id="85" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;Intel® Celeron® Prozessor&lt;br/&gt;J4125 4x 2,7 GHz&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;:&amp;nbsp;&lt;/span&gt;32 GB Ram DDR4 / 64 GB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;SSD&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.5 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="985" y="1151" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="86" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;u.a. um den Login-Server für den Production-Server zu kompilieren,&amp;nbsp;&lt;br&gt;weil hier das gleiche Betriebssystem läuft wie auf dem Production Server&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="950" y="1274.5" width="420" height="40" as="geometry"/>
</mxCell>
<mxCell id="87" value="&lt;p class=&quot;Textbody&quot;&gt;Login nur im Lokalen Netzwerk über Passwort&lt;/p&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="950" y="1324.5" width="280" height="41" as="geometry"/>
</mxCell>
<mxCell id="88" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;1fire:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: DARIO privat&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="920" y="1444.5" width="470" height="320" as="geometry"/>
</mxCell>
<mxCell id="89" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / 500 MB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.6 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;62.113.241.71&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="985" y="1475.5" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="95" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;gradido.com:&lt;/b&gt;&lt;br&gt;Sprachabhängiger Link zur Elopage Registrierung, gibt publisher-id weiter wenn angegeben, z.B. &lt;a href=&quot;https://gradido.com/173817&quot;&gt;&lt;span&gt;https://gradido.com/173817&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="940" y="1594.5" width="250" height="70" as="geometry"/>
</mxCell>
<mxCell id="96" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="1240" y="1594.5" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="97" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="1240" y="1639" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="98" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;arbeitet für mich als dns-server um meine Domains auf meinen Anschluss (wechselnde IP) zu routen&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="1120" y="1690" width="230" height="51" as="geometry"/>
</mxCell>
<mxCell id="106" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;CommunityServer&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="317" y="1501" width="93" height="29" as="geometry"/>
</mxCell>
<mxCell id="107" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;GDT-Server&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="1302" y="319.75" width="80" height="50.25" as="geometry"/>
</mxCell>
<mxCell id="108" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;GDT-Server&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="317" y="1062" width="63" height="29" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@ -0,0 +1,754 @@
<mxfile host="65bd71144e">
<diagram id="sY0-nLNpXMrYDOU7Baq7" name="Seite-1">
<mxGraphModel dx="1445" dy="941" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1654" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="104" value="&lt;font style=&quot;font-size: 24px;&quot;&gt;&lt;b style=&quot;font-size: 24px;&quot;&gt;DARION privat&lt;/b&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;verticalAlign=top;fillColor=#fa6800;strokeColor=#C73500;fontColor=#000000;fontSize=24;" parent="1" vertex="1">
<mxGeometry x="2990" y="1361" width="560" height="1079" as="geometry"/>
</mxCell>
<mxCell id="103" value="&lt;font style=&quot;font-size: 24px;&quot;&gt;&lt;b style=&quot;font-size: 24px;&quot;&gt;INTEGRAION&lt;/b&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;verticalAlign=top;fillColor=#e3c800;strokeColor=#B09500;fontColor=#000000;fontSize=24;" parent="1" vertex="1">
<mxGeometry x="1600" y="40" width="1200" height="1240" as="geometry"/>
</mxCell>
<mxCell id="101" value="&lt;font style=&quot;font-size: 24px;&quot;&gt;&lt;b style=&quot;font-size: 24px;&quot;&gt;PRODUKTION&lt;/b&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#a0522d;strokeColor=#6D1F00;fontColor=#ffffff;align=center;verticalAlign=top;fontSize=24;" parent="1" vertex="1">
<mxGeometry x="80" y="40" width="1360" height="2520" as="geometry"/>
</mxCell>
<mxCell id="2" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;STRATO: Managed Server XXLX-8&lt;/b&gt;&lt;b style=&quot;text-align: left&quot;&gt;&amp;nbsp;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" parent="1" vertex="1">
<mxGeometry x="530" y="1354" width="470" height="241" as="geometry"/>
</mxCell>
<mxCell id="3" value="&lt;ul style=&quot;font-family: &amp;quot;liberation serif&amp;quot; , serif&quot;&gt;&lt;li style=&quot;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;AMD Opteron(tm) Processor 4180 (6 x 2,6 GHz)&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 16GB&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;806 GB HDD&lt;/li&gt;&lt;li style=&quot;&quot;&gt;&lt;b&gt;OS:&lt;/b&gt;&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;align=left;" parent="1" vertex="1">
<mxGeometry x="595" y="1385" width="340" height="110" as="geometry"/>
</mxCell>
<mxCell id="4" value="&lt;span style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;gradido.net: &lt;/b&gt;&lt;br&gt;gradido Hauptseite,&lt;br&gt;wordpress&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;" parent="1" vertex="1">
<mxGeometry x="550" y="1505" width="150" height="80" as="geometry"/>
</mxCell>
<mxCell id="5" value="&lt;font face=&quot;liberation serif, serif&quot;&gt;&lt;span style=&quot;font-size: 16px&quot;&gt;21 weitere Domains&lt;/span&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;" parent="1" vertex="1">
<mxGeometry x="710" y="1505" width="140" height="50" as="geometry"/>
</mxCell>
<mxCell id="218" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="208">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="6" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;STRATO:&amp;nbsp;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;Root Server Linux C4-47: Staging&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" parent="1" vertex="1">
<mxGeometry x="1654" y="436.5" width="470" height="401" as="geometry"/>
</mxCell>
<mxCell id="7" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;AMD Opteron™ 1385 (4 x 2,7 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;:&amp;nbsp;&lt;/span&gt;4 GB DDR 2 / 8 GB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;2 x 500 GB HDD (Raid 1)&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 20.04 LTS 64bit&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt; 85.214.157.229:1618&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" parent="1" vertex="1">
<mxGeometry x="1719" y="467.5" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="8" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;nginx 1.18.0 (Ubuntu)&lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1674" y="587.5" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="9" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;php-fpm7.4&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1801" y="587.5" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="10" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br style=&quot;font-size: 12px;&quot;&gt;Distrib 10.3.31-MariaDB&lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1894" y="636.25" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="11" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;ufw 0.36&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1870" y="587.5" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="12" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;node v12.19.0&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1944" y="587.5" width="80" height="30" as="geometry"/>
</mxCell>
<mxCell id="13" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;Gradido Backend &lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 4000&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1674" y="636.25" width="90" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="14" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;Gradido Login Server &lt;br style=&quot;font-size: 12px;&quot;&gt;HTTP Port: 1200&lt;br style=&quot;font-size: 12px;&quot;&gt;JSON: 1201&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1771" y="636.25" width="110" height="51" as="geometry"/>
</mxCell>
<mxCell id="15" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;gdt.gradido.net:&lt;/b&gt; GDT-Server for testing&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1674" y="697.5" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="16" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;stage1.gradido.net:&lt;/b&gt; Auto-Deployed Gradido Setup on master branch&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1674" y="747.5" width="120" height="70" as="geometry"/>
</mxCell>
<mxCell id="17" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;stagelive.gradido.net:&lt;/b&gt; Test with Live Data (dbs deleted&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1804" y="747.5" width="110" height="70" as="geometry"/>
</mxCell>
<mxCell id="18" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;staging.gradido.net:&lt;/b&gt;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="1804" y="697.5" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="19" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Login via ssh key or password&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;align=left;fontSize=12;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="1974" y="727.5" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="20" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;align=left;fontSize=12;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="1974" y="777.5" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="21" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;STRATO:&amp;nbsp;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;Root Server Linux C4-40: Support&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" parent="1" vertex="1">
<mxGeometry x="530" y="1635" width="470" height="440" as="geometry"/>
</mxCell>
<mxCell id="22" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;AMD Opteron™ 1389 (4 x 2,9 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 8&lt;/span&gt;&amp;nbsp;GB DDR 2 / 8 GB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;2 x 1 TB HDD (Raid 1)&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04 LTS 64bit&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;85.214.26.213: 11771&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" parent="1" vertex="1">
<mxGeometry x="595" y="1666" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="23" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="550" y="1786" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="24" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="677" y="1786" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="25" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br style=&quot;font-size: 12px&quot;&gt;Distrib 10.1.44-MariaDB&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="820" y="1786" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="26" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;ufw 0.36&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="746" y="1786" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="28" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Elasticsearch version 7.8.0, Port 9200&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="550" y="1845" width="90" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="29" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Zammad (install: Puma 3.12.6, Port 3000, Postgresql, Port 5432, redis, Port 6379)&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="647" y="1845" width="163" height="50.25" as="geometry"/>
</mxCell>
<mxCell id="30" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;kanban.gradido.net:&lt;/b&gt; Wekan Kanban Board, anfangs für Sprintplanung genutzt&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="550" y="1915" width="130" height="70" as="geometry"/>
</mxCell>
<mxCell id="31" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;support.gradido.net: &lt;/b&gt;Zammad&lt;br&gt;Support-Tool, lief nicht mit 4 GB Arbeitsspeicher&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="690" y="1965" width="110" height="80" as="geometry"/>
</mxCell>
<mxCell id="33" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;wolke.gradido.net:&lt;/b&gt;&lt;br&gt;Nextcloud&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="690" y="1915" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="34" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Login via password&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="850" y="1925" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="35" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="850" y="1976" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="36" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;no ssh&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;align=left;fontSize=12;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="870" y="1505" width="90" height="40" as="geometry"/>
</mxCell>
<mxCell id="37" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;loolwsd (part of nextlcoud for edit documents in Browser) Port: 9982 + 9983&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="820" y="1845.25" width="150" height="50" as="geometry"/>
</mxCell>
<mxCell id="38" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;STRATO:&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;VPS Linux V5-49: git + gdt&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" parent="1" vertex="1">
<mxGeometry x="530" y="2115" width="470" height="400" as="geometry"/>
</mxCell>
<mxCell id="39" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;GB HDD&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04 LTS 64bit&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;85.214.134.190: 19152&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" parent="1" vertex="1">
<mxGeometry x="595" y="2146" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="40" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="550" y="2266" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="41" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="677" y="2266" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="42" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br style=&quot;font-size: 12px&quot;&gt;Distrib 10.4.12-MariaDB&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="650" y="2325" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="43" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;ufw 0.36&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="746" y="2266" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="44" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;MongoDB version v3.6.3, Port: 27017&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="550" y="2325" width="90" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="45" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;OpenSSL 1.1.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="817" y="2266" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="46" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;gdt.gradido.com: &lt;/b&gt;&lt;br&gt;Main Production GDT-Server&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="550" y="2395" width="130" height="70" as="geometry"/>
</mxCell>
<mxCell id="49" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;admin login only via password&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="730" y="2404" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="50" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="850" y="2404" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="52" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;git main repository before we used github&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="793.5" y="2325" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="53" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;git login also via ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="730" y="2454" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="54" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 10px&quot;&gt;10 Tage Backup&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="850" y="2454" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="71" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;DARIO privat:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;RockPi 4&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" parent="1" vertex="1">
<mxGeometry x="3030" y="1440" width="470" height="280" as="geometry"/>
</mxCell>
<mxCell id="72" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;Rockchip RK3399 (2x ARM A72&lt;br/&gt;1.8 GHz, 4x ARM A53 1.4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;:&amp;nbsp;&lt;/span&gt;4 GB Ram / 8 GB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;MicroSD + NVME SSD&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" parent="1" vertex="1">
<mxGeometry x="3095" y="1471" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="79" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;privater Hauptwebserver, &lt;br&gt;auch zum Testen von Gradido (Community-Server)&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="3060" y="1594.5" width="280" height="40" as="geometry"/>
</mxCell>
<mxCell id="81" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;GDT Production Backup Server&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="3060" y="1644.5" width="280" height="41" as="geometry"/>
</mxCell>
<mxCell id="84" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;DARIO privat:&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;J4125B-ITX&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" parent="1" vertex="1">
<mxGeometry x="3030" y="1760" width="470" height="280" as="geometry"/>
</mxCell>
<mxCell id="85" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;Intel® Celeron® Prozessor&lt;br/&gt;J4125 4x 2,7 GHz&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;:&amp;nbsp;&lt;/span&gt;32 GB Ram DDR4 / 64 GB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;SSD&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.5 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" parent="1" vertex="1">
<mxGeometry x="3095" y="1791" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="86" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;u.a. um den Login-Server für den Production-Server zu kompilieren,&amp;nbsp;&lt;br&gt;weil hier das gleiche Betriebssystem läuft wie auf dem Production Server&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="3060" y="1914.5" width="420" height="40" as="geometry"/>
</mxCell>
<mxCell id="87" value="&lt;p class=&quot;Textbody&quot;&gt;Login nur im Lokalen Netzwerk über Passwort&lt;/p&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="3060" y="1964.5" width="280" height="41" as="geometry"/>
</mxCell>
<mxCell id="88" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;1fire:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: DARIO privat&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" parent="1" vertex="1">
<mxGeometry x="3030" y="2084.5" width="470" height="320" as="geometry"/>
</mxCell>
<mxCell id="89" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / 500 MB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.6 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;62.113.241.71&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" parent="1" vertex="1">
<mxGeometry x="3095" y="2115.5" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="95" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;gradido.com:&lt;/b&gt;&lt;br&gt;Sprachabhängiger Link zur Elopage Registrierung, gibt publisher-id weiter wenn angegeben, z.B. &lt;a href=&quot;https://gradido.com/173817&quot;&gt;&lt;span&gt;https://gradido.com/173817&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" parent="1" vertex="1">
<mxGeometry x="3050" y="2234.5" width="250" height="70" as="geometry"/>
</mxCell>
<mxCell id="96" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="3350" y="2234.5" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="97" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="3350" y="2279" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="98" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;arbeitet für mich als dns-server um meine Domains auf meinen Anschluss (wechselnde IP) zu routen&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="3230" y="2330" width="230" height="51" as="geometry"/>
</mxCell>
<mxCell id="161" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="105" target="131">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="105" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;Provider?:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: Main Production AppServer&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="260" y="461" width="470" height="349" as="geometry"/>
</mxCell>
<mxCell id="106" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;212.83.56.124: 17611&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="325" y="492" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="107" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="280" y="612" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="108" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="407" y="612" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="109" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;ufw 0.35&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="476" y="612" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="111" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;node v12.13.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="547" y="612" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="112" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;gdd1.gradido.com: &lt;/b&gt;Gradido Main Server&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="280" y="730" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="113" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via password or ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="460" y="739" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="114" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="580" y="739" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="162" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="118" target="131">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="118" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;Provider?:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: Main Production AppServer&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="790" y="464" width="470" height="346" as="geometry"/>
</mxCell>
<mxCell id="119" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;212.83.56.124: 17611&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="855" y="495" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="120" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="810" y="615" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="121" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="937" y="615" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="122" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;ufw 0.35&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="1006" y="615" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="124" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;node v12.13.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="1077" y="615" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="125" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;gdd1.gradido.com: &lt;/b&gt;Gradido Main Server&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="810" y="744" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="126" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via password or ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="990" y="753" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="127" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="1110" y="753" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="131" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;Provider?:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: Main Production Persistenz Server&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="525" y="930" width="470" height="310" as="geometry"/>
</mxCell>
<mxCell id="132" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;212.83.56.124: 17611&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="590" y="961" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="133" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="545" y="1081" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="134" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="672" y="1081" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="135" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;ufw 0.35&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="741" y="1081" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="136" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br&gt;Distrib 10.1.43-MariaDB, &lt;br&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="545" y="1140" width="130" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="137" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;node v12.13.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="812" y="1081" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="139" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via password or ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="725" y="1121" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="140" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="845" y="1121" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="141" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;db backups&amp;nbsp;gelegentlich manuell, &lt;br&gt;download in verschlüsseltes TrueCrypt Volume auf&amp;nbsp;Arbeits-Laptop&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="725" y="1171" width="230" height="51" as="geometry"/>
</mxCell>
<mxCell id="158" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="144" target="105">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="160" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="144" target="118">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="144" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;Provider?:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: Main Production LoadBalancer&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="525" y="90" width="470" height="270" as="geometry"/>
</mxCell>
<mxCell id="145" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;212.83.56.124: 17611&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="590" y="121" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="146" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="545" y="241" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="147" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="672" y="241" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="148" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;ufw 0.35&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="741" y="241" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="150" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;node v12.13.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="812" y="241" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="151" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;gdd1.gradido.com:&lt;br&gt;&lt;/b&gt;&lt;span&gt;- Authentication&amp;nbsp;&lt;br&gt;&lt;/span&gt;&lt;span&gt;- Balancing&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="545" y="290" width="122.5" height="60" as="geometry"/>
</mxCell>
<mxCell id="152" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via password or ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="762.5" y="290" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="153" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="882.5" y="290" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="163" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Gradido Backend &lt;br&gt;Manage Node&lt;br&gt;Port:&amp;nbsp;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="360" y="670" width="100" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="166" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="468.5" y="650" width="120" height="71.25" as="geometry"/>
</mxCell>
<mxCell id="116" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Gradido Backend &lt;br&gt;Worker Node&lt;br&gt;Port:&amp;nbsp;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="166">
<mxGeometry width="100" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="164" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Gradido Backend &lt;br&gt;Worker Node&lt;br&gt;Port:&amp;nbsp;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="166">
<mxGeometry x="10" y="10" width="100" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="165" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Gradido Backend &lt;br&gt;Worker Node&lt;br&gt;Port:&amp;nbsp;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="166">
<mxGeometry x="20" y="20" width="100" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="167" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="990" y="660" width="120" height="71.25" as="geometry"/>
</mxCell>
<mxCell id="168" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Gradido Backend &lt;br&gt;Worker Node&lt;br&gt;Port:&amp;nbsp;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="167">
<mxGeometry width="100" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="169" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Gradido Backend &lt;br&gt;Worker Node&lt;br&gt;Port:&amp;nbsp;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="167">
<mxGeometry x="10" y="10" width="100" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="170" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Gradido Backend &lt;br&gt;Worker Node&lt;br&gt;Port:&amp;nbsp;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="167">
<mxGeometry x="20" y="20" width="100" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="171" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;exitX=0;exitY=0.333;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="101">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="620" y="700" as="sourcePoint"/>
<mxPoint x="1440" y="880" as="targetPoint"/>
<Array as="points"/>
</mxGeometry>
</mxCell>
<mxCell id="172" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;exitX=-0.001;exitY=0.143;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="101">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="620" y="700" as="sourcePoint"/>
<mxPoint x="1440" y="400" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="219" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="173" target="208">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="173" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;STRATO:&amp;nbsp;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;Root Server Linux C4-47: Staging&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="2270" y="436.5" width="470" height="401" as="geometry"/>
</mxCell>
<mxCell id="174" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;AMD Opteron™ 1385 (4 x 2,7 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;:&amp;nbsp;&lt;/span&gt;4 GB DDR 2 / 8 GB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;2 x 500 GB HDD (Raid 1)&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 20.04 LTS 64bit&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt; 85.214.157.229:1618&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="2335" y="467.5" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="175" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;nginx 1.18.0 (Ubuntu)&lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2290" y="587.5" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="176" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;php-fpm7.4&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2417" y="587.5" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="177" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br style=&quot;font-size: 12px;&quot;&gt;Distrib 10.3.31-MariaDB&lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2510" y="636.25" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="178" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;ufw 0.36&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2486" y="587.5" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="179" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;node v12.19.0&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2560" y="587.5" width="80" height="30" as="geometry"/>
</mxCell>
<mxCell id="180" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;Gradido Backend &lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 4000&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2290" y="636.25" width="90" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="181" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;Gradido Login Server &lt;br style=&quot;font-size: 12px;&quot;&gt;HTTP Port: 1200&lt;br style=&quot;font-size: 12px;&quot;&gt;JSON: 1201&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2387" y="636.25" width="110" height="51" as="geometry"/>
</mxCell>
<mxCell id="182" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;gdt.gradido.net:&lt;/b&gt; GDT-Server for testing&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2290" y="697.5" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="183" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;stage1.gradido.net:&lt;/b&gt; Auto-Deployed Gradido Setup on master branch&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2290" y="747.5" width="120" height="70" as="geometry"/>
</mxCell>
<mxCell id="184" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;stagelive.gradido.net:&lt;/b&gt; Test with Live Data (dbs deleted&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2420" y="747.5" width="110" height="70" as="geometry"/>
</mxCell>
<mxCell id="185" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;staging.gradido.net:&lt;/b&gt;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2420" y="697.5" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="186" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Login via ssh key or password&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;align=left;fontSize=12;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="2590" y="727.5" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="187" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;align=left;fontSize=12;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="2590" y="777.5" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="206" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="197" target="6">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="207" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="197" target="173">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="197" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;Provider?:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: Main Production LoadBalancer&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="1965" y="90" width="470" height="270" as="geometry"/>
</mxCell>
<mxCell id="198" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;212.83.56.124: 17611&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="2030" y="121" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="199" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="1985" y="241" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="200" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2112" y="241" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="201" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;ufw 0.35&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2181" y="241" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="202" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;node v12.13.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2252" y="241" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="203" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;gdd1.gradido.com:&lt;br&gt;&lt;/b&gt;&lt;span&gt;- Authentication&amp;nbsp;&lt;br&gt;&lt;/span&gt;&lt;span&gt;- Balancing&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="1985" y="290" width="122.5" height="60" as="geometry"/>
</mxCell>
<mxCell id="204" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via password or ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="2202.5" y="290" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="205" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="2322.5" y="290" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="208" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;Provider?:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: Main Production Persistenz Server&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="1977.5" y="930" width="470" height="310" as="geometry"/>
</mxCell>
<mxCell id="209" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;212.83.56.124: 17611&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="2042.5" y="961" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="210" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="1997.5" y="1081" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="211" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2124.5" y="1081" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="212" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;ufw 0.35&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2193.5" y="1081" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="213" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br&gt;Distrib 10.1.43-MariaDB, &lt;br&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="1997.5" y="1140" width="130" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="214" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;node v12.13.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="2264.5" y="1081" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="215" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via password or ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="2177.5" y="1121" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="216" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="2297.5" y="1121" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="217" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;db backups&amp;nbsp;gelegentlich manuell, &lt;br&gt;download in verschlüsseltes TrueCrypt Volume auf&amp;nbsp;Arbeits-Laptop&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="2177.5" y="1171" width="230" height="51" as="geometry"/>
</mxCell>
<mxCell id="220" value="" style="endArrow=none;html=1;strokeWidth=5;strokeColor=#FF0000;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2960" y="1361" as="sourcePoint"/>
<mxPoint x="3600" y="2471" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="221" value="" style="endArrow=none;html=1;strokeWidth=5;strokeColor=#FF0000;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="3610" y="1361" as="sourcePoint"/>
<mxPoint x="2980" y="2431" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="222" value="&lt;font style=&quot;font-size: 24px;&quot;&gt;&lt;b style=&quot;font-size: 24px;&quot;&gt;Entwicklung / Test&lt;/b&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;verticalAlign=top;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=24;" vertex="1" parent="1">
<mxGeometry x="2960" y="40" width="1200" height="1240" as="geometry"/>
</mxCell>
<mxCell id="223" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="224" target="266">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="224" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;STRATO:&amp;nbsp;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;Root Server Linux C4-47: Staging&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="3325" y="435" width="470" height="401" as="geometry"/>
</mxCell>
<mxCell id="225" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;AMD Opteron™ 1385 (4 x 2,7 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;:&amp;nbsp;&lt;/span&gt;4 GB DDR 2 / 8 GB Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;&lt;/span&gt;2 x 500 GB HDD (Raid 1)&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 20.04 LTS 64bit&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt; 85.214.157.229:1618&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="3390" y="466" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="226" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;nginx 1.18.0 (Ubuntu)&lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3345" y="586" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="227" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;php-fpm7.4&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3472" y="586" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="228" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br style=&quot;font-size: 12px;&quot;&gt;Distrib 10.3.31-MariaDB&lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3565" y="634.75" width="130" height="50" as="geometry"/>
</mxCell>
<mxCell id="229" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;ufw 0.36&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3541" y="586" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="230" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;node v12.19.0&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3615" y="586" width="80" height="30" as="geometry"/>
</mxCell>
<mxCell id="231" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;Gradido Backend &lt;br style=&quot;font-size: 12px;&quot;&gt;Port: 4000&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3345" y="634.75" width="90" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="232" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px; font-family: &amp;quot;liberation serif&amp;quot;, serif;&quot;&gt;Gradido Login Server &lt;br style=&quot;font-size: 12px;&quot;&gt;HTTP Port: 1200&lt;br style=&quot;font-size: 12px;&quot;&gt;JSON: 1201&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3442" y="634.75" width="110" height="51" as="geometry"/>
</mxCell>
<mxCell id="233" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;gdt.gradido.net:&lt;/b&gt; GDT-Server for testing&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3345" y="696" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="234" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;stage1.gradido.net:&lt;/b&gt; Auto-Deployed Gradido Setup on master branch&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3345" y="746" width="120" height="70" as="geometry"/>
</mxCell>
<mxCell id="235" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;stagelive.gradido.net:&lt;/b&gt; Test with Live Data (dbs deleted&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3475" y="746" width="110" height="70" as="geometry"/>
</mxCell>
<mxCell id="236" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;staging.gradido.net:&lt;/b&gt;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3475" y="696" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="237" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;Login via ssh key or password&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;align=left;fontSize=12;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="3645" y="726" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="238" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;align=left;fontSize=12;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="3645" y="776" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="255" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="257" target="224">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="257" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;Provider?:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: Main Production LoadBalancer&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="3325" y="90" width="470" height="270" as="geometry"/>
</mxCell>
<mxCell id="258" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;212.83.56.124: 17611&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="3390" y="121" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="259" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3345" y="241" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="260" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3472" y="241" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="261" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;ufw 0.35&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3541" y="241" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="262" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;node v12.13.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3612" y="241" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="263" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;gdd1.gradido.com:&lt;br&gt;&lt;/b&gt;&lt;span&gt;- Authentication&amp;nbsp;&lt;br&gt;&lt;/span&gt;&lt;span&gt;- Balancing&lt;/span&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3345" y="290" width="122.5" height="60" as="geometry"/>
</mxCell>
<mxCell id="264" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via password or ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="3562.5" y="290" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="265" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="3682.5" y="290" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="266" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 12pt&quot;&gt;Provider?:&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12.0pt ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;VPS Linux: Main Production Persistenz Server&lt;/span&gt;&lt;/b&gt;&lt;b style=&quot;font-size: 12pt&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;strokeColor=#666666;gradientColor=#b3b3b3;" vertex="1" parent="1">
<mxGeometry x="3337.5" y="930" width="470" height="310" as="geometry"/>
</mxCell>
<mxCell id="267" value="&lt;ul style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;CPU:&lt;/b&gt;&amp;nbsp;1x&lt;/span&gt;&amp;nbsp;vCore (2,4 GHz)&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Arbeitsspeicher&lt;/b&gt;: 1&lt;/span&gt;&amp;nbsp;GB / kein Swap&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;Persistenz:&lt;/b&gt;&amp;nbsp;?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OS:&lt;/b&gt; Ubuntu 18.04.1 LTS&lt;/li&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;&lt;b&gt;IP/Port:&lt;/b&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;212.83.56.124: 17611&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;" style="rounded=0;whiteSpace=wrap;html=1;verticalAlign=middle;labelPosition=center;verticalLabelPosition=middle;align=left;spacing=0;spacingTop=0;" vertex="1" parent="1">
<mxGeometry x="3402.5" y="961" width="365" height="109" as="geometry"/>
</mxCell>
<mxCell id="268" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;nginx 1.14.0 (Ubuntu)&lt;br style=&quot;font-size: 12px&quot;&gt;Port: 80 + 443&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3357.5" y="1081" width="120" height="40" as="geometry"/>
</mxCell>
<mxCell id="269" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;php-fpm7.2&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3484.5" y="1081" width="63" height="29" as="geometry"/>
</mxCell>
<mxCell id="270" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 12px ; font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;ufw 0.35&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3553.5" y="1081" width="63" height="30" as="geometry"/>
</mxCell>
<mxCell id="271" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;mariadb&amp;nbsp; Ver 15.1 &lt;br&gt;Distrib 10.1.43-MariaDB, &lt;br&gt;Port: 3306&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3357.5" y="1140" width="130" height="51.25" as="geometry"/>
</mxCell>
<mxCell id="272" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;node v12.13.1&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;gradientColor=#97d077;fillColor=#d5e8d4;strokeColor=#82b366;align=left;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="3624.5" y="1081" width="83" height="30" as="geometry"/>
</mxCell>
<mxCell id="273" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;login via password or ssh-key&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="3537.5" y="1121" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="274" value="&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;non standard ssh-port&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="3657.5" y="1121" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="275" value="&lt;span style=&quot;font-family: &amp;#34;liberation serif&amp;#34; , serif&quot;&gt;&lt;font style=&quot;font-size: 12px&quot;&gt;db backups&amp;nbsp;gelegentlich manuell, &lt;br&gt;download in verschlüsseltes TrueCrypt Volume auf&amp;nbsp;Arbeits-Laptop&lt;/font&gt;&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;verticalAlign=top;align=left;fontSize=12;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="3537.5" y="1171" width="230" height="51" as="geometry"/>
</mxCell>
<mxCell id="276" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;exitX=0;exitY=0.333;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1601.36" y="879.1599999999999" as="sourcePoint"/>
<mxPoint x="2800" y="880" as="targetPoint"/>
<Array as="points"/>
</mxGeometry>
</mxCell>
<mxCell id="277" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;exitX=-0.001;exitY=0.143;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1599.9999999999993" y="400.3599999999997" as="sourcePoint"/>
<mxPoint x="2800" y="400" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="278" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;exitX=0;exitY=0.333;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2961.359999999999" y="879.1599999999999" as="sourcePoint"/>
<mxPoint x="4160" y="880" as="targetPoint"/>
<Array as="points"/>
</mxGeometry>
</mxCell>
<mxCell id="279" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;exitX=-0.001;exitY=0.143;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2959.999999999999" y="400.3599999999999" as="sourcePoint"/>
<mxPoint x="4160" y="400" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="280" value="" style="endArrow=none;html=1;strokeWidth=4;exitX=0;exitY=0.333;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="1280.0000000000002" as="sourcePoint"/>
<mxPoint x="1440" y="1280.84" as="targetPoint"/>
<Array as="points"/>
</mxGeometry>
</mxCell>
<mxCell id="281" value="DMZ" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=24;" vertex="1" parent="1">
<mxGeometry x="170" y="165.5" width="40" height="20" as="geometry"/>
</mxCell>
<mxCell id="282" value="DMZ" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=24;" vertex="1" parent="1">
<mxGeometry x="1690" y="160" width="40" height="20" as="geometry"/>
</mxCell>
<mxCell id="283" value="DMZ" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=24;" vertex="1" parent="1">
<mxGeometry x="3050" y="165.5" width="40" height="20" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="Zar-6ZasfFidioh4BmVj" name="Seite-2">
<mxGraphModel dx="1228" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1654" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-0"/>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-1" parent="uKgAqf8bIy8Buk_wB0Zb-0"/>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontSize=24;strokeColor=#FF0000;strokeWidth=4;" edge="1" parent="uKgAqf8bIy8Buk_wB0Zb-1" source="uKgAqf8bIy8Buk_wB0Zb-2" target="uKgAqf8bIy8Buk_wB0Zb-22">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="125" y="120"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=24;strokeColor=#FF0000;strokeWidth=4;" edge="1" parent="uKgAqf8bIy8Buk_wB0Zb-1" source="uKgAqf8bIy8Buk_wB0Zb-2" target="uKgAqf8bIy8Buk_wB0Zb-4">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="320" y="210"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-2" value="LoginServer" style="rounded=0;whiteSpace=wrap;html=1;fontSize=24;" vertex="1" parent="uKgAqf8bIy8Buk_wB0Zb-1">
<mxGeometry x="220" y="80" width="180" height="80" as="geometry"/>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=24;strokeColor=#FF0000;strokeWidth=4;" edge="1" parent="uKgAqf8bIy8Buk_wB0Zb-1" source="uKgAqf8bIy8Buk_wB0Zb-3" target="uKgAqf8bIy8Buk_wB0Zb-2">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-3" value="NodeServer" style="rounded=0;whiteSpace=wrap;html=1;fontSize=24;" vertex="1" parent="uKgAqf8bIy8Buk_wB0Zb-1">
<mxGeometry x="480" y="80" width="180" height="80" as="geometry"/>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontSize=24;strokeColor=#FF0000;strokeWidth=4;" edge="1" parent="uKgAqf8bIy8Buk_wB0Zb-1" source="uKgAqf8bIy8Buk_wB0Zb-4" target="uKgAqf8bIy8Buk_wB0Zb-3">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="930" y="120"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-4" value="IOTA" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fontSize=24;" vertex="1" parent="uKgAqf8bIy8Buk_wB0Zb-1">
<mxGeometry x="870" y="180" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fontSize=24;strokeColor=#FF0000;strokeWidth=4;" edge="1" parent="uKgAqf8bIy8Buk_wB0Zb-1" source="uKgAqf8bIy8Buk_wB0Zb-5" target="uKgAqf8bIy8Buk_wB0Zb-10">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="120" y="620"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-28" value="1. TxDaten" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=24;" vertex="1" connectable="0" parent="uKgAqf8bIy8Buk_wB0Zb-21">
<mxGeometry x="-0.3094" y="-1" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-27" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontSize=24;strokeColor=#FF0000;strokeWidth=4;" edge="1" parent="uKgAqf8bIy8Buk_wB0Zb-1" source="uKgAqf8bIy8Buk_wB0Zb-5" target="uKgAqf8bIy8Buk_wB0Zb-10">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="70" y="690"/>
<mxPoint x="600" y="690"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-30" value="3. Signierung" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=24;" vertex="1" connectable="0" parent="uKgAqf8bIy8Buk_wB0Zb-27">
<mxGeometry x="0.1067" y="3" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-5" value="Apollo-Server" style="rounded=0;whiteSpace=wrap;html=1;fontSize=24;" vertex="1" parent="uKgAqf8bIy8Buk_wB0Zb-1">
<mxGeometry x="20" y="400" width="180" height="80" as="geometry"/>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fontSize=24;strokeColor=#FF0000;strokeWidth=4;" edge="1" parent="uKgAqf8bIy8Buk_wB0Zb-1" source="uKgAqf8bIy8Buk_wB0Zb-10" target="uKgAqf8bIy8Buk_wB0Zb-14">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-26" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.75;entryY=1;entryDx=0;entryDy=0;fontSize=24;strokeColor=#FF0000;strokeWidth=4;" edge="1" parent="uKgAqf8bIy8Buk_wB0Zb-1" source="uKgAqf8bIy8Buk_wB0Zb-10" target="uKgAqf8bIy8Buk_wB0Zb-5">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="570" y="510"/>
<mxPoint x="155" y="510"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-29" value="2. BinärDaten" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=24;" vertex="1" connectable="0" parent="uKgAqf8bIy8Buk_wB0Zb-26">
<mxGeometry x="-0.1107" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-10" value="LoginServer" style="rounded=0;whiteSpace=wrap;html=1;fontSize=24;" vertex="1" parent="uKgAqf8bIy8Buk_wB0Zb-1">
<mxGeometry x="510" y="580" width="180" height="80" as="geometry"/>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-12" value="NodeServer" style="rounded=0;whiteSpace=wrap;html=1;fontSize=24;" vertex="1" parent="uKgAqf8bIy8Buk_wB0Zb-1">
<mxGeometry x="510" y="400" width="180" height="80" as="geometry"/>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontSize=24;strokeColor=#FF0000;strokeWidth=4;" edge="1" parent="uKgAqf8bIy8Buk_wB0Zb-1" source="uKgAqf8bIy8Buk_wB0Zb-14" target="uKgAqf8bIy8Buk_wB0Zb-12">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="960" y="440"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-14" value="IOTA" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fontSize=24;" vertex="1" parent="uKgAqf8bIy8Buk_wB0Zb-1">
<mxGeometry x="900" y="500" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=24;strokeColor=#FF0000;strokeWidth=4;" edge="1" parent="uKgAqf8bIy8Buk_wB0Zb-1" source="uKgAqf8bIy8Buk_wB0Zb-22" target="uKgAqf8bIy8Buk_wB0Zb-3">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="uKgAqf8bIy8Buk_wB0Zb-22" value="CommunityServer" style="rounded=0;whiteSpace=wrap;html=1;fontSize=24;" vertex="1" parent="uKgAqf8bIy8Buk_wB0Zb-1">
<mxGeometry x="20" y="200" width="210" height="80" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 KiB

After

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@ -0,0 +1,24 @@
### Tätigkeiten, die von der Community aktzeptiert werden
Nachweise für durchgeführte Tätigkeiten, bevor diese dem AGE-Konto gutgeschrieben werden?
Liste der Tätigkeiten muss von Community erstellt, bestätigt und verwaltet werden
Bei Tätigkeit von x Stunden für das AGE muss aus der Liste die passende Tätigkeit gewählt werden und per Nachweis (andere Mitglieder, Video, o.ä.)
Bei Krankheit o.ä. muss es aber möglich sein, dass dennoch Geld auf das AGE-Konto kommt.
| PR-Kommentar | |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ulf 07.11.2021 | Definition? Ist Faulheit eine Krankheit? |
| Claus-Peter 25.11.2021 | :-) Das kommt auf die solidarische Einstellung der Community an ;-)<br /><br />da drängt sich mir die Gegenfrage auf: Bis zu welchem Alter bekommt ein Kind sein AGE-Geld geschöpft nur durch seine blos Existenz? Oder andersherum, ab und bis zu welchem Alter muss eine Gegenleistung erbracht werden, Stichworte: unbeschwerte Kindheit und wohlverdiente Altersruhe? |
Kontaktförderung durch gewichtete Tätigkeitsbestätigung ( bei mind. 2 Bestätigungen pro Tätigkeit muss mind. ein neues Mitglied dabei sein)
Liste von Mitgliedern, die ich bestätigt habe:
* Kontaktpflege
* Gewichtung
* Vernetzung
Ricardo Leppe Podcast Lern und Memotechniken

View File

@ -0,0 +1,469 @@
# Community Communication
This document contains the detailed descriptions of the public API of a community.
## Authentication/Autorization of new Community
Each public API of a community has to be authenticated and autorized before.
### Variant A:
This could be done by following the *OpenID Connect* protocoll. To fullfil these security requirements a separate security service has to be part of the Gradido-application.
Following the link [OpenID Connect](https://www.npmjs.com/package/openid-client) there can be found a server-side OpenID relying party implementation for node.js runtime.
The authentication of communities base on the community-attributes *key* and *URL*, which where exchanged during the *federation process* before. In concequence a community that hasn't execute his federation well will be unknown for other communities and can't be authenticated and autorized for further cross community API calls.
### Variant B:
A similar solution of authentication to variant A but **without autorization** can be done by using private and public key encryption. The *community creation* process will create a private and public key and store them internally. As the third step of the federation the *community communication* background process of the new *community-A* will be startet and a sequence of service invocations will exchange the necessary security data:
![../BusinessRequirements/image/AuthenticateCommunityCommunication.png](../BusinessRequirements/image/AuthenticateCommunityCommunication.png)
**1.Sequence**
1. the new *community-A* encrypt the community key of the existing *community-B* with its own privat key. Then it invokes the service *authenticateCommunity* at *community-B* by sending the own community key, the encrypted community key of *community-B* and a redirect URI back to *community-A* as input data. The *community-B* will search the given community key of *community-A* in the internally stored list of communities, which are a result of the previous *federation process* collected over a different medium.
2. If in *community-B* the given community key of *community-A* is found, a generated one-time code is stored together with the given encrypted community key in the community-entry of community-A, till an invocation of the service *verifyOneTimeCode* with this one-time-code. The one-time-code is passed back to the given Redirect URI of the *community-A*.
3. *Community-A* will send with the next invocation to *community-B* the received one-time code and the own public key by requesting the service *verifyOneTimeCode* at *community-B*.
4. *Community-B* will verify the given one-time-code and if valid, decrypt the previous received and encrypted community key from step 1 of the invocation-chain by using the given public key from *community-A*. If the decrypted community-key is equals the own community key, the public key of *community-A* is stored in the entry of *community-A* of the internal community list. As response of the *verifyOneTimeCode* the *community-B* will send back his own public key to *community-A*.
5. *Community-A* will store the received public key of *community-B* in the corresponding entry of the internal community-list.
| PR-Kommentar | zu Punkt 1 in der List oben |
| :--------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ulf<br />24.03.2022 | ComA.org --- (pubKeyA, SaltA, privKeyA(SaltA,pubKeyB) ---> ComB.org<br />
```
<--- (pubKeyB, SaltB, privKeyB(SaltA, SaltB, pubKeyA) ----
```
<br /><br />Das wäre mien Vorschlag, aber ich bin kein Crypto-Experte.<br />Tritt ein Validierungsfehler auf, wird der Call als unauthorized markiert.<br /><br />Vorteil: statless<br />Nachteil: Rechenaufwendig, kann umgangen werden, wenn Salt ein Datum ist und ein solcher Salt eine Gültigkeitsdauer hat - e.g. 10 min. Dann wäre aber SaltB unpraktikabel - für die Validierung auf ComB Seite wäre, dann eine Prüfung des Salt-Datums notwendig um replay Attacken zu verhindern. |
| Claus-Peter<br />24.03.2022 | Da scheint in deinem Bild ein Henne-Ei-Problem zu sein:<br />Wie kommt ComA für seinen ersten Request an ComB zu dem pubKeyB?<br />Den hat ComA zu dem Zeitpunkt doch noch gar nicht, oder?<br />Daher benötigt man einen mehr-schrittigen Handshake zw. den Communities, um diese Keys auszutauschen. |
| **PR-Kommentar** | **zu Punkt 2 in der Liste oben** |
| Ulf<br />24.03.2022 | explain? Out key exchange was done befor, we just need to proof that our current data is correct?! |
| Claus-Peter<br />24.03.2022 | Das ist genau was ich oben schon meinte mit dem Henne-Ei-Problem:<br /><br />Wir sollten dazu noch einmal genau den Ablauf zu den einzelnen Zeitpunkten und welche Daten in welcher Community zu den Zeitpunkten vorliegen bzw über welche Kanäle diese ausgetauscht werden.<br />Ich glaube ich skizziere dies noch einmal möglichst einfach auf... |
The result of this invocation chain is the public key exchange of the involved communities, which is the foundation to authenticate a future cross community communication - see Sequnce 2 and 3.
To reach in Variant B nearly the same security level as in Variant A each community has to integrate several components to process this invocation chain like Variant A does.
### Variant C:
The third Variant exchange the all necessary data directly without the step in between returning a one-time code per redirection URI:
1. the new *community-A* encrypt the community key of the existing *community-B* with its own privat key. Then it invokes the service *authenticateCommunity* at *community-B* by sending the own community key, the encrypted community key of *community-B* and its own public key as input data. The *community-B* will search the given community key of *community-A* in the internally stored list of communities, which are a result of the previous *federation process* collected over a different medium.
2. If in *community-B* the given community key of *community-A* is found and if the decryption of the given encrypted community key with the given public key is equals the own community key, the public key of *community-A* is stored in the entry of *community-A* of the internal community list. As response of the *authenticateCommunity* the *community-B* will send back his own public key to *community-A*.
3. *Community-A* will store the received public key of *community-B* in the corresponding entry of the internal community-list.
Variant C is quite similar to Variant B, but to exchange all security relevant data in a single request-response-roundtrip bears more security risks and should be avoided.
## Service: "Authenticate Community"
This service must be invoked at first - see Variant B above - to exchange the security relevant data before further cross community communication can be done.
The third step of the *federation process* starts the background process for community communication. As result of the previous federation steps the new community has received from at least one existing community the URL and the community key.
After receiving the input data the service answers directly with an empty response. Then it searches for the attribute "community-key-A" in the internal community list the entry of *community-A*. If the entry of *community-A* could be found with this key, a new one-time-code is generated and stored together with the attribute "community-key-B" till the invocation of service "verifyOneTimeCode". With the given redirection URI a callback at *community-A* is invoked by sending the generated One-Time-Code back to *community-A*.
### Route:
POST https://<New_Community_URL>/authenticateCommunity
### Input-Data:
```
{
"community-key-A" : "the community-key of the new community-A"
"community-key-B" : "the community-key of the community-B, replied during the federation, encrypted by the private key of community-A"
"redirectionURI" : "the URI for the redirection callback"
}
```
### Output-Data:
* none
* redirection URI: "one-time-code" : "one-time usable code with short expiration time as input for the service *verifyOneTimeCode*"
### Exceptions:
*MissingParameterException* if any of the parameter attributes is not initialized.
*UnknownCommunityException* if the community search with the value of parameter "community-key-A" could not find a matching community entry with this key.
## Service: "Verify OneTimeCode"
This service must be invoked directly after getting the *one-time code*, because this code has a very short expiration time. Together with the public key of *community-A* the one-time code is send as input data to *community-B*. The service verifies the given *one-time code* and if valid it decrypt with the given *public key* the previous receive *community-key-B* from the request *authenticateCommunity*. If this decrypted community-key is equals the own community-key the *public key* is stored in the community-entry of *community-A* of the internal community-list.
### Route:
POST https://<New_Community_URL>/verifyOneTimeCode
### Input-Data:
```
{
"one-time-code" : "one-time code with short expiration, received from community-B per redirect URI"
"public-key" : "the public key of the new community (community-A)"
}
```
### Output-Data:
```
{
"public-key" : "the public key of community-B"
}
```
### Exceptions:
*MissingParameterException* if one of the parameter attributes is not initialized.
*InvalidOneTimeCodeException* if the one-time-code is expired, invalid or unknown.
*SecurityException* if the decryption result with the given parameter *public-key* and previous receive *community-key-B* from the request *authenticateCommunity* doesn't match with the own community-key.
## Service: "open Communication"
This service must be used to start a new communication session between two communities to authenticate with the returned JWT-Token further requests.
*Community-A* will communicate with *community-B*, then *community-A* has to encrypt with its own private key the community key of *community-B*, put its own community-key and the encrypted community-key of *community-B* as input data and start with *openCommunication* to get a valid JWT-Token from *community-B*.
In *community-B* the given "community-key-A" will be used to search in the internal community-list for the community-entry with this key. If it exists the corresponding public key is used to decrypt the given parameter "community-key-B". If the decrypted result is equals the own community-key a JWT-Token is generated with a preconfigered expiration time for a community-communication-session. The token is stored internally and returned as result for *community-A.*
### Route:
POST https://<Community-B_URL>/openCommunication
### Input-Data:
The requesting *community-A* will initialize these input data:
```
{
"community-key-A" : "the community-key of the community-A"
"community-key-B" : "the community-key of the community-B, encrypted by the private key of community-A"
}
```
### Output-Data:
```
{
"token" : "valid JWT-Token with a preconfigered expiration time"
}
```
### Exceptions:
*MissingParameterException* if one of the parameter attributes is not initialized.
*UnknownCommunityException* if the community search with the value of parameter "community-key-A" could not find a matching community entry with this key.
*SecurityException* if the decrypted community-key-B will not match the own community key.
## Service: "Familiarize communities"
This request is used to exchange data between an existing and a new community. It will be invoked by the existing community, which received a valid *newCommunity*-Message from a new community during the federation process.
The invocation from the federation process gives the *Community-Key* and *New_Community_URL* as input parameters, which are used to get the *Security-Token* from the SecurityService.
The exchanged data will be transferred as a *CommunityTO* transferobject in both directions as input and output parameter.
### Route:
POST https://<New_Community_URL>/familiarizeCommunity/`<security-accesstoken>`
### Input-Data:
The *existing community* will collect its own data and transferre it as
```
{
CommunityTO {
"key" : "community-key",
"name" : "name of community",
"description" : "description of community",
"icon" : "picture of community",
"birthday" : "day of community creation",
"members" : "amount of members",
"known_communities" : "amount of known communities",
"trading_communities" : "amount of communities the members trade with"
}
}
```
### Output-Data:
The *new community* will save the received data and returns its own collected data as
```
{
CommunityTO {
"key" : "community-key",
"name" : "name of community",
"description" : "description of community",
"icon" : "picture of community",
"birthday" : "day of community creation",
"members" : "amount of members",
"known_communities" : "amount of known communities",
"trading_communities" : "amount of communities the members trade with"
}
}
```
### Exceptions:
A *SecurityException* will be thrown, if the security-accesstoken is not valid or the if internal autorization rules like black-listings will not allow access.
In case the transferred community-key from the service-consumer will not match the previous authenticated community on service-provider the exception *UnknownCommunityException* will be thrown.
In case the transferred data can't be stored on service-provider the exception *WriteAccessException* will be thrown.
## Service: "request TradingLevel"
With this service a community can ask for a trading level with another community. The *community-A* invokes this service at *community-B* to offer the own vision of trading with *community-B* by sending a TradingLevelTO with all the initialized Flags for future data exchanges. *Community-B* will store these data in the entry of *community-A* of its internal community list and mark it as an *open admin request* for trading level. Such an *open admin request* will inform the administrator of *community-B*, because administrative interactions and decisions are necessary.
After the administrator of *community-B* has cleared all community internal aspects for the requested trading level with *community-A,* he will update the stored trading level flags for *community-A* and send this data by calling the service "confirm trading Level" of *community-A*.
### Route:
POST https://<Community-B_URL>/requestTradingLevel/`<security-accesstoken>`
### Input-Data:
```
{
TradingLevelTO
{
"sendMemberDetails" : "Flag if community-A will send member details to the community-B"
"receiveMemberDetails" : "Flag if community-A will receive member details from the community-B"
"sendCoins" : "Flag if members of community-A are allowed to send coins to members of the community-B"
"receiveCoins" : "Flag if members of community-A are allowed to receive coins from members of the community-B"
"sendActivities" : "Flag if community-A will send open activities for confirmation to the community-B"
"receiveActivities" : "Flag if community-A will receive open activities for confirmation from the community-B"
"sendBackup" : "Flag if community-A will send own data to community-B as backup provider"
"receiveBackup" : "Flag if community-A will receive data from community-B as backup provider"
}
}
```
### Output-Data:
```
{
"result" : "Message if the trading level request is accepted and stored or reasons, why the request is rejected"
}
```
### Exceptions:
A *SecurityException* will be thrown, if the security-accesstoken is not valid or the if internal autorization rules like black-listings will not allow access.
In case the transferred data can't be stored on service-provider the exception *WriteAccessException* will be thrown.
## Service: "confirm TradingLevel"
With this service a community sends his trading level confirmation to a previous *requestTradingLevel* invocation of another community. The *community-B* invokes this service at *community-A* to confirm the previous received and optionally updated vision of trading level data with *community-A*. This service sends the TradingLevelTO with the confirmed flags for future data exchanges between *community-A* and *community-B*. *Community-A* will store this data in the entry of *community-B* of its internal community list and mark it as a *confirmed admin request* for trading level. The update of a *admin request* to state *confirmed* will inform the administrator of *community-A* to trigger administrative interactions and decisions.
If the confirmed trading level from *community-B* will match exactly the requested once of *community-A* the confirm request will response with an OK.
If the confirmed trading level from *community-B* can't be verified in *community-A* the confirm request will response with an ERROR.
If the confirmed trading level from *community-B* will differ, but acceptable under reservations for *community-A* the confirm request will response with an RESERVE. If one of the involved communities will change this, it has to start the tradinglevel handshake again.
If the confirmated trading level from *community-B* will absolutely not acceptable for *community-A* the confirm request will response with an REJECT and an additional roundtrip to deal a new tradinglevel between both communities will be necessary.
### Route:
POST https://<Community-A_URL>/confirmTradingLevel/`<security-accesstoken>`
### Input-Data:
The meaning of the *TradingLevelTO*-attributes in the confirmTradingLevel request must be interpreted from the confirmator point of view. For example "receiveBackup = TRUE" means *community-A* is ready to receive backup data from *community-B*, but *community-B* is as confirmator also prepared to send its data to *community-A* for backup.
```
{
TradingLevelTO
{
"sendMemberDetails" : "Flag if community-A will send member details to the community-B"
"receiveMemberDetails" : "Flag if community-A will receive member details from the community-B"
"sendCoins" : "Flag if members of community-A are allowed to send coins to members of the community-B"
"receiveCoins" : "Flag if members of community-A are allowed to receive coins from members of the community-B"
"sendActivities" : "Flag if community-A will send open activities for confirmation to the community-B"
"receiveActivities" : "Flag if community-A will receive open activities for confirmation from the community-B"
"sendBackup" : "Flag if community-A will send own data to community-B as backup provider"
"receiveBackup" : "Flag if community-A will receive data from community-B as backup provider"
}
}
```
### Output-Data:
```
{
"state" : "OK, ERROR, RESERVE, REJECT"
"result" : "optional Message to explain the state in detail"
}
```
### Exceptions:
A *SecurityException* will be thrown, if the security-accesstoken is not valid or the if internal autorization rules like black-listings will not allow access.
## Service: "Member of Community"
Before user A can start any cross-community interactions with user B, this service api can be used to check if user B is a valid member of the other community.
### Route:
GET https://<Other_Community_URL>/memberOfCommunity/`<security-accesstoken>`
### Input-Data:
```
{
userid : "user-id following the pattern <communityname@username"
}
```
### Output-Data:
the other community will search in its member list for the given userid. If the user could be found the output data will be returned, otherwise null.
```
{
UserTO
{
"userid" : "user-id",
"surename" : "surename of user",
"name" : "name of user",
"alias" : "alias name of user",
"email" : "email address of user",
"member-since" : "date of entry in community",
"interacting-members" : "amount of members the user interact with",
"interacting-communities" : "amount of communities the user interact with"
}
}
```
### Exceptions:
A *SecurityException* will be thrown, if the security-accesstoken is not valid or the if internal autorization rules like black-listings will not allow access.
## Service: "Receive Coins"
With this service a cross community transaction can be done. In detail if *user-A* member of *community-sender* wants to send *user-B* member of *community-receiver* an amount of GDDs, the gradido server of *community-sender* invokes this service at the server of *community-receiver*.
The service will use a datatype Money as attribute in the input-data with the following attributes and methods:
```
Money
{
Attributes:
- Integer "amount" : "in Gradido-Cent and so without decimal places"
- String "currencykey" : "unique currency key (communitykey) as the source community the coins are created"
Methods:
- toString() : "returns the amount as String with 2 decimal places and the Gradido-currencysymbol"
- plus(Money m) : "evaluates if the currencykey of m equals the internal currencyKey and if yes adds the amount of m to the internal ammount, otherwise throws an WrongCurrencyException"
- minus(Money m) : "evaluates if the currencykey of m equals the internal currencyKey and if yes substracts the amount of m from the internal ammount, otherwise throws an WrongCurrencyException
- isSameCommunity(Money m) : "returns TRUE if the currencykey of m is equals the internal currencyKey, otherwise FALSE"
- decay(Long sec) : "calculates the decay of the internal amount with the given duration in sec by: amount - (amount x 0.99999997802044727 ^ sec)
}
```
### Route:
GET https://<receiver_community_URL>/receiveCoins/`<security-accesstoken>`
### Input-Data:
```
{
TransactionTO
{
"sender-community" : "the key of the sender community",
"sender-user" : "the user-id of the user, who sends the coins",
"receiver-user" : "the user-id of the user, who will receive the coins",
"money" : "the amount of coins and community-currency (community-key) as type Money",
"reason for transfer" : "the transaction description",
"timestamp of transfer" : "date and time of transaction"
}
}
```
### Output-Data:
```
{
"result" : "result of a valid receive coins processing (perhaps gratitude of user or community), otherwise exception"
}
```
### Exceptions:
*WrongCommunityException* in case the receiver community didn't know the sender community.
*UnknownUserException* in case the receiver community has no user with the given receiver-user-id.
*MissingTxDetailException* in case of missing one or more attributes in the TransactionTO,
*InvalidCurrencyException* in case the currency (community-key) doesn't match with the sender-community.
*InvalidTxTimeException* in case the timestamp of transfer is in the past.
*DenyTxException* in case the receiver community or user will not interact with the sender community or user.
## Service: "get Activity List"
This service can be used to read the activity list of another community. A community supports a list of activities a member can select to create gradidos for his actions. Each activity has an attribute *topic* on which the list reading can be filtered.
### Route:
GET https://<Other_Community_URL>/getActivityList/`<security-accesstoken>`
### Input-Data:
```
{
"topics" : "list of topics the reading of the activity list should be filtered by"
}
```
### Output-Data:
```
{
"activities" : "list of found activity, which match the input-data"
}
```
### Exceptions:
## Service: "get Clearing Activities"
This service can be used to read open activities of other community members, which are open to be cleared by other users. This base on the concept to clear at least two or more activities of other users before the amount of gradidos of the own activity can be credit on the own AGE account.
### Route:
GET https://<Other_Community_URL>/getClearingActivities/`<security-accesstoken>`
### Input-Data:
### Output-Data:
### Exceptions:
## Service: "Clear Activity"
This service can be used to clear an open activity, which was read by the service getClearingActivies before. This base on the concept to clear at least two or more activities of other users before the amount of gradidos of the own activity can be credit on the own AGE account.
### Route:
### Input-Data:
### Output-Data:
### Exceptions:

View File

@ -0,0 +1,32 @@
# Federation
This document contains the concept and technical details for the *federation* of gradido communities. It base on the [ActivityPub specification](https://www.w3.org/TR/activitypub/ " ") and is extended for the gradido requirements.
## ActivityPub
The activity pub defines a server-to-server federation protocol to share information between decentralized instances and will be the main komponent for the gradido community federation.
At first we asume a *gradido community* as an *ActivityPub user*. A user is represented by "*actors*" via the users's accounts on servers. User's accounts on different servers corrsponds to different actors, which means community accounts on different servers corrsponds to different communities.
Every community (actor) has an:
* inbox: to get messages from the world
* outbox: to send messages to others
and are simple endpoints or just URLs, which are described in the *ActivityStream* of each *ActivityPub community*.
### Open Decision:
It has to be decided, if the Federation will work with an internal or with external ActivityPub-Server, as shown in the picture below:
![FederationActivityPub](./image/FederationActivityPub.png " ")
The Variant A with an internal server contains the benefit to be as independent as possible from third party service providers and will not cause additional hosting costs. But this solution will cause the additional efforts of impementing an ActivityPub-Server in the gradido application and the responsibility for this component.
The Varaint B with an external server contains the benefit to reduce the implementation efforts and the responsibility for an own ActivitPub-Server. But it will cause an additional dependency to a third party service provider and the growing hosting costs.
## ActivityStream
An ActivityStream includes all definitions and terms needed for community activities and content flow around the gradido community network.

View File

@ -0,0 +1,224 @@
<mxfile host="65bd71144e">
<diagram id="Qdxn-o_uMU4q21qeaE9f" name="Seite-1">
<mxGraphModel dx="1088" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="2336" pageHeight="1654" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="gradido application" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;verticalAlign=top;fontStyle=1;fontSize=16;" vertex="1" parent="1">
<mxGeometry x="160" y="120" width="640" height="370" as="geometry"/>
</mxCell>
<mxCell id="19" value="Federation Service" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;verticalAlign=top;fontStyle=1;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="200" y="170" width="240" height="270" as="geometry"/>
</mxCell>
<mxCell id="16" value="&amp;nbsp;intern ActivityPub Server" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;verticalAlign=top;fontStyle=1;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="480" y="250" width="300" height="160" as="geometry"/>
</mxCell>
<mxCell id="3" value="INBOX" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="580" y="290" width="80" height="40" as="geometry"/>
</mxCell>
<mxCell id="4" value="OUTBOX" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="580" y="350" width="80" height="40" as="geometry"/>
</mxCell>
<mxCell id="5" value="" style="shape=flexArrow;endArrow=classic;html=1;endWidth=18.5;endSize=6.0825;width=17.5;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="570" y="309.5" as="sourcePoint"/>
<mxPoint x="490" y="310" as="targetPoint"/>
<Array as="points">
<mxPoint x="530" y="310"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="6" value="GET" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;labelBackgroundColor=none;" vertex="1" connectable="0" parent="5">
<mxGeometry x="-0.325" y="1" relative="1" as="geometry">
<mxPoint x="-3" y="-1" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="9" value="" style="shape=flexArrow;endArrow=classic;html=1;fontSize=12;width=21.75;endSize=6.1675;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="490" y="369.88" as="sourcePoint"/>
<mxPoint x="570" y="369.88" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="10" value="POST" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;labelBackgroundColor=none;" vertex="1" connectable="0" parent="9">
<mxGeometry x="-0.275" y="2" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="11" value="" style="shape=flexArrow;endArrow=classic;html=1;endWidth=18.5;endSize=6.0825;width=17.5;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="840" y="311" as="sourcePoint"/>
<mxPoint x="670" y="310.5" as="targetPoint"/>
<Array as="points">
<mxPoint x="710" y="310.5"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="12" value="POST" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;labelBackgroundColor=none;" vertex="1" connectable="0" parent="11">
<mxGeometry x="-0.325" y="1" relative="1" as="geometry">
<mxPoint x="-3" y="-1" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="13" value="" style="shape=flexArrow;endArrow=classic;html=1;fontSize=12;width=21.75;endSize=6.1675;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="670" y="370.38" as="sourcePoint"/>
<mxPoint x="840" y="370" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="14" value="GET" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;labelBackgroundColor=none;" vertex="1" connectable="0" parent="13">
<mxGeometry x="-0.275" y="2" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="15" value="Gradido &lt;br style=&quot;font-size: 15px;&quot;&gt;Community Network" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=15;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;fontStyle=1" vertex="1" parent="1">
<mxGeometry x="870" y="245" width="220" height="170" as="geometry"/>
</mxCell>
<mxCell id="20" value="newCommunity-Msg" style="rounded=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=14;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="255" y="340" width="175" height="30" as="geometry"/>
</mxCell>
<mxCell id="21" value="replyNewCommunity-Msg" style="rounded=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=14;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="255" y="250" width="175" height="30" as="geometry"/>
</mxCell>
<mxCell id="22" value="newCommunity-Msg" style="rounded=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=14;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="255" y="280" width="175" height="30" as="geometry"/>
</mxCell>
<mxCell id="23" value="" style="endArrow=classic;html=1;fontSize=14;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="21">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="490" y="310" as="sourcePoint"/>
<mxPoint x="550" y="330" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="24" value="" style="endArrow=classic;html=1;fontSize=14;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="22">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="490" y="310" as="sourcePoint"/>
<mxPoint x="440" y="275" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="25" value="" style="endArrow=classic;html=1;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="20">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="510" y="330" as="sourcePoint"/>
<mxPoint x="490" y="370" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="26" value="replyNewCommunity-Msg" style="rounded=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=14;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="255" y="370" width="175" height="30" as="geometry"/>
</mxCell>
<mxCell id="27" value="" style="endArrow=classic;html=1;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="26">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="440" y="365" as="sourcePoint"/>
<mxPoint x="490" y="370" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="28" value="gradido application" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;verticalAlign=top;fontStyle=1;fontSize=16;" vertex="1" parent="1">
<mxGeometry x="160" y="680" width="300" height="370" as="geometry"/>
</mxCell>
<mxCell id="29" value="Federation Service" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;verticalAlign=top;fontStyle=1;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="200" y="730" width="240" height="270" as="geometry"/>
</mxCell>
<mxCell id="30" value="extern ActivityPub Server" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e6d0de;gradientColor=#d5739d;strokeColor=#996185;verticalAlign=top;fontStyle=1;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="480" y="810" width="300" height="160" as="geometry"/>
</mxCell>
<mxCell id="31" value="INBOX" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="580" y="850" width="80" height="40" as="geometry"/>
</mxCell>
<mxCell id="32" value="OUTBOX" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;gradientColor=#7ea6e0;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="580" y="910" width="80" height="40" as="geometry"/>
</mxCell>
<mxCell id="33" value="" style="shape=flexArrow;endArrow=classic;html=1;endWidth=18.5;endSize=6.0825;width=17.5;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="570" y="869.5" as="sourcePoint"/>
<mxPoint x="490" y="870" as="targetPoint"/>
<Array as="points">
<mxPoint x="530" y="870"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="34" value="GET" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;labelBackgroundColor=none;" vertex="1" connectable="0" parent="33">
<mxGeometry x="-0.325" y="1" relative="1" as="geometry">
<mxPoint x="-3" y="-1" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="35" value="" style="shape=flexArrow;endArrow=classic;html=1;fontSize=12;width=21.75;endSize=6.1675;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="490" y="929.8800000000001" as="sourcePoint"/>
<mxPoint x="570" y="929.8800000000001" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="36" value="POST" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;labelBackgroundColor=none;" vertex="1" connectable="0" parent="35">
<mxGeometry x="-0.275" y="2" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="37" value="" style="shape=flexArrow;endArrow=classic;html=1;endWidth=18.5;endSize=6.0825;width=17.5;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="840" y="871" as="sourcePoint"/>
<mxPoint x="670" y="870.5" as="targetPoint"/>
<Array as="points">
<mxPoint x="710" y="870.5"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="38" value="POST" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;labelBackgroundColor=none;" vertex="1" connectable="0" parent="37">
<mxGeometry x="-0.325" y="1" relative="1" as="geometry">
<mxPoint x="-3" y="-1" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="39" value="" style="shape=flexArrow;endArrow=classic;html=1;fontSize=12;width=21.75;endSize=6.1675;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="670" y="930.3800000000001" as="sourcePoint"/>
<mxPoint x="840" y="930" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="40" value="GET" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=12;labelBackgroundColor=none;" vertex="1" connectable="0" parent="39">
<mxGeometry x="-0.275" y="2" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="41" value="Gradido &lt;br style=&quot;font-size: 15px;&quot;&gt;Community Network" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=15;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;fontStyle=1" vertex="1" parent="1">
<mxGeometry x="870" y="805" width="220" height="170" as="geometry"/>
</mxCell>
<mxCell id="42" value="newCommunity-Msg" style="rounded=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=14;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="255" y="900" width="175" height="30" as="geometry"/>
</mxCell>
<mxCell id="43" value="replyNewCommunity-Msg" style="rounded=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=14;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="255" y="810" width="175" height="30" as="geometry"/>
</mxCell>
<mxCell id="44" value="newCommunity-Msg" style="rounded=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=14;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="255" y="840" width="175" height="30" as="geometry"/>
</mxCell>
<mxCell id="45" value="" style="endArrow=classic;html=1;fontSize=14;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="43">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="490" y="870" as="sourcePoint"/>
<mxPoint x="550" y="890" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="46" value="" style="endArrow=classic;html=1;fontSize=14;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="44">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="490" y="870" as="sourcePoint"/>
<mxPoint x="440" y="835" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="47" value="" style="endArrow=classic;html=1;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="42">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="510" y="890" as="sourcePoint"/>
<mxPoint x="490" y="930" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="48" value="replyNewCommunity-Msg" style="rounded=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;fontSize=14;fillColor=#d5e8d4;gradientColor=#97d077;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="255" y="930" width="175" height="30" as="geometry"/>
</mxCell>
<mxCell id="49" value="" style="endArrow=classic;html=1;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="48">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="440" y="925" as="sourcePoint"/>
<mxPoint x="490" y="930" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="50" value="Variant A: Federation with an &quot;internal&quot; ActivityPub-Server" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;labelBackgroundColor=none;fontSize=16;fontStyle=1" vertex="1" parent="1">
<mxGeometry x="80" y="40" width="720" height="30" as="geometry"/>
</mxCell>
<mxCell id="51" value="Variant B: Federation with an &quot;external&quot; ActivityPub-Server" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;labelBackgroundColor=none;fontSize=16;fontStyle=1" vertex="1" parent="1">
<mxGeometry x="80" y="610" width="720" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

View File

@ -1,105 +1,108 @@
<mxfile host="65bd71144e">
<diagram id="IXdqiLGuknWCw5_Zijm2" name="Seite-1">
<mxGraphModel dx="1088" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="2336" pageHeight="1654" math="0" shadow="0">
<mxGraphModel dx="535" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="2336" pageHeight="1654" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="21" value="Gradido V1.2022" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;gradientColor=#97d077;" vertex="1" parent="1">
<mxCell id="21" value="Gradido V1.2022" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;gradientColor=#97d077;" parent="1" vertex="1">
<mxGeometry x="40" y="640" width="320" height="40" as="geometry"/>
</mxCell>
<mxCell id="22" value="Redesign RegisterProcess" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="22" value="Redesign RegisterProcess" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="80" y="680" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="23" value="Admin Area" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="23" value="Admin Area" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="80" y="700" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="24" value="Account Overview vs Send Coin" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="24" value="Account Overview vs Send Coin" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="80" y="720" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="25" value="Gradido V2.2022" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;gradientColor=#97d077;" vertex="1" parent="1">
<mxCell id="25" value="Gradido V2.2022" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;gradientColor=#97d077;" parent="1" vertex="1">
<mxGeometry x="400" y="560" width="320" height="40" as="geometry"/>
</mxCell>
<mxCell id="26" value="Community-Readyness 1st-Level (Basics)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="26" value="Community-Readyness 1st-Level (Basics)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="440" y="600" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="27" value="Account-Statistics 1st Level" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxGeometry x="440" y="620" width="280" height="20" as="geometry"/>
<mxCell id="27" value="Account-Statistics 1st Level" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="440" y="700" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="28" value="Marketing Multiplication" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="28" value="Marketing Multiplication" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="440" y="640" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="29" value="Gradido V3.2022" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;gradientColor=#97d077;" vertex="1" parent="1">
<mxCell id="29" value="Gradido V3.2022" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;gradientColor=#97d077;" parent="1" vertex="1">
<mxGeometry x="760" y="480" width="320" height="40" as="geometry"/>
</mxCell>
<mxCell id="30" value="Community-Readyness 2nd-Level&amp;nbsp;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="30" value="Community-Readyness 2nd-Level&amp;nbsp;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="800" y="520" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="31" value="Account-Statistics 2nd Level" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="31" value="Account-Statistics 2nd Level" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="800" y="540" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="32" value="Managed Kubernetes" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="32" value="Managed Kubernetes" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="800" y="560" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="33" value="Gradido V4.2022" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;gradientColor=#97d077;" vertex="1" parent="1">
<mxCell id="33" value="Gradido V4.2022" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;gradientColor=#97d077;" parent="1" vertex="1">
<mxGeometry x="1120" y="400" width="320" height="40" as="geometry"/>
</mxCell>
<mxCell id="34" value="Community-Readyness 3rd-Level&amp;nbsp;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="34" value="Community-Readyness 3rd-Level&amp;nbsp;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="1160" y="440" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="35" value="Marketing Multiplication" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="35" value="Marketing Multiplication" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="1160" y="460" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="36" value="Community Providing Services" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="36" value="Community Providing Services" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="1160" y="480" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="37" value="2022" style="rounded=1;whiteSpace=wrap;html=1;gradientColor=#b3b3b3;fillColor=#f5f5f5;strokeColor=#666666;fontSize=20;fontStyle=1" vertex="1" parent="1">
<mxCell id="37" value="2022" style="rounded=1;whiteSpace=wrap;html=1;gradientColor=#b3b3b3;fillColor=#f5f5f5;strokeColor=#666666;fontSize=20;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="40" y="280" width="1400" height="40" as="geometry"/>
</mxCell>
<mxCell id="38" value="" style="endArrow=none;html=1;entryX=0;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" target="37">
<mxCell id="38" value="" style="endArrow=none;html=1;entryX=0;entryY=1;entryDx=0;entryDy=0;" parent="1" target="37" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="40" y="760" as="sourcePoint"/>
<mxPoint x="580" y="550" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="39" value="" style="endArrow=none;html=1;entryX=0;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1">
<mxCell id="39" value="" style="endArrow=none;html=1;entryX=0;entryY=1;entryDx=0;entryDy=0;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="400" y="760" as="sourcePoint"/>
<mxPoint x="400.0000000000023" y="320" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="40" value="" style="endArrow=none;html=1;entryX=0;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1">
<mxCell id="40" value="" style="endArrow=none;html=1;entryX=0;entryY=1;entryDx=0;entryDy=0;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="760" y="760" as="sourcePoint"/>
<mxPoint x="760.0000000000023" y="320" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="41" value="" style="endArrow=none;html=1;entryX=0.771;entryY=1.063;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" target="37">
<mxCell id="41" value="" style="endArrow=none;html=1;entryX=0.771;entryY=1.063;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" target="37" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1120" y="760" as="sourcePoint"/>
<mxPoint x="1130" y="340" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="42" value="&lt;font style=&quot;font-size: 18px&quot;&gt;&lt;b&gt;Q.1&amp;nbsp;&lt;/b&gt;&lt;/font&gt;" style="text;html=1;strokeColor=#666666;fillColor=#f5f5f5;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#333333;" vertex="1" parent="1">
<mxCell id="42" value="&lt;font style=&quot;font-size: 18px&quot;&gt;&lt;b&gt;Q.1&amp;nbsp;&lt;/b&gt;&lt;/font&gt;" style="text;html=1;strokeColor=#666666;fillColor=#f5f5f5;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="50.000000000002274" y="330" width="40" height="20" as="geometry"/>
</mxCell>
<mxCell id="43" value="&lt;font style=&quot;font-size: 18px&quot;&gt;&lt;b&gt;Q.2&amp;nbsp;&lt;/b&gt;&lt;/font&gt;" style="text;html=1;strokeColor=#666666;fillColor=#f5f5f5;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#333333;" vertex="1" parent="1">
<mxCell id="43" value="&lt;font style=&quot;font-size: 18px&quot;&gt;&lt;b&gt;Q.2&amp;nbsp;&lt;/b&gt;&lt;/font&gt;" style="text;html=1;strokeColor=#666666;fillColor=#f5f5f5;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="410.0000000000023" y="330" width="40" height="20" as="geometry"/>
</mxCell>
<mxCell id="44" value="&lt;font style=&quot;font-size: 18px&quot;&gt;&lt;b&gt;Q.3&amp;nbsp;&lt;/b&gt;&lt;/font&gt;" style="text;html=1;strokeColor=#666666;fillColor=#f5f5f5;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#333333;" vertex="1" parent="1">
<mxCell id="44" value="&lt;font style=&quot;font-size: 18px&quot;&gt;&lt;b&gt;Q.3&amp;nbsp;&lt;/b&gt;&lt;/font&gt;" style="text;html=1;strokeColor=#666666;fillColor=#f5f5f5;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="770.0000000000023" y="330" width="40" height="20" as="geometry"/>
</mxCell>
<mxCell id="45" value="&lt;font style=&quot;font-size: 18px&quot;&gt;&lt;b&gt;Q.4&amp;nbsp;&lt;/b&gt;&lt;/font&gt;" style="text;html=1;strokeColor=#666666;fillColor=#f5f5f5;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#333333;" vertex="1" parent="1">
<mxCell id="45" value="&lt;font style=&quot;font-size: 18px&quot;&gt;&lt;b&gt;Q.4&amp;nbsp;&lt;/b&gt;&lt;/font&gt;" style="text;html=1;strokeColor=#666666;fillColor=#f5f5f5;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#333333;" parent="1" vertex="1">
<mxGeometry x="1130.0000000000023" y="330" width="40" height="20" as="geometry"/>
</mxCell>
<mxCell id="46" value="Multi Language Support" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="46" value="Multi Language Support" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="440" y="660" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="47" value="One-Database 1st Level" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxGeometry x="440" y="680" width="280" height="20" as="geometry"/>
<mxCell id="47" value="One-Database 1st Level" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="440" y="620" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="48" value="One-Database 2nd Level" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxCell id="48" value="One-Database 2nd Level" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" parent="1" vertex="1">
<mxGeometry x="800" y="580" width="280" height="20" as="geometry"/>
</mxCell>
<mxCell id="49" value="Admin Interface Usertool" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
<mxGeometry x="440" y="680" width="280" height="20" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 94 KiB

View File

@ -1,3 +1,5 @@
CONFIG_VERSION=v1.2022-03-18
META_URL=http://localhost
META_TITLE_DE="Gradido Dein Dankbarkeitskonto"
META_TITLE_EN="Gradido - Your gratitude account"

View File

@ -1,3 +1,5 @@
CONFIG_VERSION=$FRONTEND_CONFIG_VERSION
META_URL=$META_URL
META_TITLE_DE=$META_TITLE_DE
META_TITLE_EN=$META_TITLE_EN

View File

@ -1,10 +1,12 @@
import { mount } from '@vue/test-utils'
import TransactionForm from './TransactionForm'
import flushPromises from 'flush-promises'
import { SEND_TYPES } from '@/pages/Send.vue'
import DashboardLayout from '@/layouts/DashboardLayout_gdd.vue'
const localVue = global.localVue
describe('GddSend', () => {
describe('TransactionForm', () => {
let wrapper
const mocks = {
@ -25,7 +27,12 @@ describe('GddSend', () => {
}
const Wrapper = () => {
return mount(TransactionForm, { localVue, mocks, propsData })
return mount(TransactionForm, {
localVue,
mocks,
propsData,
provide: DashboardLayout.provide,
})
}
describe('mount', () => {
@ -34,7 +41,7 @@ describe('GddSend', () => {
})
it('renders the component', () => {
expect(wrapper.find('div.transaction-form').exists()).toBeTruthy()
expect(wrapper.find('div.transaction-form').exists()).toBe(true)
})
describe('transaction form disable because balance 0,0 GDD', () => {
@ -51,31 +58,35 @@ describe('GddSend', () => {
expect(wrapper.find('.text-danger').text()).toBe('form.no_gdd_available')
})
it('has no reset button and no submit button ', () => {
expect(wrapper.find('.test-buttons').exists()).toBeFalsy()
expect(wrapper.find('.test-buttons').exists()).toBe(false)
})
})
describe('is selected: "send"', () => {
describe('send GDD', () => {
beforeEach(async () => {
// await wrapper.setData({
// selected: 'send',
// })
await wrapper.findAll('input[type="radio"]').at(0).setChecked()
})
it('has SEND_TYPES = send', () => {
expect(wrapper.vm.selected).toBe(SEND_TYPES.send)
})
describe('transaction form', () => {
beforeEach(() => {
wrapper.setProps({ balance: 100.0 })
})
describe('transaction form show because balance 100,0 GDD', () => {
it('has no warning message ', () => {
expect(wrapper.find('.errors').exists()).toBeFalsy()
expect(wrapper.find('.errors').exists()).toBe(false)
})
it('has a reset button', () => {
expect(wrapper.find('.test-buttons').findAll('button').at(0).attributes('type')).toBe(
'reset',
)
})
it('has a submit button', () => {
expect(wrapper.find('.test-buttons').findAll('button').at(1).attributes('type')).toBe(
'submit',
@ -110,6 +121,12 @@ describe('GddSend', () => {
expect(wrapper.find('span.errors').text()).toBe('validations.messages.email')
})
it('flushes an error message when email is the email of logged in user', async () => {
await wrapper.find('#input-group-1').find('input').setValue('user@example.org')
await flushPromises()
expect(wrapper.find('span.errors').text()).toBe('form.validation.is-not')
})
it('trims the email after blur', async () => {
await wrapper.find('#input-group-1').find('input').setValue(' valid@email.com ')
await wrapper.find('#input-group-1').find('input').trigger('blur')
@ -159,13 +176,13 @@ describe('GddSend', () => {
it('flushes no errors when amount is valid', async () => {
await wrapper.find('#input-group-2').find('input').setValue('87.34')
await flushPromises()
expect(wrapper.find('span.errors').exists()).toBeFalsy()
expect(wrapper.find('span.errors').exists()).toBe(false)
})
})
describe('message text box', () => {
it('has an textarea field', () => {
expect(wrapper.find('#input-group-3').find('textarea').exists()).toBeTruthy()
expect(wrapper.find('#input-group-3').find('textarea').exists()).toBe(true)
})
it('has an chat-right-text icon', () => {
@ -184,16 +201,51 @@ describe('GddSend', () => {
expect(wrapper.find('span.errors').text()).toBe('validations.messages.min')
})
it('flushes an error message when memo is more than 255 characters', async () => {
await wrapper.find('#input-group-3').find('textarea').setValue(`
Es ist ein König in Thule, der trinkt
Champagner, es geht ihm nichts drüber;
Und wenn er seinen Champagner trinkt,
Dann gehen die Augen ihm über.
Die Ritter sitzen um ihn her,
Die ganze Historische Schule;
Ihm aber wird die Zunge schwer,
Es lallt der König von Thule:
Als Alexander, der Griechenheld,
Mit seinem kleinen Haufen
Erobert hatte die ganze Welt,
Da gab er sich ans Saufen.
Ihn hatten so durstig gemacht der Krieg
Und die Schlachten, die er geschlagen;
Er soff sich zu Tode nach dem Sieg,
Er konnte nicht viel vertragen.
Ich aber bin ein stärkerer Mann
Und habe mich klüger besonnen:
Wie jener endete, fang ich an,
Ich hab mit dem Trinken begonnen.
Im Rausche wird der Heldenzug
Mir später weit besser gelingen;
Dann werde ich, taumelnd von Krug zu Krug,
Die ganze Welt bezwingen.`)
await flushPromises()
expect(wrapper.find('span.errors').text()).toBe('validations.messages.max')
})
it('flushes no error message when memo is valid', async () => {
await wrapper.find('#input-group-3').find('textarea').setValue('Long enough')
await flushPromises()
expect(wrapper.find('span.errors').exists()).toBeFalsy()
expect(wrapper.find('span.errors').exists()).toBe(false)
})
})
describe('cancel button', () => {
it('has a cancel button', () => {
expect(wrapper.find('button[type="reset"]').exists()).toBeTruthy()
expect(wrapper.find('button[type="reset"]').exists()).toBe(true)
})
it('has the text "form.cancel"', () => {
@ -242,16 +294,17 @@ describe('GddSend', () => {
})
})
describe('is selected: "link"', () => {
describe('create transaction link', () => {
beforeEach(async () => {
// await wrapper.setData({
// selected: 'link',
// })
await wrapper.findAll('input[type="radio"]').at(1).setChecked()
})
it('has SEND_TYPES = link', () => {
expect(wrapper.vm.selected).toBe(SEND_TYPES.link)
})
it('has no input field of id input-group-1', () => {
expect(wrapper.find('#input-group-1').isVisible()).toBeFalsy()
expect(wrapper.find('#input-group-1').exists()).toBe(false)
})
})
})

View File

@ -16,16 +16,15 @@
</b-form-radio>
</b-col>
</b-row>
<div class="mt-4" v-show="selected === sendTypes.link">
<div class="mt-4" v-if="selected === sendTypes.link">
<h2 class="alert-heading">{{ $t('gdd_per_link.header') }}</h2>
<div>
{{ $t('gdd_per_link.choose-amount') }}
</div>
</div>
<div>
<div v-if="selected === sendTypes.send">
<validation-provider
v-show="selected === sendTypes.send"
name="Email"
:rules="{
required: selected === sendTypes.send ? true : false,
@ -62,9 +61,7 @@
</validation-provider>
</div>
<br />
<div>
<div class="mt-4 mb-4">
<validation-provider
:name="$t('form.amount')"
:rules="{
@ -97,12 +94,12 @@
</validation-provider>
</div>
<div class="mt-4">
<div class="mb-4">
<validation-provider
:rules="{
required: true,
min: 5,
max: 150,
max: 255,
}"
:name="$t('form.message')"
v-slot="{ errors }"
@ -125,7 +122,7 @@
</b-col>
</validation-provider>
</div>
<br />
<div v-if="!!isBalanceDisabled" class="text-danger">
{{ $t('form.no_gdd_available') }}
</div>
@ -141,7 +138,6 @@
</b-button>
</b-col>
</b-row>
<br />
</b-form>
</validation-observer>
@ -160,15 +156,19 @@ export default {
},
props: {
balance: { type: Number, default: 0 },
email: { type: String, default: '' },
amount: { type: Number, default: 0 },
memo: { type: String, default: '' },
},
inject: ['getTunneledEmail'],
data() {
return {
amountFocused: false,
emailFocused: false,
form: {
email: '',
amount: '',
memo: '',
email: this.email,
amount: this.amount ? String(this.amount) : '',
memo: this.memo,
amountValue: 0.0,
},
selected: SEND_TYPES.send,
@ -208,6 +208,12 @@ export default {
sendTypes() {
return SEND_TYPES
},
recipientEmail() {
return this.getTunneledEmail()
},
},
created() {
this.form.email = this.recipientEmail ? this.recipientEmail : ''
},
}
</script>

View File

@ -31,7 +31,7 @@
</template>
<script>
export default {
name: 'TransactionResultSend',
name: 'TransactionResultSendError',
props: {
error: { type: Boolean, default: false },
errorResult: { type: String, default: '' },

View File

@ -3,10 +3,6 @@ import GddTransactionList from './GddTransactionList'
const localVue = global.localVue
const errorHandler = jest.fn()
localVue.config.errorHandler = errorHandler
const scrollToMock = jest.fn()
global.scrollTo = scrollToMock

View File

@ -23,6 +23,7 @@
class="list-group-item"
v-bind="transactions[index]"
:decayStartBlock="decayStartBlock"
v-on="$listeners"
/>
</template>
@ -31,6 +32,7 @@
class="list-group-item"
v-bind="transactions[index]"
:decayStartBlock="decayStartBlock"
v-on="$listeners"
/>
</template>
@ -39,6 +41,7 @@
class="list-group-item"
v-bind="transactions[index]"
:decayStartBlock="decayStartBlock"
v-on="$listeners"
/>
</template>

View File

@ -0,0 +1,75 @@
import { mount } from '@vue/test-utils'
import AmountAndNameRow from './AmountAndNameRow'
const localVue = global.localVue
const mocks = {
$router: {
push: jest.fn(),
},
}
const propsData = {
amount: '19.99',
text: 'Some text',
}
describe('AmountAndNameRow', () => {
let wrapper
const Wrapper = () => {
return mount(AmountAndNameRow, { localVue, mocks, propsData })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders the component', () => {
expect(wrapper.find('div.amount-and-name-row').exists()).toBe(true)
})
describe('without linked user', () => {
it('has a span with the text', () => {
expect(wrapper.find('div.gdd-transaction-list-item-name').text()).toBe('Some text')
})
it('has no link', () => {
expect(wrapper.find('div.gdd-transaction-list-item-name').find('a').exists()).toBe(false)
})
})
describe('with linked user', () => {
beforeEach(async () => {
await wrapper.setProps({
linkedUser: { firstName: 'Bibi', lastName: 'Bloxberg', email: 'bibi@bloxberg.de' },
})
})
it('has a link with first and last name', () => {
expect(wrapper.find('div.gdd-transaction-list-item-name').text()).toBe('Bibi Bloxberg')
})
it('has a link', () => {
expect(wrapper.find('div.gdd-transaction-list-item-name').find('a').exists()).toBe(true)
})
describe('click link', () => {
beforeEach(async () => {
await wrapper.find('div.gdd-transaction-list-item-name').find('a').trigger('click')
})
it('emits set tunneled email', () => {
expect(wrapper.emitted('set-tunneled-email')).toEqual([['bibi@bloxberg.de']])
})
it('pushes the route with query for email', () => {
expect(mocks.$router.push).toBeCalledWith({
path: '/send',
})
})
})
})
})
})

View File

@ -10,7 +10,21 @@
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-name">
{{ itemText }}
<div v-if="linkedUser && linkedUser.email">
<b-link @click.stop="tunnelEmail">
{{ itemText }}
</b-link>
<span v-if="transactionLinkId">
{{ $t('via_link') }}
<b-icon
icon="link45deg"
variant="muted"
class="m-mb-1"
:title="$t('gdd_per_link.redeemed-title')"
/>
</span>
</div>
<span v-else>{{ itemText }}</span>
</div>
</b-col>
</b-row>
@ -32,6 +46,17 @@ export default {
type: String,
required: false,
},
transactionLinkId: {
type: Number,
required: false,
default: null,
},
},
methods: {
tunnelEmail() {
this.$emit('set-tunneled-email', this.linkedUser.email)
this.$router.push({ path: '/send' })
},
},
computed: {
itemText() {

View File

@ -12,7 +12,7 @@
<b-col cols="11">
<!-- Amount / Name || Text -->
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" />
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" v-on="$listeners" />
<!-- Nachricht Memo -->
<memo-row :memo="memo" />

View File

@ -13,7 +13,12 @@
<b-col cols="11">
<!-- Amount / Name || Text -->
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" />
<amount-and-name-row
v-on="$listeners"
:amount="amount"
:linkedUser="linkedUser"
:transactionLinkId="transactionLinkId"
/>
<!-- Nachricht Memo -->
<memo-row :memo="memo" />
@ -86,6 +91,10 @@ export default {
type: Date,
required: true,
},
transactionLinkId: {
type: Number,
required: false,
},
},
data() {
return {

View File

@ -13,7 +13,12 @@
<b-col cols="11">
<!-- Amount / Name -->
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" />
<amount-and-name-row
v-on="$listeners"
:amount="amount"
:linkedUser="linkedUser"
:transactionLinkId="transactionLinkId"
/>
<!-- Memo -->
<memo-row :memo="memo" />
@ -87,6 +92,10 @@ export default {
type: Date,
required: true,
},
transactionLinkId: {
type: Number,
required: false,
},
},
data() {
return {

View File

@ -4,11 +4,19 @@
// Load Package Details for some default values
const pkg = require('../../package')
const constants = {
CONFIG_VERSION: {
DEFAULT: 'DEFAULT',
EXPECTED: 'v1.2022-03-18',
CURRENT: '',
},
}
const version = {
APP_VERSION: pkg.version,
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').substr(0, 7),
BUILD_COMMIT_SHORT: (process.env.BUILD_COMMIT || '0000000').slice(0, 7),
}
const environment = {
@ -16,39 +24,51 @@ const environment = {
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 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_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 ||
// '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 ||
// '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 ||
// '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',
// }
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_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 ||
'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 ||
'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 ||
'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',
}
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}',
}
const options = {}
// Check config version
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,
)
) {
throw new Error(
`Fatal: Config Version incorrect - expected "${constants.CONFIG_VERSION.EXPECTED}" or "${constants.CONFIG_VERSION.DEFAULT}", but found "${constants.CONFIG_VERSION.CURRENT}"`,
)
}
const CONFIG = {
...constants,
...version,
...environment,
...endpoints,
...options,
...meta,
}
export default CONFIG
module.exports = CONFIG

View File

@ -45,6 +45,7 @@ export const createUser = gql`
$email: String!
$language: String!
$publisherId: Int
$redeemCode: String
) {
createUser(
email: $email
@ -52,6 +53,7 @@ export const createUser = gql`
lastName: $lastName
language: $language
publisherId: $publisherId
redeemCode: $redeemCode
) {
id
}

View File

@ -67,6 +67,10 @@ export const transactionsQuery = gql`
end
duration
}
linkedUser {
email
}
transactionLinkId
}
}
}

View File

@ -140,14 +140,6 @@ describe('DashboardLayoutGdd', () => {
})
})
describe('update balance', () => {
it('updates the amount correctelly', async () => {
await wrapper.findComponent({ ref: 'router-view' }).vm.$emit('update-balance', 5)
await flushPromises()
expect(wrapper.vm.balance).toBe(-5)
})
})
describe('update transactions', () => {
beforeEach(async () => {
apolloMock.mockResolvedValue({
@ -284,5 +276,14 @@ describe('DashboardLayoutGdd', () => {
})
})
})
describe('set tunneled email', () => {
it('updates tunneled email', async () => {
await wrapper
.findComponent({ ref: 'router-view' })
.vm.$emit('set-tunneled-email', 'bibi@bloxberg.de')
expect(wrapper.vm.tunneledEmail).toBe('bibi@bloxberg.de')
})
})
})
})

View File

@ -27,8 +27,8 @@
:transactionLinkCount="transactionLinkCount"
:pending="pending"
:decayStartBlock="decayStartBlock"
@update-balance="updateBalance"
@update-transactions="updateTransactions"
@set-tunneled-email="setTunneledEmail"
></router-view>
</fade-transition>
</div>
@ -64,6 +64,12 @@ export default {
pending: true,
visible: false,
decayStartBlock: new Date(),
tunneledEmail: null,
}
},
provide() {
return {
getTunneledEmail: () => this.tunneledEmail,
}
},
methods: {
@ -112,9 +118,6 @@ export default {
// what to do when loading balance fails?
})
},
updateBalance(ammount) {
this.balance -= ammount
},
admin() {
window.location.assign(CONFIG.ADMIN_AUTH_URL.replace('{token}', this.$store.state.token))
this.$store.dispatch('logout') // logout without redirect
@ -122,6 +125,9 @@ export default {
setVisible(bool) {
this.visible = bool
},
setTunneledEmail(email) {
this.tunneledEmail = email
},
},
computed: {
elopageUri() {

View File

@ -116,6 +116,7 @@
"redeem-text": "Willst du den Betrag jetzt einlösen?",
"redeemed": "Erfolgreich eingelöst! Deinem Konto wurden {n} GDD gutgeschrieben.",
"redeemed-at": "Der Link wurde bereits am {date} eingelöst.",
"redeemed-title": "eingelöst",
"to-login": "Log dich ein",
"to-register": "Registriere ein neues Konto"
},
@ -249,5 +250,6 @@
},
"transaction-link": {
"send_you": "sendet dir"
}
},
"via_link": "über einen Link"
}

View File

@ -116,6 +116,7 @@
"redeem-text": "Do you want to redeem the amount now?",
"redeemed": "Successfully redeemed! Your account has been credited with {n} GDD.",
"redeemed-at": "The link was already redeemed on {date}.",
"redeemed-title": "redeemed",
"to-login": "Log in",
"to-register": "Register a new account"
},
@ -249,5 +250,6 @@
},
"transaction-link": {
"send_you": "wants to send you"
}
},
"via_link": "via Link"
}

View File

@ -22,6 +22,7 @@
:transaction-count="transactionCount"
:transactionLinkCount="transactionLinkCount"
@update-transactions="updateTransactions"
v-on="$listeners"
/>
<gdd-transaction-list-footer :count="transactionCount" />
</div>

View File

@ -54,25 +54,27 @@ describe('ResetPassword', () => {
describe('mount', () => {
beforeEach(() => {
jest.clearAllMocks()
wrapper = Wrapper()
})
describe('No valid optin', () => {
it.skip('does not render the Reset Password form when not authenticated', () => {
expect(wrapper.find('form').exists()).toBeFalsy()
describe('no valid optin', () => {
beforeEach(() => {
jest.clearAllMocks()
apolloQueryMock.mockRejectedValue({ message: 'Your time is up!' })
wrapper = Wrapper()
})
it.skip('toasts an error when no valid optin is given', () => {
expect(toastErrorSpy).toHaveBeenCalledWith('error')
it('toasts an error when no valid optin is given', () => {
expect(toastErrorSpy).toHaveBeenCalledWith('Your time is up!')
})
it.skip('has a message suggesting to contact the support', () => {
expect(wrapper.find('div.header').text()).toContain('settings.password.reset')
expect(wrapper.find('div.header').text()).toContain('settings.password.not-authenticated')
it('redirects to /forgot-password/resetPassword', () => {
expect(routerPushMock).toBeCalledWith('/forgot-password/resetPassword')
})
})
describe('is authenticated', () => {
describe('valid optin', () => {
it('renders the Reset Password form when authenticated', () => {
expect(wrapper.find('div.resetpwd-form').exists()).toBeTruthy()
})
@ -167,7 +169,7 @@ describe('ResetPassword', () => {
})
})
describe('server response with error code > 10min', () => {
describe('server response with error', () => {
beforeEach(async () => {
jest.clearAllMocks()
apolloMutationMock.mockRejectedValueOnce({ message: 'Error' })
@ -182,6 +184,7 @@ describe('ResetPassword', () => {
describe('server response with success on /checkEmail', () => {
beforeEach(async () => {
jest.clearAllMocks()
mocks.$route.path.mock = 'checkEmail'
apolloMutationMock.mockResolvedValue({
data: {
@ -208,6 +211,28 @@ describe('ResetPassword', () => {
it('redirects to "/thx/checkEmail"', () => {
expect(routerPushMock).toHaveBeenCalledWith('/thx/checkEmail')
})
describe('with param code', () => {
beforeEach(async () => {
mocks.$route.params.code = 'the-most-secret-code-ever'
apolloMutationMock.mockResolvedValue({
data: {
resetPassword: 'success',
},
})
wrapper = Wrapper()
await wrapper.findAll('input').at(0).setValue('Aa123456_')
await wrapper.findAll('input').at(1).setValue('Aa123456_')
await wrapper.find('form').trigger('submit')
await flushPromises()
})
it('redirects to "/thx/checkEmail/the-most-secret-code-ever"', () => {
expect(routerPushMock).toHaveBeenCalledWith(
'/thx/checkEmail/the-most-secret-code-ever',
)
})
})
})
describe('server response with success on /reset-password', () => {

View File

@ -6,11 +6,11 @@
<b-row class="justify-content-center">
<b-col xl="5" lg="6" md="8" class="px-2">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<h1>{{ $t(displaySetup.authenticated) }}</h1>
<h1>{{ $t(displaySetup.title) }}</h1>
<div class="pb-4">
<span>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
{{ $t(displaySetup.notAuthenticated) }}
{{ $t(displaySetup.text) }}
</span>
</div>
</b-col>
@ -53,14 +53,14 @@ import { queryOptIn } from '@/graphql/queries'
const textFields = {
reset: {
authenticated: 'settings.password.change-password',
notAuthenticated: 'settings.password.reset-password.text',
title: 'settings.password.change-password',
text: 'settings.password.reset-password.text',
button: 'settings.password.change-password',
linkTo: '/login',
},
checkEmail: {
authenticated: 'settings.password.set',
notAuthenticated: 'settings.password.set-password.text',
title: 'settings.password.set',
text: 'settings.password.set-password.text',
button: 'settings.password.set',
linkTo: '/login',
},
@ -97,7 +97,11 @@ export default {
.then(() => {
this.form.password = ''
if (this.$route.path.includes('checkEmail')) {
this.$router.push('/thx/checkEmail')
if (this.$route.params.code) {
this.$router.push('/thx/checkEmail/' + this.$route.params.code)
} else {
this.$router.push('/thx/checkEmail')
}
} else {
this.$router.push('/thx/resetPassword')
}

View File

@ -3,6 +3,7 @@ import Send, { SEND_TYPES } from './Send'
import { toastErrorSpy, toastSuccessSpy } from '@test/testSetup'
import { TRANSACTION_STEPS } from '@/components/GddSend.vue'
import { sendCoins, createTransactionLink } from '@/graphql/mutations.js'
import DashboardLayout from '@/layouts/DashboardLayout_gdd.vue'
const apolloMutationMock = jest.fn()
apolloMutationMock.mockResolvedValue('success')
@ -17,9 +18,7 @@ describe('Send', () => {
const propsData = {
balance: 123.45,
GdtBalance: 1234.56,
transactions: [{ balance: 0.1 }],
pending: true,
currentTransactionStep: TRANSACTION_STEPS.transactionConfirmationSend,
}
const mocks = {
@ -33,10 +32,18 @@ describe('Send', () => {
$apollo: {
mutate: apolloMutationMock,
},
$route: {
query: {},
},
}
const Wrapper = () => {
return mount(Send, { localVue, mocks, propsData })
return mount(Send, {
localVue,
mocks,
propsData,
provide: DashboardLayout.provide,
})
}
describe('mount', () => {
@ -45,11 +52,10 @@ describe('Send', () => {
})
it('has a send field', () => {
expect(wrapper.find('div.gdd-send').exists()).toBeTruthy()
expect(wrapper.find('div.gdd-send').exists()).toBe(true)
})
/* SEND */
describe('transaction form send', () => {
describe('fill transaction form for send coins', () => {
beforeEach(async () => {
wrapper.findComponent({ name: 'TransactionForm' }).vm.$emit('set-transaction', {
email: 'user@example.org',
@ -58,86 +64,93 @@ describe('Send', () => {
selected: SEND_TYPES.send,
})
})
it('steps forward in the dialog', () => {
expect(wrapper.findComponent({ name: 'TransactionConfirmationSend' }).exists()).toBe(true)
})
})
describe('confirm transaction if selected: SEND_TYPES.send', () => {
beforeEach(() => {
wrapper.setData({
currentTransactionStep: TRANSACTION_STEPS.transactionConfirmationSend,
transactionData: {
email: 'user@example.org',
amount: 23.45,
memo: 'Make the best of it!',
selected: SEND_TYPES.send,
},
})
})
describe('confirm transaction view', () => {
describe('cancel confirmation', () => {
beforeEach(async () => {
await wrapper
.findComponent({ name: 'TransactionConfirmationSend' })
.vm.$emit('on-reset')
})
it('resets the transaction process when on-reset is emitted', async () => {
await wrapper.findComponent({ name: 'TransactionConfirmationSend' }).vm.$emit('on-reset')
expect(wrapper.findComponent({ name: 'TransactionForm' }).exists()).toBeTruthy()
expect(wrapper.vm.transactionData).toEqual({
email: 'user@example.org',
amount: 23.45,
memo: 'Make the best of it!',
selected: SEND_TYPES.send,
})
})
it('shows the transaction formular again', () => {
expect(wrapper.findComponent({ name: 'TransactionForm' }).exists()).toBe(true)
})
describe('transaction is confirmed and server response is success', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper
.findComponent({ name: 'TransactionConfirmationSend' })
.vm.$emit('send-transaction')
it('restores the previous data in the formular', () => {
/* expect(wrapper.find('#input-group-1').find('input').vm.$el.value).toBe(
'user@example.org',
)
*/
expect(wrapper.find('#input-group-2').find('input').vm.$el.value).toBe('23.45')
expect(wrapper.find('#input-group-3').find('textarea').vm.$el.value).toBe(
'Make the best of it!',
)
})
})
it('calls the API when send-transaction is emitted', async () => {
expect(apolloMutationMock).toBeCalledWith(
expect.objectContaining({
mutation: sendCoins,
variables: {
email: 'user@example.org',
amount: 23.45,
memo: 'Make the best of it!',
selected: SEND_TYPES.send,
},
}),
)
describe('confirm transaction with server succees', () => {
beforeEach(async () => {
jest.clearAllMocks()
await wrapper
.findComponent({ name: 'TransactionConfirmationSend' })
.vm.$emit('send-transaction')
})
it('calls the API when send-transaction is emitted', async () => {
expect(apolloMutationMock).toBeCalledWith(
expect.objectContaining({
mutation: sendCoins,
variables: {
email: 'user@example.org',
amount: 23.45,
memo: 'Make the best of it!',
selected: SEND_TYPES.send,
},
}),
)
})
it('emits update transactions', () => {
expect(wrapper.emitted('update-transactions')).toBeTruthy()
expect(wrapper.emitted('update-transactions')).toEqual(expect.arrayContaining([[{}]]))
})
it('shows the success page', () => {
expect(wrapper.find('div.card-body').text()).toContain('form.send_transaction_success')
})
})
it('emits update-balance', () => {
expect(wrapper.emitted('update-balance')).toBeTruthy()
expect(wrapper.emitted('update-balance')).toEqual([[23.45]])
})
describe('confirm transaction with server error', () => {
beforeEach(async () => {
jest.clearAllMocks()
apolloMutationMock.mockRejectedValue({ message: 'recipient not known' })
await wrapper
.findComponent({ name: 'TransactionConfirmationSend' })
.vm.$emit('send-transaction')
})
it('shows the success page', () => {
expect(wrapper.find('div.card-body').text()).toContain('form.send_transaction_success')
})
})
it('has a component TransactionResultSendError', () => {
expect(wrapper.findComponent({ name: 'TransactionResultSendError' }).exists()).toBe(
true,
)
})
describe('transaction is confirmed and server response is error', () => {
beforeEach(async () => {
jest.clearAllMocks()
apolloMutationMock.mockRejectedValue({ message: 'recipient not known' })
await wrapper
.findComponent({ name: 'TransactionConfirmationSend' })
.vm.$emit('send-transaction')
})
it('has an standard error text', () => {
expect(wrapper.find('.test-send_transaction_error').text()).toContain(
'form.send_transaction_error',
)
})
it('shows the error page', () => {
expect(wrapper.find('.test-send_transaction_error').text()).toContain(
'form.send_transaction_error',
)
})
it('shows recipient not found', () => {
expect(wrapper.find('.test-receiver-not-found').text()).toContain(
'transaction.receiverNotFound',
)
it('shows recipient not found', () => {
expect(wrapper.find('.test-receiver-not-found').text()).toContain(
'transaction.receiverNotFound',
)
})
})
})
})
@ -151,10 +164,11 @@ describe('Send', () => {
})
await wrapper.findComponent({ name: 'TransactionForm' }).vm.$emit('set-transaction', {
amount: 56.78,
memo: 'Make the best of it link!',
memo: 'Make the best of the link!',
selected: SEND_TYPES.link,
})
})
it('steps forward in the dialog', () => {
expect(wrapper.findComponent({ name: 'TransactionConfirmationLink' }).exists()).toBe(true)
})
@ -173,18 +187,18 @@ describe('Send', () => {
mutation: createTransactionLink,
variables: {
amount: 56.78,
memo: 'Make the best of it link!',
memo: 'Make the best of the link!',
},
}),
)
})
it.skip('emits update-balance', () => {
expect(wrapper.emitted('update-balance')).toBeTruthy()
expect(wrapper.emitted('update-balance')).toEqual([[56.78]])
it('emits update-transactions', () => {
expect(wrapper.emitted('update-transactions')).toBeTruthy()
expect(wrapper.emitted('update-transactions')).toEqual(expect.arrayContaining([[{}]]))
})
it('find components ClipBoard', () => {
it('finds the clip board component', () => {
expect(wrapper.findComponent({ name: 'ClipboardCopy' }).exists()).toBe(true)
})
@ -196,7 +210,7 @@ describe('Send', () => {
expect(wrapper.find('div.card-body').text()).toContain('form.close')
})
describe('Copy link to Clipboard', () => {
describe('copy link to clipboard', () => {
const navigatorClipboard = navigator.clipboard
beforeAll(() => {
delete navigator.clipboard
@ -251,5 +265,39 @@ describe('Send', () => {
})
})
})
describe('no field selected on send transaction', () => {
const errorHandler = localVue.config.errorHandler
beforeAll(() => {
localVue.config.errorHandler = jest.fn()
})
afterAll(() => {
localVue.config.errorHandler = errorHandler
})
beforeEach(async () => {
await wrapper.setData({
currentTransactionStep: TRANSACTION_STEPS.transactionConfirmationSend,
transactionData: {
email: 'user@example.org',
amount: 23.45,
memo: 'Make the best of it!',
selected: 'not-valid',
},
})
})
it('throws an error', async () => {
try {
await wrapper
.findComponent({ name: 'TransactionConfirmationSend' })
.vm.$emit('send-transaction')
} catch (error) {
expect(error).toBe('undefined transactionData.selected : not-valid')
}
})
})
})
})

View File

@ -3,7 +3,11 @@
<b-container>
<gdd-send :currentTransactionStep="currentTransactionStep" class="pt-3 ml-2 mr-2">
<template #transactionForm>
<transaction-form :balance="balance" @set-transaction="setTransaction"></transaction-form>
<transaction-form
v-bind="transactionData"
:balance="balance"
@set-transaction="setTransaction"
></transaction-form>
</template>
<template #transactionConfirmationSend>
<transaction-confirmation-send
@ -95,7 +99,6 @@ export default {
transactions: {
default: () => [],
},
pending: {
type: Boolean,
default: true,
@ -125,7 +128,9 @@ export default {
})
.then(() => {
this.error = false
this.$emit('update-balance', this.transactionData.amount)
this.$emit('set-tunneled-email', null)
this.updateTransactions({})
this.transactionData = { ...EMPTY_TRANSACTION_DATA }
this.currentTransactionStep = TRANSACTION_STEPS.transactionResultSendSuccess
})
.catch((err) => {
@ -141,8 +146,10 @@ export default {
variables: { amount: this.transactionData.amount, memo: this.transactionData.memo },
})
.then((result) => {
this.$emit('set-tunneled-email', null)
this.code = result.data.createTransactionLink.code
this.currentTransactionStep = TRANSACTION_STEPS.transactionResultLink
this.updateTransactions({})
})
.catch((error) => {
this.toastError(error)
@ -161,7 +168,7 @@ export default {
},
},
created() {
this.updateTransactions(0)
this.updateTransactions({})
},
}
</script>

View File

@ -12,6 +12,7 @@
:show-pagination="true"
:decayStartBlock="decayStartBlock"
@update-transactions="updateTransactions"
v-on="$listeners"
/>
</b-tab>

View File

@ -9,7 +9,11 @@
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<p class="h4">{{ $t(displaySetup.subtitle) }}</p>
<hr />
<b-button v-if="displaySetup.linkTo" :to="displaySetup.linkTo">
<b-button v-if="$route.params.code" :to="`/redeem/${$route.params.code}`">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
{{ $t(displaySetup.button) }}
</b-button>
<b-button v-else :to="displaySetup.linkTo">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
{{ $t(displaySetup.button) }}
</b-button>

View File

@ -112,7 +112,7 @@ describe('router', () => {
})
describe('thx', () => {
const thx = routes.find((r) => r.path === '/thx/:comingFrom')
const thx = routes.find((r) => r.path === '/thx/:comingFrom/:code?')
it('loads the "Thx" page', async () => {
const component = await thx.component()
@ -177,7 +177,9 @@ describe('router', () => {
describe('checkEmail', () => {
it('loads the "CheckEmail" page', async () => {
const component = await routes.find((r) => r.path === '/checkEmail/:optin').component()
const component = await routes
.find((r) => r.path === '/checkEmail/:optin/:code?')
.component()
expect(component.default.name).toBe('ResetPassword')
})
})

View File

@ -47,7 +47,7 @@ const routes = [
component: () => import('@/pages/Register.vue'),
},
{
path: '/thx/:comingFrom',
path: '/thx/:comingFrom/:code?',
component: () => import('@/pages/thx.vue'),
beforeEnter: (to, from, next) => {
const validFrom = ['forgot-password', 'reset-password', 'register', 'login', 'checkEmail']
@ -79,7 +79,7 @@ const routes = [
component: () => import('@/pages/ResetPassword.vue'),
},
{
path: '/checkEmail/:optin',
path: '/checkEmail/:optin/:code?',
component: () => import('@/pages/ResetPassword.vue'),
},
{

View File

@ -3,11 +3,12 @@ const webpack = require('webpack')
const Dotenv = require('dotenv-webpack')
const StatsPlugin = require('stats-webpack-plugin')
const HtmlWebpackPlugin = require('vue-html-webpack-plugin')
const CONFIG = require('./src/config')
// vue.config.js
module.exports = {
devServer: {
port: process.env.PORT || 3000,
port: CONFIG.PORT,
},
pluginOptions: {
i18n: {
@ -35,7 +36,7 @@ module.exports = {
// 'process.env.DOCKER_WORKDIR': JSON.stringify(process.env.DOCKER_WORKDIR),
// 'process.env.BUILD_DATE': JSON.stringify(process.env.BUILD_DATE),
// 'process.env.BUILD_VERSION': JSON.stringify(process.env.BUILD_VERSION),
'process.env.BUILD_COMMIT': JSON.stringify(process.env.BUILD_COMMIT),
'process.env.BUILD_COMMIT': JSON.stringify(CONFIG.BUILD_COMMIT),
// 'process.env.PORT': JSON.stringify(process.env.PORT),
}),
// generate webpack stats to allow analysis of the bundlesize
@ -44,14 +45,14 @@ module.exports = {
vue: true,
template: 'public/index.html',
meta: {
title_de: process.env.META_TITLE_DE,
title_en: process.env.META_TITLE_EN,
description_de: process.env.META_DESCRIPTION_DE,
description_en: process.env.META_DESCRIPTION_EN,
keywords_de: process.env.META_KEYWORDS_DE,
keywords_en: process.env.META_KEYWORDS_EN,
author: process.env.META_AUTHOR,
url: process.env.META_URL,
title_de: CONFIG.META_TITLE_DE,
title_en: CONFIG.META_TITLE_EN,
description_de: CONFIG.META_DESCRIPTION_DE,
description_en: CONFIG.META_DESCRIPTION_EN,
keywords_de: CONFIG.META_KEYWORDS_DE,
keywords_en: CONFIG.META_KEYWORDS_EN,
author: CONFIG.META_AUTHOR,
url: CONFIG.META_URL,
},
}),
],
@ -61,7 +62,7 @@ module.exports = {
},
css: {
// Enable CSS source maps.
sourceMap: process.env.NODE_ENV !== 'production',
sourceMap: CONFIG.NODE_ENV !== 'production',
},
outputDir: path.resolve(__dirname, './dist'),
}