diff --git a/dht-node/.env.template b/dht-node/.env.template index efe6158a6..a7603c15a 100644 --- a/dht-node/.env.template +++ b/dht-node/.env.template @@ -8,6 +8,10 @@ DB_PASSWORD=$DB_PASSWORD DB_DATABASE=gradido_community TYPEORM_LOGGING_RELATIVE_PATH=$TYPEORM_LOGGING_RELATIVE_PATH +# Community +COMMUNITY_NAME=$COMMUNITY_NAME +COMMUNITY_DESCRIPTION=$COMMUNITY_DESCRIPTION + # Federation FEDERATION_DHT_CONFIG_VERSION=$FEDERATION_DHT_CONFIG_VERSION # if you set the value of FEDERATION_DHT_TOPIC, the DHT hyperswarm will start to announce and listen diff --git a/dht-node/package.json b/dht-node/package.json index 1f8ba4505..a66782269 100644 --- a/dht-node/package.json +++ b/dht-node/package.json @@ -23,7 +23,8 @@ "nodemon": "^2.0.20", "ts-node": "^10.9.1", "tsconfig-paths": "^4.1.2", - "typescript": "^4.9.4" + "typescript": "^4.9.4", + "uuid": "^8.3.2" }, "devDependencies": { "@types/dotenv": "^8.2.0", @@ -31,6 +32,7 @@ "@types/node": "^18.11.18", "@typescript-eslint/eslint-plugin": "^5.48.0", "@typescript-eslint/parser": "^5.48.0", + "@types/uuid": "^8.3.4", "eslint": "^8.31.0", "eslint-config-prettier": "^8.3.0", "eslint-config-standard": "^17.0.0", diff --git a/dht-node/src/config/index.ts b/dht-node/src/config/index.ts index 5c4676337..905ddb7ed 100644 --- a/dht-node/src/config/index.ts +++ b/dht-node/src/config/index.ts @@ -9,7 +9,7 @@ const constants = { LOG_LEVEL: process.env.LOG_LEVEL || 'info', CONFIG_VERSION: { DEFAULT: 'DEFAULT', - EXPECTED: 'v2.2023-02-07', + EXPECTED: 'v3.2023-04-26', CURRENT: '', }, } @@ -28,6 +28,12 @@ const database = { process.env.TYPEORM_LOGGING_RELATIVE_PATH || 'typeorm.dht-node.log', } +const community = { + COMMUNITY_NAME: process.env.COMMUNITY_NAME || 'Gradido Entwicklung', + COMMUNITY_DESCRIPTION: + process.env.COMMUNITY_DESCRIPTION || 'Gradido-Community einer lokalen Entwicklungsumgebung.', +} + const federation = { FEDERATION_DHT_TOPIC: process.env.FEDERATION_DHT_TOPIC || 'GRADIDO_HUB', FEDERATION_DHT_SEED: process.env.FEDERATION_DHT_SEED || null, @@ -51,6 +57,7 @@ const CONFIG = { ...constants, ...server, ...database, + ...community, ...federation, } diff --git a/dht-node/src/dht_node/index.ts b/dht-node/src/dht_node/index.ts index f2927bfee..fbbd9982b 100644 --- a/dht-node/src/dht_node/index.ts +++ b/dht-node/src/dht_node/index.ts @@ -4,8 +4,10 @@ import DHT from '@hyperswarm/dht' import { logger } from '@/server/logger' import CONFIG from '@/config' import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCommunity' +import { Community as DbCommunity } from '@entity/Community' import DEVOP from '@/config/devop' import { setDevOpEnvValue } from '@/config/tools' +import { v4 as uuidv4 } from 'uuid' const KEY_SECRET_SEEDBYTES = 32 const getSeed = (): Buffer | null => { @@ -42,8 +44,9 @@ export const startDHT = async (topic: string): Promise => { // insert or update keyPair in .env.devop file setDevOpEnvValue('HOME_COMMUNITY_PUBLICKEY', keyPair.publicKey.toString('hex')) setDevOpEnvValue('HOME_COMMUNITY_PRIVATEKEY', keyPair.secretKey.toString('hex')) + await writeHomeCommunityEntry(keyPair.publicKey) - const ownApiVersions = await writeFederatedHomeCommunityEnries(keyPair.publicKey) + const ownApiVersions = await writeFederatedHomeCommunityEntries(keyPair.publicKey) logger.info(`ApiList: ${JSON.stringify(ownApiVersions)}`) const node = new DHT({ keyPair }) @@ -191,7 +194,7 @@ export const startDHT = async (topic: string): Promise => { } } -async function writeFederatedHomeCommunityEnries(pubKey: any): Promise { +async function writeFederatedHomeCommunityEntries(pubKey: any): Promise { const homeApiVersions: CommunityApi[] = Object.values(ApiVersionType).map(function (apiEnum) { const comApi: CommunityApi = { api: apiEnum, @@ -215,7 +218,56 @@ async function writeFederatedHomeCommunityEnries(pubKey: any): Promise { + try { + // check for existing homeCommunity entry + let homeCom = await DbCommunity.findOne({ foreign: false, publicKey: pubKey }) + if (!homeCom) { + // check if a homecommunity with a different publicKey still exists + homeCom = await DbCommunity.findOne({ foreign: false }) + } + if (homeCom) { + // simply update the existing entry, but it MUST keep the ID and UUID because of possible relations + homeCom.publicKey = pubKey.toString('hex') + homeCom.url = CONFIG.FEDERATION_COMMUNITY_URL + homeCom.name = CONFIG.COMMUNITY_NAME + homeCom.description = CONFIG.COMMUNITY_DESCRIPTION + // this will NOT update the updatedAt column, to distingue between a normal update and the last announcement + await DbCommunity.save(homeCom) + logger.info(`home-community updated successfully: ${JSON.stringify(homeCom)}`) + } else { + // insert a new homecommunity entry including a new ID and UUID + homeCom = new DbCommunity() + homeCom.foreign = false + homeCom.publicKey = pubKey.toString('hex') + homeCom.communityUuid = await newCommunityUuid() + homeCom.url = CONFIG.FEDERATION_COMMUNITY_URL + homeCom.name = CONFIG.COMMUNITY_NAME + homeCom.description = CONFIG.COMMUNITY_DESCRIPTION + homeCom.creationDate = new Date() + // this will NOT update the updatedAt column, to distingue between a normal update and the last announcement + await DbCommunity.insert(homeCom) + logger.info(`home-community inserted successfully: ${JSON.stringify(homeCom)}`) + } + } catch (err) { + throw new Error(`Federation: Error writing HomeCommunity-Entry: ${err}`) + } +} + +const newCommunityUuid = async (): Promise => { + let uuid: string + let countIds: number + do { + uuid = uuidv4() + countIds = await DbCommunity.count({ where: { communityUuid: uuid } }) + if (countIds > 0) { + logger.info('CommunityUuid creation conflict...') + } + } while (countIds > 0) + return uuid +} diff --git a/dht-node/src/index.ts b/dht-node/src/index.ts index 19fc014c8..3e2a7a7ca 100644 --- a/dht-node/src/index.ts +++ b/dht-node/src/index.ts @@ -25,18 +25,20 @@ async function main() { // first read from .env.devop if exist let dhttopic = DEVOP.FEDERATION_DHT_TOPIC logger.debug('dhttopic set by DEVOP.FEDERATION_DHT_TOPIC={}', DEVOP.FEDERATION_DHT_TOPIC) - if(!dhttopic) { + if (!dhttopic) { dhttopic = CONFIG.FEDERATION_DHT_TOPIC - logger.debug('dhttopic overwritten by CONFIG.FEDERATION_DHT_TOPIC={}', CONFIG.FEDERATION_DHT_TOPIC) + logger.debug( + 'dhttopic overwritten by CONFIG.FEDERATION_DHT_TOPIC={}', + CONFIG.FEDERATION_DHT_TOPIC, + ) } let dhtseed = DEVOP.FEDERATION_DHT_SEED logger.debug('dhtseed set by DEVOP.FEDERATION_DHT_SEED={}', DEVOP.FEDERATION_DHT_SEED) - if(!dhtseed) { + if (!dhtseed) { dhtseed = CONFIG.FEDERATION_DHT_SEED logger.debug('dhtseed overwritten by CONFIG.FEDERATION_DHT_SEED={}', CONFIG.FEDERATION_DHT_SEED) } - logger.info( - `starting Federation on ${dhttopic} ${dhtseed ? 'with seed...' : 'without seed...'}`) + logger.info(`starting Federation on ${dhttopic} ${dhtseed ? 'with seed...' : 'without seed...'}`) await startDHT(dhttopic) } diff --git a/dht-node/yarn.lock b/dht-node/yarn.lock index 5832ecd8b..85c4d35fa 100644 --- a/dht-node/yarn.lock +++ b/dht-node/yarn.lock @@ -769,6 +769,11 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== +"@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" @@ -4138,6 +4143,11 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"