fix(core): Include role in user-invite-email-click (#21546)

This commit is contained in:
Andreas Fitzek 2025-11-04 16:26:35 +01:00 committed by GitHub
parent 4dc58aacf8
commit 27fd768deb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 45 additions and 5 deletions

View File

@ -12,9 +12,15 @@ export class UserRepository extends Repository<User> {
super(User, dataSource.manager);
}
async findManyByIds(userIds: string[]) {
async findManyByIds(
userIds: string[],
options?: {
includeRole: boolean;
},
) {
return await this.find({
where: { id: In(userIds) },
relations: options?.includeRole ? ['role'] : undefined,
});
}

View File

@ -5,7 +5,7 @@ type UserLike = {
email?: string;
firstName?: string;
lastName?: string;
role: {
role?: {
slug: string;
};
};
@ -24,7 +24,7 @@ function toRedactable(userLike: UserLike) {
_email: userLike.email,
_firstName: userLike.firstName,
_lastName: userLike.lastName,
globalRole: userLike.role.slug,
globalRole: userLike.role?.slug,
};
}

View File

@ -150,7 +150,9 @@ export class AuthController {
throw new ForbiddenError(RESPONSE_ERROR_MESSAGES.USERS_QUOTA_REACHED);
}
const users = await this.userRepository.findManyByIds([inviterId, inviteeId]);
const users = await this.userRepository.findManyByIds([inviterId, inviteeId], {
includeRole: true,
});
if (users.length !== 2) {
this.logger.debug(

View File

@ -16,7 +16,7 @@ export type UserLike = {
email?: string;
firstName?: string;
lastName?: string;
role: {
role?: {
slug: string;
};
};

View File

@ -12,6 +12,8 @@ import { LOGGED_OUT_RESPONSE_BODY } from './shared/constants';
import { createUser, createUserShell } from './shared/db/users';
import type { SuperAgentTest } from './shared/types';
import * as utils from './shared/utils/';
import { EventService } from '@/events/event.service';
import type { RelayEventMap } from '@/events/maps/relay.event-map';
let owner: User;
let authOwnerAgent: SuperAgentTest;
@ -392,6 +394,36 @@ describe('GET /resolve-signup-token', () => {
expect(response.statusCode).toBe(400);
}
});
test('should send roles for user-invite-email-click event', async () => {
const memberShell = await createUserShell(GLOBAL_MEMBER_ROLE);
const eventService = Container.get(EventService);
const emitSpy = jest.spyOn(eventService, 'emit');
await authOwnerAgent
.get('/resolve-signup-token')
.query({ inviterId: owner.id })
.query({ inviteeId: memberShell.id })
.expect(200);
// Check all emitted events
let foundEvent = false;
for (const [eventName, payload] of emitSpy.mock.calls) {
if (eventName === 'user-invite-email-click') {
foundEvent = true;
expect(payload).toBeDefined();
const { invitee, inviter } = payload as RelayEventMap['user-invite-email-click'];
expect(invitee.role).toBeDefined();
expect(invitee.role?.slug).toBe('global:member');
expect(inviter.role).toBeDefined();
expect(inviter.role?.slug).toBe('global:owner');
}
}
expect(foundEvent).toBe(true);
emitSpy.mockRestore();
});
});
describe('POST /logout', () => {