mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
add and use logging view class, annonce only configured api version
This commit is contained in:
parent
073edb57b5
commit
17a067e99b
@ -28,9 +28,9 @@ export class AuthenticationClient {
|
||||
async openConnection(args: OpenConnectionArgs): Promise<boolean | undefined> {
|
||||
logger.debug(`Authentication: openConnection at ${this.endpoint} for args:`, args)
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { data } = await this.client.rawRequest(openConnection, { args })
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
const { data } = await this.client.rawRequest<{ openConnection: boolean }>(openConnection, {
|
||||
args,
|
||||
})
|
||||
if (!data?.openConnection) {
|
||||
logger.warn(
|
||||
'Authentication: openConnection without response data from endpoint',
|
||||
|
||||
@ -5,9 +5,10 @@ import { getPublicCommunityInfo } from '@/federation/client/1_0/query/getPublicC
|
||||
import { getPublicKey } from '@/federation/client/1_0/query/getPublicKey'
|
||||
import { backendLogger as logger } from '@/server/logger'
|
||||
|
||||
import { PublicCommunityInfoLoggingView } from './logging/PublicCommunityInfoLogging.view'
|
||||
import { GetPublicKeyResult } from './model/GetPublicKeyResult'
|
||||
import { PublicCommunityInfo } from './model/PublicCommunityInfo'
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
export class FederationClient {
|
||||
dbCom: DbFederatedCommunity
|
||||
endpoint: string
|
||||
@ -30,9 +31,10 @@ export class FederationClient {
|
||||
getPublicKey = async (): Promise<string | undefined> => {
|
||||
logger.debug('Federation: getPublicKey from endpoint', this.endpoint)
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { data } = await this.client.rawRequest(getPublicKey, {})
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
const { data } = await this.client.rawRequest<{ getPublicKey: GetPublicKeyResult }>(
|
||||
getPublicKey,
|
||||
{},
|
||||
)
|
||||
if (!data?.getPublicKey?.publicKey) {
|
||||
logger.warn('Federation: getPublicKey without response data from endpoint', this.endpoint)
|
||||
return
|
||||
@ -40,10 +42,8 @@ export class FederationClient {
|
||||
logger.debug(
|
||||
'Federation: getPublicKey successful from endpoint',
|
||||
this.endpoint,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
data.getPublicKey.publicKey,
|
||||
)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
|
||||
return data.getPublicKey.publicKey
|
||||
} catch (err) {
|
||||
logger.warn('Federation: getPublicKey failed for endpoint', this.endpoint)
|
||||
@ -53,9 +53,10 @@ export class FederationClient {
|
||||
getPublicCommunityInfo = async (): Promise<PublicCommunityInfo | undefined> => {
|
||||
logger.debug(`Federation: getPublicCommunityInfo with endpoint='${this.endpoint}'...`)
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { data } = await this.client.rawRequest(getPublicCommunityInfo, {})
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
const { data } = await this.client.rawRequest<{
|
||||
getPublicCommunityInfo: PublicCommunityInfo
|
||||
}>(getPublicCommunityInfo, {})
|
||||
|
||||
if (!data?.getPublicCommunityInfo?.name) {
|
||||
logger.warn(
|
||||
'Federation: getPublicCommunityInfo without response data from endpoint',
|
||||
@ -64,9 +65,10 @@ export class FederationClient {
|
||||
return
|
||||
}
|
||||
logger.debug(`Federation: getPublicCommunityInfo successful from endpoint=${this.endpoint}`)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
logger.debug(`publicCommunityInfo:`, data.getPublicCommunityInfo)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
|
||||
logger.debug(
|
||||
`publicCommunityInfo:`,
|
||||
new PublicCommunityInfoLoggingView(data.getPublicCommunityInfo),
|
||||
)
|
||||
return data.getPublicCommunityInfo
|
||||
} catch (err) {
|
||||
logger.warn('Federation: getPublicCommunityInfo failed for endpoint', this.endpoint)
|
||||
|
||||
@ -4,6 +4,8 @@ import { GraphQLClient } from 'graphql-request'
|
||||
import { LogError } from '@/server/LogError'
|
||||
import { backendLogger as logger } from '@/server/logger'
|
||||
|
||||
import { SendCoinsArgsLoggingView } from './logging/SendCoinsArgsLogging.view'
|
||||
import { SendCoinsResultLoggingView } from './logging/SendCoinsResultLogging.view'
|
||||
import { SendCoinsArgs } from './model/SendCoinsArgs'
|
||||
import { SendCoinsResult } from './model/SendCoinsResult'
|
||||
import { revertSendCoins as revertSendCoinsQuery } from './query/revertSendCoins'
|
||||
@ -11,7 +13,6 @@ import { revertSettledSendCoins as revertSettledSendCoinsQuery } from './query/r
|
||||
import { settleSendCoins as settleSendCoinsQuery } from './query/settleSendCoins'
|
||||
import { voteForSendCoins as voteForSendCoinsQuery } from './query/voteForSendCoins'
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
export class SendCoinsClient {
|
||||
dbCom: DbFederatedCommunity
|
||||
endpoint: string
|
||||
@ -34,26 +35,26 @@ export class SendCoinsClient {
|
||||
async voteForSendCoins(args: SendCoinsArgs): Promise<SendCoinsResult> {
|
||||
logger.debug('X-Com: voteForSendCoins against endpoint=', this.endpoint)
|
||||
try {
|
||||
logger.debug(`X-Com: SendCoinsClient: voteForSendCoins with args=`, args)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { data } = await this.client.rawRequest(voteForSendCoinsQuery, { args })
|
||||
logger.debug(`X-Com: SendCoinsClient: after rawRequest...data:`, data)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
logger.debug(
|
||||
`X-Com: SendCoinsClient: voteForSendCoins with args=`,
|
||||
new SendCoinsArgsLoggingView(args),
|
||||
)
|
||||
const { data } = await this.client.rawRequest<{ voteForSendCoins: SendCoinsResult }>(
|
||||
voteForSendCoinsQuery,
|
||||
{ args },
|
||||
)
|
||||
const result = data.voteForSendCoins
|
||||
if (!data?.voteForSendCoins?.vote) {
|
||||
logger.debug('X-Com: voteForSendCoins failed with: ', data)
|
||||
logger.debug(
|
||||
'X-Com: voteForSendCoins failed with: ',
|
||||
new SendCoinsResultLoggingView(result),
|
||||
)
|
||||
return new SendCoinsResult()
|
||||
}
|
||||
const result = new SendCoinsResult()
|
||||
result.vote = true
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
||||
result.recipGradidoID = data.voteForSendCoins.recipGradidoID
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
||||
result.recipFirstName = data.voteForSendCoins.recipFirstName
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
||||
result.recipLastName = data.voteForSendCoins.recipLastName
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
||||
result.recipAlias = data.voteForSendCoins.recipAlias
|
||||
logger.debug('X-Com: voteForSendCoins successful with result=', result)
|
||||
logger.debug(
|
||||
'X-Com: voteForSendCoins successful with result=',
|
||||
new SendCoinsResultLoggingView(result),
|
||||
)
|
||||
return result
|
||||
} catch (err) {
|
||||
throw new LogError(`X-Com: voteForSendCoins failed for endpoint=${this.endpoint}:`, err)
|
||||
@ -63,11 +64,15 @@ export class SendCoinsClient {
|
||||
async revertSendCoins(args: SendCoinsArgs): Promise<boolean> {
|
||||
logger.debug('X-Com: revertSendCoins against endpoint=', this.endpoint)
|
||||
try {
|
||||
logger.debug(`X-Com: SendCoinsClient: revertSendCoins with args=`, args)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { data } = await this.client.rawRequest(revertSendCoinsQuery, { args })
|
||||
logger.debug(
|
||||
`X-Com: SendCoinsClient: revertSendCoins with args=`,
|
||||
new SendCoinsArgsLoggingView(args),
|
||||
)
|
||||
const { data } = await this.client.rawRequest<{ revertSendCoins: boolean }>(
|
||||
revertSendCoinsQuery,
|
||||
{ args },
|
||||
)
|
||||
logger.debug(`X-Com: SendCoinsClient: after revertSendCoins: data=`, data)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
if (!data?.revertSendCoins) {
|
||||
logger.warn('X-Com: revertSendCoins without response data from endpoint', this.endpoint)
|
||||
return false
|
||||
@ -88,11 +93,15 @@ export class SendCoinsClient {
|
||||
async settleSendCoins(args: SendCoinsArgs): Promise<boolean> {
|
||||
logger.debug(`X-Com: settleSendCoins against endpoint='${this.endpoint}'...`)
|
||||
try {
|
||||
logger.debug(`X-Com: SendCoinsClient: settleSendCoins with args=`, args)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { data } = await this.client.rawRequest(settleSendCoinsQuery, { args })
|
||||
logger.debug(
|
||||
`X-Com: SendCoinsClient: settleSendCoins with args=`,
|
||||
new SendCoinsArgsLoggingView(args),
|
||||
)
|
||||
const { data } = await this.client.rawRequest<{ settleSendCoins: boolean }>(
|
||||
settleSendCoinsQuery,
|
||||
{ args },
|
||||
)
|
||||
logger.debug(`X-Com: SendCoinsClient: after settleSendCoins: data=`, data)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
if (!data?.settleSendCoins) {
|
||||
logger.warn(
|
||||
'X-Com: SendCoinsClient: settleSendCoins without response data from endpoint',
|
||||
@ -115,9 +124,14 @@ export class SendCoinsClient {
|
||||
async revertSettledSendCoins(args: SendCoinsArgs): Promise<boolean> {
|
||||
logger.debug(`X-Com: revertSettledSendCoins against endpoint='${this.endpoint}'...`)
|
||||
try {
|
||||
logger.debug(`X-Com: SendCoinsClient: revertSettledSendCoins with args=`, args)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { data } = await this.client.rawRequest(revertSettledSendCoinsQuery, { args })
|
||||
logger.debug(
|
||||
`X-Com: SendCoinsClient: revertSettledSendCoins with args=`,
|
||||
new SendCoinsArgsLoggingView(args),
|
||||
)
|
||||
const { data } = await this.client.rawRequest<{ revertSettledSendCoins: boolean }>(
|
||||
revertSettledSendCoinsQuery,
|
||||
{ args },
|
||||
)
|
||||
logger.debug(`X-Com: SendCoinsClient: after revertSettledSendCoins: data=`, data)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
if (!data?.revertSettledSendCoins) {
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
import { AbstractLoggingView } from '@logging/AbstractLogging.view'
|
||||
|
||||
import { PublicCommunityInfo } from '@/federation/client/1_0/model/PublicCommunityInfo'
|
||||
|
||||
export class PublicCommunityInfoLoggingView extends AbstractLoggingView {
|
||||
public constructor(private self: PublicCommunityInfo) {
|
||||
super()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public toJSON(): any {
|
||||
return {
|
||||
name: this.self.name,
|
||||
description: this.self.description,
|
||||
creationDate: this.dateToString(this.self.creationDate),
|
||||
publicKey: this.self.publicKey,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
import { AbstractLoggingView } from '@logging/AbstractLogging.view'
|
||||
|
||||
import { SendCoinsArgs } from '@/federation/client/1_0/model/SendCoinsArgs'
|
||||
|
||||
export class SendCoinsArgsLoggingView extends AbstractLoggingView {
|
||||
public constructor(private self: SendCoinsArgs) {
|
||||
super()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public toJSON(): any {
|
||||
return {
|
||||
recipientCommunityUuid: this.self.recipientCommunityUuid,
|
||||
recipientUserIdentifier: this.self.recipientUserIdentifier,
|
||||
creationDate: this.self.creationDate,
|
||||
amount: this.decimalToString(this.self.amount),
|
||||
memoLength: this.self.memo.length,
|
||||
senderCommunityUuid: this.self.senderCommunityUuid,
|
||||
senderUserUuid: this.self.senderUserUuid,
|
||||
senderUserName: this.self.senderUserName.substring(0, 3),
|
||||
senderAlias: this.self.senderAlias?.substring(0, 3),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
import { AbstractLoggingView } from '@logging/AbstractLogging.view'
|
||||
|
||||
import { SendCoinsResult } from '@/federation/client/1_0/model/SendCoinsResult'
|
||||
|
||||
export class SendCoinsResultLoggingView extends AbstractLoggingView {
|
||||
public constructor(private self: SendCoinsResult) {
|
||||
super()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public toJSON(): any {
|
||||
return {
|
||||
vote: this.self.vote,
|
||||
recipGradidoID: this.self.recipGradidoID,
|
||||
recipFirstName: this.self.recipFirstName?.substring(0, 3),
|
||||
recipLastName: this.self.recipLastName?.substring(0, 3),
|
||||
recipAlias: this.self.recipAlias?.substring(0, 3),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import { Field, ObjectType } from 'type-graphql'
|
||||
|
||||
@ObjectType()
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export class GetPublicKeyResult {
|
||||
constructor(pubKey: string) {
|
||||
this.publicKey = pubKey
|
||||
}
|
||||
|
||||
@Field(() => String)
|
||||
publicKey: string
|
||||
}
|
||||
@ -3,14 +3,15 @@
|
||||
import { IsNull } from '@dbTools/typeorm'
|
||||
import { Community as DbCommunity } from '@entity/Community'
|
||||
import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCommunity'
|
||||
import { FederatedCommunityLoggingView } from '@logging/FederatedCommunityLogging.view'
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
import { FederationClient as V1_0_FederationClient } from '@/federation/client/1_0/FederationClient'
|
||||
import { PublicCommunityInfo } from '@/federation/client/1_0/model/PublicCommunityInfo'
|
||||
import { FederationClientFactory } from '@/federation/client/FederationClientFactory'
|
||||
import { backendLogger as logger } from '@/server/logger'
|
||||
|
||||
import { startCommunityAuthentication } from './authenticateCommunities'
|
||||
import { PublicCommunityInfoLoggingView } from './client/1_0/logging/PublicCommunityInfoLogging.view'
|
||||
import { ApiVersionType } from './enum/apiVersionType'
|
||||
|
||||
export async function startValidateCommunities(timerInterval: number): Promise<void> {
|
||||
@ -37,7 +38,7 @@ export async function validateCommunities(): Promise<void> {
|
||||
|
||||
logger.debug(`Federation: found ${dbFederatedCommunities.length} dbCommunities`)
|
||||
for (const dbCom of dbFederatedCommunities) {
|
||||
logger.debug('Federation: dbCom', dbCom)
|
||||
logger.debug('Federation: dbCom', new FederatedCommunityLoggingView(dbCom))
|
||||
const apiValueStrings: string[] = Object.values(ApiVersionType)
|
||||
logger.debug(`suppported ApiVersions=`, apiValueStrings)
|
||||
if (!apiValueStrings.includes(dbCom.apiVersion)) {
|
||||
@ -53,7 +54,7 @@ export async function validateCommunities(): Promise<void> {
|
||||
// eslint-disable-next-line camelcase
|
||||
if (client instanceof V1_0_FederationClient) {
|
||||
const pubKey = await client.getPublicKey()
|
||||
if (pubKey && pubKey === dbCom.publicKey.toString()) {
|
||||
if (pubKey && pubKey === dbCom.publicKey.toString('hex')) {
|
||||
await DbFederatedCommunity.update({ id: dbCom.id }, { verifiedAt: new Date() })
|
||||
logger.debug(`Federation: verified community with:`, dbCom.endPoint)
|
||||
const pubComInfo = await client.getPublicCommunityInfo()
|
||||
@ -68,7 +69,7 @@ export async function validateCommunities(): Promise<void> {
|
||||
logger.debug(
|
||||
'Federation: received not matching publicKey:',
|
||||
pubKey,
|
||||
dbCom.publicKey.toString(),
|
||||
dbCom.publicKey.toString('hex'),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -82,10 +83,11 @@ async function writeForeignCommunity(
|
||||
dbCom: DbFederatedCommunity,
|
||||
pubInfo: PublicCommunityInfo,
|
||||
): Promise<void> {
|
||||
if (!dbCom || !pubInfo || !(dbCom.publicKey.toString() === pubInfo.publicKey)) {
|
||||
if (!dbCom || !pubInfo || !(dbCom.publicKey.toString('hex') === pubInfo.publicKey)) {
|
||||
const pubInfoView = new PublicCommunityInfoLoggingView(pubInfo)
|
||||
logger.error(
|
||||
`Error in writeForeignCommunity: missmatching parameters or publicKey. pubInfo:${JSON.stringify(
|
||||
pubInfo,
|
||||
`Error in writeForeignCommunity: missmatching parameters or publicKey. pubInfo:${pubInfoView.toString(
|
||||
true,
|
||||
)}`,
|
||||
)
|
||||
} else {
|
||||
|
||||
@ -58,7 +58,8 @@
|
||||
"@test/*": ["test/*"],
|
||||
/* external */
|
||||
"@dbTools/*": ["../database/src/*", "../../database/build/src/*"],
|
||||
"@entity/*": ["../database/entity/*", "../../database/build/entity/*"]
|
||||
"@entity/*": ["../database/entity/*", "../../database/build/entity/*"],
|
||||
"@logging/*": ["../database/logging/*", "../../database/build/logging/*"]
|
||||
},
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
"typeRoots": ["@types", "node_modules/@types"], /* List of folders to include type definitions from. */
|
||||
|
||||
@ -3,13 +3,18 @@ import util from 'util'
|
||||
import { Decimal } from 'decimal.js-light'
|
||||
|
||||
export abstract class AbstractLoggingView {
|
||||
// eslint-disable-next-line no-undef
|
||||
protected bufferStringFormat: BufferEncoding = 'hex'
|
||||
|
||||
// This function gets called automatically when JSON.stringify() is called on this class instance
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public abstract toJSON(): any
|
||||
public toString(): string {
|
||||
return JSON.stringify(this.toJSON(), null, 2)
|
||||
public toString(compact = false): string {
|
||||
if (compact) {
|
||||
return JSON.stringify(this.toJSON())
|
||||
} else {
|
||||
return JSON.stringify(this.toJSON(), null, 2)
|
||||
}
|
||||
}
|
||||
|
||||
// called form console.log or log4js logging functions
|
||||
|
||||
24
database/logging/FederatedCommunityLogging.view.ts
Normal file
24
database/logging/FederatedCommunityLogging.view.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { FederatedCommunity } from '../entity/FederatedCommunity'
|
||||
import { AbstractLoggingView } from './AbstractLogging.view'
|
||||
|
||||
export class FederatedCommunityLoggingView extends AbstractLoggingView {
|
||||
public constructor(private self: FederatedCommunity) {
|
||||
super()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public toJSON(): any {
|
||||
return {
|
||||
id: this.self.id,
|
||||
foreign: this.self.foreign,
|
||||
publicKey: this.self.publicKey.toString(this.bufferStringFormat),
|
||||
apiVersion: this.self.apiVersion,
|
||||
endPoint: this.self.endPoint,
|
||||
lastAnnouncedAt: this.dateToString(this.self.lastAnnouncedAt),
|
||||
verifiedAt: this.self.verifiedAt,
|
||||
lastErrorAt: this.self.lastErrorAt,
|
||||
createdAt: this.dateToString(this.self.createdAt),
|
||||
updatedAt: this.dateToString(this.self.updatedAt),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,5 +15,5 @@ TYPEORM_LOGGING_RELATIVE_PATH=typeorm.dht-node.log
|
||||
FEDERATION_DHT_TOPIC=GRADIDO_HUB
|
||||
# FEDERATION_DHT_SEED=64ebcb0e3ad547848fef4197c6e2332f
|
||||
FEDERATION_COMMUNITY_URL=http://localhost
|
||||
# the api port is the dht baseport, which will be added with the supported api-versions, e.g. 1_0 = 5010
|
||||
FEDERATION_COMMUNITY_API_PORT=5000
|
||||
# comma separated values, which apis should be announced
|
||||
FEDERATION_COMMUNITY_APIS=1_0
|
||||
@ -20,4 +20,5 @@ FEDERATION_DHT_CONFIG_VERSION=$FEDERATION_DHT_CONFIG_VERSION
|
||||
FEDERATION_DHT_TOPIC=$FEDERATION_DHT_TOPIC
|
||||
FEDERATION_DHT_SEED=$FEDERATION_DHT_SEED
|
||||
FEDERATION_COMMUNITY_URL=$FEDERATION_COMMUNITY_URL
|
||||
FEDERATION_COMMUNITY_API_PORT=$FEDERATION_COMMUNITY_API_PORT
|
||||
# comma separated values, which apis should be announced
|
||||
FEDERATION_COMMUNITY_APIS=$FEDERATION_COMMUNITY_APIS
|
||||
@ -10,7 +10,7 @@ const constants = {
|
||||
LOG_LEVEL: process.env.LOG_LEVEL || 'info',
|
||||
CONFIG_VERSION: {
|
||||
DEFAULT: 'DEFAULT',
|
||||
EXPECTED: 'v3.2023-04-26',
|
||||
EXPECTED: 'v4.2024-01-17',
|
||||
CURRENT: '',
|
||||
},
|
||||
}
|
||||
@ -39,7 +39,7 @@ const federation = {
|
||||
FEDERATION_DHT_TOPIC: process.env.FEDERATION_DHT_TOPIC || 'GRADIDO_HUB',
|
||||
FEDERATION_DHT_SEED: process.env.FEDERATION_DHT_SEED || null,
|
||||
FEDERATION_COMMUNITY_URL: process.env.FEDERATION_COMMUNITY_URL || 'http://localhost',
|
||||
FEDERATION_COMMUNITY_API_PORT: process.env.FEDERATION_COMMUNITY_API_PORT || '5000',
|
||||
FEDERATION_COMMUNITY_APIS: process.env.FEDERATION_COMMUNITY_APIS || '1_0',
|
||||
}
|
||||
|
||||
// Check config version
|
||||
|
||||
@ -18,8 +18,8 @@ const ANNOUNCETIME = 30000
|
||||
|
||||
enum ApiVersionType {
|
||||
V1_0 = '1_0',
|
||||
V1_1 = '1_1',
|
||||
V2_0 = '2_0',
|
||||
V1_1 = '1_1', // currently no changes
|
||||
V2_0 = '2_0', // not exist
|
||||
}
|
||||
type CommunityApi = {
|
||||
api: string
|
||||
@ -191,9 +191,11 @@ export const startDHT = async (topic: string): Promise<void> => {
|
||||
}
|
||||
|
||||
async function writeFederatedHomeCommunityEntries(pubKey: string): Promise<CommunityApi[]> {
|
||||
const homeApiVersions: CommunityApi[] = Object.values(ApiVersionType).map(function (apiEnum) {
|
||||
const homeApiVersions: CommunityApi[] = CONFIG.FEDERATION_COMMUNITY_APIS.split(',').map(function (
|
||||
api,
|
||||
) {
|
||||
const comApi: CommunityApi = {
|
||||
api: apiEnum,
|
||||
api,
|
||||
url: CONFIG.FEDERATION_COMMUNITY_URL + '/api/',
|
||||
}
|
||||
return comApi
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
import { GetPublicCommunityInfoResult } from '@/graphql/api/1_0/model/GetPublicCommunityInfoResult'
|
||||
import { AbstractLoggingView } from '@logging/AbstractLogging.view'
|
||||
|
||||
export class GetPublicCommunityInfoResultLoggingView extends AbstractLoggingView {
|
||||
public constructor(private self: GetPublicCommunityInfoResult) {
|
||||
super()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public toJSON(): any {
|
||||
return {
|
||||
name: this.self.name,
|
||||
description: this.self.description,
|
||||
creationDate: this.dateToString(this.self.creationDate),
|
||||
publicKey: this.self.publicKey,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
import { AbstractLoggingView } from '@logging/AbstractLogging.view'
|
||||
import { SendCoinsArgs } from '@/graphql/api/1_0/model/SendCoinsArgs'
|
||||
|
||||
export class SendCoinsArgsLoggingView extends AbstractLoggingView {
|
||||
public constructor(private self: SendCoinsArgs) {
|
||||
super()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public toJSON(): any {
|
||||
return {
|
||||
recipientCommunityUuid: this.self.recipientCommunityUuid,
|
||||
recipientUserIdentifier: this.self.recipientUserIdentifier,
|
||||
creationDate: this.self.creationDate,
|
||||
amount: this.decimalToString(this.self.amount),
|
||||
memoLength: this.self.memo.length,
|
||||
senderCommunityUuid: this.self.senderCommunityUuid,
|
||||
senderUserUuid: this.self.senderUserUuid,
|
||||
senderUserName: this.self.senderUserName.substring(0, 3),
|
||||
senderAlias: this.self.senderAlias?.substring(0, 3),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@ import { Field, ObjectType } from 'type-graphql'
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export class GetPublicCommunityInfoResult {
|
||||
constructor(dbCom: DbCommunity) {
|
||||
this.publicKey = dbCom.publicKey.toString()
|
||||
this.publicKey = dbCom.publicKey.toString('hex')
|
||||
this.name = dbCom.name
|
||||
this.description = dbCom.description
|
||||
this.creationDate = dbCom.creationDate
|
||||
|
||||
@ -3,6 +3,8 @@ import { Arg, Mutation, Resolver } from 'type-graphql'
|
||||
import { federationLogger as logger } from '@/server/logger'
|
||||
import { Community as DbCommunity } from '@entity/Community'
|
||||
import { FederatedCommunity as DbFedCommunity } from '@entity/FederatedCommunity'
|
||||
import { CommunityLoggingView } from '@logging/CommunityLogging.view'
|
||||
import { FederatedCommunityLoggingView } from '@logging/FederatedCommunityLogging.view'
|
||||
import { LogError } from '@/server/LogError'
|
||||
import { OpenConnectionArgs } from '../model/OpenConnectionArgs'
|
||||
import { startAuthentication, startOpenConnectionCallback } from '../util/authenticateCommunity'
|
||||
@ -11,7 +13,6 @@ import { CONFIG } from '@/config'
|
||||
import { AuthenticationArgs } from '../model/AuthenticationArgs'
|
||||
|
||||
@Resolver()
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export class AuthenticationResolver {
|
||||
@Mutation(() => Boolean)
|
||||
async openConnection(
|
||||
@ -28,7 +29,7 @@ export class AuthenticationResolver {
|
||||
if (!comA) {
|
||||
throw new LogError(`unknown requesting community with publicKey`, pubKeyBuf.toString('hex'))
|
||||
}
|
||||
logger.debug(`Authentication: found requestedCom:`, comA)
|
||||
logger.debug(`Authentication: found requestedCom:`, new CommunityLoggingView(comA))
|
||||
// no await to respond immediatly and invoke callback-request asynchron
|
||||
void startOpenConnectionCallback(args, comA, CONFIG.FEDERATION_API)
|
||||
return true
|
||||
@ -48,7 +49,10 @@ export class AuthenticationResolver {
|
||||
if (!fedComB) {
|
||||
throw new LogError(`unknown callback community with url`, args.url)
|
||||
}
|
||||
logger.debug(`Authentication: found fedComB and start authentication:`, fedComB)
|
||||
logger.debug(
|
||||
`Authentication: found fedComB and start authentication:`,
|
||||
new FederatedCommunityLoggingView(fedComB),
|
||||
)
|
||||
// no await to respond immediatly and invoke authenticate-request asynchron
|
||||
void startAuthentication(args.oneTimeCode, fedComB)
|
||||
return true
|
||||
@ -61,13 +65,16 @@ export class AuthenticationResolver {
|
||||
): Promise<string | null> {
|
||||
logger.debug(`Authentication: authenticate() via apiVersion=1_0 ...`, args)
|
||||
const authCom = await DbCommunity.findOneByOrFail({ communityUuid: args.oneTimeCode })
|
||||
logger.debug('Authentication: found authCom:', authCom)
|
||||
logger.debug('Authentication: found authCom:', new CommunityLoggingView(authCom))
|
||||
if (authCom) {
|
||||
// TODO decrypt args.uuid with authCom.publicKey
|
||||
authCom.communityUuid = args.uuid
|
||||
authCom.authenticatedAt = new Date()
|
||||
await DbCommunity.save(authCom)
|
||||
logger.debug('Authentication: store authCom.uuid successfully:', authCom)
|
||||
logger.debug(
|
||||
'Authentication: store authCom.uuid successfully:',
|
||||
new CommunityLoggingView(authCom),
|
||||
)
|
||||
const homeCom = await DbCommunity.findOneByOrFail({ foreign: false })
|
||||
// TODO encrypt homeCom.uuid with homeCom.privateKey
|
||||
if (homeCom.communityUuid) {
|
||||
|
||||
@ -3,16 +3,19 @@ import { Query, Resolver } from 'type-graphql'
|
||||
import { federationLogger as logger } from '@/server/logger'
|
||||
import { Community as DbCommunity } from '@entity/Community'
|
||||
import { GetPublicCommunityInfoResult } from '../model/GetPublicCommunityInfoResult'
|
||||
import { GetPublicCommunityInfoResultLoggingView } from '../logger/GetPublicCommunityInfoResultLogging.view'
|
||||
|
||||
@Resolver()
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export class PublicCommunityInfoResolver {
|
||||
@Query(() => GetPublicCommunityInfoResult)
|
||||
async getPublicCommunityInfo(): Promise<GetPublicCommunityInfoResult> {
|
||||
logger.debug(`getPublicCommunityInfo() via apiVersion=1_0 ...`)
|
||||
const homeCom = await DbCommunity.findOneByOrFail({ foreign: false })
|
||||
const result = new GetPublicCommunityInfoResult(homeCom)
|
||||
logger.debug(`getPublicCommunityInfo()-1_0... return publicInfo=${JSON.stringify(result)}`)
|
||||
const publicInfoView = new GetPublicCommunityInfoResultLoggingView(result)
|
||||
logger.debug(
|
||||
`getPublicCommunityInfo()-1_0... return publicInfo=${publicInfoView.toString(true)}`,
|
||||
)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCom
|
||||
import { GetPublicKeyResult } from '../model/GetPublicKeyResult'
|
||||
|
||||
@Resolver()
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export class PublicKeyResolver {
|
||||
@Query(() => GetPublicKeyResult)
|
||||
async getPublicKey(): Promise<GetPublicKeyResult> {
|
||||
@ -16,7 +15,8 @@ export class PublicKeyResolver {
|
||||
apiVersion: '1_0',
|
||||
},
|
||||
})
|
||||
logger.debug(`getPublicKey()-1_0... return publicKey=${homeCom.publicKey}`)
|
||||
return new GetPublicKeyResult(homeCom.publicKey.toString())
|
||||
const publicKeyHex = homeCom.publicKey.toString('hex')
|
||||
logger.debug(`getPublicKey()-1_0... return publicKey=${publicKeyHex}`)
|
||||
return new GetPublicKeyResult(publicKeyHex)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import { Arg, Args, Mutation, Resolver } from 'type-graphql'
|
||||
import { Arg, Mutation, Resolver } from 'type-graphql'
|
||||
import { federationLogger as logger } from '@/server/logger'
|
||||
import { Community as DbCommunity } from '@entity/Community'
|
||||
import { PendingTransaction as DbPendingTransaction } from '@entity/PendingTransaction'
|
||||
@ -16,27 +15,16 @@ import { findUserByIdentifier } from '@/graphql/util/findUserByIdentifier'
|
||||
import { SendCoinsResult } from '../model/SendCoinsResult'
|
||||
import Decimal from 'decimal.js-light'
|
||||
import { storeForeignUser } from '../util/storeForeignUser'
|
||||
import { SendCoinsArgsLoggingView } from '../logger/SendCoinsArgsLogging.view'
|
||||
|
||||
@Resolver()
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export class SendCoinsResolver {
|
||||
@Mutation(() => SendCoinsResult)
|
||||
async voteForSendCoins(
|
||||
@Arg('data')
|
||||
args: SendCoinsArgs,
|
||||
): Promise<SendCoinsResult> {
|
||||
logger.debug(
|
||||
`voteForSendCoins() via apiVersion=1_0 ...`,
|
||||
args.recipientCommunityUuid,
|
||||
args.recipientUserIdentifier,
|
||||
args.creationDate,
|
||||
args.amount.toString(),
|
||||
args.memo,
|
||||
args.senderCommunityUuid,
|
||||
args.senderUserUuid,
|
||||
args.senderUserName,
|
||||
args.senderAlias,
|
||||
)
|
||||
logger.debug(`voteForSendCoins() via apiVersion=1_0 ...`, new SendCoinsArgsLoggingView(args))
|
||||
const result = new SendCoinsResult()
|
||||
// first check if receiver community is correct
|
||||
const homeCom = await DbCommunity.findOneBy({
|
||||
@ -167,19 +155,11 @@ export class SendCoinsResolver {
|
||||
pendingTx?.amount.toString(),
|
||||
args.amount.toString(),
|
||||
)
|
||||
throw new LogError(
|
||||
`Can't find in revertSendCoins the pending receiver TX for args=`,
|
||||
args.recipientCommunityUuid,
|
||||
args.recipientUserIdentifier,
|
||||
PendingTransactionState.NEW,
|
||||
TransactionTypeId.RECEIVE,
|
||||
args.creationDate,
|
||||
args.amount,
|
||||
args.memo,
|
||||
args.senderCommunityUuid,
|
||||
args.senderUserUuid,
|
||||
args.senderUserName,
|
||||
)
|
||||
throw new LogError(`Can't find in revertSendCoins the pending receiver TX for `, {
|
||||
args: new SendCoinsArgsLoggingView(args),
|
||||
pendingTransactionState: PendingTransactionState.NEW,
|
||||
transactionType: TransactionTypeId.RECEIVE,
|
||||
})
|
||||
}
|
||||
logger.debug(`revertSendCoins()-1_0... successfull`)
|
||||
return true
|
||||
@ -193,15 +173,7 @@ export class SendCoinsResolver {
|
||||
@Arg('data')
|
||||
args: SendCoinsArgs,
|
||||
): Promise<boolean> {
|
||||
logger.debug(
|
||||
`settleSendCoins() via apiVersion=1_0 ...userCommunityUuid=${
|
||||
args.recipientCommunityUuid
|
||||
}, userGradidoID=${args.recipientUserIdentifier}, balanceDate=${
|
||||
args.creationDate
|
||||
},amount=${args.amount.valueOf()}, memo=${args.memo}, linkedUserCommunityUuid = ${
|
||||
args.senderCommunityUuid
|
||||
}, userSenderIdentifier=${args.senderUserUuid}, userSenderName=${args.senderUserName}`,
|
||||
)
|
||||
logger.debug(`settleSendCoins() via apiVersion=1_0 ...`, new SendCoinsArgsLoggingView(args))
|
||||
// first check if receiver community is correct
|
||||
const homeCom = await DbCommunity.findOneBy({
|
||||
communityUuid: args.recipientCommunityUuid,
|
||||
@ -256,17 +228,12 @@ export class SendCoinsResolver {
|
||||
} else {
|
||||
logger.debug('XCom: settlePendingReceiveTransaction NOT matching pendingTX for settlement...')
|
||||
throw new LogError(
|
||||
`Can't find in settlePendingReceiveTransaction the pending receiver TX for args=`,
|
||||
args.recipientCommunityUuid,
|
||||
args.recipientUserIdentifier,
|
||||
PendingTransactionState.NEW,
|
||||
TransactionTypeId.RECEIVE,
|
||||
args.creationDate,
|
||||
args.amount,
|
||||
args.memo,
|
||||
args.senderCommunityUuid,
|
||||
args.senderUserUuid,
|
||||
args.senderUserName,
|
||||
`Can't find in settlePendingReceiveTransaction the pending receiver TX for `,
|
||||
{
|
||||
args: new SendCoinsArgsLoggingView(args),
|
||||
pendingTransactionState: PendingTransactionState.NEW,
|
||||
transactionTypeId: TransactionTypeId.RECEIVE,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -322,19 +289,11 @@ export class SendCoinsResolver {
|
||||
}
|
||||
} else {
|
||||
logger.debug('XCom: revertSettledSendCoins NOT matching pendingTX...')
|
||||
throw new LogError(
|
||||
`Can't find in revertSettledSendCoins the pending receiver TX for args=`,
|
||||
args.recipientCommunityUuid,
|
||||
args.recipientUserIdentifier,
|
||||
PendingTransactionState.SETTLED,
|
||||
TransactionTypeId.RECEIVE,
|
||||
args.creationDate,
|
||||
args.amount,
|
||||
args.memo,
|
||||
args.senderCommunityUuid,
|
||||
args.senderUserUuid,
|
||||
args.senderUserName,
|
||||
)
|
||||
throw new LogError(`Can't find in revertSettledSendCoins the pending receiver TX for `, {
|
||||
args: new SendCoinsArgsLoggingView(args),
|
||||
pendingTransactionState: PendingTransactionState.SETTLED,
|
||||
transactionTypeId: TransactionTypeId.RECEIVE,
|
||||
})
|
||||
}
|
||||
logger.debug(`revertSendCoins()-1_0... successfull`)
|
||||
return true
|
||||
|
||||
@ -9,13 +9,18 @@ import { AuthenticationClientFactory } from '@/client/AuthenticationClientFactor
|
||||
// eslint-disable-next-line camelcase
|
||||
import { AuthenticationClient as V1_0_AuthenticationClient } from '@/client/1_0/AuthenticationClient'
|
||||
import { AuthenticationArgs } from '../model/AuthenticationArgs'
|
||||
import { CommunityLoggingView } from '@logging/CommunityLogging.view'
|
||||
import { FederatedCommunityLoggingView } from '@logging/FederatedCommunityLogging.view'
|
||||
|
||||
export async function startOpenConnectionCallback(
|
||||
args: OpenConnectionArgs,
|
||||
comA: DbCommunity,
|
||||
api: string,
|
||||
): Promise<void> {
|
||||
logger.debug(`Authentication: startOpenConnectionCallback() with:`, args, comA)
|
||||
logger.debug(`Authentication: startOpenConnectionCallback() with:`, {
|
||||
args,
|
||||
comA: new CommunityLoggingView(comA),
|
||||
})
|
||||
try {
|
||||
const homeFedCom = await DbFedCommunity.findOneByOrFail({
|
||||
foreign: false,
|
||||
@ -30,7 +35,10 @@ export async function startOpenConnectionCallback(
|
||||
// store oneTimeCode in requestedCom.community_uuid as authenticate-request-identifier
|
||||
comA.communityUuid = oneTimeCode.toString()
|
||||
await DbCommunity.save(comA)
|
||||
logger.debug(`Authentication: stored oneTimeCode in requestedCom:`, comA)
|
||||
logger.debug(
|
||||
`Authentication: stored oneTimeCode in requestedCom:`,
|
||||
new CommunityLoggingView(comA),
|
||||
)
|
||||
|
||||
const client = AuthenticationClientFactory.getInstance(fedComA)
|
||||
// eslint-disable-next-line camelcase
|
||||
@ -57,7 +65,10 @@ export async function startAuthentication(
|
||||
oneTimeCode: string,
|
||||
fedComB: DbFedCommunity,
|
||||
): Promise<void> {
|
||||
logger.debug(`Authentication: startAuthentication()...`, oneTimeCode, fedComB)
|
||||
logger.debug(`Authentication: startAuthentication()...`, {
|
||||
oneTimeCode,
|
||||
fedComB: new FederatedCommunityLoggingView(fedComB),
|
||||
})
|
||||
try {
|
||||
const homeCom = await DbCommunity.findOneByOrFail({ foreign: false })
|
||||
|
||||
@ -88,7 +99,10 @@ export async function startAuthentication(
|
||||
callbackCom.communityUuid = fedComUuid
|
||||
callbackCom.authenticatedAt = new Date()
|
||||
await DbCommunity.save(callbackCom)
|
||||
logger.debug('Authentication: Community Authentication successful:', callbackCom)
|
||||
logger.debug(
|
||||
'Authentication: Community Authentication successful:',
|
||||
new CommunityLoggingView(callbackCom),
|
||||
)
|
||||
} else {
|
||||
logger.error('Authentication: Community Authentication failed:', authenticationArgs)
|
||||
}
|
||||
|
||||
@ -60,7 +60,8 @@
|
||||
/* external */
|
||||
"@typeorm/*": ["../backend/src/typeorm/*", "../../backend/src/typeorm/*"],
|
||||
"@dbTools/*": ["../database/src/*", "../../database/build/src/*"],
|
||||
"@entity/*": ["../database/entity/*", "../../database/build/entity/*"]
|
||||
"@entity/*": ["../database/entity/*", "../../database/build/entity/*"],
|
||||
"@logging/*": ["../database/logging/*", "../../database/build/logging/*"]
|
||||
},
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
"typeRoots": ["node_modules/@types"], /* List of folders to include type definitions from. */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user