refactor(core): Add telemetry for RBAC roles (#7969)

Add telemetry for RBAC roles, see
[requirements](https://linear.app/n8n/issue/PAY-1067/add-telemetry-events-for-adding-and-assigning-admin-users#comment-184619fe).
This commit is contained in:
Iván Ovejero 2023-12-13 12:22:11 +01:00 committed by GitHub
parent 8f364087c9
commit a70a5076ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 2 deletions

View file

@ -356,6 +356,13 @@ export interface IInternalHooksClass {
target_user_id: string[];
public_api: boolean;
email_sent: boolean;
invitee_role: string;
}): Promise<void>;
onUserRoleChange(userInviteData: {
user: User;
target_user_id: string;
public_api: boolean;
target_user_new_role: string;
}): Promise<void>;
onUserReinvite(userReinviteData: {
user: User;

View file

@ -498,6 +498,7 @@ export class InternalHooks implements IInternalHooksClass {
target_user_id: string[];
public_api: boolean;
email_sent: boolean;
invitee_role: string;
}): Promise<void> {
void Promise.all([
eventBus.sendAuditEvent({
@ -507,15 +508,28 @@ export class InternalHooks implements IInternalHooksClass {
targetUserId: userInviteData.target_user_id,
},
}),
this.telemetry.track('User invited new user', {
user_id: userInviteData.user.id,
target_user_id: userInviteData.target_user_id,
public_api: userInviteData.public_api,
email_sent: userInviteData.email_sent,
invitee_role: userInviteData.invitee_role,
}),
]);
}
async onUserRoleChange(userRoleChangeData: {
user: User;
target_user_id: string;
public_api: boolean;
target_user_new_role: string;
}) {
const { user, ...rest } = userRoleChangeData;
void this.telemetry.track('User changed role', { user_id: user.id, ...rest });
}
async onUserReinvite(userReinviteData: {
user: User;
target_user_id: string;

View file

@ -391,6 +391,13 @@ export class UsersController {
await this.userService.update(targetUser.id, { globalRole: roleToSet });
void this.internalHooks.onUserRoleChange({
user: req.user,
target_user_id: targetUser.id,
target_user_new_role: [newRole.scope, newRole.name].join(' '),
public_api: false,
});
return { success: true };
}
}

View file

@ -188,7 +188,11 @@ export class UserService {
return Promise.race([fetchPromise, timeoutPromise]);
}
private async sendEmails(owner: User, toInviteUsers: { [key: string]: string }) {
private async sendEmails(
owner: User,
toInviteUsers: { [key: string]: string },
role: 'member' | 'admin',
) {
const domain = getInstanceBaseUrl();
return Promise.all(
@ -225,6 +229,7 @@ export class UserService {
target_user_id: Object.values(toInviteUsers),
public_api: false,
email_sent: result.emailSent,
invitee_role: role, // same role for all invited users
});
} catch (e) {
if (e instanceof Error) {
@ -294,7 +299,11 @@ export class UserService {
pendingUsersToInvite.forEach(({ email, id }) => createdUsers.set(email, id));
const usersInvited = await this.sendEmails(owner, Object.fromEntries(createdUsers));
const usersInvited = await this.sendEmails(
owner,
Object.fromEntries(createdUsers),
toCreateUsers[0].role, // same role for all invited users
);
return { usersInvited, usersCreated: toCreateUsers.map(({ email }) => email) };
}