refactor(core): Rename EventRelay to EventService (no-changelog) (#10110)

This commit is contained in:
Iván Ovejero 2024-07-19 12:55:38 +02:00 committed by GitHub
parent 222a0862bd
commit aba1c64500
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 203 additions and 195 deletions

View file

@ -13,7 +13,7 @@ import { Logger } from '@/Logger';
import { jsonParse, type IDataObject, ApplicationError } from 'n8n-workflow';
import { EXTERNAL_SECRETS_INITIAL_BACKOFF, EXTERNAL_SECRETS_MAX_BACKOFF } from './constants';
import { License } from '@/License';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
import { updateIntervalTime } from './externalSecretsHelper.ee';
import { ExternalSecretsProviders } from './ExternalSecretsProviders.ee';
import { OrchestrationService } from '@/services/orchestration.service';
@ -38,7 +38,7 @@ export class ExternalSecretsManager {
private readonly license: License,
private readonly secretsProviders: ExternalSecretsProviders,
private readonly cipher: Cipher,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
async init(): Promise<void> {
@ -309,7 +309,7 @@ export class ExternalSecretsManager {
try {
testResult = await this.getProvider(vaultType)?.test();
} catch {}
this.eventRelay.emit('external-secrets-provider-settings-saved', {
this.eventService.emit('external-secrets-provider-settings-saved', {
userId,
vaultType,
isNew,

View file

@ -18,7 +18,7 @@ import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import { ProjectRepository } from '@/databases/repositories/project.repository';
import { InternalHooks } from '@/InternalHooks';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
export async function getCredentials(credentialId: string): Promise<ICredentialsDb | null> {
return await Container.get(CredentialsRepository).findOneBy({ id: credentialId });
@ -60,7 +60,7 @@ export async function saveCredential(
credential_id: credential.id,
public_api: true,
});
Container.get(EventRelay).emit('credentials-created', {
Container.get(EventService).emit('credentials-created', {
user,
credentialName: credential.name,
credentialType: credential.type,
@ -102,7 +102,7 @@ export async function removeCredential(
credential_type: credentials.type,
credential_id: credentials.id,
});
Container.get(EventRelay).emit('credentials-deleted', {
Container.get(EventService).emit('credentials-deleted', {
user,
credentialName: credentials.name,
credentialType: credentials.type,

View file

@ -10,7 +10,7 @@ import {
getTrackingInformationFromPullResult,
isSourceControlLicensed,
} from '@/environments/sourceControl/sourceControlHelper.ee';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
export = {
pull: [
@ -39,7 +39,7 @@ export = {
});
if (result.statusCode === 200) {
Container.get(EventRelay).emit('source-control-user-pulled-api', {
Container.get(EventService).emit('source-control-user-pulled-api', {
...getTrackingInformationFromPullResult(result.statusResult),
forced: req.body.force ?? false,
});

View file

@ -32,7 +32,7 @@ import { SharedWorkflowRepository } from '@/databases/repositories/sharedWorkflo
import { TagRepository } from '@/databases/repositories/tag.repository';
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
import { ProjectRepository } from '@/databases/repositories/project.repository';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
export = {
createWorkflow: [
@ -59,7 +59,7 @@ export = {
await Container.get(ExternalHooks).run('workflow.afterCreate', [createdWorkflow]);
void Container.get(InternalHooks).onWorkflowCreated(req.user, createdWorkflow, project, true);
Container.get(EventRelay).emit('workflow-created', {
Container.get(EventService).emit('workflow-created', {
workflow: createdWorkflow,
user: req.user,
});
@ -240,7 +240,7 @@ export = {
await Container.get(ExternalHooks).run('workflow.afterUpdate', [updateData]);
void Container.get(InternalHooks).onWorkflowSaved(req.user, updateData, true);
Container.get(EventRelay).emit('workflow-saved', {
Container.get(EventService).emit('workflow-saved', {
user: req.user,
workflowId: updateData.id,
workflowName: updateData.name,

View file

@ -16,7 +16,7 @@ import { toError } from '@/utils';
import type { InviteEmailData, PasswordResetData, SendEmailResult } from './Interfaces';
import { NodeMailer } from './NodeMailer';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
type Template = HandlebarsTemplateDelegate<unknown>;
type TemplateName = 'invite' | 'passwordReset' | 'workflowShared' | 'credentialsShared';
@ -125,7 +125,7 @@ export class UserManagementMailer {
message_type: 'Workflow shared',
public_api: false,
});
Container.get(EventRelay).emit('email-failed', {
Container.get(EventService).emit('email-failed', {
user: sharer,
messageType: 'Workflow shared',
});
@ -184,7 +184,7 @@ export class UserManagementMailer {
message_type: 'Credentials shared',
public_api: false,
});
Container.get(EventRelay).emit('email-failed', {
Container.get(EventService).emit('email-failed', {
user: sharer,
messageType: 'Credentials shared',
});

View file

@ -71,7 +71,7 @@ import { WorkflowRepository } from './databases/repositories/workflow.repository
import { UrlService } from './services/url.service';
import { WorkflowExecutionService } from './workflows/workflowExecution.service';
import { MessageEventBus } from '@/eventbus/MessageEventBus/MessageEventBus';
import { EventRelay } from './eventbus/event-relay.service';
import { EventService } from './eventbus/event.service';
const ERROR_TRIGGER_TYPE = config.getEnv('nodes.errorTriggerType');
@ -394,20 +394,20 @@ export function hookFunctionsPreExecute(): IWorkflowExecuteHooks {
function hookFunctionsSave(): IWorkflowExecuteHooks {
const logger = Container.get(Logger);
const workflowStatisticsService = Container.get(WorkflowStatisticsService);
const eventRelay = Container.get(EventRelay);
const eventService = Container.get(EventService);
return {
nodeExecuteBefore: [
async function (this: WorkflowHooks, nodeName: string): Promise<void> {
const { executionId, workflowData: workflow } = this;
eventRelay.emit('node-pre-execute', { executionId, workflow, nodeName });
eventService.emit('node-pre-execute', { executionId, workflow, nodeName });
},
],
nodeExecuteAfter: [
async function (this: WorkflowHooks, nodeName: string): Promise<void> {
const { executionId, workflowData: workflow } = this;
eventRelay.emit('node-post-execute', { executionId, workflow, nodeName });
eventService.emit('node-post-execute', { executionId, workflow, nodeName });
},
],
workflowExecuteBefore: [],
@ -550,27 +550,27 @@ function hookFunctionsSaveWorker(): IWorkflowExecuteHooks {
const logger = Container.get(Logger);
const internalHooks = Container.get(InternalHooks);
const workflowStatisticsService = Container.get(WorkflowStatisticsService);
const eventRelay = Container.get(EventRelay);
const eventService = Container.get(EventService);
return {
nodeExecuteBefore: [
async function (this: WorkflowHooks, nodeName: string): Promise<void> {
const { executionId, workflowData: workflow } = this;
eventRelay.emit('node-pre-execute', { executionId, workflow, nodeName });
eventService.emit('node-pre-execute', { executionId, workflow, nodeName });
},
],
nodeExecuteAfter: [
async function (this: WorkflowHooks, nodeName: string): Promise<void> {
const { executionId, workflowData: workflow } = this;
eventRelay.emit('node-post-execute', { executionId, workflow, nodeName });
eventService.emit('node-post-execute', { executionId, workflow, nodeName });
},
],
workflowExecuteBefore: [
async function (): Promise<void> {
const { executionId, workflowData } = this;
eventRelay.emit('workflow-pre-execute', { executionId, data: workflowData });
eventService.emit('workflow-pre-execute', { executionId, data: workflowData });
},
],
workflowExecuteAfter: [
@ -646,7 +646,7 @@ function hookFunctionsSaveWorker(): IWorkflowExecuteHooks {
const { executionId, workflowData: workflow } = this;
void internalHooks.onWorkflowPostExecute(executionId, workflow, runData);
eventRelay.emit('workflow-post-execute', {
eventService.emit('workflow-post-execute', {
workflowId: workflow.id,
workflowName: workflow.name,
executionId,
@ -793,7 +793,7 @@ async function executeWorkflow(
const nodeTypes = Container.get(NodeTypes);
const activeExecutions = Container.get(ActiveExecutions);
const eventRelay = Container.get(EventRelay);
const eventService = Container.get(EventService);
const workflowData =
options.loadedWorkflowData ??
@ -821,7 +821,7 @@ async function executeWorkflow(
executionId = options.parentExecutionId ?? (await activeExecutions.add(runData));
}
Container.get(EventRelay).emit('workflow-pre-execute', { executionId, data: runData });
Container.get(EventService).emit('workflow-pre-execute', { executionId, data: runData });
let data;
try {
@ -934,7 +934,7 @@ async function executeWorkflow(
await externalHooks.run('workflow.postExecute', [data, workflowData, executionId]);
void internalHooks.onWorkflowPostExecute(executionId, workflowData, data, additionalData.userId);
eventRelay.emit('workflow-post-execute', {
eventService.emit('workflow-post-execute', {
workflowId: workflowData.id,
workflowName: workflowData.name,
executionId,

View file

@ -37,7 +37,7 @@ import { PermissionChecker } from '@/UserManagement/PermissionChecker';
import { InternalHooks } from '@/InternalHooks';
import { Logger } from '@/Logger';
import { WorkflowStaticDataService } from '@/workflows/workflowStaticData.service';
import { EventRelay } from './eventbus/event-relay.service';
import { EventService } from './eventbus/event.service';
@Service()
export class WorkflowRunner {
@ -53,7 +53,7 @@ export class WorkflowRunner {
private readonly workflowStaticDataService: WorkflowStaticDataService,
private readonly nodeTypes: NodeTypes,
private readonly permissionChecker: PermissionChecker,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {
if (this.executionsMode === 'queue') {
this.jobQueue = Container.get(Queue);
@ -147,7 +147,7 @@ export class WorkflowRunner {
await this.enqueueExecution(executionId, data, loadStaticData, realtime);
} else {
await this.runMainProcess(executionId, data, loadStaticData, restartExecutionId);
this.eventRelay.emit('workflow-pre-execute', { executionId, data });
this.eventService.emit('workflow-pre-execute', { executionId, data });
}
// only run these when not in queue mode or when the execution is manual,
@ -166,7 +166,7 @@ export class WorkflowRunner {
executionData,
data.userId,
);
this.eventRelay.emit('workflow-post-execute', {
this.eventService.emit('workflow-post-execute', {
workflowId: data.workflowData.id,
workflowName: data.workflowData.name,
executionId,

View file

@ -12,7 +12,7 @@ import {
updateLdapUserOnLocalDb,
} from '@/Ldap/helpers.ee';
import type { User } from '@db/entities/User';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
export const handleLdapLogin = async (
loginId: string,
@ -55,7 +55,7 @@ export const handleLdapLogin = async (
user_type: 'ldap',
was_disabled_ldap_user: false,
});
Container.get(EventRelay).emit('user-signed-up', { user });
Container.get(EventService).emit('user-signed-up', { user });
return user;
}
} else {

View file

@ -33,7 +33,7 @@ import { ExecutionService } from '@/executions/execution.service';
import { OwnershipService } from '@/services/ownership.service';
import { WorkflowRunner } from '@/WorkflowRunner';
import { ExecutionRecoveryService } from '@/executions/execution-recovery.service';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
const open = require('open');
@ -378,7 +378,7 @@ export class Start extends BaseCommand {
projectId: project.id,
};
Container.get(EventRelay).emit('execution-started-during-bootup', {
Container.get(EventService).emit('execution-started-during-bootup', {
executionId: execution.id,
});

View file

@ -12,13 +12,13 @@ import type { WorkflowExecuteMode as ExecutionMode } from 'n8n-workflow';
import type { ExecutionRepository } from '@/databases/repositories/execution.repository';
import type { IExecutingWorkflowData } from '@/Interfaces';
import type { Telemetry } from '@/telemetry';
import type { EventRelay } from '@/eventbus/event-relay.service';
import type { EventService } from '@/eventbus/event.service';
describe('ConcurrencyControlService', () => {
const logger = mock<Logger>();
const executionRepository = mock<ExecutionRepository>();
const telemetry = mock<Telemetry>();
const eventRelay = mock<EventRelay>();
const eventService = mock<EventService>();
afterEach(() => {
config.set('executions.concurrency.productionLimit', -1);
@ -41,7 +41,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
/**
@ -63,7 +63,7 @@ describe('ConcurrencyControlService', () => {
/**
* Act
*/
new ConcurrencyControlService(logger, executionRepository, telemetry, eventRelay);
new ConcurrencyControlService(logger, executionRepository, telemetry, eventService);
} catch (error) {
/**
* Assert
@ -85,7 +85,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
/**
@ -108,7 +108,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
/**
@ -132,7 +132,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
/**
@ -161,7 +161,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
const enqueueSpy = jest.spyOn(ConcurrencyQueue.prototype, 'enqueue');
@ -187,7 +187,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
const enqueueSpy = jest.spyOn(ConcurrencyQueue.prototype, 'enqueue');
@ -216,7 +216,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
const dequeueSpy = jest.spyOn(ConcurrencyQueue.prototype, 'dequeue');
@ -242,7 +242,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
const dequeueSpy = jest.spyOn(ConcurrencyQueue.prototype, 'dequeue');
@ -271,7 +271,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
const removeSpy = jest.spyOn(ConcurrencyQueue.prototype, 'remove');
@ -299,7 +299,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
const removeSpy = jest.spyOn(ConcurrencyQueue.prototype, 'remove');
@ -327,7 +327,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
jest
@ -371,7 +371,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
const enqueueSpy = jest.spyOn(ConcurrencyQueue.prototype, 'enqueue');
@ -399,7 +399,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
const dequeueSpy = jest.spyOn(ConcurrencyQueue.prototype, 'dequeue');
@ -426,7 +426,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
const removeSpy = jest.spyOn(ConcurrencyQueue.prototype, 'remove');
@ -461,7 +461,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
/**
@ -491,7 +491,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
/**
@ -523,7 +523,7 @@ describe('ConcurrencyControlService', () => {
logger,
executionRepository,
telemetry,
eventRelay,
eventService,
);
/**

View file

@ -8,7 +8,7 @@ import { ExecutionRepository } from '@/databases/repositories/execution.reposito
import type { WorkflowExecuteMode as ExecutionMode } from 'n8n-workflow';
import type { IExecutingWorkflowData } from '@/Interfaces';
import { Telemetry } from '@/telemetry';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
export const CLOUD_TEMP_PRODUCTION_LIMIT = 999;
export const CLOUD_TEMP_REPORTABLE_THRESHOLDS = [5, 10, 20, 50, 100, 200];
@ -29,7 +29,7 @@ export class ConcurrencyControlService {
private readonly logger: Logger,
private readonly executionRepository: ExecutionRepository,
private readonly telemetry: Telemetry,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {
this.productionLimit = config.getEnv('executions.concurrency.productionLimit');
@ -63,7 +63,7 @@ export class ConcurrencyControlService {
this.productionQueue.on('execution-throttled', ({ executionId }: { executionId: string }) => {
this.log('Execution throttled', { executionId });
this.eventRelay.emit('execution-throttled', { executionId });
this.eventService.emit('execution-throttled', { executionId });
});
this.productionQueue.on('execution-released', async (executionId: string) => {

View file

@ -24,7 +24,7 @@ import { BadRequestError } from '@/errors/response-errors/bad-request.error';
import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
import { ApplicationError } from 'n8n-workflow';
import { UserRepository } from '@/databases/repositories/user.repository';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@RestController()
export class AuthController {
@ -36,7 +36,7 @@ export class AuthController {
private readonly userService: UserService,
private readonly license: License,
private readonly userRepository: UserRepository,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
private readonly postHog?: PostHogClient,
) {}
@ -93,14 +93,14 @@ export class AuthController {
this.authService.issueCookie(res, user, req.browserId);
this.eventRelay.emit('user-logged-in', {
this.eventService.emit('user-logged-in', {
user,
authenticationMethod: usedAuthenticationMethod,
});
return await this.userService.toPublic(user, { posthog: this.postHog, withScopes: true });
}
this.eventRelay.emit('user-login-failed', {
this.eventService.emit('user-login-failed', {
authenticationMethod: usedAuthenticationMethod,
userEmail: email,
reason: 'wrong credentials',
@ -180,7 +180,7 @@ export class AuthController {
}
void this.internalHooks.onUserInviteEmailClick({ inviter, invitee });
this.eventRelay.emit('user-invite-email-click', { inviter, invitee });
this.eventService.emit('user-invite-email-click', { inviter, invitee });
const { firstName, lastName } = inviter;
return { inviter: { firstName, lastName } };

View file

@ -14,7 +14,7 @@ import { Push } from '@/push';
import { CommunityPackagesService } from '@/services/communityPackages.service';
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
import { InternalServerError } from '@/errors/response-errors/internal-server.error';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
const {
PACKAGE_NOT_INSTALLED,
@ -39,7 +39,7 @@ export class CommunityPackagesController {
private readonly push: Push,
private readonly internalHooks: InternalHooks,
private readonly communityPackagesService: CommunityPackagesService,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
// TODO: move this into a new decorator `@IfConfig('executions.mode', 'queue')`
@ -116,7 +116,7 @@ export class CommunityPackagesController {
package_version: parsed.version,
failure_reason: errorMessage,
});
this.eventRelay.emit('community-package-installed', {
this.eventService.emit('community-package-installed', {
user: req.user,
inputString: name,
packageName: parsed.packageName,
@ -154,7 +154,7 @@ export class CommunityPackagesController {
package_author: installedPackage.authorName,
package_author_email: installedPackage.authorEmail,
});
this.eventRelay.emit('community-package-installed', {
this.eventService.emit('community-package-installed', {
user: req.user,
inputString: name,
packageName: parsed.packageName,
@ -253,7 +253,7 @@ export class CommunityPackagesController {
package_author: installedPackage.authorName,
package_author_email: installedPackage.authorEmail,
});
this.eventRelay.emit('community-package-deleted', {
this.eventService.emit('community-package-deleted', {
user: req.user,
packageName: name,
packageVersion: installedPackage.installedVersion,
@ -309,7 +309,7 @@ export class CommunityPackagesController {
package_author: newInstalledPackage.authorName,
package_author_email: newInstalledPackage.authorEmail,
});
this.eventRelay.emit('community-package-updated', {
this.eventService.emit('community-package-updated', {
user: req.user,
packageName: name,
packageVersionCurrent: previouslyInstalledPackage.installedVersion,

View file

@ -18,7 +18,7 @@ import { BadRequestError } from '@/errors/response-errors/bad-request.error';
import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
import { InternalHooks } from '@/InternalHooks';
import { ExternalHooks } from '@/ExternalHooks';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@RestController('/invitations')
export class InvitationController {
@ -32,7 +32,7 @@ export class InvitationController {
private readonly passwordUtility: PasswordUtility,
private readonly userRepository: UserRepository,
private readonly postHog: PostHogClient,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
/**
@ -172,7 +172,7 @@ export class InvitationController {
user_type: 'email',
was_disabled_ldap_user: false,
});
this.eventRelay.emit('user-signed-up', { user: updatedUser });
this.eventService.emit('user-signed-up', { user: updatedUser });
const publicInvitee = await this.userService.toPublic(invitee);

View file

@ -23,7 +23,7 @@ import { InternalHooks } from '@/InternalHooks';
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
import { UserRepository } from '@/databases/repositories/user.repository';
import { isApiEnabled } from '@/PublicApi';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
export const isApiEnabledMiddleware: RequestHandler = (_, res, next) => {
if (isApiEnabled()) {
@ -43,7 +43,7 @@ export class MeController {
private readonly userService: UserService,
private readonly passwordUtility: PasswordUtility,
private readonly userRepository: UserRepository,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
/**
@ -100,7 +100,7 @@ export class MeController {
const fieldsChanged = Object.keys(payload);
void this.internalHooks.onUserUpdate({ user, fields_changed: fieldsChanged });
this.eventRelay.emit('user-updated', { user, fieldsChanged });
this.eventService.emit('user-updated', { user, fieldsChanged });
const publicUser = await this.userService.toPublic(user);
@ -150,7 +150,7 @@ export class MeController {
this.authService.issueCookie(res, updatedUser, req.browserId);
void this.internalHooks.onUserUpdate({ user: updatedUser, fields_changed: ['password'] });
this.eventRelay.emit('user-updated', { user: updatedUser, fieldsChanged: ['password'] });
this.eventService.emit('user-updated', { user: updatedUser, fieldsChanged: ['password'] });
await this.externalHooks.run('user.password.update', [updatedUser.email, updatedUser.password]);
@ -199,7 +199,7 @@ export class MeController {
await this.userService.update(req.user.id, { apiKey });
void this.internalHooks.onApiKeyCreated({ user: req.user, public_api: false });
this.eventRelay.emit('api-key-created', { user: req.user });
this.eventService.emit('api-key-created', { user: req.user });
return { apiKey };
}
@ -220,7 +220,7 @@ export class MeController {
await this.userService.update(req.user.id, { apiKey: null });
void this.internalHooks.onApiKeyDeleted({ user: req.user, public_api: false });
this.eventRelay.emit('api-key-deleted', { user: req.user });
this.eventService.emit('api-key-deleted', { user: req.user });
return { success: true };
}

View file

@ -21,7 +21,7 @@ import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
import { NotFoundError } from '@/errors/response-errors/not-found.error';
import { UnprocessableRequestError } from '@/errors/response-errors/unprocessable.error';
import { UserRepository } from '@/databases/repositories/user.repository';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@RestController()
export class PasswordResetController {
@ -37,7 +37,7 @@ export class PasswordResetController {
private readonly license: License,
private readonly passwordUtility: PasswordUtility,
private readonly userRepository: UserRepository,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
/**
@ -125,7 +125,7 @@ export class PasswordResetController {
message_type: 'Reset password',
public_api: false,
});
this.eventRelay.emit('email-failed', { user, messageType: 'Reset password' });
this.eventService.emit('email-failed', { user, messageType: 'Reset password' });
if (error instanceof Error) {
throw new InternalServerError(`Please contact your administrator: ${error.message}`);
}
@ -139,7 +139,7 @@ export class PasswordResetController {
});
void this.internalHooks.onUserPasswordResetRequestClick({ user });
this.eventRelay.emit('user-password-reset-request-click', { user });
this.eventService.emit('user-password-reset-request-click', { user });
}
/**
@ -172,7 +172,7 @@ export class PasswordResetController {
this.logger.info('Reset-password token resolved successfully', { userId: user.id });
void this.internalHooks.onUserPasswordResetEmailClick({ user });
this.eventRelay.emit('user-password-reset-email-click', { user });
this.eventService.emit('user-password-reset-email-click', { user });
}
/**
@ -216,7 +216,7 @@ export class PasswordResetController {
this.authService.issueCookie(res, user, req.browserId);
void this.internalHooks.onUserUpdate({ user, fields_changed: ['password'] });
this.eventRelay.emit('user-updated', { user, fieldsChanged: ['password'] });
this.eventService.emit('user-updated', { user, fieldsChanged: ['password'] });
// if this user used to be an LDAP users
const ldapIdentity = user?.authIdentities?.find((i) => i.providerType === 'ldap');
@ -225,7 +225,7 @@ export class PasswordResetController {
user_type: 'email',
was_disabled_ldap_user: true,
});
this.eventRelay.emit('user-signed-up', { user });
this.eventService.emit('user-signed-up', { user });
}
await this.externalHooks.run('user.password.update', [user.email, passwordHash]);

View file

@ -23,7 +23,7 @@ import { ProjectRepository } from '@/databases/repositories/project.repository';
// eslint-disable-next-line n8n-local-rules/misplaced-n8n-typeorm-import
import { In, Not } from '@n8n/typeorm';
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@RestController('/projects')
export class ProjectController {
@ -31,7 +31,7 @@ export class ProjectController {
private readonly projectsService: ProjectService,
private readonly roleService: RoleService,
private readonly projectRepository: ProjectRepository,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
@Get('/')
@ -52,7 +52,7 @@ export class ProjectController {
try {
const project = await this.projectsService.createTeamProject(req.body.name, req.user);
this.eventRelay.emit('team-project-created', {
this.eventService.emit('team-project-created', {
userId: req.user.id,
role: req.user.role,
});
@ -195,7 +195,7 @@ export class ProjectController {
throw e;
}
this.eventRelay.emit('team-project-updated', {
this.eventService.emit('team-project-updated', {
userId: req.user.id,
role: req.user.role,
members: req.body.relations,
@ -211,7 +211,7 @@ export class ProjectController {
migrateToProject: req.query.transferId,
});
this.eventRelay.emit('team-project-deleted', {
this.eventService.emit('team-project-deleted', {
userId: req.user.id,
role: req.user.role,
projectId: req.params.projectId,

View file

@ -28,7 +28,7 @@ import { Project } from '@/databases/entities/Project';
import { WorkflowService } from '@/workflows/workflow.service';
import { CredentialsService } from '@/credentials/credentials.service';
import { ProjectService } from '@/services/project.service';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@RestController('/users')
export class UsersController {
@ -45,7 +45,7 @@ export class UsersController {
private readonly workflowService: WorkflowService,
private readonly credentialsService: CredentialsService,
private readonly projectService: ProjectService,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
static ERROR_MESSAGES = {
@ -258,7 +258,7 @@ export class UsersController {
telemetryData,
publicApi: false,
});
this.eventRelay.emit('user-deleted', { user: req.user });
this.eventService.emit('user-deleted', { user: req.user });
await this.externalHooks.run('user.deleted', [await this.userService.toPublic(userToDelete)]);

View file

@ -31,7 +31,7 @@ import { SharedCredentialsRepository } from '@/databases/repositories/sharedCred
import { SharedCredentials } from '@/databases/entities/SharedCredentials';
import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository';
import { z } from 'zod';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@RestController('/credentials')
export class CredentialsController {
@ -46,7 +46,7 @@ export class CredentialsController {
private readonly userManagementMailer: UserManagementMailer,
private readonly sharedCredentialsRepository: SharedCredentialsRepository,
private readonly projectRelationRepository: ProjectRelationRepository,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
@Get('/', { middlewares: listQueryMiddleware })
@ -169,7 +169,7 @@ export class CredentialsController {
credential_id: credential.id,
public_api: false,
});
this.eventRelay.emit('credentials-created', {
this.eventService.emit('credentials-created', {
user: req.user,
credentialName: newCredential.name,
credentialType: credential.type,
@ -229,7 +229,7 @@ export class CredentialsController {
credential_type: credential.type,
credential_id: credential.id,
});
this.eventRelay.emit('credentials-updated', {
this.eventService.emit('credentials-updated', {
user: req.user,
credentialName: credential.name,
credentialType: credential.type,
@ -270,7 +270,7 @@ export class CredentialsController {
credential_type: credential.type,
credential_id: credential.id,
});
this.eventRelay.emit('credentials-deleted', {
this.eventService.emit('credentials-deleted', {
user: req.user,
credentialName: credential.name,
credentialType: credential.type,
@ -344,7 +344,7 @@ export class CredentialsController {
user_ids_sharees_added: newShareeIds,
sharees_removed: amountRemoved,
});
this.eventRelay.emit('credentials-shared', {
this.eventService.emit('credentials-shared', {
user: req.user,
credentialName: credential.name,
credentialType: credential.type,

View file

@ -12,7 +12,7 @@ import type { SourceControlPreferences } from './types/sourceControlPreferences'
import type { SourceControlledFile } from './types/sourceControlledFile';
import { SOURCE_CONTROL_DEFAULT_BRANCH } from './constants';
import type { ImportResult } from './types/importResult';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
import { getRepoType } from './sourceControlHelper.ee';
import { SourceControlGetStatus } from './types/sourceControlGetStatus';
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
@ -22,7 +22,7 @@ export class SourceControlController {
constructor(
private readonly sourceControlService: SourceControlService,
private readonly sourceControlPreferencesService: SourceControlPreferencesService,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
@Get('/preferences', { middlewares: [sourceControlLicensedMiddleware], skipAuth: true })
@ -83,7 +83,7 @@ export class SourceControlController {
const resultingPreferences = this.sourceControlPreferencesService.getPreferences();
// #region Tracking Information
// located in controller so as to not call this multiple times when updating preferences
this.eventRelay.emit('source-control-settings-updated', {
this.eventService.emit('source-control-settings-updated', {
branchName: resultingPreferences.branchName,
connected: resultingPreferences.connected,
readOnlyInstance: resultingPreferences.branchReadOnly,
@ -128,7 +128,7 @@ export class SourceControlController {
}
await this.sourceControlService.init();
const resultingPreferences = this.sourceControlPreferencesService.getPreferences();
this.eventRelay.emit('source-control-settings-updated', {
this.eventService.emit('source-control-settings-updated', {
branchName: resultingPreferences.branchName,
connected: resultingPreferences.connected,
readOnlyInstance: resultingPreferences.branchReadOnly,

View file

@ -30,7 +30,7 @@ import type { TagEntity } from '@db/entities/TagEntity';
import type { Variables } from '@db/entities/Variables';
import type { SourceControlWorkflowVersionId } from './types/sourceControlWorkflowVersionId';
import type { ExportableCredential } from './types/exportableCredential';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
import { TagRepository } from '@db/repositories/tag.repository';
import { Logger } from '@/Logger';
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
@ -52,7 +52,7 @@ export class SourceControlService {
private sourceControlExportService: SourceControlExportService,
private sourceControlImportService: SourceControlImportService,
private tagRepository: TagRepository,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {
const { gitFolder, sshFolder, sshKeyName } = sourceControlPreferencesService;
this.gitFolder = gitFolder;
@ -292,7 +292,7 @@ export class SourceControlService {
});
// #region Tracking Information
this.eventRelay.emit(
this.eventService.emit(
'source-control-user-finished-push-ui',
getTrackingInformationFromPostPushResult(statusResult),
);
@ -370,7 +370,7 @@ export class SourceControlService {
}
// #region Tracking Information
this.eventRelay.emit(
this.eventService.emit(
'source-control-user-finished-pull-ui',
getTrackingInformationFromPullResult(statusResult),
);
@ -424,12 +424,12 @@ export class SourceControlService {
// #region Tracking Information
if (options.direction === 'push') {
this.eventRelay.emit(
this.eventService.emit(
'source-control-user-started-push-ui',
getTrackingInformationFromPrePushResult(sourceControlledFiles),
);
} else if (options.direction === 'pull') {
this.eventRelay.emit(
this.eventService.emit(
'source-control-user-started-pull-ui',
getTrackingInformationFromPullResult(sourceControlledFiles),
);

View file

@ -6,14 +6,14 @@ import { CacheService } from '@/services/cache/cache.service';
import { VariablesRepository } from '@db/repositories/variables.repository';
import { VariableCountLimitReachedError } from '@/errors/variable-count-limit-reached.error';
import { VariableValidationError } from '@/errors/variable-validation.error';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@Service()
export class VariablesService {
constructor(
protected cacheService: CacheService,
protected variablesRepository: VariablesRepository,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
async getAllCached(): Promise<Variables[]> {
@ -71,7 +71,7 @@ export class VariablesService {
}
this.validateVariable(variable);
this.eventRelay.emit('variable-created', { variableType: variable.type });
this.eventService.emit('variable-created', { variableType: variable.type });
const saveResult = await this.variablesRepository.save(
{
...variable,

View file

@ -2,12 +2,12 @@ import { mock } from 'jest-mock-extended';
import { AuditEventRelay } from '../audit-event-relay.service';
import type { MessageEventBus } from '../MessageEventBus/MessageEventBus';
import type { Event } from '../event.types';
import type { EventRelay } from '../event-relay.service';
import type { EventService } from '../event.service';
describe('AuditorService', () => {
const eventBus = mock<MessageEventBus>();
const eventRelay = mock<EventRelay>();
const auditor = new AuditEventRelay(eventRelay, eventBus);
const eventService = mock<EventService>();
const auditor = new AuditEventRelay(eventService, eventBus);
afterEach(() => {
jest.clearAllMocks();

View file

@ -1,14 +1,14 @@
import { Service } from 'typedi';
import { MessageEventBus } from './MessageEventBus/MessageEventBus';
import { Redactable } from '@/decorators/Redactable';
import { EventRelay } from './event-relay.service';
import { EventService } from './event.service';
import type { Event } from './event.types';
import type { IWorkflowBase } from 'n8n-workflow';
@Service()
export class AuditEventRelay {
constructor(
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
private readonly eventBus: MessageEventBus,
) {}
@ -17,42 +17,46 @@ export class AuditEventRelay {
}
private setupHandlers() {
this.eventRelay.on('workflow-created', (event) => this.workflowCreated(event));
this.eventRelay.on('workflow-deleted', (event) => this.workflowDeleted(event));
this.eventRelay.on('workflow-saved', (event) => this.workflowSaved(event));
this.eventRelay.on('workflow-pre-execute', (event) => this.workflowPreExecute(event));
this.eventRelay.on('workflow-post-execute', (event) => this.workflowPostExecute(event));
this.eventRelay.on('node-pre-execute', (event) => this.nodePreExecute(event));
this.eventRelay.on('node-post-execute', (event) => this.nodePostExecute(event));
this.eventRelay.on('user-deleted', (event) => this.userDeleted(event));
this.eventRelay.on('user-invited', (event) => this.userInvited(event));
this.eventRelay.on('user-reinvited', (event) => this.userReinvited(event));
this.eventRelay.on('user-updated', (event) => this.userUpdated(event));
this.eventRelay.on('user-signed-up', (event) => this.userSignedUp(event));
this.eventRelay.on('user-logged-in', (event) => this.userLoggedIn(event));
this.eventRelay.on('user-login-failed', (event) => this.userLoginFailed(event));
this.eventRelay.on('user-invite-email-click', (event) => this.userInviteEmailClick(event));
this.eventRelay.on('user-password-reset-email-click', (event) =>
this.eventService.on('workflow-created', (event) => this.workflowCreated(event));
this.eventService.on('workflow-deleted', (event) => this.workflowDeleted(event));
this.eventService.on('workflow-saved', (event) => this.workflowSaved(event));
this.eventService.on('workflow-pre-execute', (event) => this.workflowPreExecute(event));
this.eventService.on('workflow-post-execute', (event) => this.workflowPostExecute(event));
this.eventService.on('node-pre-execute', (event) => this.nodePreExecute(event));
this.eventService.on('node-post-execute', (event) => this.nodePostExecute(event));
this.eventService.on('user-deleted', (event) => this.userDeleted(event));
this.eventService.on('user-invited', (event) => this.userInvited(event));
this.eventService.on('user-reinvited', (event) => this.userReinvited(event));
this.eventService.on('user-updated', (event) => this.userUpdated(event));
this.eventService.on('user-signed-up', (event) => this.userSignedUp(event));
this.eventService.on('user-logged-in', (event) => this.userLoggedIn(event));
this.eventService.on('user-login-failed', (event) => this.userLoginFailed(event));
this.eventService.on('user-invite-email-click', (event) => this.userInviteEmailClick(event));
this.eventService.on('user-password-reset-email-click', (event) =>
this.userPasswordResetEmailClick(event),
);
this.eventRelay.on('user-password-reset-request-click', (event) =>
this.eventService.on('user-password-reset-request-click', (event) =>
this.userPasswordResetRequestClick(event),
);
this.eventRelay.on('api-key-created', (event) => this.apiKeyCreated(event));
this.eventRelay.on('api-key-deleted', (event) => this.apiKeyDeleted(event));
this.eventRelay.on('email-failed', (event) => this.emailFailed(event));
this.eventRelay.on('credentials-created', (event) => this.credentialsCreated(event));
this.eventRelay.on('credentials-deleted', (event) => this.credentialsDeleted(event));
this.eventRelay.on('credentials-shared', (event) => this.credentialsShared(event));
this.eventRelay.on('credentials-updated', (event) => this.credentialsUpdated(event));
this.eventRelay.on('credentials-deleted', (event) => this.credentialsDeleted(event));
this.eventRelay.on('community-package-installed', (event) =>
this.eventService.on('api-key-created', (event) => this.apiKeyCreated(event));
this.eventService.on('api-key-deleted', (event) => this.apiKeyDeleted(event));
this.eventService.on('email-failed', (event) => this.emailFailed(event));
this.eventService.on('credentials-created', (event) => this.credentialsCreated(event));
this.eventService.on('credentials-deleted', (event) => this.credentialsDeleted(event));
this.eventService.on('credentials-shared', (event) => this.credentialsShared(event));
this.eventService.on('credentials-updated', (event) => this.credentialsUpdated(event));
this.eventService.on('credentials-deleted', (event) => this.credentialsDeleted(event));
this.eventService.on('community-package-installed', (event) =>
this.communityPackageInstalled(event),
);
this.eventRelay.on('community-package-updated', (event) => this.communityPackageUpdated(event));
this.eventRelay.on('community-package-deleted', (event) => this.communityPackageDeleted(event));
this.eventRelay.on('execution-throttled', (event) => this.executionThrottled(event));
this.eventRelay.on('execution-started-during-bootup', (event) =>
this.eventService.on('community-package-updated', (event) =>
this.communityPackageUpdated(event),
);
this.eventService.on('community-package-deleted', (event) =>
this.communityPackageDeleted(event),
);
this.eventService.on('execution-throttled', (event) => this.executionThrottled(event));
this.eventService.on('execution-started-during-bootup', (event) =>
this.executionStartedDuringBootup(event),
);
}

View file

@ -3,7 +3,7 @@ import { Service } from 'typedi';
import type { Event } from './event.types';
@Service()
export class EventRelay extends EventEmitter {
export class EventService extends EventEmitter {
emit<K extends keyof Event>(eventName: K, arg: Event[K]) {
super.emit(eventName, arg);
return true;

View file

@ -12,7 +12,7 @@ export type UserLike = {
};
/**
* Events sent at services and forwarded by relays, e.g. `AuditEventRelay` and `TelemetryEventRelay`.
* Events sent by `EventService` and forwarded by relays, e.g. `AuditEventRelay` and `TelemetryEventRelay`.
*/
export type Event = {
'workflow-created': {

View file

@ -21,7 +21,7 @@ import { WorkflowCrashedError } from '@/errors/workflow-crashed.error';
import { EventMessageNode } from '@/eventbus/EventMessageClasses/EventMessageNode';
import { EventMessageWorkflow } from '@/eventbus/EventMessageClasses/EventMessageWorkflow';
import type { EventRelay } from '@/eventbus/event-relay.service';
import type { EventService } from '@/eventbus/event.service';
import type { EventMessageTypes as EventMessage } from '@/eventbus/EventMessageClasses';
import type { Logger } from '@/Logger';
@ -193,7 +193,7 @@ describe('ExecutionRecoveryService', () => {
push,
executionRepository,
orchestrationService,
mock<EventRelay>(),
mock<EventService>(),
);
});

View file

@ -16,7 +16,7 @@ import config from '@/config';
import { OnShutdown } from '@/decorators/OnShutdown';
import type { QueueRecoverySettings } from './execution.types';
import { OrchestrationService } from '@/services/orchestration.service';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
/**
* Service for recovering key properties in executions.
@ -28,7 +28,7 @@ export class ExecutionRecoveryService {
private readonly push: Push,
private readonly executionRepository: ExecutionRepository,
private readonly orchestrationService: OrchestrationService,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
/**
@ -286,7 +286,7 @@ export class ExecutionRecoveryService {
status: execution.status,
});
this.eventRelay.emit('workflow-post-execute', {
this.eventService.emit('workflow-post-execute', {
workflowId: execution.workflowData.id,
workflowName: execution.workflowData.name,
executionId: execution.id,

View file

@ -3,7 +3,7 @@ import axios from 'axios';
import { Logger } from '@/Logger';
import { License } from '@/License';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
import type { User } from '@db/entities/User';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
@ -28,7 +28,7 @@ export class LicenseService {
private readonly license: License,
private readonly workflowRepository: WorkflowRepository,
private readonly urlService: UrlService,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
async getLicenseData() {
@ -79,11 +79,11 @@ export class LicenseService {
} catch (e) {
const message = this.mapErrorMessage(e as LicenseError, 'renew');
this.eventRelay.emit('license-renewal-attempted', { success: false });
this.eventService.emit('license-renewal-attempted', { success: false });
throw new BadRequestError(message);
}
this.eventRelay.emit('license-renewal-attempted', { success: true });
this.eventService.emit('license-renewal-attempted', { success: true });
}
private mapErrorMessage(error: LicenseError, action: 'activate' | 'renew') {

View file

@ -12,7 +12,7 @@ import { InternalHooks } from '@/InternalHooks';
import { UrlService } from '@/services/url.service';
import type { UserRequest } from '@/requests';
import { InternalServerError } from '@/errors/response-errors/internal-server.error';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@Service()
export class UserService {
@ -21,7 +21,7 @@ export class UserService {
private readonly userRepository: UserRepository,
private readonly mailer: UserManagementMailer,
private readonly urlService: UrlService,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
async update(userId: string, data: Partial<User>) {
@ -158,7 +158,7 @@ export class UserService {
email_sent: result.emailSent,
invitee_role: role, // same role for all invited users
});
this.eventRelay.emit('user-invited', {
this.eventService.emit('user-invited', {
user: owner,
targetUserId: Object.values(toInviteUsers),
});
@ -169,7 +169,7 @@ export class UserService {
message_type: 'New user invite',
public_api: false,
});
this.eventRelay.emit('email-failed', { user: owner, messageType: 'New user invite' });
this.eventService.emit('email-failed', { user: owner, messageType: 'New user invite' });
this.logger.error('Failed to send email', {
userId: owner.id,
inviteAcceptUrl,

View file

@ -27,7 +27,7 @@ import {
import { SamlService } from '../saml.service.ee';
import { SamlConfiguration } from '../types/requests';
import { getInitSSOFormView } from '../views/initSsoPost';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@RestController('/sso/saml')
export class SamlController {
@ -35,7 +35,7 @@ export class SamlController {
private readonly authService: AuthService,
private readonly samlService: SamlService,
private readonly urlService: UrlService,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
@Get('/metadata', { skipAuth: true })
@ -126,7 +126,7 @@ export class SamlController {
}
}
if (loginResult.authenticatedUser) {
this.eventRelay.emit('user-logged-in', {
this.eventService.emit('user-logged-in', {
user: loginResult.authenticatedUser,
authenticationMethod: 'saml',
});
@ -144,7 +144,7 @@ export class SamlController {
return res.status(202).send(loginResult.attributes);
}
}
this.eventRelay.emit('user-login-failed', {
this.eventService.emit('user-login-failed', {
userEmail: loginResult.attributes.email ?? 'unknown',
authenticationMethod: 'saml',
});
@ -153,7 +153,7 @@ export class SamlController {
if (isConnectionTestRequest(req)) {
return res.send(getSamlConnectionTestFailedView((error as Error).message));
}
this.eventRelay.emit('user-login-failed', {
this.eventService.emit('user-login-failed', {
userEmail: 'unknown',
authenticationMethod: 'saml',
});

View file

@ -1,5 +1,5 @@
import { Service } from 'typedi';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
import type { Event } from '@/eventbus/event.types';
import { Telemetry } from '.';
import config from '@/config';
@ -7,7 +7,7 @@ import config from '@/config';
@Service()
export class TelemetryEventRelay {
constructor(
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
private readonly telemetry: Telemetry,
) {}
@ -20,34 +20,34 @@ export class TelemetryEventRelay {
}
private setupHandlers() {
this.eventRelay.on('team-project-updated', (event) => this.teamProjectUpdated(event));
this.eventRelay.on('team-project-deleted', (event) => this.teamProjectDeleted(event));
this.eventRelay.on('team-project-created', (event) => this.teamProjectCreated(event));
this.eventRelay.on('source-control-settings-updated', (event) =>
this.eventService.on('team-project-updated', (event) => this.teamProjectUpdated(event));
this.eventService.on('team-project-deleted', (event) => this.teamProjectDeleted(event));
this.eventService.on('team-project-created', (event) => this.teamProjectCreated(event));
this.eventService.on('source-control-settings-updated', (event) =>
this.sourceControlSettingsUpdated(event),
);
this.eventRelay.on('source-control-user-started-pull-ui', (event) =>
this.eventService.on('source-control-user-started-pull-ui', (event) =>
this.sourceControlUserStartedPullUi(event),
);
this.eventRelay.on('source-control-user-finished-pull-ui', (event) =>
this.eventService.on('source-control-user-finished-pull-ui', (event) =>
this.sourceControlUserFinishedPullUi(event),
);
this.eventRelay.on('source-control-user-pulled-api', (event) =>
this.eventService.on('source-control-user-pulled-api', (event) =>
this.sourceControlUserPulledApi(event),
);
this.eventRelay.on('source-control-user-started-push-ui', (event) =>
this.eventService.on('source-control-user-started-push-ui', (event) =>
this.sourceControlUserStartedPushUi(event),
);
this.eventRelay.on('source-control-user-finished-push-ui', (event) =>
this.eventService.on('source-control-user-finished-push-ui', (event) =>
this.sourceControlUserFinishedPushUi(event),
);
this.eventRelay.on('license-renewal-attempted', (event) => {
this.eventService.on('license-renewal-attempted', (event) => {
this.licenseRenewalAttempted(event);
});
this.eventRelay.on('variable-created', (event) => {
this.eventService.on('variable-created', (event) => {
this.variableCreated(event);
});
this.eventRelay.on('external-secrets-provider-settings-saved', (event) => {
this.eventService.on('external-secrets-provider-settings-saved', (event) => {
this.externalSecretsProviderSettingsSaved(event);
});
}

View file

@ -34,7 +34,7 @@ import type { EntityManager } from '@n8n/typeorm';
// eslint-disable-next-line n8n-local-rules/misplaced-n8n-typeorm-import
import { In } from '@n8n/typeorm';
import { SharedWorkflow } from '@/databases/entities/SharedWorkflow';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@Service()
export class WorkflowService {
@ -54,7 +54,7 @@ export class WorkflowService {
private readonly workflowSharingService: WorkflowSharingService,
private readonly projectService: ProjectService,
private readonly executionRepository: ExecutionRepository,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
async getMany(user: User, options?: ListQuery.Options, includeScopes?: boolean) {
@ -220,7 +220,7 @@ export class WorkflowService {
await this.externalHooks.run('workflow.afterUpdate', [updatedWorkflow]);
void Container.get(InternalHooks).onWorkflowSaved(user, updatedWorkflow, false);
this.eventRelay.emit('workflow-saved', {
this.eventService.emit('workflow-saved', {
user,
workflowId: updatedWorkflow.id,
workflowName: updatedWorkflow.name,
@ -283,7 +283,7 @@ export class WorkflowService {
await this.binaryDataService.deleteMany(idsForDeletion);
void Container.get(InternalHooks).onWorkflowDeleted(user, workflowId, false);
this.eventRelay.emit('workflow-deleted', { user, workflowId });
this.eventService.emit('workflow-deleted', { user, workflowId });
await this.externalHooks.run('workflow.afterDelete', [workflowId]);
return workflow;

View file

@ -42,7 +42,7 @@ import { In, type FindOptionsRelations } from '@n8n/typeorm';
import type { Project } from '@/databases/entities/Project';
import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository';
import { z } from 'zod';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';
@RestController('/workflows')
export class WorkflowsController {
@ -66,7 +66,7 @@ export class WorkflowsController {
private readonly projectRepository: ProjectRepository,
private readonly projectService: ProjectService,
private readonly projectRelationRepository: ProjectRelationRepository,
private readonly eventRelay: EventRelay,
private readonly eventService: EventService,
) {}
@Post('/')
@ -178,7 +178,7 @@ export class WorkflowsController {
await this.externalHooks.run('workflow.afterCreate', [savedWorkflow]);
void this.internalHooks.onWorkflowCreated(req.user, newWorkflow, project!, false);
this.eventRelay.emit('workflow-created', { user: req.user, workflow: newWorkflow });
this.eventService.emit('workflow-created', { user: req.user, workflow: newWorkflow });
const scopes = await this.workflowService.getWorkflowScopes(req.user, savedWorkflow.id);

View file

@ -21,7 +21,7 @@ import {
TestFailProvider,
} from '../../shared/ExternalSecrets/utils';
import type { SuperAgentTest } from '../shared/types';
import type { EventRelay } from '@/eventbus/event-relay.service';
import type { EventService } from '@/eventbus/event.service';
let authOwnerAgent: SuperAgentTest;
let authMemberAgent: SuperAgentTest;
@ -50,7 +50,7 @@ async function getExternalSecretsSettings(): Promise<ExternalSecretsSettings | n
return await jsonParse(Container.get(Cipher).decrypt(encSettings));
}
const eventRelay = mock<EventRelay>();
const eventService = mock<EventService>();
const resetManager = async () => {
Container.get(ExternalSecretsManager).shutdown();
@ -62,7 +62,7 @@ const resetManager = async () => {
Container.get(License),
mockProvidersInstance,
Container.get(Cipher),
eventRelay,
eventService,
),
);

View file

@ -1,6 +1,6 @@
import { LicenseErrors, LicenseService } from '@/license/license.service';
import type { License } from '@/License';
import type { EventRelay } from '@/eventbus/event-relay.service';
import type { EventService } from '@/eventbus/event.service';
import type { WorkflowRepository } from '@db/repositories/workflow.repository';
import type { TEntitlement } from '@n8n_io/license-sdk';
import { mock } from 'jest-mock-extended';
@ -10,13 +10,13 @@ describe('LicenseService', () => {
const license = mock<License>();
const workflowRepository = mock<WorkflowRepository>();
const entitlement = mock<TEntitlement>({ productId: '123' });
const eventRelay = mock<EventRelay>();
const eventService = mock<EventService>();
const licenseService = new LicenseService(
mock(),
license,
workflowRepository,
mock(),
eventRelay,
eventService,
);
license.getMainPlan.mockReturnValue(entitlement);
@ -67,7 +67,9 @@ describe('LicenseService', () => {
license.renew.mockResolvedValueOnce();
await licenseService.renewLicense();
expect(eventRelay.emit).toHaveBeenCalledWith('license-renewal-attempted', { success: true });
expect(eventService.emit).toHaveBeenCalledWith('license-renewal-attempted', {
success: true,
});
});
test('on failure', async () => {
@ -76,7 +78,9 @@ describe('LicenseService', () => {
new BadRequestError('Activation key has expired'),
);
expect(eventRelay.emit).toHaveBeenCalledWith('license-renewal-attempted', { success: false });
expect(eventService.emit).toHaveBeenCalledWith('license-renewal-attempted', {
success: false,
});
});
});
});