Skip to content

Commit

Permalink
fix: update api key creator when he is removed
Browse files Browse the repository at this point in the history
  • Loading branch information
scopsy committed Sep 7, 2022
1 parent 3612f8f commit 95cc45d
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 7 deletions.
1 change: 1 addition & 0 deletions .idea/runConfigurations/API_E2E.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MemberEntity, OrganizationRepository, MemberRepository } from '@novu/dal';
import { MemberEntity, OrganizationRepository, MemberRepository, EnvironmentRepository } from '@novu/dal';
import { UserSession } from '@novu/testing';

import { MemberRoleEnum, MemberStatusEnum } from '@novu/shared';
Expand All @@ -7,9 +7,8 @@ import { describe } from 'mocha';

describe('Remove organization member - /organizations/members/:memberId (DELETE)', async () => {
let session: UserSession;
const organizationRepository = new OrganizationRepository();
const memberRepository = new MemberRepository();

const environmentRepository = new EnvironmentRepository();
let user2: UserSession;
let user3: UserSession;

Expand Down Expand Up @@ -45,6 +44,23 @@ describe('Remove organization member - /organizations/members/:memberId (DELETE)
user3.organization = session.organization;
});

it('should switch the apiKey association when api key creator removed', async function () {
const members: MemberEntity[] = await getOrganizationMembers();
const originalCreator = members.find((i) => i._userId === session.user._id);
await user2.fetchJWT();

expect(session.environment.apiKeys[0]._userId).to.equal(session.user._id);
const { body } = await user2.testAgent.delete(`/v1/organizations/members/${originalCreator._id}`);
expect(body.data._id).to.equal(originalCreator._id);

const membersAfterRemoval: MemberEntity[] = await getOrganizationMembers(user2);
const originalCreatorAfterRemoval = membersAfterRemoval.find((i) => i._userId === originalCreator.user._id);
expect(originalCreatorAfterRemoval).to.not.be.ok;

const environment = await environmentRepository.findById(session.environment._id);
expect(environment.apiKeys[0]._userId).to.not.equal(session.user._id);
});

it('should remove the member by his id', async () => {
const members: MemberEntity[] = await getOrganizationMembers();
const user2Member = members.find((i) => i._userId === user2.user._id);
Expand All @@ -57,10 +73,16 @@ describe('Remove organization member - /organizations/members/:memberId (DELETE)
const user2Removed = membersAfterRemoval.find((i) => i._userId === user2.user._id);

expect(user2Removed).to.not.be.ok;

/**
* The API Key owner should not be updated if non creator was removed
*/
const environment = await environmentRepository.findById(session.environment._id);
expect(environment.apiKeys[0]._userId).to.equal(session.user._id);
});

async function getOrganizationMembers() {
const { body } = await session.testAgent.get('/v1/organizations/members');
async function getOrganizationMembers(sessionToUser = session) {
const { body } = await sessionToUser.testAgent.get('/v1/organizations/members');

return body.data;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { Injectable, NotFoundException, Scope } from '@nestjs/common';
import { OrganizationRepository, MemberRepository } from '@novu/dal';
import { OrganizationRepository, MemberRepository, EnvironmentRepository } from '@novu/dal';
import { RemoveMemberCommand } from './remove-member.command';
import { ApiException } from '../../../../shared/exceptions/api.exception';

@Injectable({
scope: Scope.REQUEST,
})
export class RemoveMember {
constructor(private organizationRepository: OrganizationRepository, private memberRepository: MemberRepository) {}
constructor(
private organizationRepository: OrganizationRepository,
private memberRepository: MemberRepository,
private environmentRepository: EnvironmentRepository
) {}

async execute(command: RemoveMemberCommand) {
const members = await this.memberRepository.getOrganizationMembers(command.organizationId);
Expand All @@ -19,6 +23,20 @@ export class RemoveMember {
}

await this.memberRepository.removeMemberById(command.organizationId, memberToRemove._id);
const environments = await this.environmentRepository.findOrganizationEnvironments(command.organizationId);
const isMemberAssociatedWithEnvironment = environments.some((i) =>
i.apiKeys.some((key) => key._userId === memberToRemove._userId)
);

if (isMemberAssociatedWithEnvironment) {
const admin = await this.memberRepository.getOrganizationAdminAccount(command.organizationId);

await this.environmentRepository.updateApiKeyUserId(
command.organizationId,
memberToRemove._userId,
admin._userId
);
}

return memberToRemove;
}
Expand Down
14 changes: 14 additions & 0 deletions libs/dal/src/repositories/environment/environment.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ export class EnvironmentRepository extends BaseRepository<EnvironmentEntity> {
});
}

async updateApiKeyUserId(organizationId: string, oldUserId: string, newUserId: string) {
return await this.update(
{
_organizationId: organizationId,
'apiKeys._userId': oldUserId,
},
{
$set: {
'apiKeys.$._userId': newUserId,
},
}
);
}

async findOrganizationEnvironments(organizationId: string) {
return this.find({
_organizationId: organizationId,
Expand Down

0 comments on commit 95cc45d

Please sign in to comment.