log bug fix. use federated_communities.verified_at instead of communities.authenticated_at date for deciding reachable communities

This commit is contained in:
einhornimmond 2025-10-01 13:49:10 +02:00
parent bc213707d7
commit f8ef8e111e
5 changed files with 86 additions and 45 deletions

View File

@ -16,10 +16,9 @@ import {
reachableCommunities,
} from '@/seeds/graphql/queries'
import { peterLustig } from '@/seeds/users/peter-lustig'
import { createCommunity, createAuthenticatedForeignCommunity } from 'database/src/seeds/community'
import { createCommunity, createVerifiedFederatedCommunity } from 'database/src/seeds/community'
import { getLogger } from 'config-schema/test/testSetup'
import { getCommunityByUuid } from './util/communities'
import { CONFIG } from '@/config'
jest.mock('@/password/EncryptorUtils')
@ -445,6 +444,7 @@ describe('CommunityResolver', () => {
afterAll(async () => {
await DbCommunity.clear()
await DbFederatedCommunity.clear()
})
describe('with empty list', () => {
@ -483,33 +483,37 @@ describe('CommunityResolver', () => {
describe('returns 2 filtered communities even with 3 existing entries', () => {
beforeEach(async () => {
foreignCom1 = await createCommunity(true, false)
foreignCom2 = await createAuthenticatedForeignCommunity(100, false)
foreignCom2 = await createCommunity(true, false)
const com1FedCom = await createVerifiedFederatedCommunity('1_0', 100, foreignCom1, false)
const com1FedCom2 = await createVerifiedFederatedCommunity('1_1', 100, foreignCom1, false)
const com2FedCom = await createVerifiedFederatedCommunity('1_0', 10000, foreignCom2, false)
await Promise.all([
DbCommunity.insert(foreignCom1),
DbCommunity.insert(foreignCom2)
DbCommunity.insert(foreignCom2),
DbFederatedCommunity.insert(com1FedCom),
DbFederatedCommunity.insert(com1FedCom2),
DbFederatedCommunity.insert(com2FedCom)
])
})
it('returns 2 community entries', async () => {
await expect(query({ query: reachableCommunities })).resolves.toMatchObject({
data: {
reachableCommunities: [
{
foreign: homeCom1.foreign,
name: homeCom1.name,
description: homeCom1.description,
url: homeCom1.url,
uuid: homeCom1.communityUuid,
}, {
foreign: foreignCom2.foreign,
name: foreignCom2.name,
description: foreignCom2.description,
url: foreignCom2.url,
uuid: foreignCom2.communityUuid,
},
],
},
})
const result = await query({ query: reachableCommunities })
expect(result.data.reachableCommunities.length).toBe(2)
expect(result.data.reachableCommunities).toMatchObject([
{
foreign: homeCom1.foreign,
name: homeCom1.name,
description: homeCom1.description,
url: homeCom1.url,
uuid: homeCom1.communityUuid,
}, {
foreign: foreignCom1.foreign,
name: foreignCom1.name,
description: foreignCom1.description,
url: foreignCom1.url,
uuid: foreignCom1.communityUuid,
}
])
})
})

View File

@ -33,7 +33,7 @@ function composeDataString(data: (string | Object)[]): string {
return data
.map((d) => {
// if it is a object and his toString function return only garbage
if (typeof d === 'object' && d.toString() === '[object Object]') {
if (d && typeof d === 'object' && d.toString() === '[object Object]') {
return inspect(d, )
}
if (d) {

View File

@ -1,8 +1,8 @@
import { Community as DbCommunity } from '..'
import { Community as DbCommunity, FederatedCommunity as DbFederatedCommunity } from '..'
import { AppDatabase } from '../AppDatabase'
import { getHomeCommunity, getReachableCommunities } from './communities'
import { describe, expect, it, beforeEach, beforeAll, afterAll } from 'vitest'
import { createCommunity, createAuthenticatedForeignCommunity } from '../seeds/community'
import { createCommunity, createVerifiedFederatedCommunity } from '../seeds/community'
const db = AppDatabase.getInstance()
@ -17,6 +17,7 @@ describe('community.queries', () => {
// clean db for every test case
beforeEach(async () => {
await DbCommunity.clear()
await DbFederatedCommunity.clear()
})
describe('getHomeCommunity', () => {
it('should return null if no home community exists', async () => {
@ -44,21 +45,44 @@ describe('community.queries', () => {
expect(await getReachableCommunities(1000)).toHaveLength(1)
})
it('foreign communities authenticated within chosen range', async () => {
await createAuthenticatedForeignCommunity(400)
await createAuthenticatedForeignCommunity(500)
await createAuthenticatedForeignCommunity(1200)
const com1 = await createCommunity(true)
const com2 = await createCommunity(true)
const com3 = await createCommunity(true)
await createVerifiedFederatedCommunity('1_0', 100, com1)
await createVerifiedFederatedCommunity('1_0', 500, com2)
// outside of range
await createVerifiedFederatedCommunity('1_0', 1200, com3)
const community = await getReachableCommunities(1000)
expect(community).toHaveLength(2)
const communities = await getReachableCommunities(1000)
expect(communities).toHaveLength(2)
expect(communities[0].communityUuid).toBe(com1.communityUuid)
expect(communities[1].communityUuid).toBe(com2.communityUuid)
})
it('multiple federated community api version, result in one community', async () => {
const com1 = await createCommunity(true)
await createVerifiedFederatedCommunity('1_0', 100, com1)
await createVerifiedFederatedCommunity('1_1', 100, com1)
expect(await getReachableCommunities(1000)).toHaveLength(1)
})
it('multiple federated community api version one outside of range, result in one community', async () => {
const com1 = await createCommunity(true)
await createVerifiedFederatedCommunity('1_0', 100, com1)
// outside of range
await createVerifiedFederatedCommunity('1_1', 1200, com1)
expect(await getReachableCommunities(1000)).toHaveLength(1)
})
it('foreign and home community', async () => {
// home community
await createCommunity(false)
await createAuthenticatedForeignCommunity(400)
await createAuthenticatedForeignCommunity(1200)
const com1 = await createCommunity(true)
const com2 = await createCommunity(true)
await createVerifiedFederatedCommunity('1_0', 400, com1)
await createVerifiedFederatedCommunity('1_0', 1200, com2)
expect(await getReachableCommunities(1000)).toHaveLength(2)
})
it('not authenticated foreign community', async () => {
await createCommunity(true)
it('not verified inside time frame federated community', async () => {
const com1 = await createCommunity(true)
await createVerifiedFederatedCommunity('1_0', 1200, com1)
expect(await getReachableCommunities(1000)).toHaveLength(0)
})
})

View File

@ -43,14 +43,19 @@ export async function getCommunityWithFederatedCommunityByIdentifier(
}
// returns all reachable communities
// home community and all foreign communities which have been authenticated within the last authenticationTimeoutMs
// home community and all federated communities which have been verified within the last authenticationTimeoutMs
export async function getReachableCommunities(
authenticationTimeoutMs: number,
order?: FindOptionsOrder<DbCommunity>
): Promise<DbCommunity[]> {
return await DbCommunity.find({
where: [
{ communityUuid: Not(IsNull()), authenticatedAt: MoreThanOrEqual(new Date(Date.now() - authenticationTimeoutMs)) },
{
authenticatedAt: Not(IsNull()),
federatedCommunities: {
verifiedAt: MoreThanOrEqual(new Date(Date.now() - authenticationTimeoutMs))
}
},
{ foreign: false },
],
order,

View File

@ -1,4 +1,4 @@
import { Community } from '../entity'
import { Community, FederatedCommunity } from '../entity'
import { randomBytes } from 'node:crypto'
import { v4 as uuidv4 } from 'uuid'
@ -14,8 +14,10 @@ export async function createCommunity(foreign: boolean, save: boolean = true): P
community.name = 'ForeignCommunity-name'
community.description = 'ForeignCommunity-description'
community.url = `http://foreign-${Math.random()}/api`
community.authenticatedAt = new Date()
} else {
community.foreign = false
// todo: generate valid public/private key pair (ed25519)
community.privateKey = randomBytes(64)
community.name = 'HomeCommunity-name'
community.description = 'HomeCommunity-description'
@ -24,11 +26,17 @@ export async function createCommunity(foreign: boolean, save: boolean = true): P
return save ? await community.save() : community
}
export async function createAuthenticatedForeignCommunity(
authenticatedBeforeMs: number,
export async function createVerifiedFederatedCommunity(
apiVersion: string,
verifiedBeforeMs: number,
community: Community,
save: boolean = true
): Promise<Community> {
const foreignCom = await createCommunity(true, false)
foreignCom.authenticatedAt = new Date(Date.now() - authenticatedBeforeMs)
return save ? await foreignCom.save() : foreignCom
}
): Promise<FederatedCommunity> {
const federatedCommunity = new FederatedCommunity()
federatedCommunity.apiVersion = apiVersion
federatedCommunity.endPoint = community.url
federatedCommunity.publicKey = community.publicKey
federatedCommunity.community = community
federatedCommunity.verifiedAt = new Date(Date.now() - verifiedBeforeMs)
return save ? await federatedCommunity.save() : federatedCommunity
}