Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into pay-1659-connect-up…
Browse files Browse the repository at this point in the history
…-new-project-viewer-role-to-the-fe

# Conflicts:
#	packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue
  • Loading branch information
cstuncsik committed Jul 19, 2024
2 parents 3d4ea36 + 5d54685 commit 7296490
Show file tree
Hide file tree
Showing 107 changed files with 1,539 additions and 919 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
needs: install-and-build
strategy:
matrix:
node-version: [18.x, 20.x, 22.x]
node-version: [18.x, 20.x, 22.4]
with:
ref: ${{ inputs.branch }}
nodeVersion: ${{ matrix.node-version }}
Expand Down
31 changes: 31 additions & 0 deletions packages/@n8n/config/src/configs/event-bus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Config, Env, Nested } from '../decorators';

@Config
class LogWriterConfig {
/** Number of event log files to keep */
@Env('N8N_EVENTBUS_LOGWRITER_KEEPLOGCOUNT')
readonly keepLogCount: number = 3;

/** Max size (in KB) of an event log file before a new one is started */
@Env('N8N_EVENTBUS_LOGWRITER_MAXFILESIZEINKB')
readonly maxFileSizeInKB: number = 10240; // 10 MB

/** Basename of event log file */
@Env('N8N_EVENTBUS_LOGWRITER_LOGBASENAME')
readonly logBaseName: string = 'n8nEventLog';
}

@Config
export class EventBusConfig {
/** How often (in ms) to check for unsent event messages. Can in rare cases cause a message to be sent twice. `0` to disable */
@Env('N8N_EVENTBUS_CHECKUNSENTINTERVAL')
readonly checkUnsentInterval: number = 0;

/** Endpoint to retrieve n8n version information from */
@Nested
readonly logWriter: LogWriterConfig;

/** Whether to recover execution details after a crash or only mark status executions as crashed. */
@Env('N8N_EVENTBUS_RECOVERY_MODE')
readonly crashRecoveryMode: 'simple' | 'extensive' = 'extensive';
}
12 changes: 12 additions & 0 deletions packages/@n8n/config/src/configs/templates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Config, Env } from '../decorators';

@Config
export class TemplatesConfig {
/** Whether to load workflow templates. */
@Env('N8N_TEMPLATES_ENABLED')
readonly enabled: boolean = true;

/** Host to retrieve workflow templates from endpoints. */
@Env('N8N_TEMPLATES_HOST')
readonly host: string = 'https://api.n8n.io/api/';
}
8 changes: 8 additions & 0 deletions packages/@n8n/config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { EmailConfig } from './configs/email';
import { VersionNotificationsConfig } from './configs/version-notifications';
import { PublicApiConfig } from './configs/public-api';
import { ExternalSecretsConfig } from './configs/external-secrets';
import { TemplatesConfig } from './configs/templates';
import { EventBusConfig } from './configs/event-bus';

