From c5a5067155b13479372e1099a82013af6c465e12 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Sat, 4 Oct 2025 10:23:39 +0200 Subject: [PATCH 1/4] update rights, prevent gms api access for others than admins --- admin/src/graphql/updateHomeCommunity.js | 2 +- backend/src/auth/ADMIN_RIGHTS.ts | 4 +--- backend/src/auth/DLT_CONNECTOR_RIGHTS.ts | 2 +- backend/src/auth/RIGHTS.ts | 4 +--- backend/src/graphql/model/AdminCommunityView.ts | 1 - backend/src/graphql/model/Community.ts | 4 ---- .../src/graphql/resolver/CommunityResolver.test.ts | 10 +++++----- backend/src/graphql/resolver/CommunityResolver.ts | 12 ++++++------ backend/src/seeds/graphql/mutations.ts | 1 - backend/src/seeds/graphql/queries.ts | 3 --- 10 files changed, 15 insertions(+), 28 deletions(-) diff --git a/admin/src/graphql/updateHomeCommunity.js b/admin/src/graphql/updateHomeCommunity.js index 19bfb7396..036db91e5 100644 --- a/admin/src/graphql/updateHomeCommunity.js +++ b/admin/src/graphql/updateHomeCommunity.js @@ -8,7 +8,7 @@ export const updateHomeCommunity = gql` location: $location hieroTopicId: $hieroTopicId ) { - id + uuid } } ` diff --git a/backend/src/auth/ADMIN_RIGHTS.ts b/backend/src/auth/ADMIN_RIGHTS.ts index 9ba3e7ccd..69100d7d2 100644 --- a/backend/src/auth/ADMIN_RIGHTS.ts +++ b/backend/src/auth/ADMIN_RIGHTS.ts @@ -5,8 +5,6 @@ export const ADMIN_RIGHTS = [ RIGHTS.DELETE_USER, RIGHTS.UNDELETE_USER, RIGHTS.COMMUNITY_UPDATE, - RIGHTS.COMMUNITY_BY_UUID, - RIGHTS.COMMUNITY_BY_IDENTIFIER, - RIGHTS.HOME_COMMUNITY, + RIGHTS.COMMUNITY_WITH_API_KEYS, RIGHTS.PROJECT_BRANDING_MUTATE, ] diff --git a/backend/src/auth/DLT_CONNECTOR_RIGHTS.ts b/backend/src/auth/DLT_CONNECTOR_RIGHTS.ts index 399b7c2d4..9b4c56eaa 100644 --- a/backend/src/auth/DLT_CONNECTOR_RIGHTS.ts +++ b/backend/src/auth/DLT_CONNECTOR_RIGHTS.ts @@ -1,3 +1,3 @@ import { RIGHTS } from './RIGHTS' -export const DLT_CONNECTOR_RIGHTS = [RIGHTS.COMMUNITY_BY_IDENTIFIER, RIGHTS.HOME_COMMUNITY] +export const DLT_CONNECTOR_RIGHTS = [RIGHTS.COMMUNITIES, RIGHTS.COMMUNITY_UPDATE] diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index 012a4e627..d26bdc702 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -69,9 +69,7 @@ export enum RIGHTS { SET_USER_ROLE = 'SET_USER_ROLE', DELETE_USER = 'DELETE_USER', UNDELETE_USER = 'UNDELETE_USER', - COMMUNITY_BY_UUID = 'COMMUNITY_BY_UUID', - COMMUNITY_BY_IDENTIFIER = 'COMMUNITY_BY_IDENTIFIER', - HOME_COMMUNITY = 'HOME_COMMUNITY', COMMUNITY_UPDATE = 'COMMUNITY_UPDATE', + COMMUNITY_WITH_API_KEYS = 'COMMUNITY_WITH_API_KEYS', PROJECT_BRANDING_MUTATE = 'PROJECT_BRANDING_MUTATE', } diff --git a/backend/src/graphql/model/AdminCommunityView.ts b/backend/src/graphql/model/AdminCommunityView.ts index 50cee146a..8a685fa86 100644 --- a/backend/src/graphql/model/AdminCommunityView.ts +++ b/backend/src/graphql/model/AdminCommunityView.ts @@ -38,7 +38,6 @@ export class AdminCommunityView { this.updatedAt = dbCom.updatedAt this.uuid = dbCom.communityUuid this.authenticatedAt = dbCom.authenticatedAt - this.gmsApiKey = dbCom.gmsApiKey this.hieroTopicId = dbCom.hieroTopicId if (dbCom.location) { this.location = Point2Location(dbCom.location as Point) diff --git a/backend/src/graphql/model/Community.ts b/backend/src/graphql/model/Community.ts index 62cec9cf7..e5ccad59b 100644 --- a/backend/src/graphql/model/Community.ts +++ b/backend/src/graphql/model/Community.ts @@ -12,7 +12,6 @@ export class Community { this.creationDate = dbCom.creationDate this.uuid = dbCom.communityUuid this.authenticatedAt = dbCom.authenticatedAt - this.gmsApiKey = dbCom.gmsApiKey this.hieroTopicId = dbCom.hieroTopicId } @@ -40,9 +39,6 @@ export class Community { @Field(() => Date, { nullable: true }) authenticatedAt: Date | null - @Field(() => String, { nullable: true }) - gmsApiKey: string | null - @Field(() => String, { nullable: true }) hieroTopicId: string | null } diff --git a/backend/src/graphql/resolver/CommunityResolver.test.ts b/backend/src/graphql/resolver/CommunityResolver.test.ts index c9c925a2e..20a3680e3 100644 --- a/backend/src/graphql/resolver/CommunityResolver.test.ts +++ b/backend/src/graphql/resolver/CommunityResolver.test.ts @@ -324,6 +324,10 @@ describe('CommunityResolver', () => { beforeEach(async () => { jest.clearAllMocks() + await userFactory(testEnv, peterLustig) + // login as admin + await mutate({ mutation: login, variables: peterLoginData }) + comHomeCom1 = DbCommunity.create() comHomeCom1.foreign = false comHomeCom1.url = 'http://localhost' @@ -547,13 +551,10 @@ describe('CommunityResolver', () => { describe('with empty list', () => { beforeEach(async () => { - await cleanDB() - jest.clearAllMocks() + await DbCommunity.clear() }) it('returns no community entry', async () => { - // const result: Community[] = await query({ query: getCommunities }) - // expect(result.length).toEqual(0) await expect(query({ query: communitiesQuery })).resolves.toMatchObject({ data: { communities: [], @@ -785,7 +786,6 @@ describe('CommunityResolver', () => { ).resolves.toMatchObject({ data: { updateHomeCommunity: { - id: expect.any(Number), foreign: homeCom?.foreign, name: homeCom?.name, description: homeCom?.description, diff --git a/backend/src/graphql/resolver/CommunityResolver.ts b/backend/src/graphql/resolver/CommunityResolver.ts index a46e30144..5fe7eea44 100644 --- a/backend/src/graphql/resolver/CommunityResolver.ts +++ b/backend/src/graphql/resolver/CommunityResolver.ts @@ -35,7 +35,7 @@ export class CommunityResolver { ) } - @Authorized([RIGHTS.COMMUNITIES]) + @Authorized([RIGHTS.COMMUNITY_WITH_API_KEYS]) @Query(() => [AdminCommunityView]) async allCommunities(@Args() paginated: Paginated): Promise { // communityUUID could be oneTimePassCode (uint32 number) @@ -54,7 +54,7 @@ export class CommunityResolver { return dbCommunities.map((dbCom: DbCommunity) => new Community(dbCom)) } - @Authorized([RIGHTS.COMMUNITY_BY_IDENTIFIER]) + @Authorized([RIGHTS.COMMUNITIES]) @Query(() => Community) async communityByIdentifier( @Arg('communityIdentifier') communityIdentifier: string, @@ -67,7 +67,7 @@ export class CommunityResolver { return new Community(community) } - @Authorized([RIGHTS.HOME_COMMUNITY]) + @Authorized([RIGHTS.COMMUNITIES]) @Query(() => Community) async homeCommunity(): Promise { const community = await getHomeCommunity() @@ -78,10 +78,10 @@ export class CommunityResolver { } @Authorized([RIGHTS.COMMUNITY_UPDATE]) - @Mutation(() => Community) + @Mutation(() => AdminCommunityView) async updateHomeCommunity( @Args() { uuid, gmsApiKey, location, hieroTopicId }: EditCommunityInput, - ): Promise { + ): Promise { const homeCom = await getCommunityByUuid(uuid) if (!homeCom) { throw new LogError('HomeCommunity with uuid not found: ', uuid) @@ -101,6 +101,6 @@ export class CommunityResolver { homeCom.hieroTopicId = hieroTopicId ?? null await DbCommunity.save(homeCom) } - return new Community(homeCom) + return new AdminCommunityView(homeCom) } } diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index ec0a966a8..e42e738f2 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -375,7 +375,6 @@ export const logout = gql` export const updateHomeCommunityQuery = gql` mutation ($uuid: String!, $gmsApiKey: String!) { updateHomeCommunity(uuid: $uuid, gmsApiKey: $gmsApiKey) { - id foreign name description diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index 5a8e06cc0..466e96516 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -146,7 +146,6 @@ export const communitiesQuery = gql` creationDate uuid authenticatedAt - gmsApiKey } } ` @@ -162,7 +161,6 @@ export const getCommunityByIdentifierQuery = gql` creationDate uuid authenticatedAt - gmsApiKey } } ` @@ -178,7 +176,6 @@ export const getHomeCommunityQuery = gql` creationDate uuid authenticatedAt - gmsApiKey } } ` From ad1185daf89a68b7499107c386c836119e489350 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Sat, 4 Oct 2025 10:33:43 +0200 Subject: [PATCH 2/4] fix --- .../resolver/CommunityResolver.test.ts | 8 ------- .../src/graphql/resolver/CommunityResolver.ts | 21 ------------------- 2 files changed, 29 deletions(-) diff --git a/backend/src/graphql/resolver/CommunityResolver.test.ts b/backend/src/graphql/resolver/CommunityResolver.test.ts index c952baf1b..5e7d929e2 100644 --- a/backend/src/graphql/resolver/CommunityResolver.test.ts +++ b/backend/src/graphql/resolver/CommunityResolver.test.ts @@ -227,14 +227,6 @@ describe('CommunityResolver', () => { let foreignCom4: DbFederatedCommunity beforeEach(async () => { -<<<<<<< HEAD -======= - jest.clearAllMocks() - await userFactory(testEnv, peterLustig) - // login as admin - await mutate({ mutation: login, variables: peterLoginData }) - ->>>>>>> refactor_community_auth comHomeCom1 = DbCommunity.create() comHomeCom1.foreign = false comHomeCom1.url = 'http://localhost' diff --git a/backend/src/graphql/resolver/CommunityResolver.ts b/backend/src/graphql/resolver/CommunityResolver.ts index cd199900a..c3604812e 100644 --- a/backend/src/graphql/resolver/CommunityResolver.ts +++ b/backend/src/graphql/resolver/CommunityResolver.ts @@ -24,24 +24,6 @@ import { CONFIG } from '@/config' @Resolver() export class CommunityResolver { -<<<<<<< HEAD -======= - @Authorized([RIGHTS.COMMUNITIES]) - @Query(() => [FederatedCommunity]) - async getCommunities(): Promise { - const dbFederatedCommunities: DbFederatedCommunity[] = await DbFederatedCommunity.find({ - order: { - foreign: 'ASC', - createdAt: 'DESC', - lastAnnouncedAt: 'DESC', - }, - }) - return dbFederatedCommunities.map( - (dbCom: DbFederatedCommunity) => new FederatedCommunity(dbCom), - ) - } - ->>>>>>> refactor_community_auth @Authorized([RIGHTS.COMMUNITY_WITH_API_KEYS]) @Query(() => [AdminCommunityView]) async allCommunities(@Args() paginated: Paginated): Promise { @@ -113,10 +95,7 @@ export class CommunityResolver { } await DbCommunity.save(homeCom) } -<<<<<<< HEAD -======= ->>>>>>> refactor_community_auth return new AdminCommunityView(homeCom) } } From ba6a390c7a9ede69309274d58e9d69ffe205bdbb Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Sat, 4 Oct 2025 10:35:18 +0200 Subject: [PATCH 3/4] rollback accidently changes --- backend/src/auth/RIGHTS.ts | 1 - backend/src/auth/USER_RIGHTS.ts | 1 - backend/src/federation/client/FederationClientFactory.ts | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index 30027086f..d26bdc702 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -35,7 +35,6 @@ export enum RIGHTS { UPDATE_CONTRIBUTION = 'UPDATE_CONTRIBUTION', LIST_CONTRIBUTION_LINKS = 'LIST_CONTRIBUTION_LINKS', COMMUNITY_STATISTICS = 'COMMUNITY_STATISTICS', - COMMUNITY_STATUS = 'COMMUNITY_STATUS', SEARCH_ADMIN_USERS = 'SEARCH_ADMIN_USERS', CREATE_CONTRIBUTION_MESSAGE = 'CREATE_CONTRIBUTION_MESSAGE', LIST_ALL_CONTRIBUTION_MESSAGES = 'LIST_ALL_CONTRIBUTION_MESSAGES', diff --git a/backend/src/auth/USER_RIGHTS.ts b/backend/src/auth/USER_RIGHTS.ts index 83ce9d871..3f08d1160 100644 --- a/backend/src/auth/USER_RIGHTS.ts +++ b/backend/src/auth/USER_RIGHTS.ts @@ -26,7 +26,6 @@ export const USER_RIGHTS = [ RIGHTS.SEARCH_ADMIN_USERS, RIGHTS.LIST_CONTRIBUTION_LINKS, RIGHTS.COMMUNITY_STATISTICS, - RIGHTS.COMMUNITY_STATUS, RIGHTS.CREATE_CONTRIBUTION_MESSAGE, RIGHTS.LIST_ALL_CONTRIBUTION_MESSAGES, RIGHTS.OPEN_CREATIONS, diff --git a/backend/src/federation/client/FederationClientFactory.ts b/backend/src/federation/client/FederationClientFactory.ts index 87794882d..926c3c180 100644 --- a/backend/src/federation/client/FederationClientFactory.ts +++ b/backend/src/federation/client/FederationClientFactory.ts @@ -4,7 +4,7 @@ import { FederationClient as V1_0_FederationClient } from '@/federation/client/1 import { FederationClient as V1_1_FederationClient } from '@/federation/client/1_1/FederationClient' import { ApiVersionType, ensureUrlEndsWithSlash } from 'core' -export type FederationClient = V1_0_FederationClient | V1_1_FederationClient +type FederationClient = V1_0_FederationClient | V1_1_FederationClient interface FederationClientInstance { id: number From 05f3742525282c4ea0fff5e6a0a3dea6ee8e2c29 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Sat, 4 Oct 2025 10:40:10 +0200 Subject: [PATCH 4/4] rollback --- backend/src/graphql/resolver/CommunityResolver.ts | 8 +------- backend/src/graphql/resolver/TransactionResolver.ts | 2 +- backend/test/helpers.ts | 6 ++---- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/backend/src/graphql/resolver/CommunityResolver.ts b/backend/src/graphql/resolver/CommunityResolver.ts index c3604812e..675ec858f 100644 --- a/backend/src/graphql/resolver/CommunityResolver.ts +++ b/backend/src/graphql/resolver/CommunityResolver.ts @@ -78,24 +78,18 @@ export class CommunityResolver { if (homeCom.foreign) { throw new LogError('Error: Only the HomeCommunity could be modified!') } - if ( homeCom.gmsApiKey !== gmsApiKey || homeCom.location !== location || homeCom.hieroTopicId !== hieroTopicId ) { - // TODO: think about this, it is really expected to delete gmsApiKey if no new one is given? homeCom.gmsApiKey = gmsApiKey ?? null if (location) { homeCom.location = Location2Point(location) } - // update only with new value, don't overwrite existing value with null or undefined! - if (hieroTopicId) { - homeCom.hieroTopicId = hieroTopicId - } + homeCom.hieroTopicId = hieroTopicId ?? null await DbCommunity.save(homeCom) } - return new AdminCommunityView(homeCom) } } diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index fa6170013..a61356e29 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -447,7 +447,7 @@ export class TransactionResolver { recipientCommunityIdentifier, ) if (!recipientUser) { - throw new LogError('The recipient user was not found', { recipientIdentifier, recipientCommunityIdentifier }) + throw new LogError('The recipient user was not found', recipientUser) } logger.addContext('to', recipientUser?.id) if (recipientUser.foreign) { diff --git a/backend/test/helpers.ts b/backend/test/helpers.ts index ff0c513e7..c7f533931 100644 --- a/backend/test/helpers.ts +++ b/backend/test/helpers.ts @@ -39,13 +39,11 @@ export const testEnvironment = async (testLogger = getLogger('apollo'), testI18n } export const resetEntity = async (entity: any) => { - // delete data and reset autoincrement! - await entity.clear() - /*const items = await entity.find({ withDeleted: true }) + const items = await entity.find({ withDeleted: true }) if (items.length > 0) { const ids = items.map((e: any) => e.id) await entity.delete(ids) - }*/ + } } export const resetToken = () => {