diff --git a/cypress/e2e/6-code-node.cy.ts b/cypress/e2e/6-code-node.cy.ts index 09b3088ca1..0964cff41e 100644 --- a/cypress/e2e/6-code-node.cy.ts +++ b/cypress/e2e/6-code-node.cy.ts @@ -121,7 +121,7 @@ describe('Code node', () => { .its('request.body') .should('have.keys', ['question', 'model', 'context', 'n8nVersion']); - askAiReq.its('context').should('have.keys', ['schema', 'ndvSessionId', 'sessionId']); + askAiReq.its('context').should('have.keys', ['schema', 'ndvPushRef', 'pushRef']); cy.contains('Code generation completed').should('be.visible'); cy.getByTestId('code-node-tab-code').should('contain.text', 'console.log("Hello World")'); diff --git a/packages/cli/src/GenericHelpers.ts b/packages/cli/src/GenericHelpers.ts index 92c7ad71ca..13762e5dfd 100644 --- a/packages/cli/src/GenericHelpers.ts +++ b/packages/cli/src/GenericHelpers.ts @@ -1,4 +1,3 @@ -import type express from 'express'; import { validate } from 'class-validator'; import type { WorkflowEntity } from '@db/entities/WorkflowEntity'; import type { CredentialsEntity } from '@db/entities/CredentialsEntity'; @@ -7,13 +6,6 @@ import type { User } from '@db/entities/User'; import type { UserRoleChangePayload, UserUpdatePayload } from '@/requests'; import { BadRequestError } from './errors/response-errors/bad-request.error'; -/** - * Returns the session id if one is set - */ -export function getSessionId(req: express.Request): string | undefined { - return req.headers.sessionid as string | undefined; -} - export async function validateEntity( entity: | WorkflowEntity diff --git a/packages/cli/src/Interfaces.ts b/packages/cli/src/Interfaces.ts index 5fdca9a6a6..290c65e79b 100644 --- a/packages/cli/src/Interfaces.ts +++ b/packages/cli/src/Interfaces.ts @@ -532,7 +532,7 @@ export interface IWorkflowExecutionDataProcess { runData?: IRunData; pinData?: IPinData; retryOf?: string; - sessionId?: string; + pushRef?: string; startNodes?: StartNodeData[]; workflowData: IWorkflowBase; userId: string; diff --git a/packages/cli/src/InternalHooks.ts b/packages/cli/src/InternalHooks.ts index a18dd7e671..a7baaf24b4 100644 --- a/packages/cli/src/InternalHooks.ts +++ b/packages/cli/src/InternalHooks.ts @@ -144,8 +144,8 @@ export class InternalHooks { ]); } - async onFrontendSettingsAPI(sessionId?: string): Promise { - return await this.telemetry.track('Session started', { session_id: sessionId }); + async onFrontendSettingsAPI(pushRef?: string): Promise { + return await this.telemetry.track('Session started', { session_id: pushRef }); } async onPersonalizationSurveySubmitted( diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts index 81a21bc397..52d4999b7a 100644 --- a/packages/cli/src/Server.ts +++ b/packages/cli/src/Server.ts @@ -338,7 +338,7 @@ export class Server extends AbstractServer { `/${this.restEndpoint}/settings`, ResponseHelper.send( async (req: express.Request): Promise => - frontendService.getSettings(req.headers.sessionid as string), + frontendService.getSettings(req.headers['push-ref'] as string), ), ); } diff --git a/packages/cli/src/TestWebhooks.ts b/packages/cli/src/TestWebhooks.ts index fb7418088c..d3db5357a4 100644 --- a/packages/cli/src/TestWebhooks.ts +++ b/packages/cli/src/TestWebhooks.ts @@ -91,7 +91,7 @@ export class TestWebhooks implements IWebhookManager { }); } - const { destinationNode, sessionId, workflowEntity, webhook: testWebhook } = registration; + const { destinationNode, pushRef, workflowEntity, webhook: testWebhook } = registration; const workflow = this.toWorkflow(workflowEntity); @@ -112,7 +112,7 @@ export class TestWebhooks implements IWebhookManager { workflowEntity, workflowStartNode, executionMode, - sessionId, + pushRef, undefined, // IRunExecutionData undefined, // executionId request, @@ -130,11 +130,11 @@ export class TestWebhooks implements IWebhookManager { if (executionId === undefined) return; // Inform editor-ui that webhook got received - if (sessionId !== undefined) { + if (pushRef !== undefined) { this.push.send( 'testWebhookReceived', { workflowId: webhook?.workflowId, executionId }, - sessionId, + pushRef, ); } } catch {} @@ -147,10 +147,10 @@ export class TestWebhooks implements IWebhookManager { */ if ( this.orchestrationService.isMultiMainSetupEnabled && - sessionId && - !this.push.getBackend().hasSessionId(sessionId) + pushRef && + !this.push.getBackend().hasPushRef(pushRef) ) { - const payload = { webhookKey: key, workflowEntity, sessionId }; + const payload = { webhookKey: key, workflowEntity, pushRef }; void this.orchestrationService.publish('clear-test-webhooks', payload); return; } @@ -213,7 +213,7 @@ export class TestWebhooks implements IWebhookManager { workflowEntity: IWorkflowDb, additionalData: IWorkflowExecuteAdditionalData, runData?: IRunData, - sessionId?: string, + pushRef?: string, destinationNode?: string, ) { if (!workflowEntity.id) throw new WorkflowMissingIdError(workflowEntity); @@ -260,7 +260,7 @@ export class TestWebhooks implements IWebhookManager { cacheableWebhook.userId = userId; const registration: TestWebhookRegistration = { - sessionId, + pushRef, workflowEntity, destinationNode, webhook: cacheableWebhook as IWebhookData, @@ -302,7 +302,7 @@ export class TestWebhooks implements IWebhookManager { if (!registration) continue; - const { sessionId, workflowEntity } = registration; + const { pushRef, workflowEntity } = registration; const workflow = this.toWorkflow(workflowEntity); @@ -310,9 +310,9 @@ export class TestWebhooks implements IWebhookManager { this.clearTimeout(key); - if (sessionId !== undefined) { + if (pushRef !== undefined) { try { - this.push.send('testWebhookDeleted', { workflowId }, sessionId); + this.push.send('testWebhookDeleted', { workflowId }, pushRef); } catch { // Could not inform editor, probably is not connected anymore. So simply go on. } diff --git a/packages/cli/src/WebhookHelpers.ts b/packages/cli/src/WebhookHelpers.ts index 380bf2895f..0452da8be2 100644 --- a/packages/cli/src/WebhookHelpers.ts +++ b/packages/cli/src/WebhookHelpers.ts @@ -223,7 +223,7 @@ export async function executeWebhook( workflowData: IWorkflowDb, workflowStartNode: INode, executionMode: WorkflowExecuteMode, - sessionId: string | undefined, + pushRef: string | undefined, runExecutionData: IRunExecutionData | undefined, executionId: string | undefined, req: WebhookRequest, @@ -541,7 +541,7 @@ export async function executeWebhook( const runData: IWorkflowExecutionDataProcess = { executionMode, executionData: runExecutionData, - sessionId, + pushRef, workflowData, pinData, userId: user.id, diff --git a/packages/cli/src/WorkflowExecuteAdditionalData.ts b/packages/cli/src/WorkflowExecuteAdditionalData.ts index 5b38259dce..c5507e457c 100644 --- a/packages/cli/src/WorkflowExecuteAdditionalData.ts +++ b/packages/cli/src/WorkflowExecuteAdditionalData.ts @@ -244,50 +244,50 @@ function hookFunctionsPush(): IWorkflowExecuteHooks { return { nodeExecuteBefore: [ async function (this: WorkflowHooks, nodeName: string): Promise { - const { sessionId, executionId } = this; + const { pushRef, executionId } = this; // Push data to session which started workflow before each // node which starts rendering - if (sessionId === undefined) { + if (pushRef === undefined) { return; } logger.debug(`Executing hook on node "${nodeName}" (hookFunctionsPush)`, { executionId, - sessionId, + pushRef, workflowId: this.workflowData.id, }); - pushInstance.send('nodeExecuteBefore', { executionId, nodeName }, sessionId); + pushInstance.send('nodeExecuteBefore', { executionId, nodeName }, pushRef); }, ], nodeExecuteAfter: [ async function (this: WorkflowHooks, nodeName: string, data: ITaskData): Promise { - const { sessionId, executionId } = this; + const { pushRef, executionId } = this; // Push data to session which started workflow after each rendered node - if (sessionId === undefined) { + if (pushRef === undefined) { return; } logger.debug(`Executing hook on node "${nodeName}" (hookFunctionsPush)`, { executionId, - sessionId, + pushRef, workflowId: this.workflowData.id, }); - pushInstance.send('nodeExecuteAfter', { executionId, nodeName, data }, sessionId); + pushInstance.send('nodeExecuteAfter', { executionId, nodeName, data }, pushRef); }, ], workflowExecuteBefore: [ async function (this: WorkflowHooks): Promise { - const { sessionId, executionId } = this; + const { pushRef, executionId } = this; const { id: workflowId, name: workflowName } = this.workflowData; logger.debug('Executing hook (hookFunctionsPush)', { executionId, - sessionId, + pushRef, workflowId, }); // Push data to session which started the workflow - if (sessionId === undefined) { + if (pushRef === undefined) { return; } pushInstance.send( @@ -298,24 +298,24 @@ function hookFunctionsPush(): IWorkflowExecuteHooks { startedAt: new Date(), retryOf: this.retryOf, workflowId, - sessionId, + pushRef, workflowName, }, - sessionId, + pushRef, ); }, ], workflowExecuteAfter: [ async function (this: WorkflowHooks, fullRunData: IRun): Promise { - const { sessionId, executionId, retryOf } = this; + const { pushRef, executionId, retryOf } = this; const { id: workflowId } = this.workflowData; logger.debug('Executing hook (hookFunctionsPush)', { executionId, - sessionId, + pushRef, workflowId, }); // Push data to session which started the workflow - if (sessionId === undefined) { + if (pushRef === undefined) { return; } @@ -351,7 +351,7 @@ function hookFunctionsPush(): IWorkflowExecuteHooks { retryOf, }; - pushInstance.send('executionFinished', sendData, sessionId); + pushInstance.send('executionFinished', sendData, pushRef); }, ], }; @@ -378,7 +378,7 @@ export function hookFunctionsPreExecute(): IWorkflowExecuteHooks { nodeName, data, executionData, - this.sessionId, + this.pushRef, ); }, ], @@ -578,7 +578,7 @@ function hookFunctionsSaveWorker(): IWorkflowExecuteHooks { ErrorReporter.error(e); logger.error( `There was a problem saving the workflow with id "${this.workflowData.id}" to save changed staticData: "${e.message}" (workflowExecuteAfter)`, - { sessionId: this.sessionId, workflowId: this.workflowData.id }, + { pushRef: this.pushRef, workflowId: this.workflowData.id }, ); } } @@ -939,15 +939,15 @@ export function setExecutionStatus(status: ExecutionStatus) { } export function sendDataToUI(type: string, data: IDataObject | IDataObject[]) { - const { sessionId } = this; - if (sessionId === undefined) { + const { pushRef } = this; + if (pushRef === undefined) { return; } // Push data to session which started workflow try { const pushInstance = Container.get(Push); - pushInstance.send(type as IPushDataType, data, sessionId); + pushInstance.send(type as IPushDataType, data, pushRef); } catch (error) { const logger = Container.get(Logger); logger.warn(`There was a problem sending message to UI: ${error.message}`); @@ -1128,7 +1128,7 @@ export function getWorkflowHooksMain( if (!hookFunctions.nodeExecuteAfter) hookFunctions.nodeExecuteAfter = []; return new WorkflowHooks(hookFunctions, data.executionMode, executionId, data.workflowData, { - sessionId: data.sessionId, + pushRef: data.pushRef, retryOf: data.retryOf as string, }); } diff --git a/packages/cli/src/WorkflowRunner.ts b/packages/cli/src/WorkflowRunner.ts index 7316274672..4c46d45a7d 100644 --- a/packages/cli/src/WorkflowRunner.ts +++ b/packages/cli/src/WorkflowRunner.ts @@ -295,7 +295,7 @@ export class WorkflowRunner { }); additionalData.sendDataToUI = WorkflowExecuteAdditionalData.sendDataToUI.bind({ - sessionId: data.sessionId, + pushRef: data.pushRef, }); await additionalData.hooks.executeHookFunctions('workflowExecuteBefore', []); diff --git a/packages/cli/src/controllers/e2e.controller.ts b/packages/cli/src/controllers/e2e.controller.ts index 0656e6f181..cdf02852af 100644 --- a/packages/cli/src/controllers/e2e.controller.ts +++ b/packages/cli/src/controllers/e2e.controller.ts @@ -55,7 +55,7 @@ type PushRequest = Request< {}, { type: IPushDataType; - sessionId: string; + pushRef: string; data: object; } >; diff --git a/packages/cli/src/executionLifecycleHooks/saveExecutionProgress.ts b/packages/cli/src/executionLifecycleHooks/saveExecutionProgress.ts index d5f0d7237d..933b81f788 100644 --- a/packages/cli/src/executionLifecycleHooks/saveExecutionProgress.ts +++ b/packages/cli/src/executionLifecycleHooks/saveExecutionProgress.ts @@ -13,7 +13,7 @@ export async function saveExecutionProgress( nodeName: string, data: ITaskData, executionData: IRunExecutionData, - sessionId?: string, + pushRef?: string, ) { const saveSettings = toSaveSettings(workflowData.settings); @@ -97,7 +97,7 @@ export async function saveExecutionProgress( { ...error, executionId, - sessionId, + pushRef, workflowId: workflowData.id, }, ); diff --git a/packages/cli/src/middlewares/cors.ts b/packages/cli/src/middlewares/cors.ts index a6c33dd55d..1b1379046b 100644 --- a/packages/cli/src/middlewares/cors.ts +++ b/packages/cli/src/middlewares/cors.ts @@ -8,7 +8,7 @@ export const corsMiddleware: RequestHandler = (req, res, next) => { res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.header( 'Access-Control-Allow-Headers', - 'Origin, X-Requested-With, Content-Type, Accept, sessionid', + 'Origin, X-Requested-With, Content-Type, Accept, push-ref', ); } diff --git a/packages/cli/src/push/abstract.push.ts b/packages/cli/src/push/abstract.push.ts index c74554f160..18e28d7c7b 100644 --- a/packages/cli/src/push/abstract.push.ts +++ b/packages/cli/src/push/abstract.push.ts @@ -14,7 +14,7 @@ import type { OrchestrationService } from '@/services/orchestration.service'; export abstract class AbstractPush extends EventEmitter { protected connections: Record = {}; - protected userIdBySessionId: Record = {}; + protected userIdByPushRef: Record = {}; protected abstract close(connection: T): void; protected abstract sendToOneConnection(connection: T, data: string): void; @@ -26,100 +26,100 @@ export abstract class AbstractPush extends EventEmitter { super(); } - protected add(sessionId: string, userId: User['id'], connection: T) { - const { connections, userIdBySessionId: userIdsBySessionId } = this; - this.logger.debug('Add editor-UI session', { sessionId }); + protected add(pushRef: string, userId: User['id'], connection: T) { + const { connections, userIdByPushRef } = this; + this.logger.debug('Add editor-UI session', { pushRef }); - const existingConnection = connections[sessionId]; + const existingConnection = connections[pushRef]; if (existingConnection) { // Make sure to remove existing connection with the same ID this.close(existingConnection); } - connections[sessionId] = connection; - userIdsBySessionId[sessionId] = userId; + connections[pushRef] = connection; + userIdByPushRef[pushRef] = userId; } - protected onMessageReceived(sessionId: string, msg: unknown) { - this.logger.debug('Received message from editor-UI', { sessionId, msg }); + protected onMessageReceived(pushRef: string, msg: unknown) { + this.logger.debug('Received message from editor-UI', { pushRef, msg }); - const userId = this.userIdBySessionId[sessionId]; + const userId = this.userIdByPushRef[pushRef]; - this.emit('message', { sessionId, userId, msg }); + this.emit('message', { pushRef, userId, msg }); } - protected remove(sessionId?: string) { - if (!sessionId) return; + protected remove(pushRef?: string) { + if (!pushRef) return; - this.logger.debug('Removed editor-UI session', { sessionId }); + this.logger.debug('Removed editor-UI session', { pushRef }); - delete this.connections[sessionId]; - delete this.userIdBySessionId[sessionId]; + delete this.connections[pushRef]; + delete this.userIdByPushRef[pushRef]; } - private sendToSessions(type: IPushDataType, data: unknown, sessionIds: string[]) { + private sendTo(type: IPushDataType, data: unknown, pushRefs: string[]) { this.logger.debug(`Send data of type "${type}" to editor-UI`, { dataType: type, - sessionIds: sessionIds.join(', '), + pushRefs: pushRefs.join(', '), }); const stringifiedPayload = jsonStringify({ type, data }, { replaceCircularRefs: true }); - for (const sessionId of sessionIds) { - const connection = this.connections[sessionId]; + for (const pushRef of pushRefs) { + const connection = this.connections[pushRef]; assert(connection); this.sendToOneConnection(connection, stringifiedPayload); } } - sendToAllSessions(type: IPushDataType, data?: unknown) { - this.sendToSessions(type, data, Object.keys(this.connections)); + sendToAll(type: IPushDataType, data?: unknown) { + this.sendTo(type, data, Object.keys(this.connections)); } - sendToOneSession(type: IPushDataType, data: unknown, sessionId: string) { + sendToOneSession(type: IPushDataType, data: unknown, pushRef: string) { /** * Multi-main setup: In a manual webhook execution, the main process that * handles a webhook might not be the same as the main process that created * the webhook. If so, the handler process commands the creator process to - * relay the former's execution lifecyle events to the creator's frontend. + * relay the former's execution lifecycle events to the creator's frontend. */ - if (this.orchestrationService.isMultiMainSetupEnabled && !this.hasSessionId(sessionId)) { - const payload = { type, args: data, sessionId }; + if (this.orchestrationService.isMultiMainSetupEnabled && !this.hasPushRef(pushRef)) { + const payload = { type, args: data, pushRef }; void this.orchestrationService.publish('relay-execution-lifecycle-event', payload); return; } - if (this.connections[sessionId] === undefined) { - this.logger.error(`The session "${sessionId}" is not registered.`, { sessionId }); + if (this.connections[pushRef] === undefined) { + this.logger.error(`The session "${pushRef}" is not registered.`, { pushRef }); return; } - this.sendToSessions(type, data, [sessionId]); + this.sendTo(type, data, [pushRef]); } sendToUsers(type: IPushDataType, data: unknown, userIds: Array) { const { connections } = this; - const userSessionIds = Object.keys(connections).filter((sessionId) => - userIds.includes(this.userIdBySessionId[sessionId]), + const userPushRefs = Object.keys(connections).filter((pushRef) => + userIds.includes(this.userIdByPushRef[pushRef]), ); - this.sendToSessions(type, data, userSessionIds); + this.sendTo(type, data, userPushRefs); } closeAllConnections() { - for (const sessionId in this.connections) { + for (const pushRef in this.connections) { // Signal the connection that we want to close it. // We are not removing the sessions here because it should be // the implementation's responsibility to do so once the connection // has actually closed. - this.close(this.connections[sessionId]); + this.close(this.connections[pushRef]); } } - hasSessionId(sessionId: string) { - return this.connections[sessionId] !== undefined; + hasPushRef(pushRef: string) { + return this.connections[pushRef] !== undefined; } } diff --git a/packages/cli/src/push/index.ts b/packages/cli/src/push/index.ts index a88688d6a6..94c8a32bce 100644 --- a/packages/cli/src/push/index.ts +++ b/packages/cli/src/push/index.ts @@ -41,36 +41,36 @@ export class Push extends EventEmitter { const { user, ws, - query: { sessionId }, + query: { pushRef }, } = req; - if (!sessionId) { + if (!pushRef) { if (ws) { - ws.send('The query parameter "sessionId" is missing!'); + ws.send('The query parameter "pushRef" is missing!'); ws.close(1008); return; } - throw new BadRequestError('The query parameter "sessionId" is missing!'); + throw new BadRequestError('The query parameter "pushRef" is missing!'); } if (req.ws) { - (this.backend as WebSocketPush).add(sessionId, user.id, req.ws); + (this.backend as WebSocketPush).add(pushRef, user.id, req.ws); } else if (!useWebSockets) { - (this.backend as SSEPush).add(sessionId, user.id, { req, res }); + (this.backend as SSEPush).add(pushRef, user.id, { req, res }); } else { res.status(401).send('Unauthorized'); return; } - this.emit('editorUiConnected', sessionId); + this.emit('editorUiConnected', pushRef); } broadcast(type: IPushDataType, data?: unknown) { - this.backend.sendToAllSessions(type, data); + this.backend.sendToAll(type, data); } - send(type: IPushDataType, data: unknown, sessionId: string) { - this.backend.sendToOneSession(type, data, sessionId); + send(type: IPushDataType, data: unknown, pushRef: string) { + this.backend.sendToOneSession(type, data, pushRef); } getBackend() { diff --git a/packages/cli/src/push/sse.push.ts b/packages/cli/src/push/sse.push.ts index 6c2432917c..d57b07ea1f 100644 --- a/packages/cli/src/push/sse.push.ts +++ b/packages/cli/src/push/sse.push.ts @@ -17,13 +17,13 @@ export class SSEPush extends AbstractPush { constructor(logger: Logger, orchestrationService: OrchestrationService) { super(logger, orchestrationService); - this.channel.on('disconnect', (channel, { req }) => { - this.remove(req?.query?.sessionId); + this.channel.on('disconnect', (_, { req }) => { + this.remove(req?.query?.pushRef); }); } - add(sessionId: string, userId: User['id'], connection: Connection) { - super.add(sessionId, userId, connection); + add(pushRef: string, userId: User['id'], connection: Connection) { + super.add(pushRef, userId, connection); this.channel.addClient(connection.req, connection.res); } diff --git a/packages/cli/src/push/types.ts b/packages/cli/src/push/types.ts index d99ca3f612..4068192b6c 100644 --- a/packages/cli/src/push/types.ts +++ b/packages/cli/src/push/types.ts @@ -6,7 +6,7 @@ import type { AuthenticatedRequest } from '@/requests'; // TODO: move all push related types here -export type PushRequest = AuthenticatedRequest<{}, {}, {}, { sessionId: string }>; +export type PushRequest = AuthenticatedRequest<{}, {}, {}, { pushRef: string }>; export type SSEPushRequest = PushRequest & { ws: undefined }; export type WebSocketPushRequest = PushRequest & { ws: WebSocket }; @@ -14,7 +14,7 @@ export type WebSocketPushRequest = PushRequest & { ws: WebSocket }; export type PushResponse = Response & { req: PushRequest }; export type OnPushMessageEvent = { - sessionId: string; + pushRef: string; userId: User['id']; msg: unknown; }; diff --git a/packages/cli/src/push/websocket.push.ts b/packages/cli/src/push/websocket.push.ts index cda286274e..49c081b363 100644 --- a/packages/cli/src/push/websocket.push.ts +++ b/packages/cli/src/push/websocket.push.ts @@ -18,21 +18,21 @@ export class WebSocketPush extends AbstractPush { setInterval(() => this.pingAll(), 60 * 1000); } - add(sessionId: string, userId: User['id'], connection: WebSocket) { + add(pushRef: string, userId: User['id'], connection: WebSocket) { connection.isAlive = true; connection.on('pong', heartbeat); - super.add(sessionId, userId, connection); + super.add(pushRef, userId, connection); const onMessage = (data: WebSocket.RawData) => { try { const buffer = Array.isArray(data) ? Buffer.concat(data) : Buffer.from(data); - this.onMessageReceived(sessionId, JSON.parse(buffer.toString('utf8'))); + this.onMessageReceived(pushRef, JSON.parse(buffer.toString('utf8'))); } catch (error) { this.logger.error("Couldn't parse message from editor-UI", { error: error as unknown, - sessionId, + pushRef, data, }); } @@ -42,7 +42,7 @@ export class WebSocketPush extends AbstractPush { connection.once('close', () => { connection.off('pong', heartbeat); connection.off('message', onMessage); - this.remove(sessionId); + this.remove(pushRef); }); connection.on('message', onMessage); @@ -57,11 +57,11 @@ export class WebSocketPush extends AbstractPush { } private pingAll() { - for (const sessionId in this.connections) { - const connection = this.connections[sessionId]; + for (const pushRef in this.connections) { + const connection = this.connections[pushRef]; // If a connection did not respond with a `PONG` in the last 60 seconds, disconnect if (!connection.isAlive) { - delete this.connections[sessionId]; + delete this.connections[pushRef]; return connection.terminate(); } diff --git a/packages/cli/src/services/frontend.service.ts b/packages/cli/src/services/frontend.service.ts index 18b9314f73..630c44e0a9 100644 --- a/packages/cli/src/services/frontend.service.ts +++ b/packages/cli/src/services/frontend.service.ts @@ -225,8 +225,8 @@ export class FrontendService { this.writeStaticJSON('credentials', credentials); } - getSettings(sessionId?: string): IN8nUISettings { - void this.internalHooks.onFrontendSettingsAPI(sessionId); + getSettings(pushRef?: string): IN8nUISettings { + void this.internalHooks.onFrontendSettingsAPI(pushRef); const restEndpoint = config.getEnv('endpoints.rest'); diff --git a/packages/cli/src/services/orchestration/main/handleCommandMessageMain.ts b/packages/cli/src/services/orchestration/main/handleCommandMessageMain.ts index 02cc5aae0a..4becc95240 100644 --- a/packages/cli/src/services/orchestration/main/handleCommandMessageMain.ts +++ b/packages/cli/src/services/orchestration/main/handleCommandMessageMain.ts @@ -196,11 +196,11 @@ export async function handleCommandMessageMain(messageString: string) { * Do not debounce this - all events share the same message name. */ - const { type, args, sessionId } = message.payload; + const { type, args, pushRef } = message.payload; - if (!push.getBackend().hasSessionId(sessionId)) break; + if (!push.getBackend().hasPushRef(pushRef)) break; - push.send(type, args, sessionId); + push.send(type, args, pushRef); break; } @@ -212,9 +212,9 @@ export async function handleCommandMessageMain(messageString: string) { return message; } - const { webhookKey, workflowEntity, sessionId } = message.payload; + const { webhookKey, workflowEntity, pushRef } = message.payload; - if (!push.getBackend().hasSessionId(sessionId)) break; + if (!push.getBackend().hasPushRef(pushRef)) break; const testWebhooks = Container.get(TestWebhooks); diff --git a/packages/cli/src/services/redis/RedisServiceCommands.ts b/packages/cli/src/services/redis/RedisServiceCommands.ts index b7c15ac0ef..009f39ef65 100644 --- a/packages/cli/src/services/redis/RedisServiceCommands.ts +++ b/packages/cli/src/services/redis/RedisServiceCommands.ts @@ -35,12 +35,12 @@ export type RedisServiceBaseCommand = | { senderId: string; command: 'relay-execution-lifecycle-event'; - payload: { type: IPushDataType; args: Record; sessionId: string }; + payload: { type: IPushDataType; args: Record; pushRef: string }; } | { senderId: string; command: 'clear-test-webhooks'; - payload: { webhookKey: string; workflowEntity: IWorkflowDb; sessionId: string }; + payload: { webhookKey: string; workflowEntity: IWorkflowDb; pushRef: string }; }; export type RedisServiceWorkerResponseObject = { diff --git a/packages/cli/src/services/test-webhook-registrations.service.ts b/packages/cli/src/services/test-webhook-registrations.service.ts index 3c04770084..b1cc8920a1 100644 --- a/packages/cli/src/services/test-webhook-registrations.service.ts +++ b/packages/cli/src/services/test-webhook-registrations.service.ts @@ -5,7 +5,7 @@ import type { IWorkflowDb } from '@/Interfaces'; import { TEST_WEBHOOK_TIMEOUT, TEST_WEBHOOK_TIMEOUT_BUFFER } from '@/constants'; export type TestWebhookRegistration = { - sessionId?: string; + pushRef?: string; workflowEntity: IWorkflowDb; destinationNode?: string; webhook: IWebhookData; diff --git a/packages/cli/src/workflows/workflowExecution.service.ts b/packages/cli/src/workflows/workflowExecution.service.ts index 65e947ee47..c77b102449 100644 --- a/packages/cli/src/workflows/workflowExecution.service.ts +++ b/packages/cli/src/workflows/workflowExecution.service.ts @@ -99,7 +99,7 @@ export class WorkflowExecutionService { destinationNode, }: WorkflowRequest.ManualRunPayload, user: User, - sessionId?: string, + pushRef?: string, ) { const pinnedTrigger = this.selectPinnedActivatorStarter( workflowData, @@ -122,7 +122,7 @@ export class WorkflowExecutionService { workflowData, additionalData, runData, - sessionId, + pushRef, destinationNode, ); @@ -138,7 +138,7 @@ export class WorkflowExecutionService { executionMode: 'manual', runData, pinData, - sessionId, + pushRef, startNodes, workflowData, userId: user.id, diff --git a/packages/cli/src/workflows/workflows.controller.ts b/packages/cli/src/workflows/workflows.controller.ts index 10b6a92f0b..3a775dcee7 100644 --- a/packages/cli/src/workflows/workflows.controller.ts +++ b/packages/cli/src/workflows/workflows.controller.ts @@ -3,7 +3,6 @@ import { v4 as uuid } from 'uuid'; import axios from 'axios'; import * as Db from '@/Db'; -import * as GenericHelpers from '@/GenericHelpers'; import * as ResponseHelper from '@/ResponseHelper'; import * as WorkflowHelpers from '@/WorkflowHelpers'; import type { IWorkflowResponse } from '@/Interfaces'; @@ -331,7 +330,7 @@ export class WorkflowsController { return await this.workflowExecutionService.executeManually( req.body, req.user, - GenericHelpers.getSessionId(req), + req.headers['push-ref'] as string, ); } diff --git a/packages/cli/test/unit/TestWebhooks.test.ts b/packages/cli/test/unit/TestWebhooks.test.ts index 3f53dc006b..6c7ae555b3 100644 --- a/packages/cli/test/unit/TestWebhooks.test.ts +++ b/packages/cli/test/unit/TestWebhooks.test.ts @@ -105,7 +105,7 @@ describe('TestWebhooks', () => { jest.spyOn(testWebhooks, 'getWebhookMethods').mockResolvedValue([]); const registration = mock({ - sessionId: 'some-session-id', + pushRef: 'some-session-id', workflowEntity, }); diff --git a/packages/cli/test/unit/push/index.test.ts b/packages/cli/test/unit/push/index.test.ts index a2296a61ba..390ee100e7 100644 --- a/packages/cli/test/unit/push/index.test.ts +++ b/packages/cli/test/unit/push/index.test.ts @@ -17,12 +17,12 @@ describe('Push', () => { const sseBackend = mockInstance(SSEPush); const wsBackend = mockInstance(WebSocketPush); - test('should validate sessionId on requests for websocket backend', () => { + test('should validate pushRef on requests for websocket backend', () => { config.set('push.backend', 'websocket'); const push = new Push(); const ws = mock(); const request = mock({ user, ws }); - request.query = { sessionId: '' }; + request.query = { pushRef: '' }; push.handleRequest(request, mock()); expect(ws.send).toHaveBeenCalled(); @@ -30,11 +30,11 @@ describe('Push', () => { expect(wsBackend.add).not.toHaveBeenCalled(); }); - test('should validate sessionId on requests for SSE backend', () => { + test('should validate pushRef on requests for SSE backend', () => { config.set('push.backend', 'sse'); const push = new Push(); const request = mock({ user, ws: undefined }); - request.query = { sessionId: '' }; + request.query = { pushRef: '' }; expect(() => push.handleRequest(request, mock())).toThrow(BadRequestError); expect(sseBackend.add).not.toHaveBeenCalled(); diff --git a/packages/cli/test/unit/push/websocket.push.test.ts b/packages/cli/test/unit/push/websocket.push.test.ts index ab55605ba9..47f67a6847 100644 --- a/packages/cli/test/unit/push/websocket.push.test.ts +++ b/packages/cli/test/unit/push/websocket.push.test.ts @@ -24,8 +24,8 @@ class MockWebSocket extends EventEmitter { const createMockWebSocket = () => new MockWebSocket() as unknown as jest.Mocked; describe('WebSocketPush', () => { - const sessionId1 = 'test-session1'; - const sessionId2 = 'test-session2'; + const pushRef1 = 'test-session1'; + const pushRef2 = 'test-session2'; const userId: User['id'] = 'test-user'; mockInstance(Logger); @@ -38,7 +38,7 @@ describe('WebSocketPush', () => { }); it('can add a connection', () => { - webSocketPush.add(sessionId1, userId, mockWebSocket1); + webSocketPush.add(pushRef1, userId, mockWebSocket1); expect(mockWebSocket1.listenerCount('close')).toBe(1); expect(mockWebSocket1.listenerCount('pong')).toBe(1); @@ -46,7 +46,7 @@ describe('WebSocketPush', () => { }); it('closes a connection', () => { - webSocketPush.add(sessionId1, userId, mockWebSocket1); + webSocketPush.add(pushRef1, userId, mockWebSocket1); mockWebSocket1.emit('close'); @@ -56,8 +56,8 @@ describe('WebSocketPush', () => { }); it('sends data to one connection', () => { - webSocketPush.add(sessionId1, userId, mockWebSocket1); - webSocketPush.add(sessionId2, userId, mockWebSocket2); + webSocketPush.add(pushRef1, userId, mockWebSocket1); + webSocketPush.add(pushRef2, userId, mockWebSocket2); const data: PushDataExecutionRecovered = { type: 'executionRecovered', data: { @@ -65,7 +65,7 @@ describe('WebSocketPush', () => { }, }; - webSocketPush.sendToOneSession('executionRecovered', data, sessionId1); + webSocketPush.sendToOneSession('executionRecovered', data, pushRef1); expect(mockWebSocket1.send).toHaveBeenCalledWith( JSON.stringify({ @@ -82,8 +82,8 @@ describe('WebSocketPush', () => { }); it('sends data to all connections', () => { - webSocketPush.add(sessionId1, userId, mockWebSocket1); - webSocketPush.add(sessionId2, userId, mockWebSocket2); + webSocketPush.add(pushRef1, userId, mockWebSocket1); + webSocketPush.add(pushRef2, userId, mockWebSocket2); const data: PushDataExecutionRecovered = { type: 'executionRecovered', data: { @@ -91,7 +91,7 @@ describe('WebSocketPush', () => { }, }; - webSocketPush.sendToAllSessions('executionRecovered', data); + webSocketPush.sendToAll('executionRecovered', data); const expectedMsg = JSON.stringify({ type: 'executionRecovered', @@ -107,8 +107,8 @@ describe('WebSocketPush', () => { }); it('sends data to all users connections', () => { - webSocketPush.add(sessionId1, userId, mockWebSocket1); - webSocketPush.add(sessionId2, userId, mockWebSocket2); + webSocketPush.add(pushRef1, userId, mockWebSocket1); + webSocketPush.add(pushRef2, userId, mockWebSocket2); const data: PushDataExecutionRecovered = { type: 'executionRecovered', data: { @@ -132,8 +132,8 @@ describe('WebSocketPush', () => { }); it('pings all connections', () => { - webSocketPush.add(sessionId1, userId, mockWebSocket1); - webSocketPush.add(sessionId2, userId, mockWebSocket2); + webSocketPush.add(pushRef1, userId, mockWebSocket1); + webSocketPush.add(pushRef2, userId, mockWebSocket2); jest.runOnlyPendingTimers(); @@ -144,8 +144,8 @@ describe('WebSocketPush', () => { it('emits message event when connection receives data', () => { const mockOnMessageReceived = jest.fn(); webSocketPush.on('message', mockOnMessageReceived); - webSocketPush.add(sessionId1, userId, mockWebSocket1); - webSocketPush.add(sessionId2, userId, mockWebSocket2); + webSocketPush.add(pushRef1, userId, mockWebSocket1); + webSocketPush.add(pushRef2, userId, mockWebSocket2); const data = { test: 'data' }; const buffer = Buffer.from(JSON.stringify(data)); @@ -154,7 +154,7 @@ describe('WebSocketPush', () => { expect(mockOnMessageReceived).toHaveBeenCalledWith({ msg: data, - sessionId: sessionId1, + pushRef: pushRef1, userId, }); }); diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index 1c94b7aa33..a5c0202c4b 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -1102,7 +1102,7 @@ export interface RootState { n8nMetadata: { [key: string]: string | number | undefined; }; - sessionId: string; + pushRef: string; urlBaseWebhook: string; urlBaseEditor: string; instanceId: string; @@ -1146,7 +1146,7 @@ export interface IRootState { nodeViewOffsetPosition: XYPosition; nodeViewMoveInProgress: boolean; selectedNodes: INodeUi[]; - sessionId: string; + pushRef: string; urlBaseEditor: string; urlBaseWebhook: string; workflow: IWorkflowDb; @@ -1214,7 +1214,7 @@ export interface TargetItem { export interface NDVState { activeNodeName: string | null; mainPanelDimensions: { [key: string]: { [key: string]: number } }; - sessionId: string; + pushRef: string; input: { displayMode: IRunDataDisplayMode; nodeName?: string; @@ -1428,7 +1428,7 @@ export interface CommunityNodesState { export interface IRestApiContext { baseUrl: string; - sessionId: string; + pushRef: string; } export interface IZoomConfig { diff --git a/packages/editor-ui/src/api/ai.ts b/packages/editor-ui/src/api/ai.ts index 64dfff2123..63ecbe7871 100644 --- a/packages/editor-ui/src/api/ai.ts +++ b/packages/editor-ui/src/api/ai.ts @@ -18,8 +18,8 @@ export async function generateCodeForPrompt( context: { schema: Array<{ nodeName: string; schema: Schema }>; inputSchema: { nodeName: string; schema: Schema }; - sessionId: string; - ndvSessionId: string; + pushRef: string; + ndvPushRef: string; }; model: string; n8nVersion: string; diff --git a/packages/editor-ui/src/components/CodeNodeEditor/AskAI/AskAI.vue b/packages/editor-ui/src/components/CodeNodeEditor/AskAI/AskAI.vue index 515d22e2e7..ce06458366 100644 --- a/packages/editor-ui/src/components/CodeNodeEditor/AskAI/AskAI.vue +++ b/packages/editor-ui/src/components/CodeNodeEditor/AskAI/AskAI.vue @@ -165,8 +165,8 @@ async function onSubmit() { context: { schema: schemas.parentNodesSchemas, inputSchema: schemas.inputSchema!, - ndvSessionId: useNDVStore().sessionId, - sessionId: useRootStore().sessionId, + ndvPushRef: useNDVStore().pushRef, + pushRef: useRootStore().pushRef, }, model, n8nVersion: version, diff --git a/packages/editor-ui/src/components/ExpressionEdit.vue b/packages/editor-ui/src/components/ExpressionEdit.vue index 173b03ce4a..7540d020c9 100644 --- a/packages/editor-ui/src/components/ExpressionEdit.vue +++ b/packages/editor-ui/src/components/ExpressionEdit.vue @@ -177,7 +177,7 @@ export default defineComponent({ this.segments, this.modelValue, this.workflowsStore.workflowId, - this.ndvStore.sessionId, + this.ndvStore.pushRef, this.ndvStore.activeNode?.type ?? '', ); diff --git a/packages/editor-ui/src/components/ExpressionParameterInput.vue b/packages/editor-ui/src/components/ExpressionParameterInput.vue index dd08d22f7c..dcbcb4377c 100644 --- a/packages/editor-ui/src/components/ExpressionParameterInput.vue +++ b/packages/editor-ui/src/components/ExpressionParameterInput.vue @@ -82,7 +82,7 @@ function onBlur(event?: FocusEvent | KeyboardEvent) { segments.value, props.modelValue, workflowsStore.workflowId, - ndvStore.sessionId, + ndvStore.pushRef, ndvStore.activeNode?.type ?? '', ); diff --git a/packages/editor-ui/src/components/InputPanel.vue b/packages/editor-ui/src/components/InputPanel.vue index 2794179a21..ae1a6c2206 100644 --- a/packages/editor-ui/src/components/InputPanel.vue +++ b/packages/editor-ui/src/components/InputPanel.vue @@ -8,7 +8,7 @@ :no-data-in-branch-message="$locale.baseText('ndv.input.noOutputDataInBranch')" :is-executing="isExecutingPrevious" :executing-message="$locale.baseText('ndv.input.executingPrevious')" - :session-id="sessionId" + :push-ref="pushRef" :override-outputs="connectedCurrentNodeOutputs" :mapping-enabled="isMappingEnabled" :distance-from-active="currentNodeDepth" @@ -208,7 +208,7 @@ export default defineComponent({ canLinkRuns: { type: Boolean, }, - sessionId: { + pushRef: { type: String, }, readOnly: { @@ -472,7 +472,7 @@ export default defineComponent({ this.$telemetry.track('User clicked ndv button', { node_type: this.activeNode.type, workflow_id: this.workflowsStore.workflowId, - session_id: this.sessionId, + push_ref: this.pushRef, pane: 'input', type: 'executePrevious', }); @@ -496,7 +496,7 @@ export default defineComponent({ this.$telemetry.track('User clicked ndv link', { node_type: this.activeNode.type, workflow_id: this.workflowsStore.workflowId, - session_id: this.sessionId, + push_ref: this.pushRef, pane: 'input', type: 'not-connected-help', }); diff --git a/packages/editor-ui/src/components/NodeDetailsView.vue b/packages/editor-ui/src/components/NodeDetailsView.vue index 049369d0bd..d89000a0fb 100644 --- a/packages/editor-ui/src/components/NodeDetailsView.vue +++ b/packages/editor-ui/src/components/NodeDetailsView.vue @@ -55,7 +55,7 @@ @@ -66,7 +66,7 @@ :run-index="inputRun" :linked-runs="linked" :current-node-name="inputNodeName" - :session-id="sessionId" + :push-ref="pushRef" :read-only="readOnly || hasForeignCredential" :is-production-execution-preview="isProductionExecutionPreview" :is-pane-active="isInputPaneActive" @@ -88,7 +88,7 @@ :can-link-runs="canLinkRuns" :run-index="outputRun" :linked-runs="linked" - :session-id="sessionId" + :push-ref="pushRef" :is-read-only="readOnly || hasForeignCredential" :block-u-i="blockUi && isTriggerNode && !isExecutableTriggerNode" :is-production-execution-preview="isProductionExecutionPreview" @@ -107,7 +107,7 @@ this.ndvStore.setNDVSessionId(), 0); + setTimeout(() => this.ndvStore.setNDVPushRef(), 0); void this.externalHooks.run('dataDisplay.nodeTypeChanged', { nodeSubtitle: this.nodeHelpers.getNodeSubtitle( node, @@ -503,7 +503,7 @@ export default defineComponent({ this.$telemetry.track('User opened node modal', { node_type: this.activeNodeType ? this.activeNodeType.name : '', workflow_id: this.workflowsStore.workflowId, - session_id: this.sessionId, + push_ref: this.pushRef, is_editable: !this.hasForeignCredential, parameters_pane_position: this.mainPanelPosition, input_first_connector_runs: this.maxInputRun, @@ -604,7 +604,7 @@ export default defineComponent({ this.$telemetry.track('User clicked ndv link', { node_type: this.activeNode.type, workflow_id: this.workflowsStore.workflowId, - session_id: this.sessionId, + push_ref: this.pushRef, pane: NodeConnectionType.Main, type: 'i-wish-this-node-would', }); @@ -624,7 +624,7 @@ export default defineComponent({ start_position: this.mainPanelPosition, end_position: e.position, node_type: this.activeNodeType ? this.activeNodeType.name : '', - session_id: this.sessionId, + push_ref: this.pushRef, workflow_id: this.workflowsStore.workflowId, }); this.mainPanelPosition = e.position; @@ -646,7 +646,7 @@ export default defineComponent({ trackLinking(pane: string) { this.$telemetry.track('User changed ndv run linking', { node_type: this.activeNodeType ? this.activeNodeType.name : '', - session_id: this.sessionId, + push_ref: this.pushRef, linked: this.linked, pane, }); @@ -719,12 +719,12 @@ export default defineComponent({ await this.externalHooks.run('dataDisplay.nodeEditingFinished'); this.$telemetry.track('User closed node modal', { node_type: this.activeNodeType ? this.activeNodeType.name : '', - session_id: this.sessionId, + push_ref: this.pushRef, workflow_id: this.workflowsStore.workflowId, }); this.triggerWaitingWarningEnabled = false; this.ndvStore.activeNodeName = null; - this.ndvStore.resetNDVSessionId(); + this.ndvStore.resetNDVPushRef(); }, onRunOutputIndexChange(run: number) { this.runOutputIndex = run; @@ -739,7 +739,7 @@ export default defineComponent({ }, trackRunChange(run: number, pane: string) { this.$telemetry.track('User changed ndv run dropdown', { - session_id: this.sessionId, + push_ref: this.pushRef, run_index: run, node_type: this.activeNodeType ? this.activeNodeType.name : '', pane, @@ -752,7 +752,7 @@ export default defineComponent({ this.$telemetry.track('User changed ndv input dropdown', { node_type: this.activeNode ? this.activeNode.type : '', - session_id: this.sessionId, + push_ref: this.pushRef, workflow_id: this.workflowsStore.workflowId, selection_value: index, input_node_type: this.inputNode ? this.inputNode.type : '', diff --git a/packages/editor-ui/src/components/NodeExecuteButton.vue b/packages/editor-ui/src/components/NodeExecuteButton.vue index 480a16a1db..1fcd5cf6ef 100644 --- a/packages/editor-ui/src/components/NodeExecuteButton.vue +++ b/packages/editor-ui/src/components/NodeExecuteButton.vue @@ -263,7 +263,7 @@ export default defineComponent({ node_type: this.nodeType ? this.nodeType.name : null, workflow_id: this.workflowsStore.workflowId, source: this.telemetrySource, - session_id: this.ndvStore.sessionId, + push_ref: this.ndvStore.pushRef, }; this.$telemetry.track('User clicked execute node button', telemetryPayload); await this.externalHooks.run('nodeExecuteButton.onClick', telemetryPayload); diff --git a/packages/editor-ui/src/components/NodeSettings.vue b/packages/editor-ui/src/components/NodeSettings.vue index 7ae4b38f27..bd225c1785 100644 --- a/packages/editor-ui/src/components/NodeSettings.vue +++ b/packages/editor-ui/src/components/NodeSettings.vue @@ -33,7 +33,7 @@ v-if="node && nodeValid" v-model="openPanel" :node-type="nodeType" - :session-id="sessionId" + :push-ref="pushRef" />
@@ -389,7 +389,7 @@ export default defineComponent({ dragging: { type: Boolean, }, - sessionId: { + pushRef: { type: String, }, nodeType: { diff --git a/packages/editor-ui/src/components/NodeSettingsTabs.vue b/packages/editor-ui/src/components/NodeSettingsTabs.vue index 5908f33add..741cd43ab3 100644 --- a/packages/editor-ui/src/components/NodeSettingsTabs.vue +++ b/packages/editor-ui/src/components/NodeSettingsTabs.vue @@ -32,7 +32,7 @@ export default defineComponent({ default: '', }, nodeType: {}, - sessionId: { + pushRef: { type: String, }, }, @@ -135,7 +135,7 @@ export default defineComponent({ this.$telemetry.track('User clicked ndv link', { node_type: this.activeNode.type, workflow_id: this.workflowsStore.workflowId, - session_id: this.sessionId, + push_ref: this.pushRef, pane: NodeConnectionType.Main, type: 'docs', }); diff --git a/packages/editor-ui/src/components/OutputPanel.vue b/packages/editor-ui/src/components/OutputPanel.vue index 49bc93aadb..3082e29d62 100644 --- a/packages/editor-ui/src/components/OutputPanel.vue +++ b/packages/editor-ui/src/components/OutputPanel.vue @@ -9,7 +9,7 @@ :no-data-in-branch-message="$locale.baseText('ndv.output.noOutputDataInBranch')" :is-executing="isNodeRunning" :executing-message="$locale.baseText('ndv.output.executing')" - :session-id="sessionId" + :push-ref="pushRef" :block-u-i="blockUI" :is-production-execution-preview="isProductionExecutionPreview" :is-pane-active="isPaneActive" @@ -139,7 +139,7 @@ export default defineComponent({ canLinkRuns: { type: Boolean, }, - sessionId: { + pushRef: { type: String, }, blockUI: { @@ -300,7 +300,7 @@ export default defineComponent({ this.$telemetry.track('User clicked ndv link', { workflow_id: this.workflowsStore.workflowId, - session_id: this.sessionId, + push_ref: this.pushRef, node_type: this.node.type, pane: 'output', type: 'insert-test-data', @@ -318,7 +318,7 @@ export default defineComponent({ this.$telemetry.track('User clicked ndv link', { node_type: this.node.type, workflow_id: this.workflowsStore.workflowId, - session_id: this.sessionId, + push_ref: this.pushRef, pane: 'output', type: 'settings', }); diff --git a/packages/editor-ui/src/components/ParameterInput.vue b/packages/editor-ui/src/components/ParameterInput.vue index c94d7957fb..c3d952cd0e 100644 --- a/packages/editor-ui/src/components/ParameterInput.vue +++ b/packages/editor-ui/src/components/ParameterInput.vue @@ -1145,7 +1145,7 @@ export default defineComponent({ parameter_field_type: this.parameter.type, new_expression: !this.isValueExpression, workflow_id: this.workflowsStore.workflowId, - session_id: this.ndvStore.sessionId, + push_ref: this.ndvStore.pushRef, source: this.eventSource || 'ndv', }); } @@ -1297,7 +1297,7 @@ export default defineComponent({ node_type: this.node && this.node.type, resource: this.node && this.node.parameters.resource, is_custom: value === CUSTOM_API_CALL_KEY, - session_id: this.ndvStore.sessionId, + push_ref: this.ndvStore.pushRef, parameter: this.parameter.name, }); } diff --git a/packages/editor-ui/src/components/RunData.vue b/packages/editor-ui/src/components/RunData.vue index b43e39998a..db685a2e21 100644 --- a/packages/editor-ui/src/components/RunData.vue +++ b/packages/editor-ui/src/components/RunData.vue @@ -382,7 +382,7 @@ { enabled?: boolean; value?: string }, }, - sessionId: { + pushRef: { type: String, }, paneType: { diff --git a/packages/editor-ui/src/components/RunDataJsonActions.vue b/packages/editor-ui/src/components/RunDataJsonActions.vue index 9ea46e3372..9de388bd98 100644 --- a/packages/editor-ui/src/components/RunDataJsonActions.vue +++ b/packages/editor-ui/src/components/RunDataJsonActions.vue @@ -68,7 +68,7 @@ export default defineComponent({ paneType: { type: String, }, - sessionId: { + pushRef: { type: String, }, currentOutputIndex: { @@ -222,7 +222,7 @@ export default defineComponent({ this.$telemetry.track('User copied ndv data', { node_type: this.activeNode.type, - session_id: this.sessionId, + push_ref: this.pushRef, run_index: this.runIndex, view: 'json', copy_type: copyType, diff --git a/packages/editor-ui/src/components/TriggerPanel.vue b/packages/editor-ui/src/components/TriggerPanel.vue index d668e15fe6..8c022a924f 100644 --- a/packages/editor-ui/src/components/TriggerPanel.vue +++ b/packages/editor-ui/src/components/TriggerPanel.vue @@ -142,7 +142,7 @@ export default defineComponent({ nodeName: { type: String, }, - sessionId: { + pushRef: { type: String, }, }, @@ -409,7 +409,7 @@ export default defineComponent({ openWebhookUrl() { this.$telemetry.track('User clicked ndv link', { workflow_id: this.workflowsStore.workflowId, - session_id: this.sessionId, + push_ref: this.pushRef, pane: 'input', type: 'open-chat', }); @@ -431,7 +431,7 @@ export default defineComponent({ } else if (target.dataset.key === 'executions') { this.$telemetry.track('User clicked ndv link', { workflow_id: this.workflowsStore.workflowId, - session_id: this.sessionId, + push_ref: this.pushRef, pane: 'input', type: 'open-executions-log', }); diff --git a/packages/editor-ui/src/components/WorkflowLMChat.vue b/packages/editor-ui/src/components/WorkflowLMChat.vue index 3d4d19e7e5..06de8531ca 100644 --- a/packages/editor-ui/src/components/WorkflowLMChat.vue +++ b/packages/editor-ui/src/components/WorkflowLMChat.vue @@ -465,7 +465,7 @@ export default defineComponent({ [ { json: { - sessionId: `test-${currentUser.id || 'unknown'}`, + pushRef: `test-${currentUser.id || 'unknown'}`, action: 'sendMessage', [inputKey]: message, }, diff --git a/packages/editor-ui/src/composables/usePinnedData.ts b/packages/editor-ui/src/composables/usePinnedData.ts index 1e15a1eb56..a35fdaa9ba 100644 --- a/packages/editor-ui/src/composables/usePinnedData.ts +++ b/packages/editor-ui/src/composables/usePinnedData.ts @@ -48,7 +48,7 @@ export function usePinnedData( const telemetry = useTelemetry(); const externalHooks = useExternalHooks(); - const { sessionId } = storeToRefs(rootStore); + const { pushRef } = storeToRefs(rootStore); const { isSubNodeType, isMultipleOutputsNodeType } = useNodeType({ node, }); @@ -163,7 +163,7 @@ export function usePinnedData( const telemetryPayload = { pinning_source: source, node_type: targetNode?.type, - session_id: sessionId.value, + push_ref: pushRef.value, data_size: stringSizeInBytes(data.value), view: displayMode, run_index: runIndex, @@ -187,7 +187,7 @@ export function usePinnedData( telemetry.track('Ndv data pinning failure', { pinning_source: source, node_type: targetNode?.type, - session_id: sessionId.value, + push_ref: pushRef.value, data_size: stringSizeInBytes(data.value), view: displayMode, run_index: runIndex, @@ -225,7 +225,7 @@ export function usePinnedData( telemetry.track('User unpinned ndv data', { node_type: targetNode?.type, - session_id: sessionId.value, + push_ref: pushRef.value, run_index: runIndex, source, data_size: stringSizeInBytes(data.value), diff --git a/packages/editor-ui/src/hooks/cloud.ts b/packages/editor-ui/src/hooks/cloud.ts index 4c68bc4d28..91901339c6 100644 --- a/packages/editor-ui/src/hooks/cloud.ts +++ b/packages/editor-ui/src/hooks/cloud.ts @@ -46,7 +46,7 @@ export const n8nCloudHooks: PartialDeep = { const segmentStore = useSegment(); const eventData = { source: meta.source, - nodes_panel_session_id: nodesPanelSession.sessionId, + nodes_panel_session_id: nodesPanelSession.pushRef, }; hooksResetNodesPanelSession(); @@ -61,7 +61,7 @@ export const n8nCloudHooks: PartialDeep = { eventName: 'User added node to workflow canvas', properties: { node_type: meta.nodeTypeName.split('.')[1], - nodes_panel_session_id: nodesPanelSession.sessionId, + nodes_panel_session_id: nodesPanelSession.pushRef, }, }; @@ -473,7 +473,7 @@ export const n8nCloudHooks: PartialDeep = { properties: { old_filter: meta.oldValue, new_filter: meta.newValue, - nodes_panel_session_id: nodesPanelSession.sessionId, + nodes_panel_session_id: nodesPanelSession.pushRef, }, }; nodesPanelSession.data.filterMode = meta.newValue; diff --git a/packages/editor-ui/src/hooks/utils/hooksNodesPanel.ts b/packages/editor-ui/src/hooks/utils/hooksNodesPanel.ts index d7874e7c5c..2784f35a0e 100644 --- a/packages/editor-ui/src/hooks/utils/hooksNodesPanel.ts +++ b/packages/editor-ui/src/hooks/utils/hooksNodesPanel.ts @@ -1,5 +1,5 @@ export const nodesPanelSession = { - sessionId: '', + pushRef: '', data: { nodeFilter: '', resultsNodes: [] as string[], @@ -15,13 +15,13 @@ export const hooksGenerateNodesPanelEvent = () => { results_count: nodesPanelSession.data.resultsNodes.length, results_nodes: nodesPanelSession.data.resultsNodes, filter_mode: nodesPanelSession.data.filterMode, - nodes_panel_session_id: nodesPanelSession.sessionId, + nodes_panel_session_id: nodesPanelSession.pushRef, }, }; }; export const hooksResetNodesPanelSession = () => { - nodesPanelSession.sessionId = `nodes_panel_session_${new Date().valueOf()}`; + nodesPanelSession.pushRef = `nodes_panel_session_${new Date().valueOf()}`; nodesPanelSession.data = { nodeFilter: '', resultsNodes: [], diff --git a/packages/editor-ui/src/mixins/pushConnection.ts b/packages/editor-ui/src/mixins/pushConnection.ts index 8e4aa48984..d076923dd6 100644 --- a/packages/editor-ui/src/mixins/pushConnection.ts +++ b/packages/editor-ui/src/mixins/pushConnection.ts @@ -82,8 +82,8 @@ export const pushConnection = defineComponent({ usePushConnectionStore, useCollaborationStore, ), - sessionId(): string { - return this.rootStore.sessionId; + pushRef(): string { + return this.rootStore.pushRef; }, }, methods: { diff --git a/packages/editor-ui/src/plugins/telemetry/index.ts b/packages/editor-ui/src/plugins/telemetry/index.ts index 57487456b6..462941c1c9 100644 --- a/packages/editor-ui/src/plugins/telemetry/index.ts +++ b/packages/editor-ui/src/plugins/telemetry/index.ts @@ -27,7 +27,7 @@ export class Telemetry { } private userNodesPanelSession: IUserNodesPanelSession = { - sessionId: '', + pushRef: '', data: { nodeFilter: '', resultsNodes: [], @@ -76,7 +76,7 @@ export class Telemetry { this.identify(instanceId, userId, versionCli); this.flushPageEvents(); - this.track('Session started', { session_id: rootStore.sessionId }); + this.track('Session started', { session_id: rootStore.pushRef }); } identify(instanceId: string, userId?: string, versionCli?: string) { @@ -150,8 +150,8 @@ export class Telemetry { trackAskAI(event: string, properties: IDataObject = {}) { if (this.rudderStack) { - properties.session_id = useRootStore().sessionId; - properties.ndv_session_id = useNDVStore().sessionId; + properties.session_id = useRootStore().pushRef; + properties.ndv_session_id = useNDVStore().pushRef; switch (event) { case 'askAi.generationFinished': @@ -164,12 +164,12 @@ export class Telemetry { trackNodesPanel(event: string, properties: IDataObject = {}) { if (this.rudderStack) { - properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId; + properties.nodes_panel_session_id = this.userNodesPanelSession.pushRef; switch (event) { case 'nodeView.createNodeActiveChanged': if (properties.createNodeActive !== false) { this.resetNodesPanelSession(); - properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId; + properties.nodes_panel_session_id = this.userNodesPanelSession.pushRef; this.track('User opened nodes panel', properties); } break; @@ -200,25 +200,25 @@ export class Telemetry { break; case 'nodeCreateList.onCategoryExpanded': properties.is_subcategory = false; - properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId; + properties.nodes_panel_session_id = this.userNodesPanelSession.pushRef; this.track('User viewed node category', properties); break; case 'nodeCreateList.onViewActions': - properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId; + properties.nodes_panel_session_id = this.userNodesPanelSession.pushRef; this.track('User viewed node actions', properties); break; case 'nodeCreateList.onActionsCustmAPIClicked': - properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId; + properties.nodes_panel_session_id = this.userNodesPanelSession.pushRef; this.track('User clicked custom API from node actions', properties); break; case 'nodeCreateList.addAction': - properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId; + properties.nodes_panel_session_id = this.userNodesPanelSession.pushRef; this.track('User added action', properties); break; case 'nodeCreateList.onSubcategorySelected': properties.category_name = properties.subcategory; properties.is_subcategory = true; - properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId; + properties.nodes_panel_session_id = this.userNodesPanelSession.pushRef; delete properties.selected; this.track('User viewed node category', properties); break; @@ -258,7 +258,7 @@ export class Telemetry { } private resetNodesPanelSession() { - this.userNodesPanelSession.sessionId = `nodes_panel_session_${new Date().valueOf()}`; + this.userNodesPanelSession.pushRef = `nodes_panel_session_${new Date().valueOf()}`; this.userNodesPanelSession.data = { nodeFilter: '', resultsNodes: [], @@ -271,7 +271,7 @@ export class Telemetry { search_string: this.userNodesPanelSession.data.nodeFilter, results_count: this.userNodesPanelSession.data.resultsNodes.length, filter_mode: this.userNodesPanelSession.data.filterMode, - nodes_panel_session_id: this.userNodesPanelSession.sessionId, + nodes_panel_session_id: this.userNodesPanelSession.pushRef, }; } diff --git a/packages/editor-ui/src/plugins/telemetry/telemetry.types.ts b/packages/editor-ui/src/plugins/telemetry/telemetry.types.ts index b4d0078322..4e4e083c74 100644 --- a/packages/editor-ui/src/plugins/telemetry/telemetry.types.ts +++ b/packages/editor-ui/src/plugins/telemetry/telemetry.types.ts @@ -5,7 +5,7 @@ declare global { } export interface IUserNodesPanelSession { - sessionId: string; + pushRef: string; data: IUserNodesPanelSessionData; } diff --git a/packages/editor-ui/src/stores/cloudPlan.store.ts b/packages/editor-ui/src/stores/cloudPlan.store.ts index d2201e8e5c..d564896afc 100644 --- a/packages/editor-ui/src/stores/cloudPlan.store.ts +++ b/packages/editor-ui/src/stores/cloudPlan.store.ts @@ -105,7 +105,7 @@ export const useCloudPlanStore = defineStore(STORES.CLOUD_PLAN, () => { }; const getInstanceCurrentUsage = async () => { - const usage = await getCurrentUsage({ baseUrl: rootStore.getBaseUrl, sessionId: '' }); + const usage = await getCurrentUsage({ baseUrl: rootStore.getBaseUrl, pushRef: '' }); state.usage = usage; return usage; }; diff --git a/packages/editor-ui/src/stores/n8nRoot.store.ts b/packages/editor-ui/src/stores/n8nRoot.store.ts index 34487bae34..56eeace066 100644 --- a/packages/editor-ui/src/stores/n8nRoot.store.ts +++ b/packages/editor-ui/src/stores/n8nRoot.store.ts @@ -25,7 +25,7 @@ export const useRootStore = defineStore(STORES.ROOT, { versionCli: '0.0.0', oauthCallbackUrls: {}, n8nMetadata: {}, - sessionId: Math.random().toString(36).substring(2, 15), + pushRef: Math.random().toString(36).substring(2, 15), urlBaseWebhook: 'http://localhost:5678/', urlBaseEditor: 'http://localhost:5678', isNpmAvailable: false, @@ -66,14 +66,14 @@ export const useRootStore = defineStore(STORES.ROOT, { baseUrl: window.location.host.includes('stage-app.n8n.cloud') ? CLOUD_BASE_URL_STAGING : CLOUD_BASE_URL_PRODUCTION, - sessionId: '', + pushRef: '', }; }, getRestApiContext(): IRestApiContext { return { baseUrl: this.getRestUrl, - sessionId: this.sessionId, + pushRef: this.pushRef, }; }, }, diff --git a/packages/editor-ui/src/stores/ndv.store.ts b/packages/editor-ui/src/stores/ndv.store.ts index 5ac185d4d2..b2e7e315b3 100644 --- a/packages/editor-ui/src/stores/ndv.store.ts +++ b/packages/editor-ui/src/stores/ndv.store.ts @@ -22,7 +22,7 @@ export const useNDVStore = defineStore(STORES.NDV, { state: (): NDVState => ({ activeNodeName: null, mainPanelDimensions: {}, - sessionId: '', + pushRef: '', input: { displayMode: 'schema', nodeName: undefined, @@ -184,11 +184,11 @@ export const useNDVStore = defineStore(STORES.NDV, { }, }; }, - setNDVSessionId(): void { - this.sessionId = `ndv-${uuid()}`; + setNDVPushRef(): void { + this.pushRef = `ndv-${uuid()}`; }, - resetNDVSessionId(): void { - this.sessionId = ''; + resetNDVPushRef(): void { + this.pushRef = ''; }, setPanelDisplayMode(params: { pane: NodePanelType; mode: IRunDataDisplayMode }): void { this[params.pane].displayMode = params.mode; diff --git a/packages/editor-ui/src/stores/pushConnection.store.ts b/packages/editor-ui/src/stores/pushConnection.store.ts index b636303c24..ade38baddf 100644 --- a/packages/editor-ui/src/stores/pushConnection.store.ts +++ b/packages/editor-ui/src/stores/pushConnection.store.ts @@ -6,7 +6,7 @@ import { useRootStore } from './n8nRoot.store'; import type { IPushData } from '../Interface'; export interface PushState { - sessionId: string; + pushRef: string; pushSource: WebSocket | EventSource | null; reconnectTimeout: NodeJS.Timeout | null; retryTimeout: NodeJS.Timeout | null; @@ -26,7 +26,7 @@ export const usePushConnectionStore = defineStore(STORES.PUSH, () => { const rootStore = useRootStore(); const settingsStore = useSettingsStore(); - const sessionId = computed(() => rootStore.sessionId); + const pushRef = computed(() => rootStore.pushRef); const pushSource = ref(null); const reconnectTimeout = ref(null); const connectRetries = ref(0); @@ -85,7 +85,7 @@ export const usePushConnectionStore = defineStore(STORES.PUSH, () => { const useWebSockets = settingsStore.pushBackend === 'websocket'; const { getRestUrl: restUrl } = rootStore; - const url = `/push?sessionId=${sessionId.value}`; + const url = `/push?pushRef=${pushRef.value}`; if (useWebSockets) { const { protocol, host } = window.location; @@ -151,7 +151,7 @@ export const usePushConnectionStore = defineStore(STORES.PUSH, () => { } return { - sessionId, + pushRef, pushSource, isConnectionOpen, addEventListener, diff --git a/packages/editor-ui/src/utils/apiUtils.ts b/packages/editor-ui/src/utils/apiUtils.ts index cc6b73c2b9..e6ce5d734f 100644 --- a/packages/editor-ui/src/utils/apiUtils.ts +++ b/packages/editor-ui/src/utils/apiUtils.ts @@ -125,7 +125,7 @@ export async function makeRestApiRequest( method, baseURL: context.baseUrl, endpoint, - headers: { sessionid: context.sessionId }, + headers: { 'push-ref': context.pushRef }, data, }); diff --git a/packages/editor-ui/src/utils/telemetryUtils.ts b/packages/editor-ui/src/utils/telemetryUtils.ts index 51063ab5b3..b7d1e5cadb 100644 --- a/packages/editor-ui/src/utils/telemetryUtils.ts +++ b/packages/editor-ui/src/utils/telemetryUtils.ts @@ -6,7 +6,7 @@ export function createExpressionTelemetryPayload( segments: Segment[], value: string, workflowId: string, - sessionId: string, + pushRef: string, activeNodeType: string, eventSource = 'ndv', ) { @@ -17,7 +17,7 @@ export function createExpressionTelemetryPayload( empty_expression: value === '=' || value === '={{}}' || !value, workflow_id: workflowId, source: eventSource, - session_id: sessionId, + push_ref: pushRef, is_transforming_data: resolvables.some((r) => isTransformingData(r.resolvable)), has_parameter: value.includes('$parameter'), has_mapping: hasExpressionMapping(value), diff --git a/packages/editor-ui/src/views/NodeView.vue b/packages/editor-ui/src/views/NodeView.vue index 8e789ff7d1..940ba3bab2 100644 --- a/packages/editor-ui/src/views/NodeView.vue +++ b/packages/editor-ui/src/views/NodeView.vue @@ -1066,7 +1066,7 @@ export default defineComponent({ node_type: node ? node.type : null, workflow_id: this.workflowsStore.workflowId, source: 'canvas', - session_id: this.ndvStore.sessionId, + push_ref: this.ndvStore.pushRef, }; this.$telemetry.track('User clicked execute node button', telemetryPayload); void this.externalHooks.run('nodeView.onRunNode', telemetryPayload); diff --git a/packages/workflow/src/Interfaces.ts b/packages/workflow/src/Interfaces.ts index 58a8515aae..7a90966aca 100644 --- a/packages/workflow/src/Interfaces.ts +++ b/packages/workflow/src/Interfaces.ts @@ -2102,7 +2102,7 @@ export type WorkflowActivateMode = export interface IWorkflowHooksOptionalParameters { retryOf?: string; - sessionId?: string; + pushRef?: string; } export namespace WorkflowSettings { diff --git a/packages/workflow/src/WorkflowHooks.ts b/packages/workflow/src/WorkflowHooks.ts index 1f5ad85a96..68ca3d3a83 100644 --- a/packages/workflow/src/WorkflowHooks.ts +++ b/packages/workflow/src/WorkflowHooks.ts @@ -12,7 +12,7 @@ export class WorkflowHooks { executionId: string; - sessionId?: string; + pushRef?: string; retryOf?: string; @@ -32,7 +32,7 @@ export class WorkflowHooks { this.mode = mode; this.executionId = executionId; this.workflowData = workflowData; - this.sessionId = optionalParameters.sessionId; + this.pushRef = optionalParameters.pushRef; // retryOf might be `null` from TypeORM this.retryOf = optionalParameters.retryOf ?? undefined; }