@Config
class UserManagementConfig {
Expand All @@ -31,4 +33,10 @@ export class GlobalConfig {

@Nested
externalSecrets: ExternalSecretsConfig;

@Nested
templates: TemplatesConfig;

@Nested
eventBus: EventBusConfig;
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class TextClassifier implements INodeType {
displayName: 'Text Classifier',
name: 'textClassifier',
icon: 'fa:tags',
iconColor: 'black',
group: ['transform'],
version: 1,
description: 'Classify your text into distinct categories',
Expand Down
2 changes: 1 addition & 1 deletion packages/@n8n/nodes-langchain/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"build": "tsc -p tsconfig.build.json && pnpm n8n-copy-icons && pnpm build:metadata",
"build:metadata": "pnpm n8n-generate-known && pnpm n8n-generate-ui-types",
"format": "prettier nodes credentials --write",
"lint": "eslint nodes credentials",
"lint": "eslint nodes credentials --quiet",
"lintfix": "eslint nodes credentials --fix",
"watch": "tsc-watch -p tsconfig.build.json --onCompilationComplete \"tsc-alias -p tsconfig.build.json\" --onSuccess \"pnpm n8n-generate-ui-types\"",
"test": "jest",
Expand Down
15 changes: 8 additions & 7 deletions packages/cli/src/ExternalSecrets/ExternalSecretsManager.ee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Logger } from '@/Logger';
import { jsonParse, type IDataObject, ApplicationError } from 'n8n-workflow';
import { EXTERNAL_SECRETS_INITIAL_BACKOFF, EXTERNAL_SECRETS_MAX_BACKOFF } from './constants';
import { License } from '@/License';
import { InternalHooks } from '@/InternalHooks';
import { EventService } from '@/eventbus/event.service';
import { updateIntervalTime } from './externalSecretsHelper.ee';
import { ExternalSecretsProviders } from './ExternalSecretsProviders.ee';
import { OrchestrationService } from '@/services/orchestration.service';
Expand All @@ -38,6 +38,7 @@ export class ExternalSecretsManager {
private readonly license: License,
private readonly secretsProviders: ExternalSecretsProviders,
private readonly cipher: Cipher,
private readonly eventService: EventService,
) {}

async init(): Promise<void> {
Expand Down Expand Up @@ -308,12 +309,12 @@ export class ExternalSecretsManager {
try {
testResult = await this.getProvider(vaultType)?.test();
} catch {}
void Container.get(InternalHooks).onExternalSecretsProviderSettingsSaved({
user_id: userId,
vault_type: vaultType,
is_new: isNew,
is_valid: testResult?.[0] ?? false,
error_message: testResult?.[1],
this.eventService.emit('external-secrets-provider-settings-saved', {
userId,
vaultType,
isNew,
isValid: testResult?.[0] ?? false,
errorMessage: testResult?.[1],
});
}

Expand Down
36 changes: 4 additions & 32 deletions packages/cli/src/InternalHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import type {
IExecutionTrackProperties,
} from '@/Interfaces';
import { License } from '@/License';
import { EventsService } from '@/services/events.service';
import { WorkflowStatisticsService } from '@/services/workflow-statistics.service';
import { NodeTypes } from '@/NodeTypes';
import { Telemetry } from '@/telemetry';
import type { Project } from '@db/entities/Project';
Expand All @@ -42,18 +42,18 @@ export class InternalHooks {
private readonly nodeTypes: NodeTypes,
private readonly sharedWorkflowRepository: SharedWorkflowRepository,
private readonly workflowRepository: WorkflowRepository,
eventsService: EventsService,
workflowStatisticsService: WorkflowStatisticsService,
private readonly instanceSettings: InstanceSettings,
private readonly license: License,
private readonly projectRelationRepository: ProjectRelationRepository,
private readonly sharedCredentialsRepository: SharedCredentialsRepository,
private readonly _eventBus: MessageEventBus, // needed until we decouple telemetry
) {
eventsService.on(
workflowStatisticsService.on(
'telemetry.onFirstProductionWorkflowSuccess',
async (metrics) => await this.onFirstProductionWorkflowSuccess(metrics),
);
eventsService.on(
workflowStatisticsService.on(
'telemetry.onFirstWorkflowDataLoad',
async (metrics) => await this.onFirstWorkflowDataLoad(metrics),
);
Expand Down Expand Up @@ -756,32 +756,4 @@ export class InternalHooks {
}): Promise<void> {
return await this.telemetry.track('Workflow first data fetched', data);
}

/**
* License
*/
async onLicenseRenewAttempt(data: { success: boolean }): Promise<void> {
await this.telemetry.track('Instance attempted to refresh license', data);
}

/**
* Audit
*/
async onAuditGeneratedViaCli() {
return await this.telemetry.track('Instance generated security audit via CLI command');
}

async onVariableCreated(createData: { variable_type: string }): Promise<void> {
return await this.telemetry.track('User created variable', createData);
}

async onExternalSecretsProviderSettingsSaved(saveData: {
user_id?: string | undefined;
vault_type: string;
is_valid: boolean;
is_new: boolean;
error_message?: string | undefined;
}): Promise<void> {
return await this.telemetry.track('User updated external secrets settings', saveData);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import { ProjectRepository } from '@/databases/repositories/project.repository';
import { InternalHooks } from '@/InternalHooks';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';

export async function getCredentials(credentialId: string): Promise<ICredentialsDb | null> {
return await Container.get(CredentialsRepository).findOneBy({ id: credentialId });
Expand Down Expand Up @@ -60,7 +60,7 @@ export async function saveCredential(
credential_id: credential.id,
public_api: true,
});
Container.get(EventRelay).emit('credentials-created', {
Container.get(EventService).emit('credentials-created', {
user,
credentialName: credential.name,
credentialType: credential.type,
Expand Down Expand Up @@ -102,7 +102,7 @@ export async function removeCredential(
credential_type: credentials.type,
credential_id: credentials.id,
});
Container.get(EventRelay).emit('credentials-deleted', {
Container.get(EventService).emit('credentials-deleted', {
user,
credentialName: credentials.name,
credentialType: credentials.type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
getTrackingInformationFromPullResult,
isSourceControlLicensed,
} from '@/environments/sourceControl/sourceControlHelper.ee';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';

export = {
pull: [
Expand Down Expand Up @@ -39,7 +39,7 @@ export = {
});

if (result.statusCode === 200) {
Container.get(EventRelay).emit('source-control-user-pulled-api', {
Container.get(EventService).emit('source-control-user-pulled-api', {
...getTrackingInformationFromPullResult(result.statusResult),
forced: req.body.force ?? false,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { SharedWorkflowRepository } from '@/databases/repositories/sharedWorkflo
import { TagRepository } from '@/databases/repositories/tag.repository';
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
import { ProjectRepository } from '@/databases/repositories/project.repository';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';

export = {
createWorkflow: [
Expand All @@ -59,7 +59,7 @@ export = {

await Container.get(ExternalHooks).run('workflow.afterCreate', [createdWorkflow]);
void Container.get(InternalHooks).onWorkflowCreated(req.user, createdWorkflow, project, true);
Container.get(EventRelay).emit('workflow-created', {
Container.get(EventService).emit('workflow-created', {
workflow: createdWorkflow,
user: req.user,
});
Expand Down Expand Up @@ -240,7 +240,7 @@ export = {

await Container.get(ExternalHooks).run('workflow.afterUpdate', [updateData]);
void Container.get(InternalHooks).onWorkflowSaved(req.user, updateData, true);
Container.get(EventRelay).emit('workflow-saved', {
Container.get(EventService).emit('workflow-saved', {
user: req.user,
workflowId: updateData.id,
workflowName: updateData.name,
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/UserManagement/email/UserManagementMailer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { toError } from '@/utils';

import type { InviteEmailData, PasswordResetData, SendEmailResult } from './Interfaces';
import { NodeMailer } from './NodeMailer';
import { EventRelay } from '@/eventbus/event-relay.service';
import { EventService } from '@/eventbus/event.service';

type Template = HandlebarsTemplateDelegate<unknown>;
type TemplateName = 'invite' | 'passwordReset' | 'workflowShared' | 'credentialsShared';
Expand Down Expand Up @@ -125,7 +125,7 @@ export class UserManagementMailer {
message_type: 'Workflow shared',
public_api: false,
});
Container.get(EventRelay).emit('email-failed', {
Container.get(EventService).emit('email-failed', {
user: sharer,
messageType: 'Workflow shared',
});
Expand Down Expand Up @@ -184,7 +184,7 @@ export class UserManagementMailer {
message_type: 'Credentials shared',
public_api: false,
});
Container.get(EventRelay).emit('email-failed', {
Container.get(EventService).emit('email-failed', {
user: sharer,
messageType: 'Credentials shared',
});
Expand Down
8 changes: 6 additions & 2 deletions packages/cli/src/WebhookHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ import * as WorkflowHelpers from '@/WorkflowHelpers';
import { WorkflowRunner } from '@/WorkflowRunner';
import * as WorkflowExecuteAdditionalData from '@/WorkflowExecuteAdditionalData';
import { ActiveExecutions } from '@/ActiveExecutions';
import { EventsService } from '@/services/events.service';
import { WorkflowStatisticsService } from '@/services/workflow-statistics.service';
import { OwnershipService } from './services/ownership.service';
import { parseBody } from './middlewares';
import { Logger } from './Logger';
Expand Down Expand Up @@ -360,7 +360,11 @@ export async function executeWebhook(
NodeExecuteFunctions,
executionMode,
);
Container.get(EventsService).emit('nodeFetchedData', workflow.id, workflowStartNode);
Container.get(WorkflowStatisticsService).emit(
'nodeFetchedData',
workflow.id,
workflowStartNode,
);
} catch (err) {
// Send error response to webhook caller
const errorMessage = 'Workflow Webhook Error: Workflow could not be started!';
Expand Down
Loading

0 comments on commit 7296490

Please sign in to comment.