mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
refactor(core): Clean up event relays (no-changelog) (#10284)
This commit is contained in:
parent
55f2ffe256
commit
aa0a470dce
|
@ -13,7 +13,7 @@ import { Logger } from '@/Logger';
|
||||||
import { jsonParse, type IDataObject, ApplicationError } from 'n8n-workflow';
|
import { jsonParse, type IDataObject, ApplicationError } from 'n8n-workflow';
|
||||||
import { EXTERNAL_SECRETS_INITIAL_BACKOFF, EXTERNAL_SECRETS_MAX_BACKOFF } from './constants';
|
import { EXTERNAL_SECRETS_INITIAL_BACKOFF, EXTERNAL_SECRETS_MAX_BACKOFF } from './constants';
|
||||||
import { License } from '@/License';
|
import { License } from '@/License';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
import { updateIntervalTime } from './externalSecretsHelper.ee';
|
import { updateIntervalTime } from './externalSecretsHelper.ee';
|
||||||
import { ExternalSecretsProviders } from './ExternalSecretsProviders.ee';
|
import { ExternalSecretsProviders } from './ExternalSecretsProviders.ee';
|
||||||
import { OrchestrationService } from '@/services/orchestration.service';
|
import { OrchestrationService } from '@/services/orchestration.service';
|
||||||
|
|
|
@ -9,8 +9,8 @@ import { Telemetry } from '@/telemetry';
|
||||||
import { MessageEventBus } from './eventbus/MessageEventBus/MessageEventBus';
|
import { MessageEventBus } from './eventbus/MessageEventBus/MessageEventBus';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Do not add to this class. To add audit or telemetry events, use
|
* @deprecated Do not add to this class. To add log streaming or telemetry events, use
|
||||||
* `EventService` to emit the event and then use the `AuditEventRelay` or
|
* `EventService` to emit the event and then use the `LogStreamingEventRelay` or
|
||||||
* `TelemetryEventRelay` to forward them to the event bus or telemetry.
|
* `TelemetryEventRelay` to forward them to the event bus or telemetry.
|
||||||
*/
|
*/
|
||||||
@Service()
|
@Service()
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { NON_SENSIBLE_LDAP_CONFIG_PROPERTIES } from './constants';
|
||||||
import { getLdapSynchronizations } from './helpers.ee';
|
import { getLdapSynchronizations } from './helpers.ee';
|
||||||
import { LdapConfiguration } from './types';
|
import { LdapConfiguration } from './types';
|
||||||
import { LdapService } from './ldap.service.ee';
|
import { LdapService } from './ldap.service.ee';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@RestController('/ldap')
|
@RestController('/ldap')
|
||||||
export class LdapController {
|
export class LdapController {
|
||||||
|
|
|
@ -44,7 +44,7 @@ import {
|
||||||
LDAP_LOGIN_ENABLED,
|
LDAP_LOGIN_ENABLED,
|
||||||
LDAP_LOGIN_LABEL,
|
LDAP_LOGIN_LABEL,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class LdapService {
|
export class LdapService {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { UserRepository } from '@db/repositories/user.repository';
|
||||||
import { UrlService } from '@/services/url.service';
|
import { UrlService } from '@/services/url.service';
|
||||||
import type { AuthenticatedRequest } from '@/requests';
|
import type { AuthenticatedRequest } from '@/requests';
|
||||||
import { GlobalConfig } from '@n8n/config';
|
import { GlobalConfig } from '@n8n/config';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
async function createApiRouter(
|
async function createApiRouter(
|
||||||
version: string,
|
version: string,
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { Container } from 'typedi';
|
||||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||||
import { ProjectRepository } from '@/databases/repositories/project.repository';
|
import { ProjectRepository } from '@/databases/repositories/project.repository';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
export async function getCredentials(credentialId: string): Promise<ICredentialsDb | null> {
|
export async function getCredentials(credentialId: string): Promise<ICredentialsDb | null> {
|
||||||
return await Container.get(CredentialsRepository).findOneBy({ id: credentialId });
|
return await Container.get(CredentialsRepository).findOneBy({ id: credentialId });
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
getTrackingInformationFromPullResult,
|
getTrackingInformationFromPullResult,
|
||||||
isSourceControlLicensed,
|
isSourceControlLicensed,
|
||||||
} from '@/environments/sourceControl/sourceControlHelper.ee';
|
} from '@/environments/sourceControl/sourceControlHelper.ee';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
export = {
|
export = {
|
||||||
pull: [
|
pull: [
|
||||||
|
|
|
@ -32,7 +32,7 @@ import { SharedWorkflowRepository } from '@/databases/repositories/sharedWorkflo
|
||||||
import { TagRepository } from '@/databases/repositories/tag.repository';
|
import { TagRepository } from '@/databases/repositories/tag.repository';
|
||||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||||
import { ProjectRepository } from '@/databases/repositories/project.repository';
|
import { ProjectRepository } from '@/databases/repositories/project.repository';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { EnterpriseWorkflowService } from '@/workflows/workflow.service.ee';
|
import { EnterpriseWorkflowService } from '@/workflows/workflow.service.ee';
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ import { MessageEventBus } from '@/eventbus/MessageEventBus/MessageEventBus';
|
||||||
import { handleMfaDisable, isMfaFeatureEnabled } from '@/Mfa/helpers';
|
import { handleMfaDisable, isMfaFeatureEnabled } from '@/Mfa/helpers';
|
||||||
import type { FrontendService } from '@/services/frontend.service';
|
import type { FrontendService } from '@/services/frontend.service';
|
||||||
import { OrchestrationService } from '@/services/orchestration.service';
|
import { OrchestrationService } from '@/services/orchestration.service';
|
||||||
import { AuditEventRelay } from './eventbus/audit-event-relay.service';
|
import { LogStreamingEventRelay } from '@/events/log-streaming-event-relay';
|
||||||
|
|
||||||
import '@/controllers/activeWorkflows.controller';
|
import '@/controllers/activeWorkflows.controller';
|
||||||
import '@/controllers/auth.controller';
|
import '@/controllers/auth.controller';
|
||||||
|
@ -64,7 +64,7 @@ import '@/ExternalSecrets/ExternalSecrets.controller.ee';
|
||||||
import '@/license/license.controller';
|
import '@/license/license.controller';
|
||||||
import '@/workflows/workflowHistory/workflowHistory.controller.ee';
|
import '@/workflows/workflowHistory/workflowHistory.controller.ee';
|
||||||
import '@/workflows/workflows.controller';
|
import '@/workflows/workflows.controller';
|
||||||
import { EventService } from './eventbus/event.service';
|
import { EventService } from './events/event.service';
|
||||||
|
|
||||||
const exec = promisify(callbackExec);
|
const exec = promisify(callbackExec);
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ export class Server extends AbstractServer {
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
const eventBus = Container.get(MessageEventBus);
|
const eventBus = Container.get(MessageEventBus);
|
||||||
await eventBus.initialize();
|
await eventBus.initialize();
|
||||||
Container.get(AuditEventRelay).init();
|
Container.get(LogStreamingEventRelay).init();
|
||||||
|
|
||||||
if (this.endpointPresetCredentials !== '') {
|
if (this.endpointPresetCredentials !== '') {
|
||||||
// POST endpoint to set preset credentials
|
// POST endpoint to set preset credentials
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { toError } from '@/utils';
|
||||||
|
|
||||||
import type { InviteEmailData, PasswordResetData, SendEmailResult } from './Interfaces';
|
import type { InviteEmailData, PasswordResetData, SendEmailResult } from './Interfaces';
|
||||||
import { NodeMailer } from './NodeMailer';
|
import { NodeMailer } from './NodeMailer';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
type Template = HandlebarsTemplateDelegate<unknown>;
|
type Template = HandlebarsTemplateDelegate<unknown>;
|
||||||
type TemplateName = 'invite' | 'passwordReset' | 'workflowShared' | 'credentialsShared';
|
type TemplateName = 'invite' | 'passwordReset' | 'workflowShared' | 'credentialsShared';
|
||||||
|
|
|
@ -70,7 +70,7 @@ import { WorkflowRepository } from './databases/repositories/workflow.repository
|
||||||
import { UrlService } from './services/url.service';
|
import { UrlService } from './services/url.service';
|
||||||
import { WorkflowExecutionService } from './workflows/workflowExecution.service';
|
import { WorkflowExecutionService } from './workflows/workflowExecution.service';
|
||||||
import { MessageEventBus } from '@/eventbus/MessageEventBus/MessageEventBus';
|
import { MessageEventBus } from '@/eventbus/MessageEventBus/MessageEventBus';
|
||||||
import { EventService } from './eventbus/event.service';
|
import { EventService } from './events/event.service';
|
||||||
import { GlobalConfig } from '@n8n/config';
|
import { GlobalConfig } from '@n8n/config';
|
||||||
import { SubworkflowPolicyChecker } from './subworkflows/subworkflow-policy-checker.service';
|
import { SubworkflowPolicyChecker } from './subworkflows/subworkflow-policy-checker.service';
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ import { generateFailedExecutionFromError } from '@/WorkflowHelpers';
|
||||||
import { PermissionChecker } from '@/UserManagement/PermissionChecker';
|
import { PermissionChecker } from '@/UserManagement/PermissionChecker';
|
||||||
import { Logger } from '@/Logger';
|
import { Logger } from '@/Logger';
|
||||||
import { WorkflowStaticDataService } from '@/workflows/workflowStaticData.service';
|
import { WorkflowStaticDataService } from '@/workflows/workflowStaticData.service';
|
||||||
import { EventService } from './eventbus/event.service';
|
import { EventService } from './events/event.service';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class WorkflowRunner {
|
export class WorkflowRunner {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Container } from 'typedi';
|
||||||
import { isLdapLoginEnabled } from '@/Ldap/helpers.ee';
|
import { isLdapLoginEnabled } from '@/Ldap/helpers.ee';
|
||||||
import { UserRepository } from '@db/repositories/user.repository';
|
import { UserRepository } from '@db/repositories/user.repository';
|
||||||
import { AuthError } from '@/errors/response-errors/auth.error';
|
import { AuthError } from '@/errors/response-errors/auth.error';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
export const handleEmailLogin = async (
|
export const handleEmailLogin = async (
|
||||||
email: string,
|
email: string,
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
updateLdapUserOnLocalDb,
|
updateLdapUserOnLocalDb,
|
||||||
} from '@/Ldap/helpers.ee';
|
} from '@/Ldap/helpers.ee';
|
||||||
import type { User } from '@db/entities/User';
|
import type { User } from '@db/entities/User';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
export const handleLdapLogin = async (
|
export const handleLdapLogin = async (
|
||||||
loginId: string,
|
loginId: string,
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { initExpressionEvaluator } from '@/ExpressionEvaluator';
|
||||||
import { generateHostInstanceId } from '@db/utils/generators';
|
import { generateHostInstanceId } from '@db/utils/generators';
|
||||||
import { WorkflowHistoryManager } from '@/workflows/workflowHistory/workflowHistoryManager.ee';
|
import { WorkflowHistoryManager } from '@/workflows/workflowHistory/workflowHistoryManager.ee';
|
||||||
import { ShutdownService } from '@/shutdown/Shutdown.service';
|
import { ShutdownService } from '@/shutdown/Shutdown.service';
|
||||||
import { TelemetryEventRelay } from '@/telemetry/telemetry-event-relay.service';
|
import { TelemetryEventRelay } from '@/events/telemetry-event-relay';
|
||||||
|
|
||||||
export abstract class BaseCommand extends Command {
|
export abstract class BaseCommand extends Command {
|
||||||
protected logger = Container.get(Logger);
|
protected logger = Container.get(Logger);
|
||||||
|
|
|
@ -33,7 +33,7 @@ import { ExecutionService } from '@/executions/execution.service';
|
||||||
import { OwnershipService } from '@/services/ownership.service';
|
import { OwnershipService } from '@/services/ownership.service';
|
||||||
import { WorkflowRunner } from '@/WorkflowRunner';
|
import { WorkflowRunner } from '@/WorkflowRunner';
|
||||||
import { ExecutionRecoveryService } from '@/executions/execution-recovery.service';
|
import { ExecutionRecoveryService } from '@/executions/execution-recovery.service';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
|
||||||
const open = require('open');
|
const open = require('open');
|
||||||
|
|
|
@ -30,7 +30,7 @@ import type { WorkerJobStatusSummary } from '@/services/orchestration/worker/typ
|
||||||
import { ServiceUnavailableError } from '@/errors/response-errors/service-unavailable.error';
|
import { ServiceUnavailableError } from '@/errors/response-errors/service-unavailable.error';
|
||||||
import { BaseCommand } from './BaseCommand';
|
import { BaseCommand } from './BaseCommand';
|
||||||
import { MaxStalledCountError } from '@/errors/max-stalled-count.error';
|
import { MaxStalledCountError } from '@/errors/max-stalled-count.error';
|
||||||
import { AuditEventRelay } from '@/eventbus/audit-event-relay.service';
|
import { LogStreamingEventRelay } from '@/events/log-streaming-event-relay';
|
||||||
|
|
||||||
export class Worker extends BaseCommand {
|
export class Worker extends BaseCommand {
|
||||||
static description = '\nStarts a n8n worker';
|
static description = '\nStarts a n8n worker';
|
||||||
|
@ -286,7 +286,7 @@ export class Worker extends BaseCommand {
|
||||||
await Container.get(MessageEventBus).initialize({
|
await Container.get(MessageEventBus).initialize({
|
||||||
workerId: this.queueModeId,
|
workerId: this.queueModeId,
|
||||||
});
|
});
|
||||||
Container.get(AuditEventRelay).init();
|
Container.get(LogStreamingEventRelay).init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,7 +12,7 @@ import type { WorkflowExecuteMode as ExecutionMode } from 'n8n-workflow';
|
||||||
import type { ExecutionRepository } from '@/databases/repositories/execution.repository';
|
import type { ExecutionRepository } from '@/databases/repositories/execution.repository';
|
||||||
import type { IExecutingWorkflowData } from '@/Interfaces';
|
import type { IExecutingWorkflowData } from '@/Interfaces';
|
||||||
import type { Telemetry } from '@/telemetry';
|
import type { Telemetry } from '@/telemetry';
|
||||||
import type { EventService } from '@/eventbus/event.service';
|
import type { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
describe('ConcurrencyControlService', () => {
|
describe('ConcurrencyControlService', () => {
|
||||||
const logger = mock<Logger>();
|
const logger = mock<Logger>();
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { ExecutionRepository } from '@/databases/repositories/execution.reposito
|
||||||
import type { WorkflowExecuteMode as ExecutionMode } from 'n8n-workflow';
|
import type { WorkflowExecuteMode as ExecutionMode } from 'n8n-workflow';
|
||||||
import type { IExecutingWorkflowData } from '@/Interfaces';
|
import type { IExecutingWorkflowData } from '@/Interfaces';
|
||||||
import { Telemetry } from '@/telemetry';
|
import { Telemetry } from '@/telemetry';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
export const CLOUD_TEMP_PRODUCTION_LIMIT = 999;
|
export const CLOUD_TEMP_PRODUCTION_LIMIT = 999;
|
||||||
export const CLOUD_TEMP_REPORTABLE_THRESHOLDS = [5, 10, 20, 50, 100, 200];
|
export const CLOUD_TEMP_REPORTABLE_THRESHOLDS = [5, 10, 20, 50, 100, 200];
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
|
import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
|
||||||
import { ApplicationError } from 'n8n-workflow';
|
import { ApplicationError } from 'n8n-workflow';
|
||||||
import { UserRepository } from '@/databases/repositories/user.repository';
|
import { UserRepository } from '@/databases/repositories/user.repository';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@RestController()
|
@RestController()
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { Push } from '@/push';
|
||||||
import { CommunityPackagesService } from '@/services/communityPackages.service';
|
import { CommunityPackagesService } from '@/services/communityPackages.service';
|
||||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
import { InternalServerError } from '@/errors/response-errors/internal-server.error';
|
import { InternalServerError } from '@/errors/response-errors/internal-server.error';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
PACKAGE_NOT_INSTALLED,
|
PACKAGE_NOT_INSTALLED,
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
|
import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
|
||||||
import { InternalHooks } from '@/InternalHooks';
|
import { InternalHooks } from '@/InternalHooks';
|
||||||
import { ExternalHooks } from '@/ExternalHooks';
|
import { ExternalHooks } from '@/ExternalHooks';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@RestController('/invitations')
|
@RestController('/invitations')
|
||||||
export class InvitationController {
|
export class InvitationController {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { InternalHooks } from '@/InternalHooks';
|
||||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
import { UserRepository } from '@/databases/repositories/user.repository';
|
import { UserRepository } from '@/databases/repositories/user.repository';
|
||||||
import { isApiEnabled } from '@/PublicApi';
|
import { isApiEnabled } from '@/PublicApi';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
export const API_KEY_PREFIX = 'n8n_api_';
|
export const API_KEY_PREFIX = 'n8n_api_';
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { ForbiddenError } from '@/errors/response-errors/forbidden.error';
|
||||||
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||||
import { UnprocessableRequestError } from '@/errors/response-errors/unprocessable.error';
|
import { UnprocessableRequestError } from '@/errors/response-errors/unprocessable.error';
|
||||||
import { UserRepository } from '@/databases/repositories/user.repository';
|
import { UserRepository } from '@/databases/repositories/user.repository';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@RestController()
|
@RestController()
|
||||||
export class PasswordResetController {
|
export class PasswordResetController {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { ProjectRepository } from '@/databases/repositories/project.repository';
|
||||||
// eslint-disable-next-line n8n-local-rules/misplaced-n8n-typeorm-import
|
// eslint-disable-next-line n8n-local-rules/misplaced-n8n-typeorm-import
|
||||||
import { In, Not } from '@n8n/typeorm';
|
import { In, Not } from '@n8n/typeorm';
|
||||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@RestController('/projects')
|
@RestController('/projects')
|
||||||
export class ProjectController {
|
export class ProjectController {
|
||||||
|
|
|
@ -28,7 +28,7 @@ import { Project } from '@/databases/entities/Project';
|
||||||
import { WorkflowService } from '@/workflows/workflow.service';
|
import { WorkflowService } from '@/workflows/workflow.service';
|
||||||
import { CredentialsService } from '@/credentials/credentials.service';
|
import { CredentialsService } from '@/credentials/credentials.service';
|
||||||
import { ProjectService } from '@/services/project.service';
|
import { ProjectService } from '@/services/project.service';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@RestController('/users')
|
@RestController('/users')
|
||||||
export class UsersController {
|
export class UsersController {
|
||||||
|
|
|
@ -30,7 +30,7 @@ import { SharedCredentialsRepository } from '@/databases/repositories/sharedCred
|
||||||
import { SharedCredentials } from '@/databases/entities/SharedCredentials';
|
import { SharedCredentials } from '@/databases/entities/SharedCredentials';
|
||||||
import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository';
|
import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@RestController('/credentials')
|
@RestController('/credentials')
|
||||||
export class CredentialsController {
|
export class CredentialsController {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { RedactableError } from '@/errors/redactable.error';
|
import { RedactableError } from '@/errors/redactable.error';
|
||||||
import type { UserLike } from '@/eventbus/event.types';
|
import type { UserLike } from '@/events/relay-event-map';
|
||||||
|
|
||||||
function toRedactable(userLike: UserLike) {
|
function toRedactable(userLike: UserLike) {
|
||||||
return {
|
return {
|
||||||
|
@ -14,7 +14,7 @@ function toRedactable(userLike: UserLike) {
|
||||||
type FieldName = 'user' | 'inviter' | 'invitee';
|
type FieldName = 'user' | 'inviter' | 'invitee';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark redactable properties in a `{ user: UserLike }` field in an `AuditEventRelay`
|
* Mark redactable properties in a `{ user: UserLike }` field in an `LogStreamingEventRelay`
|
||||||
* method arg. These properties will be later redacted by the log streaming
|
* method arg. These properties will be later redacted by the log streaming
|
||||||
* destination based on user prefs. Only for `n8n.audit.*` logs.
|
* destination based on user prefs. Only for `n8n.audit.*` logs.
|
||||||
*
|
*
|
||||||
|
|
|
@ -12,7 +12,7 @@ import type { SourceControlPreferences } from './types/sourceControlPreferences'
|
||||||
import type { SourceControlledFile } from './types/sourceControlledFile';
|
import type { SourceControlledFile } from './types/sourceControlledFile';
|
||||||
import { SOURCE_CONTROL_DEFAULT_BRANCH } from './constants';
|
import { SOURCE_CONTROL_DEFAULT_BRANCH } from './constants';
|
||||||
import type { ImportResult } from './types/importResult';
|
import type { ImportResult } from './types/importResult';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
import { getRepoType } from './sourceControlHelper.ee';
|
import { getRepoType } from './sourceControlHelper.ee';
|
||||||
import { SourceControlGetStatus } from './types/sourceControlGetStatus';
|
import { SourceControlGetStatus } from './types/sourceControlGetStatus';
|
||||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
|
|
|
@ -30,7 +30,7 @@ import type { TagEntity } from '@db/entities/TagEntity';
|
||||||
import type { Variables } from '@db/entities/Variables';
|
import type { Variables } from '@db/entities/Variables';
|
||||||
import type { SourceControlWorkflowVersionId } from './types/sourceControlWorkflowVersionId';
|
import type { SourceControlWorkflowVersionId } from './types/sourceControlWorkflowVersionId';
|
||||||
import type { ExportableCredential } from './types/exportableCredential';
|
import type { ExportableCredential } from './types/exportableCredential';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
import { TagRepository } from '@db/repositories/tag.repository';
|
import { TagRepository } from '@db/repositories/tag.repository';
|
||||||
import { Logger } from '@/Logger';
|
import { Logger } from '@/Logger';
|
||||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { CacheService } from '@/services/cache/cache.service';
|
||||||
import { VariablesRepository } from '@db/repositories/variables.repository';
|
import { VariablesRepository } from '@db/repositories/variables.repository';
|
||||||
import { VariableCountLimitReachedError } from '@/errors/variable-count-limit-reached.error';
|
import { VariableCountLimitReachedError } from '@/errors/variable-count-limit-reached.error';
|
||||||
import { VariableValidationError } from '@/errors/variable-validation.error';
|
import { VariableValidationError } from '@/errors/variable-validation.error';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class VariablesService {
|
export class VariablesService {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ApplicationError } from 'n8n-workflow';
|
||||||
export class RedactableError extends ApplicationError {
|
export class RedactableError extends ApplicationError {
|
||||||
constructor(fieldName: string, args: string) {
|
constructor(fieldName: string, args: string) {
|
||||||
super(
|
super(
|
||||||
`Failed to find "${fieldName}" property in argument "${args.toString()}". Please set the decorator \`@Redactable()\` only on \`AuditEventRelay\` methods where the argument contains a "${fieldName}" property.`,
|
`Failed to find "${fieldName}" property in argument "${args.toString()}". Please set the decorator \`@Redactable()\` only on \`LogStreamingEventRelay\` methods where the argument contains a "${fieldName}" property.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
import { Service } from 'typedi';
|
|
||||||
import { TypedEmitter } from '@/TypedEmitter';
|
|
||||||
import type { Event } from './event.types';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class EventService extends TypedEmitter<Event> {}
|
|
|
@ -1,16 +1,15 @@
|
||||||
import { mock } from 'jest-mock-extended';
|
import { mock } from 'jest-mock-extended';
|
||||||
import { AuditEventRelay } from '../audit-event-relay.service';
|
import { LogStreamingEventRelay } from '@/events/log-streaming-event-relay';
|
||||||
import type { MessageEventBus } from '../MessageEventBus/MessageEventBus';
|
import { EventService } from '@/events/event.service';
|
||||||
import type { Event } from '../event.types';
|
|
||||||
import { EventService } from '../event.service';
|
|
||||||
import type { INode, IRun, IWorkflowBase } from 'n8n-workflow';
|
import type { INode, IRun, IWorkflowBase } from 'n8n-workflow';
|
||||||
import type { IWorkflowDb } from '@/Interfaces';
|
import type { IWorkflowDb } from '@/Interfaces';
|
||||||
|
import type { MessageEventBus } from '@/eventbus/MessageEventBus/MessageEventBus';
|
||||||
|
import type { RelayEventMap } from '@/events/relay-event-map';
|
||||||
|
|
||||||
describe('AuditEventRelay', () => {
|
describe('LogStreamingEventRelay', () => {
|
||||||
const eventBus = mock<MessageEventBus>();
|
const eventBus = mock<MessageEventBus>();
|
||||||
const eventService = new EventService();
|
const eventService = new EventService();
|
||||||
const auditor = new AuditEventRelay(eventService, eventBus);
|
new LogStreamingEventRelay(eventService, eventBus).init();
|
||||||
auditor.init();
|
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
@ -18,7 +17,7 @@ describe('AuditEventRelay', () => {
|
||||||
|
|
||||||
describe('workflow events', () => {
|
describe('workflow events', () => {
|
||||||
it('should log on `workflow-created` event', () => {
|
it('should log on `workflow-created` event', () => {
|
||||||
const event: Event['workflow-created'] = {
|
const event: RelayEventMap['workflow-created'] = {
|
||||||
user: {
|
user: {
|
||||||
id: '123',
|
id: '123',
|
||||||
email: 'john@n8n.io',
|
email: 'john@n8n.io',
|
||||||
|
@ -52,7 +51,7 @@ describe('AuditEventRelay', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log on `workflow-deleted` event', () => {
|
it('should log on `workflow-deleted` event', () => {
|
||||||
const event: Event['workflow-deleted'] = {
|
const event: RelayEventMap['workflow-deleted'] = {
|
||||||
user: {
|
user: {
|
||||||
id: '456',
|
id: '456',
|
||||||
email: 'jane@n8n.io',
|
email: 'jane@n8n.io',
|
||||||
|
@ -80,7 +79,7 @@ describe('AuditEventRelay', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log on `workflow-saved` event', () => {
|
it('should log on `workflow-saved` event', () => {
|
||||||
const event: Event['workflow-saved'] = {
|
const event: RelayEventMap['workflow-saved'] = {
|
||||||
user: {
|
user: {
|
||||||
id: '789',
|
id: '789',
|
||||||
email: 'alex@n8n.io',
|
email: 'alex@n8n.io',
|
||||||
|
@ -119,7 +118,7 @@ describe('AuditEventRelay', () => {
|
||||||
settings: {},
|
settings: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const event: Event['workflow-pre-execute'] = {
|
const event: RelayEventMap['workflow-pre-execute'] = {
|
||||||
executionId: 'exec123',
|
executionId: 'exec123',
|
||||||
data: workflow,
|
data: workflow,
|
||||||
};
|
};
|
||||||
|
@ -139,7 +138,7 @@ describe('AuditEventRelay', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log on `workflow-post-execute` for successful execution', () => {
|
it('should log on `workflow-post-execute` for successful execution', () => {
|
||||||
const payload = mock<Event['workflow-post-execute']>({
|
const payload = mock<RelayEventMap['workflow-post-execute']>({
|
||||||
executionId: 'some-id',
|
executionId: 'some-id',
|
||||||
userId: 'some-id',
|
userId: 'some-id',
|
||||||
workflow: mock<IWorkflowBase>({ id: 'some-id', name: 'some-name' }),
|
workflow: mock<IWorkflowBase>({ id: 'some-id', name: 'some-name' }),
|
||||||
|
@ -208,7 +207,7 @@ describe('AuditEventRelay', () => {
|
||||||
|
|
||||||
describe('user events', () => {
|
describe('user events', () => {
|
||||||
it('should log on `user-updated` event', () => {
|
it('should log on `user-updated` event', () => {
|
||||||
const event: Event['user-updated'] = {
|
const event: RelayEventMap['user-updated'] = {
|
||||||
user: {
|
user: {
|
||||||
id: 'user456',
|
id: 'user456',
|
||||||
email: 'updated@example.com',
|
email: 'updated@example.com',
|
||||||
|
@ -235,7 +234,7 @@ describe('AuditEventRelay', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log on `user-deleted` event', () => {
|
it('should log on `user-deleted` event', () => {
|
||||||
const event: Event['user-deleted'] = {
|
const event: RelayEventMap['user-deleted'] = {
|
||||||
user: {
|
user: {
|
||||||
id: '123',
|
id: '123',
|
||||||
email: 'john@n8n.io',
|
email: 'john@n8n.io',
|
||||||
|
@ -262,7 +261,7 @@ describe('AuditEventRelay', () => {
|
||||||
|
|
||||||
describe('click events', () => {
|
describe('click events', () => {
|
||||||
it('should log on `user-password-reset-request-click` event', () => {
|
it('should log on `user-password-reset-request-click` event', () => {
|
||||||
const event: Event['user-password-reset-request-click'] = {
|
const event: RelayEventMap['user-password-reset-request-click'] = {
|
||||||
user: {
|
user: {
|
||||||
id: 'user101',
|
id: 'user101',
|
||||||
email: 'user101@example.com',
|
email: 'user101@example.com',
|
||||||
|
@ -287,7 +286,7 @@ describe('AuditEventRelay', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log on `user-invite-email-click` event', () => {
|
it('should log on `user-invite-email-click` event', () => {
|
||||||
const event: Event['user-invite-email-click'] = {
|
const event: RelayEventMap['user-invite-email-click'] = {
|
||||||
inviter: {
|
inviter: {
|
||||||
id: '123',
|
id: '123',
|
||||||
email: 'john@n8n.io',
|
email: 'john@n8n.io',
|
||||||
|
@ -354,7 +353,7 @@ describe('AuditEventRelay', () => {
|
||||||
settings: {},
|
settings: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const event: Event['node-pre-execute'] = {
|
const event: RelayEventMap['node-pre-execute'] = {
|
||||||
executionId: 'exec456',
|
executionId: 'exec456',
|
||||||
nodeName: 'HTTP Request',
|
nodeName: 'HTTP Request',
|
||||||
workflow,
|
workflow,
|
||||||
|
@ -399,7 +398,7 @@ describe('AuditEventRelay', () => {
|
||||||
settings: {},
|
settings: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const event: Event['node-post-execute'] = {
|
const event: RelayEventMap['node-post-execute'] = {
|
||||||
executionId: 'exec789',
|
executionId: 'exec789',
|
||||||
nodeName: 'HTTP Response',
|
nodeName: 'HTTP Response',
|
||||||
workflow,
|
workflow,
|
||||||
|
@ -422,7 +421,7 @@ describe('AuditEventRelay', () => {
|
||||||
|
|
||||||
describe('credentials events', () => {
|
describe('credentials events', () => {
|
||||||
it('should log on `credentials-shared` event', () => {
|
it('should log on `credentials-shared` event', () => {
|
||||||
const event: Event['credentials-shared'] = {
|
const event: RelayEventMap['credentials-shared'] = {
|
||||||
user: {
|
user: {
|
||||||
id: 'user123',
|
id: 'user123',
|
||||||
email: 'sharer@example.com',
|
email: 'sharer@example.com',
|
||||||
|
@ -457,7 +456,7 @@ describe('AuditEventRelay', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log on `credentials-created` event', () => {
|
it('should log on `credentials-created` event', () => {
|
||||||
const event: Event['credentials-created'] = {
|
const event: RelayEventMap['credentials-created'] = {
|
||||||
user: {
|
user: {
|
||||||
id: 'user123',
|
id: 'user123',
|
||||||
email: 'user@example.com',
|
email: 'user@example.com',
|
||||||
|
@ -494,7 +493,7 @@ describe('AuditEventRelay', () => {
|
||||||
|
|
||||||
describe('auth events', () => {
|
describe('auth events', () => {
|
||||||
it('should log on `user-login-failed` event', () => {
|
it('should log on `user-login-failed` event', () => {
|
||||||
const event: Event['user-login-failed'] = {
|
const event: RelayEventMap['user-login-failed'] = {
|
||||||
userEmail: 'user@example.com',
|
userEmail: 'user@example.com',
|
||||||
authenticationMethod: 'email',
|
authenticationMethod: 'email',
|
||||||
reason: 'Invalid password',
|
reason: 'Invalid password',
|
||||||
|
@ -515,7 +514,7 @@ describe('AuditEventRelay', () => {
|
||||||
|
|
||||||
describe('community package events', () => {
|
describe('community package events', () => {
|
||||||
it('should log on `community-package-updated` event', () => {
|
it('should log on `community-package-updated` event', () => {
|
||||||
const event: Event['community-package-updated'] = {
|
const event: RelayEventMap['community-package-updated'] = {
|
||||||
user: {
|
user: {
|
||||||
id: 'user202',
|
id: 'user202',
|
||||||
email: 'packageupdater@example.com',
|
email: 'packageupdater@example.com',
|
||||||
|
@ -552,7 +551,7 @@ describe('AuditEventRelay', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log on `community-package-installed` event', () => {
|
it('should log on `community-package-installed` event', () => {
|
||||||
const event: Event['community-package-installed'] = {
|
const event: RelayEventMap['community-package-installed'] = {
|
||||||
user: {
|
user: {
|
||||||
id: 'user789',
|
id: 'user789',
|
||||||
email: 'admin@example.com',
|
email: 'admin@example.com',
|
||||||
|
@ -593,7 +592,7 @@ describe('AuditEventRelay', () => {
|
||||||
|
|
||||||
describe('email events', () => {
|
describe('email events', () => {
|
||||||
it('should log on `email-failed` event', () => {
|
it('should log on `email-failed` event', () => {
|
||||||
const event: Event['email-failed'] = {
|
const event: RelayEventMap['email-failed'] = {
|
||||||
user: {
|
user: {
|
||||||
id: 'user789',
|
id: 'user789',
|
||||||
email: 'recipient@example.com',
|
email: 'recipient@example.com',
|
||||||
|
@ -622,7 +621,7 @@ describe('AuditEventRelay', () => {
|
||||||
|
|
||||||
describe('public API events', () => {
|
describe('public API events', () => {
|
||||||
it('should log on `public-api-key-created` event', () => {
|
it('should log on `public-api-key-created` event', () => {
|
||||||
const event: Event['public-api-key-created'] = {
|
const event: RelayEventMap['public-api-key-created'] = {
|
||||||
user: {
|
user: {
|
||||||
id: 'user101',
|
id: 'user101',
|
||||||
email: 'apiuser@example.com',
|
email: 'apiuser@example.com',
|
||||||
|
@ -650,7 +649,7 @@ describe('AuditEventRelay', () => {
|
||||||
|
|
||||||
describe('execution events', () => {
|
describe('execution events', () => {
|
||||||
it('should log on `execution-throttled` event', () => {
|
it('should log on `execution-throttled` event', () => {
|
||||||
const event: Event['execution-throttled'] = {
|
const event: RelayEventMap['execution-throttled'] = {
|
||||||
executionId: 'exec123456',
|
executionId: 'exec123456',
|
||||||
};
|
};
|
||||||
|
|
20
packages/cli/src/events/event-relay.ts
Normal file
20
packages/cli/src/events/event-relay.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { EventService } from './event.service';
|
||||||
|
import { Service } from 'typedi';
|
||||||
|
import type { RelayEventMap } from '@/events/relay-event-map';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class EventRelay {
|
||||||
|
constructor(readonly eventService: EventService) {}
|
||||||
|
|
||||||
|
protected setupListeners<EventNames extends keyof RelayEventMap>(map: {
|
||||||
|
[EventName in EventNames]?: (event: RelayEventMap[EventName]) => void | Promise<void>;
|
||||||
|
}) {
|
||||||
|
for (const [eventName, handler] of Object.entries(map) as Array<
|
||||||
|
[EventNames, (event: RelayEventMap[EventNames]) => void | Promise<void>]
|
||||||
|
>) {
|
||||||
|
this.eventService.on(eventName, async (event) => {
|
||||||
|
await handler(event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
packages/cli/src/events/event.service.ts
Normal file
6
packages/cli/src/events/event.service.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { Service } from 'typedi';
|
||||||
|
import { TypedEmitter } from '@/TypedEmitter';
|
||||||
|
import type { RelayEventMap } from './relay-event-map';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class EventService extends TypedEmitter<RelayEventMap> {}
|
|
@ -1,72 +1,58 @@
|
||||||
import { Service } from 'typedi';
|
import { Service } from 'typedi';
|
||||||
import { MessageEventBus } from './MessageEventBus/MessageEventBus';
|
import { MessageEventBus } from '@/eventbus/MessageEventBus/MessageEventBus';
|
||||||
import { Redactable } from '@/decorators/Redactable';
|
import { Redactable } from '@/decorators/Redactable';
|
||||||
import { EventService } from './event.service';
|
import { EventRelay } from '@/events/event-relay';
|
||||||
import type { Event } from './event.types';
|
import type { RelayEventMap } from '@/events/relay-event-map';
|
||||||
import type { IWorkflowBase } from 'n8n-workflow';
|
import type { IWorkflowBase } from 'n8n-workflow';
|
||||||
|
import { EventService } from './event.service';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class AuditEventRelay {
|
export class LogStreamingEventRelay extends EventRelay {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly eventService: EventService,
|
readonly eventService: EventService,
|
||||||
private readonly eventBus: MessageEventBus,
|
private readonly eventBus: MessageEventBus,
|
||||||
) {}
|
) {
|
||||||
|
super(eventService);
|
||||||
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.setupHandlers();
|
this.setupListeners({
|
||||||
|
'workflow-created': (event) => this.workflowCreated(event),
|
||||||
|
'workflow-deleted': (event) => this.workflowDeleted(event),
|
||||||
|
'workflow-saved': (event) => this.workflowSaved(event),
|
||||||
|
'workflow-pre-execute': (event) => this.workflowPreExecute(event),
|
||||||
|
'workflow-post-execute': (event) => this.workflowPostExecute(event),
|
||||||
|
'node-pre-execute': (event) => this.nodePreExecute(event),
|
||||||
|
'node-post-execute': (event) => this.nodePostExecute(event),
|
||||||
|
'user-deleted': (event) => this.userDeleted(event),
|
||||||
|
'user-invited': (event) => this.userInvited(event),
|
||||||
|
'user-reinvited': (event) => this.userReinvited(event),
|
||||||
|
'user-updated': (event) => this.userUpdated(event),
|
||||||
|
'user-signed-up': (event) => this.userSignedUp(event),
|
||||||
|
'user-logged-in': (event) => this.userLoggedIn(event),
|
||||||
|
'user-login-failed': (event) => this.userLoginFailed(event),
|
||||||
|
'user-invite-email-click': (event) => this.userInviteEmailClick(event),
|
||||||
|
'user-password-reset-email-click': (event) => this.userPasswordResetEmailClick(event),
|
||||||
|
'user-password-reset-request-click': (event) => this.userPasswordResetRequestClick(event),
|
||||||
|
'public-api-key-created': (event) => this.publicApiKeyCreated(event),
|
||||||
|
'public-api-key-deleted': (event) => this.publicApiKeyDeleted(event),
|
||||||
|
'email-failed': (event) => this.emailFailed(event),
|
||||||
|
'credentials-created': (event) => this.credentialsCreated(event),
|
||||||
|
'credentials-deleted': (event) => this.credentialsDeleted(event),
|
||||||
|
'credentials-shared': (event) => this.credentialsShared(event),
|
||||||
|
'credentials-updated': (event) => this.credentialsUpdated(event),
|
||||||
|
'community-package-installed': (event) => this.communityPackageInstalled(event),
|
||||||
|
'community-package-updated': (event) => this.communityPackageUpdated(event),
|
||||||
|
'community-package-deleted': (event) => this.communityPackageDeleted(event),
|
||||||
|
'execution-throttled': (event) => this.executionThrottled(event),
|
||||||
|
'execution-started-during-bootup': (event) => this.executionStartedDuringBootup(event),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupHandlers() {
|
// #region Workflow
|
||||||
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.eventService.on('user-password-reset-request-click', (event) =>
|
|
||||||
this.userPasswordResetRequestClick(event),
|
|
||||||
);
|
|
||||||
this.eventService.on('public-api-key-created', (event) => this.publicApiKeyCreated(event));
|
|
||||||
this.eventService.on('public-api-key-deleted', (event) => this.publicApiKeyDeleted(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.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),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Workflow
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private workflowCreated({ user, workflow }: Event['workflow-created']) {
|
private workflowCreated({ user, workflow }: RelayEventMap['workflow-created']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.workflow.created',
|
eventName: 'n8n.audit.workflow.created',
|
||||||
payload: {
|
payload: {
|
||||||
|
@ -78,7 +64,7 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private workflowDeleted({ user, workflowId }: Event['workflow-deleted']) {
|
private workflowDeleted({ user, workflowId }: RelayEventMap['workflow-deleted']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.workflow.deleted',
|
eventName: 'n8n.audit.workflow.deleted',
|
||||||
payload: { ...user, workflowId },
|
payload: { ...user, workflowId },
|
||||||
|
@ -86,7 +72,7 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private workflowSaved({ user, workflow }: Event['workflow-saved']) {
|
private workflowSaved({ user, workflow }: RelayEventMap['workflow-saved']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.workflow.updated',
|
eventName: 'n8n.audit.workflow.updated',
|
||||||
payload: {
|
payload: {
|
||||||
|
@ -97,7 +83,7 @@ export class AuditEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private workflowPreExecute({ data, executionId }: Event['workflow-pre-execute']) {
|
private workflowPreExecute({ data, executionId }: RelayEventMap['workflow-pre-execute']) {
|
||||||
const payload =
|
const payload =
|
||||||
'executionData' in data
|
'executionData' in data
|
||||||
? {
|
? {
|
||||||
|
@ -121,7 +107,7 @@ export class AuditEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private workflowPostExecute(event: Event['workflow-post-execute']) {
|
private workflowPostExecute(event: RelayEventMap['workflow-post-execute']) {
|
||||||
const { runData, workflow, ...rest } = event;
|
const { runData, workflow, ...rest } = event;
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
|
@ -155,11 +141,11 @@ export class AuditEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// #endregion
|
||||||
* Node
|
|
||||||
*/
|
|
||||||
|
|
||||||
private nodePreExecute({ workflow, executionId, nodeName }: Event['node-pre-execute']) {
|
// #region Node
|
||||||
|
|
||||||
|
private nodePreExecute({ workflow, executionId, nodeName }: RelayEventMap['node-pre-execute']) {
|
||||||
void this.eventBus.sendNodeEvent({
|
void this.eventBus.sendNodeEvent({
|
||||||
eventName: 'n8n.node.started',
|
eventName: 'n8n.node.started',
|
||||||
payload: {
|
payload: {
|
||||||
|
@ -172,7 +158,7 @@ export class AuditEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private nodePostExecute({ workflow, executionId, nodeName }: Event['node-post-execute']) {
|
private nodePostExecute({ workflow, executionId, nodeName }: RelayEventMap['node-post-execute']) {
|
||||||
void this.eventBus.sendNodeEvent({
|
void this.eventBus.sendNodeEvent({
|
||||||
eventName: 'n8n.node.finished',
|
eventName: 'n8n.node.finished',
|
||||||
payload: {
|
payload: {
|
||||||
|
@ -185,12 +171,12 @@ export class AuditEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// #endregion
|
||||||
* User
|
|
||||||
*/
|
// #region User
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private userDeleted({ user }: Event['user-deleted']) {
|
private userDeleted({ user }: RelayEventMap['user-deleted']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.deleted',
|
eventName: 'n8n.audit.user.deleted',
|
||||||
payload: user,
|
payload: user,
|
||||||
|
@ -198,7 +184,7 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private userInvited({ user, targetUserId }: Event['user-invited']) {
|
private userInvited({ user, targetUserId }: RelayEventMap['user-invited']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.invited',
|
eventName: 'n8n.audit.user.invited',
|
||||||
payload: { ...user, targetUserId },
|
payload: { ...user, targetUserId },
|
||||||
|
@ -206,7 +192,7 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private userReinvited({ user, targetUserId }: Event['user-reinvited']) {
|
private userReinvited({ user, targetUserId }: RelayEventMap['user-reinvited']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.reinvited',
|
eventName: 'n8n.audit.user.reinvited',
|
||||||
payload: { ...user, targetUserId },
|
payload: { ...user, targetUserId },
|
||||||
|
@ -214,19 +200,19 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private userUpdated({ user, fieldsChanged }: Event['user-updated']) {
|
private userUpdated({ user, fieldsChanged }: RelayEventMap['user-updated']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.updated',
|
eventName: 'n8n.audit.user.updated',
|
||||||
payload: { ...user, fieldsChanged },
|
payload: { ...user, fieldsChanged },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// #endregion
|
||||||
* Auth
|
|
||||||
*/
|
// #region Auth
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private userSignedUp({ user }: Event['user-signed-up']) {
|
private userSignedUp({ user }: RelayEventMap['user-signed-up']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.signedup',
|
eventName: 'n8n.audit.user.signedup',
|
||||||
payload: user,
|
payload: user,
|
||||||
|
@ -234,7 +220,7 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private userLoggedIn({ user, authenticationMethod }: Event['user-logged-in']) {
|
private userLoggedIn({ user, authenticationMethod }: RelayEventMap['user-logged-in']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.login.success',
|
eventName: 'n8n.audit.user.login.success',
|
||||||
payload: { ...user, authenticationMethod },
|
payload: { ...user, authenticationMethod },
|
||||||
|
@ -242,7 +228,7 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
private userLoginFailed(
|
private userLoginFailed(
|
||||||
event: Event['user-login-failed'] /* exception: no `UserLike` to redact */,
|
event: RelayEventMap['user-login-failed'] /* exception: no `UserLike` to redact */,
|
||||||
) {
|
) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.login.failed',
|
eventName: 'n8n.audit.user.login.failed',
|
||||||
|
@ -250,13 +236,13 @@ export class AuditEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// #endregion
|
||||||
* Click
|
|
||||||
*/
|
// #region Click
|
||||||
|
|
||||||
@Redactable('inviter')
|
@Redactable('inviter')
|
||||||
@Redactable('invitee')
|
@Redactable('invitee')
|
||||||
private userInviteEmailClick(event: Event['user-invite-email-click']) {
|
private userInviteEmailClick(event: RelayEventMap['user-invite-email-click']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.invitation.accepted',
|
eventName: 'n8n.audit.user.invitation.accepted',
|
||||||
payload: event,
|
payload: event,
|
||||||
|
@ -264,7 +250,7 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private userPasswordResetEmailClick({ user }: Event['user-password-reset-email-click']) {
|
private userPasswordResetEmailClick({ user }: RelayEventMap['user-password-reset-email-click']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.reset',
|
eventName: 'n8n.audit.user.reset',
|
||||||
payload: user,
|
payload: user,
|
||||||
|
@ -272,19 +258,21 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private userPasswordResetRequestClick({ user }: Event['user-password-reset-request-click']) {
|
private userPasswordResetRequestClick({
|
||||||
|
user,
|
||||||
|
}: RelayEventMap['user-password-reset-request-click']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.reset.requested',
|
eventName: 'n8n.audit.user.reset.requested',
|
||||||
payload: user,
|
payload: user,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// #endregion
|
||||||
* Public API
|
|
||||||
*/
|
// #region Public API
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private publicApiKeyCreated({ user }: Event['public-api-key-created']) {
|
private publicApiKeyCreated({ user }: RelayEventMap['public-api-key-created']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.api.created',
|
eventName: 'n8n.audit.user.api.created',
|
||||||
payload: user,
|
payload: user,
|
||||||
|
@ -292,31 +280,31 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private publicApiKeyDeleted({ user }: Event['public-api-key-deleted']) {
|
private publicApiKeyDeleted({ user }: RelayEventMap['public-api-key-deleted']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.api.deleted',
|
eventName: 'n8n.audit.user.api.deleted',
|
||||||
payload: user,
|
payload: user,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// #endregion
|
||||||
* Emailing
|
|
||||||
*/
|
// #region Email
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private emailFailed({ user, messageType }: Event['email-failed']) {
|
private emailFailed({ user, messageType }: RelayEventMap['email-failed']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.email.failed',
|
eventName: 'n8n.audit.user.email.failed',
|
||||||
payload: { ...user, messageType },
|
payload: { ...user, messageType },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// #endregion
|
||||||
* Credentials
|
|
||||||
*/
|
// #region Credentials
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private credentialsCreated({ user, ...rest }: Event['credentials-created']) {
|
private credentialsCreated({ user, ...rest }: RelayEventMap['credentials-created']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.credentials.created',
|
eventName: 'n8n.audit.user.credentials.created',
|
||||||
payload: { ...user, ...rest },
|
payload: { ...user, ...rest },
|
||||||
|
@ -324,7 +312,7 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private credentialsDeleted({ user, ...rest }: Event['credentials-deleted']) {
|
private credentialsDeleted({ user, ...rest }: RelayEventMap['credentials-deleted']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.credentials.deleted',
|
eventName: 'n8n.audit.user.credentials.deleted',
|
||||||
payload: { ...user, ...rest },
|
payload: { ...user, ...rest },
|
||||||
|
@ -332,7 +320,7 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private credentialsShared({ user, ...rest }: Event['credentials-shared']) {
|
private credentialsShared({ user, ...rest }: RelayEventMap['credentials-shared']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.credentials.shared',
|
eventName: 'n8n.audit.user.credentials.shared',
|
||||||
payload: { ...user, ...rest },
|
payload: { ...user, ...rest },
|
||||||
|
@ -340,19 +328,22 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private credentialsUpdated({ user, ...rest }: Event['credentials-updated']) {
|
private credentialsUpdated({ user, ...rest }: RelayEventMap['credentials-updated']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.user.credentials.updated',
|
eventName: 'n8n.audit.user.credentials.updated',
|
||||||
payload: { ...user, ...rest },
|
payload: { ...user, ...rest },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// #endregion
|
||||||
* Community package
|
|
||||||
*/
|
// #region Community package
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private communityPackageInstalled({ user, ...rest }: Event['community-package-installed']) {
|
private communityPackageInstalled({
|
||||||
|
user,
|
||||||
|
...rest
|
||||||
|
}: RelayEventMap['community-package-installed']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.package.installed',
|
eventName: 'n8n.audit.package.installed',
|
||||||
payload: { ...user, ...rest },
|
payload: { ...user, ...rest },
|
||||||
|
@ -360,7 +351,7 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private communityPackageUpdated({ user, ...rest }: Event['community-package-updated']) {
|
private communityPackageUpdated({ user, ...rest }: RelayEventMap['community-package-updated']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.package.updated',
|
eventName: 'n8n.audit.package.updated',
|
||||||
payload: { ...user, ...rest },
|
payload: { ...user, ...rest },
|
||||||
|
@ -368,28 +359,32 @@ export class AuditEventRelay {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redactable()
|
@Redactable()
|
||||||
private communityPackageDeleted({ user, ...rest }: Event['community-package-deleted']) {
|
private communityPackageDeleted({ user, ...rest }: RelayEventMap['community-package-deleted']) {
|
||||||
void this.eventBus.sendAuditEvent({
|
void this.eventBus.sendAuditEvent({
|
||||||
eventName: 'n8n.audit.package.deleted',
|
eventName: 'n8n.audit.package.deleted',
|
||||||
payload: { ...user, ...rest },
|
payload: { ...user, ...rest },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// #endregion
|
||||||
* Execution
|
|
||||||
*/
|
|
||||||
|
|
||||||
private executionThrottled({ executionId }: Event['execution-throttled']) {
|
// #region Execution
|
||||||
|
|
||||||
|
private executionThrottled({ executionId }: RelayEventMap['execution-throttled']) {
|
||||||
void this.eventBus.sendExecutionEvent({
|
void this.eventBus.sendExecutionEvent({
|
||||||
eventName: 'n8n.execution.throttled',
|
eventName: 'n8n.execution.throttled',
|
||||||
payload: { executionId },
|
payload: { executionId },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private executionStartedDuringBootup({ executionId }: Event['execution-started-during-bootup']) {
|
private executionStartedDuringBootup({
|
||||||
|
executionId,
|
||||||
|
}: RelayEventMap['execution-started-during-bootup']) {
|
||||||
void this.eventBus.sendExecutionEvent({
|
void this.eventBus.sendExecutionEvent({
|
||||||
eventName: 'n8n.execution.started-during-bootup',
|
eventName: 'n8n.execution.started-during-bootup',
|
||||||
payload: { executionId },
|
payload: { executionId },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
}
|
}
|
|
@ -11,12 +11,15 @@ export type UserLike = {
|
||||||
role: string;
|
role: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
export type RelayEventMap = {
|
||||||
* Events sent by `EventService` and forwarded by relays, e.g. `AuditEventRelay` and `TelemetryEventRelay`.
|
// #region Server
|
||||||
*/
|
|
||||||
export type Event = {
|
|
||||||
'server-started': {};
|
'server-started': {};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Workflow
|
||||||
|
|
||||||
'workflow-created': {
|
'workflow-created': {
|
||||||
user: UserLike;
|
user: UserLike;
|
||||||
workflow: IWorkflowBase;
|
workflow: IWorkflowBase;
|
||||||
|
@ -49,6 +52,10 @@ export type Event = {
|
||||||
runData?: IRun;
|
runData?: IRun;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Node
|
||||||
|
|
||||||
'node-pre-execute': {
|
'node-pre-execute': {
|
||||||
executionId: string;
|
executionId: string;
|
||||||
workflow: IWorkflowBase;
|
workflow: IWorkflowBase;
|
||||||
|
@ -61,6 +68,10 @@ export type Event = {
|
||||||
nodeName: string;
|
nodeName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region User
|
||||||
|
|
||||||
'user-deleted': {
|
'user-deleted': {
|
||||||
user: UserLike;
|
user: UserLike;
|
||||||
};
|
};
|
||||||
|
@ -95,6 +106,10 @@ export type Event = {
|
||||||
reason?: string;
|
reason?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Click
|
||||||
|
|
||||||
'user-invite-email-click': {
|
'user-invite-email-click': {
|
||||||
inviter: UserLike;
|
inviter: UserLike;
|
||||||
invitee: UserLike;
|
invitee: UserLike;
|
||||||
|
@ -108,6 +123,20 @@ export type Event = {
|
||||||
user: UserLike;
|
user: UserLike;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Public API
|
||||||
|
|
||||||
|
'public-api-key-created': {
|
||||||
|
user: UserLike;
|
||||||
|
publicApi: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
'public-api-key-deleted': {
|
||||||
|
user: UserLike;
|
||||||
|
publicApi: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
'public-api-invoked': {
|
'public-api-invoked': {
|
||||||
userId: string;
|
userId: string;
|
||||||
path: string;
|
path: string;
|
||||||
|
@ -115,6 +144,10 @@ export type Event = {
|
||||||
apiVersion: string;
|
apiVersion: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Email
|
||||||
|
|
||||||
'email-failed': {
|
'email-failed': {
|
||||||
user: UserLike;
|
user: UserLike;
|
||||||
messageType:
|
messageType:
|
||||||
|
@ -125,6 +158,10 @@ export type Event = {
|
||||||
| 'Credentials shared';
|
| 'Credentials shared';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Credentials
|
||||||
|
|
||||||
'credentials-created': {
|
'credentials-created': {
|
||||||
user: UserLike;
|
user: UserLike;
|
||||||
credentialType: string;
|
credentialType: string;
|
||||||
|
@ -155,6 +192,10 @@ export type Event = {
|
||||||
credentialId: string;
|
credentialId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Community package
|
||||||
|
|
||||||
'community-package-installed': {
|
'community-package-installed': {
|
||||||
user: UserLike;
|
user: UserLike;
|
||||||
inputString: string;
|
inputString: string;
|
||||||
|
@ -186,6 +227,10 @@ export type Event = {
|
||||||
packageAuthorEmail?: string;
|
packageAuthorEmail?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Execution
|
||||||
|
|
||||||
'execution-throttled': {
|
'execution-throttled': {
|
||||||
executionId: string;
|
executionId: string;
|
||||||
};
|
};
|
||||||
|
@ -194,6 +239,10 @@ export type Event = {
|
||||||
executionId: string;
|
executionId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Project
|
||||||
|
|
||||||
'team-project-updated': {
|
'team-project-updated': {
|
||||||
userId: string;
|
userId: string;
|
||||||
role: GlobalRole;
|
role: GlobalRole;
|
||||||
|
@ -217,6 +266,10 @@ export type Event = {
|
||||||
role: GlobalRole;
|
role: GlobalRole;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Source control
|
||||||
|
|
||||||
'source-control-settings-updated': {
|
'source-control-settings-updated': {
|
||||||
branchName: string;
|
branchName: string;
|
||||||
readOnlyInstance: boolean;
|
readOnlyInstance: boolean;
|
||||||
|
@ -254,12 +307,24 @@ export type Event = {
|
||||||
variablesPushed: number;
|
variablesPushed: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region License
|
||||||
|
|
||||||
'license-renewal-attempted': {
|
'license-renewal-attempted': {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Variable
|
||||||
|
|
||||||
'variable-created': {};
|
'variable-created': {};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region External secrets
|
||||||
|
|
||||||
'external-secrets-provider-settings-saved': {
|
'external-secrets-provider-settings-saved': {
|
||||||
userId?: string;
|
userId?: string;
|
||||||
vaultType: string;
|
vaultType: string;
|
||||||
|
@ -268,6 +333,10 @@ export type Event = {
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region LDAP
|
||||||
|
|
||||||
'ldap-general-sync-finished': {
|
'ldap-general-sync-finished': {
|
||||||
type: string;
|
type: string;
|
||||||
succeeded: boolean;
|
succeeded: boolean;
|
||||||
|
@ -298,17 +367,5 @@ export type Event = {
|
||||||
userId: string;
|
userId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// #endregion
|
||||||
* Events listened to by more than one relay
|
|
||||||
*/
|
|
||||||
|
|
||||||
'public-api-key-created': {
|
|
||||||
user: UserLike; // audit and telemetry
|
|
||||||
publicApi: boolean; // telemetry only
|
|
||||||
};
|
|
||||||
|
|
||||||
'public-api-key-deleted': {
|
|
||||||
user: UserLike; // audit and telemetry
|
|
||||||
publicApi: boolean; // telemetry only
|
|
||||||
};
|
|
||||||
};
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
import { Service } from 'typedi';
|
import { Service } from 'typedi';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
import type { Event } from '@/eventbus/event.types';
|
import type { RelayEventMap } from '@/events/relay-event-map';
|
||||||
import { Telemetry } from '.';
|
import { Telemetry } from '../telemetry';
|
||||||
import config from '@/config';
|
import config from '@/config';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import { License } from '@/License';
|
import { License } from '@/License';
|
||||||
|
@ -16,11 +16,12 @@ import { SharedWorkflowRepository } from '@/databases/repositories/sharedWorkflo
|
||||||
import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository';
|
import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository';
|
||||||
import type { IExecutionTrackProperties } from '@/Interfaces';
|
import type { IExecutionTrackProperties } from '@/Interfaces';
|
||||||
import { determineFinalExecutionStatus } from '@/executionLifecycleHooks/shared/sharedHookFunctions';
|
import { determineFinalExecutionStatus } from '@/executionLifecycleHooks/shared/sharedHookFunctions';
|
||||||
|
import { EventRelay } from './event-relay';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class TelemetryEventRelay {
|
export class TelemetryEventRelay extends EventRelay {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly eventService: EventService,
|
readonly eventService: EventService,
|
||||||
private readonly telemetry: Telemetry,
|
private readonly telemetry: Telemetry,
|
||||||
private readonly license: License,
|
private readonly license: License,
|
||||||
private readonly globalConfig: GlobalConfig,
|
private readonly globalConfig: GlobalConfig,
|
||||||
|
@ -28,106 +29,63 @@ export class TelemetryEventRelay {
|
||||||
private readonly nodeTypes: NodeTypes,
|
private readonly nodeTypes: NodeTypes,
|
||||||
private readonly sharedWorkflowRepository: SharedWorkflowRepository,
|
private readonly sharedWorkflowRepository: SharedWorkflowRepository,
|
||||||
private readonly projectRelationRepository: ProjectRelationRepository,
|
private readonly projectRelationRepository: ProjectRelationRepository,
|
||||||
) {}
|
) {
|
||||||
|
super(eventService);
|
||||||
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
if (!config.getEnv('diagnostics.enabled')) return;
|
if (!config.getEnv('diagnostics.enabled')) return;
|
||||||
|
|
||||||
await this.telemetry.init();
|
await this.telemetry.init();
|
||||||
|
|
||||||
this.setupHandlers();
|
this.setupListeners({
|
||||||
}
|
'team-project-updated': (event) => this.teamProjectUpdated(event),
|
||||||
|
'team-project-deleted': (event) => this.teamProjectDeleted(event),
|
||||||
private setupHandlers() {
|
'team-project-created': (event) => this.teamProjectCreated(event),
|
||||||
this.eventService.on('server-started', async () => await this.serverStarted());
|
'source-control-settings-updated': (event) => this.sourceControlSettingsUpdated(event),
|
||||||
|
'source-control-user-started-pull-ui': (event) => this.sourceControlUserStartedPullUi(event),
|
||||||
this.eventService.on('team-project-updated', (event) => this.teamProjectUpdated(event));
|
'source-control-user-finished-pull-ui': (event) =>
|
||||||
this.eventService.on('team-project-deleted', (event) => this.teamProjectDeleted(event));
|
this.sourceControlUserFinishedPullUi(event),
|
||||||
this.eventService.on('team-project-created', (event) => this.teamProjectCreated(event));
|
'source-control-user-pulled-api': (event) => this.sourceControlUserPulledApi(event),
|
||||||
this.eventService.on('source-control-settings-updated', (event) =>
|
'source-control-user-started-push-ui': (event) => this.sourceControlUserStartedPushUi(event),
|
||||||
this.sourceControlSettingsUpdated(event),
|
'source-control-user-finished-push-ui': (event) =>
|
||||||
);
|
this.sourceControlUserFinishedPushUi(event),
|
||||||
this.eventService.on('source-control-user-started-pull-ui', (event) =>
|
'license-renewal-attempted': (event) => this.licenseRenewalAttempted(event),
|
||||||
this.sourceControlUserStartedPullUi(event),
|
'variable-created': () => this.variableCreated(),
|
||||||
);
|
'external-secrets-provider-settings-saved': (event) =>
|
||||||
this.eventService.on('source-control-user-finished-pull-ui', (event) =>
|
this.externalSecretsProviderSettingsSaved(event),
|
||||||
this.sourceControlUserFinishedPullUi(event),
|
'public-api-invoked': (event) => this.publicApiInvoked(event),
|
||||||
);
|
'public-api-key-created': (event) => this.publicApiKeyCreated(event),
|
||||||
this.eventService.on('source-control-user-pulled-api', (event) =>
|
'public-api-key-deleted': (event) => this.publicApiKeyDeleted(event),
|
||||||
this.sourceControlUserPulledApi(event),
|
'community-package-installed': (event) => this.communityPackageInstalled(event),
|
||||||
);
|
'community-package-updated': (event) => this.communityPackageUpdated(event),
|
||||||
this.eventService.on('source-control-user-started-push-ui', (event) =>
|
'community-package-deleted': (event) => this.communityPackageDeleted(event),
|
||||||
this.sourceControlUserStartedPushUi(event),
|
'credentials-created': (event) => this.credentialsCreated(event),
|
||||||
);
|
'credentials-shared': (event) => this.credentialsShared(event),
|
||||||
this.eventService.on('source-control-user-finished-push-ui', (event) =>
|
'credentials-updated': (event) => this.credentialsUpdated(event),
|
||||||
this.sourceControlUserFinishedPushUi(event),
|
'credentials-deleted': (event) => this.credentialsDeleted(event),
|
||||||
);
|
'ldap-general-sync-finished': (event) => this.ldapGeneralSyncFinished(event),
|
||||||
this.eventService.on('license-renewal-attempted', (event) => {
|
'ldap-settings-updated': (event) => this.ldapSettingsUpdated(event),
|
||||||
this.licenseRenewalAttempted(event);
|
'ldap-login-sync-failed': (event) => this.ldapLoginSyncFailed(event),
|
||||||
});
|
'login-failed-due-to-ldap-disabled': (event) => this.loginFailedDueToLdapDisabled(event),
|
||||||
this.eventService.on('variable-created', () => this.variableCreated());
|
'workflow-created': (event) => this.workflowCreated(event),
|
||||||
this.eventService.on('external-secrets-provider-settings-saved', (event) => {
|
'workflow-deleted': (event) => this.workflowDeleted(event),
|
||||||
this.externalSecretsProviderSettingsSaved(event);
|
'workflow-saved': async (event) => await this.workflowSaved(event),
|
||||||
});
|
'server-started': async () => await this.serverStarted(),
|
||||||
this.eventService.on('public-api-invoked', (event) => {
|
'workflow-post-execute': async (event) => await this.workflowPostExecute(event),
|
||||||
this.publicApiInvoked(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('public-api-key-created', (event) => {
|
|
||||||
this.publicApiKeyCreated(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('public-api-key-deleted', (event) => {
|
|
||||||
this.publicApiKeyDeleted(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('community-package-installed', (event) => {
|
|
||||||
this.communityPackageInstalled(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('community-package-updated', (event) => {
|
|
||||||
this.communityPackageUpdated(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('community-package-deleted', (event) => {
|
|
||||||
this.communityPackageDeleted(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.eventService.on('credentials-created', (event) => {
|
|
||||||
this.credentialsCreated(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('ldap-general-sync-finished', (event) => {
|
|
||||||
this.ldapGeneralSyncFinished(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('ldap-settings-updated', (event) => {
|
|
||||||
this.ldapSettingsUpdated(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('ldap-login-sync-failed', (event) => {
|
|
||||||
this.ldapLoginSyncFailed(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('login-failed-due-to-ldap-disabled', (event) => {
|
|
||||||
this.loginFailedDueToLdapDisabled(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.eventService.on('workflow-created', (event) => {
|
|
||||||
this.workflowCreated(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('workflow-deleted', (event) => {
|
|
||||||
this.workflowDeleted(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('workflow-saved', async (event) => {
|
|
||||||
await this.workflowSaved(event);
|
|
||||||
});
|
|
||||||
this.eventService.on('workflow-post-execute', async (event) => {
|
|
||||||
await this.workflowPostExecute(event);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private teamProjectUpdated({ userId, role, members, projectId }: Event['team-project-updated']) {
|
// #endregion
|
||||||
|
|
||||||
|
// #region Team
|
||||||
|
|
||||||
|
private teamProjectUpdated({
|
||||||
|
userId,
|
||||||
|
role,
|
||||||
|
members,
|
||||||
|
projectId,
|
||||||
|
}: RelayEventMap['team-project-updated']) {
|
||||||
this.telemetry.track('Project settings updated', {
|
this.telemetry.track('Project settings updated', {
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
role,
|
role,
|
||||||
|
@ -143,7 +101,7 @@ export class TelemetryEventRelay {
|
||||||
projectId,
|
projectId,
|
||||||
removalType,
|
removalType,
|
||||||
targetProjectId,
|
targetProjectId,
|
||||||
}: Event['team-project-deleted']) {
|
}: RelayEventMap['team-project-deleted']) {
|
||||||
this.telemetry.track('User deleted project', {
|
this.telemetry.track('User deleted project', {
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
role,
|
role,
|
||||||
|
@ -153,19 +111,23 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private teamProjectCreated({ userId, role }: Event['team-project-created']) {
|
private teamProjectCreated({ userId, role }: RelayEventMap['team-project-created']) {
|
||||||
this.telemetry.track('User created project', {
|
this.telemetry.track('User created project', {
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
role,
|
role,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Source control
|
||||||
|
|
||||||
private sourceControlSettingsUpdated({
|
private sourceControlSettingsUpdated({
|
||||||
branchName,
|
branchName,
|
||||||
readOnlyInstance,
|
readOnlyInstance,
|
||||||
repoType,
|
repoType,
|
||||||
connected,
|
connected,
|
||||||
}: Event['source-control-settings-updated']) {
|
}: RelayEventMap['source-control-settings-updated']) {
|
||||||
this.telemetry.track('User updated source control settings', {
|
this.telemetry.track('User updated source control settings', {
|
||||||
branch_name: branchName,
|
branch_name: branchName,
|
||||||
read_only_instance: readOnlyInstance,
|
read_only_instance: readOnlyInstance,
|
||||||
|
@ -178,7 +140,7 @@ export class TelemetryEventRelay {
|
||||||
workflowUpdates,
|
workflowUpdates,
|
||||||
workflowConflicts,
|
workflowConflicts,
|
||||||
credConflicts,
|
credConflicts,
|
||||||
}: Event['source-control-user-started-pull-ui']) {
|
}: RelayEventMap['source-control-user-started-pull-ui']) {
|
||||||
this.telemetry.track('User started pull via UI', {
|
this.telemetry.track('User started pull via UI', {
|
||||||
workflow_updates: workflowUpdates,
|
workflow_updates: workflowUpdates,
|
||||||
workflow_conflicts: workflowConflicts,
|
workflow_conflicts: workflowConflicts,
|
||||||
|
@ -188,7 +150,7 @@ export class TelemetryEventRelay {
|
||||||
|
|
||||||
private sourceControlUserFinishedPullUi({
|
private sourceControlUserFinishedPullUi({
|
||||||
workflowUpdates,
|
workflowUpdates,
|
||||||
}: Event['source-control-user-finished-pull-ui']) {
|
}: RelayEventMap['source-control-user-finished-pull-ui']) {
|
||||||
this.telemetry.track('User finished pull via UI', {
|
this.telemetry.track('User finished pull via UI', {
|
||||||
workflow_updates: workflowUpdates,
|
workflow_updates: workflowUpdates,
|
||||||
});
|
});
|
||||||
|
@ -197,7 +159,7 @@ export class TelemetryEventRelay {
|
||||||
private sourceControlUserPulledApi({
|
private sourceControlUserPulledApi({
|
||||||
workflowUpdates,
|
workflowUpdates,
|
||||||
forced,
|
forced,
|
||||||
}: Event['source-control-user-pulled-api']) {
|
}: RelayEventMap['source-control-user-pulled-api']) {
|
||||||
console.log('source-control-user-pulled-api', {
|
console.log('source-control-user-pulled-api', {
|
||||||
workflow_updates: workflowUpdates,
|
workflow_updates: workflowUpdates,
|
||||||
forced,
|
forced,
|
||||||
|
@ -214,7 +176,7 @@ export class TelemetryEventRelay {
|
||||||
credsEligible,
|
credsEligible,
|
||||||
credsEligibleWithConflicts,
|
credsEligibleWithConflicts,
|
||||||
variablesEligible,
|
variablesEligible,
|
||||||
}: Event['source-control-user-started-push-ui']) {
|
}: RelayEventMap['source-control-user-started-push-ui']) {
|
||||||
this.telemetry.track('User started push via UI', {
|
this.telemetry.track('User started push via UI', {
|
||||||
workflows_eligible: workflowsEligible,
|
workflows_eligible: workflowsEligible,
|
||||||
workflows_eligible_with_conflicts: workflowsEligibleWithConflicts,
|
workflows_eligible_with_conflicts: workflowsEligibleWithConflicts,
|
||||||
|
@ -229,7 +191,7 @@ export class TelemetryEventRelay {
|
||||||
workflowsPushed,
|
workflowsPushed,
|
||||||
credsPushed,
|
credsPushed,
|
||||||
variablesPushed,
|
variablesPushed,
|
||||||
}: Event['source-control-user-finished-push-ui']) {
|
}: RelayEventMap['source-control-user-finished-push-ui']) {
|
||||||
this.telemetry.track('User finished push via UI', {
|
this.telemetry.track('User finished push via UI', {
|
||||||
workflows_eligible: workflowsEligible,
|
workflows_eligible: workflowsEligible,
|
||||||
workflows_pushed: workflowsPushed,
|
workflows_pushed: workflowsPushed,
|
||||||
|
@ -238,23 +200,35 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private licenseRenewalAttempted({ success }: Event['license-renewal-attempted']) {
|
// #endregion
|
||||||
|
|
||||||
|
// #region License
|
||||||
|
|
||||||
|
private licenseRenewalAttempted({ success }: RelayEventMap['license-renewal-attempted']) {
|
||||||
this.telemetry.track('Instance attempted to refresh license', {
|
this.telemetry.track('Instance attempted to refresh license', {
|
||||||
success,
|
success,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Variable
|
||||||
|
|
||||||
private variableCreated() {
|
private variableCreated() {
|
||||||
this.telemetry.track('User created variable');
|
this.telemetry.track('User created variable');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region External secrets
|
||||||
|
|
||||||
private externalSecretsProviderSettingsSaved({
|
private externalSecretsProviderSettingsSaved({
|
||||||
userId,
|
userId,
|
||||||
vaultType,
|
vaultType,
|
||||||
isValid,
|
isValid,
|
||||||
isNew,
|
isNew,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
}: Event['external-secrets-provider-settings-saved']) {
|
}: RelayEventMap['external-secrets-provider-settings-saved']) {
|
||||||
this.telemetry.track('User updated external secrets settings', {
|
this.telemetry.track('User updated external secrets settings', {
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
vault_type: vaultType,
|
vault_type: vaultType,
|
||||||
|
@ -264,7 +238,16 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private publicApiInvoked({ userId, path, method, apiVersion }: Event['public-api-invoked']) {
|
// #endregion
|
||||||
|
|
||||||
|
// #region Public API
|
||||||
|
|
||||||
|
private publicApiInvoked({
|
||||||
|
userId,
|
||||||
|
path,
|
||||||
|
method,
|
||||||
|
apiVersion,
|
||||||
|
}: RelayEventMap['public-api-invoked']) {
|
||||||
this.telemetry.track('User invoked API', {
|
this.telemetry.track('User invoked API', {
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
path,
|
path,
|
||||||
|
@ -273,7 +256,7 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private publicApiKeyCreated(event: Event['public-api-key-created']) {
|
private publicApiKeyCreated(event: RelayEventMap['public-api-key-created']) {
|
||||||
const { user, publicApi } = event;
|
const { user, publicApi } = event;
|
||||||
|
|
||||||
this.telemetry.track('API key created', {
|
this.telemetry.track('API key created', {
|
||||||
|
@ -282,7 +265,7 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private publicApiKeyDeleted(event: Event['public-api-key-deleted']) {
|
private publicApiKeyDeleted(event: RelayEventMap['public-api-key-deleted']) {
|
||||||
const { user, publicApi } = event;
|
const { user, publicApi } = event;
|
||||||
|
|
||||||
this.telemetry.track('API key deleted', {
|
this.telemetry.track('API key deleted', {
|
||||||
|
@ -291,6 +274,10 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Community package
|
||||||
|
|
||||||
private communityPackageInstalled({
|
private communityPackageInstalled({
|
||||||
user,
|
user,
|
||||||
inputString,
|
inputString,
|
||||||
|
@ -301,7 +288,7 @@ export class TelemetryEventRelay {
|
||||||
packageAuthor,
|
packageAuthor,
|
||||||
packageAuthorEmail,
|
packageAuthorEmail,
|
||||||
failureReason,
|
failureReason,
|
||||||
}: Event['community-package-installed']) {
|
}: RelayEventMap['community-package-installed']) {
|
||||||
this.telemetry.track('cnr package install finished', {
|
this.telemetry.track('cnr package install finished', {
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
input_string: inputString,
|
input_string: inputString,
|
||||||
|
@ -323,7 +310,7 @@ export class TelemetryEventRelay {
|
||||||
packageNodeNames,
|
packageNodeNames,
|
||||||
packageAuthor,
|
packageAuthor,
|
||||||
packageAuthorEmail,
|
packageAuthorEmail,
|
||||||
}: Event['community-package-updated']) {
|
}: RelayEventMap['community-package-updated']) {
|
||||||
this.telemetry.track('cnr package updated', {
|
this.telemetry.track('cnr package updated', {
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
package_name: packageName,
|
package_name: packageName,
|
||||||
|
@ -342,7 +329,7 @@ export class TelemetryEventRelay {
|
||||||
packageNodeNames,
|
packageNodeNames,
|
||||||
packageAuthor,
|
packageAuthor,
|
||||||
packageAuthorEmail,
|
packageAuthorEmail,
|
||||||
}: Event['community-package-deleted']) {
|
}: RelayEventMap['community-package-deleted']) {
|
||||||
this.telemetry.track('cnr package deleted', {
|
this.telemetry.track('cnr package deleted', {
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
package_name: packageName,
|
package_name: packageName,
|
||||||
|
@ -353,13 +340,17 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Credentials
|
||||||
|
|
||||||
private credentialsCreated({
|
private credentialsCreated({
|
||||||
user,
|
user,
|
||||||
credentialType,
|
credentialType,
|
||||||
credentialId,
|
credentialId,
|
||||||
projectId,
|
projectId,
|
||||||
projectType,
|
projectType,
|
||||||
}: Event['credentials-created']) {
|
}: RelayEventMap['credentials-created']) {
|
||||||
this.telemetry.track('User created credentials', {
|
this.telemetry.track('User created credentials', {
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
credential_type: credentialType,
|
credential_type: credentialType,
|
||||||
|
@ -376,7 +367,7 @@ export class TelemetryEventRelay {
|
||||||
userIdSharer,
|
userIdSharer,
|
||||||
userIdsShareesAdded,
|
userIdsShareesAdded,
|
||||||
shareesRemoved,
|
shareesRemoved,
|
||||||
}: Event['credentials-shared']) {
|
}: RelayEventMap['credentials-shared']) {
|
||||||
this.telemetry.track('User updated cred sharing', {
|
this.telemetry.track('User updated cred sharing', {
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
credential_type: credentialType,
|
credential_type: credentialType,
|
||||||
|
@ -387,7 +378,11 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private credentialsUpdated({ user, credentialId, credentialType }: Event['credentials-updated']) {
|
private credentialsUpdated({
|
||||||
|
user,
|
||||||
|
credentialId,
|
||||||
|
credentialType,
|
||||||
|
}: RelayEventMap['credentials-updated']) {
|
||||||
this.telemetry.track('User updated credentials', {
|
this.telemetry.track('User updated credentials', {
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
credential_type: credentialType,
|
credential_type: credentialType,
|
||||||
|
@ -395,7 +390,11 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private credentialsDeleted({ user, credentialId, credentialType }: Event['credentials-deleted']) {
|
private credentialsDeleted({
|
||||||
|
user,
|
||||||
|
credentialId,
|
||||||
|
credentialType,
|
||||||
|
}: RelayEventMap['credentials-deleted']) {
|
||||||
this.telemetry.track('User deleted credentials', {
|
this.telemetry.track('User deleted credentials', {
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
credential_type: credentialType,
|
credential_type: credentialType,
|
||||||
|
@ -403,12 +402,16 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region LDAP
|
||||||
|
|
||||||
private ldapGeneralSyncFinished({
|
private ldapGeneralSyncFinished({
|
||||||
type,
|
type,
|
||||||
succeeded,
|
succeeded,
|
||||||
usersSynced,
|
usersSynced,
|
||||||
error,
|
error,
|
||||||
}: Event['ldap-general-sync-finished']) {
|
}: RelayEventMap['ldap-general-sync-finished']) {
|
||||||
this.telemetry.track('Ldap general sync finished', {
|
this.telemetry.track('Ldap general sync finished', {
|
||||||
type,
|
type,
|
||||||
succeeded,
|
succeeded,
|
||||||
|
@ -430,7 +433,7 @@ export class TelemetryEventRelay {
|
||||||
synchronizationInterval,
|
synchronizationInterval,
|
||||||
loginLabel,
|
loginLabel,
|
||||||
loginEnabled,
|
loginEnabled,
|
||||||
}: Event['ldap-settings-updated']) {
|
}: RelayEventMap['ldap-settings-updated']) {
|
||||||
this.telemetry.track('User updated Ldap settings', {
|
this.telemetry.track('User updated Ldap settings', {
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
loginIdAttribute,
|
loginIdAttribute,
|
||||||
|
@ -447,21 +450,27 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private ldapLoginSyncFailed({ error }: Event['ldap-login-sync-failed']) {
|
private ldapLoginSyncFailed({ error }: RelayEventMap['ldap-login-sync-failed']) {
|
||||||
this.telemetry.track('Ldap login sync failed', { error });
|
this.telemetry.track('Ldap login sync failed', { error });
|
||||||
}
|
}
|
||||||
|
|
||||||
private loginFailedDueToLdapDisabled({ userId }: Event['login-failed-due-to-ldap-disabled']) {
|
private loginFailedDueToLdapDisabled({
|
||||||
|
userId,
|
||||||
|
}: RelayEventMap['login-failed-due-to-ldap-disabled']) {
|
||||||
this.telemetry.track('User login failed since ldap disabled', { user_ud: userId });
|
this.telemetry.track('User login failed since ldap disabled', { user_ud: userId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Workflow
|
||||||
|
|
||||||
private workflowCreated({
|
private workflowCreated({
|
||||||
user,
|
user,
|
||||||
workflow,
|
workflow,
|
||||||
publicApi,
|
publicApi,
|
||||||
projectId,
|
projectId,
|
||||||
projectType,
|
projectType,
|
||||||
}: Event['workflow-created']) {
|
}: RelayEventMap['workflow-created']) {
|
||||||
const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes);
|
const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes);
|
||||||
|
|
||||||
this.telemetry.track('User created workflow', {
|
this.telemetry.track('User created workflow', {
|
||||||
|
@ -474,7 +483,7 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private workflowDeleted({ user, workflowId, publicApi }: Event['workflow-deleted']) {
|
private workflowDeleted({ user, workflowId, publicApi }: RelayEventMap['workflow-deleted']) {
|
||||||
this.telemetry.track('User deleted workflow', {
|
this.telemetry.track('User deleted workflow', {
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
workflow_id: workflowId,
|
workflow_id: workflowId,
|
||||||
|
@ -482,7 +491,7 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async workflowSaved({ user, workflow, publicApi }: Event['workflow-saved']) {
|
private async workflowSaved({ user, workflow, publicApi }: RelayEventMap['workflow-saved']) {
|
||||||
const isCloudDeployment = config.getEnv('deployment.type') === 'cloud';
|
const isCloudDeployment = config.getEnv('deployment.type') === 'cloud';
|
||||||
|
|
||||||
const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes, {
|
const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes, {
|
||||||
|
@ -528,72 +537,12 @@ export class TelemetryEventRelay {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async serverStarted() {
|
|
||||||
const cpus = os.cpus();
|
|
||||||
const binaryDataConfig = config.getEnv('binaryDataManager');
|
|
||||||
|
|
||||||
const isS3Selected = config.getEnv('binaryDataManager.mode') === 's3';
|
|
||||||
const isS3Available = config.getEnv('binaryDataManager.availableModes').includes('s3');
|
|
||||||
const isS3Licensed = this.license.isBinaryDataS3Licensed();
|
|
||||||
const authenticationMethod = config.getEnv('userManagement.authenticationMethod');
|
|
||||||
|
|
||||||
const info = {
|
|
||||||
version_cli: N8N_VERSION,
|
|
||||||
db_type: this.globalConfig.database.type,
|
|
||||||
n8n_version_notifications_enabled: this.globalConfig.versionNotifications.enabled,
|
|
||||||
n8n_disable_production_main_process:
|
|
||||||
this.globalConfig.endpoints.disableProductionWebhooksOnMainProcess,
|
|
||||||
system_info: {
|
|
||||||
os: {
|
|
||||||
type: os.type(),
|
|
||||||
version: os.version(),
|
|
||||||
},
|
|
||||||
memory: os.totalmem() / 1024,
|
|
||||||
cpus: {
|
|
||||||
count: cpus.length,
|
|
||||||
model: cpus[0].model,
|
|
||||||
speed: cpus[0].speed,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
execution_variables: {
|
|
||||||
executions_mode: config.getEnv('executions.mode'),
|
|
||||||
executions_timeout: config.getEnv('executions.timeout'),
|
|
||||||
executions_timeout_max: config.getEnv('executions.maxTimeout'),
|
|
||||||
executions_data_save_on_error: config.getEnv('executions.saveDataOnError'),
|
|
||||||
executions_data_save_on_success: config.getEnv('executions.saveDataOnSuccess'),
|
|
||||||
executions_data_save_on_progress: config.getEnv('executions.saveExecutionProgress'),
|
|
||||||
executions_data_save_manual_executions: config.getEnv(
|
|
||||||
'executions.saveDataManualExecutions',
|
|
||||||
),
|
|
||||||
executions_data_prune: config.getEnv('executions.pruneData'),
|
|
||||||
executions_data_max_age: config.getEnv('executions.pruneDataMaxAge'),
|
|
||||||
},
|
|
||||||
n8n_deployment_type: config.getEnv('deployment.type'),
|
|
||||||
n8n_binary_data_mode: binaryDataConfig.mode,
|
|
||||||
smtp_set_up: this.globalConfig.userManagement.emails.mode === 'smtp',
|
|
||||||
ldap_allowed: authenticationMethod === 'ldap',
|
|
||||||
saml_enabled: authenticationMethod === 'saml',
|
|
||||||
license_plan_name: this.license.getPlanName(),
|
|
||||||
license_tenant_id: config.getEnv('license.tenantId'),
|
|
||||||
binary_data_s3: isS3Available && isS3Selected && isS3Licensed,
|
|
||||||
multi_main_setup_enabled: config.getEnv('multiMainSetup.enabled'),
|
|
||||||
};
|
|
||||||
|
|
||||||
const firstWorkflow = await this.workflowRepository.findOne({
|
|
||||||
select: ['createdAt'],
|
|
||||||
order: { createdAt: 'ASC' },
|
|
||||||
where: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
this.telemetry.identify(info);
|
|
||||||
this.telemetry.track('Instance started', {
|
|
||||||
...info,
|
|
||||||
earliest_workflow_created: firstWorkflow?.createdAt,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line complexity
|
// eslint-disable-next-line complexity
|
||||||
private async workflowPostExecute({ workflow, runData, userId }: Event['workflow-post-execute']) {
|
private async workflowPostExecute({
|
||||||
|
workflow,
|
||||||
|
runData,
|
||||||
|
userId,
|
||||||
|
}: RelayEventMap['workflow-post-execute']) {
|
||||||
if (!workflow.id) {
|
if (!workflow.id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -725,4 +674,74 @@ export class TelemetryEventRelay {
|
||||||
|
|
||||||
this.telemetry.trackWorkflowExecution(telemetryProperties);
|
this.telemetry.trackWorkflowExecution(telemetryProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Server
|
||||||
|
|
||||||
|
private async serverStarted() {
|
||||||
|
const cpus = os.cpus();
|
||||||
|
const binaryDataConfig = config.getEnv('binaryDataManager');
|
||||||
|
|
||||||
|
const isS3Selected = config.getEnv('binaryDataManager.mode') === 's3';
|
||||||
|
const isS3Available = config.getEnv('binaryDataManager.availableModes').includes('s3');
|
||||||
|
const isS3Licensed = this.license.isBinaryDataS3Licensed();
|
||||||
|
const authenticationMethod = config.getEnv('userManagement.authenticationMethod');
|
||||||
|
|
||||||
|
const info = {
|
||||||
|
version_cli: N8N_VERSION,
|
||||||
|
db_type: this.globalConfig.database.type,
|
||||||
|
n8n_version_notifications_enabled: this.globalConfig.versionNotifications.enabled,
|
||||||
|
n8n_disable_production_main_process:
|
||||||
|
this.globalConfig.endpoints.disableProductionWebhooksOnMainProcess,
|
||||||
|
system_info: {
|
||||||
|
os: {
|
||||||
|
type: os.type(),
|
||||||
|
version: os.version(),
|
||||||
|
},
|
||||||
|
memory: os.totalmem() / 1024,
|
||||||
|
cpus: {
|
||||||
|
count: cpus.length,
|
||||||
|
model: cpus[0].model,
|
||||||
|
speed: cpus[0].speed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
execution_variables: {
|
||||||
|
executions_mode: config.getEnv('executions.mode'),
|
||||||
|
executions_timeout: config.getEnv('executions.timeout'),
|
||||||
|
executions_timeout_max: config.getEnv('executions.maxTimeout'),
|
||||||
|
executions_data_save_on_error: config.getEnv('executions.saveDataOnError'),
|
||||||
|
executions_data_save_on_success: config.getEnv('executions.saveDataOnSuccess'),
|
||||||
|
executions_data_save_on_progress: config.getEnv('executions.saveExecutionProgress'),
|
||||||
|
executions_data_save_manual_executions: config.getEnv(
|
||||||
|
'executions.saveDataManualExecutions',
|
||||||
|
),
|
||||||
|
executions_data_prune: config.getEnv('executions.pruneData'),
|
||||||
|
executions_data_max_age: config.getEnv('executions.pruneDataMaxAge'),
|
||||||
|
},
|
||||||
|
n8n_deployment_type: config.getEnv('deployment.type'),
|
||||||
|
n8n_binary_data_mode: binaryDataConfig.mode,
|
||||||
|
smtp_set_up: this.globalConfig.userManagement.emails.mode === 'smtp',
|
||||||
|
ldap_allowed: authenticationMethod === 'ldap',
|
||||||
|
saml_enabled: authenticationMethod === 'saml',
|
||||||
|
license_plan_name: this.license.getPlanName(),
|
||||||
|
license_tenant_id: config.getEnv('license.tenantId'),
|
||||||
|
binary_data_s3: isS3Available && isS3Selected && isS3Licensed,
|
||||||
|
multi_main_setup_enabled: config.getEnv('multiMainSetup.enabled'),
|
||||||
|
};
|
||||||
|
|
||||||
|
const firstWorkflow = await this.workflowRepository.findOne({
|
||||||
|
select: ['createdAt'],
|
||||||
|
order: { createdAt: 'ASC' },
|
||||||
|
where: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
this.telemetry.identify(info);
|
||||||
|
this.telemetry.track('Instance started', {
|
||||||
|
...info,
|
||||||
|
earliest_workflow_created: firstWorkflow?.createdAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
}
|
}
|
|
@ -16,7 +16,7 @@ import config from '@/config';
|
||||||
import { OnShutdown } from '@/decorators/OnShutdown';
|
import { OnShutdown } from '@/decorators/OnShutdown';
|
||||||
import type { QueueRecoverySettings } from './execution.types';
|
import type { QueueRecoverySettings } from './execution.types';
|
||||||
import { OrchestrationService } from '@/services/orchestration.service';
|
import { OrchestrationService } from '@/services/orchestration.service';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for recovering key properties in executions.
|
* Service for recovering key properties in executions.
|
||||||
|
|
|
@ -3,7 +3,7 @@ import axios from 'axios';
|
||||||
|
|
||||||
import { Logger } from '@/Logger';
|
import { Logger } from '@/Logger';
|
||||||
import { License } from '@/License';
|
import { License } from '@/License';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
import type { User } from '@db/entities/User';
|
import type { User } from '@db/entities/User';
|
||||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { InternalHooks } from '@/InternalHooks';
|
||||||
import { UrlService } from '@/services/url.service';
|
import { UrlService } from '@/services/url.service';
|
||||||
import type { UserRequest } from '@/requests';
|
import type { UserRequest } from '@/requests';
|
||||||
import { InternalServerError } from '@/errors/response-errors/internal-server.error';
|
import { InternalServerError } from '@/errors/response-errors/internal-server.error';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
|
|
|
@ -27,7 +27,7 @@ import {
|
||||||
import { SamlService } from '../saml.service.ee';
|
import { SamlService } from '../saml.service.ee';
|
||||||
import { SamlConfiguration } from '../types/requests';
|
import { SamlConfiguration } from '../types/requests';
|
||||||
import { getInitSSOFormView } from '../views/initSsoPost';
|
import { getInitSSOFormView } from '../views/initSsoPost';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@RestController('/sso/saml')
|
@RestController('/sso/saml')
|
||||||
export class SamlController {
|
export class SamlController {
|
||||||
|
|
|
@ -33,7 +33,7 @@ import type { EntityManager } from '@n8n/typeorm';
|
||||||
// eslint-disable-next-line n8n-local-rules/misplaced-n8n-typeorm-import
|
// eslint-disable-next-line n8n-local-rules/misplaced-n8n-typeorm-import
|
||||||
import { In } from '@n8n/typeorm';
|
import { In } from '@n8n/typeorm';
|
||||||
import { SharedWorkflow } from '@/databases/entities/SharedWorkflow';
|
import { SharedWorkflow } from '@/databases/entities/SharedWorkflow';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class WorkflowService {
|
export class WorkflowService {
|
||||||
|
|
|
@ -42,7 +42,7 @@ import { In, type FindOptionsRelations } from '@n8n/typeorm';
|
||||||
import type { Project } from '@/databases/entities/Project';
|
import type { Project } from '@/databases/entities/Project';
|
||||||
import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository';
|
import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { EventService } from '@/eventbus/event.service';
|
import { EventService } from '@/events/event.service';
|
||||||
import { GlobalConfig } from '@n8n/config';
|
import { GlobalConfig } from '@n8n/config';
|
||||||
|
|
||||||
@RestController('/workflows')
|
@RestController('/workflows')
|
||||||
|
|
|
@ -21,7 +21,7 @@ import {
|
||||||
TestFailProvider,
|
TestFailProvider,
|
||||||
} from '../../shared/ExternalSecrets/utils';
|
} from '../../shared/ExternalSecrets/utils';
|
||||||
import type { SuperAgentTest } from '../shared/types';
|
import type { SuperAgentTest } from '../shared/types';
|
||||||
import type { EventService } from '@/eventbus/event.service';
|
import type { EventService } from '@/events/event.service';
|
||||||
|
|
||||||
let authOwnerAgent: SuperAgentTest;
|
let authOwnerAgent: SuperAgentTest;
|
||||||
let authMemberAgent: SuperAgentTest;
|
let authMemberAgent: SuperAgentTest;
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { type JobQueue, Queue } from '@/Queue';
|
||||||
|
|
||||||
import { setupTestCommand } from '@test-integration/utils/testCommand';
|
import { setupTestCommand } from '@test-integration/utils/testCommand';
|
||||||
import { mockInstance } from '../../shared/mocking';
|
import { mockInstance } from '../../shared/mocking';
|
||||||
import { AuditEventRelay } from '@/eventbus/audit-event-relay.service';
|
import { LogStreamingEventRelay } from '@/events/log-streaming-event-relay';
|
||||||
|
|
||||||
config.set('executions.mode', 'queue');
|
config.set('executions.mode', 'queue');
|
||||||
config.set('binaryDataManager.availableModes', 'filesystem');
|
config.set('binaryDataManager.availableModes', 'filesystem');
|
||||||
|
@ -26,7 +26,7 @@ const externalHooks = mockInstance(ExternalHooks);
|
||||||
const externalSecretsManager = mockInstance(ExternalSecretsManager);
|
const externalSecretsManager = mockInstance(ExternalSecretsManager);
|
||||||
const license = mockInstance(License);
|
const license = mockInstance(License);
|
||||||
const messageEventBus = mockInstance(MessageEventBus);
|
const messageEventBus = mockInstance(MessageEventBus);
|
||||||
const auditEventRelay = mockInstance(AuditEventRelay);
|
const logStreamingEventRelay = mockInstance(LogStreamingEventRelay);
|
||||||
const orchestrationHandlerWorkerService = mockInstance(OrchestrationHandlerWorkerService);
|
const orchestrationHandlerWorkerService = mockInstance(OrchestrationHandlerWorkerService);
|
||||||
const queue = mockInstance(Queue);
|
const queue = mockInstance(Queue);
|
||||||
const orchestrationWorkerService = mockInstance(OrchestrationWorkerService);
|
const orchestrationWorkerService = mockInstance(OrchestrationWorkerService);
|
||||||
|
@ -45,7 +45,7 @@ test('worker initializes all its components', async () => {
|
||||||
expect(externalHooks.init).toHaveBeenCalledTimes(1);
|
expect(externalHooks.init).toHaveBeenCalledTimes(1);
|
||||||
expect(externalSecretsManager.init).toHaveBeenCalledTimes(1);
|
expect(externalSecretsManager.init).toHaveBeenCalledTimes(1);
|
||||||
expect(messageEventBus.initialize).toHaveBeenCalledTimes(1);
|
expect(messageEventBus.initialize).toHaveBeenCalledTimes(1);
|
||||||
expect(auditEventRelay.init).toHaveBeenCalledTimes(1);
|
expect(logStreamingEventRelay.init).toHaveBeenCalledTimes(1);
|
||||||
expect(queue.init).toHaveBeenCalledTimes(1);
|
expect(queue.init).toHaveBeenCalledTimes(1);
|
||||||
expect(queue.process).toHaveBeenCalledTimes(1);
|
expect(queue.process).toHaveBeenCalledTimes(1);
|
||||||
expect(orchestrationWorkerService.init).toHaveBeenCalledTimes(1);
|
expect(orchestrationWorkerService.init).toHaveBeenCalledTimes(1);
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { mock } from 'jest-mock-extended';
|
||||||
|
|
||||||
import type { BaseCommand } from '@/commands/BaseCommand';
|
import type { BaseCommand } from '@/commands/BaseCommand';
|
||||||
import * as testDb from '../testDb';
|
import * as testDb from '../testDb';
|
||||||
import { TelemetryEventRelay } from '@/telemetry/telemetry-event-relay.service';
|
import { TelemetryEventRelay } from '@/events/telemetry-event-relay';
|
||||||
import { mockInstance } from '@test/mocking';
|
import { mockInstance } from '@test/mocking';
|
||||||
|
|
||||||
export const setupTestCommand = <T extends BaseCommand>(Command: Class<T>) => {
|
export const setupTestCommand = <T extends BaseCommand>(Command: Class<T>) => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { LicenseErrors, LicenseService } from '@/license/license.service';
|
import { LicenseErrors, LicenseService } from '@/license/license.service';
|
||||||
import type { License } from '@/License';
|
import type { License } from '@/License';
|
||||||
import type { EventService } from '@/eventbus/event.service';
|
import type { EventService } from '@/events/event.service';
|
||||||
import type { WorkflowRepository } from '@db/repositories/workflow.repository';
|
import type { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||||
import type { TEntitlement } from '@n8n_io/license-sdk';
|
import type { TEntitlement } from '@n8n_io/license-sdk';
|
||||||
import { mock } from 'jest-mock-extended';
|
import { mock } from 'jest-mock-extended';
|
||||||
|
|
Loading…
Reference in a new issue